Merge branch '8.11' of github.com:libvips/libvips into 8.11

This commit is contained in:
John Cupitt 2021-08-07 18:47:41 +01:00
commit 3ccf1761dd
3 changed files with 95 additions and 107 deletions

View File

@ -57,6 +57,22 @@ typedef VipsColourTransformClass VipsLCh2LabClass;
G_DEFINE_TYPE( VipsLCh2Lab, vips_LCh2Lab, VIPS_TYPE_COLOUR_TRANSFORM );
/**
* vips_col_Ch2ab:
* @C: Chroma
* @h: Hue angle (degrees)
* @a: return CIE a* value
* @b: return CIE b* value
*
* Calculate ab from Ch, h in degrees.
*/
void
vips_col_Ch2ab( float C, float h, float *a, float *b )
{
*a = C * cos( VIPS_RAD( h ) );
*b = C * sin( VIPS_RAD( h ) );
}
/* Process a buffer of data.
*/
static void
@ -75,8 +91,7 @@ vips_LCh2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
p += 3;
a = C * cos( VIPS_RAD( h ) );
b = C * sin( VIPS_RAD( h ) );
vips_col_Ch2ab( C, h, &a, &b );
q[0] = L;
q[1] = a;
@ -86,35 +101,6 @@ vips_LCh2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
}
}
/**
* vips_col_Ch2ab:
* @C: Chroma
* @h: Hue angle (degrees)
* @a: return CIE a* value
* @b: return CIE b* value
*
* Calculate ab from Ch, h in degrees.
*/
void
vips_col_Ch2ab( float C, float h, float *a, float *b )
{
float in[3];
float out[3];
float *x;
/* could be anything, we don't use this value, but we must supply one
* or static analyzers will complain.
*/
in[0] = 50.0;
in[1] = C;
in[2] = h;
x = &in[0];
vips_LCh2Lab_line( NULL, (VipsPel *) out, (VipsPel **) &x, 1 );
*a = out[1];
*b = out[2];
}
static void
vips_LCh2Lab_class_init( VipsLCh2LabClass *class )
{

View File

@ -80,6 +80,34 @@ typedef VipsColourTransformClass VipsLab2XYZClass;
G_DEFINE_TYPE( VipsLab2XYZ, vips_Lab2XYZ, VIPS_TYPE_COLOUR_TRANSFORM );
static void
vips_col_Lab2XYZ_helper( VipsLab2XYZ *Lab2XYZ,
float L, float a, float b, float *X, float *Y, float *Z )
{
double cby, tmp;
if( L < 8.0 ) {
*Y = (L * Lab2XYZ->Y0) / 903.3;
cby = 7.787 * (*Y / Lab2XYZ->Y0) + 16.0 / 116.0;
}
else {
cby = (L + 16.0) / 116.0;
*Y = Lab2XYZ->Y0 * cby * cby * cby;
}
tmp = a / 500.0 + cby;
if( tmp < 0.2069 )
*X = Lab2XYZ->X0 * (tmp - 0.13793) / 7.787;
else
*X = Lab2XYZ->X0 * tmp * tmp * tmp;
tmp = cby - b / 200.0;
if( tmp < 0.2069 )
*Z = Lab2XYZ->Z0 * (tmp - 0.13793) / 7.787;
else
*Z = Lab2XYZ->Z0 * tmp * tmp * tmp;
}
/* Process a buffer of data.
*/
static void
@ -97,33 +125,13 @@ vips_Lab2XYZ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
for( x = 0; x < width; x++ ) {
float L, a, b;
float X, Y, Z;
double cby, tmp;
L = p[0];
a = p[1];
b = p[2];
p += 3;
if( L < 8.0 ) {
Y = (L * Lab2XYZ->Y0) / 903.3;
cby = 7.787 * (Y / Lab2XYZ->Y0) + 16.0 / 116.0;
}
else {
cby = (L + 16.0) / 116.0;
Y = Lab2XYZ->Y0 * cby * cby * cby;
}
tmp = a / 500.0 + cby;
if( tmp < 0.2069 )
X = Lab2XYZ->X0 * (tmp - 0.13793) / 7.787;
else
X = Lab2XYZ->X0 * tmp * tmp * tmp;
tmp = cby - b / 200.0;
if( tmp < 0.2069 )
Z = Lab2XYZ->Z0 * (tmp - 0.13793) / 7.787;
else
Z = Lab2XYZ->Z0 * tmp * tmp * tmp;
vips_col_Lab2XYZ_helper( Lab2XYZ, L, a, b, &X, &Y, &Z );
/* Write.
*/
@ -234,23 +242,11 @@ vips_Lab2XYZ( VipsImage *in, VipsImage **out, ... )
*/
void
vips_col_Lab2XYZ( float L, float a, float b, float *X, float *Y, float *Z )
{
float in[3];
float *x;
float out[3];
{
VipsLab2XYZ Lab2XYZ;
in[0] = L;
in[1] = a;
in[2] = b;
x = in;
Lab2XYZ.X0 = VIPS_D65_X0;
Lab2XYZ.Y0 = VIPS_D65_Y0;
Lab2XYZ.Z0 = VIPS_D65_Z0;
vips_Lab2XYZ_line( (VipsColour *) &Lab2XYZ,
(VipsPel *) out, (VipsPel **) &x, 1 );
*X = out[0];
*Y = out[1];
*Z = out[2];
vips_col_Lab2XYZ_helper( &Lab2XYZ, L, a, b, X, Y, Z );
}

View File

@ -107,49 +107,67 @@ table_init( void *client )
return( NULL );
}
static void
vips_col_XYZ2Lab_helper( VipsXYZ2Lab *XYZ2Lab,
float X, float Y, float Z, float *L, float *a, float *b )
{
static GOnce once = G_ONCE_INIT;
VIPS_ONCE( &once, table_init, NULL );
float nX, nY, nZ;
int i;
float f;
float cbx, cby, cbz;
nX = QUANT_ELEMENTS * X / XYZ2Lab->X0;
nY = QUANT_ELEMENTS * Y / XYZ2Lab->Y0;
nZ = QUANT_ELEMENTS * Z / XYZ2Lab->Z0;
/* CLIP is much faster than FCLIP, and we want an int result.
*/
i = VIPS_CLIP( 0, (int) nX, QUANT_ELEMENTS - 2 );
f = nX - i;
cbx = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
i = VIPS_CLIP( 0, (int) nY, QUANT_ELEMENTS - 2 );
f = nY - i;
cby = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
i = VIPS_CLIP( 0, (int) nZ, QUANT_ELEMENTS - 2 );
f = nZ - i;
cbz = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
*L = 116.0 * cby - 16.0;
*a = 500.0 * (cbx - cby);
*b = 200.0 * (cby - cbz);
}
/* Process a buffer of data.
*/
static void
vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
{
static GOnce once = G_ONCE_INIT;
VipsXYZ2Lab *XYZ2Lab = (VipsXYZ2Lab *) colour;
float *p = (float *) in[0];
float *q = (float *) out;
int x;
VIPS_ONCE( &once, table_init, NULL );
for( x = 0; x < width; x++ ) {
float nX, nY, nZ;
int i;
float f;
float cbx, cby, cbz;
float X, Y, Z;
float L, a, b;
nX = QUANT_ELEMENTS * p[0] / XYZ2Lab->X0;
nY = QUANT_ELEMENTS * p[1] / XYZ2Lab->Y0;
nZ = QUANT_ELEMENTS * p[2] / XYZ2Lab->Z0;
X = p[0];
Y = p[1];
Z = p[2];
p += 3;
/* CLIP is much faster than FCLIP, and we want an int result.
*/
i = VIPS_CLIP( 0, (int) nX, QUANT_ELEMENTS - 2 );
f = nX - i;
cbx = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
vips_col_XYZ2Lab_helper( XYZ2Lab, X, Y, Z, &L, &a, &b );
i = VIPS_CLIP( 0, (int) nY, QUANT_ELEMENTS - 2 );
f = nY - i;
cby = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
i = VIPS_CLIP( 0, (int) nZ, QUANT_ELEMENTS - 2 );
f = nZ - i;
cbz = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
q[0] = 116.0 * cby - 16.0;
q[1] = 500.0 * (cbx - cby);
q[2] = 200.0 * (cby - cbz);
q[0] = L;
q[1] = a;
q[2] = b;
q += 3;
}
}
@ -169,24 +187,13 @@ vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
*/
void
vips_col_XYZ2Lab( float X, float Y, float Z, float *L, float *a, float *b )
{
float in[3];
float out[3];
float *x;
{
VipsXYZ2Lab XYZ2Lab;
in[0] = X;
in[1] = Y;
in[2] = Z;
x = in;
XYZ2Lab.X0 = VIPS_D65_X0;
XYZ2Lab.Y0 = VIPS_D65_Y0;
XYZ2Lab.Z0 = VIPS_D65_Z0;
vips_XYZ2Lab_line( (VipsColour *) &XYZ2Lab,
(VipsPel *) out, (VipsPel **) &x, 1 );
*L = out[0];
*a = out[1];
*b = out[2];
vips_col_XYZ2Lab_helper( &XYZ2Lab, X, Y, Z, L, a, b );
}
static int
@ -273,4 +280,3 @@ vips_XYZ2Lab( VipsImage *in, VipsImage **out, ... )
return( result );
}