sRGB2scRGB uses the colour luts directly

rather than going via a function that clips ... about 2x faster
This commit is contained in:
John Cupitt 2017-11-26 16:47:24 +00:00
parent 406e228c9b
commit 955a5a97cc
4 changed files with 50 additions and 50 deletions

View File

@ -75,21 +75,21 @@ G_DEFINE_TYPE( VipsLabQ2sRGB, vips_LabQ2sRGB, VIPS_TYPE_COLOUR_CODE );
*
* There's an extra element at the end to let us do a +1 for interpolation.
*/
static int vips_Y2v_8[256 + 1];
int vips_Y2v_8[256 + 1];
/* 8-bit sRGB -> linear lut.
*/
static float vips_v2Y_8[256];
float vips_v2Y_8[256];
/* 16-bit linear -> sRGB lut.
*
* There's an extra element at the end to let us do a +1 for interpolation.
*/
static int vips_Y2v_16[65536 + 1];
int vips_Y2v_16[65536 + 1];
/* 16-bit sRGB -> linear lut.
*/
static float vips_v2Y_16[65536];
float vips_v2Y_16[65536];
/* Do our own indexing of the arrays below to make sure we get efficient mults.
*/
@ -166,7 +166,7 @@ calcul_tables_8( void *client )
return( NULL );
}
static void
void
vips_col_make_tables_RGB_8( void )
{
static GOnce once = G_ONCE_INIT;
@ -190,7 +190,7 @@ calcul_tables_16( void *client )
return( NULL );
}
static void
void
vips_col_make_tables_RGB_16( void )
{
static GOnce once = G_ONCE_INIT;

View File

@ -205,6 +205,17 @@ GType vips_colour_difference_get_type( void );
void vips__pythagoras_line( VipsColour *colour,
VipsPel *out, VipsPel **in, int width );
/* Colour tables for Y<->v conversion. Call vips_col_make_tables_RGB_8() and
* vips_col_make_tables_RGB_16() before use to initialize.
*/
extern int vips_Y2v_8[256 + 1];
extern float vips_v2Y_8[256];
extern int vips_Y2v_16[65536 + 1];
extern float vips_v2Y_16[65536];
void vips_col_make_tables_RGB_8( void );
void vips_col_make_tables_RGB_16( void );
#ifdef __cplusplus
}
#endif /*__cplusplus*/

View File

@ -75,24 +75,6 @@ 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
@ -103,22 +85,31 @@ vips_sRGB2scRGB_line_8( float * restrict q, VipsPel * restrict p,
if( extra_bands == 0 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
q[0] = vips_v2Y_8[p[0]];
q[1] = vips_v2Y_8[p[1]];
q[2] = vips_v2Y_8[p[2]];
p += 3;
q += 3;
}
}
else if( extra_bands == 1 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
q[0] = vips_v2Y_8[p[0]];
q[1] = vips_v2Y_8[p[1]];
q[2] = vips_v2Y_8[p[2]];
q[3] = p[3];
p += 4;
q += 4;
}
}
else {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_8(q, p);
q[0] = vips_v2Y_8[p[0]];
q[1] = vips_v2Y_8[p[1]];
q[2] = vips_v2Y_8[p[2]];
p += 3;
q += 3;
@ -130,24 +121,6 @@ vips_sRGB2scRGB_line_8( float * restrict q, VipsPel * restrict p,
}
}
/* 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.
*/
static void
@ -158,22 +131,31 @@ vips_sRGB2scRGB_line_16( float * restrict q, unsigned short * restrict p,
if( extra_bands == 0 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
q[0] = vips_v2Y_16[p[0]];
q[1] = vips_v2Y_16[p[1]];
q[2] = vips_v2Y_16[p[2]];
p += 3;
q += 3;
}
}
else if( extra_bands == 1 ) {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
q[0] = vips_v2Y_16[p[0]];
q[1] = vips_v2Y_16[p[1]];
q[2] = vips_v2Y_16[p[2]];
q[3] = p[3] / 256.0;
p += 4;
q += 4;
}
}
else {
for( i = 0; i < width; i++ ) {
vips_sRGB2scRGB_pel_rgb_16(q, p);
q[0] = vips_v2Y_16[p[0]];
q[1] = vips_v2Y_16[p[1]];
q[2] = vips_v2Y_16[p[2]];
p += 3;
q += 3;
@ -201,16 +183,19 @@ vips_sRGB2scRGB_gen( VipsRegion *or,
VIPS_GATE_START( "vips_sRGB2scRGB_gen: work" );
if( in->BandFmt == VIPS_FORMAT_UCHAR ) {
vips_col_make_tables_RGB_8();
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_8( q, p,
in->Bands - 3, r->width );
vips_sRGB2scRGB_line_8( q, p, in->Bands - 3, r->width );
}
}
else {
vips_col_make_tables_RGB_16();
for( y = 0; y < r->height; y++ ) {
VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y );
float *q = (float *)

View File

@ -204,6 +204,10 @@ float vips_col_Chcmc2h( float C, float hcmc );
int vips_col_sRGB2scRGB_8( int r, int g, int b, float *R, float *G, float *B );
int vips_col_sRGB2scRGB_16( int r, int g, int b, float *R, float *G, float *B );
int vips_col_sRGB2scRGB_8_noclip( int r, int g, int b,
float *R, float *G, float *B );
int vips_col_sRGB2scRGB_16_noclip( int r, int g, int b,
float *R, float *G, float *B );
int vips_col_scRGB2XYZ( float R, float G, float B,
float *X, float *Y, float *Z );