8 and 16-bit paletter TIFFs can have alpha
plus 16-bit palette TIFFs now become 16-bit images
This commit is contained in:
parent
dd35d6ffc7
commit
6d2c4c4d60
@ -20,6 +20,7 @@
|
|||||||
- added "postbuild" signal
|
- added "postbuild" signal
|
||||||
- vips_system() now supports many input images and you can change image
|
- vips_system() now supports many input images and you can change image
|
||||||
argument order
|
argument order
|
||||||
|
- support 16-bit palette TIFFs, plus palette TIFFs can have an alpha
|
||||||
|
|
||||||
6/3/14 started 7.38.6
|
6/3/14 started 7.38.6
|
||||||
- grey ramp minimum was wrong
|
- grey ramp minimum was wrong
|
||||||
|
@ -141,6 +141,9 @@
|
|||||||
* - support separate planes for strip read
|
* - support separate planes for strip read
|
||||||
* - big cleanup
|
* - big cleanup
|
||||||
* - support for many more formats, eg. 32-bit int etc.
|
* - support for many more formats, eg. 32-bit int etc.
|
||||||
|
* 11/4/14
|
||||||
|
* - support 16 bits per sample palette images
|
||||||
|
* - palette images can have an alpha
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -683,9 +686,13 @@ parse_greyscale( ReadTiff *rtiff, VipsImage *out )
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* LUTs mapping image indexes to RGB.
|
/* LUTs mapping image indexes to RGB.
|
||||||
*/
|
*/
|
||||||
VipsPel *red;
|
VipsPel *red8;
|
||||||
VipsPel *green;
|
VipsPel *green8;
|
||||||
VipsPel *blue;
|
VipsPel *blue8;
|
||||||
|
|
||||||
|
guint16 *red16;
|
||||||
|
guint16 *green16;
|
||||||
|
guint16 *blue16;
|
||||||
|
|
||||||
/* All maps equal, so we write mono.
|
/* All maps equal, so we write mono.
|
||||||
*/
|
*/
|
||||||
@ -695,7 +702,7 @@ typedef struct {
|
|||||||
/* Per-scanline process function for palette images.
|
/* Per-scanline process function for palette images.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
palette_line( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
palette_line_bit( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
||||||
{
|
{
|
||||||
PaletteRead *read = (PaletteRead *) client;
|
PaletteRead *read = (PaletteRead *) client;
|
||||||
|
|
||||||
@ -718,82 +725,133 @@ palette_line( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
|||||||
bit -= rtiff->bits_per_sample;
|
bit -= rtiff->bits_per_sample;
|
||||||
|
|
||||||
if( read->mono ) {
|
if( read->mono ) {
|
||||||
q[0] = read->red[i];
|
q[0] = read->red8[i];
|
||||||
q += 1;
|
q += 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
q[0] = read->red[i];
|
q[0] = read->red8[i];
|
||||||
q[1] = read->green[i];
|
q[1] = read->green8[i];
|
||||||
q[2] = read->blue[i];
|
q[2] = read->blue8[i];
|
||||||
q += 3;
|
q += 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The tiff is 8-bit and can have an alpha.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
palette_line16( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client )
|
palette_line8( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
||||||
|
void *client )
|
||||||
{
|
{
|
||||||
PaletteRead *read = (PaletteRead *) client;
|
PaletteRead *read = (PaletteRead *) client;
|
||||||
|
int samples = rtiff->samples_per_pixel;
|
||||||
|
|
||||||
guint16 *data = (guint16 *) p;
|
|
||||||
int x;
|
int x;
|
||||||
|
int s;
|
||||||
|
|
||||||
for( x = 0; x < n; x++ ) {
|
for( x = 0; x < n; x++ ) {
|
||||||
int i = data[x];
|
int i = p[0];
|
||||||
|
|
||||||
if( read->mono ) {
|
if( read->mono )
|
||||||
q[0] = read->red[i];
|
q[0] = read->red8[i];
|
||||||
q += 1;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
q[0] = read->red[i];
|
q[0] = read->red8[i];
|
||||||
q[1] = read->green[i];
|
q[1] = read->green8[i];
|
||||||
q[2] = read->blue[i];
|
q[2] = read->blue8[i];
|
||||||
q += 3;
|
q += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( s = 1; s < samples; s++ )
|
||||||
|
q[s] = p[s];
|
||||||
|
|
||||||
|
q += samples;
|
||||||
|
p += samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read a palette-ised TIFF image. 1/2/4/8/16 bits only.
|
/* 16-bit tiff and can have an alpha.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
palette_line16( ReadTiff *rtiff, VipsPel *q, VipsPel *p, int n,
|
||||||
|
void *client )
|
||||||
|
{
|
||||||
|
PaletteRead *read = (PaletteRead *) client;
|
||||||
|
int samples = rtiff->samples_per_pixel;
|
||||||
|
|
||||||
|
guint16 *p16, *q16;
|
||||||
|
int x;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
q16 = (guint16 *) q;
|
||||||
|
p16 = (guint16 *) p;
|
||||||
|
|
||||||
|
for( x = 0; x < n; x++ ) {
|
||||||
|
int i = p16[0];
|
||||||
|
|
||||||
|
if( read->mono )
|
||||||
|
q16[0] = read->red16[i];
|
||||||
|
else {
|
||||||
|
q16[0] = read->red16[i];
|
||||||
|
q16[1] = read->green16[i];
|
||||||
|
q16[2] = read->blue16[i];
|
||||||
|
q16 += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( s = 1; s < samples; s++ )
|
||||||
|
q16[s] = p16[s];
|
||||||
|
|
||||||
|
q16 += samples;
|
||||||
|
p16 += samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read a palette-ised TIFF image.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
parse_palette( ReadTiff *rtiff, VipsImage *out )
|
parse_palette( ReadTiff *rtiff, VipsImage *out )
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
PaletteRead *read;
|
PaletteRead *read;
|
||||||
uint16 *tred, *tgreen, *tblue;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if( check_bits_palette( rtiff ) ||
|
if( check_bits_palette( rtiff ) ||
|
||||||
check_samples( rtiff, 1 ) )
|
check_min_samples( rtiff, 1 ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
len = 1 << rtiff->bits_per_sample;
|
len = 1 << rtiff->bits_per_sample;
|
||||||
|
|
||||||
|
if( rtiff->bits_per_sample < 8 &&
|
||||||
|
rtiff->samples_per_pixel > 1 ) {
|
||||||
|
vips_error( "tiff2vips", "%s", _( "can't have an alpha for "
|
||||||
|
"palette images less than 8 bits per sample" ) );
|
||||||
|
return( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
if( !(read = VIPS_NEW( out, PaletteRead )) ||
|
if( !(read = VIPS_NEW( out, PaletteRead )) ||
|
||||||
!(read->red = VIPS_ARRAY( out, len, VipsPel )) ||
|
!(read->red8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
||||||
!(read->green = VIPS_ARRAY( out, len, VipsPel )) ||
|
!(read->green8 = VIPS_ARRAY( out, len, VipsPel )) ||
|
||||||
!(read->blue = VIPS_ARRAY( out, len, VipsPel )) )
|
!(read->blue8 = VIPS_ARRAY( out, len, VipsPel )) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
/* Get maps, convert to 8-bit data.
|
/* Get maps, convert to 8-bit data.
|
||||||
*/
|
*/
|
||||||
if( !TIFFGetField( rtiff->tiff,
|
if( !TIFFGetField( rtiff->tiff,
|
||||||
TIFFTAG_COLORMAP, &tred, &tgreen, &tblue ) ) {
|
TIFFTAG_COLORMAP,
|
||||||
|
&read->red16, &read->green16, &read->blue16 ) ) {
|
||||||
vips_error( "tiff2vips", "%s", _( "bad colormap" ) );
|
vips_error( "tiff2vips", "%s", _( "bad colormap" ) );
|
||||||
return( -1 );
|
return( -1 );
|
||||||
}
|
}
|
||||||
for( i = 0; i < len; i++ ) {
|
for( i = 0; i < len; i++ ) {
|
||||||
read->red[i] = tred[i] >> 8;
|
read->red8[i] = read->red16[i] >> 8;
|
||||||
read->green[i] = tgreen[i] >> 8;
|
read->green8[i] = read->green16[i] >> 8;
|
||||||
read->blue[i] = tblue[i] >> 8;
|
read->blue8[i] = read->blue16[i] >> 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are all the maps equal? We have a mono image.
|
/* Are all the maps equal? We have a mono image.
|
||||||
*/
|
*/
|
||||||
read->mono = TRUE;
|
read->mono = TRUE;
|
||||||
for( i = 0; i < len; i++ )
|
for( i = 0; i < len; i++ )
|
||||||
if( read->red[i] != read->green[i] ||
|
if( read->red16[i] != read->green16[i] ||
|
||||||
read->green[i] != read->blue[i] ) {
|
read->green16[i] != read->blue16[i] ) {
|
||||||
read->mono = FALSE;
|
read->mono = FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -803,23 +861,36 @@ parse_palette( ReadTiff *rtiff, VipsImage *out )
|
|||||||
* just search the colormap.
|
* just search the colormap.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
out->BandFmt = VIPS_FORMAT_UCHAR;
|
if( rtiff->bits_per_sample <= 8 )
|
||||||
|
out->BandFmt = VIPS_FORMAT_UCHAR;
|
||||||
|
else
|
||||||
|
out->BandFmt = VIPS_FORMAT_USHORT;
|
||||||
out->Coding = VIPS_CODING_NONE;
|
out->Coding = VIPS_CODING_NONE;
|
||||||
|
|
||||||
if( read->mono ) {
|
if( read->mono ) {
|
||||||
out->Bands = 1;
|
out->Bands = rtiff->samples_per_pixel;
|
||||||
out->Type = VIPS_INTERPRETATION_B_W;
|
if( rtiff->bits_per_sample <= 8 )
|
||||||
|
out->Type = VIPS_INTERPRETATION_B_W;
|
||||||
|
else
|
||||||
|
out->Type = VIPS_INTERPRETATION_GREY16;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
out->Bands = 3;
|
out->Bands = rtiff->samples_per_pixel + 2;
|
||||||
out->Type = VIPS_INTERPRETATION_sRGB;
|
if( rtiff->bits_per_sample <= 8 )
|
||||||
|
out->Type = VIPS_INTERPRETATION_sRGB;
|
||||||
|
else
|
||||||
|
out->Type = VIPS_INTERPRETATION_RGB16;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtiff->client = read;
|
rtiff->client = read;
|
||||||
if( rtiff->bits_per_sample == 16 )
|
if( rtiff->bits_per_sample < 8 )
|
||||||
|
rtiff->sfn = palette_line_bit;
|
||||||
|
else if( rtiff->bits_per_sample == 8 )
|
||||||
|
rtiff->sfn = palette_line8;
|
||||||
|
else if( rtiff->bits_per_sample == 16 )
|
||||||
rtiff->sfn = palette_line16;
|
rtiff->sfn = palette_line16;
|
||||||
else
|
else
|
||||||
rtiff->sfn = palette_line;
|
g_assert( 0 );
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user