QVector <double> LcmsColorProfileContainer::getColorantsxyY() const { cmsCIEXYZ temp1; cmsCIExyY temp2; QVector <double> colorants(9); temp1.X = d->colorants.Red.X; temp1.Y = d->colorants.Red.Y; temp1.Z = d->colorants.Red.Z; cmsXYZ2xyY(&temp2, &temp1); colorants[0] = temp2.x; colorants[1] = temp2.y; colorants[2] = temp2.Y; temp1.X = d->colorants.Green.X; temp1.Y = d->colorants.Green.Y; temp1.Z = d->colorants.Green.Z; cmsXYZ2xyY(&temp2, &temp1); colorants[3] = temp2.x; colorants[4] = temp2.y; colorants[5] = temp2.Y; temp1.X = d->colorants.Blue.X; temp1.Y = d->colorants.Blue.Y; temp1.Z = d->colorants.Blue.Z; cmsXYZ2xyY(&temp2, &temp1); colorants[6] = temp2.x; colorants[7] = temp2.y; colorants[8] = temp2.Y; return colorants; }
// Approximate a blackbody illuminant based on CHAD information static cmsFloat64Number CHAD2Temp(const cmsMAT3* Chad) { // Convert D50 across inverse CHAD to get the absolute white point cmsVEC3 d, s; cmsCIEXYZ Dest; cmsCIExyY DestChromaticity; cmsFloat64Number TempK; cmsMAT3 m1, m2; m1 = *Chad; if (!_cmsMAT3inverse(&m1, &m2)) return FALSE; s.n[VX] = cmsD50_XYZ() -> X; s.n[VY] = cmsD50_XYZ() -> Y; s.n[VZ] = cmsD50_XYZ() -> Z; _cmsMAT3eval(&d, &m2, &s); Dest.X = d.n[VX]; Dest.Y = d.n[VY]; Dest.Z = d.n[VZ]; cmsXYZ2xyY(&DestChromaticity, &Dest); if (!cmsTempFromWhitePoint(&TempK, &DestChromaticity)) return -1.0; return TempK; }
LCMSAPI LPcmsCIExyY LCMSEXPORT cmsD50_xyY(void) { static cmsCIExyY D50xyY; cmsXYZ2xyY(&D50xyY, cmsD50_XYZ()); return &D50xyY; }
const cmsCIExyY* CMSEXPORT cmsD50_xyY(void) { static cmsCIExyY D50xyY; cmsXYZ2xyY(&D50xyY, cmsD50_XYZ()); return &D50xyY; }
static KoCIExyY RGB2xyY(cmsHPROFILE RGBProfile, qreal red, qreal green, qreal blue) { cmsHPROFILE XYZProfile = cmsCreateXYZProfile(); const cmsUInt32Number inputFormat = TYPE_RGB_DBL; const cmsUInt32Number outputFormat = TYPE_XYZ_DBL; const cmsUInt32Number transformFlags = cmsFLAGS_LOWRESPRECALC; cmsHTRANSFORM transform = cmsCreateTransform(RGBProfile, inputFormat, XYZProfile, outputFormat, INTENT_ABSOLUTE_COLORIMETRIC, transformFlags); struct XYZPixel { qreal X; qreal Y; qreal Z; }; struct RGBPixel { qreal red; qreal green; qreal blue; }; XYZPixel xyzPixel; RGBPixel rgbPixel; rgbPixel.red = red; rgbPixel.green = green; rgbPixel.blue = blue; const unsigned int numPixelsToTransform = 1; cmsDoTransform(transform, &rgbPixel, &xyzPixel, numPixelsToTransform); cmsCIEXYZ xyzPixelXYZ; xyzPixelXYZ.X = xyzPixel.X; xyzPixelXYZ.Y = xyzPixel.Y; xyzPixelXYZ.Z = xyzPixel.Z; cmsCIExyY xyzPixelxyY; cmsXYZ2xyY(&xyzPixelxyY, &xyzPixelXYZ); cmsDeleteTransform(transform); cmsCloseProfile(XYZProfile); KoCIExyY res; lcmsToPigmentViceVersaStructureCopy(res, xyzPixelxyY); return res; }
static void CreatePrimaryMatrices(LPMONITORPROFILERDATA sys) { cmsCIExyY White; MAT3 tmp; cmsXYZ2xyY(&White, &sys->hdr.WhitePoint); cmsBuildRGB2XYZtransferMatrix(&sys -> PrimariesMatrix, &White, &sys->hdr.Primaries); CopyMemory(&tmp, &sys -> PrimariesMatrix, sizeof(MAT3)); MAT3inverse(&tmp, &sys->PrimariesMatrixRev); }
static void init(void) { cmsCIEXYZ D65_XYZ = {0.95047, 1.0, 1.08883 }; cmsCIExyY D65; cmsXYZ2xyY(&D65, &D65_XYZ); cmsToneCurve *linear = cmsBuildGamma(NULL, 1.0); cmsToneCurve *linrgb[3] = {linear,linear,linear}; cmsCIExyYTRIPLE primaries = { {0.64, 0.33, 1.0}, {0.30, 0.60, 1.0}, {0.15, 0.06, 1.0} }; cmsFloat64Number P[5] = { 2.4, 1. / 1.055, 0.055 / 1.055, 1. / 12.92, 0.04045 }; cmsToneCurve *srgb = cmsBuildParametricToneCurve(NULL, 4, P); cmsToneCurve *srgbcurve[3] = {srgb,srgb,srgb}; cmsHPROFILE hsRGB = cmsCreateRGBProfile(&D65, &primaries, srgbcurve); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); cmsHPROFILE hlRGB = cmsCreateRGBProfile(&D65, &primaries, linrgb); cmsHPROFILE hlGray = cmsCreateGrayProfile(cmsD50_xyY(), linear); cmsSetHeaderFlags(hlGray, cmsEmbeddedProfileTrue); cmsSaveProfileToFile(hlGray,"lgray.icc"); cmsSetHeaderFlags(hlRGB, cmsEmbeddedProfileTrue); cmsSaveProfileToFile(hlRGB,"lrgb.icc"); xform_srgb_to_lrgb = cmsCreateTransform(hsRGB, TYPE_RGB_DBL, hlRGB, TYPE_RGB_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE /* preserve precision */ ); xform_srgb_to_lab = cmsCreateTransform(hsRGB, TYPE_RGB_DBL, hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); xform_srgb_to_lgray = cmsCreateTransform(hsRGB, TYPE_RGB_DBL, hlGray, TYPE_GRAY_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); cmsCloseProfile(hsRGB); cmsCloseProfile(hlRGB); cmsCloseProfile(hLab); cmsCloseProfile(hlGray); cmsFreeToneCurve(linear); cmsFreeToneCurve(srgb); cmsSetLogErrorHandler(errlog); /* sRGB, RGB, Lab, Gray */ printf("R',G',B',R,G,B,L,a,b,Gray\n"); }
void _cmsIdentifyWhitePoint(char *Buffer, LPcmsCIEXYZ WhitePt) { int i, n; cmsCIExyY Val; double T; WHITEPOINTS SomeIlluminants[140] = { {"CIE illuminant A", {0.4476, 0.4074, 1.0}}, {"CIE illuminant C", {0.3101, 0.3162, 1.0}}, {"D65 (daylight)", {0.3127, 0.3291, 1.0}}, }; n = FromD40toD150(&SomeIlluminants[3]) + 3; cmsXYZ2xyY(&Val, WhitePt); Val.Y = 1.; for (i=0; i < n; i++) { if (InRange(&Val, &SomeIlluminants[i].Val, 0.000005)) { strcpy(Buffer, "WhitePoint : "); strcat(Buffer, SomeIlluminants[i].Name); return; } } T = Robertson(&Val); if (T > 0) sprintf(Buffer, "White point near %dK", (int) T); else { sprintf(Buffer, "Unknown white point (X:%1.2g, Y:%1.2g, Z:%1.2g)", WhitePt -> X, WhitePt -> Y, WhitePt -> Z); } }
static BOOL ComputePrimary(LPMEASUREMENT Linearized, LPGAMMATABLE TransferCurves[3], int n, LPcmsCIExyY Primary) { double Ones[3], lmax[3]; cmsCIEXYZ PrimXYZ; SETOFPATCHES SetPrimary; int nR; /* At first, try to see if primaries are already in measurement */ SetPrimary = cmsxPCollBuildSet(Linearized, false); nR = cmsxPCollPatchesNearPrimary(Linearized, Linearized->Allowed, n, 32, SetPrimary); Ones[0] = Ones[1] = Ones[2] = 0; Ones[n] = 255.0; cmsxApplyLinearizationTable(Ones, TransferCurves, lmax); /* Do incremental regression to find primaries */ if (!cmsxRegressionInterpolatorRGB(Linearized, PT_XYZ, 4, false, 12, lmax[0], lmax[1], lmax[2], &PrimXYZ)) return false; _cmsxClampXYZ100(&PrimXYZ); cmsXYZ2xyY(Primary, &PrimXYZ); return true; }
void dkCmsXYZ2xyY(LPcmsCIExyY Dest, const cmsCIEXYZ* const Source) { cmsXYZ2xyY(static_cast<cmsCIExyY*>(Dest), Source); }
bool LcmsColorProfileContainer::init() { if (d->profile) { cmsCloseProfile(d->profile); } d->profile = cmsOpenProfileFromMem((void *)d->data->rawData().constData(), d->data->rawData().size()); #ifndef NDEBUG if (d->data->rawData().size() == 4096) { qWarning() << "Profile has a size of 4096, which is suspicious and indicates a possible misuse of QIODevice::read(int), check your code."; } #endif if (d->profile) { wchar_t buffer[_BUFFER_SIZE_]; d->colorSpaceSignature = cmsGetColorSpace(d->profile); d->deviceClass = cmsGetDeviceClass(d->profile); cmsGetProfileInfo(d->profile, cmsInfoDescription, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_); d->name = QString::fromWCharArray(buffer); //apparantly this should give us a localised string??? Not sure about this. cmsGetProfileInfo(d->profile, cmsInfoModel, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_); d->productDescription = QString::fromWCharArray(buffer); cmsGetProfileInfo(d->profile, cmsInfoManufacturer, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_); d->manufacturer = QString::fromWCharArray(buffer); cmsGetProfileInfo(d->profile, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, buffer, _BUFFER_SIZE_); d->copyright = QString::fromWCharArray(buffer); cmsProfileClassSignature profile_class; profile_class = cmsGetDeviceClass(d->profile); d->valid = (profile_class != cmsSigNamedColorClass); //This is where obtain the whitepoint, and convert it to the actual white point of the profile in the case a Chromatic adaption tag is //present. This is necessary for profiles following the v4 spec. cmsCIEXYZ baseMediaWhitePoint;//dummy to hold copy of mediawhitepoint if this is modified by chromatic adaption. if (cmsIsTag(d->profile, cmsSigMediaWhitePointTag)) { d->mediaWhitePoint = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigMediaWhitePointTag)); baseMediaWhitePoint = d->mediaWhitePoint; cmsXYZ2xyY(&d->whitePoint, &d->mediaWhitePoint); if (cmsIsTag(d->profile, cmsSigChromaticAdaptationTag)) { //the chromatic adaption tag represent a matrix from the actual white point of the profile to D50. cmsCIEXYZ *CAM1 = (cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigChromaticAdaptationTag); //We first put all our data into structures we can manipulate. double d3dummy [3] = {d->mediaWhitePoint.X, d->mediaWhitePoint.Y, d->mediaWhitePoint.Z}; QGenericMatrix<1, 3, double> whitePointMatrix(d3dummy); QTransform invertDummy(CAM1[0].X, CAM1[0].Y, CAM1[0].Z, CAM1[1].X, CAM1[1].Y, CAM1[1].Z, CAM1[2].X, CAM1[2].Y, CAM1[2].Z); //we then abuse QTransform's invert function because it probably does matrix invertion 20 times better than I can program. //if the matrix is uninvertable, invertedDummy will be an identity matrix, which for us means that it won't give any noticeble //effect when we start multiplying. QTransform invertedDummy = invertDummy.inverted(); //we then put the QTransform into a generic 3x3 matrix. double d9dummy [9] = {invertedDummy.m11(), invertedDummy.m12(), invertedDummy.m13(), invertedDummy.m21(), invertedDummy.m22(), invertedDummy.m23(), invertedDummy.m31(), invertedDummy.m32(), invertedDummy.m33() }; QGenericMatrix<3, 3, double> chromaticAdaptionMatrix(d9dummy); //multiplying our inverted adaption matrix with the whitepoint gives us the right whitepoint. QGenericMatrix<1, 3, double> result = chromaticAdaptionMatrix * whitePointMatrix; //and then we pour the matrix into the whitepoint variable. Generic matrix does row/column for indices even though it //uses column/row for initialising. d->mediaWhitePoint.X = result(0, 0); d->mediaWhitePoint.Y = result(1, 0); d->mediaWhitePoint.Z = result(2, 0); cmsXYZ2xyY(&d->whitePoint, &d->mediaWhitePoint); } } //This is for RGB profiles, but it only works for matrix profiles. Need to design it to work with non-matrix profiles. if (cmsIsTag(d->profile, cmsSigRedColorantTag)) { cmsCIEXYZTRIPLE tempColorants; tempColorants.Red = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigRedColorantTag)); tempColorants.Green = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigGreenColorantTag)); tempColorants.Blue = *((cmsCIEXYZ *)cmsReadTag(d->profile, cmsSigBlueColorantTag)); //convert to d65, this is useless. cmsAdaptToIlluminant(&d->colorants.Red, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Red); cmsAdaptToIlluminant(&d->colorants.Green, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Green); cmsAdaptToIlluminant(&d->colorants.Blue, &baseMediaWhitePoint, &d->mediaWhitePoint, &tempColorants.Blue); //d->colorants = tempColorants; d->hasColorants = true; } else { //qDebug()<<d->name<<": has no colorants"; d->hasColorants = false; } //retrieve TRC. if (cmsIsTag(d->profile, cmsSigRedTRCTag) && cmsIsTag(d->profile, cmsSigBlueTRCTag) && cmsIsTag(d->profile, cmsSigGreenTRCTag)) { d->redTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigRedTRCTag)); d->greenTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigGreenTRCTag)); d->blueTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigBlueTRCTag)); d->redTRCReverse = cmsReverseToneCurve(d->redTRC); d->greenTRCReverse = cmsReverseToneCurve(d->greenTRC); d->blueTRCReverse = cmsReverseToneCurve(d->blueTRC); d->hasTRC = true; } else if (cmsIsTag(d->profile, cmsSigGrayTRCTag)) { d->grayTRC = ((cmsToneCurve *)cmsReadTag (d->profile, cmsSigGrayTRCTag)); d->grayTRCReverse = cmsReverseToneCurve(d->grayTRC); d->hasTRC = true; } else { d->hasTRC = false; } // Check if the profile can convert (something->this) d->suitableForOutput = cmsIsMatrixShaper(d->profile) || (cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT) && cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_OUTPUT)); d->version = cmsGetProfileVersion(d->profile); d->defaultIntent = cmsGetHeaderRenderingIntent(d->profile); d->isMatrixShaper = cmsIsMatrixShaper(d->profile); d->isPerceptualCLUT = cmsIsCLUT(d->profile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT); d->isSaturationCLUT = cmsIsCLUT(d->profile, INTENT_SATURATION, LCMS_USED_AS_INPUT); d->isAbsoluteCLUT = cmsIsCLUT(d->profile, INTENT_SATURATION, LCMS_USED_AS_INPUT); d->isRelativeCLUT = cmsIsCLUT(d->profile, INTENT_RELATIVE_COLORIMETRIC, LCMS_USED_AS_INPUT); return true; } return false; }
BOOL cmsxComputeMatrixShaper(const char* ReferenceSheet, const char* MeasurementSheet, int Medium, LPGAMMATABLE TransferCurves[3], LPcmsCIEXYZ WhitePoint, LPcmsCIEXYZ BlackPoint, LPcmsCIExyYTRIPLE Primaries) { MEASUREMENT Linearized; cmsCIEXYZ Black, White; cmsCIExyYTRIPLE PrimarySet; LPPATCH PatchWhite, PatchBlack; LPPATCH PatchRed, PatchGreen, PatchBlue; double Distance; /* Load sheets */ if (!cmsxPCollBuildMeasurement(&Linearized, ReferenceSheet, MeasurementSheet, PATCH_HAS_XYZ|PATCH_HAS_RGB)) return false; /* Any patch to deal of? */ if (cmsxPCollCountSet(&Linearized, Linearized.Allowed) <= 0) return false; /* Try to see if proper primaries, white and black already present */ PatchWhite = cmsxPCollFindWhite(&Linearized, Linearized.Allowed, &Distance); if (Distance != 0) PatchWhite = NULL; PatchBlack = cmsxPCollFindBlack(&Linearized, Linearized.Allowed, &Distance); if (Distance != 0) PatchBlack = NULL; PatchRed = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 0, &Distance); if (Distance != 0) PatchRed = NULL; PatchGreen = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 1, &Distance); if (Distance != 0) PatchGreen = NULL; PatchBlue = cmsxPCollFindPrimary(&Linearized, Linearized.Allowed, 2, &Distance); if (Distance != 0) PatchBlue= NULL; /* If we got primaries, then we can also get prelinearization */ /* by Levenberg-Marquardt. This applies on monitor profiles */ if (PatchWhite && PatchRed && PatchGreen && PatchBlue) { /* Build matrix with primaries */ MAT3 Mat, MatInv; LPSAMPLEDCURVE Xr,Yr, Xg, Yg, Xb, Yb; int i, nRes, cnt; VEC3init(&Mat.v[0], PatchRed->XYZ.X, PatchGreen->XYZ.X, PatchBlue->XYZ.X); VEC3init(&Mat.v[1], PatchRed->XYZ.Y, PatchGreen->XYZ.Y, PatchBlue->XYZ.Y); VEC3init(&Mat.v[2], PatchRed->XYZ.Z, PatchGreen->XYZ.Z, PatchBlue->XYZ.Z); /* Invert matrix */ MAT3inverse(&Mat, &MatInv); nRes = cmsxPCollCountSet(&Linearized, Linearized.Allowed); Xr = cmsAllocSampledCurve(nRes); Yr = cmsAllocSampledCurve(nRes); Xg = cmsAllocSampledCurve(nRes); Yg = cmsAllocSampledCurve(nRes); Xb = cmsAllocSampledCurve(nRes); Yb = cmsAllocSampledCurve(nRes); /* Convert XYZ of all patches to RGB */ cnt = 0; for (i=0; i < Linearized.nPatches; i++) { if (Linearized.Allowed[i]) { VEC3 RGBprime, XYZ; LPPATCH p; p = Linearized.Patches + i; XYZ.n[0] = p -> XYZ.X; XYZ.n[1] = p -> XYZ.Y; XYZ.n[2] = p -> XYZ.Z; MAT3eval(&RGBprime, &MatInv, &XYZ); Xr ->Values[cnt] = p ->Colorant.RGB[0]; Yr ->Values[cnt] = Clip(RGBprime.n[0]); Xg ->Values[cnt] = p ->Colorant.RGB[1]; Yg ->Values[cnt] = Clip(RGBprime.n[1]); Xb ->Values[cnt] = p ->Colorant.RGB[2]; Yb ->Values[cnt] = Clip(RGBprime.n[2]); cnt++; } } TransferCurves[0] = cmsxEstimateGamma(Xr, Yr, 1024); TransferCurves[1] = cmsxEstimateGamma(Xg, Yg, 1024); TransferCurves[2] = cmsxEstimateGamma(Xb, Yb, 1024); if (WhitePoint) { WhitePoint->X = PatchWhite->XYZ.X; WhitePoint->Y= PatchWhite ->XYZ.Y; WhitePoint->Z= PatchWhite ->XYZ.Z; } if (BlackPoint && PatchBlack) { BlackPoint->X = PatchBlack ->XYZ.X; BlackPoint->Y = PatchBlack ->XYZ.Y; BlackPoint->Z = PatchBlack ->XYZ.Z; } if (Primaries) { cmsXYZ2xyY(&Primaries->Red, &PatchRed ->XYZ); cmsXYZ2xyY(&Primaries->Green, &PatchGreen ->XYZ); cmsXYZ2xyY(&Primaries->Blue, &PatchBlue ->XYZ); } cmsFreeSampledCurve(Xr); cmsFreeSampledCurve(Yr); cmsFreeSampledCurve(Xg); cmsFreeSampledCurve(Yg); cmsFreeSampledCurve(Xb); cmsFreeSampledCurve(Yb); cmsxPCollFreeMeasurements(&Linearized); return true; } /* Compute prelinearization */ cmsxComputeLinearizationTables(&Linearized, PT_XYZ, TransferCurves, 1024, Medium); /* Linearize measurements */ cmsxPCollLinearizePatches(&Linearized, Linearized.Allowed, TransferCurves); /* Endpoints */ ComputeWhiteAndBlackPoints(&Linearized, TransferCurves, &Black, &White); /* Primaries */ ComputePrimary(&Linearized, TransferCurves, 0, &PrimarySet.Red); ComputePrimary(&Linearized, TransferCurves, 1, &PrimarySet.Green); ComputePrimary(&Linearized, TransferCurves, 2, &PrimarySet.Blue); if (BlackPoint) { *BlackPoint = Black; Div100(BlackPoint); } if (WhitePoint) { *WhitePoint = White; Div100(WhitePoint); } if (Primaries) { *Primaries = PrimarySet; } cmsxPCollFreeMeasurements(&Linearized); return true; }
static void gcm_picker_refresh_results (GcmPickerPrivate *priv) { cmsCIExyY xyY; cmsHPROFILE profile_lab; cmsHPROFILE profile_rgb; cmsHPROFILE profile_xyz; cmsHTRANSFORM transform_error; cmsHTRANSFORM transform_lab; cmsHTRANSFORM transform_rgb; gboolean ret; CdColorLab color_lab; CdColorRGB8 color_rgb; CdColorXYZ color_error; CdColorXYZ color_xyz; gdouble temperature = 0.0f; GtkImage *image; GtkLabel *label; g_autoptr(GdkPixbuf) pixbuf = NULL; g_autofree gchar *text_ambient = NULL; g_autofree gchar *text_error = NULL; g_autofree gchar *text_lab = NULL; g_autofree gchar *text_rgb = NULL; g_autofree gchar *text_temperature = NULL; g_autofree gchar *text_whitepoint = NULL; g_autofree gchar *text_xyz = NULL; /* nothing set yet */ if (priv->profile_filename == NULL) return; /* copy as we're modifying the value */ cd_color_xyz_copy (&priv->last_sample, &color_xyz); /* create new pixbuf of the right size */ image = GTK_IMAGE (gtk_builder_get_object (priv->builder, "image_preview")); pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, gtk_widget_get_allocated_width (GTK_WIDGET (image)), gtk_widget_get_allocated_height (GTK_WIDGET (image))); /* lcms scales these for some reason */ color_xyz.X /= 100.0f; color_xyz.Y /= 100.0f; color_xyz.Z /= 100.0f; /* get profiles */ profile_xyz = cmsCreateXYZProfile (); profile_rgb = cmsOpenProfileFromFile (priv->profile_filename, "r"); profile_lab = cmsCreateLab4Profile (cmsD50_xyY ()); /* create transforms */ transform_rgb = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL, profile_rgb, TYPE_RGB_8, INTENT_PERCEPTUAL, 0); if (transform_rgb == NULL) return; transform_lab = cmsCreateTransform (profile_xyz, TYPE_XYZ_DBL, profile_lab, TYPE_Lab_DBL, INTENT_PERCEPTUAL, 0); if (transform_lab == NULL) return; transform_error = cmsCreateTransform (profile_rgb, TYPE_RGB_8, profile_xyz, TYPE_XYZ_DBL, INTENT_PERCEPTUAL, 0); if (transform_error == NULL) return; cmsDoTransform (transform_rgb, &color_xyz, &color_rgb, 1); cmsDoTransform (transform_lab, &color_xyz, &color_lab, 1); cmsDoTransform (transform_error, &color_rgb, &color_error, 1); /* destroy lcms state */ cmsDeleteTransform (transform_rgb); cmsDeleteTransform (transform_lab); cmsDeleteTransform (transform_error); cmsCloseProfile (profile_xyz); cmsCloseProfile (profile_rgb); cmsCloseProfile (profile_lab); /* set XYZ */ label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_xyz")); text_xyz = g_strdup_printf ("%.3f, %.3f, %.3f", priv->last_sample.X, priv->last_sample.Y, priv->last_sample.Z); gtk_label_set_label (label, text_xyz); /* set LAB */ label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_lab")); text_lab = g_strdup_printf ("%.3f, %.3f, %.3f", color_lab.L, color_lab.a, color_lab.b); gtk_label_set_label (label, text_lab); /* set whitepoint */ cmsXYZ2xyY (&xyY, (cmsCIEXYZ *)&priv->last_sample); label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_whitepoint")); text_whitepoint = g_strdup_printf ("%.3f,%.3f [%.3f]", xyY.x, xyY.y, xyY.Y); gtk_label_set_label (label, text_whitepoint); /* set temperature */ ret = cmsTempFromWhitePoint (&temperature, &xyY); if (ret) { /* round to nearest 10K */ temperature = (((guint) temperature) / 10) * 10; } label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_temperature")); text_temperature = g_strdup_printf ("%.0fK", temperature); gtk_label_set_label (label, text_temperature); /* set RGB */ label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_rgb")); text_rgb = g_strdup_printf ("%i, %i, %i (#%02X%02X%02X)", color_rgb.R, color_rgb.G, color_rgb.B, color_rgb.R, color_rgb.G, color_rgb.B); gtk_label_set_label (label, text_rgb); gcm_picker_set_pixbuf_color (pixbuf, color_rgb.R, color_rgb.G, color_rgb.B); /* set error */ label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_error")); if (color_xyz.X > 0.01f && color_xyz.Y > 0.01f && color_xyz.Z > 0.01f) { text_error = g_strdup_printf ("%.1f%%, %.1f%%, %.1f%%", ABS ((color_error.X - color_xyz.X) / color_xyz.X * 100), ABS ((color_error.Y - color_xyz.Y) / color_xyz.Y * 100), ABS ((color_error.Z - color_xyz.Z) / color_xyz.Z * 100)); gtk_label_set_label (label, text_error); } else { /* TRANSLATORS: this is when the error is invalid */ gtk_label_set_label (label, _("Unknown")); } /* set ambient */ label = GTK_LABEL (gtk_builder_get_object (priv->builder, "label_ambient")); if (priv->last_ambient < 0) { /* TRANSLATORS: this is when the ambient light level is unknown */ gtk_label_set_label (label, _("Unknown")); } else { text_ambient = g_strdup_printf ("%.1f Lux", priv->last_ambient); gtk_label_set_label (label, text_ambient); } /* set image */ gtk_image_set_from_pixbuf (image, pixbuf); }
BOOL cmsxMonitorProfilerDo(LPMONITORPROFILERDATA sys) { cmsCIExyY White; LPLUT AToB0, BToA0; AToB0 = BToA0 = NULL; if (!*sys -> hdr.OutputProfileFile) return false; if (sys->hdr.ReferenceSheet[0] || sys->hdr.MeasurementSheet[0]) { if (sys->hdr.printf) { sys->hdr.printf("Loading sheets..."); if (sys->hdr.ReferenceSheet[0]) sys->hdr.printf("Reference sheet: %s", sys->hdr.ReferenceSheet); if (sys->hdr.MeasurementSheet[0]) sys->hdr.printf("Measurement sheet: %s", sys->hdr.MeasurementSheet); } if (!cmsxComputeMatrixShaper(sys -> hdr.ReferenceSheet, sys -> hdr.MeasurementSheet, MEDIUM_TRANSMISSIVE, sys -> Prelinearization, &sys -> hdr.WhitePoint, &sys -> hdr.BlackPoint, &sys -> hdr.Primaries)) return false; if (sys->hdr.printf) { char Buffer[1024]; _cmsIdentifyWhitePoint(Buffer, &sys ->hdr.WhitePoint); sys->hdr.printf("%s", Buffer); sys->hdr.printf("Primaries: R:%1.2g, %1.2g G:%1.2g, %1.2g B:%1.2g, %1.2g", sys->hdr.Primaries.Red.x,sys->hdr.Primaries.Red.y, sys->hdr.Primaries.Green.x, sys->hdr.Primaries.Green.y, sys->hdr.Primaries.Blue.x, sys->hdr.Primaries.Blue.y); } } CreatePrimaryMatrices(sys); cmsXYZ2xyY(&White, &sys->hdr.WhitePoint); sys->hdr.hProfile = cmsCreateRGBProfile(&White, &sys-> hdr.Primaries, sys -> Prelinearization); cmsSetDeviceClass(sys->hdr.hProfile, sys->hdr.DeviceClass); if (sys -> hdr.lUseCIECAM97s) sys->hdr.PCSType = PT_Lab; else sys->hdr.PCSType = PT_XYZ; cmsSetPCS(sys->hdr.hProfile, _cmsICCcolorSpace(sys->hdr.PCSType)); if (sys -> hdr.lUseCIECAM97s) CreateLUTS(sys, &AToB0, &BToA0); cmsxEmbedTextualInfo(&sys ->hdr); cmsAddTag(sys->hdr.hProfile, icSigMediaWhitePointTag, &sys->hdr.WhitePoint); cmsAddTag(sys->hdr.hProfile, icSigMediaBlackPointTag, &sys->hdr.BlackPoint); if (sys->hdr.ProfileVerbosityLevel >= 2) { cmsxEmbedCharTarget(&sys ->hdr); } _cmsSaveProfile(sys->hdr.hProfile, sys->hdr.OutputProfileFile); cmsCloseProfile(sys->hdr.hProfile); sys->hdr.hProfile = NULL; if (AToB0) cmsFreeLUT(AToB0); if (BToA0) cmsFreeLUT(BToA0); if (sys ->Prelinearization[0]) cmsFreeGammaTriple(sys -> Prelinearization); return true; }
static BOOL CreateLUTS(LPMONITORPROFILERDATA sys, LPLUT* A2B, LPLUT* B2A) { LPLUT AToB0 = cmsAllocLUT(); LPLUT BToA0 = cmsAllocLUT(); LPGAMMATABLE LabG; cmsCIExyY xyY; cmsAlloc3DGrid(AToB0, sys->hdr.CLUTPoints, 3, 3); cmsAlloc3DGrid(BToA0, sys->hdr.CLUTPoints, 3, 3); /* cmsAllocLinearTable(AToB0, sys -> Prelinearization, 1); */ sys->ReverseTables[0] = cmsReverseGamma(4096, sys ->Prelinearization[0]); sys->ReverseTables[1] = cmsReverseGamma(4096, sys ->Prelinearization[1]); sys->ReverseTables[2] = cmsReverseGamma(4096, sys ->Prelinearization[2]); /* Prelinearization */ LabG = cmsBuildGamma(4096, 3.0); sys -> PreLab[0] = cmsJoinGammaEx(LabG, sys ->Prelinearization[0], 4096); sys -> PreLab[1] = cmsJoinGammaEx(LabG, sys ->Prelinearization[1], 4096); sys -> PreLab[2] = cmsJoinGammaEx(LabG, sys ->Prelinearization[2], 4096); sys -> PreLabRev[0] = cmsJoinGammaEx(sys ->Prelinearization[0], LabG, 4096); sys -> PreLabRev[1] = cmsJoinGammaEx(sys ->Prelinearization[1], LabG, 4096); sys -> PreLabRev[2] = cmsJoinGammaEx(sys ->Prelinearization[2], LabG, 4096); cmsFreeGamma(LabG); cmsAllocLinearTable(AToB0, sys->PreLabRev, 1); cmsAllocLinearTable(BToA0, sys->PreLab, 2); /* Set CIECAM97s parameters */ sys -> hdr.device.whitePoint.X = sys -> hdr.WhitePoint.X * 100.; sys -> hdr.device.whitePoint.Y = sys -> hdr.WhitePoint.Y * 100.; sys -> hdr.device.whitePoint.Z = sys -> hdr.WhitePoint.Z * 100.; /* Normalize White point for CIECAM97s model */ cmsXYZ2xyY(&xyY, &sys -> hdr.device.whitePoint); xyY.Y = 100.; cmsxyY2XYZ(&sys -> hdr.device.whitePoint, &xyY); sys->hdr.hDevice = cmsCIECAM97sInit(&sys->hdr.device); sys->hdr.hPCS = cmsCIECAM97sInit(&sys->hdr.PCS); cmsSample3DGrid(AToB0, RegressionSamplerA2B, sys, 0); cmsSample3DGrid(BToA0, RegressionSamplerB2A, sys, 0); cmsCIECAM97sDone(sys->hdr.hDevice); cmsCIECAM97sDone(sys->hdr.hPCS); cmsAddTag(sys->hdr.hProfile, icSigAToB0Tag, AToB0); cmsAddTag(sys->hdr.hProfile, icSigBToA0Tag, BToA0); /* This is the 0xff00 trick to map white at lattice point */ BToA0 ->Matrix.v[0].n[0] = DOUBLE_TO_FIXED((65535.0 / 65280.0)); *A2B = AToB0; *B2A = BToA0; cmsFreeGammaTriple(sys->ReverseTables); cmsFreeGammaTriple(sys->PreLab); cmsFreeGammaTriple(sys->PreLabRev); return true; }
int main(int argc, char *argv[]) { LPLUT AToB0, BToA0; LPGAMMATABLE PreLinear[3]; LPGAMMATABLE Lin; CARGO Cargo; cmsHPROFILE hProfile; cmsCIEXYZ wp; fprintf(stderr, "Creating lcmscmy.icm..."); wp.X = 55.6549; wp.Y = 59.0485; wp.Z = 72.5494; cmsXYZ2xyY(&Cus, &wp); InitCargo(&Cargo); hProfile = cmsCreateLabProfile(&Cus); // Create linearization Lin = CreateLinear(); PreLinear[0] = Lin; PreLinear[1] = Lin; PreLinear[2] = Lin; AToB0 = cmsAllocLUT(); BToA0 = cmsAllocLUT(); cmsAlloc3DGrid(AToB0, 33, 3, 3); cmsAlloc3DGrid(BToA0, 33, 3, 3); cmsSample3DGrid(AToB0, Reverse, &Cargo, 0); cmsSample3DGrid(BToA0, Forward, &Cargo, 0); cmsAllocLinearTable(AToB0, PreLinear, 1); cmsAllocLinearTable(BToA0, PreLinear, 2); cmsAddTag(hProfile, icSigAToB0Tag, AToB0); cmsAddTag(hProfile, icSigBToA0Tag, BToA0); cmsSetColorSpace(hProfile, icSigCmyData); cmsAddTag(hProfile, icSigProfileDescriptionTag, "Little cms CMY mixing"); cmsAddTag(hProfile, icSigCopyrightTag, "Copyright (c) Marti Maria, 2002. All rights reserved."); cmsAddTag(hProfile, icSigDeviceMfgDescTag, "Little cms"); cmsAddTag(hProfile, icSigDeviceModelDescTag, "CMY mixing"); _cmsSaveProfile(hProfile, "lcmscmy.icm"); cmsFreeGamma(Lin); cmsFreeLUT(AToB0); cmsFreeLUT(BToA0); cmsCloseProfile(hProfile); FreeCargo(&Cargo); fprintf(stderr, "Done.\n"); return 0; }