mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
support floating-point tiff files
This commit is contained in:
parent
a726ccf303
commit
06b2e69a49
@ -213,11 +213,10 @@ read(PNMReader *reader) {
|
|||||||
// Description: Writes the PFM data to the indicated file, returning
|
// Description: Writes the PFM data to the indicated file, returning
|
||||||
// true on success, false on failure.
|
// true on success, false on failure.
|
||||||
//
|
//
|
||||||
// This can also handle writing a standard image file
|
// If the type implied by the filename extension
|
||||||
// supported by PNMImage, if the filename extension is
|
// supports floating-point, the data will be written
|
||||||
// some image type's extension other than "pfm"; it
|
// directly; otherwise, the floating-point data will be
|
||||||
// will be quietly converted to the appropriate integer
|
// quietly converted to the appropriate integer type.
|
||||||
// type.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool PfmFile::
|
bool PfmFile::
|
||||||
write(const Filename &fullpath) {
|
write(const Filename &fullpath) {
|
||||||
@ -234,21 +233,6 @@ write(const Filename &fullpath) {
|
|||||||
<< "Unable to open " << filename << "\n";
|
<< "Unable to open " << filename << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string extension = downcase(fullpath.get_extension());
|
|
||||||
if (extension != "pfm") {
|
|
||||||
// Maybe we're trying to write a different kind of image file.
|
|
||||||
PNMImage pnm;
|
|
||||||
PNMWriter *writer = pnm.make_writer(&out, false, fullpath, NULL);
|
|
||||||
if (writer != (PNMWriter *)NULL) {
|
|
||||||
// Yep.
|
|
||||||
if (store(pnm)) {
|
|
||||||
return pnm.write(writer);
|
|
||||||
}
|
|
||||||
// Couldn't make an image. Carry on directly.
|
|
||||||
delete writer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pnmimage_cat.is_debug()) {
|
if (pnmimage_cat.is_debug()) {
|
||||||
pnmimage_cat.debug()
|
pnmimage_cat.debug()
|
||||||
|
@ -165,6 +165,8 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_maxval = PGM_MAXMAXVAL;
|
||||||
|
|
||||||
(*_file) >> _x_size >> _y_size >> _scale;
|
(*_file) >> _x_size >> _y_size >> _scale;
|
||||||
if (!(*_file)) {
|
if (!(*_file)) {
|
||||||
pnmimage_cat.debug()
|
pnmimage_cat.debug()
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "pnmFileTypeRegistry.h"
|
#include "pnmFileTypeRegistry.h"
|
||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
#include "ppmcmap.h"
|
#include "ppmcmap.h"
|
||||||
|
#include "pfmFile.h"
|
||||||
|
|
||||||
// Tiff will want to re-typedef these things.
|
// Tiff will want to re-typedef these things.
|
||||||
#define int8 tiff_int8
|
#define int8 tiff_int8
|
||||||
@ -76,9 +77,6 @@ short tiff_predictor = 0;
|
|||||||
/* 0, 1, or 2; meaningful when tiff_compression == COMPRESSION_LZW. */
|
/* 0, 1, or 2; meaningful when tiff_compression == COMPRESSION_LZW. */
|
||||||
|
|
||||||
|
|
||||||
long tiff_rowsperstrip = 0;
|
|
||||||
/* 0 or any positive number */
|
|
||||||
|
|
||||||
#ifndef PHOTOMETRIC_DEPTH
|
#ifndef PHOTOMETRIC_DEPTH
|
||||||
#define PHOTOMETRIC_DEPTH 32768
|
#define PHOTOMETRIC_DEPTH 32768
|
||||||
#endif
|
#endif
|
||||||
@ -369,6 +367,8 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_is_valid) {
|
if (_is_valid) {
|
||||||
|
if ( ! TIFFGetField( tif, TIFFTAG_SAMPLEFORMAT, &sample_format ) )
|
||||||
|
sample_format = SAMPLEFORMAT_UINT;
|
||||||
if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
|
if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
|
||||||
bps = 1;
|
bps = 1;
|
||||||
if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
|
if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
|
||||||
@ -378,6 +378,20 @@ Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number) :
|
|||||||
pnmimage_tiff_cat.error()
|
pnmimage_tiff_cat.error()
|
||||||
<< "Error getting photometric from TIFF file.\n";
|
<< "Error getting photometric from TIFF file.\n";
|
||||||
_is_valid = false;
|
_is_valid = false;
|
||||||
|
|
||||||
|
} else if (sample_format == SAMPLEFORMAT_IEEEFP) {
|
||||||
|
// Floating-point TIFF. We only accept 32-bit floats.
|
||||||
|
if (bps != 32) {
|
||||||
|
pnmimage_tiff_cat.error()
|
||||||
|
<< "Can only read 32-bit float TIFF files, not " << bps << "-bit.\n";
|
||||||
|
_is_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (sample_format != SAMPLEFORMAT_UINT) {
|
||||||
|
// Can't understand other kinds of sample formats.
|
||||||
|
pnmimage_tiff_cat.error()
|
||||||
|
<< "Can't understand sample format\n";
|
||||||
|
_is_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,6 +579,54 @@ PNMFileTypeTIFF::Reader::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMFileTypeTIFF::Reader::is_floating_point
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if this PNMFileType represents a
|
||||||
|
// floating-point image type, false if it is a normal,
|
||||||
|
// integer type. If this returns true, read_pfm() is
|
||||||
|
// implemented instead of read_data().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PNMFileTypeTIFF::Reader::
|
||||||
|
is_floating_point() {
|
||||||
|
return sample_format = SAMPLEFORMAT_IEEEFP;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMFileTypeTIFF::Reader::read_pfm
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Reads floating-point data directly into the indicated
|
||||||
|
// PfmFile. Returns true on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PNMFileTypeTIFF::Reader::
|
||||||
|
read_pfm(PfmFile &pfm) {
|
||||||
|
if (!is_valid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x_size = get_x_size();
|
||||||
|
int y_size = get_y_size();
|
||||||
|
int num_channels = get_num_channels();
|
||||||
|
|
||||||
|
pfm.clear(x_size, y_size, num_channels);
|
||||||
|
vector_float table;
|
||||||
|
pfm.swap_table(table);
|
||||||
|
|
||||||
|
for (int yi = 0; yi < y_size; ++yi) {
|
||||||
|
float *row = &table[(yi * x_size) * _num_channels];
|
||||||
|
|
||||||
|
if (TIFFReadScanline(tif, row, yi, 0 ) < 0 ) {
|
||||||
|
pnmimage_tiff_cat.error()
|
||||||
|
<< "failed a scanline read on row " << yi << "\n";
|
||||||
|
pfm.swap_table(table);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pfm.swap_table(table);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PNMFileTypeTIFF::Reader::supports_read_row
|
// Function: PNMFileTypeTIFF::Reader::supports_read_row
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -855,6 +917,91 @@ Writer(PNMFileType *type, ostream *file, bool owns_file) :
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMFileTypeTIFF::Writer::supports_floating_point
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if this PNMFileType can accept a
|
||||||
|
// floating-point image type, false if it can only
|
||||||
|
// accept a normal, integer type. If this returns true,
|
||||||
|
// write_pfm() is implemented.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PNMFileTypeTIFF::Writer::
|
||||||
|
supports_floating_point() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMFileTypeTIFF::Writer::supports_integer
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Returns true if this PNMFileType can accept an
|
||||||
|
// integer image type, false if it can only
|
||||||
|
// accept a floating-point type. If this returns true,
|
||||||
|
// write_data() or write_row() is implemented.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PNMFileTypeTIFF::Writer::
|
||||||
|
supports_integer() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: PNMFileTypeTIFF::Writer::write_pfm
|
||||||
|
// Access: Public, Virtual
|
||||||
|
// Description: Writes floating-point data from the indicated
|
||||||
|
// PfmFile. Returns true on success, false on failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool PNMFileTypeTIFF::Writer::
|
||||||
|
write_pfm(const PfmFile &pfm) {
|
||||||
|
struct tiff *tif;
|
||||||
|
|
||||||
|
// Open output file.
|
||||||
|
tif = TIFFClientOpen("TIFF file", "w",
|
||||||
|
(thandle_t) _file,
|
||||||
|
ostream_dont_read, ostream_write,
|
||||||
|
(TIFFSeekProc)ostream_seek,
|
||||||
|
iostream_dont_close, ostream_size,
|
||||||
|
iostream_map, iostream_unmap);
|
||||||
|
if (tif == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int x_size = pfm.get_x_size();
|
||||||
|
int y_size = pfm.get_y_size();
|
||||||
|
int num_channels = pfm.get_num_channels();
|
||||||
|
|
||||||
|
int photometric = 0;
|
||||||
|
if (num_channels >= 3) {
|
||||||
|
photometric = PHOTOMETRIC_RGB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set TIFF parameters.
|
||||||
|
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, x_size);
|
||||||
|
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, y_size);
|
||||||
|
TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
|
||||||
|
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
|
||||||
|
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
||||||
|
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
|
||||||
|
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
|
||||||
|
TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, "Generated via pnmimage.\n" );
|
||||||
|
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, num_channels);
|
||||||
|
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
||||||
|
|
||||||
|
const vector_float &table = pfm.get_table();
|
||||||
|
for (int yi = 0; yi < y_size; ++yi) {
|
||||||
|
const float *row = &table[(yi * x_size) * _num_channels];
|
||||||
|
|
||||||
|
if (TIFFWriteScanline(tif, (tdata_t)row, yi, 0 ) < 0) {
|
||||||
|
pnmimage_tiff_cat.error()
|
||||||
|
<< "failed a scanline write on row " << yi << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TIFFFlushData(tif);
|
||||||
|
TIFFClose(tif);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: PNMFileTypeTIFF::Writer::write_data
|
// Function: PNMFileTypeTIFF::Writer::write_data
|
||||||
// Access: Public, Virtual
|
// Access: Public, Virtual
|
||||||
@ -992,8 +1139,6 @@ write_data(xel *array, xelval *alpha) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( tiff_rowsperstrip == 0 )
|
|
||||||
tiff_rowsperstrip = ( 8 * 1024 ) / bytesperrow;
|
|
||||||
buf = (unsigned char*) malloc( bytesperrow );
|
buf = (unsigned char*) malloc( bytesperrow );
|
||||||
if ( buf == (unsigned char*) 0 ) {
|
if ( buf == (unsigned char*) 0 ) {
|
||||||
pnmimage_tiff_cat.error()
|
pnmimage_tiff_cat.error()
|
||||||
@ -1004,6 +1149,7 @@ write_data(xel *array, xelval *alpha) {
|
|||||||
/* Set TIFF parameters. */
|
/* Set TIFF parameters. */
|
||||||
TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, _x_size );
|
TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, _x_size );
|
||||||
TIFFSetField( tif, TIFFTAG_IMAGELENGTH, _y_size );
|
TIFFSetField( tif, TIFFTAG_IMAGELENGTH, _y_size );
|
||||||
|
TIFFSetField( tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT );
|
||||||
TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, bitspersample );
|
TIFFSetField( tif, TIFFTAG_BITSPERSAMPLE, bitspersample );
|
||||||
TIFFSetField( tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
|
TIFFSetField( tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT );
|
||||||
TIFFSetField( tif, TIFFTAG_COMPRESSION, tiff_compression );
|
TIFFSetField( tif, TIFFTAG_COMPRESSION, tiff_compression );
|
||||||
@ -1020,8 +1166,6 @@ write_data(xel *array, xelval *alpha) {
|
|||||||
if (has_alpha()) {
|
if (has_alpha()) {
|
||||||
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
|
TIFFSetField(tif, TIFFTAG_EXTRASAMPLES, 1, extra_samples);
|
||||||
}
|
}
|
||||||
TIFFSetField( tif, TIFFTAG_ROWSPERSTRIP, tiff_rowsperstrip );
|
|
||||||
/* TIFFSetField( tif, TIFFTAG_STRIPBYTECOUNTS, _y_size / tiff_rowsperstrip ); */
|
|
||||||
TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
|
TIFFSetField( tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG );
|
||||||
|
|
||||||
if ( chv == (colorhist_vector) 0 ) {
|
if ( chv == (colorhist_vector) 0 ) {
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number);
|
Reader(PNMFileType *type, istream *file, bool owns_file, string magic_number);
|
||||||
virtual ~Reader();
|
virtual ~Reader();
|
||||||
|
|
||||||
|
virtual bool is_floating_point();
|
||||||
|
virtual bool read_pfm(PfmFile &pfm);
|
||||||
virtual bool supports_read_row() const;
|
virtual bool supports_read_row() const;
|
||||||
virtual bool read_row(xel *array, xelval *alpha, int x_size, int y_size);
|
virtual bool read_row(xel *array, xelval *alpha, int x_size, int y_size);
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ public:
|
|||||||
xelval next_sample_32(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;
|
xelval next_sample_general(unsigned char *&buf_ptr, int &bits_left) const;
|
||||||
|
|
||||||
|
unsigned short sample_format;
|
||||||
unsigned short photomet;
|
unsigned short photomet;
|
||||||
unsigned short bps, spp;
|
unsigned short bps, spp;
|
||||||
unsigned short unassoc_alpha_sample, assoc_alpha_sample;
|
unsigned short unassoc_alpha_sample, assoc_alpha_sample;
|
||||||
@ -78,6 +81,9 @@ public:
|
|||||||
public:
|
public:
|
||||||
Writer(PNMFileType *type, ostream *file, bool owns_file);
|
Writer(PNMFileType *type, ostream *file, bool owns_file);
|
||||||
|
|
||||||
|
virtual bool supports_floating_point();
|
||||||
|
virtual bool supports_integer();
|
||||||
|
virtual bool write_pfm(const PfmFile &pfm);
|
||||||
virtual int write_data(xel *array, xelval *alpha);
|
virtual int write_data(xel *array, xelval *alpha);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user