new icc transformer compiles

This commit is contained in:
John Cupitt 2012-09-25 22:06:24 +01:00
parent ecb8faa7cd
commit e793d38aa7
16 changed files with 1261 additions and 1763 deletions

View File

@ -2,7 +2,8 @@
- redone im_Lab2XYZ(), im_XYZ2Lab(), im_Lab2LCh(), im_LCh2Lab(), im_UCS2LCh,
im_LCh2UCS(), im_XYZ2Yxy(), im_Yxy2XYZ(), im_float2rad(), im_rad2float(),
im_Lab2LabQ(), im_LabQ2Lab(), im_Lab2LabS(), im_LabS2Lab(), im_LabQ2LabS(),
im_LabS2LabQ(), im_LabQ2disp(), im_XYZ2disp(), im_disp2XYZ() as classes
im_LabS2LabQ(), im_LabQ2disp(), im_XYZ2disp(), im_disp2XYZ(),
im_icc_import*(), im_icc_export*(), im_icc_transform*() as classes
13/9/12 started 7.30.3
- linecache sized itself too large

3
TODO
View File

@ -1,3 +1,6 @@
- im_icc_ac2rc needs doing once we have a general 'convert' operator
- boolean.c has
vips_check_noncomplex( "VipsBoolean", binary->left ) )

View File

@ -195,9 +195,8 @@ vips_Lab2XYZ_init( VipsLab2XYZ *Lab2XYZ )
*
* @temp: colour temperature
*
* Turn Lab to XYZ.
*
* The colour temperature defaults to D65, but can be specified with @temp.
* Turn Lab to XYZ. The colour temperature defaults to D65, but can be
* specified with @temp.
*
* Returns: 0 on success, -1 on error
*/

View File

@ -24,7 +24,7 @@ libcolour_la_SOURCES = \
LabQ2sRGB.c \
XYZ2sRGB.c \
sRGB2XYZ.c \
im_icc_transform.c \
icc_transform.c \
im_lab_morph.c \
im_dE00_fromLab.c \
im_dECMC_fromLab.c \

View File

@ -249,7 +249,12 @@ vips_XYZ2Lab_init( VipsXYZ2Lab *XYZ2Lab )
* @in: input image
* @out: output image
*
* Turn XYZ to D65 Lab.
* optional arguments:
*
* @temp: colour temperature
*
* Turn XYZ to Lab, optionally specifying the colour temperature. @temp
* defaults to D65.
*
* Returns: 0 on success, -1 on error.
*/

View File

@ -83,11 +83,26 @@ vips_colour_gen( VipsRegion *or,
return( 0 );
}
static int
vips_colour_attach_profile( VipsImage *im, const char *filename )
{
char *data;
unsigned int data_length;
if( !(data = vips__file_read_name( filename, VIPS_ICC_DIR,
&data_length )) )
return( -1 );
vips_image_set_blob( im, VIPS_META_ICC_NAME,
(VipsCallbackFn) g_free, data, data_length );
return( 0 );
}
static int
vips_colour_build( VipsObject *object )
{
VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
VipsColour *colour = VIPS_COLOUR( object );
VipsColourClass *class = VIPS_COLOUR_GET_CLASS( colour );
int i;
@ -104,7 +119,7 @@ vips_colour_build( VipsObject *object )
g_object_set( colour, "out", vips_image_new(), NULL );
if( colour->n > MAX_INPUT_IMAGES ) {
vips_error( "VipsColour",
vips_error( class->nickname,
"%s", _( "too many input images" ) );
return( -1 );
}
@ -116,10 +131,15 @@ vips_colour_build( VipsObject *object )
return( -1 );
vips_demand_hint_array( colour->out,
VIPS_DEMAND_STYLE_THINSTRIP, colour->in );
colour->out->Coding = class->coding;
colour->out->Type = class->interpretation;
colour->out->BandFmt = class->format;
colour->out->Bands = class->bands;
colour->out->Coding = colour->coding;
colour->out->Type = colour->interpretation;
colour->out->BandFmt = colour->format;
colour->out->Bands = colour->bands;
if( colour->profile_filename )
if( vips_colour_attach_profile( colour->out,
colour->profile_filename ) )
return( -1 );
if( vips_image_generate( colour->out,
vips_start_many, vips_colour_gen, vips_stop_many,
@ -160,6 +180,12 @@ vips_colour_class_init( VipsColourClass *class )
static void
vips_colour_init( VipsColour *colour )
{
VipsColourClass *class = VIPS_COLOUR_GET_CLASS( colour );
colour->coding = class->coding;
colour->interpretation = class->interpretation;
colour->format = class->format;
colour->bands = class->bands;
}
G_DEFINE_ABSTRACT_TYPE( VipsColourSpace, vips_colour_space, VIPS_TYPE_COLOUR );
@ -266,7 +292,6 @@ vips_colour_code_build( VipsObject *object )
VipsColour *colour = VIPS_COLOUR( object );
VipsColourCode *code = VIPS_COLOUR_CODE( object );
VipsColourCodeClass *class = VIPS_COLOUR_CODE_GET_CLASS( object );
VipsColourClass *colour_class = VIPS_COLOUR_CLASS( class );
VipsImage **t;
VipsImage *in;
@ -279,22 +304,22 @@ vips_colour_code_build( VipsObject *object )
if( in &&
vips_check_coding( VIPS_OBJECT_CLASS( class )->nickname,
in, class->input_coding ) )
in, code->input_coding ) )
return( -1 );
/* Extra band processing. don't do automatic detach/reattach if either
* input or output will be coded.
*/
if( in &&
class->input_coding == VIPS_CODING_NONE &&
colour_class->coding == VIPS_CODING_NONE &&
class->input_bands > 0 ) {
if( in->Bands > class->input_bands ) {
code->input_coding == VIPS_CODING_NONE &&
colour->coding == VIPS_CODING_NONE &&
code->input_bands > 0 ) {
if( in->Bands > code->input_bands ) {
if( vips_extract_band( in, &t[1], 0,
"n", class->input_bands, NULL ) )
"n", code->input_bands, NULL ) )
return( -1 );
if( vips_extract_band( in, &t[2], class->input_bands,
"n", in->Bands - class->input_bands,
if( vips_extract_band( in, &t[2], code->input_bands,
"n", in->Bands - code->input_bands,
NULL ) )
return( -1 );
in = t[1];
@ -302,14 +327,14 @@ vips_colour_code_build( VipsObject *object )
}
else if( vips_check_bands_atleast(
VIPS_OBJECT_CLASS( class )->nickname,
in, class->input_bands ) )
in, code->input_bands ) )
return( -1 );
}
if( in &&
class->input_coding == VIPS_CODING_NONE &&
class->input_format != VIPS_FORMAT_NOTSET ) {
if( vips_cast( in, &t[3], class->input_format, NULL ) )
code->input_coding == VIPS_CODING_NONE &&
code->input_format != VIPS_FORMAT_NOTSET ) {
if( vips_cast( in, &t[3], code->input_format, NULL ) )
return( -1 );
in = t[3];
}
@ -365,6 +390,11 @@ vips_colour_code_class_init( VipsColourCodeClass *class )
static void
vips_colour_code_init( VipsColourCode *code )
{
VipsColourCodeClass *class = VIPS_COLOUR_CODE_GET_CLASS( code );
code->input_coding = class->input_coding;
code->input_format = class->input_format;
code->input_bands = class->input_bands;
}
/* Called from iofuncs to init all operations in this dir. Use a plugin system
@ -392,6 +422,11 @@ vips_colour_operation_init( void )
extern GType vips_LabQ2sRGB_get_type( void );
extern GType vips_XYZ2sRGB_get_type( void );
extern GType vips_sRGB2XYZ_get_type( void );
#if defined(HAVE_LCMS) || defined(HAVE_LCMS2)
extern GType vips_icc_import_get_type( void );
extern GType vips_icc_export_get_type( void );
extern GType vips_icc_transform_get_type( void );
#endif
vips_Lab2XYZ_get_type();
vips_XYZ2Lab_get_type();
@ -412,4 +447,9 @@ vips_colour_operation_init( void )
vips_LabQ2sRGB_get_type();
vips_XYZ2sRGB_get_type();
vips_sRGB2XYZ_get_type();
#if defined(HAVE_LCMS) || defined(HAVE_LCMS2)
vips_icc_import_get_type();
vips_icc_export_get_type();
vips_icc_transform_get_type();
#endif
}

View File

@ -69,6 +69,17 @@ typedef struct _VipsColour {
int n;
VipsImage *out;
/* Set fields on ->out from these.
*/
VipsCoding coding;
VipsInterpretation interpretation;
VipsBandFormat format;
int bands;
/* Attach this profile, if set.
*/
char *profile_filename;
} VipsColour;
typedef struct _VipsColourClass {
@ -78,12 +89,13 @@ typedef struct _VipsColourClass {
*/
VipsColourProcessFn process_line;
/* Set fields on ->out from these.
/* Init fields on instance from these.
*/
VipsCoding coding;
VipsInterpretation interpretation;
VipsBandFormat format;
int bands;
} VipsColourClass;
GType vips_colour_get_type( void );
@ -143,6 +155,12 @@ typedef struct _VipsColourCode {
VipsImage *in;
/* Test in against these, init them from class.
*/
VipsCoding input_coding;
VipsBandFormat input_format;
int input_bands;
} VipsColourCode;
typedef struct _VipsColourCodeClass {
@ -171,4 +189,3 @@ GType vips_colour_code_get_type( void );
#endif /*VIPS__COLOUR_H*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2556,3 +2556,84 @@ im_LabQ2sRGB( IMAGE *in, IMAGE *out )
return( 0 );
}
int
im_icc_transform( VipsImage *in, VipsImage *out,
const char *input_profile_filename,
const char *output_profile_filename,
VipsIntent intent )
{
VipsImage *x;
if( vips_icc_transform( in, &x, output_profile_filename,
"input_profile", input_profile_filename,
"intent", intent,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int
im_icc_import( VipsImage *in, VipsImage *out,
const char *input_profile_filename, VipsIntent intent )
{
VipsImage *x;
if( vips_icc_import( in, &x,
"input_profile", input_profile_filename,
"intent", intent,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int
im_icc_import_embedded( VipsImage *in, VipsImage *out, VipsIntent intent )
{
VipsImage *x;
if( vips_icc_import( in, &x,
"embedded", TRUE,
"intent", intent,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}
int
im_icc_export_depth( VipsImage *in, VipsImage *out, int depth,
const char *output_profile_filename, VipsIntent intent )
{
VipsImage *x;
if( vips_icc_export( in, &x, output_profile_filename,
"depth", depth,
"intent", intent,
NULL ) )
return( -1 );
if( im_copy( x, out ) ) {
g_object_unref( x );
return( -1 );
}
g_object_unref( x );
return( 0 );
}

View File

@ -62,6 +62,7 @@ vips_scan_headers = \
${top_srcdir}/libvips/include/vips/conversion.h \
${top_srcdir}/libvips/include/vips/util.h \
${top_srcdir}/libvips/include/vips/image.h \
${top_srcdir}/libvips/include/vips/colour.h \
${top_srcdir}/libvips/include/vips/operation.h \
${top_srcdir}/libvips/include/vips/object.h

View File

@ -92,6 +92,24 @@ extern "C" {
#define VIPS_D3250_Y0 (100.0)
#define VIPS_D3250_Z0 (45.8501)
/**
* VipsIntent:
* @VIPS_INTENT_PERCEPTUAL: perceptual rendering intent
* @VIPS_INTENT_RELATIVE: relative colorimetric rendering intent
* @VIPS_INTENT_SATURATION: saturation rendering intent
* @VIPS_INTENT_ABSOLUTE: absolute colorimetric rendering intent
*
* The rendering intent. #VIPS_INTENT_ABSOLUTE is best for
* scientific work, #VIPS_INTENT_RELATIVE is usually best for
* accurate communication with other imaging libraries.
*/
typedef enum {
VIPS_INTENT_PERCEPTUAL = 0,
VIPS_INTENT_RELATIVE,
VIPS_INTENT_SATURATION,
VIPS_INTENT_ABSOLUTE
} VipsIntent;
int vips_LabQ2sRGB( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
int vips_rad2float( VipsImage *in, VipsImage **out, ... )
@ -135,6 +153,18 @@ int vips_LabS2Lab( VipsImage *in, VipsImage **out, ... )
int vips_Lab2LabS( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
int vips_icc_present( void );
int vips_icc_transform( VipsImage *in, VipsImage **out,
const char *output_profile_filename, ... )
__attribute__((sentinel));
int vips_icc_import( VipsImage *in, VipsImage **out, ... )
__attribute__((sentinel));
int vips_icc_export( VipsImage *in, VipsImage **out,
const char *output_profile, ... )
__attribute__((sentinel));
int vips_icc_ac2rc( VipsImage *in, VipsImage *out,
const char *profile_filename );
void vips_col_Lab2XYZ( float L, float a, float b,
float *X, float *Y, float *Z );
void vips_col_XYZ2Lab( float X, float Y, float Z,
@ -187,27 +217,6 @@ int im_lab_morph( VipsImage *in, VipsImage *out,
double L_offset, double L_scale,
double a_scale, double b_scale );
/* Render intents for icc wrappers.
*/
typedef enum {
IM_INTENT_PERCEPTUAL = 0,
IM_INTENT_RELATIVE_COLORIMETRIC,
IM_INTENT_SATURATION,
IM_INTENT_ABSOLUTE_COLORIMETRIC
} VipsIntent;
int im_icc_present( void );
int im_icc_transform( VipsImage *in, VipsImage *out,
const char *input_profile_filename,
const char *output_profile_filename,
VipsIntent intent );
int im_icc_import( VipsImage *in, VipsImage *out,
const char *input_profile_filename, VipsIntent intent );
int im_icc_import_embedded( VipsImage *in, VipsImage *out, VipsIntent intent );
int im_icc_export_depth( VipsImage *in, VipsImage *out, int depth,
const char *output_profile_filename, VipsIntent intent );
int im_icc_ac2rc( VipsImage *in, VipsImage *out, const char *profile_filename );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -57,6 +57,9 @@ GType vips_band_format_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_BAND_FORMAT (vips_band_format_get_type())
GType vips_coding_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_CODING (vips_coding_get_type())
/* enumerations from "../../../libvips/include/vips/colour.h" */
GType vips_intent_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_INTENT (vips_intent_get_type())
/* enumerations from "../../../libvips/include/vips/operation.h" */
GType vips_operation_flags_get_type (void) G_GNUC_CONST;
#define VIPS_TYPE_OPERATION_FLAGS (vips_operation_flags_get_type())

View File

@ -141,6 +141,11 @@ extern "C" {
#define IMAGE VipsImage
#define REGION VipsRegion
#define IM_INTENT_PERCEPTUAL VIPS_INTENT_PERCEPTUAL
#define IM_INTENT_RELATIVE_COLORIMETRIC VIPS_INTENT_RELATIVE_COLORIMETRIC
#define IM_INTENT_SATURATION VIPS_INTENT_SATURATION
#define IM_INTENT_ABSOLUTE_COLORIMETRIC VIPS_INTENT_ABSOLUTE_COLORIMETRIC
/* Renamed macros.
*/
@ -750,6 +755,20 @@ int im_dECMC_fromdisp( IMAGE *, IMAGE *, IMAGE *, struct im_col_display * );
#define im_XYZ2disp(A, B, C) (im_XYZ2sRGB(A, B))
#define im_LabQ2disp(A, B, C) (im_LabQ2sRGB(A, B))
int im_icc_transform( VipsImage *in, VipsImage *out,
const char *input_profile_filename,
const char *output_profile_filename,
VipsIntent intent );
#define im_icc_present vips_icc_present
int im_icc_import( VipsImage *in, VipsImage *out,
const char *input_profile_filename, VipsIntent intent );
int im_icc_import_embedded( VipsImage *in, VipsImage *out, VipsIntent intent );
int im_icc_export_depth( VipsImage *in, VipsImage *out, int depth,
const char *output_profile_filename, VipsIntent intent );
int im_icc_ac2rc( VipsImage *in, VipsImage *out, const char *profile_filename );
/* ruby-vips uses this
*/
#define vips_class_map_concrete_all vips_class_map_all

View File

@ -47,6 +47,7 @@ vips_scan_headers = \
${top_srcdir}/libvips/include/vips/util.h \
${top_srcdir}/libvips/include/vips/image.h \
${top_srcdir}/libvips/include/vips/operation.h \
${top_srcdir}/libvips/include/vips/colour.h \
${top_srcdir}/libvips/include/vips/object.h
enumtypes.c: $(vips_scan_headers) Makefile

View File

@ -511,6 +511,26 @@ vips_operation_flags_get_type( void )
return( etype );
}
/* enumerations from "../../libvips/include/vips/colour.h" */
GType
vips_intent_get_type( void )
{
static GType etype = 0;
if( etype == 0 ) {
static const GEnumValue values[] = {
{VIPS_INTENT_PERCEPTUAL, "VIPS_INTENT_PERCEPTUAL", "perceptual"},
{VIPS_INTENT_RELATIVE, "VIPS_INTENT_RELATIVE", "relative"},
{VIPS_INTENT_SATURATION, "VIPS_INTENT_SATURATION", "saturation"},
{VIPS_INTENT_ABSOLUTE, "VIPS_INTENT_ABSOLUTE", "absolute"},
{0, NULL, NULL}
};
etype = g_enum_register_static( "VipsIntent", values );
}
return( etype );
}
/* enumerations from "../../libvips/include/vips/object.h" */
GType
vips_argument_flags_get_type( void )