~20% sRGB to scRGB speedup for common 3 and 4 band images

This commit is contained in:
Lovell Fuller 2017-11-24 21:45:00 +00:00
parent f9f717a843
commit cac1b5b9c6
1 changed files with 101 additions and 47 deletions

View File

@ -73,6 +73,24 @@ typedef VipsOperationClass VipssRGB2scRGBClass;
G_DEFINE_TYPE( VipssRGB2scRGB, vips_sRGB2scRGB, VIPS_TYPE_OPERATION );
/* Convert an 8-bit pixel.
*/
static void
vips_sRGB2scRGB_pel_rgb_8( float * restrict q,
VipsPel * restrict p )
{
const int r = p[0];
const int g = p[1];
const int b = p[2];
float R, G, B;
vips_col_sRGB2scRGB_8( r, g, b, &R, &G, &B );
q[0] = R;
q[1] = G;
q[2] = B;
}
/* Convert a buffer of 8-bit pixels.
*/
static void
@ -81,28 +99,51 @@ vips_sRGB2scRGB_line_8( float * restrict q, VipsPel * restrict p,
{
int i, j;
for( i = 0; i < width; i++ ) {
int r = p[0];
int g = p[1];
int b = p[2];
float R, G, B;
p += 3;
vips_col_sRGB2scRGB_8( r, g, b, &R, &G, &B );
q[0] = R;
q[1] = G;
q[2] = B;
q += 3;
for( j = 0; j < extra_bands; j++ )
q[j] = p[j];
p += extra_bands;
q += extra_bands;
if( extra_bands == 0 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
p += 3;
q += 3;
}
}
else if( extra_bands == 1 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
q[3] = p[3];
p += 4;
q += 4;
}
}
else {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
p += 3;
q += 3;
for( j = 0; j < extra_bands; j++ )
q[j] = p[j];
p += extra_bands;
q += extra_bands;
}
}
}
/* Convert a 16-bit pixel.
*/
static void
vips_sRGB2scRGB_pel_rgb_16( float * restrict q,
unsigned short * restrict p )
{
const int r = p[0];
const int g = p[1];
const int b = p[2];
float R, G, B;
vips_col_sRGB2scRGB_16( r, g, b, &R, &G, &B );
q[0] = R;
q[1] = G;
q[2] = B;
}
/* Convert a buffer of 16-bit pixels.
@ -113,27 +154,32 @@ vips_sRGB2scRGB_line_16( float * restrict q, unsigned short * restrict p,
{
int i, j;
for( i = 0; i < width; i++ ) {
int r = p[0];
int g = p[1];
int b = p[2];
if( extra_bands == 0 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
p += 3;
q += 3;
}
}
else if( extra_bands == 1 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
q[3] = p[3] / 256.0;
p += 4;
q += 4;
}
}
else {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
p += 3;
q += 3;
float R, G, B;
p += 3;
vips_col_sRGB2scRGB_16( r, g, b, &R, &G, &B );
q[0] = R;
q[1] = G;
q[2] = B;
q += 3;
for( j = 0; j < extra_bands; j++ )
q[j] = p[j] / 256.0;
p += extra_bands;
q += extra_bands;
for( j = 0; j < extra_bands; j++ )
q[j] = p[j] / 256.0;
p += extra_bands;
q += extra_bands;
}
}
}
@ -152,17 +198,25 @@ vips_sRGB2scRGB_gen( VipsRegion *or,
VIPS_GATE_START( "vips_sRGB2scRGB_gen: work" );
for( y = 0; y < r->height; y++ ) {
VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y );
float *q = (float *)
VIPS_REGION_ADDR( or, r->left, r->top + y );
if( in->BandFmt == VIPS_FORMAT_UCHAR ) {
for( y = 0; y < r->height; y++ ) {
VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y );
float *q = (float *)
VIPS_REGION_ADDR( or, r->left, r->top + y );
if( in->BandFmt == VIPS_FORMAT_UCHAR )
vips_sRGB2scRGB_line_8( q, p,
in->Bands - 3, r->width );
else
}
}
else {
for( y = 0; y < r->height; y++ ) {
VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y );
float *q = (float *)
VIPS_REGION_ADDR( or, r->left, r->top + y );
vips_sRGB2scRGB_line_16( q, (unsigned short *) p,
in->Bands - 3, r->width );
}
}
VIPS_GATE_STOP( "vips_sRGB2scRGB_gen: work" );