Exemple #1
0
static void
lcms_image_transform_indexed (gint32                    image,
                              cmsHPROFILE               src_profile,
                              cmsHPROFILE               dest_profile,
                              GimpColorRenderingIntent  intent,
                              gboolean                  bpc)
{
  cmsHTRANSFORM    transform;
  guchar          *cmap;
  gint             n_cmap_bytes;
  cmsUInt32Number  format = TYPE_RGB_8;

  cmap = gimp_image_get_colormap (image, &n_cmap_bytes);

  transform = cmsCreateTransform (src_profile,  format,
                                  dest_profile, format,
                                  intent,
                                  cmsFLAGS_NOOPTIMIZE |
                                  bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0);

  if (transform)
    {
      cmsDoTransform (transform, cmap, cmap, n_cmap_bytes / 3);
      cmsDeleteTransform (transform);
    }
  else
    {
      g_warning ("cmsCreateTransform() failed!");
    }

  gimp_image_set_colormap (image, cmap, n_cmap_bytes);
}
Exemple #2
0
/* Have the CMS release the link */
void
gscms_release_link(gsicc_link_t *icclink)
{
    if (icclink->link_handle !=NULL )
        cmsDeleteTransform(icclink->link_handle);

    icclink->link_handle = NULL;
}
Exemple #3
0
void gui_cleanup(struct dt_iop_module_t *self)
{
  dt_iop_colortransfer_gui_data_t *g = (dt_iop_colortransfer_gui_data_t *)self->gui_data;
  dt_colorspaces_cleanup_profile(g->hsRGB);
  dt_colorspaces_cleanup_profile(g->hLab);
  cmsDeleteTransform(g->xform);
  free(self->gui_data);
  self->gui_data = NULL;
}
Exemple #4
0
static
int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent, cmsUInt32Number dwFlags)
{
    cmsHTRANSFORM xform;    
    int i, nColors, nColorant;
    cmsUInt32Number OutputFormat;
    char ColorName[32];
    char Colorant[128];
	cmsNAMEDCOLORLIST* NamedColorList;

	
    OutputFormat = cmsFormatterForColorspaceOfProfile(hNamedColor, 2, FALSE);
	nColorant    = T_CHANNELS(OutputFormat);

	
    xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, NULL, OutputFormat, Intent, dwFlags);
    if (xform == NULL) return 0;


	NamedColorList = cmsGetNamedColorList(xform);
	if (NamedColorList == NULL) return 0;

    _cmsIOPrintf(m, "<<\n");
    _cmsIOPrintf(m, "(colorlistcomment) (%s) \n", "Named profile");
    _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
    _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");

    nColors   = cmsNamedColorCount(NamedColorList);
    
    for (i=0; i < nColors; i++) {
        
        cmsUInt16Number In[1];
        cmsUInt16Number Out[cmsMAXCHANNELS];

        In[0] = (cmsUInt16Number) i;

        if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
                continue;

        cmsDoTransform(xform, In, Out, 1);      
        BuildColorantList(Colorant, nColorant, Out);
        _cmsIOPrintf(m, "  (%s) [ %s ]\n", ColorName, Colorant);
    }

    _cmsIOPrintf(m, "   >>");

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

    _cmsIOPrintf(m, " /Current exch /HPSpotTable defineresource pop\n");
    }

    cmsDeleteTransform(xform);  
    return 1;
}
Exemple #5
0
static void
gimp_view_renderer_transform_free (GimpViewRenderer *renderer)
{
  if (renderer->profile_transform)
    {
      cmsDeleteTransform (renderer->profile_transform);
      renderer->profile_transform   = NULL;
      renderer->profile_src_format  = NULL;
      renderer->profile_dest_format = NULL;
    }
}
Exemple #6
0
void gui_cleanup(struct dt_iop_module_t *self)
{
  dt_iop_colorzones_gui_data_t *c = (dt_iop_colorzones_gui_data_t *)self->gui_data;
  dt_conf_set_int("plugins/darkroom/colorzones/gui_channel", c->channel);
  dt_colorspaces_cleanup_profile(c->hsRGB);
  dt_colorspaces_cleanup_profile(c->hLab);
  cmsDeleteTransform(c->xform);
  dt_draw_curve_destroy(c->minmax_curve);
  free(self->gui_data);
  self->gui_data = NULL;
}
Exemple #7
0
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
{
  dt_iop_colorout_data_t *d = (dt_iop_colorout_data_t *)piece->data;
  if(d->xform)
  {
    cmsDeleteTransform(d->xform);
    d->xform = NULL;
  }

  free(piece->data);
  piece->data = NULL;
}
static void
cdisplay_lcms_finalize (GObject *object)
{
  CdisplayLcms *lcms = CDISPLAY_LCMS (object);

  if (lcms->transform)
    {
      cmsDeleteTransform (lcms->transform);
      lcms->transform = NULL;
    }

  G_OBJECT_CLASS (cdisplay_lcms_parent_class)->finalize (object);
}
Exemple #9
0
void cleanup_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
{
  dt_iop_colorout_data_t *d = (dt_iop_colorout_data_t *)piece->data;
  if(d->output) dt_colorspaces_cleanup_profile(d->output);
  dt_colorspaces_cleanup_profile(d->Lab);
  if (d->xform)
  {
    cmsDeleteTransform(d->xform);
    d->xform = 0;
  }

  free(piece->data);
}
Exemple #10
0
void* convert_space (const void *source_data_ptr, int width, int height) {

    // Assign the memory for the transform
    void *YourOutputBuffer = malloc(sizeof(void)*width*height*4);
    
    // Create the required variables
    cmsHPROFILE hInProfile, hOutProfile; 
    cmsHTRANSFORM hTransform; 
    
    // Load the colour profiles
    hInProfile = cmsOpenProfileFromFile("/Library/Application Support/Nikon/Profiles/NKAdobe.icm", "r"); 
    hOutProfile = cmsCreate_sRGBProfile();
    
    // Create the transform matrix
    hTransform = cmsCreateTransform(hInProfile, 
                                    TYPE_RGBA_8, 
                                    hOutProfile, 
                                    TYPE_RGBA_8, 
                                    INTENT_PERCEPTUAL, 
                                    0);
    
    // Convert the image colours
    cmsDoTransform(hTransform, 
                   source_data_ptr, 
                   YourOutputBuffer, 
                   width*height);

    // Delete the opened stuff
    cmsDeleteTransform(hTransform); 
    cmsCloseProfile(hInProfile); 
    cmsCloseProfile(hOutProfile);
    
    // Create the return data object
  //  CFDataRef ret_val = CFDataCreate (NULL, YourOutputBuffer, height * width * 4);
    
    // release the old image
//	CFRelease (source_data_ptr);

	// Null the pointer after releasing
    source_data_ptr = NULL;
    
    // NULL the pointer
    source_data_ptr = NULL;

	// Free the temp buffer for the colour space image
 //   free(YourOutputBuffer);
    
    fprintf(stdout, "Colour space converted.");
	// return the new image
	return YourOutputBuffer;
}
static void
gcm_cell_renderer_set_color (GcmCellRendererColor *renderer)
{
	CdColorRGB8 rgb;
	GdkPixbuf *pixbuf = NULL;
	gint height = 26; /* TODO: needs to be a property */
	gint width = 400; /* TODO: needs to be a property */
	gint x, y;
	guchar *pixels;
	guint pos;
	cmsHPROFILE profile_srgb = NULL;
	cmsHPROFILE profile_lab = NULL;
	cmsHTRANSFORM xform = NULL;

	/* nothing set yet */
	if (renderer->color == NULL)
		goto out;

	/* convert the color to sRGB */
	profile_lab = cmsCreateLab2Profile (NULL);
	profile_srgb = cmsCreate_sRGBProfile ();
	xform = cmsCreateTransform (profile_lab, TYPE_Lab_DBL,
				    profile_srgb, TYPE_RGB_8,
				    INTENT_ABSOLUTE_COLORIMETRIC, 0);
	cmsDoTransform (xform, renderer->color, &rgb, 1);

	/* create a pixbuf of the right size */
	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);
	width = gdk_pixbuf_get_width (pixbuf);
	height = gdk_pixbuf_get_height (pixbuf);
	pixels = gdk_pixbuf_get_pixels (pixbuf);
	for (y=0; y<height; y++) {
		for (x=0; x<width; x++) {
			pos = (y*width+x) * 3;
			pixels[pos+0] = rgb.R;
			pixels[pos+1] = rgb.G;
			pixels[pos+2] = rgb.B;
		}
	}
out:
	g_object_set (renderer, "pixbuf", pixbuf, NULL);
	if (profile_srgb != NULL)
		cmsCloseProfile (profile_srgb);
	if (profile_lab != NULL)
		cmsCloseProfile (profile_lab);
	if (xform != NULL)
		cmsDeleteTransform (xform);
	if (pixbuf != NULL)
		g_object_unref (pixbuf);
}
void IccColorProfile::calculateFloatUIMinMax(void)
{
    QVector<KoChannelInfo::DoubleRange> &ret = d->shared->uiMinMaxes;

    cmsHPROFILE cprofile = d->shared->lcmsProfile->lcmsProfile();
    Q_ASSERT(cprofile);

    cmsColorSpaceSignature color_space_sig = cmsGetColorSpace(cprofile);
    unsigned int num_channels = cmsChannelsOf(color_space_sig);
    unsigned int color_space_mask = _cmsLCMScolorSpace(color_space_sig);

    Q_ASSERT(num_channels>=1 && num_channels <=4);  // num_channels==1 is for grayscale, we need to handle it
    Q_ASSERT(color_space_mask);

    // to try to find the max range of float/doubles for this profile,
    // pass in min/max int and make the profile convert that
    // this is far from perfect, we need a better way, if possible to get the "bounds" of a profile

    uint16_t in_min_pixel[4] = {0,0,0,0};
    uint16_t in_max_pixel[4] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF};
    double out_min_pixel[4] = {0,0,0,0};
    double out_max_pixel[4] = {0,0,0,0};

    cmsHTRANSFORM trans = cmsCreateTransform(
        cprofile,
        (COLORSPACE_SH(color_space_mask)|CHANNELS_SH(num_channels)|BYTES_SH(2)),
        cprofile,
        (COLORSPACE_SH(color_space_mask)|FLOAT_SH(1)|CHANNELS_SH(num_channels)|BYTES_SH(0)), //NOTE THAT 'BYTES' FIELD IS SET TO ZERO ON DLB because 8 bytes overflows the bitfield
        INTENT_PERCEPTUAL, 0);      // does the intent matter in this case?

    if (trans) {
        cmsDoTransform(trans, in_min_pixel, out_min_pixel, 1);
        cmsDoTransform(trans, in_max_pixel, out_max_pixel, 1);
        cmsDeleteTransform(trans);
    }//else, we'll just default to [0..1] below

    ret.resize(num_channels);
    for (unsigned int i=0; i<num_channels; ++i) {
        if (out_min_pixel[i] < out_max_pixel[i]) {
            ret[i].minVal = out_min_pixel[i];
            ret[i].maxVal = out_max_pixel[i];
        } else {
            // aparently we can't even guarentee that converted_to_double(0x0000) < converted_to_double(0xFFFF)
            // assume [0..1] in such cases
            // we need to find a really solid way of determining the bounds of a profile, if possible
            ret[i].minVal = 0;
            ret[i].maxVal = 1;
        }
    }
}
Exemple #13
0
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;
}
int main(int  argc, char* argv[])
{

    int r, g, b;
    cmsUInt8Number RGB[3], RGB_OUT[3];
    cmsHTRANSFORM xform;
    cmsHPROFILE hProfile;
    double err, SumX=0, SumX2=0, Peak = 0, n = 0;


    if (argc != 2) {
        printf("roundtrip <RGB icc profile>\n");
        return 1;
    }

    hProfile = cmsOpenProfileFromFile(argv[1], "r");
    xform = cmsCreateTransform(hProfile,TYPE_RGB_8, hProfile, TYPE_RGB_8, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE);

    for (r=0; r< 256; r++) {
        printf("%d  \r", r);
        for (g=0; g < 256; g++) {
            for (b=0; b < 256; b++) {

                RGB[0] = r;
                RGB[1] = g;
                RGB[2] = b;

                cmsDoTransform(xform, RGB, RGB_OUT, 1);

                err = VecDist(RGB, RGB_OUT);

                SumX  += err;
                SumX2 += err * err;
                n += 1.0;
                if (err > Peak)
                    Peak = err;

            }
        }
    }

    printf("Average %g\n", SumX / n);
    printf("Max %g\n", Peak);
    printf("Std  %g\n", sqrt((n*SumX2 - SumX * SumX) / (n*(n-1))));
    cmsCloseProfile(hProfile);
    cmsDeleteTransform(xform);

    return 0;
}
Exemple #15
0
static
void CloseTransforms(void)
{
	int i;

    if (hColorTransform) cmsDeleteTransform(hColorTransform);
    if (hInput) cmsCloseProfile(hInput);
    if (hOutput) cmsCloseProfile(hOutput);             
    if (hProof) cmsCloseProfile(hProof);

	for (i=0; i < nProfiles; i++)
			cmsCloseProfile(hProfiles[i]);
       
    hColorTransform = NULL; hInput = NULL; hOutput = NULL; hProof = NULL;
}
Exemple #16
0
// Detect Total area coverage of the profile
cmsFloat64Number CMSEXPORT cmsDetectTAC(cmsHPROFILE hProfile)
{
    cmsTACestimator bp;
    cmsUInt32Number dwFormatter;
    cmsUInt32Number GridPoints[MAX_INPUT_DIMENSIONS];
    cmsHPROFILE hLab;
    cmsContext ContextID = cmsGetProfileContextID(hProfile);

    // TAC only works on output profiles
    if (cmsGetDeviceClass(hProfile) != cmsSigOutputClass) {
        return 0;
    }

    // Create a fake formatter for result
    dwFormatter = cmsFormatterForColorspaceOfProfile(hProfile, 4, TRUE);

    bp.nOutputChans = T_CHANNELS(dwFormatter);
    bp.MaxTAC = 0;    // Initial TAC is 0

    //  for safety
    if (bp.nOutputChans >= cmsMAXCHANNELS) return 0;

    hLab = cmsCreateLab4ProfileTHR(ContextID, NULL);
    if (hLab == NULL) return 0;
    // Setup a roundtrip on perceptual intent in output profile for TAC estimation
    bp.hRoundTrip = cmsCreateTransformTHR(ContextID, hLab, TYPE_Lab_16,
                                          hProfile, dwFormatter, INTENT_PERCEPTUAL, cmsFLAGS_NOOPTIMIZE|cmsFLAGS_NOCACHE);

    cmsCloseProfile(hLab);
    if (bp.hRoundTrip == NULL) return 0;

    // For L* we only need black and white. For C* we need many points
    GridPoints[0] = 6;
    GridPoints[1] = 74;
    GridPoints[2] = 74;


    if (!cmsSliceSpace16(3, GridPoints, EstimateTAC, &bp)) {
        bp.MaxTAC = 0;
    }

    cmsDeleteTransform(bp.hRoundTrip);

    // Results in %
    return bp.MaxTAC;
}
Exemple #17
0
static void color_man_cache_unref(ColorManCache *cc)
{
	if (!cc) return;

	cc->refcount--;
	if (cc->refcount < 1)
		{
		if (cc->transform) cmsDeleteTransform(cc->transform);
		if (cc->profile_in) cmsCloseProfile(cc->profile_in);
		if (cc->profile_out) cmsCloseProfile(cc->profile_out);

		g_free(cc->profile_in_file);
		g_free(cc->profile_out_file);

		g_free(cc);
		}
}
Exemple #18
0
static
int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent)
{
    cmsHTRANSFORM xform;
    cmsHPROFILE   hLab;
    int i, nColors;
    char ColorName[32];
    cmsNAMEDCOLORLIST* NamedColorList;

	hLab  = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
    xform = cmsCreateTransform(hNamedColor, TYPE_NAMED_COLOR_INDEX, hLab, TYPE_Lab_DBL, Intent, 0);
    if (xform == NULL) return 0;

	NamedColorList = cmsGetNamedColorList(xform);
    if (NamedColorList == NULL) return 0;

    _cmsIOPrintf(m, "<<\n");
    _cmsIOPrintf(m, "(colorlistcomment) (%s)\n", "Named color CSA");
    _cmsIOPrintf(m, "(Prefix) [ (Pantone ) (PANTONE ) ]\n");
    _cmsIOPrintf(m, "(Suffix) [ ( CV) ( CVC) ( C) ]\n");

    nColors   = cmsNamedColorCount(NamedColorList);


    for (i=0; i < nColors; i++) {
        
        cmsUInt16Number In[1];
        cmsCIELab Lab;

        In[0] = (cmsUInt16Number) i;

        if (!cmsNamedColorInfo(NamedColorList, i, ColorName, NULL, NULL, NULL, NULL))
                continue;

        cmsDoTransform(xform, In, &Lab, 1);     
        _cmsIOPrintf(m, "  (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
    }


        
    _cmsIOPrintf(m, ">>\n");

    cmsDeleteTransform(xform);
    cmsCloseProfile(hLab);
    return 1;
}
static void
cdisplay_proof_finalize (GObject *object)
{
  CdisplayProof *proof = CDISPLAY_PROOF (object);

  if (proof->profile)
    {
      g_free (proof->profile);
      proof->profile = NULL;
    }

  if (proof->transform)
    {
      cmsDeleteTransform (proof->transform);
      proof->transform = NULL;
    }

  G_OBJECT_CLASS (cdisplay_proof_parent_class)->finalize (object);
}
Exemple #20
0
// Compute K -> L* relationship. Flags may include black point compensation. In this case,
// the relationship is assumed from the profile with BPC to a black point zero.
static
cmsToneCurve* ComputeKToLstar(cmsContext            ContextID,
                               cmsUInt32Number       nPoints,
                               cmsUInt32Number       nProfiles,
                               const cmsUInt32Number Intents[],
                               const cmsHPROFILE     hProfiles[],
                               const cmsBool         BPC[],
                               const cmsFloat64Number AdaptationStates[],
                               cmsUInt32Number dwFlags)
{
    cmsToneCurve* out = NULL;
    cmsUInt32Number i;
    cmsHTRANSFORM xform;
    cmsCIELab Lab;
    cmsFloat32Number cmyk[4];
    cmsFloat32Number* SampledPoints;

    xform = _cmsChain2Lab(ContextID, nProfiles, TYPE_CMYK_FLT, TYPE_Lab_DBL, Intents, hProfiles, BPC, AdaptationStates, dwFlags);
    if (xform == NULL) return NULL;

    SampledPoints = (cmsFloat32Number*) _cmsCalloc(ContextID, nPoints, sizeof(cmsFloat32Number));
    if (SampledPoints  == NULL) goto Error;

    for (i=0; i < nPoints; i++) {

        cmyk[0] = 0;
        cmyk[1] = 0;
        cmyk[2] = 0;
        cmyk[3] = (cmsFloat32Number) ((i * 100.0) / (nPoints-1));

        cmsDoTransform(xform, cmyk, &Lab, 1);
        SampledPoints[i]= (cmsFloat32Number) (1.0 - Lab.L / 100.0); // Negate K for easier operation
    }

    out = cmsBuildTabulatedToneCurveFloat(ContextID, nPoints, SampledPoints);

Error:

    cmsDeleteTransform(xform);
    if (SampledPoints) _cmsFree(ContextID, SampledPoints);

    return out;
}
Exemple #21
0
BOOL close_transform( HTRANSFORM handle )
{
    DWORD_PTR index;
    struct transform *transform;

    EnterCriticalSection( &MSCMS_handle_cs );

    index = (DWORD_PTR)handle - 1;
    if (index > num_transform_handles)
    {
        LeaveCriticalSection( &MSCMS_handle_cs );
        return FALSE;
    }
    transform = &transformtable[index];

    cmsDeleteTransform( transform->cmstransform );
    memset( transform, 0, sizeof(struct transform) );

    LeaveCriticalSection( &MSCMS_handle_cs );
    return TRUE;
}
static void
gimp_image_convert_profile_indexed (GimpImage                *image,
                                    GimpColorProfile         *src_profile,
                                    GimpColorProfile         *dest_profile,
                                    GimpColorRenderingIntent  intent,
                                    gboolean                  bpc,
                                    GimpProgress             *progress)
{
  cmsHPROFILE         src_lcms;
  cmsHPROFILE         dest_lcms;
  guchar             *cmap;
  gint                n_colors;
  GimpColorTransform  transform;

  src_lcms  = gimp_color_profile_get_lcms_profile (src_profile);
  dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);

  n_colors = gimp_image_get_colormap_size (image);
  cmap     = g_memdup (gimp_image_get_colormap (image), n_colors * 3);

  transform = cmsCreateTransform (src_lcms,  TYPE_RGB_8,
                                  dest_lcms, TYPE_RGB_8,
                                  intent,
                                  cmsFLAGS_NOOPTIMIZE |
                                  (bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0));

  if (transform)
    {
      cmsDoTransform (transform, cmap, cmap, n_colors);
      cmsDeleteTransform (transform);

      gimp_image_set_colormap (image, cmap, n_colors, TRUE);
    }
  else
    {
      g_warning ("cmsCreateTransform() failed!");
    }

  g_free (cmap);
}
static void
cdisplay_proof_changed (GimpColorDisplay *display)
{
  CdisplayProof *proof = CDISPLAY_PROOF (display);
  cmsHPROFILE    rgbProfile;
  cmsHPROFILE    proofProfile;

  if (proof->transform)
    {
      cmsDeleteTransform (proof->transform);
      proof->transform = NULL;
    }

  if (! proof->profile)
    return;

  rgbProfile = cmsCreate_sRGBProfile ();

  proofProfile = cmsOpenProfileFromFile (proof->profile, "r");

  if (proofProfile)
    {
      DWORD flags = cmsFLAGS_SOFTPROOFING;

      if (proof->bpc)
        flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

      proof->transform = cmsCreateProofingTransform (rgbProfile,
                                                     TYPE_RGB_8,
                                                     rgbProfile, TYPE_RGB_8,
                                                     proofProfile,
                                                     proof->intent,
                                                     proof->intent,
                                                     flags);

      cmsCloseProfile (proofProfile);
    }

  cmsCloseProfile (rgbProfile);
}
Exemple #24
0
static
cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent)
{
    cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL);
    cmsHPROFILE hXYZ  = cmsCreateXYZProfile();
    cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE);
    int i;

    for (i=0; i < 256; i++) {
        
      cmsUInt8Number Gray = (cmsUInt8Number) i;
      cmsCIEXYZ XYZ;
      
        cmsDoTransform(xform, &Gray, &XYZ, 1);
        
		Out ->Table16[i] =_cmsQuickSaturateWord(XYZ.Y * 65535.0);
    }

    cmsDeleteTransform(xform);
    cmsCloseProfile(hXYZ);
    return Out;
}
Exemple #25
0
// Get a black point of output CMYK profile, discounting any ink-limiting embedded 
// in the profile. For doing that, we use perceptual intent in input direction:
// Lab (0, 0, 0) -> [Perceptual] Profile -> CMYK -> [Rel. colorimetric] Profile -> Lab
static
cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfile)
                                   
{    
    cmsHTRANSFORM hRoundTrip;    
    cmsCIELab LabIn, LabOut;
    cmsCIEXYZ  BlackXYZ;        
 
     // Is the intent supported by the profile?
    if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) {

        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return TRUE;
    }
        
    hRoundTrip = CreateRoundtripXForm(hProfile, INTENT_PERCEPTUAL);
    if (hRoundTrip == NULL) {
        BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0;
        return FALSE;
    }

    LabIn.L = LabIn.a = LabIn.b = 0;
    cmsDoTransform(hRoundTrip, &LabIn, &LabOut, 1);

    // Clip Lab to reasonable limits
    if (LabOut.L > 50) LabOut.L = 50;
    LabOut.a = LabOut.b = 0;

    cmsDeleteTransform(hRoundTrip);
  
    // Convert it to XYZ
    cmsLab2XYZ(NULL, &BlackXYZ, &LabOut);   
    
    if (BlackPoint != NULL)
        *BlackPoint = BlackXYZ;

    return TRUE;
}
Exemple #26
0
        void CorrectImage(wxImage& image, const vigra::ImageImportInfo::ICCProfile& iccProfile, const cmsHPROFILE& monitorProfile)
        {
            cmsHPROFILE inputICC = NULL;
            if (!iccProfile.empty())
            {
                inputICC = cmsOpenProfileFromMem(iccProfile.data(), iccProfile.size());
            };
            // check type of input profile
            if (inputICC != NULL)
            {
                if (cmsGetColorSpace(inputICC) != cmsSigRgbData)
                {
                    cmsCloseProfile(inputICC);
                    inputICC = NULL;
                };
            };
            // if there is no icc profile in file fall back to sRGB
            if (inputICC == NULL)
            {
                inputICC = cmsCreate_sRGBProfile();
            };
            // now build transform
            cmsHTRANSFORM transform = cmsCreateTransform(inputICC, TYPE_RGB_8,
                monitorProfile, TYPE_RGB_8,
                INTENT_PERCEPTUAL, cmsFLAGS_BLACKPOINTCOMPENSATION);
            unsigned char* imgData = image.GetData();
            const int imgWidth = image.GetWidth();
            const int imgHeight = image.GetHeight();
#pragma omp parallel for
            for (int y = 0; y < imgHeight; ++y)
            {
                cmsDoTransform(transform, imgData + 3 * y * imgWidth, imgData + 3 * y * imgWidth, imgWidth);
            };
            cmsDeleteTransform(transform);
            cmsCloseProfile(inputICC);
        };
Exemple #27
0
cmsBool GetProfileRGBPrimaries(cmsHPROFILE hProfile, cmsCIEXYZTRIPLE* const result, cmsUInt32Number intent)
{
    cmsHPROFILE hXYZ;
    cmsHTRANSFORM hTransform;
    cmsFloat64Number rgb[3][3] = {{1., 0., 0.},
                                  {0., 1., 0.},
                                  {0., 0., 1.}};

    hXYZ = cmsCreateXYZProfile();

    if (hXYZ == NULL)
        return FALSE;

    hTransform = cmsCreateTransform(hProfile, TYPE_RGB_DBL, hXYZ, TYPE_XYZ_DBL,
                                    intent, cmsFLAGS_NOCACHE | cmsFLAGS_NOOPTIMIZE);
    cmsCloseProfile(hXYZ);

    if (hTransform == NULL)
        return FALSE;

    cmsDoTransform(hTransform, rgb, result, 3);
    cmsDeleteTransform(hTransform);
    return TRUE;
}
static void
gimp_image_convert_profile_rgb (GimpImage                *image,
                                GimpColorProfile         *src_profile,
                                GimpColorProfile         *dest_profile,
                                GimpColorRenderingIntent  intent,
                                gboolean                  bpc,
                                GimpProgress             *progress)
{
  GList *layers;
  GList *list;
  gint   n_drawables;
  gint   nth_drawable;

  layers = gimp_image_get_layer_list (image);

  n_drawables = g_list_length (layers);

  for (list = layers, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable    *drawable = list->data;
      cmsHPROFILE      src_lcms;
      cmsHPROFILE      dest_lcms;
      const Babl      *iter_format;
      cmsUInt32Number  lcms_format;
      cmsUInt32Number  flags;
      cmsHTRANSFORM    transform;

      if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
        continue;

      src_lcms  = gimp_color_profile_get_lcms_profile (src_profile);
      dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);

      iter_format =
        gimp_color_profile_get_format (gimp_drawable_get_format (drawable),
                                       &lcms_format);

      flags = cmsFLAGS_NOOPTIMIZE;

      if (bpc)
        flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;

      transform = cmsCreateTransform (src_lcms,  lcms_format,
                                      dest_lcms, lcms_format,
                                      intent, flags);

      if (transform)
        {
          GeglBuffer         *buffer;
          GeglBufferIterator *iter;

          buffer = gimp_drawable_get_buffer (drawable);

          gimp_drawable_push_undo (drawable, NULL, NULL,
                                   0, 0,
                                   gegl_buffer_get_width  (buffer),
                                   gegl_buffer_get_height (buffer));

          iter = gegl_buffer_iterator_new (buffer, NULL, 0,
                                           iter_format,
                                           GEGL_ACCESS_READWRITE,
                                           GEGL_ABYSS_NONE);

          while (gegl_buffer_iterator_next (iter))
            {
              cmsDoTransform (transform,
                              iter->data[0], iter->data[0], iter->length);
            }

          gimp_drawable_update (drawable, 0, 0,
                                gegl_buffer_get_width  (buffer),
                                gegl_buffer_get_height (buffer));

          cmsDeleteTransform (transform);
        }

      if (progress)
        gimp_progress_set_value (progress,
                                 (gdouble) nth_drawable / (gdouble) n_drawables);
    }

  g_list_free (layers);
}
Exemple #29
0
static
int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
{
    cmsHPROFILE hLab;
    cmsHTRANSFORM xform;
    cmsUInt32Number nChannels;
    cmsUInt32Number InputFormat;
    int rc;
    cmsHPROFILE Profiles[2];
    cmsCIEXYZ BlackPointAdaptedToD50;

    // Does create a device-link based transform. 
    // The DeviceLink is next dumped as working CSA.
    
    InputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
    nChannels   = T_CHANNELS(InputFormat);

	
	cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);

 	// Adjust output to Lab4 
    hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);

	Profiles[0] = hProfile;
	Profiles[1] = hLab;

	xform = cmsCreateMultiprofileTransform(Profiles, 2,  InputFormat, TYPE_Lab_DBL, Intent, 0);
	cmsCloseProfile(hLab);
	
	if (xform == NULL) {

		cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Profile -> Lab");
		return 0;
	}
    
    // Only 1, 3 and 4 channels are allowed

    switch (nChannels) {

    case 1: {            
		    cmsToneCurve* Gray2Y = ExtractGray2Y(m ->ContextID, hProfile, Intent);
            EmitCIEBasedA(m, Gray2Y, &BlackPointAdaptedToD50);            
            cmsFreeToneCurve(Gray2Y);            
            }
            break;

    case 3: 
    case 4: {
		    cmsUInt32Number OutFrm = TYPE_Lab_16;
            cmsPipeline* DeviceLink;
            _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform;

			DeviceLink = cmsPipelineDup(v ->Lut);
			if (DeviceLink == NULL) return 0;

			dwFlags |= cmsFLAGS_FORCE_CLUT;
			_cmsOptimizePipeline(&DeviceLink, Intent, &InputFormat, &OutFrm, &dwFlags);
            
            rc = EmitCIEBasedDEF(m, DeviceLink, Intent, &BlackPointAdaptedToD50);
            cmsPipelineFree(DeviceLink);            
            }
            break;

    default:

		cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Only 3, 4 channels supported for CSA. This profile has %d channels.", nChannels);
        return 0;
    }
    

    cmsDeleteTransform(xform);
    
    return 1;
}
Exemple #30
0
static
int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags)
{
    cmsHPROFILE hLab;
    cmsHTRANSFORM xform;
    int i, nChannels;
    cmsUInt32Number OutputFormat;
    _cmsTRANSFORM* v;
    cmsPipeline* DeviceLink;
    cmsHPROFILE Profiles[3];
    cmsCIEXYZ BlackPointAdaptedToD50;
    cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION);
    cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP);
	cmsUInt32Number InFrm = TYPE_Lab_16;
	int RelativeEncodingIntent;
	cmsColorSpaceSignature ColorSpace;
    
    
	hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL);
	if (hLab == NULL) return 0;

    OutputFormat = cmsFormatterForColorspaceOfProfile(hProfile, 2, FALSE);
	nChannels    = T_CHANNELS(OutputFormat);

	ColorSpace = cmsGetColorSpace(hProfile);

	// For absolute colorimetric, the LUT is encoded as relative in order to preserve precision.

    RelativeEncodingIntent = Intent;
	if (RelativeEncodingIntent == INTENT_ABSOLUTE_COLORIMETRIC)
		RelativeEncodingIntent = INTENT_RELATIVE_COLORIMETRIC;


	// Use V4 Lab always
	Profiles[0] = hLab;
	Profiles[1] = hProfile;

	xform = cmsCreateMultiprofileTransformTHR(m ->ContextID, 
		                                      Profiles, 2, TYPE_Lab_DBL, 
		                                      OutputFormat, RelativeEncodingIntent, 0);
	cmsCloseProfile(hLab);

    if (xform == NULL) {
                        
		cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Cannot create transform Lab -> Profile in CRD creation");
        return 0;
    }

    // Get a copy of the internal devicelink
    v = (_cmsTRANSFORM*) xform;
    DeviceLink = cmsPipelineDup(v ->Lut);
	if (DeviceLink == NULL) return 0;
   
  
	// We need a CLUT
	dwFlags |= cmsFLAGS_FORCE_CLUT;
	_cmsOptimizePipeline(&DeviceLink, RelativeEncodingIntent, &InFrm, &OutputFormat, &dwFlags);
  
    _cmsIOPrintf(m, "<<\n");
    _cmsIOPrintf(m, "/ColorRenderingType 1\n");


    cmsDetectBlackPoint(&BlackPointAdaptedToD50, hProfile, Intent, 0);

    // Emit headers, etc.
    EmitWhiteBlackD50(m, &BlackPointAdaptedToD50);
    EmitPQRStage(m, hProfile, lDoBPC, Intent == INTENT_ABSOLUTE_COLORIMETRIC);
    EmitXYZ2Lab(m);
        
   
    // FIXUP: map Lab (100, 0, 0) to perfect white, because the particular encoding for Lab 
    // does map a=b=0 not falling into any specific node. Since range a,b goes -128..127, 
    // zero is slightly moved towards right, so assure next node (in L=100 slice) is mapped to
    // zero. This would sacrifice a bit of highlights, but failure to do so would cause
    // scum dot. Ouch.
    
    if (Intent == INTENT_ABSOLUTE_COLORIMETRIC)
            lFixWhite = FALSE;

    _cmsIOPrintf(m, "/RenderTable ");
    
	
    WriteCLUT(m, cmsPipelineGetPtrToFirstStage(DeviceLink), "<", ">\n", "", "", lFixWhite, ColorSpace);
    
    _cmsIOPrintf(m, " %d {} bind ", nChannels);

    for (i=1; i < nChannels; i++)
            _cmsIOPrintf(m, "dup ");

    _cmsIOPrintf(m, "]\n");

        
    EmitIntent(m, Intent);

    _cmsIOPrintf(m, ">>\n");

    if (!(dwFlags & cmsFLAGS_NODEFAULTRESOURCEDEF)) {

        _cmsIOPrintf(m, "/Current exch /ColorRendering defineresource pop\n");
    }

    cmsPipelineFree(DeviceLink);
    cmsDeleteTransform(xform);
 
    return 1;   
}