From 78b5ad5883a72cb69278a1578133bc8def5458e4 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Mon, 2 Apr 2012 11:12:40 +0100 Subject: [PATCH] add ARGB coding --- ChangeLog | 2 ++ TODO | 24 +++++++++++++++--------- libvips/colour/colour.c | 13 +++++++++++++ libvips/colour/im_argb2rgba.c | 10 ++-------- libvips/colour/im_rad2float.c | 12 +++--------- libvips/deprecated/vips7compat.c | 1 + libvips/foreign/foreign.c | 27 ++++++++++++++++++++------- libvips/foreign/openslide2vips.c | 2 +- libvips/foreign/openslideload.c | 2 ++ libvips/include/vips/colour.h | 2 ++ libvips/include/vips/error.h | 1 + libvips/include/vips/image.h | 6 ++++-- libvips/iofuncs/enumtypes.c | 1 + libvips/iofuncs/error.c | 29 ++++++++++++++++++++++++++++- libvips/iofuncs/image.c | 3 ++- libvips/iofuncs/vips.c | 1 + 16 files changed, 98 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index 556cd4fb..9b6ddedc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ - nearest-neighbor interpolation rounds coordinates to nearest instead of rounding down (thanks Nicolas) - add dzsave, save in deep zoom format +- add VIPS_CODING_ARGB +- openslideload output tagged as ARGB 13/3/12 started 7.28.2 - xres/yres tiffsave args were broken diff --git a/TODO b/TODO index 79013bd3..06e83442 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,15 @@ +- can we do CMC(2:1) by warping UCS space? + +- add a simple wrapping of im_affinei_all() to the po db, perhaps the name of + the interpolator as a string? + +- dzsave should maybe write some xml as well, see the Python dz writer? + +- the operation cache needs to detect invalidate + + + + blocking bugs ============= @@ -40,18 +52,10 @@ foreign ppm.c radiance.c -- is the tif reader deadlocking sometimes? - - is it when we get a non-seq error? - - should there be some way to set the seq cache size? +- should there be some way to set the seq cache size? - foreign docs come up as "VipsForeignSave", annoying, why? -- make an argb coding type, add to nip2 and known coding - - see openslide - - add nifti support http://niftilib.sourceforge.net/ @@ -84,6 +88,8 @@ packaging - do we bundle "convert" in the OS X / win32 builds? if we don't we should +- goffice on OS X seems to be broken? + convolution =========== diff --git a/libvips/colour/colour.c b/libvips/colour/colour.c index 660ec06c..9234b53a 100644 --- a/libvips/colour/colour.c +++ b/libvips/colour/colour.c @@ -791,6 +791,19 @@ vips_rad2float( VipsImage *in, VipsImage **out, ... ) return( result ); } +int +vips_argb2rgba( VipsImage *in, VipsImage **out, ... ) +{ + va_list ap; + int result; + + va_start( ap, out ); + result = vips_call_split( "im_argb2rgba", ap, in, out ); + va_end( ap ); + + return( result ); +} + int vips_float2rad( VipsImage *in, VipsImage **out, ... ) { diff --git a/libvips/colour/im_argb2rgba.c b/libvips/colour/im_argb2rgba.c index 90c3eac3..0009e2fc 100644 --- a/libvips/colour/im_argb2rgba.c +++ b/libvips/colour/im_argb2rgba.c @@ -88,14 +88,8 @@ im_argb2rgba( VipsImage *in, IMAGE *out ) { guint32 bg; - /* check for RAD coding - if( in->Coding != IM_CODING_RAD ) { - im_error( "im_rad2float", "%s", _( "not a RAD image" ) ); - return( -1 ); - } - */ - - if( im_cp_desc( out, in ) ) + if( vips_check_coding_argb( "argb2rgba", in ) || + im_cp_desc( out, in ) ) return( -1 ); out->Coding = IM_CODING_NONE; diff --git a/libvips/colour/im_rad2float.c b/libvips/colour/im_rad2float.c index c8010a5d..528732e4 100644 --- a/libvips/colour/im_rad2float.c +++ b/libvips/colour/im_rad2float.c @@ -180,18 +180,12 @@ rad2float( COLR *inp, COLOR *outbuf, int n ) int im_rad2float( IMAGE *in, IMAGE *out ) { - /* check for RAD coding - */ - if( in->Coding != IM_CODING_RAD ) { - im_error( "im_rad2float", "%s", _( "not a RAD image" ) ); - return( -1 ); - } - - if( im_cp_desc( out, in ) ) + if( vips_check_coding_rad( "argb2rgba", in ) || + im_cp_desc( out, in ) ) return( -1 ); out->Bands = 3; out->BandFmt = IM_BANDFMT_FLOAT; - out->Coding = IM_CODING_NONE; + out->Coding = VIPS_CODING_NONE; if( im_wrapone( in, out, (im_wrapone_fn) rad2float, NULL, NULL ) ) diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index b2fd04c4..32976458 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -293,6 +293,7 @@ static const char *im_Coding[] = { "RGB_COMPRESSED", "LUM_COMPRESSED", "IM_CODING_RAD", + "VIPS_CODING_ARGB", NULL }; diff --git a/libvips/foreign/foreign.c b/libvips/foreign/foreign.c index ef64b34a..37d308f9 100644 --- a/libvips/foreign/foreign.c +++ b/libvips/foreign/foreign.c @@ -1138,6 +1138,20 @@ vips_foreign_convert_saveable( VipsForeignSave *save ) in = out; } + /* If this is a ARGB, we go to png-style RGBA. + */ + if( in->Coding == VIPS_CODING_ARGB ) { + VipsImage *out; + + if( vips_argb2rgba( in, &out, NULL ) ) { + g_object_unref( in ); + return( -1 ); + } + g_object_unref( in ); + + in = out; + } + /* Get the bands right. */ if( in->Coding == VIPS_CODING_NONE ) { @@ -2054,7 +2068,7 @@ vips_openexrload( const char *filename, VipsImage **out, ... ) * * Optional arguments: * - * @layer: load this layer + * @level: load this level of the pyramid * @associated: load this associated image * * Read a virtual slide supported by the OpenSlide library into a VIPS image. @@ -2062,10 +2076,9 @@ vips_openexrload( const char *filename, VipsImage **out, ... ) * and Trestle formats. * * To facilitate zooming, virtual slide formats include multiple scaled-down - * versions of the high-resolution image. These are typically called - * "levels", though OpenSlide and im_openslide2vips() call them "layers". + * versions of the high-resolution image. * By default, vips_openslideload() reads the highest-resolution layer - * (layer 0). Set @layer to the layer number you want. + * (level 0). Set @level to the level number you want. * * In addition to the slide image itself, virtual slide formats sometimes * include additional images, such as a scan of the slide's barcode. @@ -2074,10 +2087,10 @@ vips_openexrload( const char *filename, VipsImage **out, ... ) * A slide's associated images are listed in the * "slide-associated-images" metadata item. * - * The output of this operator is in pre-multipled ARGB format. Use - * im_argb2rgba() to decode to png-style RGBA. + * The output of this operator is in Cairo-style pre-multipled ARGB format. + * Use vips_argb2rgba() to decode to png-style RGBA. * - * See also: vips_image_new_from_file(). + * See also: vips_argb2rgba(), vips_image_new_from_file(). * * Returns: 0 on success, -1 on error. */ diff --git a/libvips/foreign/openslide2vips.c b/libvips/foreign/openslide2vips.c index 0d257336..23f58725 100644 --- a/libvips/foreign/openslide2vips.c +++ b/libvips/foreign/openslide2vips.c @@ -211,7 +211,7 @@ readslide_new( const char *filename, VipsImage *out, } vips_image_init_fields( out, w, h, 4, VIPS_FORMAT_UCHAR, - VIPS_CODING_NONE, VIPS_INTERPRETATION_RGB, 1.0, 1.0 ); + VIPS_CODING_ARGB, VIPS_INTERPRETATION_RGB, 1.0, 1.0 ); for( properties = openslide_get_property_names( rslide->osr ); *properties != NULL; properties++ ) diff --git a/libvips/foreign/openslideload.c b/libvips/foreign/openslideload.c index 23abd2f1..3c2a3c69 100644 --- a/libvips/foreign/openslideload.c +++ b/libvips/foreign/openslideload.c @@ -4,6 +4,8 @@ * - from openslideload.c * 28/2/12 * - convert "layer" to "level" where externally visible + * 2/4/12 + * - output images coded as ARGB */ /* diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index 6f6ea93d..3a33e1ab 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -51,6 +51,8 @@ int vips_rad2float( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_float2rad( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); +int vips_argb2rgba( VipsImage *in, VipsImage **out, ... ) + __attribute__((sentinel)); int vips_LabS2LabQ( VipsImage *in, VipsImage **out, ... ) __attribute__((sentinel)); int vips_LabQ2Lab( VipsImage *in, VipsImage **out, ... ) diff --git a/libvips/include/vips/error.h b/libvips/include/vips/error.h index 2681efae..086f4e43 100644 --- a/libvips/include/vips/error.h +++ b/libvips/include/vips/error.h @@ -59,6 +59,7 @@ int vips_check_uncoded( const char *domain, VipsImage *im ); int vips_check_coding_known( const char *domain, VipsImage *im ); int vips_check_coding_labq( const char *domain, VipsImage *im ); int vips_check_coding_rad( const char *domain, VipsImage *im ); +int vips_check_coding_argb( const char *domain, VipsImage *im ); int vips_check_coding_noneorlabq( const char *domain, VipsImage *im ); int vips_check_coding_same( const char *domain, VipsImage *im1, VipsImage *im2 ); int vips_check_mono( const char *domain, VipsImage *im ); diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index cd5e1d44..81aa9a3b 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -198,11 +198,12 @@ typedef enum { * @VIPS_CODING_NONE: pixels are not coded * @VIPS_CODING_LABQ: pixels encode 3 float CIELAB values as 4 uchar * @VIPS_CODING_RAD: pixels encode 3 float RGB as 4 uchar (Radiance coding) + * @VIPS_CODING_ARGB: Cairo-style pre-multiplied ARGB * * How pixels are coded. * * Normally, pixels are uncoded and can be manipulated as you would expect. - * However some file formats code pixels for compression, and sometimes it's + * However some file formats code pixels for storage, and sometimes it's * useful to be able to manipulate images in the coded format. * * The gaps in the numbering are historical and must be maintained. Allocate @@ -213,7 +214,8 @@ typedef enum { VIPS_CODING_NONE = 0, VIPS_CODING_LABQ = 2, VIPS_CODING_RAD = 6, - VIPS_CODING_LAST = 7 + VIPS_CODING_ARGB = 7, + VIPS_CODING_LAST = 8 } VipsCoding; /* Struct we keep a record of execution time in. Passed to eval signal so diff --git a/libvips/iofuncs/enumtypes.c b/libvips/iofuncs/enumtypes.c index c8eb8554..66fb9b88 100644 --- a/libvips/iofuncs/enumtypes.c +++ b/libvips/iofuncs/enumtypes.c @@ -483,6 +483,7 @@ vips_coding_get_type( void ) {VIPS_CODING_NONE, "VIPS_CODING_NONE", "none"}, {VIPS_CODING_LABQ, "VIPS_CODING_LABQ", "labq"}, {VIPS_CODING_RAD, "VIPS_CODING_RAD", "rad"}, + {VIPS_CODING_ARGB, "VIPS_CODING_ARGB", "argb"}, {VIPS_CODING_LAST, "VIPS_CODING_LAST", "last"}, {0, NULL, NULL} }; diff --git a/libvips/iofuncs/error.c b/libvips/iofuncs/error.c index bfe88c91..61fb7013 100644 --- a/libvips/iofuncs/error.c +++ b/libvips/iofuncs/error.c @@ -490,7 +490,8 @@ vips_check_coding_known( const char *domain, VipsImage *im ) */ if( im->Coding != VIPS_CODING_NONE && im->Coding != VIPS_CODING_LABQ && - im->Coding != VIPS_CODING_RAD ) { + im->Coding != VIPS_CODING_RAD && + im->Coding != VIPS_CODING_ARGB ) { vips_error( domain, "%s", _( "unknown image coding" ) ); return( -1 ); } @@ -524,6 +525,32 @@ vips_check_coding_rad( const char *domain, VipsImage *im ) return( 0 ); } +/** + * vips_check_coding_argb: + * @domain: the originating domain for the error message + * @im: image to check + * + * Check that the image is in ARGB coding. + * If not, set an error message + * and return non-zero. + * + * See also: vips_error(). + * + * Returns: 0 on OK, or -1 on error. + */ +int +vips_check_coding_argb( const char *domain, VipsImage *im ) +{ + if( im->Coding != VIPS_CODING_ARGB || + im->BandFmt != VIPS_FORMAT_UCHAR || + im->Bands != 4 ) { + vips_error( domain, "%s", _( "ARGB coding only" ) ); + return( -1 ); + } + + return( 0 ); +} + /** * vips_check_coding_labq: * @domain: the originating domain for the error message diff --git a/libvips/iofuncs/image.c b/libvips/iofuncs/image.c index 0f40aa79..52332a37 100644 --- a/libvips/iofuncs/image.c +++ b/libvips/iofuncs/image.c @@ -456,7 +456,8 @@ vips_image_sanity( VipsObject *object, VipsBuf *buf ) (image->Coding != -1 && image->Coding != VIPS_CODING_NONE && image->Coding != VIPS_CODING_LABQ && - image->Coding != VIPS_CODING_RAD) || + image->Coding != VIPS_CODING_RAD && + image->Coding != VIPS_CODING_ARGB) || image->Type > VIPS_INTERPRETATION_ARRAY || image->dtype > VIPS_IMAGE_PARTIAL || image->dhint > VIPS_DEMAND_STYLE_ANY ) diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 8c65478b..22596e10 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -188,6 +188,7 @@ image_pixel_length( VipsImage *image ) switch( image->Coding ) { case VIPS_CODING_LABQ: case VIPS_CODING_RAD: + case VIPS_CODING_ARGB: case VIPS_CODING_NONE: psize = VIPS_IMAGE_SIZEOF_IMAGE( image ); break;