Fixed issues with bitdepth
This commit is contained in:
parent
17a9bf393f
commit
00bd91a3c4
@ -1063,34 +1063,36 @@ rtiff_onebit_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *flg )
|
||||
static void
|
||||
rtiff_twobit_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *flg )
|
||||
{
|
||||
int x, i, z;
|
||||
int minisblack =
|
||||
rtiff->header.photometric_interpretation == PHOTOMETRIC_MINISBLACK;
|
||||
VipsPel bits;
|
||||
int x, i, z;
|
||||
int minisblack =
|
||||
rtiff->header.photometric_interpretation == PHOTOMETRIC_MINISBLACK;
|
||||
VipsPel twobits, fourbits, bits;
|
||||
|
||||
x = 0;
|
||||
for( i = 0; i < (n >> 2); i++ ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
x = 0;
|
||||
for( i = 0; i < (n >> 2); i++ ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
|
||||
for( z = 0; z < 4; z++ ) {
|
||||
/* The grey shade is the value four times concatenated */
|
||||
q[x] = (bits & 0xC0) | ((bits & 0xC0) >> 2)
|
||||
| ((bits & 0xC0) >> 4) | (bits >> 6);
|
||||
bits <<= 2;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
for( z = 0; z < 4; z++ ) {
|
||||
/* The grey shade is the value four times concatenated */
|
||||
twobits = bits >> 6;
|
||||
fourbits = twobits | (twobits << 2);
|
||||
q[x] = fourbits | (fourbits << 4);
|
||||
bits <<= 2;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do last byte in line.
|
||||
*/
|
||||
if( n & 3 ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
for( z = 0; z < (n & 3) ; z++ ) {
|
||||
q[x + z] = (bits & 0xC0) | ((bits & 0xC0) >> 2)
|
||||
| ((bits & 0xC0) >> 4) | (bits >> 6);
|
||||
bits <<= 2;
|
||||
}
|
||||
}
|
||||
/* Do last byte in line.
|
||||
*/
|
||||
if( n & 3 ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
for( z = 0; z < (n & 3) ; z++ ) {
|
||||
twobits = bits >> 6;
|
||||
fourbits = twobits | (twobits << 2);
|
||||
q[x + z] = fourbits | (fourbits << 4);
|
||||
bits <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Per-scanline process function for 4 bit greyscale images.
|
||||
@ -1098,33 +1100,33 @@ rtiff_twobit_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *flg )
|
||||
static void
|
||||
rtiff_fourbit_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *flg )
|
||||
{
|
||||
int x, i, z;
|
||||
int minisblack =
|
||||
rtiff->header.photometric_interpretation == PHOTOMETRIC_MINISBLACK;
|
||||
VipsPel bits;
|
||||
int x, i, z;
|
||||
int minisblack =
|
||||
rtiff->header.photometric_interpretation == PHOTOMETRIC_MINISBLACK;
|
||||
VipsPel bits;
|
||||
|
||||
x = 0;
|
||||
x = 0;
|
||||
|
||||
for( i = 0; i < (n >> 1); i++ ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
for( i = 0; i < (n >> 1); i++ ) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
|
||||
for( z = 0; z < 2; z++ ) {
|
||||
/* The grey shade is the value two times concatenated */
|
||||
q[x] = (bits & 0xF0) | (bits >> 4);
|
||||
bits <<= 4;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
for( z = 0; z < 2; z++ ) {
|
||||
/* The grey shade is the value two times concatenated */
|
||||
q[x] = (bits & 0xF0) | (bits >> 4);
|
||||
bits <<= 4;
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do last byte in line.
|
||||
*/
|
||||
if( n & 1) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
for( z = 0; z < (n & 1) ; z++ ) {
|
||||
q[x + z] = (bits & 0xF0) | (bits >> 4);
|
||||
bits <<= 4;
|
||||
}
|
||||
}
|
||||
/* Do last byte in line.
|
||||
*/
|
||||
if( n & 1) {
|
||||
bits = (VipsPel) minisblack ? p[i] : ~p[i];
|
||||
for( z = 0; z < (n & 1) ; z++ ) {
|
||||
q[x + z] = (bits & 0xF0) | (bits >> 4);
|
||||
bits <<= 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -638,6 +638,8 @@ vips_foreign_save_tiff_buffer_init( VipsForeignSaveTiffBuffer *buffer )
|
||||
* In case @miniswhite is set to true this behavior is inverted.
|
||||
* In case of depth 4: values < 16 are written as black, and so on for the
|
||||
* lighter shades. In case @miniswhite is set to true this behavior is inverted.
|
||||
*
|
||||
* Set @bitdepth to 8 to squash 3-band float CIELAB images down to 8-bit CIELAB.
|
||||
*
|
||||
* Use @resunit to override the default resolution unit.
|
||||
* The default
|
||||
@ -703,7 +705,7 @@ vips_tiffsave( VipsImage *in, const char *filename, ... )
|
||||
* * @tile_height: %gint for tile size
|
||||
* * @pyramid: %gboolean, write an image pyramid
|
||||
* * @squash: %gboolean, squash 8-bit images down to 1 bit
|
||||
* * @bitdepth: %int, change bit depth to 1,2 or 4-bit
|
||||
* * @bitdepth: %int, change bit depth to 1,2 or 4-bit or squash float to 8 bit
|
||||
* * @miniswhite: %gboolean, write 1-bit images as MINISWHITE
|
||||
* * @resunit: #VipsForeignTiffResunit for resolution unit
|
||||
* * @xres: %gdouble horizontal resolution in pixels/mm
|
||||
|
@ -197,7 +197,7 @@
|
||||
* - add support for subifd pyramid layers
|
||||
* 8/6/20
|
||||
* - add bitdepth support for 2 and 4 bit greyscale images
|
||||
|
||||
*/
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
@ -1041,7 +1041,7 @@ ready_to_write( Wtiff *wtiff )
|
||||
|
||||
/* "squash" float LAB down to LABQ.
|
||||
*/
|
||||
if( wtiff->bitdepth == 1 &&
|
||||
if( (wtiff->bitdepth &&
|
||||
wtiff->input->Bands == 3 &&
|
||||
wtiff->input->BandFmt == VIPS_FORMAT_FLOAT &&
|
||||
wtiff->input->Type == VIPS_INTERPRETATION_LAB ) {
|
||||
@ -1201,11 +1201,9 @@ wtiff_new( VipsImage *input, const char *filename,
|
||||
/* Can only have byte fractional bit depths for 8 bit mono.
|
||||
* 3-band float should have been packed above.
|
||||
*/
|
||||
if( wtiff->bitdepth && (wtiff->bitdepth == 1 || wtiff->bitdepth == 2
|
||||
|| wtiff->bitdepth == 4 )
|
||||
&& !(wtiff->ready->Coding == VIPS_CODING_NONE &&
|
||||
wtiff->ready->BandFmt == VIPS_FORMAT_UCHAR &&
|
||||
wtiff->ready->Bands == 1) ) {
|
||||
if( wtiff->bitdepth && !(wtiff->ready->Coding == VIPS_CODING_NONE &&
|
||||
wtiff->ready->BandFmt == VIPS_FORMAT_UCHAR &&
|
||||
wtiff->ready->Bands == 1) ) {
|
||||
g_warning( "%s",
|
||||
( "can only set bitdepth for 1-band uchar and "
|
||||
"3-band float lab -- disabling bitdepth" ) );
|
||||
@ -1250,11 +1248,11 @@ wtiff_new( VipsImage *input, const char *filename,
|
||||
*/
|
||||
if( wtiff->ready->Coding == VIPS_CODING_LABQ )
|
||||
wtiff->tls = wtiff->tilew * 3;
|
||||
else if( wtiff->bitdepth == 1)
|
||||
else if( wtiff->bitdepth == 1 )
|
||||
wtiff->tls = VIPS_ROUND_UP( wtiff->tilew, 8 ) / 8;
|
||||
else if( wtiff->bitdepth == 2)
|
||||
else if( wtiff->bitdepth == 2 )
|
||||
wtiff->tls = VIPS_ROUND_UP( wtiff->tilew, 4 ) / 4;
|
||||
else if( wtiff->bitdepth == 4)
|
||||
else if( wtiff->bitdepth == 4 )
|
||||
wtiff->tls = VIPS_ROUND_UP( wtiff->tilew, 2 ) / 2;
|
||||
else
|
||||
wtiff->tls = VIPS_IMAGE_SIZEOF_PEL( wtiff->ready ) *
|
||||
@ -1322,28 +1320,17 @@ eightbit2twobit( Wtiff *wtiff, VipsPel *q, VipsPel *p, int n )
|
||||
{
|
||||
int x;
|
||||
VipsPel bits;
|
||||
VipsPel mask = wtiff->miniswhite ? 3 : 0;
|
||||
|
||||
bits = 0;
|
||||
if( !wtiff->miniswhite ) { //avoid unnecessary branches
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 2;
|
||||
bits |= p[x] >> 6;
|
||||
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 2;
|
||||
bits |= (p[x] >> 6) ^ mask;
|
||||
|
||||
if( (x & 0x3) == 0x3 ) {
|
||||
*q++ = bits;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 2;
|
||||
bits |= p[x] >> 6;
|
||||
|
||||
if( (x & 0x3) == 0x3 ) {
|
||||
*q++ = ~bits;
|
||||
bits = 0;
|
||||
}
|
||||
if( (x & 0x3) == 0x3 ) {
|
||||
*q++ = bits;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1360,30 +1347,19 @@ eightbit2fourbit( Wtiff *wtiff, VipsPel *q, VipsPel *p, int n )
|
||||
{
|
||||
int x;
|
||||
VipsPel bits;
|
||||
|
||||
VipsPel mask = wtiff->miniswhite ? 15 : 0;
|
||||
bits = 0;
|
||||
if( !wtiff->miniswhite ) { //avoid unnecessary branches
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 4;
|
||||
bits |= p[x] >> 4;
|
||||
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 4;
|
||||
bits |= (p[x] >> 4) ^ mask;
|
||||
|
||||
if( (x & 0x1) == 0x1 ) {
|
||||
*q++ = bits;
|
||||
bits = 0;
|
||||
}
|
||||
if( (x & 0x1) == 0x1 ) {
|
||||
*q++ = bits;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for( x = 0; x < n; x++ ) {
|
||||
bits <<= 4;
|
||||
bits |= p[x] >> 4;
|
||||
|
||||
if( (x & 0x1) == 0x1 ) {
|
||||
*q++ = ~bits;
|
||||
bits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Any left-over bits? Need to be left-aligned.
|
||||
*/
|
||||
if( (x & 0x1) != 0 )
|
||||
@ -1642,11 +1618,11 @@ wtiff_layer_write_strip( Wtiff *wtiff, Layer *layer, VipsRegion *strip )
|
||||
eightbit2onebit( wtiff, wtiff->tbuf, p, im->Xsize );
|
||||
p = wtiff->tbuf;
|
||||
}
|
||||
else if( wtiff->bitdepth == 2) {
|
||||
else if( wtiff->bitdepth == 2 ) {
|
||||
eightbit2twobit( wtiff, wtiff->tbuf, p, im->Xsize );
|
||||
p = wtiff->tbuf;
|
||||
}
|
||||
else if( wtiff->bitdepth == 4) {
|
||||
else if( wtiff->bitdepth == 4 ) {
|
||||
eightbit2fourbit( wtiff, wtiff->tbuf, p, im->Xsize );
|
||||
p = wtiff->tbuf;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user