/* * Get a strip-organized image with * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ static int gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) { TIFF* tif = img->tif; tileSeparateRoutine put = img->put.separate; uint16 orientation; u_char *buf; u_char *r, *g, *b, *a; uint32 row, y, nrow; tsize_t scanline; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t stripsize; int32 fromskew, toskew; int alpha = img->alpha; stripsize = TIFFStripSize(tif); r = buf = (u_char *)_TIFFmalloc(4*stripsize); if (buf == 0) { TIFFError(TIFFFileName(tif), "No space for tile buffer"); return (0); } g = r + stripsize; b = g + stripsize; a = b + stripsize; if (!alpha) memset(a, 0xff, stripsize); y = setorientation(img, h); orientation = img->orientation; toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w); TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += rowsperstrip) { nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), r, nrow*scanline) < 0 && img->stoponerr) break; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1), g, nrow*scanline) < 0 && img->stoponerr) break; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2), b, nrow*scanline) < 0 && img->stoponerr) break; if (alpha && (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3), a, nrow*scanline) < 0 && img->stoponerr)) break; (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r, g, b, a); y += (orientation == ORIENTATION_TOPLEFT ? -(int32) nrow : (int32) nrow); } _TIFFfree(buf); return (1); }
/* * Get a strip-organized image with * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ static int gtStripSeparate(TIFFImageIter* img, void *udata, uint32 w, uint32 h) { TIFF* tif = img->tif; ImageIterTileSeparateRoutine callback = img->callback.separate; uint16 orientation; u_char *buf; u_char *r, *g, *b, *a; uint32 row, nrow; tsize_t scanline; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t stripsize; int32 fromskew; int alpha = img->alpha; stripsize = TIFFStripSize(tif); r = buf = (u_char *)_TIFFmalloc(4*stripsize); if (buf == 0) { TIFFError(TIFFFileName(tif), "No space for tile buffer"); return (0); } g = r + stripsize; b = g + stripsize; a = b + stripsize; if (!alpha) memset(a, 0xff, stripsize); orientation = img->orientation; TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += rowsperstrip) { nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), r, nrow*scanline) < 0 && img->stoponerr) break; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1), g, nrow*scanline) < 0 && img->stoponerr) break; if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2), b, nrow*scanline) < 0 && img->stoponerr) break; if (alpha && (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3), a, nrow*scanline) < 0 && img->stoponerr)) break; (*callback)(img, udata, 0, row, w, nrow, fromskew, r, g, b, a); } _TIFFfree(buf); return (1); }
/* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ boolean TIFFRasterImpl::gtStripContig( const RGBvalue* Map, u_long h, u_long w ) { u_char* buf = new u_char[TIFFStripSize(tif_)]; if (buf == nil) { TIFFError(TIFFFileName(tif_), "No space for strip buffer"); return (false); } tileContigRoutine put = pickTileContigCase(Map); u_long y = setorientation(h); int toskew = (int)(orientation_ == ORIENTATION_TOPLEFT ? -w + -w : -w + w); u_long rowsperstrip = (u_long) -1L; TIFFGetField(tif_, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); u_long imagewidth; TIFFGetField(tif_, TIFFTAG_IMAGEWIDTH, &imagewidth); int scanline = TIFFScanlineSize(tif_); int fromskew = (int)(w < imagewidth ? imagewidth - w : 0); for (u_long row = 0; row < h; row += rowsperstrip) { u_int nrow = u_int(row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip( tif_, TIFFComputeStrip(tif_, row, 0), buf, nrow*scanline) < 0 ) { break; } (this->*put)(raster_ + y*w, buf, Map, w, nrow, fromskew, toskew); y += (orientation_ == ORIENTATION_TOPLEFT ? -nrow : nrow); } delete buf; return true; }
tdata_t tif_ReadContigStripData(TIFF* tif) { tdata_t raster = tif_Malloc(tif); tsize_t result; tsize_t offset; tsize_t stripSize = TIFFStripSize(tif); tstrip_t stripMax = TIFFNumberOfStrips(tif); tstrip_t istrip; if (tif == NULL) return NULL; offset = 0; if (raster != NULL) { for (istrip = 0; istrip < stripMax; istrip++){ result = TIFFReadEncodedStrip (tif, istrip, ((char*)raster)+offset, stripSize); if (result == -1) { printf("Read error on input strip number %d\n", istrip); } offset += result; } } return raster; }
/* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static int gtStripContig(TIFFImageIter* img, void *udata, uint32 w, uint32 h) { TIFF* tif = img->tif; ImageIterTileContigRoutine callback = img->callback.contig; uint16 orientation; uint32 row, nrow; u_char* buf; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t scanline; int32 fromskew; buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif)); if (buf == 0) { TIFFError(TIFFFileName(tif), "No space for strip buffer"); return (0); } orientation = img->orientation; TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += rowsperstrip) { nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf, nrow*scanline) < 0 && img->stoponerr) break; (*callback)(img, udata, 0, row, w, nrow, fromskew, buf); } _TIFFfree(buf); return (1); }
bool CaViewerCore::openTif(ImageInfo info, int nSequence) { static const QString sProgressFormat = QObject::tr("Loading... %p%"); TIFF* tif = TIFFOpen(info.fullName(nSequence).toStdString().c_str(), "r"); quint16 bps, spp; quint32 rps; TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rps); const quint32 stripSize = TIFFNumberOfStrips(tif); const quint32 stripLength = TIFFStripSize(tif); int nPrevImgCount = 0; for(int count = 0; count < nSequence; ++count) nPrevImgCount += info.imageSize(count); if(bps == 16 && spp == 1) // for 16-bit mono channel tif { for(int imgCount = 0; imgCount < info.imageSize(nSequence); ++imgCount) { const int globalCount = nPrevImgCount + imgCount; const int height = globalCount % info.heightSize(); const int time = globalCount / info.heightSize(); cv::Mat_<quint16> img = m_lImage->at(height).at(time); #pragma omp parallel for schedule(static) for(quint32 stripCount = 0; stripCount < stripSize; ++stripCount) { quint16* const stripBuf = reinterpret_cast<quint16*>(new quint8[stripLength]); #pragma omp critical TIFFReadEncodedStrip(tif, stripCount, stripBuf, stripLength); for(quint32 rowInStrip = 0; rowInStrip < rps; ++rowInStrip) { const quint32 imgStrip = rowInStrip + rps * stripCount; quint16* const matData = reinterpret_cast<quint16*>(img.data + img.step * imgStrip); for(int col = 0; col < info.colSize(); ++col) { const quint16 oriValue = stripBuf[col + rowInStrip * info.colSize()]; matData[col] = oriValue; } if(imgStrip == info.rowSize() - 1) break; } } TIFFReadDirectory(tif); emit changedProgressValue(100.0 * globalCount / m_lImage->size(), sProgressFormat); } return true; } else return false; TIFFClose(tif); }
char *appendSlice2Tiff3DFile ( void *fhandler, int slice, unsigned char *img, unsigned int img_width, unsigned int img_height, int spp, int bpp, int NPages ) { TIFF *output = (TIFF *) fhandler; TIFFSetDirectory(output,slice); // WARNING: slice must be the first page after the last, otherwise the file can be corrupted TIFFSetField(output, TIFFTAG_IMAGEWIDTH, img_width); TIFFSetField(output, TIFFTAG_IMAGELENGTH, img_height); TIFFSetField(output, TIFFTAG_BITSPERSAMPLE, (uint16)bpp); TIFFSetField(output, TIFFTAG_SAMPLESPERPIXEL, (uint16)spp); TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, (rowsPerStrip == -1) ? img_height : rowsPerStrip); TIFFSetField(output, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_LZW); //TIFFSetField(output, TIFFTAG_COMPRESSION, COMPRESSION_NONE); TIFFSetField(output, TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG); TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); //TIFFSetField(output, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); // We are writing single page of the multipage file TIFFSetField(output, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE); TIFFSetField(output, TIFFTAG_PAGENUMBER, (uint16)slice, (uint16)NPages); if ( rowsPerStrip == -1 ) TIFFWriteEncodedStrip(output, 0, img, img_width * img_height * spp * (bpp/8)); else { int check,StripsPerImage,LastStripSize; uint32 rps = rowsPerStrip; unsigned char *buf = img; StripsPerImage = (img_height + rps - 1) / rps; LastStripSize = img_height % rps; if (LastStripSize==0) LastStripSize=rps; for (int i=0; i < StripsPerImage-1; i++){ //if (comp==1) { // TIFFReadRawStrip(input, i, buf, spp * rps * img_width * (bpp/8)); // buf = buf + spp * rps * img_width * (bpp/8); //} //else{ TIFFWriteEncodedStrip(output, i, buf, spp * rps * img_width * (bpp/8)); buf = buf + spp * rps * img_width * (bpp/8); //} } //if (comp==1) { // TIFFReadRawStrip(input, StripsPerImage-1, buf, spp * LastStripSize * img_width * (bpp/8)); //} //else{ TIFFReadEncodedStrip(output, StripsPerImage-1, buf, spp * LastStripSize * img_width * (bpp/8)); //} buf = buf + spp * LastStripSize * img_width * (bpp/8); } //img += img_width * img_height; TIFFWriteDirectory(output); return (char *) 0; }
static int StripBasedXform(cmsHTRANSFORM hXForm, TIFF* in, TIFF* out, int nPlanes) { tsize_t BufSizeIn = TIFFStripSize(in); tsize_t BufSizeOut = TIFFStripSize(out); unsigned char *BufferIn, *BufferOut; ttile_t i, StripCount = TIFFNumberOfStrips(in) / nPlanes; uint32 sw; uint32 sl; uint32 iml; int j; int PixelCount; TIFFGetFieldDefaulted(in, TIFFTAG_IMAGEWIDTH, &sw); TIFFGetFieldDefaulted(in, TIFFTAG_ROWSPERSTRIP, &sl); TIFFGetFieldDefaulted(in, TIFFTAG_IMAGELENGTH, &iml); BufferIn = (unsigned char *) _TIFFmalloc(BufSizeIn * nPlanes); if (!BufferIn) OutOfMem(BufSizeIn * nPlanes); BufferOut = (unsigned char *) _TIFFmalloc(BufSizeOut * nPlanes); if (!BufferOut) OutOfMem(BufSizeOut * nPlanes); for (i = 0; i < StripCount; i++) { for (j=0; j < nPlanes; j++) { if (TIFFReadEncodedStrip(in, i + (j * StripCount), BufferIn + (j * BufSizeIn), BufSizeIn) < 0) goto cleanup; } PixelCount = (int) sw * (iml < sl ? iml : sl); iml -= sl; cmsDoTransform(hXForm, BufferIn, BufferOut, PixelCount); for (j=0; j < nPlanes; j++) { if (TIFFWriteEncodedStrip(out, i + (j * StripCount), BufferOut + j * BufSizeOut, BufSizeOut) < 0) goto cleanup; } } _TIFFfree(BufferIn); _TIFFfree(BufferOut); return 1; cleanup: _TIFFfree(BufferIn); _TIFFfree(BufferOut); return 0; }
int main (int argc, char ** argv) { TIFF *image; short *rowBuf; int i; int imgW = 0, imgH = 0, bps = 0, spp = 0; int rowsPerStrip = 0; // create a bigtiff file if((image = TIFFOpen(BT_FILE, "r8")) == NULL) { printf("\nCould not open file for reading\n"); exit(1); } TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &imgW); TIFFGetField(image, TIFFTAG_IMAGELENGTH, &imgH); TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bps); if(TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp) == 0) printf("\nCould not read TIFFTAG_SAMPLESPERPIXEL"); if(TIFFGetField(image, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip) == 0) printf("\nCould not read TIFFTAG_ROWSPERSTRIP"); // TIFFGetField(image, TIFFTAG_COMPRESSION, COMPRESSION_NONE); // TIFFGetField(image, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); // TIFFGetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); // TIFFGetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); //TIFFSetDirectory(image, 0); printf("\nImage Size = %dx%d. Bps = %d. Spp = %d. RowsPerStrip = %d", imgW, imgH, bps, spp, rowsPerStrip); fflush(stdout); printf("\nPress Enter to continue .."); getchar(); // create a pattern in buffer int rowBufSize = imgW * bps * spp / 8; if((rowBuf = (short *)malloc (rowBufSize)) == NULL) { printf("\nError allocating %d bytes for row buffer", rowBufSize); exit(1); } // read the strips from the TIFF file for (i = 0; i < imgH; i++) { printf("\nReading row (strip) # %d", i);fflush(stdout); TIFFReadEncodedStrip(image, i, (tdata_t)rowBuf, (tsize_t)-1); } free(rowBuf); // close the file TIFFClose(image); return 0; } // End of main
_declspec (dllexport) int32_t readStrip(TIFF* tif, // TIFF handle - IN const int slice, // required slice - IN uint8_t* strip, // OUT, caller allocates memory const int linesPerStrip, // strip size / scanline size - IN const int stripSize) // strip size - IN { int32_t err = 0; int stripOfInterest = slice / linesPerStrip; // keep integer division here err = TIFFReadEncodedStrip(tif, stripOfInterest, strip, stripSize); return err; }
void printTIF(TIFF* tif, int pageNumber) { uint32 w, h; uint16 unit; float xres, yres; tstrip_t s, ns; TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); if (!TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres)) { TIFFWarning(TIFFFileName(tif), "No x-resolution, assuming %g dpi", defxres); xres = defxres; } if (!TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres)) { TIFFWarning(TIFFFileName(tif), "No y-resolution, assuming %g lpi", defyres); yres = defyres; /* XXX */ } if (TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &unit) && unit == RESUNIT_CENTIMETER) { xres *= 25.4; yres *= 25.4; } printf("%%%%Page: \"%d\" %d\n", pageNumber, pageNumber); printf("/$pageTop save def gsave\n"); if (scaleToPage) { float yscale = pageHeight / (h/yres); float xscale = pageWidth / (w/xres); printf("%d %d translate\n", (int) (((basePageWidth - pageWidth) * points) * half), (int)((yscale*(h/yres)*points) + (basePageHeight - pageHeight) * points * half) ); printf("%g %g scale\n", (72.*xscale)/xres, -(72.*yscale)/yres); } else { printf("%d %d translate\n", (int) ((basePageWidth - pageWidth) * points * half), (int)((72.*h/yres) + (basePageHeight - pageHeight) * points * half) ); printf("%g %g scale\n", 72./xres, -72./yres); } printf("0 setgray\n"); TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, printruns); ns = TIFFNumberOfStrips(tif); row = 0; for (s = 0; s < ns; s++) (void) TIFFReadEncodedStrip(tif, s, (tdata_t) NULL, (tsize_t) -1); printf("p\n"); printf("grestore $pageTop restore\n"); totalPages++; }
/* * Get a strip-organized image with * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ boolean TIFFRasterImpl::gtStripSeparate( const RGBvalue* Map, u_long h, u_long w ) { u_long stripsize = TIFFStripSize(tif_); u_char* buf = new u_char[3*stripsize]; u_char* r = buf; u_char* g = r + stripsize; u_char* b = g + stripsize; tileSeparateRoutine put = pickTileSeparateCase(Map); u_long y = setorientation(h); int toskew = (int)(orientation_ == ORIENTATION_TOPLEFT ? -w + -w : -w + w); u_long rowsperstrip = (u_long) -1L; TIFFGetField(tif_, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); u_long imagewidth; TIFFGetField(tif_, TIFFTAG_IMAGEWIDTH, &imagewidth); int scanline = TIFFScanlineSize(tif_); int fromskew = (int)(w < imagewidth ? imagewidth - w : 0); for (u_long row = 0; row < h; row += rowsperstrip) { u_int nrow = u_int(row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip( tif_, TIFFComputeStrip(tif_, row, 0), r, nrow*scanline) < 0 ) { break; } if (TIFFReadEncodedStrip( tif_, TIFFComputeStrip(tif_, row, 1), g, nrow*scanline) < 0 ) { break; } if (TIFFReadEncodedStrip( tif_, TIFFComputeStrip(tif_, row, 2), b, nrow*scanline) < 0 ) { break; } (this->*put)(raster_ + y*w, r, g, b, Map, w, nrow, fromskew, toskew); y += (orientation_ == ORIENTATION_TOPLEFT ? -nrow : nrow); } delete buf; return true; }
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; }
/* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 * * Hacked from the tif_getimage.c file. * * This is set up to allow us to just copy the data to the raster * for 1-bit bitmaps */ static int getStripContig1Bit(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) { TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint16 orientation; uint32 row, y, nrow, rowstoread; uint32 pos; u_char* buf; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t scanline; int32 fromskew, toskew; tstrip_t strip; tsize_t stripsize; u_char* braster = (u_char*)raster; // byte wide raster uint32 wb = WIDTHBYTES(w); int ret = 1; buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif)); if (buf == 0) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); return (0); } y = setorientation(img, h); orientation = img->orientation; toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? wb+wb : wb-wb); TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0)/8; for (row = 0; row < h; row += nrow) { rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip; nrow = (row + rowstoread > h ? h - row : rowstoread); strip = TIFFComputeStrip(tif,row+img->row_offset, 0); stripsize = ((row + img->row_offset)%rowsperstrip + nrow) * scanline; if (TIFFReadEncodedStrip(tif, strip, buf, stripsize ) < 0 && img->stoponerr) { ret = 0; break; } pos = ((row + img->row_offset) % rowsperstrip) * scanline; (*put)(img, (uint32*)(braster+y*wb), 0, y, w, nrow, fromskew, toskew, buf + pos); y += (orientation == ORIENTATION_TOPLEFT ?-(int32) nrow : (int32) nrow); } _TIFFfree(buf); return (ret); }
_declspec (dllexport) void sinograph(TIFF* tif, const uint32_t slice, const int32_t w, const int32_t l, const int32_t total_quantity, int32_t samples_per_pixel, uint32_t used_quantity, const char* resultPath) { if (slice >= (uint32_t) l) { return; } char pathName[1024]; strcpy_s(pathName, resultPath); strcat_s(pathName, "\\sinograph.tif"); TIFF* resultTif = makeTiffImage(pathName); TIFFSetField(resultTif, TIFFTAG_IMAGEWIDTH, w); TIFFSetField(resultTif, TIFFTAG_IMAGELENGTH, used_quantity); TIFFSetField(resultTif, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(resultTif, TIFFTAG_SAMPLESPERPIXEL, samples_per_pixel); TIFFSetField(resultTif, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(resultTif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(resultTif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(resultTif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); TIFFSetField(resultTif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); int32_t scanlineSize = TIFFScanlineSize(tif); int32_t stripSize = TIFFStripSize(tif); int linesPerStrip = stripSize / scanlineSize; int stripOfInterest = slice / linesPerStrip; // keep integer division here int offsetPixels = slice % linesPerStrip * w; uint8_t* buffer = (uint8_t*) _TIFFmalloc(stripSize); int32_t selector = (total_quantity + used_quantity - 1) / used_quantity; used_quantity = 0; for (int32_t i = 0; i < total_quantity; i++) { if (i % selector != 0) { continue; } TIFFSetDirectory(tif, i); TIFFReadEncodedStrip(tif, stripOfInterest, buffer, stripSize); TIFFWriteScanline(resultTif, buffer + offsetPixels, used_quantity, scanlineSize); ++used_quantity; } _TIFFfree(buffer); TIFFClose(resultTif); }
int read_strips(TIFF *tif, const tdata_t array, const tsize_t size) { tstrip_t strip, nstrips; tsize_t stripsize, offset; tdata_t buf = NULL; stripsize = TIFFStripSize(tif); if (!stripsize) { fprintf (stderr, "Wrong size of strip.\n"); return -1; } buf = _TIFFmalloc(stripsize); if (!buf) { fprintf (stderr, "Can't allocate space for strip buffer.\n"); return -1; } nstrips = TIFFNumberOfStrips(tif); for (offset = 0, strip = 0; offset < size && strip < nstrips; offset+=stripsize, strip++) { /* * Properly read last strip. */ tsize_t bufsize = size - offset; if (bufsize > stripsize) bufsize = stripsize; if (TIFFReadEncodedStrip(tif, strip, buf, -1) != bufsize) { fprintf (stderr, "Can't read strip %lu.\n", (unsigned long)strip); return -1; } if (memcmp(buf, (char *)array + offset, bufsize) != 0) { fprintf (stderr, "Wrong data read for strip %lu.\n", (unsigned long)strip); _TIFFfree(buf); return -1; } } _TIFFfree(buf); return 0; }
unsigned char* HeightMipmap::readTile(int tx, int ty) { char buf[256]; unsigned char *data = new unsigned char[(tileSize + 5) * (tileSize + 5) * 2]; int nTiles = max(1, (baseLevelSize / tileSize) >> (maxLevel - currentLevel)); int nTilesPerFile = min(nTiles, 16); int dx = tx / nTilesPerFile; int dy = ty / nTilesPerFile; tx = tx % nTilesPerFile; ty = ty % nTilesPerFile; sprintf(buf, "%s/%.2d-%.4d-%.4d.tiff", cache.c_str(), currentLevel, dx, dy); TIFF* f = TIFFOpen(buf, "rb"); TIFFSetDirectory(f, tx + ty * nTilesPerFile); TIFFReadEncodedStrip(f, 0, data, (tsize_t) -1); TIFFClose(f); return data; }
// Read 8-bit TIFFs. // // // No intensity remapping. // static void Raster8FromTif8Bit( TIFF *tif, int w, int h, uint8* raster, FILE* flog ) { int npixels = w * h; int NB, nb, j; // read encoded strips for( j = 0, NB = 0; NB < npixels; NB += nb, ++j ) { nb = TIFFReadEncodedStrip( tif, j, raster + NB, (tsize_t)-1 ); } fprintf( flog, "TIF(8): Last Encoded strip had %d bytes.\n", nb ); }
bool CTiffImg::ReadLine(unsigned char *pBuf) { if (!m_bRead) return false; unsigned long nStrip = m_nCurLine / m_nRowsPerStrip; unsigned long nRowOffset = m_nCurLine % m_nRowsPerStrip; if (nStrip != m_nCurStrip) { m_nCurStrip = nStrip; if (TIFFReadEncodedStrip(m_hTif, m_nCurStrip, m_pStripBuf, m_nStripSize) < 0) { return false; } } memcpy(pBuf, m_pStripBuf+nRowOffset*m_nBytesPerLine, m_nBytesPerLine); m_nCurLine++; return true; }
int ReadTiff(const char * filename, std::vector<unsigned char> * ptr, int * w, int * h, int * depth) { TIFF* tiff = TIFFOpen(filename, "r"); if (!tiff) { std::cerr << "Error: Couldn't open " << filename << " fopen returned 0"; return 0; } uint16 bps, spp; TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, w); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, h); TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &bps); TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &spp); *depth = bps * spp / 8; ptr->resize((*h)*(*w)*(*depth)); if (*depth==4) { if (ptr != nullptr) { if (!TIFFReadRGBAImageOriented(tiff, *w, *h, (uint32*)&((*ptr)[0]), ORIENTATION_TOPLEFT, 0)) { TIFFClose(tiff); return 0; } } } else { for (size_t i=0; i<TIFFNumberOfStrips(tiff); ++i) { if (TIFFReadEncodedStrip(tiff, i, ((uint8*)&((*ptr)[0]))+i*TIFFStripSize(tiff),(tsize_t)-1) == std::numeric_limits<tsize_t>::max()) { TIFFClose(tiff); return 0; } } } TIFFClose(tiff); return 1; }
std::auto_ptr<image_list> STKFormat::read_multi(byte_source* src, ImageFactory* factory) { shift_source moved(src); stk_extend ext; tiff_warn_error twe; tif_holder t = read_client(&moved); std::auto_ptr<image_list> images(new image_list); const uint32 h = tiff_get<uint32>(t, TIFFTAG_IMAGELENGTH); const uint32 w = tiff_get<uint32>(t, TIFFTAG_IMAGEWIDTH); const uint16 nr_samples = tiff_get<uint16>(t, TIFFTAG_SAMPLESPERPIXEL, 1); const uint16 bits_per_sample = tiff_get<uint16>(t, TIFFTAG_BITSPERSAMPLE, 8); const int depth = nr_samples > 1 ? nr_samples : -1; const int strip_size = TIFFStripSize(t.tif); const int n_strips = TIFFNumberOfStrips(t.tif); int32_t n_planes; void* data; TIFFGetField(t.tif, UIC3Tag, &n_planes, &data); int raw_strip_size = 0; for (int st = 0; st != n_strips; ++st) { raw_strip_size += TIFFRawStripSize(t.tif, st); } for (int z = 0; z < n_planes; ++z) { // Monkey patch strip offsets. This is very hacky, but it seems to work! moved.shift(z * raw_strip_size); std::auto_ptr<Image> output(factory->create(bits_per_sample, h, w, depth)); uint8_t* start = output->rowp_as<uint8_t>(0); for (int st = 0; st != n_strips; ++st) { const int offset = TIFFReadEncodedStrip(t.tif, st, start, strip_size); if (offset == -1) { throw CannotReadError("imread.imread._tiff.stk: Error reading strip"); } start += offset; } images->push_back(output); } return images; }
int tiff_decode_complex(TIFF *tif, clFFT_Complex *buffer, int offset) { const int strip_size = TIFFStripSize(tif); const int n_strips = TIFFNumberOfStrips(tif); printf("\nstrip_size:%d ; n_strips:%d\n", strip_size, n_strips); int result = 0; int width, height; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); float *temp_buffer = (float *)malloc(strip_size); for (int strip = 0; strip < n_strips; strip++) { result = TIFFReadEncodedStrip(tif, strip, temp_buffer, strip_size); if (result == -1) return 0; int pixels_per_strip = strip_size / sizeof(float); int rows = pixels_per_strip / width; for(int i = 0; i < rows; ++i) { for(int j = offset; j < width; ++j) { buffer[strip * (pixels_per_strip - rows * offset) + i * (width-offset) + j - offset].real = temp_buffer[i * width + j]; buffer[strip * (pixels_per_strip - rows * offset) + i * (width-offset) + j - offset].imag = 0.0; } } } free(temp_buffer); return 1; }
/* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static int gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h) { TIFF* tif = img->tif; tileContigRoutine put = img->put.contig; uint16 orientation; uint32 row, y, nrow; u_char* buf; uint32 rowsperstrip; uint32 imagewidth = img->width; tsize_t scanline; int32 fromskew, toskew; buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif)); if (buf == 0) { TIFFError(TIFFFileName(tif), "No space for strip buffer"); return (0); } y = setorientation(img, h); orientation = img->orientation; toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w); TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); scanline = TIFFScanlineSize(tif); fromskew = (w < imagewidth ? imagewidth - w : 0); for (row = 0; row < h; row += rowsperstrip) { nrow = (row + rowsperstrip > h ? h - row : rowsperstrip); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf, nrow*scanline) < 0 && img->stoponerr) break; (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf); y += (orientation == ORIENTATION_TOPLEFT ? -(int32) nrow : (int32) nrow); } _TIFFfree(buf); return (1); }
/* Variant of TIFFReadEncodedStrip() that does * * if *buf == NULL, *buf = _TIFFmalloc(bufsizetoalloc) only after TIFFFillStrip() has * succeeded. This avoid excessive memory allocation in case of truncated * file. * * calls regular TIFFReadEncodedStrip() if *buf != NULL */ tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF* tif, uint32 strip, void **buf, tmsize_t bufsizetoalloc, tmsize_t size_to_read) { tmsize_t this_stripsize; uint16 plane; if( *buf != NULL ) { return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read); } this_stripsize=TIFFReadEncodedStripGetStripSize(tif, strip, &plane); if (this_stripsize==((tmsize_t)(-1))) return((tmsize_t)(-1)); if ((size_to_read!=(tmsize_t)(-1))&&(size_to_read<this_stripsize)) this_stripsize=size_to_read; if (!TIFFFillStrip(tif,strip)) return((tmsize_t)(-1)); *buf = _TIFFmalloc(bufsizetoalloc); if (*buf == NULL) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer"); return((tmsize_t)(-1)); } _TIFFmemset(*buf, 0, bufsizetoalloc); if ((*tif->tif_decodestrip)(tif,*buf,this_stripsize,plane)<=0) return((tmsize_t)(-1)); (*tif->tif_postdecode)(tif,*buf,this_stripsize); return(this_stripsize); }
void XdmfTIFFController::read(XdmfArray * const array) { TIFF* tif = TIFFOpen(mFilePath.c_str(), "r"); unsigned int compression = 0; TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression); unsigned int currentDirectory = 0; if (tif && mStart.size() >= 3) { // setting the start for the first directory TIFFSetDirectory(tif, mStart[2]); currentDirectory = mStart[2]; } unsigned int amountWritten = 0; // Only used for 1d controllers unsigned int sizeLeft = this->getSize(); if (!array->isInitialized()) { array->initialize(this->getType()); } if (array->getSize() != this->getSize()) { array->resize(mDimensions, 0); } // For single dimension version only unsigned int currentRowStart = mStart[0]; unsigned int scanlineIndex = 0; if (mDimensions.size() > 1) { scanlineIndex = mStart[1]; } if (tif) { bool validDir = true; while (validDir) { // Directories are handled by the third dimension // If no directories are specified, progress as far // as needed to fill the dimensions provided. unsigned int imagelength, bitsPerSample; tdata_t buf; unsigned int row; unsigned int scanlinesize = TIFFScanlineSize(tif); shared_ptr<const XdmfArrayType> tiffDataType = array->getArrayType(); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength); if (compression == 1) { // Specific to non-compressed read if (bitsPerSample / 8 == 1) { tiffDataType = XdmfArrayType::UInt8(); } else if (bitsPerSample / 8 == 2) { tiffDataType = XdmfArrayType::UInt16(); } else if (bitsPerSample / 8 == 4) { tiffDataType = XdmfArrayType::UInt32(); } // the buffer is a number of bytes equal to the scan line size buf = _TIFFmalloc(scanlinesize ); scanlinesize /= array->getArrayType()->getElementSize(); if (mDimensions.size() == 1) { if (sizeLeft == 0) { break; } // If there is one dimensions then we treat the entire entry as a single dataset. // We need to adjust the starting point accordingly. for (row = 0; row < imagelength; ++row) { TIFFReadScanline(tif, buf, row); unsigned int amountRead = sizeLeft; if ((scanlinesize - currentRowStart) / mStride[0] <= sizeLeft) { amountRead = (scanlinesize - currentRowStart) / mStride[0]; if (scanlinesize % mStride[0] != 0 && currentRowStart % mStride[0] <= scanlinesize - (amountRead * mStride[0] + currentRowStart)) { amountRead++; } } readToArray(array, buf, amountWritten, currentRowStart, mStride[0], amountRead, tiffDataType); // check to see how the start matches up with the scanline size amountWritten += amountRead; if (sizeLeft == 0) { break; } if (amountRead < sizeLeft) { sizeLeft = sizeLeft - amountRead; } else { sizeLeft = 0; } if (((int)((amountRead * mStride[0]) + currentRowStart)) - scanlinesize >= 0) { currentRowStart = ((amountRead * mStride[0]) + currentRowStart) - scanlinesize; } else { currentRowStart = ((amountRead * (mStride[0] + 1)) + currentRowStart) - scanlinesize; } } } else { // Dimensions correspond to scanline size and number of scanlines unsigned int rowstride = mStride[1]; unsigned int currentRowStart = mStart[0]; for (row = mStart[1]; row < imagelength && row < mDataspaceDimensions[1]; row+=rowstride) { TIFFReadScanline(tif, buf, row); readToArray(array, buf, amountWritten, currentRowStart, mStride[0], mDimensions[0], tiffDataType); amountWritten += mDimensions[0]; } } _TIFFfree(buf); } else if (compression == 5) { // In this case we need to use strips instead of scanlines // scanline size is in bytes when dealing with compression if (bitsPerSample == 1) { tiffDataType = XdmfArrayType::UInt8(); } else if (bitsPerSample == 2) { tiffDataType = XdmfArrayType::UInt16(); } else if (bitsPerSample == 4) { tiffDataType = XdmfArrayType::UInt32(); } // the buffer is a number of bytes equal to the scan line size buf = _TIFFmalloc(TIFFStripSize(tif)); scanlinesize /= array->getArrayType()->getElementSize(); // For each strip in the directory for (unsigned int strip = 0; strip < TIFFNumberOfStrips(tif); strip++) { if (sizeLeft == 0) { break; } unsigned int currentStripSize = TIFFReadEncodedStrip(tif, strip, buf, -1); currentStripSize = currentStripSize / array->getArrayType()->getElementSize(); // Size is in bits, and is not necessarily the same per strip unsigned int numberScanlines = currentStripSize / scanlinesize; // For the case of a partial scanline if (currentStripSize % scanlinesize != 0) { ++numberScanlines; } // If singledimensional // then write out the strip as if it was a scanline if (mDimensions.size() == 1) { unsigned int amountRead = sizeLeft; if ((currentStripSize - currentRowStart) / mStride[0] <= sizeLeft) { amountRead = (currentStripSize - currentRowStart) / mStride[0]; if (currentStripSize % mStride[0] != 0 && currentRowStart % mStride[0] <= currentStripSize - (amountRead * mStride[0] + currentRowStart)) { amountRead++; } } readToArray(array, buf, amountWritten, currentRowStart, mStride[0], amountRead, tiffDataType); amountWritten += amountRead; if (sizeLeft == 0) { break; } if (amountRead < sizeLeft) { sizeLeft = sizeLeft - amountRead; } else { sizeLeft = 0; } if (((int)((amountRead * mStride[0]) + currentRowStart)) - currentStripSize >= 0) { currentRowStart = ((amountRead * mStride[0]) + currentRowStart) - currentStripSize; } else { currentRowStart = ((amountRead * (mStride[0] + 1)) + currentRowStart) - currentStripSize; } } else { currentRowStart = scanlineIndex; // If multidimensional // Loop through the scanlines in the strip for (; scanlineIndex < numberScanlines; scanlineIndex += mStride[1]) { readToArray(array, buf, amountWritten, currentRowStart, mStride[0], mDimensions[0], tiffDataType); amountWritten += mDimensions[0]; currentRowStart = currentRowStart + scanlinesize * mStride[1]; } scanlineIndex = scanlineIndex % mStride[1]; } } } if (mStride.size() >= 3) { currentDirectory += mStride[2]; } else { ++currentDirectory; } validDir = TIFFSetDirectory(tif, currentDirectory); } } else { XdmfError::message(XdmfError::FATAL, "Error: Invalid TIFF file"); } TIFFClose(tif); }
BOOL CImageTIFF::Read(FILE* stream) { TIFF* m_tif = TIFFOpenEx(stream, "rb"); uint32 height=0; uint32 width=0; uint16 bitspersample=1; uint16 samplesperpixel=1; uint32 rowsperstrip=-1; uint16 photometric=0; uint16 compression=1; uint32 x, y; BOOL isRGB; BYTE *bits; //pointer to source data BYTE *bits2; //pointer to destination data try{ //check if it's a tiff file if (!m_tif) throw "Error encountered while opening TIFF file"; m_info.nNumFrames=0; while(TIFFSetDirectory(m_tif,(uint16)m_info.nNumFrames)) m_info.nNumFrames++; if (!TIFFSetDirectory(m_tif, (uint16)m_info.nFrame)) throw "Error: page not present in TIFF file"; //get image m_info TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression); if (compression == COMPRESSION_LZW) throw "LZW compression is no longer supported due to Unisys patent enforcement"; TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric); m_header.biWidth = width; m_header.biHeight = height; m_header.biClrUsed=0; m_info.nBkgndIndex =-1; isRGB = (bitspersample >= 8) && (photometric == PHOTOMETRIC_RGB) || (photometric == PHOTOMETRIC_YCBCR) || (photometric == PHOTOMETRIC_SEPARATED) || (photometric == PHOTOMETRIC_LOGLUV); if (isRGB){ m_header.biBitCount=24; m_info.bColorType = COLORTYPE_COLOR; }else{ m_info.bColorType = COLORTYPE_PALETTE; if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)){ if (bitspersample == 1){ m_header.biBitCount=1; //B&W image m_header.biClrUsed =2; } else { m_header.biBitCount=8; //gray scale m_header.biClrUsed =256; } } else if (bitspersample == 4) { m_header.biBitCount=4; // 16 colors m_header.biClrUsed=16; } else { m_header.biBitCount=8; //256 colors m_header.biClrUsed=256; } } Create(m_header.biWidth,m_header.biHeight,m_header.biBitCount); //image creation if (isRGB) { // Read the whole image into one big RGBA buffer using // the traditional TIFFReadRGBAImage() API that we trust. uint32* raster; // retrieve RGBA image uint32 *row; raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == NULL) throw "No space for raster buffer"; // Read the image in one chunk into an RGBA array if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) { _TIFFfree(raster); throw "Corrupted TIFF file!"; } // read the raster lines and save them in the DIB // with RGB mode, we have to change the order of the 3 samples RGB row = &raster[0]; bits2 = m_info.pImage; for (y = 0; y < height; y++) { bits = bits2; for (x = 0; x < width; x++) { *bits++ = (BYTE)TIFFGetB(row[x]); *bits++ = (BYTE)TIFFGetG(row[x]); *bits++ = (BYTE)TIFFGetR(row[x]); } row += width; bits2 += m_info.dwEffWidth; } _TIFFfree(raster); } else { RGBQUAD *pal; pal=(RGBQUAD*)calloc(256,sizeof(RGBQUAD)); if (pal==NULL) throw "Unable to allocate TIFF palette"; // set up the colormap based on photometric switch(photometric) { case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types case PHOTOMETRIC_MINISWHITE: if (bitspersample == 1) { // Monochrome image if (photometric == PHOTOMETRIC_MINISBLACK) { pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255; } else { pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255; } } else { // need to build the scale for greyscale images if (photometric == PHOTOMETRIC_MINISBLACK) { for (int i = 0; i < 256; i++) { pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = i; } } else { for (int i = 0; i < 256; i++) { pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = 255 - i; } } } break; case PHOTOMETRIC_PALETTE: // color map indexed uint16 *red; uint16 *green; uint16 *blue; TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue); // Is the palette 16 or 8 bits ? BOOL Palette16Bits = FALSE; int n=1<<bitspersample; while (n-- > 0) { if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) { Palette16Bits=TRUE; break; } } // load the palette in the DIB for (int i = (1 << bitspersample) - 1; i >= 0; i--) { if (Palette16Bits) { pal[i].rgbRed =(BYTE) CVT(red[i]); pal[i].rgbGreen = (BYTE) CVT(green[i]); pal[i].rgbBlue = (BYTE) CVT(blue[i]); } else { pal[i].rgbRed = (BYTE) red[i]; pal[i].rgbGreen = (BYTE) green[i]; pal[i].rgbBlue = (BYTE) blue[i]; } } break; } SetPalette(pal,m_header.biClrUsed); //palette assign free(pal); // read the tiff lines and save them in the DIB uint32 nrow; uint32 ys; int line = CalculateLine(width, bitspersample * samplesperpixel); // int pitch = CalculatePitch(line); long bitsize= TIFFStripSize(m_tif); bits = (BYTE*)malloc(bitsize); for (ys = 0; ys < height; ys += rowsperstrip) { nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip); if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), bits, nrow * line) == -1) { free(bits); throw "Corrupted TIFF file!"; } for (y = 0; y < nrow; y++) { memcpy(m_info.pImage+m_info.dwEffWidth*(height-ys-nrow+y),bits+(nrow-y-1)*line,line); } /*if (m_header.biClrUsed==2){ for (y = 0; y < nrow; y++) { for (x = 0; x < width; x++) { SetPixelIndex(x,y+ys,(bits[y*line+(x>>3)]>>(7-x%8))&0x01); }}}*/ } free(bits); } } catch (char *message) { strncpy(m_info.szLastError,message,255); if (m_tif) TIFFClose(m_tif); return FALSE; } TIFFClose(m_tif); return TRUE; }
int readTiff(const char*file, MyBuf *buf){ TIFF *image; // Open the TIFF image if((image = TIFFOpen(file, "r")) == NULL){ MyTRACE( "Could not open incoming image\n"); return(42); } int sts = tiffSize_(image, &buf->w, &buf->h, &buf->linestep, &buf->type); if(sts!=0) goto Exit; assert(buf->type == TYPE_32F || buf->type == TYPE_16S || buf->type == TYPE_16U); unsigned long imageOffset = 0; unsigned long bufferSize = buf->h * buf->linestep; buf->p = malloc(bufferSize); for (int stripCount = 0; stripCount < buf->h; stripCount++) { int result; if((result = TIFFReadEncodedStrip (image, stripCount, (char*)buf->p + imageOffset, buf->linestep)) == -1){ MyTRACE( "Read error on input strip number %d\n", stripCount); return(42); } imageOffset += result; } // Deal with photometric interpretations uint16 photo; if(TIFFGetField(image, TIFFTAG_PHOTOMETRIC, &photo) == 0){ MyTRACE( "Image has an undefined photometric interpretation\n"); return(42); } MyTRACE( "TIFFTAG_PHOTOMETRIC %d\n", photo); //if(photo != PHOTOMETRIC_MINISWHITE){ // // Flip bits // // MyTRACE("Fixing the photometric interpretation\n"); // // for(count = 0; count < bufferSize; count++) // // buffer[count] = ~buffer[count]; //} // Deal with fillorder // if(TIFFGetField(image, TIFFTAG_FILLORDER, &fillorder) == 0){ // MyTRACE( "Image has an undefined fillorder\n"); // return(42); // } // // if(fillorder != FILLORDER_MSB2LSB){ // // We need to swap bits -- ABCDEFGH becomes HGFEDCBA //MyTRACE( "Image has an undefined fillorder2\n"); // // MyTRACE("Fixing the fillorder\n"); // // for(count = 0; count < bufferSize; count++){ // // tempbyte = 0; // // if(buffer[count] & 128) tempbyte += 1; // // if(buffer[count] & 64) tempbyte += 2; // // if(buffer[count] & 32) tempbyte += 4; // // if(buffer[count] & 16) tempbyte += 8; // // if(buffer[count] & 8) tempbyte += 16; // // if(buffer[count] & 4) tempbyte += 32; // // if(buffer[count] & 2) tempbyte += 64; // // if(buffer[count] & 1) tempbyte += 128; // // buffer[count] = tempbyte; // // } // } // FILE *fp = fopen("c:\\temp\\tiff.log","w"); // for(count = 0; count < bufferSize; count++){ // fprintf(fp, "%03f ", buffer[count]); // if((count + 1) % (width / 8) == 0) fprintf(fp, "\n"); // else fprintf(fp, " "); // } // fclose(fp); Exit: TIFFClose(image); return 0; }
Image *Read (IStream *file, const Image::ReadOptions& options) { int nrow; int result = 0; long LineSize; TIFF *tif; Image *image ; uint16 BitsPerSample; uint16 BytesPerSample = 1; uint16 PhotometricInterpretation; uint16 SamplePerPixel; uint16 Orientation; uint32 RowsPerStrip; unsigned int width; unsigned int height; // TODO - TIFF files probably have some gamma info in them by default, but we're currently ignorant about that. // Until that is fixed, use whatever the user has chosen as default. GammaCurvePtr gamma; if (options.gammacorrect && options.defaultGamma) gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma); // [CLi] TIFF is specified to use associated (= premultiplied) alpha, so that's the preferred mode to use for the image container unless the user overrides // (e.g. to handle a non-compliant file). bool premul = true; if (options.premultiplyOverride) premul = options.premultiply; // Rather than have libTIFF complain about tags it doesn't understand, // we just suppress all the warnings. TIFFSetWarningHandler(SuppressTIFFWarnings); TIFFSetErrorHandler(SuppressTIFFWarnings); // Open and do initial processing tif = TIFFClientOpen("Dummy File Name", "r", file, Tiff_Read, Tiff_Write, Tiff_Seek, Tiff_Close, Tiff_Size, Tiff_Map, Tiff_Unmap); if (!tif) return (NULL) ; // Get basic information about the image int ExtraSamples, ExtraSampleInfo; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); TIFFGetField(tif, TIFFTAG_ORIENTATION, &Orientation); TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel); TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &ExtraSamples, &ExtraSampleInfo); // don't support more than 16 bits per sample if (BitsPerSample == 16) { BytesPerSample = 2 ; options.warnings.push_back ("Warning: reading 16 bits/sample TIFF file; components crunched to 8"); } LineSize = TIFFScanlineSize(tif); assert (SamplePerPixel == (int) (LineSize / width) / BytesPerSample); // SamplePerPixel = (int)(LineSize / width); #if 0 // For now we are ignoring the orientation of the image... switch (Orientation) { case ORIENTATION_TOPLEFT: break; case ORIENTATION_TOPRIGHT: break; case ORIENTATION_BOTRIGHT: break; case ORIENTATION_BOTLEFT: break; case ORIENTATION_LEFTTOP: break; case ORIENTATION_RIGHTTOP: break; case ORIENTATION_RIGHTBOT: break; case ORIENTATION_LEFTBOT: break; default: break; } #endif //PhotometricInterpretation = 2 image is RGB //PhotometricInterpretation = 3 image have a color palette if (PhotometricInterpretation == PHOTOMETRIC_PALETTE && (TIFFIsTiled(tif) == 0)) { uint16 *red, *green, *blue; //load the palette int cmap_len = (1 << BitsPerSample); TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); vector<Image::RGBMapEntry> colormap ; Image::RGBMapEntry entry; // I may be mistaken, but it appears that alpha/opacity information doesn't // appear in a Paletted Tiff image. Well - if it does, it's not as easy to // get at as RGB. // Read the palette // Is the palette 16 or 8 bits ? if (checkcmap(cmap_len, red, green, blue) == 16) { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 65535); entry.green = IntDecode(gamma, green[i], 65535); entry.blue = IntDecode(gamma, blue[i], 65535); colormap.push_back (entry); } } else { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 255); entry.green = IntDecode(gamma, green[i], 255); entry.blue = IntDecode(gamma, blue[i], 255); colormap.push_back (entry); } } Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = Image::Colour_Map; image = Image::Create (width, height, imagetype, colormap) ; image->SetPremultiplied(premul); // specify whether the color map data has premultiplied alpha boost::scoped_array<unsigned char> buf (new unsigned char [TIFFStripSize(tif)]); //read the tiff lines and save them in the image //with RGB mode, we have to change the order of the 3 samples RGB <=> BGR for (int row=0;row<height;row+=RowsPerStrip) { nrow = (row + (int)RowsPerStrip > height ? height - row : RowsPerStrip); TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf.get(), nrow * LineSize); for (int l = 0, offset = 0; l < nrow ; l++, offset += LineSize) for (int x = 0 ; x < width ; x++) image->SetIndexedValue (x, row+l, buf[offset+x]) ; } } else { // Allocate the row buffers for the image boost::scoped_array<uint32> buf (new uint32 [width * height]) ; Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = ( GammaCurve::IsNeutral(gamma) ? Image::RGBA_Int8 : Image::RGBA_Gamma8 ); image = Image::Create (width, height, imagetype) ; image->SetPremultiplied(premul); // set desired storage mode regarding alpha premultiplication image->TryDeferDecoding(gamma, 255); // try to have gamma adjustment being deferred until image evaluation. TIFFReadRGBAImage(tif, width, height, buf.get(), 0); uint32 abgr, *tbuf = buf.get(); for (int i=height-1;i>=0;i--) { for (int j=0;j<width;j++) { abgr = *tbuf++; unsigned int b = (unsigned char)TIFFGetB(abgr); unsigned int g = (unsigned char)TIFFGetG(abgr); unsigned int r = (unsigned char)TIFFGetR(abgr); unsigned int a = (unsigned char)TIFFGetA(abgr); SetEncodedRGBAValue(image, j, i, gamma, 255, r, g, b, a, premul) ; } } } TIFFClose(tif); return (image) ; }
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 NITFUncompressBILEVEL( NITFImage *psImage, GByte *pabyInputData, int nInputBytes, GByte *pabyOutputImage ) { int nOutputBytes= (psImage->nBlockWidth * psImage->nBlockHeight + 7)/8; /* -------------------------------------------------------------------- */ /* Write memory TIFF with the bilevel data. */ /* -------------------------------------------------------------------- */ CPLString osFilename; osFilename.Printf( "/vsimem/nitf-wrk-%ld.tif", (long) CPLGetPID() ); VSILFILE* fpL = VSIFOpenL(osFilename, "w+"); if( fpL == NULL ) return FALSE; TIFF *hTIFF = VSI_TIFFOpen( osFilename, "w+", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } TIFFSetField( hTIFF, TIFFTAG_IMAGEWIDTH, psImage->nBlockWidth ); TIFFSetField( hTIFF, TIFFTAG_IMAGELENGTH, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_BITSPERSAMPLE, 1 ); TIFFSetField( hTIFF, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT ); TIFFSetField( hTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG ); TIFFSetField( hTIFF, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB ); TIFFSetField( hTIFF, TIFFTAG_ROWSPERSTRIP, psImage->nBlockHeight ); TIFFSetField( hTIFF, TIFFTAG_SAMPLESPERPIXEL, 1 ); TIFFSetField( hTIFF, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK ); TIFFSetField( hTIFF, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX3 ); if( psImage->szCOMRAT[0] == '2' ) TIFFSetField( hTIFF, TIFFTAG_GROUP3OPTIONS, GROUP3OPT_2DENCODING ); TIFFWriteRawStrip( hTIFF, 0, pabyInputData, nInputBytes ); TIFFWriteDirectory( hTIFF ); TIFFClose( hTIFF ); /* -------------------------------------------------------------------- */ /* Now open and read it back. */ /* -------------------------------------------------------------------- */ int bResult = TRUE; hTIFF = VSI_TIFFOpen( osFilename, "r", fpL ); if (hTIFF == NULL) { VSIFCloseL(fpL); return FALSE; } if( TIFFReadEncodedStrip( hTIFF, 0, pabyOutputImage, nOutputBytes ) == -1 ) { memset( pabyOutputImage, 0, nOutputBytes ); bResult = FALSE; } TIFFClose( hTIFF ); VSIFCloseL(fpL); VSIUnlink( osFilename ); return bResult; }