The Independent JPEG Group's JPEG software v4

This commit is contained in:
Thomas G. Lane
1992-12-10 00:00:00 +00:00
committed by DRC
parent 4a6b730364
commit 88aeed428f
78 changed files with 4906 additions and 2527 deletions

View File

@@ -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;