load lab 8bit with alpha to labS

This commit is contained in:
Angel Sánchez 2019-07-25 10:40:52 +02:00 committed by John Cupitt
parent c7b286ff8e
commit 6df26bfc9b
2 changed files with 81 additions and 22 deletions

View File

@ -787,6 +787,57 @@ rtiff_parse_labpack( Rtiff *rtiff, VipsImage *out )
return( 0 );
}
/* Per-scanline process function for 8-bit VIPS_CODING_LAB to 16-bit LabS with
* alpha.
*/
static void
rtiff_lab_with_alpha_line( Rtiff *rtiff,
VipsPel *q, VipsPel *p, int n, void *dummy )
{
int samples_per_pixel = rtiff->header.samples_per_pixel;
unsigned char *p1;
short *q1;
int x;
p1 = (unsigned char *) p;
q1 = (short *) q;
for( x = 0; x < n; x++ ) {
int i;
q1[0] = ((unsigned int) p1[0]) * 32767 / 255;
q1[1] = ((short) p1[1]) << 8;
q1[2] = ((short) p1[2]) << 8;
for( i = 3; i < samples_per_pixel; i++ )
q1[i] = (p1[i] << 8) + p1[i];
q1 += samples_per_pixel;
p1 += samples_per_pixel;
}
}
/* Read an 8-bit LAB image with alpha bands into 16-bit LabS.
*/
static int
rtiff_parse_lab_with_alpha( Rtiff *rtiff, VipsImage *out )
{
if( rtiff_check_min_samples( rtiff, 4 ) ||
rtiff_check_bits( rtiff, 8 ) ||
rtiff_check_interpretation( rtiff, PHOTOMETRIC_CIELAB ) )
return( -1 );
out->Bands = rtiff->header.samples_per_pixel;
out->BandFmt = VIPS_FORMAT_SHORT;
out->Coding = VIPS_CODING_NONE;
out->Type = VIPS_INTERPRETATION_LABS;
rtiff->sfn = rtiff_lab_with_alpha_line;
return( 0 );
}
/* Per-scanline process function for LABS.
*/
static void
@ -802,7 +853,7 @@ rtiff_labs_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *dummy )
p1 = (unsigned short *) p;
q1 = (short *) q;
for( x = 0; x < n; x++ ) {
/* We use a signed int16 for L.
/* We use signed int16 for L.
*/
q1[0] = p1[0] >> 1;
@ -1314,10 +1365,15 @@ rtiff_pick_reader( Rtiff *rtiff )
int bits_per_sample = rtiff->header.bits_per_sample;
int photometric_interpretation =
rtiff->header.photometric_interpretation;
int samples_per_pixel = rtiff->header.samples_per_pixel;
if( photometric_interpretation == PHOTOMETRIC_CIELAB ) {
if( bits_per_sample == 8 )
return( rtiff_parse_labpack );
if( bits_per_sample == 8 ) {
if( samples_per_pixel > 3 )
return( rtiff_parse_lab_with_alpha );
else
return( rtiff_parse_labpack );
}
if( bits_per_sample == 16 )
return( rtiff_parse_labs );
}

View File

@ -1117,18 +1117,18 @@ wtiff_new( VipsImage *im, const char *filename,
static void
LabQ2LabC( VipsPel *q, VipsPel *p, int n )
{
int x;
int x;
for( x = 0; x < n; x++ ) {
/* Get most significant 8 bits of lab.
*/
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
for( x = 0; x < n; x++ ) {
/* Get most significant 8 bits of lab.
*/
q[0] = p[0];
q[1] = p[1];
q[2] = p[2];
p += 4;
q += 3;
}
p += 4;
q += 3;
}
}
/* Pack 8 bit VIPS to 1 bit TIFF.
@ -1236,22 +1236,25 @@ invert_band0( Wtiff *wtiff, VipsPel *q, VipsPel *p, int n )
/* Convert VIPS LABS to TIFF 16 bit LAB.
*/
static void
LabS2Lab16( VipsPel *q, VipsPel *p, int n )
LabS2Lab16( VipsPel *q, VipsPel *p, int n, int samples_per_pixel )
{
int x;
int x;
short *p1 = (short *) p;
unsigned short *q1 = (unsigned short *) q;
for( x = 0; x < n; x++ ) {
int i;
/* TIFF uses unsigned 16 bit ... move zero, scale up L.
*/
q1[0] = VIPS_LSHIFT_INT( (int) p1[0], 1 );
q1[1] = p1[1];
q1[2] = p1[2];
p1 += 3;
q1 += 3;
}
for( i = 1; i < samples_per_pixel; i++ )
q1[i] = p1[i];
q1 += samples_per_pixel;
p1 += samples_per_pixel;
}
}
/* Pack the pixels in @area from @in into a TIFF tile buffer.
@ -1286,7 +1289,7 @@ wtiff_pack2tiff( Wtiff *wtiff, Layer *layer,
invert_band0( wtiff, q, p, area->width );
else if( wtiff->im->BandFmt == VIPS_FORMAT_SHORT &&
wtiff->im->Type == VIPS_INTERPRETATION_LABS )
LabS2Lab16( q, p, area->width );
LabS2Lab16( q, p, area->width, in->im->Bands );
else
memcpy( q, p,
area->width *
@ -1369,7 +1372,7 @@ wtiff_layer_write_strip( Wtiff *wtiff, Layer *layer, VipsRegion *strip )
}
else if( im->BandFmt == VIPS_FORMAT_SHORT &&
im->Type == VIPS_INTERPRETATION_LABS ) {
LabS2Lab16( wtiff->tbuf, p, im->Xsize );
LabS2Lab16( wtiff->tbuf, p, im->Xsize, im->Bands );
p = wtiff->tbuf;
}
else if( wtiff->onebit ) {