work in progress: start enhancing tiff reader to handle bits per sample

This commit is contained in:
Dane Springmeyer 2014-12-03 18:37:27 -05:00
parent 2f0e236bc0
commit f82d57f497

View file

@ -132,6 +132,10 @@ private:
tiff_ptr tif_; tiff_ptr tif_;
bool premultiplied_alpha_; bool premultiplied_alpha_;
bool has_alpha_; bool has_alpha_;
unsigned bps_;
unsigned photometric_;
unsigned bands_;
public: public:
enum TiffType { enum TiffType {
generic=1, generic=1,
@ -186,7 +190,10 @@ tiff_reader<T>::tiff_reader(std::string const& file_name)
tile_width_(0), tile_width_(0),
tile_height_(0), tile_height_(0),
premultiplied_alpha_(false), premultiplied_alpha_(false),
has_alpha_(false) has_alpha_(false),
bps_(0),
photometric_(0),
bands_(1)
{ {
if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ file_name); if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ file_name);
init(); init();
@ -203,7 +210,10 @@ tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
tile_width_(0), tile_width_(0),
tile_height_(0), tile_height_(0),
premultiplied_alpha_(false), premultiplied_alpha_(false),
has_alpha_(false) has_alpha_(false),
bps_(0),
photometric_(0),
bands_(1)
{ {
if (!stream_) throw image_reader_exception("TIFF reader: cannot open image stream "); if (!stream_) throw image_reader_exception("TIFF reader: cannot open image stream ");
stream_.seekg(0, std::ios::beg); stream_.seekg(0, std::ios::beg);
@ -221,39 +231,51 @@ void tiff_reader<T>::init()
if (!tif) throw image_reader_exception("Can't open tiff file"); if (!tif) throw image_reader_exception("Can't open tiff file");
char msg[1024]; TIFFGetField(tif,TIFFTAG_BITSPERSAMPLE,&bps_);
TIFFGetField(tif,TIFFTAG_PHOTOMETRIC,&photometric_);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &bands_);
if (TIFFRGBAImageOK(tif,msg)) MAPNIK_LOG_DEBUG(tiff_reader) << "bits per sample: " << bps_;
MAPNIK_LOG_DEBUG(tiff_reader) << "photometric: " << photometric_;
MAPNIK_LOG_DEBUG(tiff_reader) << "bands: " << bands_;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width_);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height_);
if (bps_ <= 8)
{ {
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width_); char msg[1024];
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height_); if (TIFFRGBAImageOK(tif,msg))
if (TIFFIsTiled(tif))
{ {
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width_); if (TIFFIsTiled(tif))
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height_);
read_method_=tiled;
}
else if (TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rows_per_strip_)!=0)
{
read_method_=stripped;
}
//TIFFTAG_EXTRASAMPLES
uint16 extrasamples = 0;
uint16* sampleinfo = nullptr;
if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
&extrasamples, &sampleinfo))
{
has_alpha_ = true;
if (extrasamples == 1 &&
sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA)
{ {
premultiplied_alpha_ = true; TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width_);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tile_height_);
MAPNIK_LOG_DEBUG(tiff_reader) << "reading tiled tiff";
read_method_=tiled;
}
else if (TIFFGetField(tif,TIFFTAG_ROWSPERSTRIP,&rows_per_strip_)!=0)
{
MAPNIK_LOG_DEBUG(tiff_reader) << "reading striped tiff";
read_method_=stripped;
}
//TIFFTAG_EXTRASAMPLES
uint16 extrasamples = 0;
uint16* sampleinfo = nullptr;
if (TIFFGetField(tif, TIFFTAG_EXTRASAMPLES,
&extrasamples, &sampleinfo))
{
has_alpha_ = true;
if (extrasamples == 1 &&
sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA)
{
premultiplied_alpha_ = true;
}
} }
} }
} else
else {
{ MAPNIK_LOG_ERROR(tiff) << msg;
throw image_reader_exception(msg); }
} }
} }
@ -306,12 +328,12 @@ image_data_any tiff_reader<T>::read(unsigned x, unsigned y, unsigned width, unsi
} }
template <typename T> template <typename T>
void tiff_reader<T>::read_generic(unsigned, unsigned, image_data_32&) void tiff_reader<T>::read_generic(unsigned, unsigned, image_data_32& image)
{ {
TIFF* tif = open(stream_); TIFF* tif = open(stream_);
if (tif) if (tif)
{ {
MAPNIK_LOG_DEBUG(tiff_reader) << "tiff_reader: TODO - tiff is not stripped or tiled"; MAPNIK_LOG_ERROR(tiff_reader) << "tiff_reader: TODO - tiff is not stripped or tiled";
} }
} }
@ -343,7 +365,11 @@ void tiff_reader<T>::read_tiled(unsigned x0,unsigned y0,image_data_32& image)
for (int x=start_x;x<end_x;x+=tile_width_) for (int x=start_x;x<end_x;x+=tile_width_)
{ {
if (!TIFFReadRGBATile(tif,x,y,buf)) break; if (!TIFFReadRGBATile(tif,x,y,buf))
{
MAPNIK_LOG_ERROR(tiff_reader) << "TIFFReadRGBATile failed";
break;
}
tx0=std::max(x0,(unsigned)x); tx0=std::max(x0,(unsigned)x);
tx1=std::min(width+x0,(unsigned)(x+tile_width_)); tx1=std::min(width+x0,(unsigned)(x+tile_width_));
@ -383,8 +409,11 @@ void tiff_reader<T>::read_stripped(unsigned x0,unsigned y0,image_data_32& image)
ty0 = std::max(y0,y)-y; ty0 = std::max(y0,y)-y;
ty1 = std::min(height+y0,y+rows_per_strip_)-y; ty1 = std::min(height+y0,y+rows_per_strip_)-y;
if (!TIFFReadRGBAStrip(tif,y,buf)) break; if (!TIFFReadRGBAStrip(tif,y,buf))
{
MAPNIK_LOG_ERROR(tiff_reader) << "TIFFReadRGBAStrip failed";
break;
}
row=y+ty0-y0; row=y+ty0-y0;
int n0=laststrip ? 0:(rows_per_strip_-ty1); int n0=laststrip ? 0:(rows_per_strip_-ty1);