On Wed, Nov 29, 2017 at 6:16 AM, Robert Bieber <[email protected]> wrote: > Hi all, Hi.
> I'm a newcomer to RawSpeed (and raw decoding in general, for that matter), > but I was hoping I might be able to port the Phase One sensor correction > functionality in dcraw to RawSpeed's IiqDecoder. > I think I've pretty well > figured out how the correction I'm concerned with works: the RAW file > includes four sets of control points (one for each quadrant of the image) > that define curves to apply to all the pixels in each respective quadrant > (this is to compensate for the fact that the "sensor" in these cameras is > actually four separate sensors being read at the same time, and they can > have slight variations). Sounds easy-ish. > The trickiest part for me right now, aside from making sure I get all the RS > conventions and formatting right (which I'm hoping I'll get hammered into me > in PR comments), is actually calculating the curves. dcraw does it with a > cubic spline function, but I can't find any comparable function looking > through the Doxygen for RS. I did find curve_tools.c/h in Darktable, which > looks promising. So, a couple questions: 0. https://github.com/darktable-org/darktable/blob/97e66ba84a2ce3c4d53027ebf7c81cc6302ff599/src/common/curve_tools.c#L5-L8 > darktable is free software: you can redistribute it and/or modify > it under the terms of the GNU General Public License as published by > the Free Software Foundation, either version 3 of the License, or > (at your option) any later version. and RawSpeed is LGPL2. so that not is even an option. > 1. Will any of those curve_tools functions in DT do what the cubic_spline > function in dcraw (reproduced below for reference) does? I'm not really > familiar with calculating curves, but I'm a bit worried that it seems like > they're all geared towards interpolating a single point on a curve, which > I'm assuming would be very slow compared to the approach dcraw takes of > calculating all the points on the curve and then just doing a lookup for > each pixel. Let's not do premature optimizations :) Implement the most dumbest/simplest variant, that is actually readable, then i'll add tests and a benchmark; and *then* a specialized, faster implementation *may* be added. > 2. Assuming one of those is useful, how should I go about reusing it in RS? > Should I just copy/paste it? I could always make it a public function in > RawSpeed and then use it from DT, but it seems like it would be odd to have > a single utility function like that call out to the raw decoding library. > My intuition is it's probably just okay to have them live in both places, > but I'm open to suggestions. Just add a new one into rawspeed. > Thanks, > Robby Roman. > dcraw's cubic_spline implementation follows: > ----------------------------------- > > > void CLASS cubic_spline (const int *x_, const int *y_, const int len) > { > float **A, *b, *c, *d, *x, *y; > int i, j; > > A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); > if (!A) return; > A[0] = (float *) (A + 2*len); > for (i = 1; i < 2*len; i++) > A[i] = A[0] + 2*len*i; > y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); > for (i = 0; i < len; i++) { > x[i] = x_[i] / 65535.0; > y[i] = y_[i] / 65535.0; > } > for (i = len-1; i > 0; i--) { > b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); > d[i-1] = x[i] - x[i-1]; > } > for (i = 1; i < len-1; i++) { > A[i][i] = 2 * (d[i-1] + d[i]); > if (i > 1) { > A[i][i-1] = d[i-1]; > A[i-1][i] = d[i-1]; > } > A[i][len-1] = 6 * (b[i+1] - b[i]); > } > for(i = 1; i < len-2; i++) { > float v = A[i+1][i] / A[i][i]; > for(j = 1; j <= len-1; j++) > A[i+1][j] -= v * A[i][j]; > } > for(i = len-2; i > 0; i--) { > float acc = 0; > for(j = i; j <= len-2; j++) > acc += A[i][j]*c[j]; > c[i] = (A[i][len-1] - acc) / A[i][i]; > } > for (i = 0; i < 0x10000; i++) { > float x_out = (float)(i / 65535.0); > float y_out = 0; > for (j = 0; j < len-1; j++) { > if (x[j] <= x_out && x_out <= x[j+1]) { > float v = x_out - x[j]; > y_out = y[j] + > ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v > + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; > } > } > curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : > (ushort)(y_out * 65535.0 + 0.5)); > } > free (A); > } > > > ___________________________________________________________________________ > darktable developer mailing list > to unsubscribe send a mail to [email protected] > ___________________________________________________________________________ darktable developer mailing list to unsubscribe send a mail to [email protected]
