📄 gd_topal.c
字号:
* for the nearest entry to some cell in the update box. */#ifdef ORIGINAL_LIB_JPEG numcolors = find_nearby_colors (cinfo, minc0, minc1, minc2, colorlist); /* Determine the actually nearest colors. */ find_best_colors (cinfo, minc0, minc1, minc2, numcolors, colorlist, bestcolor);#else numcolors = find_nearby_colors (oim, nim, cquantize, minc0, minc1, minc2, colorlist); find_best_colors (oim, nim, cquantize, minc0, minc1, minc2, numcolors, colorlist, bestcolor);#endif /* Save the best color numbers (plus 1) in the main cache array */ c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */ c1 <<= BOX_C1_LOG; c2 <<= BOX_C2_LOG; cptr = bestcolor; for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) { for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) { cachep = &histogram[c0 + ic0][c1 + ic1][c2]; for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {#ifdef ORIGINAL_LIB_JPEG *cachep++ = (histcell) (GETJSAMPLE (*cptr++) + 1);#else *cachep++ = (histcell) ((*cptr++) + 1);#endif } } }}/* * Map some rows of pixels to the output colormapped representation. */METHODDEF (void)#ifndef ORIGINAL_LIB_JPEGpass2_no_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize){ register int *inptr; register unsigned char *outptr; int width = oim->sx; int num_rows = oim->sy;#elsepass2_no_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)/* This version performs no dithering */{ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; register JSAMPROW inptr, outptr; JDIMENSION width = cinfo->output_width;#endif hist3d histogram = cquantize->histogram; register int c0, c1, c2; int row; JDIMENSION col; register histptr cachep; for (row = 0; row < num_rows; row++) { inptr = input_buf[row]; outptr = output_buf[row]; for (col = width; col > 0; col--) { /* get pixel value and index into the cache */ int r, g, b;#ifdef ORIGINAL_LIB_JPEG r = GETJSAMPLE (*inptr++); g = GETJSAMPLE (*inptr++); b = GETJSAMPLE (*inptr++);#else r = gdTrueColorGetRed (*inptr); g = gdTrueColorGetGreen (*inptr); /* 2.0.24: inptr must not be incremented until after transparency check, if any. Thanks to "Super Pikeman." */ b = gdTrueColorGetBlue (*inptr); /* If the pixel is transparent, we assign it the palette index that * will later be added at the end of the palette as the transparent * index. */ if ((oim->transparent >= 0) && (oim->transparent == *inptr)) { *outptr++ = nim->colorsTotal; inptr++; continue; } inptr++;#endif c0 = r >> C0_SHIFT; c1 = g >> C1_SHIFT; c2 = b >> C2_SHIFT; cachep = &histogram[c0][c1][c2]; /* If we have not seen this color before, find nearest colormap entry */ /* and update the cache */ if (*cachep == 0)#ifdef ORIGINAL_LIB_JPEG fill_inverse_cmap (cinfo, c0, c1, c2);#else fill_inverse_cmap (oim, nim, cquantize, c0, c1, c2);#endif /* Now emit the colormap index for this cell */#ifdef ORIGINAL_LIB_JPEG *outptr++ = (JSAMPLE) (*cachep - 1);#else *outptr++ = (*cachep - 1);#endif } }}METHODDEF (void)#ifndef ORIGINAL_LIB_JPEGpass2_fs_dither (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize){#elsepass2_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)/* This version performs Floyd-Steinberg dithering */{ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; JSAMPROW inptr; /* => current input pixel */#endif hist3d histogram = cquantize->histogram; register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */ LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */ register FSERRPTR errorptr; /* => fserrors[] at column before current */ histptr cachep; int dir; /* +1 or -1 depending on direction */ int dir3; /* 3*dir, for advancing inptr & errorptr */ int row; JDIMENSION col;#ifdef ORIGINAL_LIB_JPEG JSAMPROW outptr; /* => current output pixel */ JDIMENSION width = cinfo->output_width; JSAMPLE *range_limit = cinfo->sample_range_limit; JSAMPROW colormap0 = cinfo->colormap[0]; JSAMPROW colormap1 = cinfo->colormap[1]; JSAMPROW colormap2 = cinfo->colormap[2];#else int *inptr; /* => current input pixel */ unsigned char *outptr; /* => current output pixel */ int width = oim->sx; int num_rows = oim->sy; int *colormap0 = nim->red; int *colormap1 = nim->green; int *colormap2 = nim->blue;#endif int *error_limit = cquantize->error_limiter; SHIFT_TEMPS for (row = 0; row < num_rows; row++) { inptr = input_buf[row]; outptr = output_buf[row]; if (cquantize->on_odd_row) { /* work right to left in this row */ inptr += (width - 1) * 3; /* so point to rightmost pixel */ outptr += width - 1; dir = -1; dir3 = -3; errorptr = cquantize->fserrors + (width + 1) * 3; /* => entry after last column */#ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS cquantize->on_odd_row = FALSE; /* flip for next time */#endif } else { /* work left to right in this row */ dir = 1; dir3 = 3; errorptr = cquantize->fserrors; /* => entry before first real column */#ifdef ORIGINAL_LIB_JPEG_REVERSE_ODD_ROWS cquantize->on_odd_row = TRUE; /* flip for next time */#endif } /* Preset error values: no error propagated to first pixel from left */ cur0 = cur1 = cur2 = 0; /* and no error propagated to row below yet */ belowerr0 = belowerr1 = belowerr2 = 0; bpreverr0 = bpreverr1 = bpreverr2 = 0; for (col = width; col > 0; col--) { /* If this pixel is transparent, we want to assign it to the special * transparency color index past the end of the palette rather than * go through matching / dithering. */ if ((oim->transparent >= 0) && (*inptr == oim->transparent)) { *outptr = nim->colorsTotal; errorptr[0] = 0; errorptr[1] = 0; errorptr[2] = 0; errorptr[3] = 0; inptr += dir; outptr += dir; errorptr += dir3; continue; } /* curN holds the error propagated from the previous pixel on the * current line. Add the error propagated from the previous line * to form the complete error correction term for this pixel, and * round the error term (which is expressed * 16) to an integer. * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct * for either sign of the error value. * Note: errorptr points to *previous* column's array entry. */ cur0 = RIGHT_SHIFT (cur0 + errorptr[dir3 + 0] + 8, 4); cur1 = RIGHT_SHIFT (cur1 + errorptr[dir3 + 1] + 8, 4); cur2 = RIGHT_SHIFT (cur2 + errorptr[dir3 + 2] + 8, 4); /* Limit the error using transfer function set by init_error_limit. * See comments with init_error_limit for rationale. */ cur0 = error_limit[cur0]; cur1 = error_limit[cur1]; cur2 = error_limit[cur2]; /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE. * The maximum error is +- MAXJSAMPLE (or less with error limiting); * this sets the required size of the range_limit array. */#ifdef ORIGINAL_LIB_JPEG cur0 += GETJSAMPLE (inptr[0]); cur1 += GETJSAMPLE (inptr[1]); cur2 += GETJSAMPLE (inptr[2]); cur0 = GETJSAMPLE (range_limit[cur0]); cur1 = GETJSAMPLE (range_limit[cur1]); cur2 = GETJSAMPLE (range_limit[cur2]);#else cur0 += gdTrueColorGetRed (*inptr); cur1 += gdTrueColorGetGreen (*inptr); cur2 += gdTrueColorGetBlue (*inptr); range_limit (cur0); range_limit (cur1); range_limit (cur2);#endif /* Index into the cache with adjusted pixel value */ cachep = &histogram[cur0 >> C0_SHIFT][cur1 >> C1_SHIFT][cur2 >> C2_SHIFT]; /* If we have not seen this color before, find nearest colormap */ /* entry and update the cache */ if (*cachep == 0)#ifdef ORIGINAL_LIB_JPEG fill_inverse_cmap (cinfo, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);#else fill_inverse_cmap (oim, nim, cquantize, cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);#endif /* Now emit the colormap index for this cell */ { register int pixcode = *cachep - 1; *outptr = (JSAMPLE) pixcode; /* Compute representation error for this pixel */#define GETJSAMPLE cur0 -= GETJSAMPLE (colormap0[pixcode]); cur1 -= GETJSAMPLE (colormap1[pixcode]); cur2 -= GETJSAMPLE (colormap2[pixcode]);#undef GETJSAMPLE } /* Compute error fractions to be propagated to adjacent pixels. * Add these into the running sums, and simultaneously shift the * next-line error sums left by 1 column. */ { register LOCFSERROR bnexterr, delta; bnexterr = cur0; /* Process component 0 */ delta = cur0 * 2; cur0 += delta; /* form error * 3 */ errorptr[0] = (FSERROR) (bpreverr0 + cur0); cur0 += delta; /* form error * 5 */ bpreverr0 = belowerr0 + cur0; belowerr0 = bnexterr; cur0 += delta; /* form error * 7 */ bnexterr = cur1; /* Process component 1 */ delta = cur1 * 2; cur1 += delta; /* form error * 3 */ errorptr[1] = (FSERROR) (bpreverr1 + cur1); cur1 += delta; /* form error * 5 */ bpreverr1 = belowerr1 + cur1; belowerr1 = bnexterr; cur1 += delta; /* form error * 7 */ bnexterr = cur2; /* Process component 2 */ delta = cur2 * 2; cur2 += delta; /* form error * 3 */ errorptr[2] = (FSERROR) (bpreverr2 + cur2); cur2 += delta; /* form error * 5 */ bpreverr2 = belowerr2 + cur2; belowerr2 = bnexterr; cur2 += delta; /* form error * 7 */ } /* At this point curN contains the 7/16 error value to be propagated * to the next pixel on the current line, and all the errors for the * next line have been shifted over. We are therefore ready to move on. */#ifdef ORIGINAL_LIB_JPEG inptr += dir3; /* Advance pixel pointers to next column */#else inptr += dir; /* Advance pixel pointers to next column */#endif outptr += dir; errorptr += dir3; /* advance errorptr to current column */ } /* Post-loop cleanup: we must unload the final error values into the * final fserrors[] entry. Note we need not unload belowerrN because * it is for the dummy column before or after the actual array. */ errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */ errorptr[1] = (FSERROR) bpreverr1; errorptr[2] = (FSERROR) bpreverr2; }}/* * Initialize the error-limiting transfer function (lookup table). * The raw F-S error computation can potentially compute error values of up to * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be * much less, otherwise obviously wrong pixels will be created. (Typical * effects include weird fringes at color-area boundaries, isolated bright * pixels in a dark area, etc.) The standard advice for avoiding this problem * is to ensure that the "corners" of the color cube are allocated as output * colors; then repeated errors in the same direction cannot cause cascading * error buildup. However, that only prevents the error from getting * completely out of hand; Aaron Giles reports that error limiting improves * the results even with corner colors allocated. * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty * well, but the smoother transfer function used below is even better. Thanks * to Aaron Giles for this idea. */LOCAL (void)#ifdef ORIGINAL_LIB_JPEGinit_error_limit (j_decompress_ptr cinfo)#elseinit_error_limit (gdImagePtr oim, gdImagePtr nim, my_cquantize_ptr cquantize)#endif/* Allocate and fill in the error_limiter table */{ int *table; int in, out;#ifdef ORIGINAL_LIB_JPEG my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; table = (int *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE * 2 + 1) * SIZEOF (int));#else cquantize->error_limiter_storage = (int *) gdMalloc ((MAXJSAMPLE * 2 + 1) * sizeof (int)); if (!cquantize->error_limiter_storage) { return; } table = cquantize->error_limiter_storage;#endif table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */ cquantize->error_limiter = table;#define STEPSIZE ((MAXJSAMPLE+1)/16) /* Map errors 1:1 up to +- MAXJSAMPLE/16 */ out = 0; for (in = 0; in < STEPSIZE; in++, out++) { table[in] = out; table[-in] = -out; } /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */ for (; in < STEPSIZE * 3; in++, out += (in & 1) ? 0 : 1) { table[in] = out; table[-in] = -out; } /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */ for (; in <= MAXJSAMPLE; in++) { table[in] = out; table[-in] = -out; }#undef STEPSIZE}/* * Finish up at the end of each pass. */#ifdef ORIGINAL_LIB_JPEGMETHODDEF (void)finish_pass1 (j_decompress_ptr cinfo){ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize; /* Select the representative colors and fill in cinfo->colormap */ cinfo->colormap = cquantize->sv_colormap; select_colors (cinfo, cquantize->desired); /* Force next pass to zero the color index table */ cquantize->needs_zeroed = TRUE;}METHODDEF (void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -