copy swap uses glib byte order macros

2x faster byte swapping by using the glib byte swap macros
This commit is contained in:
John Cupitt 2011-12-01 18:47:36 +00:00
parent 261af58e00
commit 878edcf4ea
4 changed files with 40 additions and 39 deletions

View File

@ -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

4
TODO
View File

@ -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

View File

@ -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 );

View File

@ -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 }
};