# HG changeset patch # User alex@thinkpad # Date 1386872697 -7200 # Node ID ab68b0fa190193b7c1bfcd2119352ae779428a3e # Parent 518491f4fa3046733ec1f095dff8ce9b12cd3904 Small highlight fix for negative EV with restore==clip Vanilla ufraw alters some perfectly exposed pixels - they get converged to gray to prepare for highlight recovery; obviously, if you don't use HR, this alteration is not needed and does more harm than good. If there's nothing clipped in the raw file, you should be able to get 100% unclipped output (well, with some amount of negative exposure, or with the new soft film option) diff -r 518491f4fa30 -r ab68b0fa1901 ufraw_developer.c --- a/ufraw_developer.c Thu Dec 12 20:21:38 2013 +0200 +++ b/ufraw_developer.c Thu Dec 12 20:24:57 2013 +0200 @@ -853,7 +853,8 @@ { unsigned c; gint64 tmppix[4]; - gboolean clipped = FALSE; + gboolean clipped = FALSE; /* clipped after RGB multipliers */ + gboolean clipped_in_raw = FALSE; /* clipped in the raw file */ unsigned exposure = d->exposure; if (d->clipHighlights == film_highlights) { @@ -869,7 +870,16 @@ tmppix[c] /= 0x10000; if (d->restoreDetails != clip_details && tmppix[c] > d->max) { + /* will attempt to do highlight recovery */ + /* note that ufraw's highlight recovery will sacrifice some well-exposed pixels by converging them to gray */ + /* (those "clipped" after applying WB, but not clipped in the original raw file) */ + /* this helps simplifying the highlight recovery algorithm, as there's no more need to propagate the colors from nearby pixels */ clipped = TRUE; + } else if (exposure < d->max) { + /* negative exposure compensation, clip highlights */ + /* only clip whatever is clipped in the original raw file, and nothing more */ + if (in[c] > d->rgbMax) + clipped_in_raw = TRUE; } else { tmppix[c] = MIN(tmppix[c], d->max); } @@ -936,6 +946,10 @@ tmppix[minc] = lum * (0x10000 - sat) / 0x10000; tmppix[midc] = lum * (0x10000 - sat + sat * hue / 0x10000) / 0x10000; } + } else if (clipped_in_raw) { + /* just set this pixel to white or neutral gray */ + for (c = 0; c < d->colors; c++) + tmppix[c] = exposure; } else { /* !clipped */ if (d->useMatrix) apply_matrix(d, tmppix, tmppix);