102#if LF_VERSION < ((0 << 24) | (2 << 16) | (9 << 8) | 0)
103#define LF_SEARCH_SORT_AND_UNIQUIFY 2
106#if LF_VERSION == ((0 << 24) | (3 << 16) | (95 << 8) | 0)
196 return _(
"_lens correction");
201 return _(
"vignette|chromatic aberrations|distortion");
208 _(
"linear, RGB, scene-referred"),
209 _(
"geometric and reconstruction, RGB"),
210 _(
"linear, RGB, scene-referred"));
235 void *new_params,
const int new_version)
237 if(old_version == 2 && new_version == 5)
249 lfLensType target_geom;
254 } dt_iop_lensfun_params_v2_t;
256 const dt_iop_lensfun_params_v2_t *o = (dt_iop_lensfun_params_v2_t *)old_params;
262 n->modify_flags = o->modify_flags;
263 n->inverse = o->inverse;
267 n->aperture = o->aperture;
268 n->distance = o->distance;
269 n->target_geom = o->target_geom;
270 n->tca_override = o->tca_override;
271 g_strlcpy(
n->camera, o->camera,
sizeof(
n->camera));
272 g_strlcpy(
n->lens, o->lens,
sizeof(
n->lens));
281 if(old_version == 3 && new_version == 5)
292 lfLensType target_geom;
297 } dt_iop_lensfun_params_v3_t;
299 const dt_iop_lensfun_params_v3_t *o = (dt_iop_lensfun_params_v3_t *)old_params;
317 if(old_version == 4 && new_version == 5)
328 lfLensType target_geom;
334 } dt_iop_lensfun_params_v4_t;
336 const dt_iop_lensfun_params_v4_t *o = (dt_iop_lensfun_params_v4_t *)old_params;
356 const char *found_or = strstr(orig_lens,
" or ");
357 const char *found_parenthesis = strstr(orig_lens,
" (");
359 if(found_or || found_parenthesis)
361 size_t pos_or = (size_t)(found_or - orig_lens);
362 size_t pos_parenthesis = (size_t)(found_parenthesis - orig_lens);
363 size_t pos = pos_or < pos_parenthesis ? pos_or : pos_parenthesis;
367 char *new_lens = (
char *)malloc(pos + 1);
369 strncpy(new_lens, orig_lens, pos);
370 new_lens[pos] =
'\0';
376 char *new_lens = strdup(orig_lens);
382 char *new_lens = strdup(orig_lens);
391 int mods_todo =
d->modify_flags & mods_filter;
392 int mods_done_tmp = 0;
395 mod =
new lfModifier(
d->crop, w, h, LF_PF_F32, (force_inverse) ? !
d->inverse :
d->inverse);
396 if(mods_todo & LF_MODIFY_DISTORTION)
397 mods_done_tmp |= mod->EnableDistortionCorrection(
d->lens,
d->focal);
398 if((mods_todo & LF_MODIFY_GEOMETRY) && (
d->lens->Type !=
d->target_geom))
399 mods_done_tmp |= mod->EnableProjectionTransform(
d->lens,
d->focal,
d->target_geom);
400 if((mods_todo & LF_MODIFY_SCALE) && (
d->scale != 1.0))
401 mods_done_tmp |= mod->EnableScaling(
d->scale);
402 if(mods_todo & LF_MODIFY_TCA)
404 if(
d->tca_override) mods_done_tmp |= mod->EnableTCACorrection(
d->custom_tca);
405 else mods_done_tmp |= mod->EnableTCACorrection(
d->lens,
d->focal);
407 if(mods_todo & LF_MODIFY_VIGNETTING)
408 mods_done_tmp |= mod->EnableVignettingCorrection(
d->lens,
d->focal,
d->aperture,
d->distance);
410 mod =
new lfModifier(
d->lens,
d->crop, w, h);
411 mods_done_tmp = mod->Initialize(
d->lens, LF_PF_F32,
d->focal,
d->aperture,
d->distance,
d->scale,
d->target_geom, mods_todo,
412 (force_inverse) ? !
d->inverse :
d->inverse);
415 if(mods_done) *mods_done = mods_done_tmp;
423 const dt_aligned_pixel_simd_t half =
dt_simd_set1(0.5f);
445 const void *
const ivoid,
void *
const ovoid)
453 const int ch_width =
ch * roi_in->
width;
458 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
465 const int used_lf_mask = (raw_monochrome) ? LF_MODIFY_ALL & ~LF_MODIFY_TCA : LF_MODIFY_ALL;
472 const lfModifier *modifier =
get_modifier(&modflags, orig_w, orig_h,
d, used_lf_mask,
FALSE);
481 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
484 const size_t bufsize = (size_t)roi_out->
width * 2 * 3;
486 size_t padded_bufsize;
491#pragma omp parallel for default(none) \
492 firstprivate(roi_out, roi_in, padded_bufsize, modifier, ch, d, buf, ovoid, ivoid, ch_width, interpolation, raw_monochrome, mask_display)
494 for(
int y = 0; y < roi_out->
height; y++)
497 modifier->ApplySubpixelGeometryDistortion(roi_out->
x, roi_out->
y + y, roi_out->
width, 1, bufptr);
501 for(
int x = 0;
x < roi_out->
width;
x++, bufptr += 6,
out +=
ch)
503 dt_aligned_pixel_simd_t pixel = { 0.f };
504 for(
int c = 0; c < 3; c++)
506 if(
d->do_nan_checks && (!isfinite(bufptr[c * 2]) || !isfinite(bufptr[c * 2 + 1])))
512 const float *
const inptr = (
const float *
const)ivoid + (
size_t)c;
513 const float pi0 = fmaxf(fminf(bufptr[c * 2] - roi_in->
x, roi_in->
width - 1.0f), 0.0f);
514 const float pi1 = fmaxf(fminf(bufptr[c * 2 + 1] - roi_in->
y, roi_in->
height - 1.0f), 0.0f);
519 if(raw_monochrome) pixel[0] = pixel[2] = pixel[1];
523 if(
d->do_nan_checks && (!isfinite(bufptr[2]) || !isfinite(bufptr[3])))
530 const float *
const inptr = (
const float *
const)ivoid + (
size_t)3;
531 const float pi0 = fmaxf(fminf(bufptr[2] - roi_in->
x, roi_in->
width - 1.0f), 0.0f);
532 const float pi1 = fmaxf(fminf(bufptr[3] - roi_in->
y, roi_in->
height - 1.0f), 0.0f);
538 else for(
int c = 0; c <
ch; c++)
out[c] = pixel[c];
542 for(
int c = 0; c < 3; c++)
out[c] = pixel[c];
553 if(modflags & LF_MODIFY_VIGNETTING)
556 for(
int y = 0; y < roi_out->
height; y++)
561 modifier->ApplyColorModification(
out, roi_out->
x, roi_out->
y + y, roi_out->
width, 1,
562 pixelformat,
ch * roi_out->
width);
570 const size_t bufsize = (size_t)roi_in->
width * roi_in->
height *
ch *
sizeof(
float);
575 memcpy(buf, ivoid, bufsize);
577 if(modflags & LF_MODIFY_VIGNETTING)
580 for(
int y = 0; y < roi_in->
height; y++)
584 float *bufptr = ((
float *)buf) + (size_t)
ch * roi_in->
width * y;
585 modifier->ApplyColorModification(bufptr, roi_in->
x, roi_in->
y + y, roi_in->
width, 1,
586 pixelformat,
ch * roi_in->
width);
591 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
594 const size_t buf2size = (size_t)roi_out->
width * 2 * 3;
595 size_t padded_buf2size;
604#pragma omp parallel for default(none) \
605 firstprivate(roi_out, roi_in, ovoid, ch, padded_buf2size, modifier, mask_display, raw_monochrome, interpolation, ch_width, buf, d, buf2)
607 for(
int y = 0; y < roi_out->
height; y++)
610 modifier->ApplySubpixelGeometryDistortion(roi_out->
x, roi_out->
y + y, roi_out->
width,
614 for(
int x = 0;
x < roi_out->
width;
x++, buf2ptr += 6,
out +=
ch)
616 dt_aligned_pixel_simd_t pixel = { 0.f };
617 for(
int c = 0; c < 3; c++)
619 if(
d->do_nan_checks && (!isfinite(buf2ptr[c * 2]) || !isfinite(buf2ptr[c * 2 + 1])))
625 float *bufptr = ((
float *)buf) + c;
626 const float pi0 = fmaxf(fminf(buf2ptr[c * 2] - roi_in->
x, roi_in->
width - 1.0f), 0.0f);
627 const float pi1 = fmaxf(fminf(buf2ptr[c * 2 + 1] - roi_in->
y, roi_in->
height - 1.0f), 0.0f);
631 if(raw_monochrome) pixel[0] = pixel[2] = pixel[1];
634 if(
d->do_nan_checks && (!isfinite(buf2ptr[2]) || !isfinite(buf2ptr[3])))
641 float *bufptr = ((
float *)buf) + 3;
642 const float pi0 = fmaxf(fminf(buf2ptr[2] - roi_in->
x, roi_in->
width - 1.0f), 0.0f);
643 const float pi1 = fmaxf(fminf(buf2ptr[3] - roi_in->
y, roi_in->
height - 1.0f), 0.0f);
649 else for(
int c = 0; c <
ch; c++)
out[c] = pixel[c];
653 for(
int c = 0; c < 3; c++)
out[c] = pixel[c];
661 memcpy(
ovoid, buf, bufsize);
691 const int used_lf_mask = (raw_monochrome) ? LF_MODIFY_ALL & ~LF_MODIFY_TCA : LF_MODIFY_ALL;
693 cl_mem dev_tmpbuf = NULL;
694 cl_mem dev_tmp = NULL;
697 float *tmpbuf = NULL;
698 lfModifier *modifier = NULL;
700 const int devid = pipe->
devid;
701 const int iwidth = roi_in->
width;
702 const int iheight = roi_in->
height;
703 const int owidth = roi_out->
width;
704 const int oheight = roi_out->
height;
705 const int roi_in_x = roi_in->
x;
706 const int roi_in_y = roi_in->
y;
707 const int width =
MAX(iwidth, owidth);
708 const int height =
MAX(iheight, oheight);
710 const int tmpbufwidth = owidth * 2 * 3;
711 const size_t tmpbuflen =
d->inverse ? (size_t)oheight * owidth * 2 * 3 *
sizeof(
float)
712 :
MAX((
size_t)oheight * owidth * 2 * 3, (
size_t)iheight * iwidth *
ch)
718 size_t origin[] = { 0, 0, 0 };
719 size_t iregion[] = { (size_t)iwidth, (
size_t)iheight, 1 };
720 size_t oregion[] = { (size_t)owidth, (
size_t)oheight, 1 };
728 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
731 if(err != CL_SUCCESS)
goto error;
735 switch(interpolation->
id)
768 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
771 for(
int y = 0; y < roi_out->
height; y++)
773 float *pi = tmpbuf + (size_t)y * tmpbufwidth;
774 modifier->ApplySubpixelGeometryDistortion(roi_out->
x, roi_out->
y + y, roi_out->
width, 1, pi);
780 (
size_t)owidth * oheight * 2 * 3 *
sizeof(
float), CL_TRUE);
781 if(err != CL_SUCCESS)
goto error;
795 if(err != CL_SUCCESS)
goto error;
800 if(err != CL_SUCCESS)
goto error;
803 if(modflags & LF_MODIFY_VIGNETTING)
806 for(
int y = 0; y < roi_out->
height; y++)
810 float *buf = tmpbuf + (size_t)y *
ch * roi_out->
width;
812 modifier->ApplyColorModification(buf, roi_out->
x, roi_out->
y + y, roi_out->
width, 1,
813 pixelformat,
ch * roi_out->
width);
819 (
size_t)
ch * roi_out->
width * roi_out->
height *
sizeof(
float),
821 if(err != CL_SUCCESS)
goto error;
829 if(err != CL_SUCCESS)
goto error;
834 if(err != CL_SUCCESS)
goto error;
841 if(modflags & LF_MODIFY_VIGNETTING)
844 for(
int y = 0; y < roi_in->
height; y++)
848 float *buf = tmpbuf + (size_t)y *
ch * roi_in->
width;
850 modifier->ApplyColorModification(buf, roi_in->
x, roi_in->
y + y, roi_in->
width, 1,
851 pixelformat,
ch * roi_in->
width);
857 devid, tmpbuf, dev_tmpbuf, 0, (
size_t)
ch * roi_in->
width * roi_in->
height *
sizeof(
float), CL_TRUE);
858 if(err != CL_SUCCESS)
goto error;
866 if(err != CL_SUCCESS)
goto error;
871 if(err != CL_SUCCESS)
goto error;
874 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
877 for(
int y = 0; y < roi_out->
height; y++)
879 float *pi = tmpbuf + (size_t)y * tmpbufwidth;
880 modifier->ApplySubpixelGeometryDistortion(roi_out->
x, roi_out->
y + y, roi_out->
width, 1, pi);
886 (
size_t)owidth * oheight * 2 * 3 *
sizeof(
float), CL_TRUE);
887 if(err != CL_SUCCESS)
goto error;
901 if(err != CL_SUCCESS)
goto error;
906 if(err != CL_SUCCESS)
goto error;
946 float *
const __restrict points,
size_t points_count)
949 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
return 0;
956 const lfModifier *modifier =
get_modifier(&modflags, orig_w, orig_h,
d, used_lf_mask,
TRUE);
957 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
960 for(
size_t i = 0;
i < points_count * 2;
i += 2)
963 modifier->ApplySubpixelGeometryDistortion(points[
i], points[
i + 1], 1, 1, buf);
967 points[
i + 1] = buf[3];
976 float *
const __restrict points,
size_t points_count)
980 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
return 0;
986 const lfModifier *modifier =
get_modifier(&modflags, orig_w, orig_h,
d, used_lf_mask,
FALSE);
988 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
991 for(
size_t i = 0;
i < points_count * 2;
i += 2)
994 modifier->ApplySubpixelGeometryDistortion(points[
i], points[
i + 1], 1, 1, buf);
998 points[
i + 1] = buf[3];
1008 const float *
const in,
float *
const out,
const dt_iop_roi_t *
const roi_in,
1014 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
1023 const lfModifier *modifier =
get_modifier(&modflags, orig_w, orig_h,
d, LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE,
FALSE);
1027 if(!(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE)))
1037 const size_t bufsize = (size_t)roi_out->
width * 2 * 3;
1038 size_t padded_bufsize;
1042 for(
int y = 0; y < roi_out->
height; y++)
1045 modifier->ApplySubpixelGeometryDistortion(roi_out->
x, roi_out->
y + y, roi_out->
width, 1, bufptr);
1048 float *_out =
out + (size_t)y * roi_out->
width;
1049 for(
int x = 0;
x < roi_out->
width;
x++, bufptr += 6, _out++)
1051 if(
d->do_nan_checks && (!isfinite(bufptr[2]) || !isfinite(bufptr[3])))
1058 const float pi0 = bufptr[2] - roi_in->
x;
1059 const float pi1 = bufptr[3] - roi_in->
y;
1085 if(!
d->lens || !
d->lens->Maker ||
d->crop <= 0.0f)
return;
1090 const lfModifier *modifier =
get_modifier(&modflags, orig_w, orig_h,
d, LF_MODIFY_ALL,
FALSE);
1092 if(modflags & (LF_MODIFY_TCA | LF_MODIFY_DISTORTION | LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE))
1094 const int xoff = roi_in->
x;
1095 const int yoff = roi_in->
y;
1098 const int awidth = abs(
width);
1099 const int aheight = abs(
height);
1100 const int xstep = (
width < 0) ? -1 : 1;
1101 const int ystep = (
height < 0) ? -1 : 1;
1103 float xm = FLT_MAX, xM = -FLT_MAX, ym = FLT_MAX, yM = -FLT_MAX;
1104 const size_t nbpoints = 2 * awidth + 2 * aheight;
1113#pragma omp parallel default(none) reduction(min : xm, ym) reduction(max : xM, yM) \
1114 firstprivate(modifier, xoff, yoff, awidth, aheight, width, height, nbpoints, ystep, xstep, buf)
1118 for(
int i = 0;
i < awidth;
i++)
1119 modifier->ApplySubpixelGeometryDistortion(xoff +
i * xstep, yoff, 1, 1, buf + 6 *
i);
1121 for(
int i = 0;
i < awidth;
i++)
1122 modifier->ApplySubpixelGeometryDistortion(xoff +
i * xstep, yoff + (
height - 1), 1, 1, buf + 6 * (awidth +
i));
1124 for(
int j = 0; j < aheight; j++)
1125 modifier->ApplySubpixelGeometryDistortion(xoff, yoff + j * ystep, 1, 1, buf + 6 * (2 * awidth + j));
1127 for(
int j = 0; j < aheight; j++)
1128 modifier->ApplySubpixelGeometryDistortion(xoff + (
width - 1), yoff + j * ystep, 1, 1, buf + 6 * (2 * awidth + aheight + j));
1134 for(
size_t k = 0;
k < nbpoints;
k++)
1137 for(
size_t c = 0; c < 6; c+=2)
1139 const float x = buf[6 *
k + c];
1140 const float y = buf[6 *
k + c + 1];
1141 xm = isnan(
x) ? xm :
MIN(xm,
x);
1142 xM = isnan(
x) ? xM :
MAX(xM,
x);
1143 ym = isnan(y) ? ym :
MIN(ym, y);
1144 yM = isnan(y) ? yM :
MAX(yM, y);
1152 if(!isfinite(xm) || !(0 <= xm && xm < orig_w)) xm = 0;
1153 if(!isfinite(xM) || !(1 <= xM && xM < orig_w)) xM = orig_w;
1154 if(!isfinite(ym) || !(0 <= ym && ym < orig_h)) ym = 0;
1155 if(!isfinite(yM) || !(1 <= yM && yM < orig_h)) yM = orig_h;
1158 roi_in->
x = fmaxf(0.0f, roundf(xm - interpolation->
width));
1159 roi_in->
y = fmaxf(0.0f, roundf(ym - interpolation->
width));
1160 roi_in->
width = roundf(fminf(orig_w - roi_in->
x, xM - roi_in->
x + interpolation->
width));
1161 roi_in->
height = roundf(fminf(orig_h - roi_in->
y, yM - roi_in->
y + interpolation->
width));
1164 roi_in->
x = CLAMP(roi_in->
x, 0, (
int)floorf(orig_w));
1165 roi_in->
y = CLAMP(roi_in->
y, 0, (
int)floorf(orig_h));
1166 roi_in->
width = CLAMP(roi_in->
width, 1, (
int)ceilf(orig_w) - roi_in->
x);
1167 roi_in->
height = CLAMP(roi_in->
height, 1, (
int)ceilf(orig_h) - roi_in->
y);
1180 if(
p->modified == 0)
1195 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
1196 const lfCamera *camera = NULL;
1197 const lfCamera **cam = NULL;
1203 d->lens =
new lfLens;
1208 cam = dt_iop_lensfun_db->FindCamerasExt(NULL,
p->camera, 0);
1212 d->crop = cam[0]->CropFactor;
1220 = dt_iop_lensfun_db->FindLenses(camera, NULL,
p->lens, 0);
1224 *
d->lens = *lens[0];
1232 .Model = LF_TCA_MODEL_LINEAR,
1234 .Terms = {
p->tca_r,
p->tca_b },
1238 .CropFactor =
d->crop,
1239 .AspectRatio = (float)img->
width / (
float)img->
height
1244 lfLensCalibTCA tca = { LF_TCA_MODEL_NONE };
1246 tca.Model = LF_TCA_MODEL_LINEAR;
1247 tca.Terms[0] =
p->tca_r;
1248 tca.Terms[1] =
p->tca_b;
1249 if(
d->lens->CalibTCA)
1250 while(
d->lens->CalibTCA[0])
d->lens->RemoveCalibTCA(0);
1251 d->lens->AddCalibTCA(&tca);
1258 d->modify_flags =
p->modify_flags;
1260 d->inverse =
p->inverse;
1261 d->scale =
p->scale;
1262 d->focal =
p->focal;
1263 d->aperture =
p->aperture;
1264 d->distance =
p->distance;
1265 d->target_geom =
p->target_geom;
1266 d->do_nan_checks =
TRUE;
1267 d->tca_override =
p->tca_override;
1273 if(
d->target_geom == LF_RECTILINEAR)
1275 d->do_nan_checks =
FALSE;
1277 else if(
d->target_geom ==
d->lens->Type)
1279 d->do_nan_checks =
FALSE;
1306 const int program = 2;
1315 lfDatabase *dt_iop_lensfun_db =
new lfDatabase;
1316 gd->
db = (lfDatabase *)dt_iop_lensfun_db;
1318#if defined(__MACH__) || defined(__APPLE__)
1320 if(dt_iop_lensfun_db->Load() != LF_NO_ERROR)
1327 GFile *file = g_file_parse_name(datadir);
1328 GFile *parent = g_file_get_parent(file);
1329 gchar *path = g_file_get_path(parent);
1330 g_object_unref(parent);
1331 g_object_unref(file);
1332#ifdef LF_MAX_DATABASE_VERSION
1333 gchar *sysdbpath = g_build_filename(path,
"lensfun",
"version_" STR(LF_MAX_DATABASE_VERSION), (
char *)NULL);
1337 const long userdbts = dt_iop_lensfun_db->ReadTimestamp(dt_iop_lensfun_db->UserUpdatesLocation);
1338 const long sysdbts = dt_iop_lensfun_db->ReadTimestamp(sysdbpath);
1339 const char *dbpath = userdbts > sysdbts ? dt_iop_lensfun_db->UserUpdatesLocation : sysdbpath;
1340 if(dt_iop_lensfun_db->Load(dbpath) != LF_NO_ERROR)
1341 fprintf(stderr,
"[iop_lens]: could not load lensfun database in `%s'!\n", dbpath);
1343 dt_iop_lensfun_db->Load(dt_iop_lensfun_db->UserLocation);
1346#ifdef LF_MAX_DATABASE_VERSION
1347 dt_free(dt_iop_lensfun_db->HomeDataDir);
1348 dt_iop_lensfun_db->HomeDataDir = g_strdup(sysdbpath);
1349 if(dt_iop_lensfun_db->Load() != LF_NO_ERROR)
1351 fprintf(stderr,
"[iop_lens]: could not load lensfun database in `%s'!\n", sysdbpath);
1353 dt_free(dt_iop_lensfun_db->HomeDataDir);
1354 dt_iop_lensfun_db->HomeDataDir = g_build_filename(path,
"lensfun", (
char *)NULL);
1355 if(dt_iop_lensfun_db->Load() != LF_NO_ERROR)
1356 fprintf(stderr,
"[iop_lens]: could not load lensfun database in `%s'!\n", dt_iop_lensfun_db->HomeDataDir);
1357#ifdef LF_MAX_DATABASE_VERSION
1362#ifdef LF_MAX_DATABASE_VERSION
1374 const dt_image_t *img = &
module->dev->image_storage;
1381 g_strlcpy(
d->lens, new_lens,
sizeof(
d->lens));
1383 g_strlcpy(
d->camera, img->
exif_model,
sizeof(
d->camera));
1388 d->modify_flags = LF_MODIFY_TCA | LF_MODIFY_VIGNETTING | LF_MODIFY_DISTORTION |
1389 LF_MODIFY_GEOMETRY | LF_MODIFY_SCALE;
1392 d->target_geom = LF_RECTILINEAR;
1395 d->modify_flags &= ~LF_MODIFY_TCA;
1400 for(
char cnt = 0, *c =
model; c <
model + 100 && *c !=
'\0'; c++)
1402 if(++cnt == 2) *c =
'\0';
1416 const lfLens **lens = gd->
db->FindLenses(cam[0], NULL,
d->lens, 0);
1419 if(!lens && islower(cam[0]->Mount[0]))
1428 g_strlcpy(
d->lens,
"",
sizeof(
d->lens));
1431 lens = gd->
db->FindLenses(cam[0], NULL,
d->lens, 0);
1444 if(!
d->lens[0] && islower(cam[0]->Mount[0]))
1450 size_t min_model_len = SIZE_MAX;
1451 for(
int i = 0; lens[
i];
i++)
1453 if(strlen(lens[
i]->Model) < min_model_len)
1455 min_model_len = strlen(lens[
i]->Model);
1461 g_strlcpy(
d->lens, lens[lens_i]->Model,
sizeof(
d->lens));
1464 d->target_geom = lens[lens_i]->Type;
1468 d->crop = cam[0]->CropFactor;
1470 module->workflow_enabled = dt_image_needs_rawprepare(img);
1482 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
1483 delete dt_iop_lensfun_db;
1502 if(
x == 0)
return 1;
1524 int length = array->len;
1525 g_ptr_array_set_size(array, length + 1);
1526 const void **root = (
const void **)array->pdata;
1528 int m = 0, l = 0,
r = length - 1;
1531 if(l <=
r && !root[
r])
r--;
1536 int cmp = compare(root[
m], item);
1551 memmove(root +
m + 1, root +
m,
sizeof(
void *) * (length -
m));
1558 int length = array->len;
1559 void **root = array->pdata;
1561 int l = 0,
r = length - 1;
1564 if(!length)
return -1;
1572 cmp = compare(root[
m], item);
1588 int length = array->len;
1589 g_ptr_array_set_size(array, length + 1);
1590 root = (
const void **)array->pdata;
1591 memmove(root + index + 1, root + index,
sizeof(
void *) * (length - index));
1609 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
g->camera_model))),
"");
1610 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->camera_model),
"");
1614 g_strlcpy(
p->camera, cam->Model,
sizeof(
p->camera));
1615 p->crop = cam->CropFactor;
1618 maker = lf_mlstr_get(cam->Maker);
1619 model = lf_mlstr_get(cam->Model);
1620 variant = lf_mlstr_get(cam->Variant);
1625 fm = g_strdup_printf(
"%s, %s",
maker,
model);
1627 fm = g_strdup_printf(
"%s",
model);
1628 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
g->camera_model))), fm);
1633 snprintf(_variant,
sizeof(_variant),
" (%s)", variant);
1637 fm = g_strdup_printf(_(
"maker:\t\t%s\n"
1640 "crop factor:\t%.1f"),
1641 maker,
model, _variant, cam->Mount, cam->CropFactor);
1642 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->camera_model), fm);
1649 camera_set(self, (lfCamera *)g_object_get_data(G_OBJECT(menuitem),
"lfCamera"));
1660 GPtrArray *makers, *submenus;
1664 gtk_widget_destroy(GTK_WIDGET(
g->camera_menu));
1665 g->camera_menu = NULL;
1669 makers = g_ptr_array_new();
1670 submenus = g_ptr_array_new();
1671 for(
i = 0; camlist[
i];
i++)
1674 const char *
m = lf_mlstr_get(camlist[
i]->Maker);
1681 submenu = gtk_menu_new();
1685 submenu = (
GtkWidget *)g_ptr_array_index(submenus, idx);
1687 m = lf_mlstr_get(camlist[
i]->Model);
1688 if(!camlist[
i]->Variant)
1689 item = gtk_menu_item_new_with_label(
m);
1692 gchar *fm = g_strdup_printf(
"%s (%s)",
m, camlist[
i]->Variant);
1693 item = gtk_menu_item_new_with_label(fm);
1696 gtk_widget_show(item);
1697 g_object_set_data(G_OBJECT(item),
"lfCamera", (
void *)camlist[
i]);
1699 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
1702 g->camera_menu = GTK_MENU(gtk_menu_new());
1703 for(
i = 0;
i < makers->len;
i++)
1705 GtkWidget *item = (
GtkWidget *)gtk_menu_item_new_with_label((
const gchar *)g_ptr_array_index(makers,
i));
1706 gtk_widget_show(item);
1707 gtk_menu_shell_append(GTK_MENU_SHELL(
g->camera_menu), item);
1708 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), (
GtkWidget *)g_ptr_array_index(submenus,
i));
1711 g_ptr_array_free(submenus,
TRUE);
1712 g_ptr_array_free(makers,
TRUE);
1717 while(txt[0] && isspace(txt[0])) txt++;
1718 size_t len = strlen(txt);
1719 if(len > sz_model - 1) len = sz_model - 1;
1720 memcpy(
model, txt, len);
1728 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
1733 const lfCamera *
const *camlist;
1735 camlist = dt_iop_lensfun_db->GetCameras();
1740 dt_gui_menu_popup(GTK_MENU(
g->camera_menu), button, GDK_GRAVITY_SOUTH, GDK_GRAVITY_NORTH);
1747 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
1749 char make[200],
model[200];
1756 const lfCamera *
const *camlist;
1758 camlist = dt_iop_lensfun_db->GetCameras();
1768 const lfCamera **camlist = dt_iop_lensfun_db->FindCamerasExt(make,
model, 0);
1775 dt_gui_menu_popup(GTK_MENU(
g->camera_menu), button, GDK_GRAVITY_SOUTH_EAST, GDK_GRAVITY_NORTH_EAST);
1784 if(text) (
void)sscanf(text,
"%f", &
p->focal);
1793 if(text) (
void)sscanf(text,
"%f", &
p->aperture);
1802 if(text) (
void)sscanf(text,
"%f", &
p->distance);
1810 gtk_widget_destroy(widget);
1821 gdouble focal_values[]
1822 = { -INFINITY, 4.5, 8, 10, 12, 14, 15, 16, 17, 18, 20, 24, 28, 30, 31, 35,
1823 38, 40, 43, 45, 50, 55, 60, 70, 75, 77, 80, 85, 90, 100, 105, 110,
1824 120, 135, 150, 200, 210, 240, 250, 300, 400, 500, 600, 800, 1000, INFINITY };
1825 gdouble aperture_values[]
1826 = { -INFINITY, 0.7, 0.8, 0.9, 1, 1.1, 1.2, 1.4, 1.8, 2, 2.2, 2.5, 2.8, 3.2, 3.4, 4, 4.5, 5.0,
1827 5.6, 6.3, 7.1, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 29, 32, 38, INFINITY };
1831 gtk_widget_set_sensitive(GTK_WIDGET(
g->modflags),
FALSE);
1832 gtk_widget_set_sensitive(GTK_WIDGET(
g->target_geom),
FALSE);
1833 gtk_widget_set_sensitive(GTK_WIDGET(
g->scale),
FALSE);
1834 gtk_widget_set_sensitive(GTK_WIDGET(
g->reverse),
FALSE);
1835 gtk_widget_set_sensitive(GTK_WIDGET(
g->tca_r),
FALSE);
1836 gtk_widget_set_sensitive(GTK_WIDGET(
g->tca_b),
FALSE);
1837 gtk_widget_set_sensitive(GTK_WIDGET(
g->message),
FALSE);
1845 gtk_widget_set_sensitive(GTK_WIDGET(
g->modflags),
TRUE);
1846 gtk_widget_set_sensitive(GTK_WIDGET(
g->target_geom),
TRUE);
1847 gtk_widget_set_sensitive(GTK_WIDGET(
g->scale),
TRUE);
1848 gtk_widget_set_sensitive(GTK_WIDGET(
g->reverse),
TRUE);
1849 gtk_widget_set_sensitive(GTK_WIDGET(
g->tca_r),
TRUE);
1850 gtk_widget_set_sensitive(GTK_WIDGET(
g->tca_b),
TRUE);
1851 gtk_widget_set_sensitive(GTK_WIDGET(
g->message),
TRUE);
1856 maker = lf_mlstr_get(lens->Maker);
1857 model = lf_mlstr_get(lens->Model);
1859 g_strlcpy(
p->lens, lens->Model,
sizeof(
p->lens));
1864 fm = g_strdup_printf(
"%s, %s",
maker,
model);
1866 fm = g_strdup_printf(
"%s",
model);
1867 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
g->lens_model))), fm);
1871 char focal[100], aperture[100], mounts[200];
1873 if(lens->MinFocal < lens->MaxFocal)
1874 snprintf(focal,
sizeof(focal),
"%g-%gmm", lens->MinFocal, lens->MaxFocal);
1876 snprintf(focal,
sizeof(focal),
"%gmm", lens->MinFocal);
1877 if(lens->MinAperture < lens->MaxAperture)
1878 snprintf(aperture,
sizeof(aperture),
"%g-%g", lens->MinAperture, lens->MaxAperture);
1880 snprintf(aperture,
sizeof(aperture),
"%g", lens->MinAperture);
1884 const char*
const* mount_names = lens->GetMountNames();
1886 while (mount_names && *mount_names) {
1887 if(
i > 0) g_strlcat(mounts,
", ",
sizeof(mounts));
1888 g_strlcat(mounts, *mount_names,
sizeof(mounts));
1894 for(
i = 0; lens->Mounts[
i];
i++)
1896 if(
i > 0) g_strlcat(mounts,
", ",
sizeof(mounts));
1897 g_strlcat(mounts, lens->Mounts[
i],
sizeof(mounts));
1900 fm = g_strdup_printf(_(
"maker:\t\t%s\n"
1902 "focal range:\t%s\n"
1904 "crop factor:\t%.1f\n"
1909 g->camera->CropFactor,
1913 lfLens::GetLensTypeDesc(lens->Type, NULL), mounts);
1915 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->lens_model), fm);
1919 gtk_container_foreach(GTK_CONTAINER(
g->lens_param_box),
delete_children, NULL);
1921 int ffi = 1, fli = -1;
1922 for(
i = 1;
i <
sizeof(focal_values) /
sizeof(gdouble) - 1;
i++)
1924 if(focal_values[
i] < lens->MinFocal) ffi =
i + 1;
1925 if(focal_values[
i] > lens->MaxFocal && fli == -1) fli =
i;
1927 if(focal_values[ffi] > lens->MinFocal)
1929 focal_values[ffi - 1] = lens->MinFocal;
1932 if(lens->MaxFocal == 0 || fli < 0) fli =
sizeof(focal_values) /
sizeof(gdouble) - 2;
1933 if(focal_values[fli + 1] < lens->MaxFocal)
1935 focal_values[fli + 1] = lens->MaxFocal;
1938 if(fli < ffi) fli = ffi + 1;
1946 gtk_widget_set_tooltip_text(w, _(
"focal length (mm)"));
1947 snprintf(txt,
sizeof(txt),
"%.*f",
precision(
p->focal, 10.0),
p->focal);
1949 for(
int k = 0;
k < fli - ffi;
k++)
1951 snprintf(txt,
sizeof(txt),
"%.*f",
precision(focal_values[ffi +
k], 10.0), focal_values[ffi +
k]);
1955 gtk_box_pack_start(GTK_BOX(
g->lens_param_box), w,
TRUE,
TRUE, 0);
1960 ffi = 1, fli =
sizeof(aperture_values) /
sizeof(gdouble) - 1;
1961 for(
i = 1;
i <
sizeof(aperture_values) /
sizeof(gdouble) - 1;
i++)
1962 if(aperture_values[
i] < lens->MinAperture) ffi =
i + 1;
1963 if(aperture_values[ffi] > lens->MinAperture)
1965 aperture_values[ffi - 1] = lens->MinAperture;
1971 gtk_widget_set_tooltip_text(w, _(
"f-number (aperture)"));
1972 snprintf(txt,
sizeof(txt),
"%.*f",
precision(
p->aperture, 10.0),
p->aperture);
1974 for(
int k = 0;
k < fli - ffi;
k++)
1976 snprintf(txt,
sizeof(txt),
"%.*f",
precision(aperture_values[ffi +
k], 10.0), aperture_values[ffi +
k]);
1980 gtk_box_pack_start(GTK_BOX(
g->lens_param_box), w,
TRUE,
TRUE, 0);
1986 gtk_widget_set_tooltip_text(w, _(
"distance to subject"));
1987 snprintf(txt,
sizeof(txt),
"%.*f",
precision(
p->distance, 10.0),
p->distance);
1990 for(
int k = 0;
k < 25;
k++)
1992 if(val > 1000.0f) val = 1000.0f;
1993 snprintf(txt,
sizeof(txt),
"%.*f",
precision(val, 10.0), val);
1995 if(val >= 1000.0f)
break;
1999 gtk_box_pack_start(GTK_BOX(
g->lens_param_box), w,
TRUE,
TRUE, 0);
2003 gtk_widget_show_all(
g->lens_param_box);
2011 lens_set(self, (lfLens *)g_object_get_data(G_OBJECT(menuitem),
"lfLens"));
2023 GPtrArray *makers, *submenus;
2027 gtk_widget_destroy(GTK_WIDGET(
g->lens_menu));
2028 g->lens_menu = NULL;
2032 makers = g_ptr_array_new();
2033 submenus = g_ptr_array_new();
2034 for(
i = 0; lenslist[
i];
i++)
2037 const char *
m = lf_mlstr_get(lenslist[
i]->Maker);
2044 submenu = gtk_menu_new();
2048 submenu = (
GtkWidget *)g_ptr_array_index(submenus, idx);
2050 item = gtk_menu_item_new_with_label(lf_mlstr_get(lenslist[
i]->Model));
2051 gtk_widget_show(item);
2052 g_object_set_data(G_OBJECT(item),
"lfLens", (
void *)lenslist[
i]);
2053 g_signal_connect(G_OBJECT(item),
"activate", G_CALLBACK(
lens_menu_select), self);
2054 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), item);
2057 g->lens_menu = GTK_MENU(gtk_menu_new());
2058 for(
i = 0;
i < makers->len;
i++)
2060 GtkWidget *item = gtk_menu_item_new_with_label((
const gchar *)g_ptr_array_index(makers,
i));
2061 gtk_widget_show(item);
2062 gtk_menu_shell_append(GTK_MENU_SHELL(
g->lens_menu), item);
2063 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), (
GtkWidget *)g_ptr_array_index(submenus,
i));
2066 g_ptr_array_free(submenus,
TRUE);
2067 g_ptr_array_free(makers,
TRUE);
2074 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
2076 const lfLens **lenslist;
2087 dt_gui_menu_popup(GTK_MENU(
g->lens_menu), button, GDK_GRAVITY_SOUTH, GDK_GRAVITY_NORTH);
2094 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
2096 const lfLens **lenslist;
2104 lenslist = dt_iop_lensfun_db->FindLenses(
g->camera, NULL,
2111 dt_gui_menu_popup(GTK_MENU(
g->lens_menu), button, GDK_GRAVITY_SOUTH_EAST, GDK_GRAVITY_NORTH_EAST);
2122 p->target_geom = (lfLensType)(pos + LF_UNKNOWN + 1);
2134 for(GList *modifiers =
g->modifiers; modifiers; modifiers = g_list_next(modifiers))
2139 p->modify_flags = (
p->modify_flags & ~LENSFUN_MODFLAG_MASK) | mm->
modflag;
2152 gtk_widget_set_visible(
g->tca_override, !raw_monochrome);
2157 gtk_widget_set_visible(
g->tca_r,
p->tca_override && !raw_monochrome);
2158 gtk_widget_set_visible(
g->tca_b,
p->tca_override && !raw_monochrome);
2172 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
2174 if(
p->lens[0] !=
'\0')
2177 const lfLens **lenslist
2178 = dt_iop_lensfun_db->FindLenses(camera, NULL,
p->lens, 0);
2188#if defined(__GNUC__) && (__GNUC__ > 7)
2191 .
lens = (lfLens *)lenslist[0],
2192 .modify_flags =
p->modify_flags,
2193 .inverse =
p->inverse,
2197 .aperture =
p->aperture,
2198 .distance =
p->distance,
2199 .target_geom =
p->target_geom,
2200 .custom_tca = { .Model = LF_TCA_MODEL_NONE }
2208 d.
lens = (lfLens *)lenslist[0];
2209 d.modify_flags =
p->modify_flags;
2210 d.inverse =
p->inverse;
2214 d.aperture =
p->aperture;
2215 d.distance =
p->distance;
2216 d.target_geom =
p->target_geom;
2217 d.custom_tca.Model = LF_TCA_MODEL_NONE;
2222 scale = modifier->GetAutoScale(
p->inverse);
2252 const char empty_message[] =
"";
2253 char *message = (
char *)empty_message;
2254 for(GList *modifiers =
g->modifiers; modifiers && self->
enabled; modifiers = g_list_next(modifiers))
2265 gtk_label_set_text(
g->message, message);
2266 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->message), message);
2275 g->camera_menu = NULL;
2276 g->lens_menu = NULL;
2277 g->modifiers = NULL;
2280 g->corrections_done = -1;
2288 g->modifiers = g_list_append(
g->modifiers, modifier);
2290 modifier->
pos = ++pos;
2294 g->modifiers = g_list_append(
g->modifiers, modifier);
2296 modifier->
pos = ++pos;
2300 g->modifiers = g_list_append(
g->modifiers, modifier);
2302 modifier->
pos = ++pos;
2306 g->modifiers = g_list_append(
g->modifiers, modifier);
2308 modifier->
pos = ++pos;
2312 g->modifiers = g_list_append(
g->modifiers, modifier);
2314 modifier->
pos = ++pos;
2318 g->modifiers = g_list_append(
g->modifiers, modifier);
2320 modifier->
pos = ++pos;
2324 g->modifiers = g_list_append(
g->modifiers, modifier);
2326 modifier->
pos = ++pos;
2330 g->modifiers = g_list_append(
g->modifiers, modifier);
2332 modifier->
pos = ++pos;
2335 gtk_widget_set_name(self->
widget,
"lens-module");
2346 gtk_box_pack_start(GTK_BOX(hbox),
g->find_camera_button,
FALSE,
FALSE, 0);
2358 gtk_box_pack_start(GTK_BOX(hbox),
g->find_lens_button,
FALSE,
FALSE, 0);
2363 gtk_box_pack_start(GTK_BOX(self->
widget),
g->lens_param_box,
TRUE,
TRUE, 0);
2369 char make [200],
model [200];
2370 const gchar *txt = gtk_entry_get_text(GTK_ENTRY(
g->lens_model));
2371 parse_maker_model (txt, make,
sizeof (make),
model,
sizeof (
model));
2373 const lfLens **lenslist = lf_db_find_lenses_hd (dt_iop_lensfun_db,
g->camera,
2374 make [0] ? make : NULL,
2376 if(lenslist)
lens_set (self, lenslist[0]);
2385 gtk_box_pack_start(GTK_BOX(self->
widget),
g->modflags,
TRUE,
TRUE, 0);
2386 gtk_widget_set_tooltip_text(
g->modflags, _(
"which corrections to apply"));
2387 GList *l =
g->modifiers;
2395 g_signal_connect(G_OBJECT(
g->modflags),
"value-changed", G_CALLBACK(
modflags_changed), (gpointer)self);
2400 gtk_box_pack_start(GTK_BOX(self->
widget),
g->target_geom,
TRUE,
TRUE, 0);
2401 gtk_widget_set_tooltip_text(
g->target_geom, _(
"target geometry"));
2406#if LF_VERSION >= ((0 << 24) | (2 << 16) | (6 << 8) | 0)
2419 g_signal_connect(G_OBJECT(
g->scale),
"quad-pressed", G_CALLBACK(
autoscale_pressed), self);
2420 gtk_widget_set_tooltip_text(
g->scale, _(
"auto scale"));
2426 gtk_widget_set_tooltip_text(
g->reverse, _(
"correct distortions or apply them"));
2433 gtk_widget_set_tooltip_text(
g->tca_r, _(
"Transversal Chromatic Aberration red"));
2437 gtk_widget_set_tooltip_text(
g->tca_b, _(
"Transversal Chromatic Aberration blue"));
2441 GtkBox *hbox1 = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL,
DT_GUI_BOX_SPACING));
2442 GtkWidget *label = gtk_label_new(_(
"corrections done: "));
2443 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
2444 gtk_widget_set_tooltip_text(label, _(
"which corrections have actually been done"));
2445 gtk_box_pack_start(GTK_BOX(hbox1), label,
FALSE,
FALSE, 0);
2446 g->message = GTK_LABEL(gtk_label_new(
""));
2447 gtk_label_set_ellipsize(GTK_LABEL(
g->message), PANGO_ELLIPSIZE_MIDDLE);
2448 gtk_box_pack_start(GTK_BOX(hbox1), GTK_WIDGET(
g->message),
FALSE,
FALSE, 0);
2449 gtk_box_pack_start(GTK_BOX(self->
widget), GTK_WIDGET(hbox1),
TRUE,
TRUE, 0);
2462 if(
p->modified == 0)
2472 lfDatabase *dt_iop_lensfun_db = (lfDatabase *)gd->
db;
2475 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
g->camera_model))),
p->camera);
2476 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
g->lens_model))),
p->lens);
2477 gtk_widget_set_tooltip_text(
g->camera_model,
"");
2478 gtk_widget_set_tooltip_text(
g->lens_model,
"");
2481 for(GList *modifiers =
g->modifiers; modifiers; modifiers = g_list_next(modifiers))
2493 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
g->tca_override),
p->tca_override);
2494 const lfCamera **cam = NULL;
2499 cam = dt_iop_lensfun_db->FindCamerasExt(NULL,
p->camera, 0);
2507 if(
g->camera &&
p->lens[0])
2512 const lfLens **lenslist = dt_iop_lensfun_db->FindLenses(
g->camera, NULL,
2531 g->corrections_done = -1;
2533 gtk_label_set_text(
g->message,
"");
2548 const int used_lf_mask = raw_monochrome ? (LF_MODIFY_ALL & ~LF_MODIFY_TCA) : LF_MODIFY_ALL;
2551 lens_d, used_lf_mask,
FALSE);
2558 for(GList *modifiers =
g->modifiers; !
IS_NULL_PTR(modifiers); modifiers = g_list_next(modifiers))
2561 if(mm->
modflag ==
g->corrections_done)
2563 gtk_label_set_text(
g->message, mm->
name);
2564 gtk_widget_set_tooltip_text(GTK_WIDGET(
g->message), mm->
name);
2582 g->modifiers = g_list_delete_link(
g->modifiers,
g->modifiers);
static void error(char *msg)
void dt_bauhaus_slider_set_digits(GtkWidget *widget, int val)
void dt_bauhaus_combobox_set_editable(GtkWidget *widget, int editable)
int dt_bauhaus_combobox_get(GtkWidget *widget)
const char * dt_bauhaus_combobox_get_text(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
void dt_bauhaus_widget_set_quad_paint(GtkWidget *widget, dt_bauhaus_quad_paint_f f, int paint_flags, void *paint_data)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
return vector dt_simd_set1(valid ?(scaling+NORM_MIN) :NORM_MIN)
const dt_colormatrix_t dt_aligned_pixel_t out
dt_store_simd_aligned(out, dt_mat3x4_mul_vec4(vin, dt_colormatrix_row_to_simd(matrix, 0), dt_colormatrix_row_to_simd(matrix, 1), dt_colormatrix_row_to_simd(matrix, 2)))
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
gboolean dt_image_is_monochrome(const dt_image_t *img)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define dt_free_align(ptr)
static void * dt_calloc_align(size_t size)
#define dt_gui_freeze_begin()
#define dt_gui_freeze_end()
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
void void void gboolean dt_gui_widgets_suppressed(void)
#define DT_MODULE_INTROSPECTION(MODVER, PARAMSTYPE)
#define __OMP_PARALLEL_FOR_CPP__(...)
#define dt_pixelpipe_cache_free_align(mem)
#define __DT_CLONE_TARGETS__
#define dt_get_perthread(buf, padsize)
#define dt_pixelpipe_cache_alloc_perthread_float(n, padded_size)
#define DT_PIXEL_SIMD_CHANNELS
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_dev_add_history_item(dev, module, enable, redraw)
dt_dev_pixelpipe_iop_t * dt_dev_distort_get_iop_pipe(struct dt_dev_pixelpipe_t *pipe, struct dt_iop_module_t *module)
@ DT_DEV_PIXELPIPE_DISPLAY_MASK
void dtgtk_cairo_paint_refresh(cairo_t *cr, gint x, gint y, gint w, gint h, gint flags, void *data)
void dtgtk_cairo_paint_solid_arrow(cairo_t *cr, gint x, int y, gint w, gint h, gint flags, void *data)
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_gui_menu_popup(GtkMenu *menu, GtkWidget *button, GdkGravity widget_anchor, GdkGravity menu_anchor)
void dt_gui_add_class(GtkWidget *widget, const gchar *class_name)
#define DT_GUI_BOX_SPACING
static void dt_iop_image_copy_by_size(float *const __restrict__ out, const float *const __restrict__ in, const size_t width, const size_t height, const size_t ch)
void dt_iop_compute_module_hash(dt_iop_module_t *module, GList *masks)
const char ** dt_iop_set_description(dt_iop_module_t *module, const char *main_text, const char *purpose, const char *input, const char *process, const char *output)
static void dt_iop_gui_enter_critical_section(dt_iop_module_t *const module) ACQUIRE(&module -> gui_lock)
@ IOP_FLAGS_TILING_FULL_ROI
static void dt_iop_gui_leave_critical_section(dt_iop_module_t *const module) RELEASE(&module -> gui_lock)
#define IOP_GUI_ALLOC(module)
GtkWidget * dt_iop_button_new(dt_iop_module_t *self, const gchar *label, GCallback callback, gboolean local, guint accel_key, GdkModifierType mods, DTGTKCairoPaintIconFunc paint, gint paintflags, GtkWidget *box)
GtkWidget * dt_bauhaus_toggle_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_slider_from_params(dt_iop_module_t *self, const char *param)
GtkWidget * dt_bauhaus_combobox_from_params(dt_iop_module_t *self, const char *param)
const struct dt_interpolation * dt_interpolation_new(enum dt_interpolation_type type)
__DT_CLONE_TARGETS__ float dt_interpolation_compute_sample(const struct dt_interpolation *itor, const float *in, const float x, const float y, const int width, const int height, const int samplestride, const int linestride)
@ DT_INTERPOLATION_BICUBIC
@ DT_INTERPOLATION_BILINEAR
@ DT_INTERPOLATION_MITCHELL
@ DT_INTERPOLATION_USERPREF_WARP
#define LF_SEARCH_SORT_AND_UNIQUIFY
int distort_backtransform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *const __restrict points, size_t points_count)
void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
void distort_mask(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, const float *const in, float *const out, const dt_iop_roi_t *const roi_in, const dt_iop_roi_t *const roi_out)
const char ** description(struct dt_iop_module_t *self)
static void _lens_fill_vignette_row(float *const buf, const int width, const int ch)
static int ptr_array_find_sorted(const GPtrArray *array, const void *item, GCompareFunc compare)
static void lens_set(dt_iop_module_t *self, const lfLens *lens)
void reload_defaults(dt_iop_module_t *module)
static void lens_comboentry_distance_update(GtkWidget *widget, dt_iop_module_t *self)
static __DT_CLONE_TARGETS__ lfModifier * get_modifier(int *mods_done, int w, int h, const dt_iop_lensfun_data_t *d, int mods_filter, gboolean force_inverse)
static char * _lens_sanitize(const char *orig_lens)
static void lens_autosearch_clicked(GtkWidget *button, gpointer user_data)
static void autoscale_pressed(GtkWidget *button, gpointer user_data)
__DT_CLONE_TARGETS__ int process(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, const void *const ivoid, void *const ovoid)
static void camera_menu_select(GtkMenuItem *menuitem, gpointer user_data)
static void camera_set(dt_iop_module_t *self, const lfCamera *cam)
static void lens_comboentry_focal_update(GtkWidget *widget, dt_iop_module_t *self)
static void camera_menusearch_clicked(GtkWidget *button, gpointer user_data)
static void lens_comboentry_aperture_update(GtkWidget *widget, dt_iop_module_t *self)
@ LENSFUN_MODFLAG_TCA_VIGN
@ LENSFUN_MODFLAG_DIST_TCA
@ LENSFUN_MODFLAG_DIST_VIGN
void init_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
int distort_transform(dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, float *const __restrict points, size_t points_count)
static void ptr_array_insert_index(GPtrArray *array, const void *item, int index)
void gui_update(struct dt_iop_module_t *self)
Refresh GUI controls from current params and configuration.
static int precision(double x, double adj)
void gui_init(struct dt_iop_module_t *self)
void gui_changed(dt_iop_module_t *self, GtkWidget *w, void *previous)
void tiling_callback(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, const struct dt_dev_pixelpipe_iop_t *piece, struct dt_develop_tiling_t *tiling)
static float get_autoscale(dt_iop_module_t *self, dt_iop_lensfun_params_t *p, const lfCamera *camera)
static void lens_menu_fill(dt_iop_module_t *self, const lfLens *const *lenslist)
void cleanup_global(dt_iop_module_so_t *module)
static void camera_menu_fill(dt_iop_module_t *self, const lfCamera *const *camlist)
static void corrections_done(gpointer instance, gpointer user_data)
int default_colorspace(dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece)
static void lens_menusearch_clicked(GtkWidget *button, gpointer user_data)
void modify_roi_in(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, const dt_iop_roi_t *const roi_out, dt_iop_roi_t *roi_in)
void gui_cleanup(struct dt_iop_module_t *self)
static int ptr_array_insert_sorted(GPtrArray *array, const void *item, GCompareFunc compare)
static void lens_menu_select(GtkMenuItem *menuitem, gpointer user_data)
static void target_geometry_changed(GtkWidget *widget, gpointer user_data)
static void parse_model(const char *txt, char *model, size_t sz_model)
void cleanup_pipe(struct dt_iop_module_t *self, dt_dev_pixelpipe_t *pipe, dt_dev_pixelpipe_iop_t *piece)
static void delete_children(GtkWidget *widget, gpointer data)
void init_global(dt_iop_module_so_t *module)
int process_cl(struct dt_iop_module_t *self, const dt_dev_pixelpipe_t *pipe, const dt_dev_pixelpipe_iop_t *piece, cl_mem dev_in, cl_mem dev_out)
static void modflags_changed(GtkWidget *widget, gpointer user_data)
static void camera_autosearch_clicked(GtkWidget *button, gpointer user_data)
void modify_roi_out(struct dt_iop_module_t *self, const struct dt_dev_pixelpipe_t *pipe, struct dt_dev_pixelpipe_iop_t *piece, dt_iop_roi_t *roi_out, const dt_iop_roi_t *roi_in)
int legacy_params(dt_iop_module_t *self, const void *const old_params, const int old_version, void *new_params, const int new_version)
float *const restrict const size_t k
float *const restrict const size_t const size_t ch
int dt_opencl_enqueue_kernel_2d(const int dev, const int kernel, const size_t *sizes)
void * dt_opencl_alloc_device_buffer(const int devid, const size_t size)
void * dt_opencl_alloc_device(const int devid, const int width, const int height, const int bpp)
int dt_opencl_create_kernel(const int prog, const char *name)
int dt_opencl_write_buffer_to_device(const int devid, void *host, void *device, const size_t offset, const size_t size, const int blocking)
int dt_opencl_enqueue_copy_image(const int devid, cl_mem src, cl_mem dst, size_t *orig_src, size_t *orig_dst, size_t *region)
void dt_opencl_free_kernel(const int kernel)
int dt_opencl_set_kernel_arg(const int dev, const int kernel, const int num, const size_t size, const void *arg)
void dt_opencl_release_mem_object(cl_mem mem)
#define DT_DEBUG_CONTROL_SIGNAL_DISCONNECT(ctlsig, cb, user_data)
@ DT_SIGNAL_DEVELOP_PREVIEW_PIPE_FINISHED
This signal is raised when develop preview pipe process is finished no param, no returned value.
#define DT_DEBUG_CONTROL_SIGNAL_CONNECT(ctlsig, signal, cb, user_data)
struct _GtkWidget GtkWidget
dt_pthread_mutex_t plugin_threadsafe
struct dt_control_signal_t * signals
struct dt_bauhaus_t * bauhaus
struct dt_develop_t * develop
dt_iop_buffer_dsc_t dsc_in
struct dt_iop_module_t *void * data
gboolean cache_output_on_ram
dt_dev_pixelpipe_type_t type
struct dt_dev_pixelpipe_t * virtual_pipe
float exif_focus_distance
enum dt_interpolation_type id
lfLensCalibTCA custom_tca
int kernel_lens_distort_bicubic
int kernel_lens_distort_bilinear
int kernel_lens_distort_mitchell
GtkWidget * find_camera_button
GtkWidget * find_lens_button
GtkWidget * lens_param_box
dt_iop_global_data_t * data
dt_iop_params_t * default_params
struct dt_develop_t * dev
dt_iop_gui_data_t * gui_data
dt_iop_global_data_t * global_data
Region of interest passed through the pixelpipe.
size_t dt_utf8_strlcpy(char *dest, const char *src, size_t n)