sclass Hi15Image extends WAndHImpl is MakesBufferedImage { short[] pixels; *() {} // for persistence *(int *w, int *h, short[] *pixels) {} // TODO: optimize! *(BufferedImage img) { this(RGBImage(img)); } *(RGBImage img) { w = img.getWidth(); h = img.getHeight(); pixels = new short[w*h]; for y to h: for x to w: pixels[y*w+x] = rgbIntToHi15(img.getInt(x, y)); } *(MakesBufferedImage img) { this(toBufferedImage(img)); } RGBImage toRGB() { RGBImage img = new RGBImage(w, h); int i = 0, w = this.w, h = this.h; for y to h: for x to w: img.setPixel(x, y, hi15ToRGBInt(pixels[i++])); ret img; } public BufferedImage getBufferedImage() { ret toRGB().getBufferedImage(); } // 0 to 32767 short getHi15Pixel aka getHi15Color(int x, int y) { ret pixels[y*w+x]; } // idx = index in pixel array public short getHi15Pixel_noRangeCheck(int idx) { ret pixels[idx]; } static int perChannelBitCountMask(int bitCount) { int mask = ((~0x1F) >> bitCount) & 0x1F; int mask2 = (mask << 10) | (mask << 5) | mask; ret mask2; } void reducePerChannelBitCount(int bitCount) { if (bitCount >= 5) ret; int mask = perChannelBitCountMask(bitCount); short[] pixels = this.pixels; for (int i = 0; i < pixels.length; i++) pixels[i] = (short) (pixels[i] & mask); } void reduceColorCount(int numColors) { assertPowerOfTwo(numColors); int bits = dualLog(numColors); assertDivisibleBy(3, bits); int bitsPerChannel = bits/3; reducePerChannelBitCount(bitsPerChannel); } }