int cmmMultiprofileSampler(WORD In[], WORD Out[], LPVOID Cargo) { int i; cmsHTRANSFORM* Transforms = (cmsHTRANSFORM*)Cargo; // Need to go from In to Out at least once cmsDoTransform(Transforms[0], In, Out, 1); for (i=1; Transforms[i]; i++) cmsDoTransform(Transforms[i], Out, Out, 1); return TRUE; }
static int BlackPointUsingPerceptualBlack(LPcmsCIEXYZ BlackPoint, cmsHPROFILE hProfile, DWORD dwFlags) { cmsHTRANSFORM hPercLab2CMYK, hRelColCMYK2Lab; cmsHPROFILE hLab; cmsCIELab LabIn, LabOut; WORD CMYK[MAXCHANNELS]; cmsCIEXYZ BlackXYZ, MediaWhite; if (!cmsIsIntentSupported(hProfile, INTENT_PERCEPTUAL, LCMS_USED_AS_INPUT)) { BlackPoint -> X = BlackPoint ->Y = BlackPoint -> Z = 0.0; return 0; } hLab = cmsCreateLabProfile(NULL); hPercLab2CMYK = cmsCreateTransform(hLab, TYPE_Lab_DBL, hProfile, TYPE_CMYK_16, INTENT_PERCEPTUAL, cmsFLAGS_NOTPRECALC); hRelColCMYK2Lab = cmsCreateTransform(hProfile, TYPE_CMYK_16, hLab, TYPE_Lab_DBL, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOTPRECALC); LabIn.L = LabIn.a = LabIn.b = 0; cmsDoTransform(hPercLab2CMYK, &LabIn, CMYK, 1); cmsDoTransform(hRelColCMYK2Lab, CMYK, &LabOut, 1); if (LabOut.L > 50) LabOut.L = 50; LabOut.a = LabOut.b = 0; cmsDeleteTransform(hPercLab2CMYK); cmsDeleteTransform(hRelColCMYK2Lab); cmsCloseProfile(hLab); cmsLab2XYZ(NULL, &BlackXYZ, &LabOut); if (!(dwFlags & LCMS_BPFLAGS_D50_ADAPTED)){ cmsTakeMediaWhitePoint(&MediaWhite, hProfile); cmsAdaptToIlluminant(BlackPoint, cmsD50_XYZ(), &MediaWhite, &BlackXYZ); } else *BlackPoint = BlackXYZ; return 1; }
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 int SoftProofSampler(register WORD In[], register WORD Out[], register LPVOID Cargo) { LPGAMUTCHAIN t = (LPGAMUTCHAIN) Cargo; WORD Colorant[MAXCHANNELS]; // From pcs to colorant cmsDoTransform(t -> hForward, In, Colorant, 1); // Now, do the inverse, from colorant to pcs. cmsDoTransform(t -> hReverse, Colorant, Out, 1); return TRUE; }
int main(int argc, char *argv[]) { WORD Input[MAXCHANNELS], Output[MAXCHANNELS], PCSLab[MAXCHANNELS], PCSxyz[MAXCHANNELS]; fprintf(stderr, "little cms ColorSpace conversion calculator - v1.8\n\n"); if (argc == 1) Help(); HandleSwitches(argc, argv); cmsSetErrorHandler(MyErrorHandler); OpenTransforms(); for(;;) { if (xisatty(stdin)) printf("\nEnter values, 'q' to quit\n"); if (feof(stdin)) break; TakeValues(Input); cmsDoTransform(hTrans, Input, Output, 1); if (Verbose) { if (hTransXYZ) cmsDoTransform(hTransXYZ, Input, PCSxyz, 1); if (hTransLab) cmsDoTransform(hTransLab, Input, PCSLab, 1); } if (xisatty(stdin)) printf("\n"); PrintResults(Output, OutputColorSpace); printf("\n"); if (Verbose && hTransXYZ && hTransLab) { PrintResults(PCSxyz, icSigXYZData); printf("\n"); PrintResults(PCSLab, icSigLabData); printf("\n"); } } return 0; }
static void PrintPCSEncoded(cmsFloat64Number Input[]) { if (Verbose > 1 && hTransXYZ && hTransLab) { cmsUInt16Number XYZ[3], Lab[3]; if (hTransXYZ) cmsDoTransform(hTransXYZ, Input, XYZ, 1); if (hTransLab) cmsDoTransform(hTransLab, Input, Lab, 1); printf("[PCS] Lab=(0x%04X,0x%04X,0x%04X) XYZ=(0x%04X,0x%04X,0x%04X)\n", Lab[0], Lab[1], Lab[2], XYZ[0], XYZ[1], XYZ[2]); } }
void color_man_correct_region(ColorMan *cm, GdkPixbuf *pixbuf, gint x, gint y, gint w, gint h) { ColorManCache *cc; guchar *pix; gint rs; gint i; gint pixbuf_width, pixbuf_height; pixbuf_width = gdk_pixbuf_get_width(pixbuf); pixbuf_height = gdk_pixbuf_get_height(pixbuf); cc = cm->profile; pix = gdk_pixbuf_get_pixels(pixbuf); rs = gdk_pixbuf_get_rowstride(pixbuf); w = MIN(w, pixbuf_width - x); h = MIN(h, pixbuf_height - y); pix += x * ((cc->has_alpha) ? 4 : 3); for (i = 0; i < h; i++) { guchar *pbuf; pbuf = pix + ((y + i) * rs); cmsDoTransform(cc->transform, pbuf, pbuf, w); } }
static void jpeg_load_cmyk_to_rgb (guchar *buf, glong pixels, gpointer transform) { const guchar *src = buf; guchar *dest = buf; if (transform) { cmsDoTransform (transform, buf, buf, pixels); return; } /* NOTE: The following code assumes inverted CMYK values, even when an APP14 marker doesn't exist. This is the behavior of recent versions of PhotoShop as well. */ while (pixels--) { guint c = src[0]; guint m = src[1]; guint y = src[2]; guint k = src[3]; dest[0] = (c * k) / 255; dest[1] = (m * k) / 255; dest[2] = (y * k) / 255; src += 4; dest += 3; } }
/** * cd_icc_effect_generate_cogl_color_data: **/ static CoglHandle cd_icc_effect_generate_cogl_color_data (const gchar *filename, GError **error) { CoglHandle tex = NULL; cmsHPROFILE device_profile; cmsHPROFILE srgb_profile; cmsUInt8Number *data; cmsHTRANSFORM transform; guint array_size; guint r, g, b; guint8 *p; cmsSetLogErrorHandler (cd_icc_effect_error_cb); srgb_profile = cmsCreate_sRGBProfile (); device_profile = cmsOpenProfileFromFile (filename, "r"); /* create a cube and cut itup into parts */ array_size = GCM_GLSL_LOOKUP_SIZE * GCM_GLSL_LOOKUP_SIZE * GCM_GLSL_LOOKUP_SIZE; data = g_new0 (cmsUInt8Number, 3 * array_size); transform = cmsCreateTransform (srgb_profile, TYPE_RGB_8, device_profile, TYPE_RGB_8, INTENT_PERCEPTUAL, 0); /* we failed */ if (transform == NULL) { g_set_error (error, 1, 0, "could not create transform"); goto out; } /* create mapping (blue->r, green->t, red->s) */ for (p = data, b = 0; b < GCM_GLSL_LOOKUP_SIZE; b++) { for (g = 0; g < GCM_GLSL_LOOKUP_SIZE; g++) { for (r = 0; r < GCM_GLSL_LOOKUP_SIZE; r++) { *(p++) = (r * 255) / (GCM_GLSL_LOOKUP_SIZE - 1); *(p++) = (g * 255) / (GCM_GLSL_LOOKUP_SIZE - 1); *(p++) = (b * 255) / (GCM_GLSL_LOOKUP_SIZE - 1); } } } cmsDoTransform (transform, data, data, array_size); /* creates a cogl texture from the data */ tex = cogl_texture_3d_new_from_data (GCM_GLSL_LOOKUP_SIZE, /* width */ GCM_GLSL_LOOKUP_SIZE, /* height */ GCM_GLSL_LOOKUP_SIZE, /* depth */ COGL_TEXTURE_NO_AUTO_MIPMAP, COGL_PIXEL_FORMAT_RGB_888, COGL_PIXEL_FORMAT_ANY, /* data is tightly packed so we can pass zero */ 0, 0, data, error); out: cmsCloseProfile (device_profile); cmsCloseProfile (srgb_profile); if (transform != NULL) cmsDeleteTransform (transform); g_free (data); return tex; }
static gboolean cd_sensor_get_sample_wait_cb (GTask *task) { CdSensor *sensor = CD_SENSOR (g_task_get_source_object (task)); CdSensorDummyPrivate *priv = cd_sensor_dummy_get_private (sensor); CdColorXYZ *sample = NULL; g_autoptr(GError) error = NULL; /* never setup */ if (priv->transform_fake == NULL) { g_task_return_new_error (task, CD_SENSOR_ERROR, CD_SENSOR_ERROR_NO_SUPPORT, "no fake transfor set up"); return G_SOURCE_REMOVE; } /* run the sample through the profile */ sample = cd_color_xyz_new (); cmsDoTransform (priv->transform_fake, &priv->sample_fake, sample, 1); /* emulate */ cd_sensor_button_pressed (sensor); /* just return without a problem */ g_task_return_pointer (task, sample, (GDestroyNotify) cd_color_xyz_free); return G_SOURCE_REMOVE; }
static void jpeg_load_cmyk_to_rgb (guchar *buf, glong pixels, gpointer transform) { const guchar *src = buf; guchar *dest = buf; if (transform) { cmsDoTransform (transform, buf, buf, pixels); return; } while (pixels--) { guint c = src[0]; guint m = src[1]; guint y = src[2]; guint k = src[3]; dest[0] = (c * k) / 255; dest[1] = (m * k) / 255; dest[2] = (y * k) / 255; src += 4; dest += 3; } }
static VALUE transform_convert(int argc, VALUE *argv, VALUE self){ if(argc != 4){ return Qnil; } cmsHPROFILE hInProfile, hOutProfile; cmsHTRANSFORM hTransform; VALUE in = rb_iv_get(self, "@in"); VALUE out = rb_iv_get(self, "@out"); hInProfile = cmsOpenProfileFromFile(RSTRING(in)->ptr, "r"); hOutProfile = cmsOpenProfileFromFile(RSTRING(out)->ptr, "r"); hTransform = cmsCreateTransform(hInProfile, TYPE_CMYK_8, hOutProfile, TYPE_RGB_8, INTENT_PERCEPTUAL, 0); cmsCloseProfile(hInProfile); cmsCloseProfile(hOutProfile); //TODO: Remove duplication cmsUInt8Number cmyk_temp[4] = { NUM2INT(argv[0]), NUM2INT(argv[1]), NUM2INT(argv[2]), NUM2INT(argv[3]) };; cmsUInt8Number rgb_temp[3]; // printf("Transfrom result is cmyk(%d, %d, %d, %d)\n", cmyk_temp[0], cmyk_temp[1], cmyk_temp[2], cmyk_temp[3]); cmsDoTransform(hTransform, cmyk_temp, rgb_temp, 1); // printf("Transfrom result is rgb(%d, %d, %d)\n", rgb_temp[0], rgb_temp[1], rgb_temp[2]); return rb_ary_new3(3, INT2FIX(rgb_temp[0]), INT2FIX(rgb_temp[1]), INT2FIX(rgb_temp[2])); }
static void PrintPCSFloat(cmsFloat64Number Input[]) { if (Verbose > 1 && hTransXYZ && hTransLab) { cmsCIEXYZ XYZ = { 0, 0, 0 }; cmsCIELab Lab = { 0, 0, 0 }; if (hTransXYZ) cmsDoTransform(hTransXYZ, Input, &XYZ, 1); if (hTransLab) cmsDoTransform(hTransLab, Input, &Lab, 1); printf("[PCS] Lab=(%.4f,%.4f,%.4f) XYZ=(%.4f,%.4f,%.4f)\n", Lab.L, Lab.a, Lab.b, XYZ.X * 100.0, XYZ.Y * 100.0, XYZ.Z * 100.0); } }
static PyObject * pycms_TransformPixel (PyObject *self, PyObject *args) { unsigned char *inbuf; int channel1,channel2,channel3,channel4; void *transform; cmsHTRANSFORM hTransform; PyObject *result; if (!PyArg_ParseTuple(args, "Oiiii", &transform, &channel1, &channel2, &channel3, &channel4)) { Py_INCREF(Py_None); return Py_None; } inbuf=malloc(4); inbuf[0]=(unsigned char)channel1; inbuf[1]=(unsigned char)channel2; inbuf[2]=(unsigned char)channel3; inbuf[3]=(unsigned char)channel4; hTransform = (cmsHTRANSFORM) PyCObject_AsVoidPtr(transform); cmsDoTransform(hTransform, inbuf, inbuf, 1); result = Py_BuildValue("[iiii]", inbuf[0], inbuf[1], inbuf[2], inbuf[3]); free(inbuf); return result; }
static PyObject * pycms_TransformPixel2 (PyObject *self, PyObject *args) { double channel1,channel2,channel3,channel4; unsigned char *inbuf; void *transform; cmsHTRANSFORM hTransform; PyObject *result; if (!PyArg_ParseTuple(args, "Odddd", &transform, &channel1, &channel2, &channel3, &channel4)) { Py_INCREF(Py_None); return Py_None; } inbuf=malloc(4); inbuf[0]=(unsigned char)(channel1*255); inbuf[1]=(unsigned char)(channel2*255); inbuf[2]=(unsigned char)(channel3*255); inbuf[3]=(unsigned char)(channel4*255); hTransform = (cmsHTRANSFORM) PyCObject_AsVoidPtr(transform); cmsDoTransform(hTransform, inbuf, inbuf, 1); result = Py_BuildValue("(dddd)", (double)inbuf[0]/255, (double)inbuf[1]/255, (double)inbuf[2]/255, (double)inbuf[3]/255); free(inbuf); return result; }
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); }
// 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 LPGAMMATABLE ComputeKToLstar(cmsHPROFILE hProfile, int nPoints, int Intent, DWORD dwFlags) { LPGAMMATABLE out; int i; WORD cmyk[4], wLab[3]; cmsHPROFILE hLab = cmsCreateLabProfile(NULL); cmsHTRANSFORM xform = cmsCreateTransform(hProfile, TYPE_CMYK_16, hLab, TYPE_Lab_16, Intent, (dwFlags|cmsFLAGS_NOTPRECALC)); out = cmsAllocGamma(nPoints); for (i=0; i < nPoints; i++) { cmyk[0] = 0; cmyk[1] = 0; cmyk[2] = 0; cmyk[3] = _cmsQuantizeVal(i, nPoints); cmsDoTransform(xform, cmyk, wLab, 1); out->GammaTable[i] = (WORD) (0xFFFF - wLab[0]); } cmsDeleteTransform(xform); cmsCloseProfile(hLab); return out; }
// This callback just accounts the maximum ink dropped in the given node. It does not populate any // memory, as the destination table is NULL. Its only purpose it to know the global maximum. static int EstimateTAC(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void * Cargo) { cmsTACestimator* bp = (cmsTACestimator*) Cargo; cmsFloat32Number RoundTrip[cmsMAXCHANNELS]; cmsUInt32Number i; cmsFloat32Number Sum; // Evaluate the xform cmsDoTransform(bp->hRoundTrip, In, RoundTrip, 1); // All all amounts of ink for (Sum=0, i=0; i < bp ->nOutputChans; i++) Sum += RoundTrip[i]; // If above maximum, keep track of input values if (Sum > bp ->MaxTAC) { bp ->MaxTAC = Sum; for (i=0; i < bp ->nOutputChans; i++) { bp ->MaxInput[i] = In[i]; } } return TRUE; cmsUNUSED_PARAMETER(Out); }
static void lcms_image_transform_indexed (gint32 image, cmsHPROFILE src_profile, cmsHPROFILE dest_profile, GimpColorRenderingIntent intent, gboolean bpc) { cmsHTRANSFORM transform; guchar *cmap; gint num_colors; cmap = gimp_image_get_colormap (image, &num_colors); transform = cmsCreateTransform (src_profile, TYPE_RGB_8, dest_profile, TYPE_RGB_8, intent, bpc ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0); if (transform) { cmsDoTransform (transform, cmap, cmap, num_colors); cmsDeleteTransform(transform); } else { g_warning ("cmsCreateTransform() failed!"); } gimp_image_set_colormap (image, cmap, num_colors); }
static PyObject * pycms_TransformBitmap (PyObject *self, PyObject *args) { ImagingObject* inImage; ImagingObject* outImage; Imaging inImg, outImg; void *transform; cmsHTRANSFORM hTransform; int width, height, i; if (!PyArg_ParseTuple(args, "OOOii", &transform, &inImage, &outImage, &width, &height)) { Py_INCREF(Py_None); return Py_None; } inImg=inImage->image; outImg=outImage->image; hTransform = (cmsHTRANSFORM) PyCObject_AsVoidPtr(transform); for (i = 0; i < height; i++) { cmsDoTransform(hTransform, inImg->image[i], outImg->image[i], width); } Py_INCREF(Py_None); return Py_None; }
static gboolean cluster_preview_expose (GtkWidget *widget, GdkEventExpose *event, dt_iop_module_t *self) { // dt_iop_colortransfer_params_t *p = (dt_iop_colortransfer_params_t *)self->params; 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 *)&g->flowback; if(!g->flowback_set) p = (dt_iop_colortransfer_params_t *)self->params; const int inset = 5; int width = widget->allocation.width, height = widget->allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; if(g->flowback_set) gtk_widget_set_sensitive(g->apply_button, TRUE); #if 0 if(g->flowback_set) { memcpy(self->params, &g->flowback, self->params_size); g->flowback_set = 0; p->flag = APPLY; dt_dev_add_history_item(darktable.develop, self, TRUE); } #endif const float sep = 2.0; const float qwd = (width-(p->n-1)*sep)/(float)p->n; for(int cl=0; cl<p->n; cl++) { // draw cluster for(int j=-1; j<=1; j++) for(int i=-1; i<=1; i++) { // draw 9x9 grid showing mean and variance of this cluster. double rgb[3] = {0.5, 0.5, 0.5}; cmsCIELab Lab; Lab.L = 5.0;//53.390011; Lab.a = (p->mean[cl][0] + i*p->var[cl][0]);// / Lab.L; Lab.b = (p->mean[cl][1] + j*p->var[cl][1]);// / Lab.L; Lab.L = 53.390011; cmsDoTransform(g->xform, &Lab, rgb, 1); cairo_set_source_rgb (cr, rgb[0], rgb[1], rgb[2]); cairo_rectangle(cr, qwd*(i+1)/3.0, height*(j+1)/3.0, qwd/3.0-.5, height/3.0-.5); cairo_fill(cr); } cairo_translate (cr, qwd + sep, 0); } cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static cmsInt32Number PCS2Display_Sampler16(const cmsUInt16Number in[], cmsUInt16Number out[], void* userdata) { //std::cout << "r" << in[0] << " g" << in[1] << " b" << in[2] << "\n"; SamplerData* data = (SamplerData*) userdata; cmsDoTransform(data->from_PCS16, in, out, 1); // we don't have a reverse Lab -> Display transform return 1; }
static gboolean dt_iop_monochrome_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { dt_iop_module_t *self = (dt_iop_module_t *)user_data; dt_iop_monochrome_gui_data_t *g = (dt_iop_monochrome_gui_data_t *)self->gui_data; dt_iop_monochrome_params_t *p = (dt_iop_monochrome_params_t *)self->params; const int inset = DT_COLORCORRECTION_INSET; GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); int width = allocation.width, height = allocation.height; cairo_surface_t *cst = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_create(cst); // clear bg cairo_set_source_rgb (cr, .2, .2, .2); cairo_paint(cr); cairo_translate(cr, inset, inset); width -= 2*inset; height -= 2*inset; // clip region to inside: cairo_rectangle(cr, 0, 0, width, height); cairo_clip(cr); // flip y: cairo_translate(cr, 0, height); cairo_scale(cr, 1., -1.); const int cells = 8; for(int j=0; j<cells; j++) for(int i=0; i<cells; i++) { double rgb[3] = {0.5, 0.5, 0.5}; cmsCIELab Lab; Lab.L = 53.390011; Lab.a = Lab.b = 0; // grey // dt_iop_sRGB_to_Lab(rgb, Lab, 0, 0, 1.0, 1, 1); // get grey in Lab Lab.a = PANEL_WIDTH*(i/(cells-1.0) - .5); Lab.b = PANEL_WIDTH*(j/(cells-1.0) - .5); const float f = color_filter(Lab.a, Lab.b, p->a, p->b, 40*40*p->size*p->size); Lab.L *= f*f; // exaggerate filter a little cmsDoTransform(g->xform, &Lab, rgb, 1); cairo_set_source_rgb (cr, rgb[0], rgb[1], rgb[2]); cairo_rectangle(cr, width*i/(float)cells, height*j/(float)cells, width/(float)cells-1, height/(float)cells-1); cairo_fill(cr); } cairo_set_source_rgb(cr, .7, .7, .7); const float x = p->a * width/PANEL_WIDTH + width * .5f, y = p->b * height/PANEL_WIDTH + height* .5f; cairo_arc(cr, x, y, width*.22f*p->size, 0, 2.0*M_PI); cairo_stroke(cr); if(g->dragging) dt_dev_add_history_item(darktable.develop, self, TRUE); cairo_destroy(cr); cairo_t *cr_pixmap = gdk_cairo_create(gtk_widget_get_window(widget)); cairo_set_source_surface (cr_pixmap, cst, 0, 0); cairo_paint(cr_pixmap); cairo_destroy(cr_pixmap); cairo_surface_destroy(cst); return TRUE; }
static void colorsel_cmyk_adj_update (GtkAdjustment *adj, ColorselCmyk *module) { GimpColorSelector *selector = GIMP_COLOR_SELECTOR (module); gint i; gdouble value; for (i = 0; i < 4; i++) if (module->adj[i] == adj) break; value = gtk_adjustment_get_value (adj) / 100.0; switch (i) { case 0: module->cmyk.c = value; break; case 1: module->cmyk.m = value; break; case 2: module->cmyk.y = value; break; case 3: module->cmyk.k = value; break; default: return; } if (module->cmyk2rgb) { gdouble cmyk_values[4]; gdouble rgb_values[3]; cmyk_values[0] = module->cmyk.c * 100.0; cmyk_values[1] = module->cmyk.m * 100.0; cmyk_values[2] = module->cmyk.y * 100.0; cmyk_values[3] = module->cmyk.k * 100.0; cmsDoTransform (module->cmyk2rgb, cmyk_values, rgb_values, 1); selector->rgb.r = rgb_values[0]; selector->rgb.g = rgb_values[1]; selector->rgb.b = rgb_values[2]; } else { gimp_cmyk_to_rgb (&module->cmyk, &selector->rgb); } gimp_rgb_to_hsv (&selector->rgb, &selector->hsv); gimp_color_selector_color_changed (selector); }
static int StripBasedXform(cmsHTRANSFORM hXForm, TIFF* in, TIFF* out, int nPlanes) { tsize_t BufSizeIn = TIFFStripSize(in); tsize_t BufSizeOut = TIFFStripSize(out); unsigned char *BufferIn, *BufferOut; ttile_t i, StripCount = TIFFNumberOfStrips(in) / nPlanes; uint32 sw; uint32 sl; uint32 iml; int j; int PixelCount; TIFFGetFieldDefaulted(in, TIFFTAG_IMAGEWIDTH, &sw); TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &sl); TIFFGetFieldDefaulted(in, TIFFTAG_IMAGELENGTH, &iml); BufferIn = (unsigned char *) _TIFFmalloc(BufSizeIn * nPlanes); if (!BufferIn) OutOfMem(BufSizeIn * nPlanes); BufferOut = (unsigned char *) _TIFFmalloc(BufSizeOut * nPlanes); if (!BufferOut) OutOfMem(BufSizeOut * nPlanes); for (i = 0; i < StripCount; i++) { for (j=0; j < nPlanes; j++) { if (TIFFReadEncodedStrip(in, i + (j * StripCount), BufferIn + (j * BufSizeIn), BufSizeIn) < 0) goto cleanup; } PixelCount = (int) sw * (iml < sl ? iml : sl); iml -= sl; cmsDoTransform(hXForm, BufferIn, BufferOut, PixelCount); for (j=0; j < nPlanes; j++) { if (TIFFWriteEncodedStrip(out, i + (j * StripCount), BufferOut + j * BufSizeOut, BufSizeOut) < 0) goto cleanup; } } _TIFFfree(BufferIn); _TIFFfree(BufferOut); return 1; cleanup: _TIFFfree(BufferIn); _TIFFfree(BufferOut); return 0; }
static void generate_testcase(double r, double g, double b) { double SRGB[3] = {r,g,b}; double LRGB[3]; cmsCIELab Lab; double gray; cmsDoTransform(xform_srgb_to_lrgb, SRGB, LRGB, 1); cmsDoTransform(xform_srgb_to_lab, SRGB, &Lab, 1); cmsDoTransform(xform_srgb_to_lgray, SRGB, &gray, 1); /* Use 6 digits precision. do not use more because you'd start seeing * small errors, probably because LCMS is using single precision float * internally. * This means 4 fractional digits for Lab, since it already has ~2 before. * */ printf("%.6f,%.6f,%.6f,%.6f,%.6f,%.6f,%.4f,%.4f,%.4f,%6f\n", SRGB[0],SRGB[1],SRGB[2], LRGB[0],LRGB[1],LRGB[2], Lab.L, Lab.a, Lab.b, gray); }
static void ApplyTransforms(const mxArray *In, mxArray *Out) { double *Input = mxGetPr(In); double *Output = mxGetPr(Out); size_t nPixels = GetNumberOfPixels(In);; cmsDoTransform(hColorTransform, Input, Output, nPixels ); }
void dkCmsDoTransform(cmsHTRANSFORM Transform, LPVOID InputBuffer, LPVOID OutputBuffer, unsigned int Size) { cmsDoTransform(Transform, static_cast<const void*>( InputBuffer ), static_cast<void*>( OutputBuffer ), static_cast<cmsUInt32Number>( Size )); }
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 cmsDoTransformGeneric (JNIEnv *env, jclass clazz, jlong hTransform, jbyteArray jinputBuffer, jbyteArray joutputBuffer, jint size) { char *inputBuffer = (char *) (*env)->GetPrimitiveArrayCritical(env, jinputBuffer, 0); char *outputBuffer = (char *) (*env)->GetPrimitiveArrayCritical(env, joutputBuffer, 0); if (hTransform) cmsDoTransform((cmsHTRANSFORM)(intptr_t) hTransform, inputBuffer, outputBuffer, size); (*env)->ReleasePrimitiveArrayCritical(env, jinputBuffer, inputBuffer, 0); (*env)->ReleasePrimitiveArrayCritical(env, joutputBuffer, outputBuffer, 0); }