~ubuntu-branches/ubuntu/saucy/darktable/saucy

« back to all changes in this revision

Viewing changes to src/iop/colorin.c

  • Committer: Bazaar Package Importer
  • Author(s): David Bremner
  • Date: 2011-07-12 09:36:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110712093646-yp9dbxan44dmw15h
Tags: 0.9-1
* New upstream release.
* Remove all patches now upstream; only patch for
  -Wno-error=unused-but-set-variable remains.
* Bump Standards-Version to 3.9.2 (no changes)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "develop/develop.h"
27
27
#include "control/control.h"
28
28
#include "gui/gtk.h"
29
 
#include "libraw/libraw.h"
30
29
#include "common/colorspaces.h"
31
30
#include "common/colormatrices.c"
32
31
#include "common/opencl.h"
33
32
#include "dtgtk/resetlabel.h"
 
33
#include "external/adobe_coeff.c"
34
34
 
35
35
DT_MODULE(1)
36
36
 
98
98
    dt_iop_color_profile_t *pp = (dt_iop_color_profile_t *)prof->data;
99
99
    if(pp->pos == pos)
100
100
    {
101
 
      strcpy(p->iccprofile, pp->filename);
 
101
      g_strlcpy(p->iccprofile, pp->filename, sizeof(p->iccprofile));
102
102
      dt_dev_add_history_item(darktable.develop, self, TRUE);
103
103
      return;
104
104
    }
112
112
lerp_lut(const float *const lut, const float v)
113
113
{
114
114
  // TODO: check if optimization is worthwhile!
115
 
  const float ft = v*LUT_SAMPLES;
116
 
  // NaN-safe clamping:
117
 
  const int t = ft > 0 ? (ft < LUT_SAMPLES-2 ? ft : LUT_SAMPLES-2) : 0;
 
115
  const float ft = CLAMPS(v*(LUT_SAMPLES-1), 0, LUT_SAMPLES-1);
 
116
  const int t = ft < LUT_SAMPLES-2 ? ft : LUT_SAMPLES-2;
118
117
  const float f = ft - t;
119
118
  const float l1 = lut[t];
120
119
  const float l2 = lut[t+1];
122
121
}
123
122
 
124
123
#ifdef HAVE_OPENCL
125
 
void
 
124
int
126
125
process_cl (struct dt_iop_module_t *self, dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out, const dt_iop_roi_t *roi_in, const dt_iop_roi_t *roi_out)
127
126
{
128
127
  dt_iop_colorin_data_t *d = (dt_iop_colorin_data_t *)piece->data;
129
128
  dt_iop_colorin_global_data_t *gd = (dt_iop_colorin_global_data_t *)self->data;
 
129
  cl_mem dev_m = NULL, dev_r = NULL, dev_g = NULL, dev_b = NULL;
130
130
 
131
 
  cl_int err;
 
131
  cl_int err = -999;
 
132
  const int map_blues = self->dev->image->flags & DT_IMAGE_RAW;
132
133
  const int devid = piece->pipe->devid;
133
134
  size_t sizes[] = {roi_in->width, roi_in->height, 1};
134
 
  cl_mem dev_m = dt_opencl_copy_host_to_device_constant(sizeof(float)*9, devid, d->cmatrix);
135
 
  cl_mem dev_r = dt_opencl_copy_host_to_device(d->lut[0], 256, 256, devid, sizeof(float));
136
 
  cl_mem dev_g = dt_opencl_copy_host_to_device(d->lut[1], 256, 256, devid, sizeof(float));
137
 
  cl_mem dev_b = dt_opencl_copy_host_to_device(d->lut[2], 256, 256, devid, sizeof(float));
 
135
  dev_m = dt_opencl_copy_host_to_device_constant(sizeof(float)*9, devid, d->cmatrix);
 
136
  if (dev_m == NULL) goto error;
 
137
  dev_r = dt_opencl_copy_host_to_device(d->lut[0], 256, 256, devid, sizeof(float));
 
138
  if (dev_r == NULL) goto error;
 
139
  dev_g = dt_opencl_copy_host_to_device(d->lut[1], 256, 256, devid, sizeof(float));
 
140
  if (dev_g == NULL) goto error;
 
141
  dev_b = dt_opencl_copy_host_to_device(d->lut[2], 256, 256, devid, sizeof(float));
 
142
  if (dev_b == NULL) goto error;
138
143
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 0, sizeof(cl_mem), (void *)&dev_in);
139
144
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 1, sizeof(cl_mem), (void *)&dev_out);
140
145
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 2, sizeof(cl_mem), (void *)&dev_m);
141
146
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 3, sizeof(cl_mem), (void *)&dev_r);
142
147
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 4, sizeof(cl_mem), (void *)&dev_g);
143
148
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 5, sizeof(cl_mem), (void *)&dev_b);
 
149
  dt_opencl_set_kernel_arg(darktable.opencl, devid, gd->kernel_colorin, 6, sizeof(cl_int), (void *)&map_blues);
144
150
  err = dt_opencl_enqueue_kernel_2d(darktable.opencl, devid, gd->kernel_colorin, sizes);
145
 
  if(err != CL_SUCCESS) fprintf(stderr, "couldn't enqueue colorin kernel! %d\n", err);
146
 
  clReleaseMemObject(dev_m);
147
 
  clReleaseMemObject(dev_r);
148
 
  clReleaseMemObject(dev_g);
149
 
  clReleaseMemObject(dev_b);
 
151
  if(err != CL_SUCCESS) goto error;
 
152
  dt_opencl_release_mem_object(dev_m);
 
153
  dt_opencl_release_mem_object(dev_r);
 
154
  dt_opencl_release_mem_object(dev_g);
 
155
  dt_opencl_release_mem_object(dev_b);
 
156
  return TRUE;
 
157
 
 
158
error:
 
159
  if (dev_m != NULL) dt_opencl_release_mem_object(dev_m);
 
160
  if (dev_r != NULL) dt_opencl_release_mem_object(dev_r);
 
161
  if (dev_g != NULL) dt_opencl_release_mem_object(dev_g);
 
162
  if (dev_b != NULL) dt_opencl_release_mem_object(dev_b);
 
163
  dt_print(DT_DEBUG_OPENCL, "[opencl_colorin] couldn't enqueue kernel! %d\n", err);
 
164
  return FALSE;
150
165
}
151
166
#endif
152
167
 
158
173
  float *in  = (float *)i;
159
174
  float *out = (float *)o;
160
175
  const int ch = piece->colors;
 
176
  const int map_blues = self->dev->image->flags & DT_IMAGE_RAW;
161
177
 
162
178
  if(mat[0] != -666.0f)
163
179
  {
164
180
    // only color matrix. use our optimized fast path!
165
181
#ifdef _OPENMP
166
 
#pragma omp parallel for default(none) shared(roi_out, out, in, d) schedule(static)
 
182
    #pragma omp parallel for default(none) shared(roi_out, out, in, d) schedule(static)
167
183
#endif
168
184
    for(int k=0; k<roi_out->width*roi_out->height; k++)
169
185
    {
173
189
      // memcpy(cam, buf_in, sizeof(float)*3);
174
190
      // TODO: avoid calling this for linear profiles? doesn't seem to impact performance much.
175
191
      for(int i=0; i<3; i++) cam[i] = lerp_lut(d->lut[i], buf_in[i]);
176
 
      // manual gamut mapping. these values cause trouble when converting back from Lab to sRGB:
177
 
      const float YY = cam[0]+cam[1]+cam[2];
178
 
      const float zz = cam[2]/YY;
179
 
      // lower amount and higher bound_z make the effect smaller.
180
 
      // the effect is weakened the darker input values are, saturating at bound_Y
181
 
      const float bound_z = 0.5f, bound_Y = 0.5f;
182
 
      const float amount = 0.11f;
183
 
      if (zz > bound_z)
 
192
 
 
193
      if(map_blues)
184
194
      {
185
 
        const float t = (zz - bound_z)/(1.0f-bound_z) * fminf(1.0, YY/bound_Y);
186
 
        cam[1] += t*amount;
187
 
        cam[2] -= t*amount;
 
195
        // manual gamut mapping. these values cause trouble when converting back from Lab to sRGB.
 
196
        // deeply saturated blues turn into purple fringes, so dampen them before conversion.
 
197
        // this is off for non-raw images, which don't seem to have this problem.
 
198
        // might be caused by too loose clipping bounds during highlight clipping?
 
199
        const float YY = cam[0]+cam[1]+cam[2];
 
200
        const float zz = cam[2]/YY;
 
201
        // lower amount and higher bound_z make the effect smaller.
 
202
        // the effect is weakened the darker input values are, saturating at bound_Y
 
203
        const float bound_z = 0.5f, bound_Y = 0.8f;
 
204
        const float amount = 0.11f;
 
205
        if (zz > bound_z)
 
206
        {
 
207
          const float t = (zz - bound_z)/(1.0f-bound_z) * fminf(1.0, YY/bound_Y);
 
208
          cam[1] += t*amount;
 
209
          cam[2] -= t*amount;
 
210
        }
188
211
      }
189
212
      // now convert camera to XYZ using the color matrix
190
213
      for(int j=0; j<3; j++)
205
228
 
206
229
    // FIXME: for some unapparent reason even this breaks lcms2 :(
207
230
#if 0//def _OPENMP
208
 
#pragma omp parallel for default(none) shared(roi_out, out, in, d, cam, Lab, rowsize) schedule(static)
 
231
    #pragma omp parallel for default(none) shared(roi_out, out, in, d, cam, Lab, rowsize) schedule(static)
209
232
#endif
210
233
    for(int k=0; k<roi_out->height; k++)
211
234
    {
249
272
{
250
273
  // pthread_mutex_lock(&darktable.plugin_threadsafe);
251
274
  dt_iop_colorin_params_t *p = (dt_iop_colorin_params_t *)p1;
252
 
#ifdef HAVE_GEGL
253
 
  // pull in new params to gegl
254
 
#error "gegl version needs some more care!"
255
 
#else
256
275
  dt_iop_colorin_data_t *d = (dt_iop_colorin_data_t *)piece->data;
257
276
  if(d->input) cmsCloseProfile(d->input);
258
277
  const int num_threads = dt_get_num_threads();
277
296
  if(!strcmp(p->iccprofile, "cmatrix"))
278
297
  {
279
298
    // color matrix
280
 
    int ret;
281
299
    dt_image_full_path(self->dev->image->id, filename, 1024);
282
 
    libraw_data_t *raw = libraw_init(0);
283
 
    ret = libraw_open_file(raw, filename);
284
 
    if(!ret)
285
 
    {
286
 
      float cmat[3][4];
287
 
      for(int k=0; k<4; k++) for(int i=0; i<3; i++)
288
 
        {
289
 
          // d->cmatrix[i][k] = raw->color.rgb_cam[i][k];
290
 
          cmat[i][k] = raw->color.rgb_cam[i][k];
291
 
        }
292
 
      d->input = dt_colorspaces_create_cmatrix_profile(cmat);
293
 
    }
294
 
    libraw_close(raw);
 
300
    char makermodel[1024];
 
301
    dt_colorspaces_get_makermodel(makermodel, 1024, self->dev->image->exif_maker, self->dev->image->exif_model);
 
302
    float cam_xyz[12];
 
303
    dt_dcraw_adobe_coeff(makermodel, "", (float (*)[12])cam_xyz);
 
304
    d->input = dt_colorspaces_create_xyzimatrix_profile((float (*)[3])cam_xyz);
295
305
  }
296
306
  else if(!strcmp(p->iccprofile, "sRGB"))
297
307
  {
356
366
    }
357
367
  }
358
368
  // pthread_mutex_unlock(&darktable.plugin_threadsafe);
359
 
#endif
360
369
}
361
370
 
362
371
void init_pipe (struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
412
421
  if(strcmp(p->iccprofile, "darktable")) fprintf(stderr, "[colorin] could not find requested profile `%s'!\n", p->iccprofile);
413
422
}
414
423
 
 
424
void reload_defaults(dt_iop_module_t *module)
 
425
{
 
426
  dt_iop_colorin_params_t tmp = (dt_iop_colorin_params_t)
 
427
  {
 
428
    "darktable", DT_INTENT_PERCEPTUAL
 
429
  };
 
430
  if(dt_image_is_ldr(module->dev->image)) g_strlcpy(tmp.iccprofile, "sRGB", sizeof(tmp.iccprofile));
 
431
  memcpy(module->params, &tmp, sizeof(dt_iop_colorin_params_t));
 
432
  memcpy(module->default_params, &tmp, sizeof(dt_iop_colorin_params_t));
 
433
}
 
434
 
415
435
void init(dt_iop_module_t *module)
416
436
{
417
437
  // module->data = malloc(sizeof(dt_iop_colorin_data_t));
419
439
  module->default_params = malloc(sizeof(dt_iop_colorin_params_t));
420
440
  module->params_size = sizeof(dt_iop_colorin_params_t);
421
441
  module->gui_data = NULL;
422
 
  module->priority = 300;
 
442
  module->priority = 333; // module order created by iop_dependencies.py, do not edit!
423
443
  module->hide_enable_button = 1;
424
 
  dt_iop_colorin_params_t tmp = (dt_iop_colorin_params_t)
425
 
  {"darktable", DT_INTENT_PERCEPTUAL
426
 
  };
427
 
  if(dt_image_is_ldr(module->dev->image)) strcpy(tmp.iccprofile, "sRGB");
428
 
  memcpy(module->params, &tmp, sizeof(dt_iop_colorin_params_t));
429
 
  memcpy(module->default_params, &tmp, sizeof(dt_iop_colorin_params_t));
430
444
}
431
445
 
432
446
void cleanup(dt_iop_module_t *module)
448
462
 
449
463
  // get color matrix from raw image:
450
464
  dt_iop_color_profile_t *prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
451
 
  strcpy(prof->filename, "cmatrix");
452
 
  strcpy(prof->name, "cmatrix");
 
465
  g_strlcpy(prof->filename, "cmatrix", sizeof(prof->filename));
 
466
  g_strlcpy(prof->name, "cmatrix", sizeof(prof->name));
453
467
  g->profiles = g_list_append(g->profiles, prof);
454
468
  int pos = prof->pos = 0;
455
469
 
461
475
    if(!strcmp(makermodel, dt_profiled_colormatrices[k].makermodel))
462
476
    {
463
477
      prof = (dt_iop_color_profile_t *)malloc(sizeof(dt_iop_color_profile_t));
464
 
      strcpy(prof->filename, "darktable");
465
 
      strcpy(prof->name, "darktable");
 
478
      g_strlcpy(prof->filename, "darktable", sizeof(prof->filename));
 
479
      g_strlcpy(prof->name, "darktable", sizeof(prof->name));
466
480
      g->profiles = g_list_append(g->profiles, prof);
467
481
      prof->pos = ++pos;
468
482
      break;
471
485
 
472
486
  // sRGB for ldr image input
473
487
  prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
474
 
  strcpy(prof->filename, "sRGB");
475
 
  strcpy(prof->name, "sRGB");
 
488
  g_strlcpy(prof->filename, "sRGB", sizeof(prof->filename));
 
489
  g_strlcpy(prof->name, "sRGB", sizeof(prof->name));
476
490
  g->profiles = g_list_append(g->profiles, prof);
477
491
  prof->pos = ++pos;
478
492
 
479
493
  // adobe rgb built-in
480
494
  prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
481
 
  strcpy(prof->filename, "adobergb");
482
 
  strcpy(prof->name, "adobergb");
 
495
  g_strlcpy(prof->filename, "adobergb", sizeof(prof->filename));
 
496
  g_strlcpy(prof->name, "adobergb", sizeof(prof->name));
483
497
  g->profiles = g_list_append(g->profiles, prof);
484
498
  prof->pos = ++pos;
485
499
 
486
500
  // add std RGB profile:
487
501
  prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
488
 
  strcpy(prof->filename, "linear_rgb");
489
 
  strcpy(prof->name, "linear_rgb");
 
502
  g_strlcpy(prof->filename, "linear_rgb", sizeof(prof->filename));
 
503
  g_strlcpy(prof->name, "linear_rgb", sizeof(prof->name));
490
504
  g->profiles = g_list_append(g->profiles, prof);
491
505
  prof->pos = ++pos;
492
506
 
493
507
  // XYZ built-in
494
508
  prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
495
 
  strcpy(prof->filename, "XYZ");
496
 
  strcpy(prof->name, "XYZ");
 
509
  g_strlcpy(prof->filename, "XYZ", sizeof(prof->filename));
 
510
  g_strlcpy(prof->name, "XYZ", sizeof(prof->name));
497
511
  g->profiles = g_list_append(g->profiles, prof);
498
512
  prof->pos = ++pos;
499
513
 
500
514
  // infrared built-in
501
515
  prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
502
 
  strcpy(prof->filename, "infrared");
503
 
  strcpy(prof->name, "infrared");
 
516
  g_strlcpy(prof->filename, "infrared", sizeof(prof->filename));
 
517
  g_strlcpy(prof->name, "infrared", sizeof(prof->name));
504
518
  g->profiles = g_list_append(g->profiles, prof);
505
519
  prof->pos = ++pos;
506
520
 
526
540
        dt_iop_color_profile_t *prof = (dt_iop_color_profile_t *)g_malloc0(sizeof(dt_iop_color_profile_t));
527
541
        char name[1024];
528
542
        cmsGetProfileInfoASCII(tmpprof, cmsInfoDescription, getenv("LANG"), getenv("LANG")+3, name, 1024);
529
 
        strcpy(prof->name, name);
 
543
        g_strlcpy(prof->name, name, sizeof(prof->name));
530
544
 
531
 
        strcpy(prof->filename, d_name);
 
545
        g_strlcpy(prof->filename, d_name, sizeof(prof->filename));
532
546
        cmsCloseProfile(tmpprof);
533
547
        g->profiles = g_list_append(g->profiles, prof);
534
548
        prof->pos = ++pos;
554
568
    else if(!strcmp(prof->name, "darktable"))
555
569
      gtk_combo_box_append_text(g->cbox2, _("enhanced color matrix"));
556
570
    else if(!strcmp(prof->name, "sRGB"))
557
 
      gtk_combo_box_append_text(g->cbox2, _("srgb (e.g. jpg)"));
 
571
      gtk_combo_box_append_text(g->cbox2, _("sRGB (e.g. jpg)"));
558
572
    else if(!strcmp(prof->name, "adobergb"))
559
 
      gtk_combo_box_append_text(g->cbox2, _("adobe rgb"));
 
573
      gtk_combo_box_append_text(g->cbox2, _("Adobe RGB"));
560
574
    else if(!strcmp(prof->name, "linear_rgb"))
561
 
      gtk_combo_box_append_text(g->cbox2, _("linear rgb"));
 
575
      gtk_combo_box_append_text(g->cbox2, _("linear RGB"));
562
576
    else if(!strcmp(prof->name, "infrared"))
563
 
      gtk_combo_box_append_text(g->cbox2, _("linear infrared bgr"));
 
577
      gtk_combo_box_append_text(g->cbox2, _("linear infrared BGR"));
564
578
    else if(!strcmp(prof->name, "XYZ"))
565
 
      gtk_combo_box_append_text(g->cbox2, _("linear xyz"));
 
579
      gtk_combo_box_append_text(g->cbox2, _("linear XYZ"));
566
580
    else
567
581
      gtk_combo_box_append_text(g->cbox2, prof->name);
568
582
    l = g_list_next(l);
572
586
 
573
587
  char tooltip[1024];
574
588
  snprintf(tooltip, 1024, _("icc profiles in %s/color/in or %s/color/in"), confdir, datadir);
575
 
  gtk_object_set(GTK_OBJECT(g->cbox2), "tooltip-text", tooltip, (char *)NULL);
 
589
  g_object_set(G_OBJECT(g->cbox2), "tooltip-text", tooltip, (char *)NULL);
576
590
 
577
591
  g_signal_connect (G_OBJECT (g->cbox2), "changed",
578
592
                    G_CALLBACK (profile_changed),
591
605
  free(self->gui_data);
592
606
  self->gui_data = NULL;
593
607
}
 
608
 
 
609
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;