From 878edcf4ea7ab22998fe1993f915d37cd3fe3dec Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 1 Dec 2011 18:47:36 +0000 Subject: [PATCH] copy swap uses glib byte order macros 2x faster byte swapping by using the glib byte swap macros --- ChangeLog | 6 ++++- TODO | 4 ---- libvips/conversion/copy.c | 49 ++++++++++++++++++--------------------- tools/edvips.c | 20 +++++++++------- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index f32bb96c..ce155f86 100644 --- a/ChangeLog +++ b/ChangeLog @@ -49,9 +49,13 @@ - set _O_TEMPORARY on delete-on-close temp images if possible - unlink temps on rewind on *nix, less likely to leave temps on a crash - added complex conj as a basic operation -- rect/polar/conj work o any format, not just complex +- rect/polar/conj work on any format, not just complex - new VipsFile system for load/save in image formats - options now introspectable, try "vips jpegsave" +- copy swap uses glib byteswap macros, about 2x faster +- edvips can change vips header byte ordering +- "header" is terse by default +- "header" outputs filenames if working on many files 12/10/11 started 7.26.6 - NOCACHE was not being set correctly on OS X causing performance diff --git a/TODO b/TODO index ff9942e8..5dbb524f 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,3 @@ -- get copy swap to use the glib byte order macros as well, faster? - - - - test vips_foreign_load_vips_get_flags(), sense inverted? test load/save jpeg buffer diff --git a/libvips/conversion/copy.c b/libvips/conversion/copy.c index 29af89e1..7df5b9f4 100644 --- a/libvips/conversion/copy.c +++ b/libvips/conversion/copy.c @@ -45,6 +45,8 @@ * - im_copy_set() now sets xoff / yoff again hmmm * 29/9/11 * - rewrite as a class + * 1/12/11 + * - use glib byteswap macros */ /* @@ -136,13 +138,14 @@ G_DEFINE_TYPE( VipsCopy, vips_copy, VIPS_TYPE_CONVERSION ); static void vips_copy_swap2( PEL *in, PEL *out, int width, VipsImage *im ) { - int x; - int sz = VIPS_IMAGE_SIZEOF_PEL( im ) * width; /* Bytes in buffer */ + guint16 *p = (guint16 *) in; + guint16 *q = (guint16 *) out; + int sz = (VIPS_IMAGE_SIZEOF_PEL( im ) * width) / 2; - for( x = 0; x < sz; x += 2 ) { - out[x] = in[x + 1]; - out[x + 1] = in[x]; - } + int x; + + for( x = 0; x < sz; x++ ) + out[x] = GUINT16_SWAP_LE_BE( in[x] ); } /* Swap 4- of bytes. @@ -150,15 +153,14 @@ vips_copy_swap2( PEL *in, PEL *out, int width, VipsImage *im ) static void vips_copy_swap4( PEL *in, PEL *out, int width, VipsImage *im ) { - int x; - int sz = VIPS_IMAGE_SIZEOF_PEL( im ) * width; /* Bytes in buffer */ + guint32 *p = (guint32 *) in; + guint32 *q = (guint32 *) out; + int sz = (VIPS_IMAGE_SIZEOF_PEL( im ) * width) / 4; - for( x = 0; x < sz; x += 4 ) { - out[x] = in[x + 3]; - out[x + 1] = in[x + 2]; - out[x + 2] = in[x + 1]; - out[x + 3] = in[x]; - } + int x; + + for( x = 0; x < sz; x++ ) + out[x] = GUINT32_SWAP_LE_BE( in[x] ); } /* Swap 8- of bytes. @@ -166,19 +168,14 @@ vips_copy_swap4( PEL *in, PEL *out, int width, VipsImage *im ) static void vips_copy_swap8( PEL *in, PEL *out, int width, VipsImage *im ) { - int x; - int sz = VIPS_IMAGE_SIZEOF_PEL( im ) * width; /* Bytes in buffer */ + guint64 *p = (guint64 *) in; + guint64 *q = (guint64 *) out; + int sz = (VIPS_IMAGE_SIZEOF_PEL( im ) * width) / 8; - for( x = 0; x < sz; x += 8 ) { - out[x] = in[x + 7]; - out[x + 1] = in[x + 6]; - out[x + 2] = in[x + 5]; - out[x + 3] = in[x + 4]; - out[x + 4] = in[x + 3]; - out[x + 5] = in[x + 2]; - out[x + 6] = in[x + 1]; - out[x + 7] = in[x]; - } + int x; + + for( x = 0; x < sz; x++ ) + out[x] = GUINT64_SWAP_LE_BE( in[x] ); } typedef void (*SwapFn)( PEL *in, PEL *out, int width, VipsImage *im ); diff --git a/tools/edvips.c b/tools/edvips.c index 74f83f80..a8d66c16 100644 --- a/tools/edvips.c +++ b/tools/edvips.c @@ -80,16 +80,14 @@ static gboolean setext = FALSE; static GOptionEntry entries[] = { { "endian", 'n', 0, G_OPTION_ARG_STRING, &endian, N_( "tag file as big or little-endian" ), NULL }, - { "xsize", 'x', 0, G_OPTION_ARG_STRING, &xsize, - N_( "set Xsize to N" ), "N" }, - { "ysize", 'y', 0, G_OPTION_ARG_STRING, &ysize, - N_( "set Ysize to N" ), "N" }, + { "width", 'w', 0, G_OPTION_ARG_STRING, &xsize, + N_( "set width to N pixels" ), "N" }, + { "height", 'h', 0, G_OPTION_ARG_STRING, &ysize, + N_( "set height to N pixels" ), "N" }, { "bands", 'b', 0, G_OPTION_ARG_STRING, &bands, N_( "set Bands to N" ), "N" }, { "format", 'f', 0, G_OPTION_ARG_STRING, &format, N_( "set BandFmt to F (eg. uchar, float)" ), "F" }, - { "type", 't', 0, G_OPTION_ARG_STRING, &type, - N_( "set Type to T (deprecated, use interpretation)" ), "T" }, { "interpretation", 'i', 0, G_OPTION_ARG_STRING, &type, N_( "set interpretation to I (eg. xyz)" ), "I" }, { "coding", 'c', 0, G_OPTION_ARG_STRING, &coding, @@ -99,11 +97,17 @@ static GOptionEntry entries[] = { { "yres", 'Y', 0, G_OPTION_ARG_STRING, &yres, N_( "set Yres to R pixels/mm" ), "R" }, { "xoffset", 'u', 0, G_OPTION_ARG_STRING, &xoffset, - N_( "set Xoffset to N" ), "N" }, + N_( "set Xoffset to N pixels" ), "N" }, { "yoffset", 'v', 0, G_OPTION_ARG_STRING, &yoffset, - N_( "set Yoffset to N" ), "N" }, + N_( "set Yoffset to N pixels" ), "N" }, { "setext", 'e', 0, G_OPTION_ARG_NONE, &setext, N_( "replace extension block with stdin" ), NULL }, + { "xsize", 'x', 0, G_OPTION_ARG_STRING, &xsize, + N_( "set Xsize to N (deprecated, use width)" ), "N" }, + { "ysize", 'y', 0, G_OPTION_ARG_STRING, &ysize, + N_( "set Ysize to N (deprecated, use height)" ), "N" }, + { "type", 't', 0, G_OPTION_ARG_STRING, &type, + N_( "set Type to T (deprecated, use interpretation)" ), "T" }, { NULL } };