The Independent JPEG Group's JPEG software v4
This commit is contained in:
90
jquant2.c
90
jquant2.c
@@ -913,16 +913,26 @@ pass2_dither (decompress_info_ptr cinfo, int num_rows,
|
||||
JSAMPIMAGE image_data, JSAMPARRAY output_workspace)
|
||||
/* This version performs Floyd-Steinberg dithering */
|
||||
{
|
||||
register FSERROR val;
|
||||
register FSERRPTR thisrowerr, nextrowerr;
|
||||
#ifdef EIGHT_BIT_SAMPLES
|
||||
register int c0, c1, c2;
|
||||
int two_val;
|
||||
#else
|
||||
register FSERROR c0, c1, c2;
|
||||
register int pixcode;
|
||||
FSERROR two_val;
|
||||
#endif
|
||||
register FSERRPTR thisrowerr, nextrowerr;
|
||||
JSAMPROW ptr0, ptr1, ptr2, outptr;
|
||||
histptr cachep;
|
||||
register int pixcode;
|
||||
int dir;
|
||||
long col;
|
||||
int row;
|
||||
long col;
|
||||
long width = cinfo->image_width;
|
||||
JSAMPLE *range_limit = cinfo->sample_range_limit;
|
||||
JSAMPROW colormap0 = my_colormap[0];
|
||||
JSAMPROW colormap1 = my_colormap[1];
|
||||
JSAMPROW colormap2 = my_colormap[2];
|
||||
SHIFT_TEMPS
|
||||
|
||||
/* Convert data to colormap indexes, which we save in output_workspace */
|
||||
for (row = 0; row < num_rows; row++) {
|
||||
@@ -950,33 +960,21 @@ pass2_dither (decompress_info_ptr cinfo, int num_rows,
|
||||
/* need only initialize this one entry in nextrowerr */
|
||||
nextrowerr[0] = nextrowerr[1] = nextrowerr[2] = 0;
|
||||
for (col = width; col > 0; col--) {
|
||||
/* Get this pixel's value and add accumulated errors */
|
||||
/* The errors are in units of 1/16th pixel value */
|
||||
val = (GETJSAMPLE(*ptr0) << 4) + thisrowerr[0];
|
||||
if (val <= 0) val = 0; /* must watch for range overflow! */
|
||||
else {
|
||||
val += 8; /* divide by 16 with proper rounding */
|
||||
val >>= 4;
|
||||
if (val > MAXJSAMPLE) val = MAXJSAMPLE;
|
||||
}
|
||||
c0 = val;
|
||||
val = (GETJSAMPLE(*ptr1) << 4) + thisrowerr[1];
|
||||
if (val <= 0) val = 0; /* must watch for range overflow! */
|
||||
else {
|
||||
val += 8; /* divide by 16 with proper rounding */
|
||||
val >>= 4;
|
||||
if (val > MAXJSAMPLE) val = MAXJSAMPLE;
|
||||
}
|
||||
c1 = val;
|
||||
val = (GETJSAMPLE(*ptr2) << 4) + thisrowerr[2];
|
||||
if (val <= 0) val = 0; /* must watch for range overflow! */
|
||||
else {
|
||||
val += 8; /* divide by 16 with proper rounding */
|
||||
val >>= 4;
|
||||
if (val > MAXJSAMPLE) val = MAXJSAMPLE;
|
||||
}
|
||||
c2 = val;
|
||||
/* Index into the cache with adjusted value */
|
||||
/* For each component, get accumulated error and round to integer;
|
||||
* form pixel value + error, and range-limit to 0..MAXJSAMPLE.
|
||||
* RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
|
||||
* for either sign of the error value. Max error is +- MAXJSAMPLE.
|
||||
*/
|
||||
c0 = RIGHT_SHIFT(thisrowerr[0] + 8, 4);
|
||||
c1 = RIGHT_SHIFT(thisrowerr[1] + 8, 4);
|
||||
c2 = RIGHT_SHIFT(thisrowerr[2] + 8, 4);
|
||||
c0 += GETJSAMPLE(*ptr0);
|
||||
c1 += GETJSAMPLE(*ptr1);
|
||||
c2 += GETJSAMPLE(*ptr2);
|
||||
c0 = GETJSAMPLE(range_limit[c0]);
|
||||
c1 = GETJSAMPLE(range_limit[c1]);
|
||||
c2 = GETJSAMPLE(range_limit[c2]);
|
||||
/* Index into the cache with adjusted pixel value */
|
||||
cachep = & histogram[c0 >> Y_SHIFT][c1 >> C_SHIFT][c2 >> C_SHIFT];
|
||||
/* If we have not seen this color before, find nearest colormap */
|
||||
/* entry and update the cache */
|
||||
@@ -986,34 +984,34 @@ pass2_dither (decompress_info_ptr cinfo, int num_rows,
|
||||
pixcode = *cachep - 1;
|
||||
*outptr = (JSAMPLE) pixcode;
|
||||
/* Compute representation error for this pixel */
|
||||
c0 -= (FSERROR) GETJSAMPLE(my_colormap[0][pixcode]);
|
||||
c1 -= (FSERROR) GETJSAMPLE(my_colormap[1][pixcode]);
|
||||
c2 -= (FSERROR) GETJSAMPLE(my_colormap[2][pixcode]);
|
||||
c0 -= GETJSAMPLE(colormap0[pixcode]);
|
||||
c1 -= GETJSAMPLE(colormap1[pixcode]);
|
||||
c2 -= GETJSAMPLE(colormap2[pixcode]);
|
||||
/* Propagate error to adjacent pixels */
|
||||
/* Remember that nextrowerr entries are in reverse order! */
|
||||
val = c0 * 2;
|
||||
two_val = c0 * 2;
|
||||
nextrowerr[0-3] = c0; /* not +=, since not initialized yet */
|
||||
c0 += val; /* form error * 3 */
|
||||
c0 += two_val; /* form error * 3 */
|
||||
nextrowerr[0+3] += c0;
|
||||
c0 += val; /* form error * 5 */
|
||||
c0 += two_val; /* form error * 5 */
|
||||
nextrowerr[0 ] += c0;
|
||||
c0 += val; /* form error * 7 */
|
||||
c0 += two_val; /* form error * 7 */
|
||||
thisrowerr[0+3] += c0;
|
||||
val = c1 * 2;
|
||||
two_val = c1 * 2;
|
||||
nextrowerr[1-3] = c1; /* not +=, since not initialized yet */
|
||||
c1 += val; /* form error * 3 */
|
||||
c1 += two_val; /* form error * 3 */
|
||||
nextrowerr[1+3] += c1;
|
||||
c1 += val; /* form error * 5 */
|
||||
c1 += two_val; /* form error * 5 */
|
||||
nextrowerr[1 ] += c1;
|
||||
c1 += val; /* form error * 7 */
|
||||
c1 += two_val; /* form error * 7 */
|
||||
thisrowerr[1+3] += c1;
|
||||
val = c2 * 2;
|
||||
two_val = c2 * 2;
|
||||
nextrowerr[2-3] = c2; /* not +=, since not initialized yet */
|
||||
c2 += val; /* form error * 3 */
|
||||
c2 += two_val; /* form error * 3 */
|
||||
nextrowerr[2+3] += c2;
|
||||
c2 += val; /* form error * 5 */
|
||||
c2 += two_val; /* form error * 5 */
|
||||
nextrowerr[2 ] += c2;
|
||||
c2 += val; /* form error * 7 */
|
||||
c2 += two_val; /* form error * 7 */
|
||||
thisrowerr[2+3] += c2;
|
||||
/* Advance to next column */
|
||||
ptr0 += dir;
|
||||
|
||||
Reference in New Issue
Block a user