int ReadStrip(TIFF* tiff, UINT32 row, UINT32* buffer) { uint16 photometric; TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); // To avoid dealing with YCbCr subsampling, let libtiff handle it if (photometric == PHOTOMETRIC_YCBCR) { TIFFRGBAImage img; char emsg[1024] = ""; UINT32 rows_per_strip, rows_to_read; int ok; TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip); if ((row % rows_per_strip) != 0) { TRACE(("Row passed to ReadStrip() must be first in a strip.")); return -1; } if (TIFFRGBAImageOK(tiff, emsg) && TIFFRGBAImageBegin(&img, tiff, 0, emsg)) { TRACE(("Initialized RGBAImage\n")); img.req_orientation = ORIENTATION_TOPLEFT; img.row_offset = row; img.col_offset = 0; rows_to_read = min(rows_per_strip, img.height - row); TRACE(("rows to read: %d\n", rows_to_read)); ok = TIFFRGBAImageGet(&img, buffer, img.width, rows_to_read); TIFFRGBAImageEnd(&img); } else { ok = 0; } if (ok == 0) { TRACE(("Decode Error, row %d; msg: %s\n", row, emsg)); return -1; } return 0; } if (TIFFReadEncodedStrip(tiff, TIFFComputeStrip(tiff, row, 0), (tdata_t)buffer, -1) == -1) { TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, row, 0))); return -1; } return 0; }
void tiff_reader<T>::init() { TIFFSetWarningHandler(0); // Note - we intentially set the error handling to null // when opening the image for the first time to avoid // leaking in TiffOpen: https://github.com/mapnik/mapnik/issues/1783 TIFFSetErrorHandler(0); TIFF* tif = open(stream_); if (!tif) throw image_reader_exception("Can't open tiff file"); TIFFSetErrorHandler(on_error); char msg[1024]; if (TIFFRGBAImageOK(tif,msg)) { TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width_); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height_); if (TIFFIsTiled(tif)) { TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tile_width_); 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; uint16* sampleinfo; TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); if (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA) { premultiplied_alpha_ = true; } } else { throw image_reader_exception(msg); } }
PVOID ReadTIFF ( LPCTSTR lpszPath ) { void* pDIB = 0; TIFFErrorHandler wh; wh = TIFFSetWarningHandler(MyWarningHandler); if (ChkTIFF(lpszPath)) { TIFF* tif = TIFFOpen(lpszPath, "r"); if (tif) { char emsg[1024]; if (TIFFRGBAImageOK(tif, emsg)) { TIFFDibImage img; char emsg[1024]; if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg)) { size_t npixels; uint32* raster; DibInstallHack(&img); npixels = img.tif.width * img.tif.height; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width, img.tif.height)) { pDIB = TIFFRGBA2DIB(&img, raster); } } _TIFFfree(raster); } TIFFRGBAImageEnd(&img.tif); } else { TRACE("Unable to open image(%s): %s\n", lpszPath, emsg ); } TIFFClose(tif); } } TIFFSetWarningHandler(wh); return pDIB; }
bool TiffDecoder::readData( Mat& img ) { bool result = false; bool color = img.channels() > 1; uchar* data = img.data; int step = (int)img.step; if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F ) return false; if( m_tif && m_width && m_height ) { TIFF* tif = (TIFF*)m_tif; int tile_width0 = m_width, tile_height0 = 0; int x, y, i; int is_tiled = TIFFIsTiled(tif); int photometric; TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ); int bpp = 8, ncn = photometric > 1 ? 3 : 1; TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp ); TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn ); const int bitsPerByte = 8; int dst_bpp = (int)(img.elemSize1() * bitsPerByte); if(dst_bpp == 8) { char errmsg[1024]; if(!TIFFRGBAImageOK( tif, errmsg )) { close(); return false; } } if( (!is_tiled) || (is_tiled && TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) && TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 ))) { if(!is_tiled) TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 ); if( tile_width0 <= 0 ) tile_width0 = m_width; if( tile_height0 <= 0 ) tile_height0 = m_height; AutoBuffer<uchar> _buffer(tile_height0*tile_width0*8); uchar* buffer = _buffer; ushort* buffer16 = (ushort*)buffer; float* buffer32 = (float*)buffer; double* buffer64 = (double*)buffer; int tileidx = 0; for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 ) { int tile_height = tile_height0; if( y + tile_height > m_height ) tile_height = m_height - y; for( x = 0; x < m_width; x += tile_width0, tileidx++ ) { int tile_width = tile_width0, ok; if( x + tile_width > m_width ) tile_width = m_width - x; switch(dst_bpp) { case 8: { if( !is_tiled ) ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer ); else ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer ); if( !ok ) { close(); return false; } for( i = 0; i < tile_height; i++ ) if( color ) icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0, data + x*3 + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); else icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0, data + x + step*(tile_height - i - 1), 0, cvSize(tile_width,1), 2 ); break; } case 16: { if( !is_tiled ) ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; else ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0; if( !ok ) { close(); return false; } for( i = 0; i < tile_height; i++ ) { if( color ) { if( ncn == 1 ) { icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1) ); } else if( ncn == 3 ) { icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1) ); } else { icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x*3, 0, cvSize(tile_width,1), 2 ); } } else { if( ncn == 1 ) { memcpy((ushort*)(data + step*i)+x, buffer16 + i*tile_width*ncn, tile_width*sizeof(buffer16[0])); } else { icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0, (ushort*)(data + step*i) + x, 0, cvSize(tile_width,1), ncn, 2 ); } } } break; } case 32: case 64: { if( !is_tiled ) ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; else ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0; if( !ok || ncn != 1 ) { close(); return false; } for( i = 0; i < tile_height; i++ ) { if(dst_bpp == 32) { memcpy((float*)(data + step*i)+x, buffer32 + i*tile_width*ncn, tile_width*sizeof(buffer32[0])); } else { memcpy((double*)(data + step*i)+x, buffer64 + i*tile_width*ncn, tile_width*sizeof(buffer64[0])); } } break; } default: { close(); return false; } } } } result = true; } } close(); return result; }
int vglPrintTiffInfo(char* inFilename, char* msg){ if (msg){ printf("====== %s:\n", msg); } else { printf("====== vglPrintTiffInfo:\n"); } TIFF* tif = TIFFOpen(inFilename, "r"); if (tif == NULL){ fprintf(stderr, "%s:%s: Error: File %s not found.\n", __FILE__, __FUNCTION__, inFilename); return 1; } if (tif) { uint32 w, h; uint16 bps, spp, photo, config, pageNumber, numberPages; uint32 subfileType; tdir_t dirCount; tstrip_t stripMax; tstrip_t istrip; tsize_t stripSize; tsize_t npixels; tsize_t pixelSize; tdata_t raster; tsize_t result, offset; char* rasterc; uint32 iw, ih; int i; do{ TIFFPrintDirectory(tif, stdout, 255); } while(TIFFReadDirectory(tif)); printf("TIFFScanlineSize = %ld\n", (long int) TIFFScanlineSize(tif)); printf("TIFFRasterScanlineSize = %ld\n", (long int) TIFFRasterScanlineSize(tif)); printf("TIFFStripSize = %ld\n", (long int) TIFFStripSize(tif)); printf("TIFFNumberOfStrips = %d\n", TIFFNumberOfStrips(tif)); printf("TIFFVStripSize = %ld\n", (long int) TIFFVStripSize(tif,0)); printf("TIFFTileRowSize = %ld\n", (long int) TIFFTileRowSize(tif)); printf("TIFFTileSize = %ld\n", (long int) TIFFTileSize(tif)); printf("TIFFNumberOfTiles = %d\n", TIFFNumberOfTiles(tif)); printf("TIFFVTileSize = %ld\n", (long int) TIFFVTileSize(tif,0)); printf("TIFFDefaultStripSize = %d\n", TIFFDefaultStripSize(tif,0)); printf("TIFFFileno = %d\n", TIFFFileno(tif)); printf("TIFFGetMode = %d\n", TIFFGetMode(tif)); printf("TIFFIsTiled = %d\n", TIFFIsTiled(tif)); printf("TIFFIsByteSwapped = %d\n", TIFFIsByteSwapped(tif)); printf("TIFFRGBAImageOK = %d\n", TIFFRGBAImageOK(tif, (char*)"TIFFRGBAImageOK mesg\n")); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo); TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config); TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pageNumber, &numberPages); TIFFGetField(tif, TIFFTAG_SUBFILETYPE, &subfileType); stripSize = TIFFStripSize(tif); stripMax = TIFFNumberOfStrips(tif); switch(bps){ case 8: pixelSize = 1; break; case 16: pixelSize = 2; break; default: pixelSize = 0; break; } dirCount = tif_DirCount(tif); printf("size = %lu, w = %d, h = %d, spp = %d, bps = %d, pixelSize = %ld\n", sizeof(w), w, h, spp, bps, (long int) pixelSize); printf("Page Number = %d\n", pageNumber); printf("Number Pages = %d\n", numberPages); printf("Photometric interpretation = %d\n", photo); printf("Planar configuration = %d\n", config); printf("stripSize = %ld, stripMax = %d\n", (long int) stripSize, stripMax); printf("Number of directories = %d\n", dirCount); printf("Subfile type = %d\n", subfileType); //printbin((char*)&w, sizeof(w)); //printbin((char*)&h, sizeof(h)); //raster = tif_ReadData(tif); //tif_PrintAsc(tif, raster, (char*)"ascimg.txt"); TIFFClose(tif); } return 0; }
GthImage * _cairo_image_surface_create_from_tiff (GInputStream *istream, GthFileData *file_data, int requested_size, int *original_width_p, int *original_height_p, gboolean *loaded_original_p, gpointer user_data, GCancellable *cancellable, GError **error) { GthImage *image; Handle handle; TIFF *tif; gboolean first_directory; int best_directory; int max_width, max_height, min_diff; uint32 image_width; uint32 image_height; uint32 spp; uint16 extrasamples; uint16 *sampleinfo; uint16 orientation; char emsg[1024]; cairo_surface_t *surface; cairo_surface_metadata_t*metadata; uint32 *raster; image = gth_image_new (); handle.cancellable = cancellable; handle.size = 0; if ((file_data != NULL) && (file_data->info != NULL)) { handle.istream = g_buffered_input_stream_new (istream); handle.size = g_file_info_get_size (file_data->info); } else { void *data; gsize size; /* read the whole stream to get the file size */ if (! _g_input_stream_read_all (istream, &data, &size, cancellable, error)) return image; handle.istream = g_memory_input_stream_new_from_data (data, size, g_free); handle.size = size; } TIFFSetErrorHandler (tiff_error_handler); TIFFSetWarningHandler (tiff_error_handler); tif = TIFFClientOpen ("gth-tiff-reader", "r", &handle, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); if (tif == NULL) { g_object_unref (handle.istream); g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "Couldn't allocate memory for writing TIFF file"); return image; } /* find the best image to load */ first_directory = TRUE; best_directory = -1; max_width = -1; max_height = -1; min_diff = 0; do { int width; int height; if (TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &width) != 1) continue; if (TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &height) != 1) continue; if (! TIFFRGBAImageOK (tif, emsg)) continue; if (width > max_width) { max_width = width; max_height = height; if (requested_size <= 0) best_directory = TIFFCurrentDirectory (tif); } if (requested_size > 0) { int diff = abs (requested_size - width); if (first_directory) { min_diff = diff; best_directory = TIFFCurrentDirectory (tif); } else if (diff < min_diff) { min_diff = diff; best_directory = TIFFCurrentDirectory (tif); } } first_directory = FALSE; } while (TIFFReadDirectory (tif)); if (best_directory == -1) { TIFFClose (tif); g_object_unref (handle.istream); g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "Invalid TIFF format"); return image; } /* read the image */ TIFFSetDirectory (tif, best_directory); TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &image_width); TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &image_height); TIFFGetField (tif, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetFieldDefaulted (tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo); if (TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation) != 1) orientation = ORIENTATION_TOPLEFT; if (original_width_p) *original_width_p = max_width; if (original_height_p) *original_height_p = max_height; if (loaded_original_p) *loaded_original_p = (max_width == image_width); surface = _cairo_image_surface_create (CAIRO_FORMAT_ARGB32, image_width, image_height); if (surface == NULL) { TIFFClose (tif); g_object_unref (handle.istream); g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "Couldn't allocate memory for writing TIFF file"); return image; } metadata = _cairo_image_surface_get_metadata (surface); _cairo_metadata_set_has_alpha (metadata, (extrasamples == 1) || (spp == 4)); _cairo_metadata_set_original_size (metadata, max_width, max_height); raster = (uint32*) _TIFFmalloc (image_width * image_height * sizeof (uint32)); if (raster == NULL) { cairo_surface_destroy (surface); TIFFClose (tif); g_object_unref (handle.istream); g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "Couldn't allocate memory for writing TIFF file"); return image; } if (TIFFReadRGBAImageOriented (tif, image_width, image_height, raster, orientation, 0)) { guchar *surface_row; int line_step; int x, y, temp; guchar r, g, b, a; uint32 *src_pixel; surface_row = _cairo_image_surface_flush_and_get_data (surface); line_step = cairo_image_surface_get_stride (surface); src_pixel = raster; for (y = 0; y < image_height; y++) { guchar *dest_pixel = surface_row; if (g_cancellable_is_cancelled (cancellable)) goto stop_loading; for (x = 0; x < image_width; x++) { r = TIFFGetR (*src_pixel); g = TIFFGetG (*src_pixel); b = TIFFGetB (*src_pixel); a = TIFFGetA (*src_pixel); CAIRO_SET_RGBA (dest_pixel, r, g, b, a); dest_pixel += 4; src_pixel += 1; } surface_row += line_step; } } stop_loading: cairo_surface_mark_dirty (surface); if (! g_cancellable_is_cancelled (cancellable)) gth_image_set_cairo_surface (image, surface); _TIFFfree (raster); cairo_surface_destroy (surface); TIFFClose (tif); g_object_unref (handle.istream); return image; }