X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/8ebac85f46199cb0e1ce01ae60a8db6894bf9fbb..debe370bf1907100f0de258a7ee74bf28c6bc103:/filters.im diff --git a/filters.im b/filters.im index 918963ec..e247c9cc 100644 --- a/filters.im +++ b/filters.im @@ -414,7 +414,6 @@ i_bumpmap_complex(i_img *im, i_color *Is) { i_img new_im; - int inflight; i_img_dim x, y; int ch; i_img_dim mx, Mx, my, My; @@ -462,7 +461,6 @@ i_bumpmap_complex(i_img *im, L.z = -Lz; normalize(&L); } else { /* Light is the position of the light source */ - inflight = 0; L.x = -0.2; L.y = -0.4; L.z = 1; @@ -650,6 +648,102 @@ i_watermark(i_img *im, i_img *wmark, i_img_dim tx, i_img_dim ty, int pixdiff) { } } +/* +=item i_autolevels_mono(im, lsat, usat) + +Do autolevels, but monochromatically. + +=cut +*/ + +void +i_autolevels_mono(i_img *im, float lsat, float usat) { + i_color val; + i_img_dim i, x, y, hist[256]; + i_img_dim sum_lum, min_lum, max_lum; + i_img_dim upper_accum, lower_accum; + i_color *row; + dIMCTXim(im); + int adapt_channels = im->channels == 4 ? 2 : 1; + int color_channels = i_img_color_channels(im); + i_img_dim color_samples = im->xsize * color_channels; + + + im_log((aIMCTX, 1,"i_autolevels_mono(im %p, lsat %f,usat %f)\n", im, lsat,usat)); + + /* build the histogram in 8-bits, unless the image has a very small + range it should make little difference to the result */ + sum_lum = 0; + for (i = 0; i < 256; i++) + hist[i] = 0; + + row = mymalloc(im->xsize * sizeof(i_color)); + /* create histogram for each channel */ + for (y = 0; y < im->ysize; y++) { + i_color *p = row; + i_glin(im, 0, im->xsize, y, row); + if (im->channels > 2) + i_adapt_colors(adapt_channels, im->channels, row, im->xsize); + for (x = 0; x < im->xsize; x++) { + hist[p->channel[0]]++; + ++p; + } + } + myfree(row); + + for(i = 0; i < 256; i++) { + sum_lum += hist[i]; + } + + min_lum = 0; + lower_accum = 0; + for (i = 0; i < 256; ++i) { + if (lower_accum < sum_lum * lsat) + min_lum = i; + lower_accum += hist[i]; + } + + max_lum = 255; + upper_accum = 0; + for(i = 255; i >= 0; i--) { + if (upper_accum < sum_lum * usat) + max_lum = i; + upper_accum += hist[i]; + } + +#code im->bits <= 8 + IM_SAMPLE_T *srow = mymalloc(color_samples * sizeof(IM_SAMPLE_T)); +#ifdef IM_EIGHT_BIT + IM_WORK_T low = min_lum; + i_sample_t lookup[256]; +#else + IM_WORK_T low = min_lum / 255.0 * IM_SAMPLE_MAX; +#endif + double scale = 255.0 / (max_lum - min_lum); + +#ifdef IM_EIGHT_BIT + for (i = 0; i < 256; ++i) { + IM_WORK_T tmp = (i - low) * scale; + lookup[i] = IM_LIMIT(tmp); + } +#endif + + for(y = 0; y < im->ysize; y++) { + IM_GSAMP(im, 0, im->xsize, y, srow, NULL, color_channels); + for(i = 0; i < color_samples; ++i) { +#ifdef IM_EIGHT_BIT + srow[i] = lookup[srow[i]]; +#else + IM_WORK_T tmp = (srow[i] - low) * scale; + srow[i] = IM_LIMIT(tmp); +#endif + } + IM_PSAMP(im, 0, im->xsize, y, srow, NULL, color_channels); + } + myfree(srow); +#/code +} + /* =item i_autolevels(im, lsat, usat, skew) @@ -663,6 +757,9 @@ occur when changing the contrast. usat - fraction of pixels that will be truncated at the higher end of the spectrum skew - not used yet +Note: this code calculates levels and adjusts each channel separately, +which will typically cause a color shift. + =cut */ @@ -1236,6 +1333,10 @@ i_nearest_color(i_img *im, int num, i_img_dim *xo, i_img_dim *yo, i_color *oval, i_nearest_color_foo(im, num, xo, yo, ival, dmeasure); + myfree(cmatch); + myfree(ival); + myfree(tval); + return 1; } @@ -1650,7 +1751,6 @@ i_fountain(i_img *im, double xa, double ya, double xb, double yb, i_fcolor *line = NULL; i_fcolor *work = NULL; size_t line_bytes; - i_fountain_seg *my_segs; i_fill_combine_f combine_func = NULL; i_fill_combinef_f combinef_func = NULL; dIMCTXim(im); @@ -1673,7 +1773,6 @@ i_fountain(i_img *im, double xa, double ya, double xb, double yb, fount_init_state(&state, xa, ya, xb, yb, type, repeat, combine, super_sample, ssample_param, count, segs); - my_segs = state.segs; for (y = 0; y < im->ysize; ++y) { i_glinf(im, 0, im->xsize, y, line); @@ -2358,8 +2457,9 @@ fill_fountf(i_fill_t *fill, i_img_dim x, i_img_dim y, i_img_dim width, got_one = f->state.ssfunc(&c, x, y, &f->state); else got_one = fount_getat(&c, x, y, &f->state); - - *data++ = c; + + if (got_one) + *data++ = c; ++x; }