Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prophoto RGB support #1744

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/common/colorspaces.c
Expand Up @@ -38,6 +38,7 @@
#endif

static const cmsCIEXYZ d65 = {0.95045471, 1.00000000, 1.08905029};
//static const cmsCIEXYZ d50 = {0.96422000, 1.00000000, 0.82490000};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment added, but I don't see why? If there is noting to say about it, better remove this line otherwise can you add a blurb about what it is about?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to use the same structure of code that is used for Adobe RGB, but none of these constants are actually used in the code, which is strange because we are supposed to correct the XYZ illuminant (D50 or D65) at some point when applying the conversion matrices between color spaces. So anyway, I dropped that here only for consistency, but they might come in handy at some point.

static const cmsCIEXYZTRIPLE rec709_primaries_pre_quantized = {
{0.43603516, 0.22248840, 0.01391602},
{0.38511658, 0.71690369, 0.09706116},
Expand All @@ -53,6 +54,11 @@ static const cmsCIEXYZTRIPLE adobe_primaries_prequantized = {
{0.20527649, 0.62567139, 0.06086731},
{0.14918518, 0.06321716, 0.74456787}
};
static const cmsCIEXYZTRIPLE prophoto_primaries_prequantized = {
{0.7976749f, 0.1351917f, 0.0313534f},
{0.2880402f, 0.7118741f, 0.0000857f},
{0.0000000f, 0.0000000f, 0.8252100f}
};

#define generate_mat3inv_body(c_type, A, B) \
int mat3inv_##c_type(c_type *const dst, const c_type *const src) \
Expand Down Expand Up @@ -339,6 +345,18 @@ static cmsHPROFILE dt_colorspaces_create_adobergb_profile(void)
return profile;
}

static cmsHPROFILE dt_colorspaces_create_prophotorgb_profile(void)
{
cmsToneCurve *transferFunction = cmsBuildGamma(NULL, 1.8);

cmsHPROFILE profile = _create_lcms_profile("Prophoto RGB", "Prophoto RGB",
&prophoto_primaries_prequantized, transferFunction, TRUE);

cmsFreeToneCurve(transferFunction);

return profile;
}

static cmsToneCurve *build_linear_gamma(void)
{
double Parameters[2];
Expand Down Expand Up @@ -945,7 +963,8 @@ static const char *_profile_names[] =
N_("standard color matrix"),
N_("enhanced color matrix"),
N_("vendor color matrix"),
N_("alternate color matrix")
N_("alternate color matrix"),
N_("Prophoto RGB"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bear with me, I'm no expert. But is it ok to have a Prophoto RGB color space into the list of matrix? I mean we don't have Adobe RGB here for example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's an error, it shouldn't be there, I will fix that.

};

static dt_colorspaces_color_profile_t *_create_profile(dt_colorspaces_color_profile_type_t type,
Expand All @@ -971,6 +990,9 @@ static void _update_display_transforms(dt_colorspaces_t *self)

if(self->transform_adobe_rgb_to_display) cmsDeleteTransform(self->transform_adobe_rgb_to_display);
self->transform_adobe_rgb_to_display = NULL;

if(self->transform_prophoto_rgb_to_display) cmsDeleteTransform(self->transform_prophoto_rgb_to_display);
self->transform_prophoto_rgb_to_display = NULL;

const dt_colorspaces_color_profile_t *display_dt_profile = _get_profile(self, self->display_type,
self->display_filename,
Expand All @@ -994,6 +1016,14 @@ static void _update_display_transforms(dt_colorspaces_t *self)
TYPE_BGRA_8,
self->display_intent,
0);

self->transform_prophoto_rgb_to_display = cmsCreateTransform(_get_profile(self, DT_COLORSPACE_PROPHOTORGB, "",
DT_PROFILE_DIRECTION_DISPLAY)->profile,
TYPE_RGBA_8,
display_profile,
TYPE_BGRA_8,
self->display_intent,
0);
}

// update cached transforms for color management of thumbnails
Expand Down Expand Up @@ -1157,6 +1187,11 @@ dt_colorspaces_t *dt_colorspaces_init()
dt_colorspaces_create_adobergb_profile(),
_("Adobe RGB (compatible)"),
++in_pos, ++out_pos, ++display_pos));

res->profiles = g_list_append(res->profiles, _create_profile(DT_COLORSPACE_PROPHOTORGB,
dt_colorspaces_create_prophotorgb_profile(),
_("Prophoto RGB"),
++in_pos, ++out_pos, ++display_pos));

res->profiles = g_list_append(res->profiles, _create_profile(DT_COLORSPACE_LIN_REC709,
dt_colorspaces_create_linear_rec709_rgb_profile(),
Expand Down
5 changes: 3 additions & 2 deletions src/common/colorspaces.h
Expand Up @@ -57,7 +57,8 @@ typedef enum dt_colorspaces_color_profile_type_t
DT_COLORSPACE_VENDOR_MATRIX = 13,
DT_COLORSPACE_ALTERNATE_MATRIX = 14,
DT_COLORSPACE_BRG = 15,
DT_COLORSPACE_LAST = 16
DT_COLORSPACE_LAST = 16,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think LAST should stays in last position, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes sense, I didn't wanted to change the order since I wasn't sure it would be safe.

DT_COLORSPACE_PROPHOTORGB = 17
} dt_colorspaces_color_profile_type_t;

typedef enum dt_colorspaces_color_mode_t
Expand Down Expand Up @@ -95,7 +96,7 @@ typedef struct dt_colorspaces_t

dt_colorspaces_color_mode_t mode;

cmsHTRANSFORM transform_srgb_to_display, transform_adobe_rgb_to_display;
cmsHTRANSFORM transform_srgb_to_display, transform_adobe_rgb_to_display, transform_prophoto_rgb_to_display;

} dt_colorspaces_t;

Expand Down
4 changes: 4 additions & 0 deletions src/common/exif.cc
Expand Up @@ -873,6 +873,8 @@ static bool dt_exif_read_exif_data(dt_image_t *img, Exiv2::ExifData &exifData)
img->colorspace = DT_IMAGE_COLORSPACE_SRGB;
else if(colorspace == 0x02)
img->colorspace = DT_IMAGE_COLORSPACE_ADOBE_RGB;
else if(colorspace == 0x03)
img->colorspace = DT_IMAGE_COLORSPACE_PROPHOTO_RGB;
else if(colorspace == 0xffff)
{
if(FIND_EXIF_TAG("Exif.Iop.InteroperabilityIndex"))
Expand Down Expand Up @@ -2865,6 +2867,8 @@ dt_colorspaces_color_profile_type_t dt_exif_get_color_space(const uint8_t *data,
return DT_COLORSPACE_SRGB;
else if(colorspace == 0x02)
return DT_COLORSPACE_ADOBERGB;
else if(colorspace == 0x03)
return DT_COLORSPACE_PROPHOTORGB;
else if(colorspace == 0xffff)
{
if((pos = exifData.findKey(Exiv2::ExifKey("Exif.Iop.InteroperabilityIndex"))) != exifData.end()
Expand Down
3 changes: 2 additions & 1 deletion src/common/image.h
Expand Up @@ -76,7 +76,8 @@ typedef enum dt_image_colorspace_t
{
DT_IMAGE_COLORSPACE_NONE,
DT_IMAGE_COLORSPACE_SRGB,
DT_IMAGE_COLORSPACE_ADOBE_RGB
DT_IMAGE_COLORSPACE_ADOBE_RGB,
DT_IMAGE_COLORSPACE_PROPHOTO_RGB
} dt_image_colorspace_t;

typedef struct dt_image_raw_parameters_t
Expand Down
7 changes: 7 additions & 0 deletions src/iop/colorin.c
Expand Up @@ -62,6 +62,7 @@ typedef enum dt_iop_color_normalize_t
DT_NORMALIZE_OFF,
DT_NORMALIZE_SRGB,
DT_NORMALIZE_ADOBE_RGB,
DT_NORMALIZE_PROPHOTO_RGB,
DT_NORMALIZE_LINEAR_REC709_RGB,
DT_NORMALIZE_LINEAR_REC2020_RGB
} dt_iop_color_normalize_t;
Expand Down Expand Up @@ -1287,6 +1288,9 @@ void commit_params(struct dt_iop_module_t *self, dt_iop_params_t *p1, dt_dev_pix
case DT_NORMALIZE_ADOBE_RGB:
d->nrgb = dt_colorspaces_get_profile(DT_COLORSPACE_ADOBERGB, "", DT_PROFILE_DIRECTION_IN)->profile;
break;
case DT_NORMALIZE_PROPHOTO_RGB:
d->nrgb = dt_colorspaces_get_profile(DT_COLORSPACE_PROPHOTORGB, "", DT_PROFILE_DIRECTION_IN)->profile;
break;
case DT_NORMALIZE_LINEAR_REC709_RGB:
d->nrgb = dt_colorspaces_get_profile(DT_COLORSPACE_LIN_REC709, "", DT_PROFILE_DIRECTION_IN)->profile;
break;
Expand Down Expand Up @@ -1678,6 +1682,8 @@ void reload_defaults(dt_iop_module_t *module)
tmp.type = DT_COLORSPACE_SRGB;
else if(module->dev->image_storage.colorspace == DT_IMAGE_COLORSPACE_ADOBE_RGB)
tmp.type = DT_COLORSPACE_ADOBERGB;
else if(module->dev->image_storage.colorspace == DT_IMAGE_COLORSPACE_PROPHOTO_RGB)
tmp.type = DT_COLORSPACE_PROPHOTORGB;
else if(dt_image_is_ldr(&module->dev->image_storage))
tmp.type = DT_COLORSPACE_SRGB;
else if(!isnan(module->dev->image_storage.d65_color_matrix[0]))
Expand Down Expand Up @@ -1863,6 +1869,7 @@ void gui_init(struct dt_iop_module_t *self)
dt_bauhaus_combobox_add(g->clipping_combobox, _("off"));
dt_bauhaus_combobox_add(g->clipping_combobox, _("sRGB"));
dt_bauhaus_combobox_add(g->clipping_combobox, _("Adobe RGB (compatible)"));
dt_bauhaus_combobox_add(g->clipping_combobox, _("Prophoto RGB"));
dt_bauhaus_combobox_add(g->clipping_combobox, _("linear Rec709 RGB"));
dt_bauhaus_combobox_add(g->clipping_combobox, _("linear Rec2020 RGB"));

Expand Down
5 changes: 5 additions & 0 deletions src/views/view.c
Expand Up @@ -1021,6 +1021,11 @@ int dt_view_image_expose(dt_view_image_over_t *image_over, uint32_t imgid, cairo
{
transform = darktable.color_profiles->transform_adobe_rgb_to_display;
}
else if(buf.color_space == DT_COLORSPACE_PROPHOTORGB &&
darktable.color_profiles->transform_prophoto_rgb_to_display)
{
transform = darktable.color_profiles->transform_prophoto_rgb_to_display;
}
else
{
pthread_rwlock_unlock(&darktable.color_profiles->xprofile_lock);
Expand Down