// same brightness level count for each channel for now sclass PosterizeBufferedImageToHi15 { BufferedImage img; Hi15Image result; IPosterizer posterizer; *(int brightnessLevels, BufferedImage *img) { if (brightnessLevels >= 256 || img == null) posterizer = new DummyPosterizer; posterizer = SinglePixelPosterizer(brightnessLevels); } *(IPosterizer *posterizer, BufferedImage *img) {} run { if (img == null) ret; if (posterizer cast DummyPosterizer) ret with result = new Hi15Image(img); GrabbableRGBBytePixels gp = grabbableRGBBytePixels(img); if (gp != null) ret with run(gp); GrabbableIntPixels gp2 = grabbableIntPixels_fastOrSlow(img); run(gp2); } void run(GrabbableIntPixels gp) { int w = img.getWidth(), h = img.getHeight(), n = w*h; int[] pixels = gp.data; short[] pixels2 = new[n]; byte[] cache = cachePosterizer(); int extraStride = gp.scanlineStride-w; int iOut = 0, iIn = gp.offset; for y to h: { for x to w: { int rgb = pixels[iIn++]; pixels2[iOut++] = (short) ((cache[(rgb >> 16) & 0xFF] << 10) | (cache[(rgb >> 8) & 0xFF] << 5) | cache[rgb & 0xFF]); } iIn += extraStride; } result = new Hi15Image(w, h, pixels2); } void run(GrabbableRGBBytePixels gp) { int w = img.getWidth(), h = img.getHeight(), n = w*h; byte[] pixels = gp.data; short[] pixels2 = new[n]; byte[] cache = cachePosterizer(); int extraStride = gp.scanlineStride-w*3; int iOut = 0, iIn = gp.offset; for y to h: { for x to w: { int r = pixels[iIn++] & 0xFF; int g = pixels[iIn++] & 0xFF; int b = pixels[iIn++] & 0xFF; pixels2[iOut++] = (short) ((cache[r] << 10) | (cache[g] << 5) | cache[b]); } iIn += extraStride; } result = new Hi15Image(w, h, pixels2); } public BufferedImage pixelPreservingSrcImage() { ret img; } Hi15Image get() { if (result == null) run(); ret result; } byte[] cachePosterizer() { byte[] cache = new[256]; for i to 256: cache[i] = (byte) (posterizer.get(i) >> 3); ret cache; } }