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; }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_colortransfer_gui_data_t)); self->widget = gtk_label_new(_("this module will be removed in the future\nand is only here so you can " "switch it off\nand move to the new color mapping module.")); gtk_misc_set_alignment(GTK_MISC(self->widget), 0.0f, 0.5f); #if 0 self->gui_data = malloc(sizeof(dt_iop_colortransfer_gui_data_t)); dt_iop_colortransfer_gui_data_t *g = (dt_iop_colortransfer_gui_data_t *)self->gui_data; // dt_iop_colortransfer_params_t *p = (dt_iop_colortransfer_params_t *)self->params; g->flowback_set = 0; g->hsRGB = dt_colorspaces_create_srgb_profile(); g->hLab = dt_colorspaces_create_lab_profile(); g->xform = cmsCreateTransform(g->hLab, TYPE_Lab_DBL, g->hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0); self->widget = GTK_WIDGET(gtk_vbox_new(FALSE, DT_GUI_IOP_MODULE_CONTROL_SPACING)); g_signal_connect (G_OBJECT(self->widget), "expose-event", G_CALLBACK(expose), self); g->area = gtk_drawing_area_new(); gtk_widget_set_size_request(GTK_WIDGET(g->area), 300, 100); gtk_box_pack_start(GTK_BOX(self->widget), g->area, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (g->area), "expose-event", G_CALLBACK (cluster_preview_expose), self); GtkBox *box = GTK_BOX(gtk_hbox_new(FALSE, 5)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(box), TRUE, TRUE, 0); GtkWidget *button; g->spinbutton = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1, MAXN, 1)); g_object_set(G_OBJECT(g->spinbutton), "tooltip-text", _("number of clusters to find in image"), (char *)NULL); gtk_box_pack_start(box, GTK_WIDGET(g->spinbutton), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(g->spinbutton), "value-changed", G_CALLBACK(spinbutton_changed), (gpointer)self); button = dtgtk_button_new_with_label(_("acquire"), NULL, CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER); g->acquire_button = button; g_object_set(G_OBJECT(button), "tooltip-text", _("analyze this image"), (char *)NULL); gtk_box_pack_start(box, button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(acquire_button_pressed), (gpointer)self); g->apply_button = dtgtk_button_new_with_label(_("apply"), NULL, CPF_STYLE_FLAT|CPF_DO_NOT_USE_BORDER); g_object_set(G_OBJECT(g->apply_button), "tooltip-text", _("apply previously analyzed image look to this image"), (char *)NULL); gtk_box_pack_start(box, g->apply_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->apply_button), "clicked", G_CALLBACK(apply_button_pressed), (gpointer)self); FILE *f = fopen("/tmp/dt_colortransfer_loaded", "rb"); if(f) { if(fread(&g->flowback, self->params_size, 1, f) > 0) g->flowback_set = 1; fclose(f); } else gtk_widget_set_sensitive(GTK_WIDGET(g->apply_button), FALSE); #endif }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_colortransfer_gui_data_t)); self->widget = gtk_label_new(_("this module will be removed in the future\nand is only here so you can " "switch it off\nand move to the new color mapping module.")); gtk_widget_set_halign(self->widget, GTK_ALIGN_START); #if 0 self->gui_data = malloc(sizeof(dt_iop_colortransfer_gui_data_t)); dt_iop_colortransfer_gui_data_t *g = (dt_iop_colortransfer_gui_data_t *)self->gui_data; // dt_iop_colortransfer_params_t *p = (dt_iop_colortransfer_params_t *)self->params; g->flowback_set = 0; cmsHPROFILE hsRGB = dt_colorspaces_get_profile(DT_COLORSPACE_SRGB, "", DT_PROFILE_DIRECTION_IN)->profile; cmsHPROFILE hLab = dt_colorspaces_get_profile(DT_COLORSPACE_LAB, "", DT_PROFILE_DIRECTION_ANY)->profile; g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0); self->widget = GTK_WIDGET(gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_IOP_MODULE_CONTROL_SPACING)); g_signal_connect (G_OBJECT(self->widget), "draw", G_CALLBACK(draw), self); g->area = gtk_drawing_area_new(); gtk_widget_set_size_request(GTK_WIDGET(g->area), 300, 100); gtk_box_pack_start(GTK_BOX(self->widget), g->area, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (g->area), "draw", G_CALLBACK (cluster_preview_draw), self); GtkBox *box = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(box), TRUE, TRUE, 0); GtkWidget *button; g->spinbutton = GTK_SPIN_BUTTON(gtk_spin_button_new_with_range(1, MAXN, 1)); gtk_widget_set_tooltip_text(GTK_WIDGET(g->spinbutton), _("number of clusters to find in image")); gtk_box_pack_start(box, GTK_WIDGET(g->spinbutton), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(g->spinbutton), "value-changed", G_CALLBACK(spinbutton_changed), (gpointer)self); button = gtk_button_new_with_label(_("acquire")); g->acquire_button = button; gtk_widget_set_tooltip_text(button, _("analyze this image")); gtk_box_pack_start(box, button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(acquire_button_pressed), (gpointer)self); g->apply_button = gtk_button_new_with_label(_("apply")); gtk_widget_set_tooltip_text(g->apply_button, _("apply previously analyzed image look to this image")); gtk_box_pack_start(box, g->apply_button, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->apply_button), "clicked", G_CALLBACK(apply_button_pressed), (gpointer)self); FILE *f = g_fopen("/tmp/dt_colortransfer_loaded", "rb"); if(f) { if(fread(&g->flowback, self->params_size, 1, f) > 0) g->flowback_set = 1; fclose(f); } else gtk_widget_set_sensitive(GTK_WIDGET(g->apply_button), FALSE); #endif }
cmsHTRANSFORM cmmCreateTransform(cmsHPROFILE Input, DWORD InputFormat, cmsHPROFILE Output, DWORD OutputFormat, int Intent, DWORD dwFlags) { // Make sure that modifications are saved in the profile buffer for both in and out updateAll(Input); updateAll(Output); // Pass profiles to LCMS return cmsCreateTransform(Input, InputFormat, Output, OutputFormat, Intent, dwFlags); }
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); }
cmsHTRANSFORM dkCmsCreateTransform(cmsHPROFILE Input, DWORD InputFormat, cmsHPROFILE Output, DWORD OutputFormat, int Intent, DWORD dwFlags) { return cmsCreateTransform(Input, static_cast<cmsUInt32Number>( InputFormat ), Output, static_cast<cmsUInt32Number>( OutputFormat ), static_cast<cmsUInt32Number>( Intent ), static_cast<cmsUInt32Number>( dwFlags )); }
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; } } }
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; }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_monochrome_gui_data_t)); dt_iop_monochrome_gui_data_t *g = (dt_iop_monochrome_gui_data_t *)self->gui_data; g->dragging = 0; self->request_color_pick = DT_REQUEST_COLORPICK_OFF; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); dt_gui_add_help_link(self->widget, dt_get_help_url(self->op)); g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0); gtk_widget_set_tooltip_text(GTK_WIDGET(g->area), _("drag and scroll mouse wheel to adjust the virtual color filter")); gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | darktable.gui->scroll_mask); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_monochrome_draw), self); g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_monochrome_button_press), self); g_signal_connect(G_OBJECT(g->area), "button-release-event", G_CALLBACK(dt_iop_monochrome_button_release), self); g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_monochrome_motion_notify), self); g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_monochrome_leave_notify), self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_monochrome_scrolled), self); GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_BAUHAUS_SPACE); g->highlights = dt_bauhaus_slider_new_with_range(self, 0.0, 1.0, 0.01, 0.0, 2); gtk_widget_set_tooltip_text(g->highlights, _("how much to keep highlights")); dt_bauhaus_widget_set_label(g->highlights, NULL, _("highlights")); gtk_box_pack_start(GTK_BOX(box), g->highlights, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(g->highlights), "value-changed", G_CALLBACK(highlights_callback), self); g->colorpicker = dtgtk_togglebutton_new(dtgtk_cairo_paint_colorpicker, CPF_STYLE_FLAT | CPF_DO_NOT_USE_BORDER, NULL); gtk_widget_set_size_request(GTK_WIDGET(g->colorpicker), DT_PIXEL_APPLY_DPI(14), DT_PIXEL_APPLY_DPI(14)); gtk_box_pack_end(GTK_BOX(box), GTK_WIDGET(g->colorpicker), FALSE, FALSE, 0); g_signal_connect(G_OBJECT(g->colorpicker), "toggled", G_CALLBACK(picker_callback), self); gtk_box_pack_end(GTK_BOX(self->widget), GTK_WIDGET(box), TRUE, TRUE, 0); cmsHPROFILE hsRGB = dt_colorspaces_get_profile(DT_COLORSPACE_SRGB, "", DT_PROFILE_DIRECTION_IN)->profile; cmsHPROFILE hLab = dt_colorspaces_get_profile(DT_COLORSPACE_LAB, "", DT_PROFILE_DIRECTION_ANY)->profile; g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0); // cmsFLAGS_NOTPRECALC); }
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; }
int main(void) { cmsHPROFILE hInProfile, hOutProfile; cmsHTRANSFORM hTransform; int i; hInProfile = cmsOpenProfileFromFile("USWebCoatedSWOP.icc", "r"); hOutProfile = cmsOpenProfileFromFile("AdobeRGB1998.icc", "r"); hTransform = cmsCreateTransform(hInProfile, TYPE_CMYK_8, hOutProfile, TYPE_RGB_8, INTENT_PERCEPTUAL, 0); cmsCloseProfile(hInProfile); cmsCloseProfile(hOutProfile); return 0; }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_monochrome_gui_data_t)); dt_iop_monochrome_gui_data_t *g = (dt_iop_monochrome_gui_data_t *)self->gui_data; g->dragging = 0; self->widget = gtk_vbox_new(FALSE, DT_BAUHAUS_SPACE); g->area = GTK_DRAWING_AREA(gtk_drawing_area_new()); // GtkWidget *asp = gtk_aspect_frame_new(NULL, 0.5, 0.5, 1.0, TRUE); // gtk_box_pack_start(GTK_BOX(self->widget), asp, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0); // gtk_container_add(GTK_CONTAINER(asp), GTK_WIDGET(g->area)); gtk_drawing_area_size(g->area, 0, 258); g_object_set(G_OBJECT(g->area), "tooltip-text", _("drag and scroll mouse wheel to adjust the virtual color filter"), (char *)NULL); gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK); g_signal_connect (G_OBJECT (g->area), "expose-event", G_CALLBACK (dt_iop_monochrome_expose), self); g_signal_connect (G_OBJECT (g->area), "button-press-event", G_CALLBACK (dt_iop_monochrome_button_press), self); g_signal_connect (G_OBJECT (g->area), "button-release-event", G_CALLBACK (dt_iop_monochrome_button_release), self); g_signal_connect (G_OBJECT (g->area), "motion-notify-event", G_CALLBACK (dt_iop_monochrome_motion_notify), self); g_signal_connect (G_OBJECT (g->area), "leave-notify-event", G_CALLBACK (dt_iop_monochrome_leave_notify), self); g_signal_connect (G_OBJECT (g->area), "scroll-event", G_CALLBACK (dt_iop_monochrome_scrolled), self); g->highlights = dt_bauhaus_slider_new_with_range(self, 0.0, 1.0, 0.01, 0.0, 2); g_object_set (GTK_OBJECT(g->highlights), "tooltip-text", _("how much to keep highlights"), (char *)NULL); dt_bauhaus_widget_set_label(g->highlights, _("highlights")); gtk_box_pack_start(GTK_BOX(self->widget), g->highlights, TRUE, TRUE, 0); g_signal_connect (G_OBJECT (g->highlights), "value-changed", G_CALLBACK (highlights_callback), self); g->hsRGB = dt_colorspaces_create_srgb_profile(); g->hLab = dt_colorspaces_create_lab_profile(); g->xform = cmsCreateTransform(g->hLab, TYPE_Lab_DBL, g->hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);//cmsFLAGS_NOTPRECALC); }
/* Get the link from the CMS. TODO: Add error checking */ gcmmhlink_t gscms_get_link(gcmmhprofile_t lcms_srchandle, gcmmhprofile_t lcms_deshandle, gsicc_rendering_param_t *rendering_params) { DWORD src_data_type,des_data_type; icColorSpaceSignature src_color_space,des_color_space; int src_nChannels,des_nChannels; int lcms_src_color_space, lcms_des_color_space; /* Check for case of request for a transfrom from a device link profile in that case, the destination profile is NULL */ /* First handle all the source stuff */ src_color_space = cmsGetColorSpace(lcms_srchandle); lcms_src_color_space = _cmsLCMScolorSpace(src_color_space); /* littlecms returns -1 for types it does not (but should) understand */ if (lcms_src_color_space < 0) lcms_src_color_space = 0; src_nChannels = _cmsChannelsOf(src_color_space); /* For now, just do single byte data, interleaved. We can change this when we use the transformation. */ src_data_type = (COLORSPACE_SH(lcms_src_color_space)| CHANNELS_SH(src_nChannels)|BYTES_SH(2)); if (lcms_deshandle != NULL) { des_color_space = cmsGetColorSpace(lcms_deshandle); } else { /* We must have a device link profile. */ des_color_space = cmsGetPCS(lcms_deshandle); } lcms_des_color_space = _cmsLCMScolorSpace(des_color_space); if (lcms_des_color_space < 0) lcms_des_color_space = 0; des_nChannels = _cmsChannelsOf(des_color_space); des_data_type = (COLORSPACE_SH(lcms_des_color_space)| CHANNELS_SH(des_nChannels)|BYTES_SH(2)); /* Create the link */ return(cmsCreateTransform(lcms_srchandle, src_data_type, lcms_deshandle, des_data_type, rendering_params->rendering_intent, (cmsFLAGS_BLACKPOINTCOMPENSATION | cmsFLAGS_HIGHRESPRECALC))); /* cmsFLAGS_HIGHRESPRECALC) cmsFLAGS_NOTPRECALC cmsFLAGS_LOWRESPRECALC*/ }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_colorcorrection_gui_data_t)); dt_iop_colorcorrection_gui_data_t *g = (dt_iop_colorcorrection_gui_data_t *)self->gui_data; g->selected = 0; self->widget = gtk_vbox_new(FALSE, DT_BAUHAUS_SPACE); g->area = GTK_DRAWING_AREA(gtk_drawing_area_new()); GtkWidget *asp = gtk_aspect_frame_new(NULL, 0.5, 0.5, 1.0, TRUE); gtk_box_pack_start(GTK_BOX(self->widget), asp, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(asp), GTK_WIDGET(g->area)); gtk_drawing_area_size(g->area, 258, 258); g_object_set (GTK_OBJECT(g->area), "tooltip-text", _("drag the line for split toning. " "bright means highlights, dark means shadows. " "use mouse wheel to change saturation."), (char *)NULL); gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK); g_signal_connect (G_OBJECT (g->area), "expose-event", G_CALLBACK (dt_iop_colorcorrection_expose), self); g_signal_connect (G_OBJECT (g->area), "button-press-event", G_CALLBACK (dt_iop_colorcorrection_button_press), self); g_signal_connect (G_OBJECT (g->area), "motion-notify-event", G_CALLBACK (dt_iop_colorcorrection_motion_notify), self); g_signal_connect (G_OBJECT (g->area), "leave-notify-event", G_CALLBACK (dt_iop_colorcorrection_leave_notify), self); g_signal_connect (G_OBJECT (g->area), "scroll-event", G_CALLBACK (dt_iop_colorcorrection_scrolled), self); g->slider = dt_bauhaus_slider_new_with_range(self, -3.0f, 3.0f, 0.01f, 1.0f, 2); gtk_box_pack_start(GTK_BOX(self->widget), g->slider, TRUE, TRUE, 0); g_object_set (GTK_OBJECT(g->slider), "tooltip-text", _("set the global saturation"), (char *)NULL); dt_bauhaus_widget_set_label(g->slider,_("saturation")); g_signal_connect (G_OBJECT (g->slider), "value-changed", G_CALLBACK (sat_callback), self); g->hsRGB = dt_colorspaces_create_srgb_profile(); g->hLab = dt_colorspaces_create_lab_profile(); g->xform = cmsCreateTransform(g->hLab, TYPE_Lab_DBL, g->hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0);//cmsFLAGS_NOTPRECALC); }
static cmsHTRANSFORM _buildTransform(cmsHPROFILE hInputProfile, cmsHPROFILE hOutputProfile, char *sInMode, char *sOutMode, int iRenderingIntent, cmsUInt32Number cmsFLAGS) { cmsHTRANSFORM hTransform; Py_BEGIN_ALLOW_THREADS /* create the transform */ hTransform = cmsCreateTransform(hInputProfile, findLCMStype(sInMode), hOutputProfile, findLCMStype(sOutMode), iRenderingIntent, cmsFLAGS); Py_END_ALLOW_THREADS if (!hTransform) PyErr_SetString(PyExc_ValueError, "cannot build transform"); return hTransform; /* if NULL, an exception is set */ }
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); }
void gui_init(struct dt_iop_module_t *self) { self->gui_data = malloc(sizeof(dt_iop_colorcorrection_gui_data_t)); dt_iop_colorcorrection_gui_data_t *g = (dt_iop_colorcorrection_gui_data_t *)self->gui_data; g->selected = 0; self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_BAUHAUS_SPACE); g->area = GTK_DRAWING_AREA(dtgtk_drawing_area_new_with_aspect_ratio(1.0)); gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(g->area), TRUE, TRUE, 0); g_object_set(G_OBJECT(g->area), "tooltip-text", _("drag the line for split toning. " "bright means highlights, dark means shadows. " "use mouse wheel to change saturation."), (char *)NULL); gtk_widget_add_events(GTK_WIDGET(g->area), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_SCROLL_MASK); g_signal_connect(G_OBJECT(g->area), "draw", G_CALLBACK(dt_iop_colorcorrection_draw), self); g_signal_connect(G_OBJECT(g->area), "button-press-event", G_CALLBACK(dt_iop_colorcorrection_button_press), self); g_signal_connect(G_OBJECT(g->area), "motion-notify-event", G_CALLBACK(dt_iop_colorcorrection_motion_notify), self); g_signal_connect(G_OBJECT(g->area), "leave-notify-event", G_CALLBACK(dt_iop_colorcorrection_leave_notify), self); g_signal_connect(G_OBJECT(g->area), "scroll-event", G_CALLBACK(dt_iop_colorcorrection_scrolled), self); g->slider = dt_bauhaus_slider_new_with_range(self, -3.0f, 3.0f, 0.01f, 1.0f, 2); gtk_box_pack_start(GTK_BOX(self->widget), g->slider, TRUE, TRUE, 0); g_object_set(G_OBJECT(g->slider), "tooltip-text", _("set the global saturation"), (char *)NULL); dt_bauhaus_widget_set_label(g->slider, NULL, _("saturation")); g_signal_connect(G_OBJECT(g->slider), "value-changed", G_CALLBACK(sat_callback), self); cmsHPROFILE hsRGB = dt_colorspaces_get_profile(DT_COLORSPACE_SRGB, "", DT_PROFILE_DIRECTION_IN)->profile; cmsHPROFILE hLab = dt_colorspaces_get_profile(DT_COLORSPACE_LAB, "", DT_PROFILE_DIRECTION_ANY)->profile; g->xform = cmsCreateTransform(hLab, TYPE_Lab_DBL, hsRGB, TYPE_RGB_DBL, INTENT_PERCEPTUAL, 0); // cmsFLAGS_NOTPRECALC); }
void TestKoLcmsColorProfile::testConversion() { const KoColorSpace *sRgb = KoColorSpaceRegistry::instance()->rgb16("sRGB built-in"); Q_ASSERT(sRgb); const KoColorSpace *linearRgb = KoColorSpaceRegistry::instance()->rgb16("scRGB (linear)"); Q_ASSERT(linearRgb); quint16 src[4]; src[0] = 257; src[1] = 257; src[2] = 257; src[3] = 65535; quint16 dst[4]; memset(&dst, 0, 8); linearRgb->convertPixelsTo((quint8 *)&src, (quint8 *)&dst, sRgb, 1, KoColorConversionTransformation::IntentRelativeColorimetric, KoColorConversionTransformation::BlackpointCompensation); quint16 dst2[4]; memset(&dst2, 0, 8); cmsHPROFILE sRgbProfile = cmsCreate_sRGBProfile(); QByteArray rawData = linearRgb->profile()->rawData(); cmsHPROFILE linearRgbProfile = cmsOpenProfileFromMem((void *)rawData.constData(), rawData.size()); cmsHTRANSFORM tf = cmsCreateTransform(linearRgbProfile, TYPE_BGRA_16, sRgbProfile, TYPE_BGRA_16, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); cmsDoTransform(tf, (quint8 *)&src, (quint8 *)&dst2, 1); Q_ASSERT(dst[0] == dst2[0]); }
static cmsHTRANSFORM cd_sensor_get_fake_transform (CdSensorDummyPrivate *priv) { cmsHTRANSFORM transform; cmsHPROFILE profile_srgb; cmsHPROFILE profile_xyz; profile_srgb = cmsCreate_sRGBProfile (); profile_xyz = cmsCreateXYZProfile (); transform = cmsCreateTransform (profile_srgb, TYPE_RGB_DBL, profile_xyz, TYPE_XYZ_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE); if (transform == NULL) { g_warning ("failed to setup RGB -> XYZ transform"); goto out; } out: if (profile_srgb != NULL) cmsCloseProfile (profile_srgb); if (profile_xyz != NULL) cmsCloseProfile (profile_xyz); return transform; }
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); };
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 lcms_image_transform_rgb (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { cmsHTRANSFORM transform = NULL; DWORD last_format = 0; gint *layers; gint num_layers; gint i; layers = gimp_image_get_layers (image, &num_layers); for (i = 0; i < num_layers; i++) { GimpDrawable *drawable = gimp_drawable_get (layers[i]); DWORD format; switch (drawable->bpp) { case 3: format = TYPE_RGB_8; break; case 4: format = TYPE_RGBA_8; break; default: g_warning ("%s: unexpected bpp", G_STRLOC); continue; } if (! transform || format != last_format) { if (transform) cmsDeleteTransform (transform); transform = cmsCreateTransform (src_profile, format, dest_profile, format, intent, bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0); last_format = format; } if (transform) { lcms_drawable_transform (drawable, transform, (gdouble) i / num_layers, (gdouble) (i + 1) / num_layers); } else { g_warning ("cmsCreateTransform() failed!"); } gimp_drawable_detach (drawable); } if (transform) cmsDeleteTransform(transform); g_free (layers); }
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); }
void CLASS apply_profile (const char *input, const char *output) { char *prof; cmsHPROFILE hInProfile=0, hOutProfile=0; cmsHTRANSFORM hTransform; FILE *fp; unsigned size; #ifndef USE_LCMS2 cmsErrorAction (LCMS_ERROR_SHOW); #endif if (strcmp (input, "embed")) hInProfile = cmsOpenProfileFromFile (input, "r"); else if (profile_length) { #ifndef LIBRAW_LIBRARY_BUILD prof = (char *) malloc (profile_length); merror (prof, "apply_profile()"); fseek (ifp, profile_offset, SEEK_SET); fread (prof, 1, profile_length, ifp); hInProfile = cmsOpenProfileFromMem (prof, profile_length); free (prof); #else hInProfile = cmsOpenProfileFromMem (imgdata.color.profile, profile_length); #endif } else { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_NO_EMBEDDED_PROFILE; #endif #ifdef DCRAW_VERBOSE fprintf (stderr,_("%s has no embedded profile.\n"), ifname); #endif } if (!hInProfile) { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_NO_INPUT_PROFILE; #endif return; } if (!output) hOutProfile = cmsCreate_sRGBProfile(); else if ((fp = fopen (output, "rb"))) { fread (&size, 4, 1, fp); fseek (fp, 0, SEEK_SET); oprof = (unsigned *) malloc (size = ntohl(size)); merror (oprof, "apply_profile()"); fread (oprof, 1, size, fp); fclose (fp); if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { free (oprof); oprof = 0; } } #ifdef DCRAW_VERBOSE else fprintf (stderr,_("Cannot open file %s!\n"), output); #endif if (!hOutProfile) { #ifdef LIBRAW_LIBRARY_BUILD imgdata.process_warnings |= LIBRAW_WARN_BAD_OUTPUT_PROFILE; #endif goto quit; } #ifdef DCRAW_VERBOSE if (verbose) fprintf (stderr,_("Applying color profile...\n")); #endif #ifdef LIBRAW_LIBRARY_BUILD RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,0,2); #endif hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); cmsDoTransform (hTransform, image, image, width*height); raw_color = 1; /* Don't use rgb_cam with a profile */ cmsDeleteTransform (hTransform); cmsCloseProfile (hOutProfile); quit: cmsCloseProfile (hInProfile); #ifdef LIBRAW_LIBRARY_BUILD RUN_CALLBACK(LIBRAW_PROGRESS_APPLY_PROFILE,1,2); #endif }
GimpColorTransform gimp_widget_get_color_transform (GtkWidget *widget, GimpColorConfig *config, GimpColorProfile *src_profile, const Babl **src_format, const Babl **dest_format) { GimpColorTransform transform = NULL; GimpColorProfile *dest_profile = NULL; GimpColorProfile *proof_profile = NULL; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, }; g_return_val_if_fail (widget == NULL || GTK_IS_WIDGET (widget), NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL); g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL); g_return_val_if_fail (src_format != NULL, NULL); g_return_val_if_fail (dest_format != NULL, NULL); switch (config->mode) { case GIMP_COLOR_MANAGEMENT_OFF: return NULL; case GIMP_COLOR_MANAGEMENT_SOFTPROOF: proof_profile = gimp_color_config_get_printer_color_profile (config, NULL); /* fallthru */ case GIMP_COLOR_MANAGEMENT_DISPLAY: dest_profile = get_display_profile (widget, config); break; } src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); *src_format = gimp_color_profile_get_format (*src_format, &lcms_src_format); *dest_format = gimp_color_profile_get_format (*dest_format, &lcms_dest_format); if (proof_profile) { cmsHPROFILE proof_lcms; cmsUInt32Number softproof_flags = cmsFLAGS_SOFTPROOFING; proof_lcms = gimp_color_profile_get_lcms_profile (proof_profile); if (config->simulation_use_black_point_compensation) { softproof_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } if (config->simulation_gamut_check) { guchar r, g, b; softproof_flags |= cmsFLAGS_GAMUTCHECK; gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b); alarmCodes[0] = (cmsUInt16Number) r * 256; alarmCodes[1] = (cmsUInt16Number) g * 256; alarmCodes[2] = (cmsUInt16Number) b * 256; cmsSetAlarmCodes (alarmCodes); } transform = cmsCreateProofingTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, proof_lcms, config->simulation_intent, config->display_intent, softproof_flags); g_object_unref (proof_profile); } else if (! gimp_color_profile_is_equal (src_profile, dest_profile)) { cmsUInt32Number display_flags = 0; if (config->display_use_black_point_compensation) { display_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } transform = cmsCreateTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, config->display_intent, display_flags); } g_object_unref (dest_profile); return transform; }
/** * gimp_color_transform_new: * @src_profile: * @src_format: * @desr_profile: * @dest_format: * @rendering_intent: * @flags: * * This function creates an color transform. * * Return value: the #GimpColorTransform, or %NULL if no transform is needed * to convert between pixels of @src_profile and @dest_profile. * * Since: 2.10 **/ GimpColorTransform * gimp_color_transform_new (GimpColorProfile *src_profile, const Babl *src_format, GimpColorProfile *dest_profile, const Babl *dest_format, GimpColorRenderingIntent rendering_intent, GimpColorTransformFlags flags) { GimpColorTransform *transform; GimpColorTransformPrivate *priv; cmsHPROFILE src_lcms; cmsHPROFILE dest_lcms; cmsUInt32Number lcms_src_format; cmsUInt32Number lcms_dest_format; g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL); g_return_val_if_fail (src_format != NULL, NULL); g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), NULL); g_return_val_if_fail (dest_format != NULL, NULL); if (gimp_color_transform_can_gegl_copy (src_profile, dest_profile)) return NULL; transform = g_object_new (GIMP_TYPE_COLOR_TRANSFORM, NULL); priv = transform->priv; src_lcms = gimp_color_profile_get_lcms_profile (src_profile); dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile); priv->src_format = gimp_color_profile_get_format (src_format, &lcms_src_format); priv->dest_format = gimp_color_profile_get_format (dest_format, &lcms_dest_format); lcms_error_clear (); priv->transform = cmsCreateTransform (src_lcms, lcms_src_format, dest_lcms, lcms_dest_format, rendering_intent, flags); if (lcms_last_error) { if (priv->transform) { cmsDeleteTransform (priv->transform); priv->transform = NULL; } g_printerr ("%s\n", lcms_last_error); } if (! priv->transform) { g_object_unref (transform); transform = NULL; } return transform; }
static void cdisplay_lcms_changed (GimpColorDisplay *display) { CdisplayLcms *lcms = CDISPLAY_LCMS (display); GimpColorConfig *config = gimp_color_display_get_config (display); cmsHPROFILE src_profile = NULL; cmsHPROFILE dest_profile = NULL; cmsHPROFILE proof_profile = NULL; cmsUInt16Number alarmCodes[cmsMAXCHANNELS] = { 0, }; if (lcms->transform) { cmsDeleteTransform (lcms->transform); lcms->transform = NULL; } if (! config) return; switch (config->mode) { case GIMP_COLOR_MANAGEMENT_OFF: return; case GIMP_COLOR_MANAGEMENT_SOFTPROOF: proof_profile = cdisplay_lcms_get_printer_profile (lcms); /* fallthru */ case GIMP_COLOR_MANAGEMENT_DISPLAY: src_profile = cdisplay_lcms_get_rgb_profile (lcms); dest_profile = cdisplay_lcms_get_display_profile (lcms); break; } if (proof_profile) { cmsUInt32Number softproof_flags = 0; if (! src_profile) src_profile = gimp_lcms_create_srgb_profile (); if (! dest_profile) dest_profile = gimp_lcms_create_srgb_profile (); softproof_flags |= cmsFLAGS_SOFTPROOFING; if (config->simulation_use_black_point_compensation) { softproof_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } if (config->simulation_gamut_check) { guchar r, g, b; softproof_flags |= cmsFLAGS_GAMUTCHECK; gimp_rgb_get_uchar (&config->out_of_gamut_color, &r, &g, &b); alarmCodes[0] = (cmsUInt16Number) r * 256; alarmCodes[1] = (cmsUInt16Number) g * 256; alarmCodes[2] = (cmsUInt16Number) b * 256; cmsSetAlarmCodes (alarmCodes); } lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_RGBA_FLT, dest_profile, TYPE_RGBA_FLT, proof_profile, config->simulation_intent, config->display_intent, softproof_flags); cmsCloseProfile (proof_profile); } else if (src_profile || dest_profile) { cmsUInt32Number display_flags = 0; if (! src_profile) src_profile = gimp_lcms_create_srgb_profile (); if (! dest_profile) dest_profile = gimp_lcms_create_srgb_profile (); if (config->display_use_black_point_compensation) { display_flags |= cmsFLAGS_BLACKPOINTCOMPENSATION; } lcms->transform = cmsCreateTransform (src_profile, TYPE_RGBA_FLT, dest_profile, TYPE_RGBA_FLT, config->display_intent, display_flags); } if (dest_profile) cmsCloseProfile (dest_profile); if (src_profile) cmsCloseProfile (src_profile); }
// Creates all needed color transforms static cmsBool OpenTransforms(void) { cmsHPROFILE hInput, hOutput, hProof; cmsUInt32Number dwIn, dwOut, dwFlags; cmsNAMEDCOLORLIST* List; int i; // We don't need cache dwFlags = cmsFLAGS_NOCACHE; if (lIsDeviceLink) { hInput = OpenStockProfile(0, cInProf); if (hInput == NULL) return FALSE; hOutput = NULL; hProof = NULL; if (cmsGetDeviceClass(hInput) == cmsSigNamedColorClass) { OutputColorSpace = cmsGetColorSpace(hInput); InputColorSpace = cmsGetPCS(hInput); } else { InputColorSpace = cmsGetColorSpace(hInput); OutputColorSpace = cmsGetPCS(hInput); } // Read colorant tables if present if (cmsIsTag(hInput, cmsSigColorantTableTag)) { List = cmsReadTag(hInput, cmsSigColorantTableTag); InputColorant = cmsDupNamedColorList(List); InputRange = 1; } else InputColorant = ComponentNames(InputColorSpace, TRUE); if (cmsIsTag(hInput, cmsSigColorantTableOutTag)){ List = cmsReadTag(hInput, cmsSigColorantTableOutTag); OutputColorant = cmsDupNamedColorList(List); OutputRange = 1; } else OutputColorant = ComponentNames(OutputColorSpace, FALSE); } else { hInput = OpenStockProfile(0, cInProf); if (hInput == NULL) return FALSE; hOutput = OpenStockProfile(0, cOutProf); if (hOutput == NULL) return FALSE; hProof = NULL; if (cmsGetDeviceClass(hInput) == cmsSigLinkClass || cmsGetDeviceClass(hOutput) == cmsSigLinkClass) FatalError("Use %cl flag for devicelink profiles!\n", SW); InputColorSpace = cmsGetColorSpace(hInput); OutputColorSpace = cmsGetColorSpace(hOutput); // Read colorant tables if present if (cmsIsTag(hInput, cmsSigColorantTableTag)) { List = cmsReadTag(hInput, cmsSigColorantTableTag); InputColorant = cmsDupNamedColorList(List); if (cmsNamedColorCount(InputColorant) <= 3) SetRange(255, TRUE); else SetRange(1, TRUE); // Inks are already divided by 100 in the formatter } else InputColorant = ComponentNames(InputColorSpace, TRUE); if (cmsIsTag(hOutput, cmsSigColorantTableTag)){ List = cmsReadTag(hOutput, cmsSigColorantTableTag); OutputColorant = cmsDupNamedColorList(List); if (cmsNamedColorCount(OutputColorant) <= 3) SetRange(255, FALSE); else SetRange(1, FALSE); // Inks are already divided by 100 in the formatter } else OutputColorant = ComponentNames(OutputColorSpace, FALSE); if (cProofing != NULL) { hProof = OpenStockProfile(0, cProofing); if (hProof == NULL) return FALSE; dwFlags |= cmsFLAGS_SOFTPROOFING; } } // Print information on profiles if (Verbose > 2) { printf("Profile:\n"); PrintProfileInformation(hInput); if (hOutput) { printf("Output profile:\n"); PrintProfileInformation(hOutput); } if (hProof != NULL) { printf("Proofing profile:\n"); PrintProfileInformation(hProof); } } // Input is always in floating point dwIn = cmsFormatterForColorspaceOfProfile(hInput, 0, TRUE); if (lIsDeviceLink) { dwOut = cmsFormatterForPCSOfProfile(hInput, lIsFloat ? 0 : 2, lIsFloat); } else { // 16 bits or floating point (only on output) dwOut = cmsFormatterForColorspaceOfProfile(hOutput, lIsFloat ? 0 : 2, lIsFloat); } // For named color, there is a specialized formatter if (cmsGetDeviceClass(hInput) == cmsSigNamedColorClass) { dwIn = TYPE_NAMED_COLOR_INDEX; InputNamedColor = TRUE; } // Precision mode switch (PrecalcMode) { case 0: dwFlags |= cmsFLAGS_NOOPTIMIZE; break; case 2: dwFlags |= cmsFLAGS_HIGHRESPRECALC; break; case 3: dwFlags |= cmsFLAGS_LOWRESPRECALC; break; case 1: break; default: FatalError("Unknown precalculation mode '%d'", PrecalcMode); } if (BlackPointCompensation) dwFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION; if (GamutCheck) { cmsUInt16Number Alarm[cmsMAXCHANNELS]; if (hProof == NULL) FatalError("I need proofing profile -p for gamut checking!"); for (i=0; i < cmsMAXCHANNELS; i++) Alarm[i] = 0xFFFF; cmsSetAlarmCodes(Alarm); dwFlags |= cmsFLAGS_GAMUTCHECK; } // The main transform hTrans = cmsCreateProofingTransform(hInput, dwIn, hOutput, dwOut, hProof, Intent, ProofingIntent, dwFlags); if (hProof) cmsCloseProfile(hProof); if (hTrans == NULL) return FALSE; // PCS Dump if requested hTransXYZ = NULL; hTransLab = NULL; if (hOutput && Verbose > 1) { cmsHPROFILE hXYZ = cmsCreateXYZProfile(); cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); hTransXYZ = cmsCreateTransform(hInput, dwIn, hXYZ, lIsFloat ? TYPE_XYZ_DBL : TYPE_XYZ_16, Intent, cmsFLAGS_NOCACHE); if (hTransXYZ == NULL) return FALSE; hTransLab = cmsCreateTransform(hInput, dwIn, hLab, lIsFloat? TYPE_Lab_DBL : TYPE_Lab_16, Intent, cmsFLAGS_NOCACHE); if (hTransLab == NULL) return FALSE; cmsCloseProfile(hXYZ); cmsCloseProfile(hLab); } if (hInput) cmsCloseProfile(hInput); if (hOutput) cmsCloseProfile(hOutput); return TRUE; }