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 );
|
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.
|
/* Process a buffer of data.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -75,8 +91,7 @@ vips_LCh2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
|||||||
|
|
||||||
p += 3;
|
p += 3;
|
||||||
|
|
||||||
a = C * cos( VIPS_RAD( h ) );
|
vips_col_Ch2ab( C, h, &a, &b );
|
||||||
b = C * sin( VIPS_RAD( h ) );
|
|
||||||
|
|
||||||
q[0] = L;
|
q[0] = L;
|
||||||
q[1] = a;
|
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
|
static void
|
||||||
vips_LCh2Lab_class_init( VipsLCh2LabClass *class )
|
vips_LCh2Lab_class_init( VipsLCh2LabClass *class )
|
||||||
{
|
{
|
||||||
|
@ -80,6 +80,34 @@ typedef VipsColourTransformClass VipsLab2XYZClass;
|
|||||||
|
|
||||||
G_DEFINE_TYPE( VipsLab2XYZ, vips_Lab2XYZ, VIPS_TYPE_COLOUR_TRANSFORM );
|
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.
|
/* Process a buffer of data.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@ -97,33 +125,13 @@ vips_Lab2XYZ_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
|||||||
for( x = 0; x < width; x++ ) {
|
for( x = 0; x < width; x++ ) {
|
||||||
float L, a, b;
|
float L, a, b;
|
||||||
float X, Y, Z;
|
float X, Y, Z;
|
||||||
double cby, tmp;
|
|
||||||
|
|
||||||
L = p[0];
|
L = p[0];
|
||||||
a = p[1];
|
a = p[1];
|
||||||
b = p[2];
|
b = p[2];
|
||||||
p += 3;
|
p += 3;
|
||||||
|
|
||||||
if( L < 8.0 ) {
|
vips_col_Lab2XYZ_helper( Lab2XYZ, L, a, b, &X, &Y, &Z );
|
||||||
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;
|
|
||||||
|
|
||||||
/* Write.
|
/* Write.
|
||||||
*/
|
*/
|
||||||
@ -234,23 +242,11 @@ vips_Lab2XYZ( VipsImage *in, VipsImage **out, ... )
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips_col_Lab2XYZ( float L, float a, float b, float *X, float *Y, float *Z )
|
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;
|
VipsLab2XYZ Lab2XYZ;
|
||||||
|
|
||||||
in[0] = L;
|
|
||||||
in[1] = a;
|
|
||||||
in[2] = b;
|
|
||||||
x = in;
|
|
||||||
Lab2XYZ.X0 = VIPS_D65_X0;
|
Lab2XYZ.X0 = VIPS_D65_X0;
|
||||||
Lab2XYZ.Y0 = VIPS_D65_Y0;
|
Lab2XYZ.Y0 = VIPS_D65_Y0;
|
||||||
Lab2XYZ.Z0 = VIPS_D65_Z0;
|
Lab2XYZ.Z0 = VIPS_D65_Z0;
|
||||||
vips_Lab2XYZ_line( (VipsColour *) &Lab2XYZ,
|
vips_col_Lab2XYZ_helper( &Lab2XYZ, L, a, b, X, Y, Z );
|
||||||
(VipsPel *) out, (VipsPel **) &x, 1 );
|
|
||||||
*X = out[0];
|
|
||||||
*Y = out[1];
|
|
||||||
*Z = out[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,49 +107,67 @@ table_init( void *client )
|
|||||||
return( NULL );
|
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.
|
/* Process a buffer of data.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
||||||
{
|
{
|
||||||
static GOnce once = G_ONCE_INIT;
|
|
||||||
|
|
||||||
VipsXYZ2Lab *XYZ2Lab = (VipsXYZ2Lab *) colour;
|
VipsXYZ2Lab *XYZ2Lab = (VipsXYZ2Lab *) colour;
|
||||||
float *p = (float *) in[0];
|
float *p = (float *) in[0];
|
||||||
float *q = (float *) out;
|
float *q = (float *) out;
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
VIPS_ONCE( &once, table_init, NULL );
|
|
||||||
|
|
||||||
for( x = 0; x < width; x++ ) {
|
for( x = 0; x < width; x++ ) {
|
||||||
float nX, nY, nZ;
|
float X, Y, Z;
|
||||||
int i;
|
float L, a, b;
|
||||||
float f;
|
|
||||||
float cbx, cby, cbz;
|
|
||||||
|
|
||||||
nX = QUANT_ELEMENTS * p[0] / XYZ2Lab->X0;
|
X = p[0];
|
||||||
nY = QUANT_ELEMENTS * p[1] / XYZ2Lab->Y0;
|
Y = p[1];
|
||||||
nZ = QUANT_ELEMENTS * p[2] / XYZ2Lab->Z0;
|
Z = p[2];
|
||||||
p += 3;
|
p += 3;
|
||||||
|
|
||||||
/* CLIP is much faster than FCLIP, and we want an int result.
|
vips_col_XYZ2Lab_helper( XYZ2Lab, X, Y, Z, &L, &a, &b );
|
||||||
*/
|
|
||||||
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 );
|
q[0] = L;
|
||||||
f = nY - i;
|
q[1] = a;
|
||||||
cby = cbrt_table[i] + f * (cbrt_table[i + 1] - cbrt_table[i]);
|
q[2] = b;
|
||||||
|
|
||||||
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 += 3;
|
q += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,24 +187,13 @@ vips_XYZ2Lab_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width )
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
vips_col_XYZ2Lab( float X, float Y, float Z, float *L, float *a, float *b )
|
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;
|
VipsXYZ2Lab XYZ2Lab;
|
||||||
|
|
||||||
in[0] = X;
|
|
||||||
in[1] = Y;
|
|
||||||
in[2] = Z;
|
|
||||||
x = in;
|
|
||||||
XYZ2Lab.X0 = VIPS_D65_X0;
|
XYZ2Lab.X0 = VIPS_D65_X0;
|
||||||
XYZ2Lab.Y0 = VIPS_D65_Y0;
|
XYZ2Lab.Y0 = VIPS_D65_Y0;
|
||||||
XYZ2Lab.Z0 = VIPS_D65_Z0;
|
XYZ2Lab.Z0 = VIPS_D65_Z0;
|
||||||
vips_XYZ2Lab_line( (VipsColour *) &XYZ2Lab,
|
vips_col_XYZ2Lab_helper( &XYZ2Lab, X, Y, Z, L, a, b );
|
||||||
(VipsPel *) out, (VipsPel **) &x, 1 );
|
|
||||||
*L = out[0];
|
|
||||||
*a = out[1];
|
|
||||||
*b = out[2];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -273,4 +280,3 @@ vips_XYZ2Lab( VipsImage *in, VipsImage **out, ... )
|
|||||||
|
|
||||||
return( result );
|
return( result );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user