fix up XYZ PCS and vipsthumbnail

fix import and export scaling, get vipsthumbnail to use it in --linear
mode
This commit is contained in:
John Cupitt 2013-11-12 17:18:41 +00:00
parent 0257dda270
commit 53e86e71f4
4 changed files with 24 additions and 18 deletions

View File

@ -19,6 +19,7 @@
- rename vips_gammacorrect() as vips_gamma(), now takes 1 / exp - rename vips_gammacorrect() as vips_gamma(), now takes 1 / exp
- vips_gamma() works for any format - vips_gamma() works for any format
- add --linear mode to vipsthumbnail - add --linear mode to vipsthumbnail
- support XYZ as a PCS for vips_icc_import() and vips_icc_export()
18/10/13 started 7.36.3 18/10/13 started 7.36.3
- fix compiler warnings in ubuntu 13.10 - fix compiler warnings in ubuntu 13.10

8
TODO
View File

@ -2,14 +2,6 @@
- vipsthumbnail can use vips_conv() now and get rid of the INTMASK - vipsthumbnail can use vips_conv() now and get rid of the INTMASK
- vips_icc_import() could offer XYZ as well as LAB? it'd save two conversions
in vipsthumbnail
vips_icc_export() would need to be able to accept both types as well
at the moment, icc_export() assumes LAB, it needs a vips_colourspace() on
the input to do an automatic transform for you see vips_dE00() etc.
- jpegsave needs a --strip option - jpegsave needs a --strip option
- jpegsave needs chroma subsampling controls, see: - jpegsave needs chroma subsampling controls, see:

View File

@ -24,6 +24,8 @@
* - redo as a class * - redo as a class
* 14/5/13 * 14/5/13
* - import and export would segv on very wide images * - import and export would segv on very wide images
* 12/11/13
* - support XYZ as an alternative PCS
*/ */
/* /*
@ -512,15 +514,19 @@ decode_lab( guint16 *fixed, float *lab, int n )
} }
} }
#define X_FAC (VIPS_D50_X0 * 32768 / (VIPS_D65_X0 * 100))
#define Y_FAC (VIPS_D50_Y0 * 32768 / (VIPS_D65_Y0 * 100))
#define Z_FAC (VIPS_D50_Z0 * 32768 / (VIPS_D65_Z0 * 100))
static void static void
decode_xyz( guint16 *fixed, float *xyz, int n ) decode_xyz( guint16 *fixed, float *xyz, int n )
{ {
int i; int i;
for( i = 0; i < n; i++ ) { for( i = 0; i < n; i++ ) {
xyz[0] = (double) fixed[0] / 652.800; xyz[0] = (double) fixed[0] / X_FAC;
xyz[1] = (double) fixed[1] / 652.800; xyz[1] = (double) fixed[1] / Y_FAC;
xyz[2] = (double) fixed[2] / 652.800; xyz[2] = (double) fixed[2] / Z_FAC;
xyz += 3; xyz += 3;
fixed += 3; fixed += 3;
@ -623,6 +629,14 @@ vips_icc_export_build( VipsObject *object )
VipsIcc *icc = (VipsIcc *) object; VipsIcc *icc = (VipsIcc *) object;
VipsIccExport *export = (VipsIccExport *) object; VipsIccExport *export = (VipsIccExport *) object;
/* If icc->pcs hasn't been set and this image is tagged as XYZ, swap
* to XYZ pcs. This will save a XYZ->LAB conversion when we chain up.
*/
if( !vips_object_argument_isset( object, "pcs" ) &&
code->in &&
code->in->Type == VIPS_INTERPRETATION_XYZ )
icc->pcs = VIPS_INTERPRETATION_XYZ;
if( icc->pcs == VIPS_PCS_LAB ) { if( icc->pcs == VIPS_PCS_LAB ) {
#ifdef HAVE_LCMS2 #ifdef HAVE_LCMS2
cmsCIExyY white; cmsCIExyY white;
@ -741,9 +755,9 @@ encode_xyz( float *xyz, guint16 *fixed, int n )
if( Z > MAX_ENCODEABLE_XYZ ) if( Z > MAX_ENCODEABLE_XYZ )
Z = MAX_ENCODEABLE_XYZ; Z = MAX_ENCODEABLE_XYZ;
fixed[0] = X * 652.800 + 0.5; fixed[0] = X * X_FAC + 0.5;
fixed[1] = Y * 652.800 + 0.5; fixed[1] = Y * Y_FAC + 0.5;
fixed[2] = Z * 652.800 + 0.5; fixed[2] = Z * Z_FAC + 0.5;
xyz += 3; xyz += 3;
fixed += 3; fixed += 3;

View File

@ -349,6 +349,7 @@ thumbnail_shrink( VipsObject *thumbnail, VipsImage *in,
if( vips_icc_import( in, &t[1], if( vips_icc_import( in, &t[1],
"input_profile", import_profile, "input_profile", import_profile,
"embedded", TRUE, "embedded", TRUE,
"pcs", VIPS_PCS_XYZ,
NULL ) ) NULL ) )
return( NULL ); return( NULL );
@ -419,10 +420,8 @@ thumbnail_shrink( VipsObject *thumbnail, VipsImage *in,
vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) { vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
vips_info( "vipsthumbnail", vips_info( "vipsthumbnail",
"exporting to device space with a profile" ); "exporting to device space with a profile" );
if( vips_colourspace( in, &t[6], if( vips_icc_export( in, &t[7],
VIPS_INTERPRETATION_LAB, NULL ) || "output_profile", export_profile,
vips_icc_export( t[6], &t[7],
"output_profile", export_profile,
NULL ) ) NULL ) )
return( NULL ); return( NULL );
in = t[7]; in = t[7];