hackery to move to vips_copy()

half-way through moving over to the new vips_copy()
This commit is contained in:
John Cupitt 2011-10-11 17:47:06 +01:00
parent b0249a85d8
commit 66126c1076
9 changed files with 348 additions and 225 deletions

View File

@ -20,6 +20,7 @@
- added --vips-leak flag
- added VipsCopy
- more VipsImage props
- added vips_image_write(), old one becomes vips_image_write_filename()
10/8/11 started 7.26.3
- don't use G_VALUE_COLLECT_INIT(), many platforms do not have a glib this

19
TODO
View File

@ -1,3 +1,22 @@
- vips_image_write() uses im_copy() to send an image to a file
but im_copy() now calls vips_copy(), which can't actually write to a
specific descriptor!
vips_image_write() needs to do some behind-the-scenes magic, I'm not quite
sure what
just vips_image_generate() with a pointer copy I think, basically
vipscopy without creating the output
rename as vips_image_write_to_filename(), vips_image_write() should write to
a VipsImage
im_add() etc. compat functions need to start calling vips_image_write()
instead of im_copy()
- vipscopy
how would we do meta sets?

View File

@ -383,214 +383,3 @@ im_copy_native( IMAGE *in, IMAGE *out, gboolean is_msb_first )
else
return( im_copy( in, out ) );
}
/* Convert to a saveable format.
*
* im__saveable_t gives the general type of image
* we make: vanilla 1/3 bands (eg. PPM), with an optional alpha (eg. PNG), or
* with CMYK as an option (eg. JPEG).
*
* format_table[] says how to convert each input format.
*
* Need to im_close() the result IMAGE.
*/
IMAGE *
im__convert_saveable( IMAGE *in,
im__saveable_t saveable, int format_table[10] )
{
IMAGE *out;
if( !(out = im_open( "convert-for-save", "p" )) )
return( NULL );
/* If this is an IM_CODING_LABQ, we can go straight to RGB.
*/
if( in->Coding == IM_CODING_LABQ ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
static void *table = NULL;
/* Make sure fast LabQ2disp tables are built. 7 is sRGB.
*/
if( !table )
table = im_LabQ2disp_build_table( NULL,
im_col_displays( 7 ) );
if( !t || im_LabQ2disp_table( in, t, table ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* If this is an IM_CODING_RAD, we go to float RGB or XYZ. We should
* probably un-gamma-correct the RGB :(
*/
if( in->Coding == IM_CODING_RAD ) {
IMAGE *t;
if( !(t = im_open_local( out, "conv:1", "p" )) ||
im_rad2float( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* Get the bands right.
*/
if( in->Coding == IM_CODING_NONE ) {
if( in->Bands == 2 && saveable != IM__RGBA ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_extract_band( in, t, 0 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
else if( in->Bands > 3 && saveable == IM__RGB ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t ||
im_extract_bands( in, t, 0, 3 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
else if( in->Bands > 4 &&
(saveable == IM__RGB_CMYK || saveable == IM__RGBA) ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t ||
im_extract_bands( in, t, 0, 4 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* Else we have saveable IM__ANY and we don't chop bands down.
*/
}
/* Interpret the Type field for colorimetric images.
*/
if( in->Bands == 3 && in->BandFmt == IM_BANDFMT_SHORT &&
in->Type == IM_TYPE_LABS ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_LabS2LabQ( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( in->Coding == IM_CODING_LABQ ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_LabQ2Lab( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( in->Coding != IM_CODING_NONE ) {
im_close( out );
return( NULL );
}
if( in->Bands == 3 && in->Type == IM_TYPE_LCH ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_LCh2Lab( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_YXY ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_Yxy2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_UCS ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_UCS2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_LAB ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_Lab2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_XYZ ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_XYZ2disp( t[0], t[1], im_col_displays( 7 ) ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
/* Cast to the output format.
*/
{
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_clip2fmt( in, t, format_table[in->BandFmt] ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( im_copy( in, out ) ) {
im_close( out );
return( NULL );
}
return( out );
}

View File

@ -986,3 +986,59 @@ im_demand_hint (IMAGE * im, VipsDemandStyle hint, ...)
return (im_demand_hint_array (im, hint, ar));
}
int
im_copy_set( IMAGE *in, IMAGE *out,
VipsType type, float xres, float yres, int xoffset, int yoffset )
{
return( vips_copy( in, out,
"interpretation", type,
"xres", xres,
"yres", yres,
"xoffset", xoffset,
"yoffset", yoffset,
NULL ) );
}
int
im_copy_morph( IMAGE *in, IMAGE *out,
int bands, VipsBandFmt bandfmt, VipsCoding coding )
{
return( vips_copy( in, out,
"bands", bands,
"format", bandfmt,
"coding", coding,
NULL ) );
}
int
im_copy( IMAGE *in, IMAGE *out )
{
return( im_copy_set( in, out,
in->Type, in->Xres, in->Yres, 0, 0 ) );
}
int
im_copy_swap( IMAGE *in, IMAGE *out )
{
return( vips_copy( in, out, "swap", TRUE, NULL ) );
}
int
im_copy_set_meta( IMAGE *in, IMAGE *out, const char *field, GValue *value )
{
if( im_copy( in, out ) )
return( 1 );
im_meta_set( out, field, value );
return( 0 );
}
int
im_copy_native( IMAGE *in, IMAGE *out, gboolean is_msb_first )
{
if( is_msb_first != im_amiMSBfirst() )
return( im_copy_swap( in, out ) );
else
return( im_copy( in, out ) );
}

View File

@ -144,6 +144,217 @@ im_vips2mimejpeg( IMAGE *in, int qfac )
#include <jpeglib.h>
#include <jerror.h>
/* Convert to a saveable format.
*
* im__saveable_t gives the general type of image
* we make: vanilla 1/3 bands (eg. PPM), with an optional alpha (eg. PNG), or
* with CMYK as an option (eg. JPEG).
*
* format_table[] says how to convert each input format.
*
* Need to im_close() the result IMAGE.
*/
IMAGE *
im__convert_saveable( IMAGE *in,
im__saveable_t saveable, int format_table[10] )
{
IMAGE *out;
if( !(out = im_open( "convert-for-save", "p" )) )
return( NULL );
/* If this is an IM_CODING_LABQ, we can go straight to RGB.
*/
if( in->Coding == IM_CODING_LABQ ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
static void *table = NULL;
/* Make sure fast LabQ2disp tables are built. 7 is sRGB.
*/
if( !table )
table = im_LabQ2disp_build_table( NULL,
im_col_displays( 7 ) );
if( !t || im_LabQ2disp_table( in, t, table ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* If this is an IM_CODING_RAD, we go to float RGB or XYZ. We should
* probably un-gamma-correct the RGB :(
*/
if( in->Coding == IM_CODING_RAD ) {
IMAGE *t;
if( !(t = im_open_local( out, "conv:1", "p" )) ||
im_rad2float( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* Get the bands right.
*/
if( in->Coding == IM_CODING_NONE ) {
if( in->Bands == 2 && saveable != IM__RGBA ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_extract_band( in, t, 0 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
else if( in->Bands > 3 && saveable == IM__RGB ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t ||
im_extract_bands( in, t, 0, 3 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
else if( in->Bands > 4 &&
(saveable == IM__RGB_CMYK || saveable == IM__RGBA) ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t ||
im_extract_bands( in, t, 0, 4 ) ) {
im_close( out );
return( NULL );
}
in = t;
}
/* Else we have saveable IM__ANY and we don't chop bands down.
*/
}
/* Interpret the Type field for colorimetric images.
*/
if( in->Bands == 3 && in->BandFmt == IM_BANDFMT_SHORT &&
in->Type == IM_TYPE_LABS ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_LabS2LabQ( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( in->Coding == IM_CODING_LABQ ) {
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_LabQ2Lab( in, t ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( in->Coding != IM_CODING_NONE ) {
im_close( out );
return( NULL );
}
if( in->Bands == 3 && in->Type == IM_TYPE_LCH ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_LCh2Lab( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_YXY ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_Yxy2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_UCS ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_UCS2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_LAB ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_Lab2XYZ( t[0], t[1] ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
if( in->Bands == 3 && in->Type == IM_TYPE_XYZ ) {
IMAGE *t[2];
if( im_open_local_array( out, t, 2, "conv-1", "p" ) ||
im_clip2fmt( in, t[0], IM_BANDFMT_FLOAT ) ||
im_XYZ2disp( t[0], t[1], im_col_displays( 7 ) ) ) {
im_close( out );
return( NULL );
}
in = t[1];
}
/* Cast to the output format.
*/
{
IMAGE *t = im_open_local( out, "conv:1", "p" );
if( !t || im_clip2fmt( in, t, format_table[in->BandFmt] ) ) {
im_close( out );
return( NULL );
}
in = t;
}
if( im_copy( in, out ) ) {
im_close( out );
return( NULL );
}
return( out );
}
/* Define a new error handler for when we bomb out.
*/
typedef struct {

View File

@ -45,16 +45,6 @@ int vips_copy( VipsImage *in, VipsImage **out, ... );
DOUBLEMASK *im_vips2mask( VipsImage *in, const char *filename );
int im_mask2vips( DOUBLEMASK *in, VipsImage *out );
int im_copy( VipsImage *in, VipsImage *out );
int im_copy_set( VipsImage *in, VipsImage *out,
VipsInterpretation interpretation,
float xres, float yres, int xoffset, int yoffset );
int im_copy_set_meta( VipsImage *in, VipsImage *out,
const char *field, GValue *value );
int im_copy_morph( VipsImage *in, VipsImage *out,
int bands, VipsBandFormat format, VipsCoding coding );
int im_copy_swap( VipsImage *in, VipsImage *out );
int im_copy_native( VipsImage *in, VipsImage *out, gboolean is_msb_first );
int im_copy_file( VipsImage *in, VipsImage *out );
int im_clip2fmt( VipsImage *in, VipsImage *out, VipsBandFormat fmt );

View File

@ -473,7 +473,8 @@ VipsImage *vips_image_new_from_memory( void *buffer,
void vips_image_set_delete_on_close( VipsImage *image,
gboolean delete_on_close );
VipsImage *vips_image_new_disc_temp( const char *format );
int vips_image_write( VipsImage *image, const char *filename );
int vips_image_write( VipsImage *image, VipsImage *out );
int vips_image_write_filename( VipsImage *image, const char *filename );
gboolean vips_image_isMSBfirst( VipsImage *image );
gboolean vips_image_isfile( VipsImage *image );

View File

@ -526,6 +526,17 @@ int im_min( VipsImage *in, double *out );
int im_minpos( VipsImage *in, int *xpos, int *ypos, double *out );
int im_avg( VipsImage *in, double *out );
int im_copy( VipsImage *in, VipsImage *out );
int im_copy_set( VipsImage *in, VipsImage *out,
VipsInterpretation interpretation,
float xres, float yres, int xoffset, int yoffset );
int im_copy_set_meta( VipsImage *in, VipsImage *out,
const char *field, GValue *value );
int im_copy_morph( VipsImage *in, VipsImage *out,
int bands, VipsBandFormat format, VipsCoding coding );
int im_copy_swap( VipsImage *in, VipsImage *out );
int im_copy_native( VipsImage *in, VipsImage *out, gboolean is_msb_first );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -1759,9 +1759,54 @@ vips_image_new_disc_temp( const char *format )
return( image );
}
static int
vips_image_write_gen( VipsRegion *or,
void *seq, void *a, void *b, gboolean *stop )
{
VipsRegion *ir = (VipsRegion *) seq;
VipsRect *r = &or->valid;
/* Copy with pointers.
*/
if( vips_region_prepare( ir, r ) ||
vips_region_region( or, ir, r, r->left, r->top ) )
return( -1 );
return( 0 );
}
/**
* vips_image_write:
* @image: image to write
* @out: write to this image
*
* A convenience function to write a #VipsImage to another #VipsImage. Unlike
* vips_copy(), you can specify the #VipsImage you want to write to.
*
* Returns: 0 on success, or -1 on error.
*/
int
vips_image_write( VipsImage *image, VipsImage *out )
{
if( vips_image_pio_input( image ) ||
vips_image_pio_output( out ) )
return( -1 );
if( vips_image_copy_fields( out, image ) )
return( -1 );
vips_demand_hint( out,
VIPS_DEMAND_STYLE_THINSTRIP, image, NULL );
if( vips_image_generate( out,
vips_start_one, vips_image_write_gen, vips_stop_one,
copy->input, copy ) )
return( -1 );
return( 0 );
}
/**
* vips_image_write_filename:
* @image: image to write
* @filename: write to this file
*
* A convenience function to write a #VipsImage to a file.
@ -1769,7 +1814,7 @@ vips_image_new_disc_temp( const char *format )
* Returns: 0 on success, or -1 on error.
*/
int
vips_image_write( VipsImage *image, const char *filename )
vips_image_write_filename( VipsImage *image, const char *filename )
{
VipsImage *out;
@ -1777,7 +1822,7 @@ vips_image_write( VipsImage *image, const char *filename )
if( !(out = vips_image_new_mode( filename, "w" )) )
return( -1 );
if( im_copy( image, out ) ) {
if( vips_image_write( image, out ) ) {
g_object_unref( out );
return( -1 );
}
@ -2060,7 +2105,7 @@ vips_image_wio_input( VipsImage *image )
*/
if( !(t1 = vips_image_new_mode( "wio_input", "t" )) )
return( -1 );
if( im_copy( image, t1 ) ) {
if( vips_image_write( image, t1 ) ) {
g_object_unref( t1 );
return( -1 );
}