コード例 #1
0
ファイル: colorspaces.c プロジェクト: jonleighton/darktable
cmsHPROFILE
dt_colorspaces_create_xyzimatrix_profile(float mat[3][3])
{
  // mat: xyz -> cam
  float imat[3][3];
  mat3inv ((float *)imat, (float *)mat);
  return dt_colorspaces_create_xyzmatrix_profile(imat);
}
コード例 #2
0
ファイル: mat3.cpp プロジェクト: keesvp/OpenIL
int matpl2( mat3typ tr, rvec3typ pl )
{
  if ( !mat3inv( tr ) )
    return 0;
  return imatpl2( tr, pl );
}
コード例 #3
0
ファイル: colorspaces.c プロジェクト: jonleighton/darktable
static int
dt_colorspaces_get_matrix_from_profile (cmsHPROFILE prof, float *matrix, float *lutr, float *lutg, float* lutb, const int lutsize, const int input)
{
  // create an OpenCL processable matrix + tone curves from an cmsHPROFILE:

  // check this first:
  if(!cmsIsMatrixShaper(prof)) return 1;

  cmsToneCurve* red_curve   = cmsReadTag(prof, cmsSigRedTRCTag);
  cmsToneCurve* green_curve = cmsReadTag(prof, cmsSigGreenTRCTag);
  cmsToneCurve* blue_curve  = cmsReadTag(prof, cmsSigBlueTRCTag);

  cmsCIEXYZ *red_color   = cmsReadTag(prof, cmsSigRedColorantTag);
  cmsCIEXYZ *green_color = cmsReadTag(prof, cmsSigGreenColorantTag);
  cmsCIEXYZ *blue_color  = cmsReadTag(prof, cmsSigBlueColorantTag);

  if(!red_curve || !green_curve || !blue_curve || !red_color || !green_color || !blue_color) return 2;

  matrix[0] = red_color->X;
  matrix[1] = green_color->X;
  matrix[2] = blue_color->X;
  matrix[3] = red_color->Y;
  matrix[4] = green_color->Y;
  matrix[5] = blue_color->Y;
  matrix[6] = red_color->Z;
  matrix[7] = green_color->Z;
  matrix[8] = blue_color->Z;

  // some camera ICC profiles claim to have color locations for red, green and blue base colors defined, 
  // but in fact these are all set to zero. we catch this case here.
  float sum = 0.0f;
  for(int k=0; k<9; k++) sum += matrix[k];
  if(sum == 0.0f) return 3;

  if(input)
  {
    // mark as linear, if they are:
    if(cmsIsToneCurveLinear(red_curve))   lutr[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutr[k] = cmsEvalToneCurveFloat(red_curve,   k/(lutsize-1.0f));
    if(cmsIsToneCurveLinear(green_curve)) lutg[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutg[k] = cmsEvalToneCurveFloat(green_curve, k/(lutsize-1.0f));
    if(cmsIsToneCurveLinear(blue_curve))  lutb[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutb[k] = cmsEvalToneCurveFloat(blue_curve,  k/(lutsize-1.0f));
  }
  else
  {
    // invert profile->XYZ matrix for output profiles
    float tmp[9];
    memcpy(tmp, matrix, sizeof(float)*9);
    if(mat3inv (matrix, tmp)) return 3;
    // also need to reverse gamma, to apply reverse before matrix multiplication:
    cmsToneCurve* rev_red   = cmsReverseToneCurveEx(0x8000, red_curve);
    cmsToneCurve* rev_green = cmsReverseToneCurveEx(0x8000, green_curve);
    cmsToneCurve* rev_blue  = cmsReverseToneCurveEx(0x8000, blue_curve);
    if(!rev_red || !rev_green || !rev_blue)
    {
      cmsFreeToneCurve(rev_red);
      cmsFreeToneCurve(rev_green);
      cmsFreeToneCurve(rev_blue);
      return 4;
    }
    // pass on tonecurves, in case lutsize > 0:
    if(cmsIsToneCurveLinear(red_curve))   lutr[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutr[k] = cmsEvalToneCurveFloat(rev_red,   k/(lutsize-1.0f));
    if(cmsIsToneCurveLinear(green_curve)) lutg[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutg[k] = cmsEvalToneCurveFloat(rev_green, k/(lutsize-1.0f));
    if(cmsIsToneCurveLinear(blue_curve))  lutb[0] = -1.0f;
    else for(int k=0; k<lutsize; k++)     lutb[k] = cmsEvalToneCurveFloat(rev_blue,  k/(lutsize-1.0f));
    cmsFreeToneCurve(rev_red);
    cmsFreeToneCurve(rev_green);
    cmsFreeToneCurve(rev_blue);
  }
  return 0;
}
コード例 #4
0
ファイル: colorspaces.c プロジェクト: jonleighton/darktable
int
dt_colorspaces_get_darktable_matrix(const char *makermodel, float *matrix)
{
  dt_profiled_colormatrix_t *preset = NULL;
  for(int k=0; k<dt_profiled_colormatrix_cnt; k++)
  {
    if(!strcasecmp(makermodel, dt_profiled_colormatrices[k].makermodel))
    {
      preset = dt_profiled_colormatrices + k;
      break;
    }
  }
  if(!preset) return -1;

  const float wxyz = preset->white[0]+ preset->white[1]+ preset->white[2];
  const float rxyz = preset->rXYZ[0] + preset->rXYZ[1] + preset->rXYZ[2];
  const float gxyz = preset->gXYZ[0] + preset->gXYZ[1] + preset->gXYZ[2];
  const float bxyz = preset->bXYZ[0] + preset->bXYZ[1] + preset->bXYZ[2];

  const float xn = preset->white[0]/wxyz;
  const float yn = preset->white[1]/wxyz;
  const float xr = preset->rXYZ[0]/rxyz;
  const float yr = preset->rXYZ[1]/rxyz;
  const float xg = preset->gXYZ[0]/gxyz;
  const float yg = preset->gXYZ[1]/gxyz;
  const float xb = preset->bXYZ[0]/bxyz;
  const float yb = preset->bXYZ[1]/bxyz;

  const float primaries[9] = {xr,         xg,         xb,
                              yr,         yg,         yb,
                              1.0f-xr-yr, 1.0f-xg-yg, 1.0f-xb-yb
                             };

  float result[9];
  if(mat3inv(result, primaries)) return -1;

  const float whitepoint[3] = {xn/yn, 1.0f, (1.0f-xn-yn)/yn};
  float coeff[3];

  // get inverse primary whitepoint
  mat3mulv(coeff, result, whitepoint);


  float tmp[9] = { coeff[0]*xr,           coeff[1]*xg,           coeff[2]*xb,
                   coeff[0]*yr,           coeff[1]*yg,           coeff[2]*yb,
                   coeff[0]*(1.0f-xr-yr), coeff[1]*(1.0f-xg-yg), coeff[2]*(1.0f-xb-yb)
                 };

  // input whitepoint[] in XYZ with Y normalized to 1.0f
  const float dn[3] = { preset->white[0]/(float)preset->white[1], 1.0f, preset->white[2]/(float)preset->white[1]};
  const float lam_rigg[9] = { 0.8951,  0.2664, -0.1614,
                              -0.7502,  1.7135,  0.0367,
                              0.0389, -0.0685,  1.0296
                            };
  const float d50[3] = { 0.9642, 1.0, 0.8249 };


  // adapt to d50
  float chad_inv[9];
  if(mat3inv(chad_inv, lam_rigg)) return -1;

  float cone_src_rgb[3], cone_dst_rgb[3];
  mat3mulv(cone_src_rgb, lam_rigg, dn);
  mat3mulv(cone_dst_rgb, lam_rigg, d50);

  const float cone[9] = { cone_dst_rgb[0]/cone_src_rgb[0], 0.0f, 0.0f,
                          0.0f, cone_dst_rgb[1]/cone_src_rgb[1], 0.0f,
                          0.0f, 0.0f, cone_dst_rgb[2]/cone_src_rgb[2]
                        };

  float tmp2[9];
  float bradford[9];
  mat3mul(tmp2, cone, lam_rigg);
  mat3mul(bradford, chad_inv, tmp2);

  mat3mul(matrix, bradford, tmp);
  return 0;
}