@@ -57,7 +57,8 @@ const char *iop_order_string[] =
5757{
5858 N_ ("custom" ),
5959 N_ ("legacy" ),
60- N_ ("v3.0" )
60+ N_ ("v3.0 RAW" ),
61+ N_ ("v3.0 JPEG" )
6162};
6263
6364const char * dt_iop_order_string (const dt_iop_order_t order )
@@ -164,6 +165,7 @@ const dt_iop_order_entry_t legacy_order[] = {
164165 { { 0.0f }, "" , 0 }
165166};
166167
168+ // default order for RAW files, assumed to be linear from start
167169const dt_iop_order_entry_t v30_order [] = {
168170 { { 1.0 }, "rawprepare" , 0 },
169171 { { 2.0 }, "invert" , 0 },
@@ -269,6 +271,120 @@ const dt_iop_order_entry_t v30_order[] = {
269271 { { 0.0f }, "" , 0 }
270272};
271273
274+ // default order for JPEG/TIFF/PNG files, non-linear before colorin
275+ const dt_iop_order_entry_t v30_jpg_order [] = {
276+ // the following modules are not used anyway for non-RAW images :
277+ { { 1.0 }, "rawprepare" , 0 },
278+ { { 2.0 }, "invert" , 0 },
279+ { { 3.0f }, "temperature" , 0 },
280+ { { 4.0f }, "highlights" , 0 },
281+ { { 5.0f }, "cacorrect" , 0 },
282+ { { 6.0f }, "hotpixels" , 0 },
283+ { { 7.0f }, "rawdenoise" , 0 },
284+ { { 8.0f }, "demosaic" , 0 },
285+ // all the modules between [8; 28] expect linear RGB, so they need to be moved after colorin
286+ { { 28.0f }, "colorin" , 0 },
287+ // moved modules : (copy-pasted in the same order)
288+ { { 28.0f }, "denoiseprofile" , 0 },
289+ { { 28.0f }, "bilateral" , 0 },
290+ { { 28.0f }, "rotatepixels" , 0 },
291+ { { 28.0f }, "scalepixels" , 0 },
292+ { { 28.0f }, "lens" , 0 },
293+ { { 28.0f }, "cacorrectrgb" , 0 }, // correct chromatic aberrations after lens correction so that lensfun
294+ // does not reintroduce chromatic aberrations when trying to correct them
295+ { { 28.0f }, "hazeremoval" , 0 },
296+ { { 28.0f }, "ashift" , 0 },
297+ { { 28.0f }, "flip" , 0 },
298+ { { 28.0f }, "clipping" , 0 },
299+ { { 28.0f }, "liquify" , 0 },
300+ { { 28.0f }, "spots" , 0 },
301+ { { 28.0f }, "retouch" , 0 },
302+ { { 28.0f }, "exposure" , 0 },
303+ { { 28.0f }, "mask_manager" , 0 },
304+ { { 28.0f }, "tonemap" , 0 },
305+ { { 28.0f }, "toneequal" , 0 }, // last module that need enlarged roi_in
306+ { { 28.0f }, "crop" , 0 }, // should go after all modules that may need a wider roi_in
307+ { { 28.0f }, "graduatednd" , 0 },
308+ { { 28.0f }, "profile_gamma" , 0 },
309+ { { 28.0f }, "equalizer" , 0 },
310+ // from there, it's the same as the raw order
311+ { { 28.5f }, "diffuse" , 0 },
312+ { { 28.5f }, "channelmixerrgb" , 0 },
313+ { { 28.5f }, "censorize" , 0 },
314+ { { 28.5f }, "negadoctor" , 0 }, // Cineon film encoding comes after scanner input color profile
315+ { { 28.5f }, "blurs" , 0 }, // physically-accurate blurs (motion and lens)
316+ { { 29.0f }, "nlmeans" , 0 }, // signal processing (denoising)
317+ // -> needs a signal as scene-referred as possible (even if it works in Lab)
318+ { { 30.0f }, "colorchecker" , 0 }, // calibration to "neutral" exchange colour space
319+ // -> improve colour calibration of colorin and reproductibility
320+ // of further edits (styles etc.)
321+ { { 31.0f }, "defringe" , 0 }, // desaturate fringes in Lab, so needs properly calibrated colours
322+ // in order for chromaticity to be meaningful,
323+ { { 32.0f }, "atrous" , 0 }, // frequential operation, needs a signal as scene-referred as possible to avoid halos
324+ { { 33.0f }, "lowpass" , 0 }, // same
325+ { { 34.0f }, "highpass" , 0 }, // same
326+ { { 35.0f }, "sharpen" , 0 }, // same, worst than atrous in same use-case, less control overall
327+ { { 36.0f }, "lut3d" , 0 }, // apply a creative style or film emulation, possibly non-linear,
328+ // so better move it after frequential ops that need L2 Hilbert spaces
329+ // of square summable functions
330+ { { 37.0f }, "colortransfer" , 0 }, // probably better if source and destination colours are neutralized in the
331+ // same
332+ // colour exchange space, hence after colorin and colorcheckr,
333+ // but apply after frequential ops in case it does non-linear witchcraft,
334+ // just to be safe
335+ { { 38.0f }, "colormapping" , 0 }, // same
336+ { { 39.0f }, "channelmixer" , 0 }, // does exactly the same thing as colorin, aka RGB to RGB matrix conversion,
337+ // but coefs are user-defined instead of calibrated and read from ICC
338+ // profile. Really versatile yet under-used module, doing linear ops, very
339+ // good in scene-referred workflow
340+ { { 40.0f }, "basicadj" , 0 }, // module mixing view/model/control at once, usage should be discouraged
341+ { { 41.0f }, "colorbalance" , 0 }, // scene-referred color manipulation
342+ { { 41.5f }, "colorbalancergb" , 0 }, // scene-referred color manipulation
343+ { { 42.0f }, "rgbcurve" , 0 }, // really versatile way to edit colour in scene-referred and display-referred
344+ // workflow
345+ { { 43.0f }, "rgblevels" , 0 }, // same
346+ { { 44.0f }, "basecurve" , 0 }, // conversion from scene-referred to display referred, reverse-engineered
347+ // on camera JPEG default look
348+ { { 45.0f }, "filmic" , 0 }, // same, but different (parametric) approach
349+ { { 46.0f }, "filmicrgb" , 0 }, // same, upgraded
350+ { { 47.0f }, "colisa" , 0 }, // edit contrast while damaging colour
351+ { { 48.0f }, "tonecurve" , 0 }, // same
352+ { { 49.0f }, "levels" , 0 }, // same
353+ { { 50.0f }, "shadhi" , 0 }, // same
354+ { { 51.0f }, "zonesystem" , 0 }, // same
355+ { { 52.0f }, "globaltonemap" , 0 }, // same
356+ { { 53.0f }, "relight" , 0 }, // flatten local contrast while pretending do add lightness
357+ { { 54.0f }, "bilat" , 0 }, // improve clarity/local contrast after all the bad things we have done
358+ // to it with tonemapping
359+ { { 55.0f }, "colorcorrection" , 0 }, // now that the colours have been damaged by contrast manipulations,
360+ // try to recover them - global adjustment of white balance for shadows and
361+ // highlights
362+ { { 56.0f }, "colorcontrast" , 0 }, // adjust chrominance globally
363+ { { 57.0f }, "velvia" , 0 }, // same
364+ { { 58.0f }, "vibrance" , 0 }, // same, but more subtle
365+ { { 60.0f }, "colorzones" , 0 }, // same, but locally
366+ { { 61.0f }, "bloom" , 0 }, // creative module
367+ { { 62.0f }, "colorize" , 0 }, // creative module
368+ { { 63.0f }, "lowlight" , 0 }, // creative module
369+ { { 64.0f }, "monochrome" , 0 }, // creative module
370+ { { 65.0f }, "grain" , 0 }, // creative module
371+ { { 66.0f }, "soften" , 0 }, // creative module
372+ { { 67.0f }, "splittoning" , 0 }, // creative module
373+ { { 68.0f }, "vignette" , 0 }, // creative module
374+ { { 69.0f }, "colorreconstruct" , 0 }, // try to salvage blown areas before ICC intents in LittleCMS2 do things
375+ // with them.
376+ { { 70.0f }, "colorout" , 0 },
377+ { { 71.0f }, "clahe" , 0 },
378+ { { 72.0f }, "finalscale" , 0 },
379+ { { 73.0f }, "overexposed" , 0 },
380+ { { 74.0f }, "rawoverexposed" , 0 },
381+ { { 75.0f }, "dither" , 0 },
382+ { { 76.0f }, "borders" , 0 },
383+ { { 77.0f }, "watermark" , 0 },
384+ { { 78.0f }, "gamma" , 0 },
385+ { { 0.0f }, "" , 0 }
386+ };
387+
272388static void * _dup_iop_order_entry (const void * src , gpointer data );
273389static int _count_entries_operation (GList * e_list , const char * operation );
274390
@@ -447,7 +563,7 @@ gint dt_sort_iop_list_by_order_f(gconstpointer a, gconstpointer b)
447563
448564dt_iop_order_t dt_ioppr_get_iop_order_list_kind (GList * iop_order_list )
449565{
450- // first check if this is the v30 order
566+ // first check if this is the v30 order RAW
451567 int k = 0 ;
452568 GList * l = iop_order_list ;
453569 gboolean ok = TRUE;
@@ -473,6 +589,32 @@ dt_iop_order_t dt_ioppr_get_iop_order_list_kind(GList *iop_order_list)
473589
474590 if (ok ) return DT_IOP_ORDER_V30 ;
475591
592+ // then check if this is the v30 order JPG
593+ k = 0 ;
594+ l = iop_order_list ;
595+ ok = TRUE;
596+ while (l )
597+ {
598+ const dt_iop_order_entry_t * const restrict entry = (dt_iop_order_entry_t * )l -> data ;
599+ if (strcmp (v30_jpg_order [k ].operation , entry -> operation ))
600+ {
601+ ok = FALSE;
602+ break ;
603+ }
604+ else
605+ {
606+ // skip all the other instance of same module if any
607+ while (g_list_next (l )
608+ && !strcmp (v30_jpg_order [k ].operation , ((dt_iop_order_entry_t * )(g_list_next (l )-> data ))-> operation ))
609+ l = g_list_next (l );
610+ }
611+
612+ k ++ ;
613+ l = g_list_next (l );
614+ }
615+
616+ if (ok ) return DT_IOP_ORDER_V30_JPG ;
617+
476618 // then check if this is the legacy order
477619 k = 0 ;
478620 l = iop_order_list ;
@@ -596,6 +738,10 @@ GList *dt_ioppr_get_iop_order_list_version(dt_iop_order_t version)
596738 {
597739 iop_order_list = _table_to_list (v30_order );
598740 }
741+ else if (version == DT_IOP_ORDER_V30_JPG )
742+ {
743+ iop_order_list = _table_to_list (v30_jpg_order );
744+ }
599745
600746 return iop_order_list ;
601747}
@@ -677,6 +823,10 @@ GList *dt_ioppr_get_iop_order_list(int32_t imgid, gboolean sorted)
677823 {
678824 iop_order_list = _table_to_list (v30_order );
679825 }
826+ else if (version == DT_IOP_ORDER_V30_JPG )
827+ {
828+ iop_order_list = _table_to_list (v30_jpg_order );
829+ }
680830 else
681831 fprintf (stderr , "[dt_ioppr_get_iop_order_list] invalid iop order version %d for imgid %d\n" , version , imgid );
682832
0 commit comments