add support for lcms black point compensation

Add a --black-point-compensation flag.

See https://github.com/libvips/libvips/discussions/2169
This commit is contained in:
John Cupitt 2021-03-29 12:41:02 +01:00
parent e4453f8b18
commit 005360dba7
2 changed files with 44 additions and 13 deletions

View File

@ -22,6 +22,7 @@
- add vips_image_[set|get]_array_double()
- add GIF load with libnsgif
- add JPEG2000 load and save
- add black_point_compensation flag for icc transforms
22/12/20 start 8.10.6
- don't seek on bad file descriptors [kleisauke]

View File

@ -43,6 +43,8 @@
* they can be triggered under normal circumstances
* 17/4/19 kleisauke
* - better rejection of broken embedded profiles
* 29/3/21 [hanssonrickard]
* - add black_point_compensation
*/
/*
@ -152,6 +154,7 @@ typedef struct _VipsIcc {
VipsIntent intent;
VipsPCS pcs;
int depth;
gboolean black_point_compensation;
VipsBlob *in_blob;
cmsHPROFILE in_profile;
@ -215,6 +218,8 @@ vips_icc_build( VipsObject *object )
VipsColourCode *code = (VipsColourCode *) object;
VipsIcc *icc = (VipsIcc *) object;
cmsUInt32Number flags;
if( icc->depth != 8 &&
icc->depth != 16 ) {
vips_error( class->nickname,
@ -353,10 +358,15 @@ vips_icc_build( VipsObject *object )
/* Use cmsFLAGS_NOCACHE to disable the 1-pixel cache and make
* calling cmsDoTransform() from multiple threads safe.
*/
flags = cmsFLAGS_NOCACHE;
if( icc->black_point_compensation )
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
if( !(icc->trans = cmsCreateTransform(
icc->in_profile, icc->in_icc_format,
icc->out_profile, icc->out_icc_format,
icc->intent, cmsFLAGS_NOCACHE )) )
icc->intent, flags )) )
return( -1 );
if( VIPS_OBJECT_CLASS( vips_icc_parent_class )->
@ -394,6 +404,13 @@ vips_icc_class_init( VipsIccClass *class )
G_STRUCT_OFFSET( VipsIcc, pcs ),
VIPS_TYPE_PCS, VIPS_PCS_LAB );
VIPS_ARG_BOOL( class, "black_point_compensation", 7,
_( "Black point compensation" ),
_( "Enable black point compensation" ),
VIPS_ARGUMENT_OPTIONAL_INPUT,
G_STRUCT_OFFSET( VipsIcc, black_point_compensation ),
FALSE );
cmsSetLogErrorHandler( icc_error );
}
@ -1345,10 +1362,11 @@ vips_icc_is_compatible_profile( VipsImage *image,
*
* Optional arguments:
*
* * @input_profile: get the input profile from here
* * @intent: transform with this intent
* * @embedded: use profile embedded in input image
* * @pcs: use XYZ or LAB PCS
* * @pcs: #VipsPCS, use XYZ or LAB PCS
* * @intent: #VipsIntent, transform with this intent
* * @black_point_compensation: %gboolean, enable black point compensation
* * @embedded: %gboolean, use profile embedded in input image
* * @input_profile: %gchararray, get the input profile from here
*
* Import an image from device space to D65 LAB with an ICC profile. If @pcs is
* set to #VIPS_PCS_XYZ, use CIE XYZ PCS instead.
@ -1365,6 +1383,9 @@ vips_icc_is_compatible_profile( VipsImage *image,
* @input_profile. If @input_profile is not supplied, the
* metadata profile, if any, is used as a fall-back.
*
* If @black_point_compensation is set, LCMS black point compensation is
* enabled.
*
* Returns: 0 on success, -1 on error.
*/
int
@ -1388,10 +1409,11 @@ vips_icc_import( VipsImage *in, VipsImage **out, ... )
*
* Optional arguments:
*
* * @intent: transform with this intent
* * @depth: depth of output image in bits
* * @output_profile: get the output profile from here
* * @pcs: use XYZ or LAB PCS
* * @pcs: #VipsPCS, use XYZ or LAB PCS
* * @intent: #VipsIntent, transform with this intent
* * @black_point_compensation: %gboolean, enable black point compensation
* * @output_profile: %gchararray, get the output profile from here
* * @depth: %gint, depth of output image in bits
*
* Export an image from D65 LAB to device space with an ICC profile.
* If @pcs is
@ -1400,6 +1422,9 @@ vips_icc_import( VipsImage *in, VipsImage **out, ... )
* If @output_profile is set, export with that and attach it to the output
* image.
*
* If @black_point_compensation is set, LCMS black point compensation is
* enabled.
*
* Returns: 0 on success, -1 on error.
*/
int
@ -1424,10 +1449,12 @@ vips_icc_export( VipsImage *in, VipsImage **out, ... )
*
* Optional arguments:
*
* * @input_profile: get the input profile from here
* * @intent: transform with this intent
* * @depth: depth of output image in bits
* * @embedded: use profile embedded in input image
* * @pcs: #VipsPCS, use XYZ or LAB PCS
* * @intent: #VipsIntent, transform with this intent
* * @black_point_compensation: %gboolean, enable black point compensation
* * @embedded: %gboolean, use profile embedded in input image
* * @input_profile: %gchararray, get the input profile from here
* * @depth: %gint, depth of output image in bits
*
* Transform an image with a pair of ICC profiles. The input image is moved to
* profile-connection space with the input profile and then to the output
@ -1445,6 +1472,9 @@ vips_icc_export( VipsImage *in, VipsImage **out, ... )
* @input_profile. If @input_profile is not supplied, the
* metadata profile, if any, is used as a fall-back.
*
* If @black_point_compensation is set, LCMS black point compensation is
* enabled.
*
* The output image has the output profile attached to the #VIPS_META_ICC_NAME
* field.
*