}
}
private void process(RGB24Image in, Paletted8Image out)
{
UniformPaletteQuantizer upq = new UniformPaletteQuantizer(redBits, greenBits, blueBits);
if (out == null)
{
out = new MemoryPaletted8Image(in.getWidth(), in.getHeight(), upq.createPalette());
setOutputImage(out);
}
int D1 = 4;
int D2 = 4;
int D1D2 = D1 * D2;
final int[] DITHER_MATRIX = {0, 8, 2, 10, 12, 4, 14, 6, 3, 11, 1, 9, 15, 7, 13, 5};
final int RED_SPACE = 255 / ((1 << redBits) - 1);
final int GREEN_SPACE = 255 / ((1 << greenBits) - 1);
final int BLUE_SPACE = 255 / ((1 << blueBits) - 1);
/*final int RED_SHIFT = 8 - redBits;
final int GREEN_SHIFT = 8 - redBits;
final int BLUE_SHIFT = 8 - redBits;
final int NUM_RED_VALUES = 1 << redBits;
final int NUM_GREEN_VALUES = 1 << greenBits;
final int NUM_BLUE_VALUES = 1 << blueBits;*/
final int[] RED_DITHER_SIGNAL = new int[D1D2];
final int[] GREEN_DITHER_SIGNAL = new int[D1D2];
final int[] BLUE_DITHER_SIGNAL = new int[D1D2];
for (int i = 0; i < D1D2; i++)
{
RED_DITHER_SIGNAL[i] = (2 * DITHER_MATRIX[i] - D1D2 + 1) * RED_SPACE / (2 * D1D2);
GREEN_DITHER_SIGNAL[i] = (2 * DITHER_MATRIX[i] - D1D2 + 1) * GREEN_SPACE / (2 * D1D2);
BLUE_DITHER_SIGNAL[i] = (2 * DITHER_MATRIX[i] - D1D2 + 1) * BLUE_SPACE / (2 * D1D2);
}
final int HEIGHT = in.getHeight();
final int WIDTH = in.getWidth();
int rowOffset = 0;
for (int y = 0; y < HEIGHT; y++)
{
int offset = rowOffset;
final int MAX_OFFSET = rowOffset + D1;
for (int x = 0; x < WIDTH; x++)
{
int redSample = in.getSample(INDEX_RED, x, y);
redSample = redSample + RED_DITHER_SIGNAL[ offset ];
if (redSample < 0)
{
redSample = 0;
}
else
if (redSample > 255)
{
redSample = 255;
}
int greenSample = in.getSample(INDEX_GREEN, x, y);
greenSample = greenSample + GREEN_DITHER_SIGNAL[ offset ];
if (greenSample < 0)
{
greenSample = 0;
}
else
if (greenSample > 255)
{
greenSample = 255;
}
int blueSample = in.getSample(INDEX_BLUE, x, y);
blueSample = blueSample + BLUE_DITHER_SIGNAL[ offset ];
if (blueSample < 0)
{
blueSample = 0;
}
else
if (blueSample > 255)
{
blueSample = 255;
}
out.putSample(0, x, y, upq.mapToIndex(redSample, greenSample, blueSample));
offset++;
if (offset == MAX_OFFSET)
{
offset = rowOffset;
}