mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 17:35:34 -04:00
robustify tiff alpha channel support a tiny bit
This commit is contained in:
parent
6956d642d2
commit
470ad797ae
@ -384,11 +384,48 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_is_valid) {
|
if (_is_valid) {
|
||||||
if (spp >= 1 && spp <= 4) {
|
unsigned short num_extra_samples;
|
||||||
_num_channels = spp;
|
unsigned short *extra_samples = NULL;
|
||||||
|
|
||||||
|
if (!TIFFGetField(tif, TIFFTAG_EXTRASAMPLES, &num_extra_samples,
|
||||||
|
&extra_samples)) {
|
||||||
|
num_extra_samples = 0;
|
||||||
|
}
|
||||||
|
_num_channels = spp - num_extra_samples;
|
||||||
|
unassoc_alpha_sample = 0;
|
||||||
|
assoc_alpha_sample = 0;
|
||||||
|
|
||||||
|
if (_num_channels == 1 || _num_channels == 3) {
|
||||||
|
// Look for an alpha channel in one of the extra samples, if
|
||||||
|
// any.
|
||||||
|
bool got_alpha = false;
|
||||||
|
for (unsigned short s = 0; s < num_extra_samples && !got_alpha; s++) {
|
||||||
|
if (extra_samples[s] == EXTRASAMPLE_UNASSALPHA) {
|
||||||
|
unassoc_alpha_sample = s + _num_channels;
|
||||||
|
_num_channels++;
|
||||||
|
got_alpha = true;
|
||||||
|
|
||||||
|
} else if (extra_samples[s] == EXTRASAMPLE_ASSOCALPHA) {
|
||||||
|
assoc_alpha_sample = s + _num_channels;
|
||||||
|
_num_channels++;
|
||||||
|
got_alpha = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unfortunately, Photoshop seems to write
|
||||||
|
// EXTRASAMPLE_UNSPECIFIED into the EXTRASAMPLES field for its
|
||||||
|
// alpha channels. If we have exactly one extra channel and
|
||||||
|
// it's an UNSPECIFIED channel, assume it's meant to be alpha.
|
||||||
|
if (!got_alpha && num_extra_samples == 1 &&
|
||||||
|
extra_samples[0] == EXTRASAMPLE_UNSPECIFIED) {
|
||||||
|
unassoc_alpha_sample = _num_channels;
|
||||||
|
_num_channels++;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
pnmimage_tiff_cat.error()
|
pnmimage_tiff_cat.error()
|
||||||
<< "Cannot handle " << spp << "-channel image.\n";
|
<< "Cannot handle " << spp << "-color image (with "
|
||||||
|
<< num_extra_samples << " extra channels).\n";
|
||||||
_is_valid = false;
|
_is_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,7 +441,7 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
_maxval = ( 1 << bps ) - 1;
|
_maxval = ( 1 << bps ) - 1;
|
||||||
if ( _maxval == 1 && spp == 1 ) {
|
if ( _maxval == 1 && _num_channels == 1 ) {
|
||||||
if (pnmimage_tiff_cat.is_debug()) {
|
if (pnmimage_tiff_cat.is_debug()) {
|
||||||
pnmimage_tiff_cat.debug(false)
|
pnmimage_tiff_cat.debug(false)
|
||||||
<< "monochrome\n";
|
<< "monochrome\n";
|
||||||
@ -561,7 +598,8 @@ read_row(xel *row_data, xelval *alpha_data) {
|
|||||||
|
|
||||||
unsigned char *buf = (unsigned char*) alloca((size_t)TIFFScanlineSize(tif));
|
unsigned char *buf = (unsigned char*) alloca((size_t)TIFFScanlineSize(tif));
|
||||||
int col;
|
int col;
|
||||||
unsigned char sample;
|
xelval gray, sample;
|
||||||
|
xelval r, g, b;
|
||||||
|
|
||||||
if ( TIFFReadScanline( tif, buf, current_row, 0 ) < 0 ) {
|
if ( TIFFReadScanline( tif, buf, current_row, 0 ) < 0 ) {
|
||||||
pnmimage_tiff_cat.error()
|
pnmimage_tiff_cat.error()
|
||||||
@ -570,6 +608,7 @@ read_row(xel *row_data, xelval *alpha_data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *inP = buf;
|
unsigned char *inP = buf;
|
||||||
|
unsigned s;
|
||||||
int bitsleft = 8;
|
int bitsleft = 8;
|
||||||
|
|
||||||
switch ( photomet ) {
|
switch ( photomet ) {
|
||||||
@ -577,11 +616,21 @@ read_row(xel *row_data, xelval *alpha_data) {
|
|||||||
for ( col = 0; col < _x_size; ++col )
|
for ( col = 0; col < _x_size; ++col )
|
||||||
{
|
{
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
PPM_PUTB(row_data[col], sample);
|
gray = sample;
|
||||||
if ( spp == 2 ) {
|
|
||||||
NEXTSAMPLE; // Alpha channel
|
for (s = 1; s < spp; s++) {
|
||||||
alpha_data[col] = sample;
|
NEXTSAMPLE;
|
||||||
|
if (s == unassoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
|
||||||
|
} else if (s == assoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
if (sample != 0) {
|
||||||
|
gray = (xelval)((float)gray * _maxval / (float)sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
PPM_PUTB(row_data[col], gray);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -589,12 +638,23 @@ read_row(xel *row_data, xelval *alpha_data) {
|
|||||||
for ( col = 0; col < _x_size; ++col )
|
for ( col = 0; col < _x_size; ++col )
|
||||||
{
|
{
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
sample = _maxval - sample;
|
gray = _maxval - sample;
|
||||||
PPM_PUTB(row_data[col], sample);
|
for (s = 1; s < spp; s++) {
|
||||||
if ( spp == 2 ) {
|
NEXTSAMPLE;
|
||||||
NEXTSAMPLE; // Alpha channel
|
sample = _maxval - sample;
|
||||||
alpha_data[col] = sample;
|
|
||||||
|
if (s == unassoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
|
||||||
|
} else if (s == assoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
if (sample != 0) {
|
||||||
|
gray = (xelval)((float)gray * _maxval / (float)sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PPM_PUTB(row_data[col], gray);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -603,28 +663,53 @@ read_row(xel *row_data, xelval *alpha_data) {
|
|||||||
{
|
{
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
row_data[col] = colormap[sample];
|
row_data[col] = colormap[sample];
|
||||||
if ( spp == 2 ) {
|
|
||||||
NEXTSAMPLE; // Alpha channel
|
for (s = 1; s < spp; s++) {
|
||||||
alpha_data[col] = sample;
|
NEXTSAMPLE;
|
||||||
|
if (s == unassoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
|
||||||
|
} else if (s == assoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
if (sample != 0) {
|
||||||
|
r = PPM_GETR(row_data[col]);
|
||||||
|
g = PPM_GETG(row_data[col]);
|
||||||
|
b = PPM_GETB(row_data[col]);
|
||||||
|
r = (xelval)((float)r * _maxval / (float)sample);
|
||||||
|
g = (xelval)((float)g * _maxval / (float)sample);
|
||||||
|
b = (xelval)((float)b * _maxval / (float)sample);
|
||||||
|
PPM_ASSIGN(row_data[col], r, g, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PHOTOMETRIC_RGB:
|
case PHOTOMETRIC_RGB:
|
||||||
for ( col = 0; col < _x_size; ++col ) {
|
for ( col = 0; col < _x_size; ++col ) {
|
||||||
xelval r, g, b;
|
|
||||||
|
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
r = sample;
|
r = sample;
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
g = sample;
|
g = sample;
|
||||||
NEXTSAMPLE;
|
NEXTSAMPLE;
|
||||||
b = sample;
|
b = sample;
|
||||||
PPM_ASSIGN(row_data[col], r, g, b);
|
|
||||||
if ( spp == 4 ) {
|
for (s = 3; s < spp; s++) {
|
||||||
NEXTSAMPLE; // Alpha channel
|
NEXTSAMPLE;
|
||||||
alpha_data[col] = sample;
|
if (s == unassoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
|
||||||
|
} else if (s == assoc_alpha_sample) {
|
||||||
|
alpha_data[col] = sample;
|
||||||
|
if (sample != 0) {
|
||||||
|
r = (xelval)((float)r * _maxval / (float)sample);
|
||||||
|
g = (xelval)((float)g * _maxval / (float)sample);
|
||||||
|
b = (xelval)((float)b * _maxval / (float)sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PPM_ASSIGN(row_data[col], r, g, b);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
unsigned short photomet;
|
unsigned short photomet;
|
||||||
unsigned short bps, spp;
|
unsigned short bps, spp;
|
||||||
|
unsigned short unassoc_alpha_sample, assoc_alpha_sample;
|
||||||
xel colormap[TIFF_COLORMAP_MAXCOLORS];
|
xel colormap[TIFF_COLORMAP_MAXCOLORS];
|
||||||
|
|
||||||
int current_row;
|
int current_row;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user