Merge branch '8.11' of github.com:libvips/libvips into 8.11
This commit is contained in:
commit
3ccf1761dd
@ -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 )
|
||||
{
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user