示例#1
0
/*
 * 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);
}
示例#2
0
/*
 * 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);
}
示例#3
0
/*
 * 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;
}
示例#4
0
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;
}
示例#5
0
/*
 * 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);
}
示例#6
0
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);
}
示例#7
0
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;
}
示例#8
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;
}
示例#9
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 
示例#10
0
_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;
}
示例#11
0
文件: fax2ps.c 项目: hkaiser/TRiAS
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++;
}
示例#12
0
/*
 * 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;
}
示例#13
0
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;
}
示例#14
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);
}
示例#15
0
_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;
}
示例#17
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;
}
示例#18
0
// 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 );
}
示例#19
0
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;
}
示例#20
0
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;
}
示例#21
0
文件: _tiff.cpp 项目: qbbian/imread
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;
}
示例#22
0
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;
}
示例#23
0
/*
 * 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);
}
示例#24
0
文件: tif_read.c 项目: hdfeos/gdal
/* 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);


}
示例#25
0
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);
}
示例#26
0
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;
}
示例#27
0
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;
}
示例#28
0
文件: tiff.cpp 项目: SteveShaw/povray
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) ;
}
示例#29
0
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;
}
示例#30
0
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;
}