sRGB2scRGB uses the colour luts directly
rather than going via a function that clips ... about 2x faster
This commit is contained in:
parent
406e228c9b
commit
955a5a97cc
|
@ -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;
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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 *)
|
||||
|
|
|
@ -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 );
|
||||
|
|
Loading…
Reference in New Issue