Hi all,

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).

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:

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.

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.

Thanks,
Robby

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 darktable-dev+unsubscr...@lists.darktable.org

Reply via email to