mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
16-bit-per-sample tiff files
This commit is contained in:
parent
544e8dbc90
commit
995ce8b11a
@ -268,7 +268,8 @@ BMPwriterow(
|
||||
unsigned long cx,
|
||||
unsigned short bpp,
|
||||
int indexed,
|
||||
colorhash_table cht)
|
||||
colorhash_table cht,
|
||||
xelval maxval)
|
||||
{
|
||||
BITSTREAM b;
|
||||
unsigned nbyte = 0;
|
||||
@ -299,9 +300,9 @@ BMPwriterow(
|
||||
|
||||
for (x = 0; x < cx; x++, row++)
|
||||
{
|
||||
PutByte(fp, PPM_GETB(*row));
|
||||
PutByte(fp, PPM_GETG(*row));
|
||||
PutByte(fp, PPM_GETR(*row));
|
||||
PutByte(fp, PPM_GETB(*row) * 255 / maxval);
|
||||
PutByte(fp, PPM_GETG(*row) * 255 / maxval);
|
||||
PutByte(fp, PPM_GETR(*row) * 255 / maxval);
|
||||
nbyte += 3;
|
||||
}
|
||||
}
|
||||
@ -329,7 +330,8 @@ BMPwritebits(
|
||||
unsigned short cBitCount,
|
||||
pixel **pixels,
|
||||
int indexed,
|
||||
colorhash_table cht)
|
||||
colorhash_table cht,
|
||||
xelval maxval)
|
||||
{
|
||||
int nbyte = 0;
|
||||
long y;
|
||||
@ -347,7 +349,8 @@ BMPwritebits(
|
||||
for (y = (long)cy - 1; y >= 0; y--)
|
||||
{
|
||||
int rc;
|
||||
rc = BMPwriterow(fp, pixels[y], cx, cBitCount, indexed, cht);
|
||||
rc = BMPwriterow(fp, pixels[y], cx, cBitCount, indexed, cht,
|
||||
maxval);
|
||||
|
||||
if(rc == -1)
|
||||
{
|
||||
@ -460,7 +463,7 @@ BMPEncode(
|
||||
pm_error(er_internal, "BMPEncode");
|
||||
}
|
||||
|
||||
nbyte += BMPwritebits(fp, x, y, bpp, pixels, true, cht);
|
||||
nbyte += BMPwritebits(fp, x, y, bpp, pixels, true, cht, 255);
|
||||
if(nbyte != BMPlenfile(classv, bpp, x, y))
|
||||
{
|
||||
pm_error(er_internal, "BMPEncode");
|
||||
@ -476,7 +479,8 @@ BMPEncode24(
|
||||
int classv,
|
||||
int x,
|
||||
int y,
|
||||
pixel **pixels)
|
||||
pixel **pixels,
|
||||
xelval maxval)
|
||||
{
|
||||
unsigned long nbyte = 0;
|
||||
int bpp = 24;
|
||||
@ -493,7 +497,8 @@ BMPEncode24(
|
||||
pm_error(er_internal, "BMPEncode24");
|
||||
}
|
||||
|
||||
nbyte += BMPwritebits(fp, x, y, bpp, pixels, false, colorhash_table());
|
||||
nbyte += BMPwritebits(fp, x, y, bpp, pixels, false, colorhash_table(),
|
||||
maxval);
|
||||
if(nbyte != BMPlenfile(classv, bpp, x, y))
|
||||
{
|
||||
pm_error(er_internal, "BMPEncode24");
|
||||
@ -582,7 +587,7 @@ write_data(xel *array, xelval *) {
|
||||
chv = ppm_computecolorhist(pixels, _x_size, _y_size, MAXCOLORS, &colors);
|
||||
if (bmp_bpp > 8) {
|
||||
// Quietly generate a 24-bit image.
|
||||
BMPEncode24(_file, classv, _x_size, _y_size, pixels);
|
||||
BMPEncode24(_file, classv, _x_size, _y_size, pixels, _maxval);
|
||||
|
||||
} else if (chv == (colorhist_vector) 0) {
|
||||
if (bmp_bpp != 0) {
|
||||
@ -591,7 +596,7 @@ write_data(xel *array, xelval *) {
|
||||
<< "too many colors for " << bmp_bpp << "-bit image.\n";
|
||||
}
|
||||
|
||||
BMPEncode24(_file, classv, _x_size, _y_size, pixels);
|
||||
BMPEncode24(_file, classv, _x_size, _y_size, pixels, _maxval);
|
||||
|
||||
} else {
|
||||
pnmimage_bmp_cat.debug()
|
||||
|
@ -582,17 +582,6 @@ supports_read_row() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define NEXTSAMPLE \
|
||||
{ \
|
||||
if ( bitsleft == 0 ) \
|
||||
{ \
|
||||
++inP; \
|
||||
bitsleft = 8; \
|
||||
} \
|
||||
bitsleft -= bps; \
|
||||
sample = ( *inP >> bitsleft ) & _maxval; \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::read_row
|
||||
// Access: Public, Virtual
|
||||
@ -608,7 +597,9 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char *buf = (unsigned char*) alloca((size_t)TIFFScanlineSize(tif));
|
||||
size_t scanline_size = (size_t)TIFFScanlineSize(tif);
|
||||
unsigned char *buf = (unsigned char*) alloca(scanline_size);
|
||||
|
||||
int col;
|
||||
xelval gray, sample;
|
||||
xelval r, g, b;
|
||||
@ -619,19 +610,42 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char *inP = buf;
|
||||
unsigned char *buf_ptr = buf;
|
||||
unsigned s;
|
||||
int bitsleft = 8;
|
||||
int bits_left = 8;
|
||||
|
||||
// Get a pointer to a function that extracts the next bps-bit sample
|
||||
// from the bitarray. There are a handful of different functions,
|
||||
// which are optimized for different values of bps.
|
||||
xelval (PNMFileTypeTIFF::Reader::*next_sample)(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
|
||||
if (bps < 8) {
|
||||
next_sample = &PNMFileTypeTIFF::Reader::next_sample_lt_8;
|
||||
|
||||
} else if (bps == 8) {
|
||||
next_sample = &PNMFileTypeTIFF::Reader::next_sample_8;
|
||||
|
||||
} else if (bps == 16) {
|
||||
next_sample = &PNMFileTypeTIFF::Reader::next_sample_16;
|
||||
|
||||
} else if (bps == 32) {
|
||||
// Actually, it's not likely that a 32-bit sample will fit within
|
||||
// a xelval. Deal with this when we come to it.
|
||||
next_sample = &PNMFileTypeTIFF::Reader::next_sample_32;
|
||||
|
||||
} else {
|
||||
next_sample = &PNMFileTypeTIFF::Reader::next_sample_general;
|
||||
}
|
||||
|
||||
switch ( photomet ) {
|
||||
case PHOTOMETRIC_MINISBLACK:
|
||||
for ( col = 0; col < _x_size; ++col )
|
||||
{
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
gray = sample;
|
||||
|
||||
for (s = 1; s < spp; s++) {
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
if (s == unassoc_alpha_sample) {
|
||||
alpha_data[col] = sample;
|
||||
|
||||
@ -649,10 +663,10 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
case PHOTOMETRIC_MINISWHITE:
|
||||
for ( col = 0; col < _x_size; ++col )
|
||||
{
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
gray = _maxval - sample;
|
||||
for (s = 1; s < spp; s++) {
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
sample = _maxval - sample;
|
||||
|
||||
if (s == unassoc_alpha_sample) {
|
||||
@ -673,11 +687,11 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
case PHOTOMETRIC_PALETTE:
|
||||
for ( col = 0; col < _x_size; ++col )
|
||||
{
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
row_data[col] = colormap[sample];
|
||||
|
||||
for (s = 1; s < spp; s++) {
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
if (s == unassoc_alpha_sample) {
|
||||
alpha_data[col] = sample;
|
||||
|
||||
@ -699,15 +713,15 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
|
||||
case PHOTOMETRIC_RGB:
|
||||
for ( col = 0; col < _x_size; ++col ) {
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
r = sample;
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
g = sample;
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
b = sample;
|
||||
|
||||
for (s = 3; s < spp; s++) {
|
||||
NEXTSAMPLE;
|
||||
sample = (this->*next_sample)(buf_ptr, bits_left);
|
||||
if (s == unassoc_alpha_sample) {
|
||||
alpha_data[col] = sample;
|
||||
|
||||
@ -731,10 +745,106 @@ read_row(xel *row_data, xelval *alpha_data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nassertr(buf_ptr <= buf + scanline_size, false);
|
||||
|
||||
current_row++;
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::next_sample_lt_8
|
||||
// Access: Private
|
||||
// Description: Returns the next color sample from the row, when it
|
||||
// is known that bps < 8.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
xelval PNMFileTypeTIFF::Reader::
|
||||
next_sample_lt_8(unsigned char *&buf_ptr, int &bits_left) const {
|
||||
if (bits_left == 0) {
|
||||
++buf_ptr;
|
||||
bits_left = 8;
|
||||
}
|
||||
|
||||
bits_left -= bps;
|
||||
return (*buf_ptr >> bits_left) & _maxval;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::next_sample_8
|
||||
// Access: Private
|
||||
// Description: Returns the next color sample from the row, when it
|
||||
// is known that bps == 8.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
xelval PNMFileTypeTIFF::Reader::
|
||||
next_sample_8(unsigned char *&buf_ptr, int &bits_left) const {
|
||||
return *buf_ptr++;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::next_sample_16
|
||||
// Access: Private
|
||||
// Description: Returns the next color sample from the row, when it
|
||||
// is known that bps == 16.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
xelval PNMFileTypeTIFF::Reader::
|
||||
next_sample_16(unsigned char *&buf_ptr, int &bits_left) const {
|
||||
// The TIFF library has already byte-swapped the values if
|
||||
// necessary. Thus, we only need to treat it as an array of shorts.
|
||||
unsigned short result = *(unsigned short *)buf_ptr;
|
||||
buf_ptr += 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::next_sample_32
|
||||
// Access: Private
|
||||
// Description: Returns the next color sample from the row, when it
|
||||
// is known that bps == 32.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
xelval PNMFileTypeTIFF::Reader::
|
||||
next_sample_32(unsigned char *&buf_ptr, int &bits_left) const {
|
||||
// The TIFF library has already byte-swapped the values if
|
||||
// necessary. Thus, we only need to treat it as an array of longs.
|
||||
unsigned long result = *(unsigned long *)buf_ptr;
|
||||
buf_ptr += 2;
|
||||
return (xelval)result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Reader::next_sample_general
|
||||
// Access: Private
|
||||
// Description: Returns the next color sample from the row, in
|
||||
// general. This unpacks an arbitrary string of bits
|
||||
// from the sequence.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
xelval PNMFileTypeTIFF::Reader::
|
||||
next_sample_general(unsigned char *&buf_ptr, int &bits_left) const {
|
||||
unsigned int result = 0;
|
||||
int bits_needed = bps;
|
||||
|
||||
while (bits_needed > 0) {
|
||||
nassertr(bits_left >= 0, 0);
|
||||
if (bits_left == 0) {
|
||||
++buf_ptr;
|
||||
bits_left = 8;
|
||||
}
|
||||
|
||||
if (bits_needed <= bits_left) {
|
||||
bits_left -= bits_needed;
|
||||
unsigned int mask = (1 << bits_needed) - 1;
|
||||
result |= ((*buf_ptr) >> bits_left) & mask;
|
||||
bits_needed = 0;
|
||||
|
||||
} else {
|
||||
bits_needed -= bits_left;
|
||||
unsigned int mask = (1 << bits_left) - 1;
|
||||
result |= ((*buf_ptr) & mask) << bits_needed;
|
||||
bits_left = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PNMFileTypeTIFF::Writer::Constructor
|
||||
|
@ -63,6 +63,12 @@ public:
|
||||
virtual bool read_row(xel *array, xelval *alpha);
|
||||
|
||||
private:
|
||||
xelval next_sample_lt_8(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
xelval next_sample_8(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
xelval next_sample_16(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
xelval next_sample_32(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
xelval next_sample_general(unsigned char *&buf_ptr, int &bits_left) const;
|
||||
|
||||
unsigned short photomet;
|
||||
unsigned short bps, spp;
|
||||
unsigned short unassoc_alpha_sample, assoc_alpha_sample;
|
||||
|
Loading…
x
Reference in New Issue
Block a user