Пример #1
0
int
ReadChar8TIFF(char *pp_file)
{
	TIFF           *lp_tif;
	char           *lp_pixels;
	unsigned char  *lp_tiffdata;
	int             lv_nstrips;
	int             lv_stripsize;
	int             lv_counter;
	int             lv_pixel;
	int             lv_npixels;
	int             lv_step;
	tdata_t         lp_buf;
	tstrip_t        lv_strip;
	uint16          lv_bitsper;

	if (lp_tif = TIFFOpen(pp_file, "r"))
	{
		TIFFGetField(lp_tif, TIFFTAG_BITSPERSAMPLE, &lv_bitsper);
		if (lv_bitsper != 8)
		{
			fprintf(stderr, "Colour data not 8 bit per channel!\n");;
			TIFFClose(lp_tif);
			return 0;
		}
		TIFFGetField(lp_tif, TIFFTAG_IMAGEWIDTH, &gv_width);
		TIFFGetField(lp_tif, TIFFTAG_IMAGELENGTH, &gv_height);

		gp_cdata = (unsigned char *) malloc(gv_width * gv_height * sizeof(unsigned char));

		lv_pixel = 0;
		lv_npixels = gv_width * gv_height;
		if (lp_tif)
		{
			if (gv_colour != MONO)
				lv_step = 3;
			else
				lv_step = 1;
			lv_stripsize = TIFFStripSize(lp_tif);
			lv_nstrips = TIFFNumberOfStrips(lp_tif);
			lp_buf = _TIFFmalloc(TIFFStripSize(lp_tif));
			lv_counter = 0;
			for (lv_strip = 0; lv_strip < lv_nstrips; lv_strip++)
			{
				TIFFReadEncodedStrip(lp_tif, lv_strip, lp_buf, (tsize_t) - 1);
				lp_tiffdata = (unsigned char *) lp_buf;
				for (lv_pixel = 0; lv_pixel < lv_stripsize; lv_pixel += lv_step)	/* NOTE 3 Channel */
				{
					if (lv_counter < lv_npixels)
					{
						switch (gv_colour)
						{
						case RED:
						case MONO:
							gp_cdata[lv_counter] = lp_tiffdata[lv_pixel];
							break;
						case GREEN:
							gp_cdata[lv_counter] = lp_tiffdata[lv_pixel + 1];
							break;
						case BLUE:
							gp_cdata[lv_counter] = lp_tiffdata[lv_pixel + 2];
							break;
						}
						lv_counter++;
					}
				}
			}
			_TIFFfree(lp_buf);
		}
		TIFFClose(lp_tif);
	} else
		return 0;
	return 1;
}
Пример #2
0
  /*
   * Save an image using libtiff 
   */
int saveTIFF( const char *path, commonImage_t *image, compressionType_e cType, bool verbose )
 {
   int rval = 0;
   TIFF *out = TIFFOpen( path, "w" );

   int bitspersample;
   int samplesperpixel=1;

   if (out != NULL){

     //////////////////////////////////////////////////
     // Fill out the "header" info
     TIFFSetField( out, TIFFTAG_IMAGEWIDTH, image->width);
     TIFFSetField( out, TIFFTAG_IMAGELENGTH, image->height);

     TIFFSetField( out, TIFFTAG_COMPRESSION, cType);

     TIFFSetField( out, TIFFTAG_PLANARCONFIG, 1); //RGBRGBRGB... (or GGGGGG...)

     if (image->mode == Gray8bpp || image->mode == Gray10bpp || image->mode == Gray12bpp || 
	 image->mode == Gray14bpp || image->mode == Gray16bpp || image->mode == Gray32bpp ){

       TIFFSetField( out, TIFFTAG_PHOTOMETRIC, 1);
     }

     //Assume that bits are not packed. ie if over 8 bits but less than 16 bits per channel => 2bytes
     switch (image->mode){
     case Gray8bpp:       
     case RGB8bpp:
     case RGBA8bpp:
       bitspersample = 8;       
       break;
     case Gray10bpp:
     case Gray12bpp:
     case Gray14bpp:
     case Gray16bpp:
       bitspersample = 16;
       break;
     case Gray24bpp:
       bitspersample = 24;
       break;
     case Gray32bpp:
       bitspersample = 32;
       break;
     default:
       if (verbose)
	 std::cerr << "Unsupported image format encountered" << std::endl;
       rval = -2;
       break;
     }
     TIFFSetField( out, TIFFTAG_BITSPERSAMPLE, bitspersample);   

     if (image->mode == RGB8bpp)
       samplesperpixel=3;
     else if (image->mode == RGBA8bpp)
       samplesperpixel=4;

     TIFFSetField( out, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);

     //////////////////////////////////////////////////////
     //Do the actual data write (buffered to row at once)
     tsize_t linebytes = bitspersample*samplesperpixel*image->width ;
     int fract = linebytes%8;
     linebytes /= 8;
     if (fract > 0)
       linebytes++;

     TIFFSetField( out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize( out, linebytes ));
     
   
     unsigned char *lineBuffer;
     lineBuffer = (unsigned char*) _TIFFmalloc( linebytes );
     if(!lineBuffer){
       if (verbose){
	 std::cerr << "Error while allocating file write buffer" << std::endl;
       }
       rval = -3;
     }
     else{     
       char *ptIn = (char*)(image->data);
       for(uint32 row = 0; row < image->height; row++){
	 
	 memcpy(lineBuffer, ptIn, linebytes);
	 if (TIFFWriteScanline(out, lineBuffer, row, 0) < 0)
	   break;
	 
	 ptIn += linebytes;

       }
       _TIFFfree(lineBuffer);          
     }

   }else{
     if (verbose){
       std::cerr << "commonImage::saveTIFF Error opening file for writing: " << path << std::endl;       
       rval = -1;
     }
   }
   
   TIFFClose(out);   
   return rval;
 }
Пример #3
0
bool CxImageTIF::EncodeBody(TIFF *m_tif, bool multipage, int page, int pagecount)
{
	uint32 height=head.biHeight;
	uint32 width=head.biWidth;
	uint16 bitcount=head.biBitCount;
	uint16 bitspersample;
	uint16 samplesperpixel;
	uint16 photometric=0;
	uint16 compression;
//	uint16 pitch;
//	int line;
	uint32 x, y;

	samplesperpixel = ((bitcount == 24) || (bitcount == 32)) ? (BYTE)3 : (BYTE)1;
#if CXIMAGE_SUPPORT_ALPHA
	if (bitcount==24 && AlphaIsValid()) { bitcount=32; samplesperpixel=4; }
#endif //CXIMAGE_SUPPORT_ALPHA

	bitspersample = bitcount / samplesperpixel;

	//set the PHOTOMETRIC tag
	RGBQUAD *rgb = GetPalette();
	switch (bitcount) {
		case 1:
			if (CompareColors(&rgb[0],&rgb[1])<0) {
				/* <abe> some viewers do not handle PHOTOMETRIC_MINISBLACK:
				 * let's transform the image in PHOTOMETRIC_MINISWHITE
				 */
				//invert the colors
				RGBQUAD tempRGB=GetPaletteColor(0);
				SetPaletteColor(0,GetPaletteColor(1));
				SetPaletteColor(1,tempRGB);
				//invert the pixels
				BYTE *iSrc=info.pImage;
				for (unsigned long i=0;i<head.biSizeImage;i++){
					*iSrc=(BYTE)~(*(iSrc));
					iSrc++;
				}
				photometric = PHOTOMETRIC_MINISWHITE;
				//photometric = PHOTOMETRIC_MINISBLACK;
			} else {
				photometric = PHOTOMETRIC_MINISWHITE;
			}
			break;
		case 4:	// Check if the DIB has a color or a greyscale palette
		case 8:
			photometric = PHOTOMETRIC_MINISBLACK; //default to gray scale
			for (x = 0; x < head.biClrUsed; x++) {
				if ((rgb->rgbRed != x)||(rgb->rgbRed != rgb->rgbGreen)||(rgb->rgbRed != rgb->rgbBlue)){
					photometric = PHOTOMETRIC_PALETTE;
					break;
				}
				rgb++;
			}
			break;
		case 24:
		case 32:
			photometric = PHOTOMETRIC_RGB;			
			break;
	}

#if CXIMAGE_SUPPORT_ALPHA
	if (AlphaIsValid() && bitcount==8) samplesperpixel=2; //8bpp + alpha layer
#endif //CXIMAGE_SUPPORT_ALPHA

//	line = CalculateLine(width, bitspersample * samplesperpixel);
//	pitch = (uint16)CalculatePitch(line);

	//prepare the palette struct
	RGBQUAD pal[256];
	if (GetPalette()){
		BYTE b;
		memcpy(pal,GetPalette(),GetPaletteSize());
		for(WORD a=0;a<head.biClrUsed;a++){	//swap blue and red components
			b=pal[a].rgbBlue; pal[a].rgbBlue=pal[a].rgbRed; pal[a].rgbRed=b;
		}
	}

	// handle standard width/height/bpp stuff
	TIFFSetField(m_tif, TIFFTAG_IMAGEWIDTH, width);
	TIFFSetField(m_tif, TIFFTAG_IMAGELENGTH, height);
	TIFFSetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
	TIFFSetField(m_tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
	TIFFSetField(m_tif, TIFFTAG_PHOTOMETRIC, photometric);
	TIFFSetField(m_tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);	// single image plane 
	TIFFSetField(m_tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

	uint32 rowsperstrip = TIFFDefaultStripSize(m_tif, (uint32) -1);  //<REC> gives better compression
	TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

	// handle metrics
	TIFFSetField(m_tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
	TIFFSetField(m_tif, TIFFTAG_XRESOLUTION, (float)info.xDPI);
	TIFFSetField(m_tif, TIFFTAG_YRESOLUTION, (float)info.yDPI);
//	TIFFSetField(m_tif, TIFFTAG_XPOSITION, (float)info.xOffset);
//	TIFFSetField(m_tif, TIFFTAG_YPOSITION, (float)info.yOffset);

	// multi-paging - Thanks to Abe <God(dot)bless(at)marihuana(dot)com>
	if (multipage)
	{
		char page_number[20];
		sprintf(page_number, "Page %d", page);

		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
		TIFFSetField(m_tif, TIFFTAG_PAGENUMBER, page,pagecount);
		TIFFSetField(m_tif, TIFFTAG_PAGENAME, page_number);
	} else {
		TIFFSetField(m_tif, TIFFTAG_SUBFILETYPE, 0);
	}

	// palettes (image colormaps are automatically scaled to 16-bits)
	if (photometric == PHOTOMETRIC_PALETTE) {
		uint16 *r, *g, *b;
		r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * 256);
		g = r + 256;
		b = g + 256;

		for (int i = 255; i >= 0; i--) {
			b[i] = (uint16)SCALE((uint16)pal[i].rgbRed);
			g[i] = (uint16)SCALE((uint16)pal[i].rgbGreen);
			r[i] = (uint16)SCALE((uint16)pal[i].rgbBlue);
		}

		TIFFSetField(m_tif, TIFFTAG_COLORMAP, r, g, b);
		_TIFFfree(r);
	}

	// compression
	if (GetCodecOption(CXIMAGE_FORMAT_TIF)) {
		compression = (WORD)GetCodecOption(CXIMAGE_FORMAT_TIF);
	} else {
		switch (bitcount) {
			case 1 :
				compression = COMPRESSION_CCITTFAX4;
				break;
			case 4 :
			case 8 :
				compression = COMPRESSION_LZW;
				break;
			case 24 :
			case 32 :
				compression = COMPRESSION_JPEG;
				break;
			default :
				compression = COMPRESSION_NONE;
				break;
		}
	}
	TIFFSetField(m_tif, TIFFTAG_COMPRESSION, compression);

	switch (compression) {
	case COMPRESSION_JPEG:
		TIFFSetField(m_tif, TIFFTAG_JPEGQUALITY, info.nQuality);
		TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, ((7+rowsperstrip)>>3)<<3);
   		break;
	case COMPRESSION_LZW:
		if (bitcount>=8) TIFFSetField(m_tif, TIFFTAG_PREDICTOR, 2);
		break;
	}

	// read the DIB lines from bottom to top and save them in the TIF

	BYTE *bits;
	switch(bitcount) {				
		case 1 :
		case 4 :
		case 8 :
		{
			if (samplesperpixel==1){
				for (y = 0; y < height; y++) {
					bits= info.pImage + (height - y - 1)*info.dwEffWidth;
					if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) return false;
				}
			}
#if CXIMAGE_SUPPORT_ALPHA
			else { //8bpp + alpha layer
				bits = (BYTE*)malloc(2*width);
				if (!bits) return false;
				for (y = 0; y < height; y++) {
					for (x=0;x<width;x++){
						bits[2*x]=GetPixelIndex(x,height - y - 1);
						bits[2*x+1]=AlphaGet(x,height - y - 1);
					}
					if (TIFFWriteScanline(m_tif,bits, y, 0)==-1) {
						free(bits);
						return false;
					}
				}
				free(bits);
			}
#endif //CXIMAGE_SUPPORT_ALPHA
			break;
		}				
		case 24:
		{
			BYTE *buffer = (BYTE *)malloc(info.dwEffWidth);
			if (!buffer) return false;
			for (y = 0; y < height; y++) {
				// get a pointer to the scanline
				memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
				// TIFFs store color data RGB instead of BGR
				BYTE *pBuf = buffer;
				for (x = 0; x < width; x++) {
					BYTE tmp = pBuf[0];
					pBuf[0] = pBuf[2];
					pBuf[2] = tmp;
					pBuf += 3;
				}
				// write the scanline to disc
				if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
					free(buffer);
					return false;
				}
			}
			free(buffer);
			break;
		}				
		case 32 :
		{
#if CXIMAGE_SUPPORT_ALPHA
			BYTE *buffer = (BYTE *)malloc((info.dwEffWidth*4)/3);
			if (!buffer) return false;
			for (y = 0; y < height; y++) {
				// get a pointer to the scanline
				memcpy(buffer, info.pImage + (height - y - 1)*info.dwEffWidth, info.dwEffWidth);
				// TIFFs store color data RGB instead of BGR
				BYTE *pSrc = buffer + 3 * width;
				BYTE *pDst = buffer + 4 * width;
				for (x = 0; x < width; x++) {
					pDst-=4;
					pSrc-=3;
					pDst[3] = AlphaGet(width-x-1,height-y-1);
					pDst[2] = pSrc[0];
					pDst[1] = pSrc[1];
					pDst[0] = pSrc[2];
				}
				// write the scanline to disc
				if (TIFFWriteScanline(m_tif, buffer, y, 0)==-1){
					free(buffer);
					return false;
				}
			}
			free(buffer);
#endif //CXIMAGE_SUPPORT_ALPHA
			break;
		}				
	}
	return true;
}
Пример #4
0
/*
 * Read the next TIFF directory from a file
 * and convert it to the internal format.
 * We read directories sequentially.
 */
int
TIFFReadDirectory(TIFF* tif)
{
	register TIFFDirEntry* dp;
	register int n;
	register TIFFDirectory* td;
	TIFFDirEntry* dir;
	int iv;
	long v;
	double dv;
	const TIFFFieldInfo* fip;
	int fix;
	uint16 dircount;
	toff_t nextdiroff;
	char* cp;
	int diroutoforderwarning = 0;

	tif->tif_diroff = tif->tif_nextdiroff;
	if (tif->tif_diroff == 0)		/* no more directories */
		return (0);
	/*
	 * Cleanup any previous compression state.
	 */
	(*tif->tif_cleanup)(tif);
	tif->tif_curdir++;
	nextdiroff = 0;
	if (!isMapped(tif)) {
		if (!SeekOK(tif, tif->tif_diroff)) {
			TIFFError(tif->tif_name,
			    "Seek error accessing TIFF directory");
			return (0);
		}
		if (!ReadOK(tif, &dircount, sizeof (uint16))) {
			TIFFError(tif->tif_name,
			    "Can not read TIFF directory count");
			return (0);
		}
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabShort(&dircount);
		dir = (TIFFDirEntry *)CheckMalloc(tif,
		    dircount * sizeof (TIFFDirEntry), "to read TIFF directory");
		if (dir == NULL)
			return (0);
		if (!ReadOK(tif, dir, dircount*sizeof (TIFFDirEntry))) {
			TIFFError(tif->tif_name, "Can not read TIFF directory");
			goto bad;
		}
		/*
		 * Read offset to next directory for sequential scans.
		 */
		(void) ReadOK(tif, &nextdiroff, sizeof (uint32));
	} else {
		toff_t off = tif->tif_diroff;

		if (off + sizeof (uint16) > tif->tif_size) {
			TIFFError(tif->tif_name,
			    "Can not read TIFF directory count");
			return (0);
		} else
			_TIFFmemcpy(&dircount, tif->tif_base + off, sizeof (uint16));
		off += sizeof (uint16);
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabShort(&dircount);
		dir = (TIFFDirEntry *)CheckMalloc(tif,
		    dircount * sizeof (TIFFDirEntry), "to read TIFF directory");
		if (dir == NULL)
			return (0);
		if (off + dircount*sizeof (TIFFDirEntry) > tif->tif_size) {
			TIFFError(tif->tif_name, "Can not read TIFF directory");
			goto bad;
		} else
			_TIFFmemcpy(dir, tif->tif_base + off,
			    dircount*sizeof (TIFFDirEntry));
		off += dircount* sizeof (TIFFDirEntry);
		if (off + sizeof (uint32) <= tif->tif_size)
			_TIFFmemcpy(&nextdiroff, tif->tif_base+off, sizeof (uint32));
	}
	if (tif->tif_flags & TIFF_SWAB)
		TIFFSwabLong(&nextdiroff);
	tif->tif_nextdiroff = nextdiroff;

	tif->tif_flags &= ~TIFF_BEENWRITING;	/* reset before new dir */
	/*
	 * Setup default value and then make a pass over
	 * the fields to check type and tag information,
	 * and to extract info required to size data
	 * structures.  A second pass is made afterwards
	 * to read in everthing not taken in the first pass.
	 */
	td = &tif->tif_dir;
	/* free any old stuff and reinit */
	TIFFFreeDirectory(tif);
	TIFFDefaultDirectory(tif);
	/*
	 * Electronic Arts writes gray-scale TIFF files
	 * without a PlanarConfiguration directory entry.
	 * Thus we setup a default value here, even though
	 * the TIFF spec says there is no default value.
	 */
	TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

	/*
	 * Sigh, we must make a separate pass through the
	 * directory for the following reason:
	 *
	 * We must process the Compression tag in the first pass
	 * in order to merge in codec-private tag definitions (otherwise
	 * we may get complaints about unknown tags).  However, the
	 * Compression tag may be dependent on the SamplesPerPixel
	 * tag value because older TIFF specs permited Compression
	 * to be written as a SamplesPerPixel-count tag entry.
	 * Thus if we don't first figure out the correct SamplesPerPixel
	 * tag value then we may end up ignoring the Compression tag
	 * value because it has an incorrect count value (if the
	 * true value of SamplesPerPixel is not 1).
	 *
	 * It sure would have been nice if Aldus had really thought
	 * this stuff through carefully.
	 */ 
	for (dp = dir, n = dircount; n > 0; n--, dp++) {
		if (tif->tif_flags & TIFF_SWAB) {
			TIFFSwabArrayOfShort(&dp->tdir_tag, 2);
			TIFFSwabArrayOfLong(&dp->tdir_count, 2);
		}
		if (dp->tdir_tag == TIFFTAG_SAMPLESPERPIXEL) {
			if (!TIFFFetchNormalTag(tif, dp))
				goto bad;
			dp->tdir_tag = IGNORE;
		}
	}
	/*
	 * First real pass over the directory.
	 */
	fix = 0;
	for (dp = dir, n = dircount; n > 0; n--, dp++) {

                /*
                 * Find the field information entry for this tag.
		 * Added check for tags to ignore ... [BFC]
                 */
		if( TIFFReassignTagToIgnore(TIS_EXTRACT, dp->tdir_tag) )
                    dp->tdir_tag = IGNORE;

		if (dp->tdir_tag == IGNORE)
                    continue;
                
		/*
		 * Silicon Beach (at least) writes unordered
		 * directory tags (violating the spec).  Handle
		 * it here, but be obnoxious (maybe they'll fix it?).
		 */
		if (dp->tdir_tag < tif->tif_fieldinfo[fix]->field_tag) {
			if (!diroutoforderwarning) {
				TIFFWarning(tif->tif_name,
	"invalid TIFF directory; tags are not sorted in ascending order");
				diroutoforderwarning = 1;
			}
			fix = 0;			/* O(n^2) */
		}
		while (fix < tif->tif_nfields &&
		    tif->tif_fieldinfo[fix]->field_tag < dp->tdir_tag)
			fix++;
		if (fix == tif->tif_nfields ||
		    tif->tif_fieldinfo[fix]->field_tag != dp->tdir_tag) {
			TIFFWarning(tif->tif_name,
			    "unknown field with tag %d (0x%x) ignored",
			    dp->tdir_tag,  dp->tdir_tag);
			dp->tdir_tag = IGNORE;
			fix = 0;			/* restart search */
			continue;
		}
		/*
		 * Null out old tags that we ignore.
		 */
		if (tif->tif_fieldinfo[fix]->field_bit == FIELD_IGNORE) {
	ignore:
			dp->tdir_tag = IGNORE;
			continue;
		}
		/*
		 * Check data type.
		 */
		fip = tif->tif_fieldinfo[fix];
		while (dp->tdir_type != (u_short) fip->field_type) {
			if (fip->field_type == TIFF_ANY)	/* wildcard */
				break;
			fip++, fix++;
			if (fix == tif->tif_nfields ||
			    fip->field_tag != dp->tdir_tag) {
				TIFFWarning(tif->tif_name,
				   "wrong data type %d for \"%s\"; tag ignored",
				    dp->tdir_type, fip[-1].field_name);
				goto ignore;
			}
		}
		/*
		 * Check count if known in advance.
		 */
		if (fip->field_readcount != TIFF_VARIABLE) {
			uint32 expected = (fip->field_readcount == TIFF_SPP) ?
			    (uint32) td->td_samplesperpixel :
			    (uint32) fip->field_readcount;
			if (!CheckDirCount(tif, dp, expected))
				goto ignore;
		}

		switch (dp->tdir_tag) {
		case TIFFTAG_COMPRESSION:
			/*
			 * The 5.0 spec says the Compression tag has
			 * one value, while earlier specs say it has
			 * one value per sample.  Because of this, we
			 * accept the tag if one value is supplied.
			 */
			if (dp->tdir_count == 1) {
				v = TIFFExtractData(tif,
				    dp->tdir_type, dp->tdir_offset);
				if (!TIFFSetField(tif, dp->tdir_tag, (int)v))
					goto bad;
				break;
			}
			if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
			    !TIFFSetField(tif, dp->tdir_tag, iv))
				goto bad;
			dp->tdir_tag = IGNORE;
			break;
		case TIFFTAG_STRIPOFFSETS:
		case TIFFTAG_STRIPBYTECOUNTS:
		case TIFFTAG_TILEOFFSETS:
		case TIFFTAG_TILEBYTECOUNTS:
			TIFFSetFieldBit(tif, fip->field_bit);
			break;
		case TIFFTAG_IMAGEWIDTH:
		case TIFFTAG_IMAGELENGTH:
		case TIFFTAG_IMAGEDEPTH:
		case TIFFTAG_TILELENGTH:
		case TIFFTAG_TILEWIDTH:
		case TIFFTAG_TILEDEPTH:
		case TIFFTAG_PLANARCONFIG:
		case TIFFTAG_ROWSPERSTRIP:
			if (!TIFFFetchNormalTag(tif, dp))
				goto bad;
			dp->tdir_tag = IGNORE;
			break;
		case TIFFTAG_EXTRASAMPLES:
			(void) TIFFFetchExtraSamples(tif, dp);
			dp->tdir_tag = IGNORE;
			break;
		}
	}

	/*
	 * Allocate directory structure and setup defaults.
	 */
	if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
		MissingRequired(tif, "ImageLength");
		goto bad;
	}
	if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
		MissingRequired(tif, "PlanarConfiguration");
		goto bad;
	}
	/* 
 	 * Setup appropriate structures (by strip or by tile)
	 */
	if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
		td->td_nstrips = TIFFNumberOfStrips(tif);
		td->td_tilewidth = td->td_imagewidth;
		td->td_tilelength = td->td_rowsperstrip;
		td->td_tiledepth = td->td_imagedepth;
		tif->tif_flags &= ~TIFF_ISTILED;
	} else {
		td->td_nstrips = TIFFNumberOfTiles(tif);
		tif->tif_flags |= TIFF_ISTILED;
	}
	td->td_stripsperimage = td->td_nstrips;
	if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
		td->td_stripsperimage /= td->td_samplesperpixel;
	if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
		MissingRequired(tif,
		    isTiled(tif) ? "TileOffsets" : "StripOffsets");
		goto bad;
	}

	/*
	 * Second pass: extract other information.
	 */
	for (dp = dir, n = dircount; n > 0; n--, dp++) {
		if (dp->tdir_tag == IGNORE)
			continue;
		switch (dp->tdir_tag) {
		case TIFFTAG_MINSAMPLEVALUE:
		case TIFFTAG_MAXSAMPLEVALUE:
		case TIFFTAG_BITSPERSAMPLE:
			/*
			 * The 5.0 spec says the Compression tag has
			 * one value, while earlier specs say it has
			 * one value per sample.  Because of this, we
			 * accept the tag if one value is supplied.
			 *
			 * The MinSampleValue, MaxSampleValue and
			 * BitsPerSample tags are supposed to be written
			 * as one value/sample, but some vendors incorrectly
			 * write one value only -- so we accept that
			 * as well (yech).
			 */
			if (dp->tdir_count == 1) {
				v = TIFFExtractData(tif,
				    dp->tdir_type, dp->tdir_offset);
				if (!TIFFSetField(tif, dp->tdir_tag, (int)v))
					goto bad;
				break;
			}
			/* fall thru... */
		case TIFFTAG_DATATYPE:
		case TIFFTAG_SAMPLEFORMAT:
			if (!TIFFFetchPerSampleShorts(tif, dp, &iv) ||
			    !TIFFSetField(tif, dp->tdir_tag, iv))
				goto bad;
			break;
		case TIFFTAG_SMINSAMPLEVALUE:
		case TIFFTAG_SMAXSAMPLEVALUE:
			if (!TIFFFetchPerSampleAnys(tif, dp, &dv) ||
			    !TIFFSetField(tif, dp->tdir_tag, dv))
				goto bad;
			break;
		case TIFFTAG_STRIPOFFSETS:
		case TIFFTAG_TILEOFFSETS:
			if (!TIFFFetchStripThing(tif, dp,
			    td->td_nstrips, &td->td_stripoffset))
				goto bad;
			break;
		case TIFFTAG_STRIPBYTECOUNTS:
		case TIFFTAG_TILEBYTECOUNTS:
			if (!TIFFFetchStripThing(tif, dp,
			    td->td_nstrips, &td->td_stripbytecount))
				goto bad;
			break;
		case TIFFTAG_COLORMAP:
		case TIFFTAG_TRANSFERFUNCTION:
			/*
			 * TransferFunction can have either 1x or 3x data
			 * values; Colormap can have only 3x items.
			 */
			v = 1L<<td->td_bitspersample;
			if (dp->tdir_tag == TIFFTAG_COLORMAP ||
			    dp->tdir_count != (uint32) v) {
				if (!CheckDirCount(tif, dp, (uint32)(3*v)))
					break;
			}
			v *= sizeof (uint16);
			cp = CheckMalloc(tif, dp->tdir_count * sizeof (uint16),
			    "to read \"TransferFunction\" tag");
			if (cp != NULL) {
				if (TIFFFetchData(tif, dp, cp)) {
					/*
					 * This deals with there being only
					 * one array to apply to all samples.
					 */
					uint32 c =
					    (uint32)1 << td->td_bitspersample;
					if (dp->tdir_count == c)
						v = 0;
					TIFFSetField(tif, dp->tdir_tag,
					    cp, cp+v, cp+2*v);
				}
				_TIFFfree(cp);
			}
			break;
		case TIFFTAG_PAGENUMBER:
		case TIFFTAG_HALFTONEHINTS:
		case TIFFTAG_YCBCRSUBSAMPLING:
		case TIFFTAG_DOTRANGE:
			(void) TIFFFetchShortPair(tif, dp);
			break;
#ifdef COLORIMETRY_SUPPORT
		case TIFFTAG_REFERENCEBLACKWHITE:
			(void) TIFFFetchRefBlackWhite(tif, dp);
			break;
#endif
/* BEGIN REV 4.0 COMPATIBILITY */
		case TIFFTAG_OSUBFILETYPE:
			v = 0;
			switch (TIFFExtractData(tif, dp->tdir_type,
			    dp->tdir_offset)) {
			case OFILETYPE_REDUCEDIMAGE:
				v = FILETYPE_REDUCEDIMAGE;
				break;
			case OFILETYPE_PAGE:
				v = FILETYPE_PAGE;
				break;
			}
			if (v)
				(void) TIFFSetField(tif,
				    TIFFTAG_SUBFILETYPE, (int)v);
			break;
/* END REV 4.0 COMPATIBILITY */
		default:
			(void) TIFFFetchNormalTag(tif, dp);
			break;
		}
	}
	/*
	 * Verify Palette image has a Colormap.
	 */
	if (td->td_photometric == PHOTOMETRIC_PALETTE &&
	    !TIFFFieldSet(tif, FIELD_COLORMAP)) {
		MissingRequired(tif, "Colormap");
		goto bad;
	}
	/*
	 * Attempt to deal with a missing StripByteCounts tag.
	 */
	if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
		/*
		 * Some manufacturers violate the spec by not giving
		 * the size of the strips.  In this case, assume there
		 * is one uncompressed strip of data.
		 */
		if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
		    td->td_nstrips > 1) ||
		    (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
		     td->td_nstrips != td->td_samplesperpixel)) {
		    MissingRequired(tif, "StripByteCounts");
		    goto bad;
		}
		TIFFWarning(tif->tif_name,
			"TIFF directory is missing required \"%s\" field, calculating from imagelength",
		    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
		EstimateStripByteCounts(tif, dir, dircount);
#define	BYTECOUNTLOOKSBAD \
    ((td->td_stripbytecount[0] == 0 && td->td_stripoffset[0] != 0) || \
    (td->td_compression == COMPRESSION_NONE && \
     td->td_stripbytecount[0] > TIFFGetFileSize(tif) - td->td_stripoffset[0]))
	} else if (td->td_nstrips == 1 && BYTECOUNTLOOKSBAD) {
		/*
		 * Plexus (and others) sometimes give a value
		 * of zero for a tag when they don't know what
		 * the correct value is!  Try and handle the
		 * simple case of estimating the size of a one
		 * strip image.
		 */
		TIFFWarning(tif->tif_name,
	    "Bogus \"%s\" field, ignoring and calculating from imagelength",
		    _TIFFFieldWithTag(tif,TIFFTAG_STRIPBYTECOUNTS)->field_name);
		EstimateStripByteCounts(tif, dir, dircount);
	}
	if (dir)
		_TIFFfree((char *)dir);
	if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
		td->td_maxsamplevalue = (uint16)((1L<<td->td_bitspersample)-1);
	/*
	 * Setup default compression scheme.
	 */
	if (!TIFFFieldSet(tif, FIELD_COMPRESSION))
		TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
        /*
         * Some manufacturers make life difficult by writing
	 * large amounts of uncompressed data as a single strip.
	 * This is contrary to the recommendations of the spec.
         * The following makes an attempt at breaking such images
	 * into strips closer to the recommended 8k bytes.  A
	 * side effect, however, is that the RowsPerStrip tag
	 * value may be changed.
         */
	if (td->td_nstrips == 1 && td->td_compression == COMPRESSION_NONE &&
	    (tif->tif_flags & (TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP)
		ChopUpSingleUncompressedStrip(tif);
	/*
	 * Reinitialize i/o since we are starting on a new directory.
	 */
	tif->tif_row = (uint32) -1;
	tif->tif_curstrip = (tstrip_t) -1;
	tif->tif_col = (uint32) -1;
	tif->tif_curtile = (ttile_t) -1;
	tif->tif_tilesize = TIFFTileSize(tif);
	tif->tif_scanlinesize = TIFFScanlineSize(tif);
	return (1);
bad:
	if (dir)
		_TIFFfree(dir);
	return (0);
}
Пример #5
0
/*
 * Read the specified tile and setup for decoding. The data buffer is
 * expanded, as necessary, to hold the tile's data.
 */
int
TIFFFillTile(TIFF* tif, ttile_t tile)
{
	static const char module[] = "TIFFFillTile";
	TIFFDirectory *td = &tif->tif_dir;

	if ((tif->tif_flags&TIFF_NOREADRAW)==0)
	{
		/*
		 * FIXME: butecount should have tsize_t type, but for now
		 * libtiff defines tsize_t as a signed 32-bit integer and we
		 * are losing ability to read arrays larger than 2^31 bytes.
		 * So we are using uint32 instead of tsize_t here.
		 */
		uint32 bytecount = td->td_stripbytecount[tile];
		if (bytecount <= 0) {
			TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
			    "%lu: Invalid tile byte count, tile %lu",
			    (unsigned long) bytecount, (unsigned long) tile);
			return (0);
		}
		if (isMapped(tif) &&
		    (isFillOrder(tif, td->td_fillorder)
		     || (tif->tif_flags & TIFF_NOBITREV))) {
			/*
			 * The image is mapped into memory and we either don't
			 * need to flip bits or the compression routine is
			 * going to handle this operation itself.  In this
			 * case, avoid copying the raw data and instead just
			 * reference the data from the memory mapped file
			 * image.  This assumes that the decompression
			 * routines do not modify the contents of the raw data
			 * buffer (if they try to, the application will get a
			 * fault since the file is mapped read-only).
			 */
			if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
				_TIFFfree(tif->tif_rawdata);
			tif->tif_flags &= ~TIFF_MYBUFFER;
			/*
			 * We must check for overflow, potentially causing
			 * an OOB read. Instead of simple
			 *
			 *  td->td_stripoffset[tile]+bytecount > tif->tif_size
			 *
			 * comparison (which can overflow) we do the following
			 * two comparisons:
			 */
			if (bytecount > tif->tif_size ||
			    td->td_stripoffset[tile] > tif->tif_size - bytecount) {
				tif->tif_curtile = NOTILE;
				return (0);
			}
			tif->tif_rawdatasize = bytecount;
			tif->tif_rawdata =
				tif->tif_base + td->td_stripoffset[tile];
		} else {
			/*
			 * Expand raw data buffer, if needed, to hold data
			 * tile coming from file (perhaps should set upper
			 * bound on the size of a buffer we'll use?).
			 */
			if (bytecount > (uint32)tif->tif_rawdatasize) {
				tif->tif_curtile = NOTILE;
				if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
					TIFFErrorExt(tif->tif_clientdata,
						     module,
				"%s: Data buffer too small to hold tile %ld",
						     tif->tif_name,
						     (long) tile);
					return (0);
				}
				if (!TIFFReadBufferSetup(tif, 0,
				    TIFFroundup(bytecount, 1024)))
					return (0);
			}
			if ((uint32)TIFFReadRawTile1(tif, tile,
				(unsigned char *)tif->tif_rawdata,
				bytecount, module) != bytecount)
				return (0);
			if (!isFillOrder(tif, td->td_fillorder) &&
			    (tif->tif_flags & TIFF_NOBITREV) == 0)
				TIFFReverseBits(tif->tif_rawdata, bytecount);
		}
	}
	return (TIFFStartTile(tif, tile));
}
Пример #6
0
static int
cvt_whole_image( TIFF *in, TIFF *out )

{
    uint32* raster;			/* retrieve RGBA image */
    uint32  width, height;		/* image width & height */
    uint32  row;
    size_t pixel_count;
        
    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);
    pixel_count = width * height;

    /* XXX: Check the integer overflow. */
    if (!width || !height || pixel_count / width != height) {
        TIFFError(TIFFFileName(in),
		  "Malformed input file; can't allocate buffer for raster of %lux%lu size",
		  (unsigned long)width, (unsigned long)height);
        return 0;
    }

    rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
    TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

    raster = (uint32*)_TIFFCheckMalloc(in, pixel_count, sizeof(uint32), "raster buffer");
    if (raster == 0) {
        TIFFError(TIFFFileName(in), "Requested buffer size is %lu elements %lu each",
		  (unsigned long)pixel_count, (unsigned long)sizeof(uint32));
        return (0);
    }

    /* Read the image in one chunk into an RGBA array */
    if (!TIFFReadRGBAImageOriented(in, width, height, raster,
                                   ORIENTATION_TOPLEFT, 0)) {
        _TIFFfree(raster);
        return (0);
    }

    /*
     * XXX: raster array has 4-byte unsigned integer type, that is why
     * we should rearrange it here.
     */
#if HOST_BIGENDIAN
    TIFFSwabArrayOfLong(raster, width * height);
#endif

    /*
     * Do we want to strip away alpha components?
     */
    if (no_alpha)
    {
        size_t count = pixel_count;
        unsigned char *src, *dst;

	src = dst = (unsigned char *) raster;
        while (count > 0)
        {
	    *(dst++) = *(src++);
	    *(dst++) = *(src++);
	    *(dst++) = *(src++);
	    src++;
	    count--;
        }
    }

    /*
     * Write out the result in strips
     */
    for (row = 0; row < height; row += rowsperstrip)
    {
        unsigned char * raster_strip;
        int	rows_to_write;
        int	bytes_per_pixel;

        if (no_alpha)
        {
            raster_strip = ((unsigned char *) raster) + 3 * row * width;
            bytes_per_pixel = 3;
        }
        else
        {
            raster_strip = (unsigned char *) (raster + row * width);
            bytes_per_pixel = 4;
        }

        if( row + rowsperstrip > height )
            rows_to_write = height - row;
        else
            rows_to_write = rowsperstrip;

        if( TIFFWriteEncodedStrip( out, row / rowsperstrip, raster_strip,
                             bytes_per_pixel * rows_to_write * width ) == -1 )
        {
            _TIFFfree( raster );
            return 0;
        }
    }

    _TIFFfree( raster );

    return 1;
}
Пример #7
0
/*
 * Print the contents of the current directory
 * to the specified stdio file stream.
 */
void
TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
{
	TIFFDirectory *td = &tif->tif_dir;
	char *sep;
	uint16 i;
	long l, n;

	fprintf(fd, "TIFF Directory at offset 0x%lx (%lu)\n",
		(unsigned long)tif->tif_diroff, (unsigned long)tif->tif_diroff);
	if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
		fprintf(fd, "  Subfile Type:");
		sep = " ";
		if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
			fprintf(fd, "%sreduced-resolution image", sep);
			sep = "/";
		}
		if (td->td_subfiletype & FILETYPE_PAGE) {
			fprintf(fd, "%smulti-page document", sep);
			sep = "/";
		}
		if (td->td_subfiletype & FILETYPE_MASK)
			fprintf(fd, "%stransparency mask", sep);
		fprintf(fd, " (%lu = 0x%lx)\n",
		    (long) td->td_subfiletype, (long) td->td_subfiletype);
	}
	if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
		fprintf(fd, "  Image Width: %lu Image Length: %lu",
		    (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
		if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
			fprintf(fd, " Image Depth: %lu",
			    (unsigned long) td->td_imagedepth);
		fprintf(fd, "\n");
	}
	if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
		fprintf(fd, "  Tile Width: %lu Tile Length: %lu",
		    (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
		if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
			fprintf(fd, " Tile Depth: %lu",
			    (unsigned long) td->td_tiledepth);
		fprintf(fd, "\n");
	}
	if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
		fprintf(fd, "  Resolution: %g, %g",
		    td->td_xresolution, td->td_yresolution);
		if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
			switch (td->td_resolutionunit) {
			case RESUNIT_NONE:
				fprintf(fd, " (unitless)");
				break;
			case RESUNIT_INCH:
				fprintf(fd, " pixels/inch");
				break;
			case RESUNIT_CENTIMETER:
				fprintf(fd, " pixels/cm");
				break;
			default:
				fprintf(fd, " (unit %u = 0x%x)",
				    td->td_resolutionunit,
				    td->td_resolutionunit);
				break;
			}
		}
		fprintf(fd, "\n");
	}
	if (TIFFFieldSet(tif,FIELD_POSITION))
		fprintf(fd, "  Position: %g, %g\n",
		    td->td_xposition, td->td_yposition);
	if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
		fprintf(fd, "  Bits/Sample: %u\n", td->td_bitspersample);
	if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
		fprintf(fd, "  Sample Format: ");
		switch (td->td_sampleformat) {
		case SAMPLEFORMAT_VOID:
			fprintf(fd, "void\n");
			break;
		case SAMPLEFORMAT_INT:
			fprintf(fd, "signed integer\n");
			break;
		case SAMPLEFORMAT_UINT:
			fprintf(fd, "unsigned integer\n");
			break;
		case SAMPLEFORMAT_IEEEFP:
			fprintf(fd, "IEEE floating point\n");
			break;
		case SAMPLEFORMAT_COMPLEXINT:
			fprintf(fd, "complex signed integer\n");
			break;
		case SAMPLEFORMAT_COMPLEXIEEEFP:
			fprintf(fd, "complex IEEE floating point\n");
			break;
		default:
			fprintf(fd, "%u (0x%x)\n",
			    td->td_sampleformat, td->td_sampleformat);
			break;
		}
	}
	if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
		const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
		fprintf(fd, "  Compression Scheme: ");
		if (c)
			fprintf(fd, "%s\n", c->name);
		else
			fprintf(fd, "%u (0x%x)\n",
			    td->td_compression, td->td_compression);
	}
	if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
		fprintf(fd, "  Photometric Interpretation: ");
		if (td->td_photometric < NPHOTONAMES)
			fprintf(fd, "%s\n", photoNames[td->td_photometric]);
		else {
			switch (td->td_photometric) {
			case PHOTOMETRIC_LOGL:
				fprintf(fd, "CIE Log2(L)\n");
				break;
			case PHOTOMETRIC_LOGLUV:
				fprintf(fd, "CIE Log2(L) (u',v')\n");
				break;
			default:
				fprintf(fd, "%u (0x%x)\n",
				    td->td_photometric, td->td_photometric);
				break;
			}
		}
	}
	if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
		fprintf(fd, "  Extra Samples: %u<", td->td_extrasamples);
		sep = "";
		for (i = 0; i < td->td_extrasamples; i++) {
			switch (td->td_sampleinfo[i]) {
			case EXTRASAMPLE_UNSPECIFIED:
				fprintf(fd, "%sunspecified", sep);
				break;
			case EXTRASAMPLE_ASSOCALPHA:
				fprintf(fd, "%sassoc-alpha", sep);
				break;
			case EXTRASAMPLE_UNASSALPHA:
				fprintf(fd, "%sunassoc-alpha", sep);
				break;
			default:
				fprintf(fd, "%s%u (0x%x)", sep,
				    td->td_sampleinfo[i], td->td_sampleinfo[i]);
				break;
			}
			sep = ", ";
		}
		fprintf(fd, ">\n");
	}
	if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
		char* cp;
		fprintf(fd, "  Ink Names: ");
		i = td->td_samplesperpixel;
		sep = "";
		for (cp = td->td_inknames; i > 0; cp = strchr(cp,'\0')+1, i--) {
			fputs(sep, fd);
			_TIFFprintAscii(fd, cp);
			sep = ", ";
		}
                fputs("\n", fd);
	}
	if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
		fprintf(fd, "  Thresholding: ");
		switch (td->td_threshholding) {
		case THRESHHOLD_BILEVEL:
			fprintf(fd, "bilevel art scan\n");
			break;
		case THRESHHOLD_HALFTONE:
			fprintf(fd, "halftone or dithered scan\n");
			break;
		case THRESHHOLD_ERRORDIFFUSE:
			fprintf(fd, "error diffused\n");
			break;
		default:
			fprintf(fd, "%u (0x%x)\n",
			    td->td_threshholding, td->td_threshholding);
			break;
		}
	}
	if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
		fprintf(fd, "  FillOrder: ");
		switch (td->td_fillorder) {
		case FILLORDER_MSB2LSB:
			fprintf(fd, "msb-to-lsb\n");
			break;
		case FILLORDER_LSB2MSB:
			fprintf(fd, "lsb-to-msb\n");
			break;
		default:
			fprintf(fd, "%u (0x%x)\n",
			    td->td_fillorder, td->td_fillorder);
			break;
		}
	}
	if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
        {
            /*
             * For hacky reasons (see tif_jpeg.c - JPEGFixupTestSubsampling),
             * we need to fetch this rather than trust what is in our
             * structures.
             */
            uint16 subsampling[2];

            TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
                          subsampling + 0, subsampling + 1 );
		fprintf(fd, "  YCbCr Subsampling: %u, %u\n",
                        subsampling[0], subsampling[1] );
        }
	if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
		fprintf(fd, "  YCbCr Positioning: ");
		switch (td->td_ycbcrpositioning) {
		case YCBCRPOSITION_CENTERED:
			fprintf(fd, "centered\n");
			break;
		case YCBCRPOSITION_COSITED:
			fprintf(fd, "cosited\n");
			break;
		default:
			fprintf(fd, "%u (0x%x)\n",
			    td->td_ycbcrpositioning, td->td_ycbcrpositioning);
			break;
		}
	}
	if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
		fprintf(fd, "  Halftone Hints: light %u dark %u\n",
		    td->td_halftonehints[0], td->td_halftonehints[1]);
	if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
		fprintf(fd, "  Orientation: ");
		if (td->td_orientation < NORIENTNAMES)
			fprintf(fd, "%s\n", orientNames[td->td_orientation]);
		else
			fprintf(fd, "%u (0x%x)\n",
			    td->td_orientation, td->td_orientation);
	}
	if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
		fprintf(fd, "  Samples/Pixel: %u\n", td->td_samplesperpixel);
	if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
		fprintf(fd, "  Rows/Strip: ");
		if (td->td_rowsperstrip == (uint32) -1)
			fprintf(fd, "(infinite)\n");
		else
			fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
	}
	if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
		fprintf(fd, "  Min Sample Value: %u\n", td->td_minsamplevalue);
	if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
		fprintf(fd, "  Max Sample Value: %u\n", td->td_maxsamplevalue);
	if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
		fprintf(fd, "  SMin Sample Value: %g\n",
		    td->td_sminsamplevalue);
	if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
		fprintf(fd, "  SMax Sample Value: %g\n",
		    td->td_smaxsamplevalue);
	if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
		fprintf(fd, "  Planar Configuration: ");
		switch (td->td_planarconfig) {
		case PLANARCONFIG_CONTIG:
			fprintf(fd, "single image plane\n");
			break;
		case PLANARCONFIG_SEPARATE:
			fprintf(fd, "separate image planes\n");
			break;
		default:
			fprintf(fd, "%u (0x%x)\n",
			    td->td_planarconfig, td->td_planarconfig);
			break;
		}
	}
	if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
		fprintf(fd, "  Page Number: %u-%u\n",
		    td->td_pagenumber[0], td->td_pagenumber[1]);
	if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
		fprintf(fd, "  Color Map: ");
		if (flags & TIFFPRINT_COLORMAP) {
			fprintf(fd, "\n");
			n = 1L<<td->td_bitspersample;
			for (l = 0; l < n; l++)
				fprintf(fd, "   %5lu: %5u %5u %5u\n",
				    l,
				    td->td_colormap[0][l],
				    td->td_colormap[1][l],
				    td->td_colormap[2][l]);
		} else
			fprintf(fd, "(present)\n");
	}
	if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
		fprintf(fd, "  Transfer Function: ");
		if (flags & TIFFPRINT_CURVES) {
			fprintf(fd, "\n");
			n = 1L<<td->td_bitspersample;
			for (l = 0; l < n; l++) {
				fprintf(fd, "    %2lu: %5u",
				    l, td->td_transferfunction[0][l]);
				for (i = 1; i < td->td_samplesperpixel; i++)
					fprintf(fd, " %5u",
					    td->td_transferfunction[i][l]);
				fputc('\n', fd);
			}
		} else
			fprintf(fd, "(present)\n");
	}
	if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
		fprintf(fd, "  SubIFD Offsets:");
		for (i = 0; i < td->td_nsubifd; i++)
			fprintf(fd, " %5lu", (long) td->td_subifd[i]);
		fputc('\n', fd);
	}

        /*
        ** Custom tag support.
        */
        {
            int  i;
            short count;

            count = (short) TIFFGetTagListCount(tif);
            for(i = 0; i < count; i++) {
                ttag_t  tag = TIFFGetTagListEntry(tif, i);
                const TIFFFieldInfo *fip;
                uint32 value_count;
                int mem_alloc = 0;
                void *raw_data;

                fip = TIFFFieldWithTag(tif, tag);
                if(fip == NULL)
			continue;

		if(fip->field_passcount) {
			if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
				continue;
		} else {
			if (fip->field_readcount == TIFF_VARIABLE
			    || fip->field_readcount == TIFF_VARIABLE2)
				value_count = 1;
			else if (fip->field_readcount == TIFF_SPP)
				value_count = td->td_samplesperpixel;
			else
				value_count = fip->field_readcount;
			if ((fip->field_type == TIFF_ASCII
			     || fip->field_readcount == TIFF_VARIABLE
			     || fip->field_readcount == TIFF_VARIABLE2
			     || fip->field_readcount == TIFF_SPP
			     || value_count > 1)
			    && fip->field_tag != TIFFTAG_PAGENUMBER
			    && fip->field_tag != TIFFTAG_HALFTONEHINTS
			    && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
			    && fip->field_tag != TIFFTAG_DOTRANGE) {
				if(TIFFGetField(tif, tag, &raw_data) != 1)
					continue;
			} else if (fip->field_tag != TIFFTAG_PAGENUMBER
				   && fip->field_tag != TIFFTAG_HALFTONEHINTS
				   && fip->field_tag != TIFFTAG_YCBCRSUBSAMPLING
				   && fip->field_tag != TIFFTAG_DOTRANGE) {
				raw_data = _TIFFmalloc(
					_TIFFDataSize(fip->field_type)
					* value_count);
				mem_alloc = 1;
				if(TIFFGetField(tif, tag, raw_data) != 1) {
					_TIFFfree(raw_data);
					continue;
				}
			} else {
				/* 
				 * XXX: Should be fixed and removed, see the
				 * notes related to TIFFTAG_PAGENUMBER,
				 * TIFFTAG_HALFTONEHINTS,
				 * TIFFTAG_YCBCRSUBSAMPLING and
				 * TIFFTAG_DOTRANGE tags in tif_dir.c. */
				char *tmp;
				raw_data = _TIFFmalloc(
					_TIFFDataSize(fip->field_type)
					* value_count);
				tmp = raw_data;
				mem_alloc = 1;
				if(TIFFGetField(tif, tag, tmp,
				tmp + _TIFFDataSize(fip->field_type)) != 1) {
					_TIFFfree(raw_data);
					continue;
				}
			}
		}

		/*
		 * Catch the tags which needs to be specially handled and
		 * pretty print them. If tag not handled in
		 * _TIFFPrettyPrintField() fall down and print it as any other
		 * tag.
		 */
		if (_TIFFPrettyPrintField(tif, fd, tag, value_count, raw_data)) {
			if(mem_alloc)
				_TIFFfree(raw_data);
			continue;
		}
		else
			_TIFFPrintField(fd, fip, value_count, raw_data);

		if(mem_alloc)
			_TIFFfree(raw_data);
            }
        }
        
	if (tif->tif_tagmethods.printdir)
		(*tif->tif_tagmethods.printdir)(tif, fd, flags);
	if ((flags & TIFFPRINT_STRIPS) &&
	    TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
		tstrip_t s;

		fprintf(fd, "  %lu %s:\n",
		    (long) td->td_nstrips,
		    isTiled(tif) ? "Tiles" : "Strips");
		for (s = 0; s < td->td_nstrips; s++)
			fprintf(fd, "    %3lu: [%8lu, %8lu]\n",
			    (unsigned long) s,
			    (unsigned long) td->td_stripoffset[s],
			    (unsigned long) td->td_stripbytecount[s]);
	}
}
Пример #8
0
/* This function will write an entire directory to the disk, and return the
   offset value indicating where in the file it wrote the beginning of the
   directory structure. This is NOT the same as the offset value before
   calling this function, because some of the fields may have caused various
   data items to be written out BEFORE writing the directory structure.

   This code was basically written by ripping of the TIFFWriteDirectory() 
   code and generalizing it, using RPS's TIFFWritePliIfd() code for
   inspiration.  My original goal was to make this code general enough that
   the original TIFFWriteDirectory() could be rewritten to just call this
   function with the appropriate field and field-accessing arguments.

   However, now I realize that there's a lot of code that gets executed for
   the main, standard TIFF directories that does not apply to special
   private subdirectories, so such a reimplementation for the sake of
   eliminating redundant or duplicate code is probably not possible,
   unless we also pass in a Main flag to indiciate which type of handling
   to do, which would be kind of a hack. I've marked those places where I
   changed or ripped out code which would have to be re-inserted to
   generalize this function. If it can be done in a clean and graceful way,
   it would be a great way to generalize the TIFF library. Otherwise, I'll
   just leave this code here where it duplicates but remains on top of and
   hopefully mostly independent of the main TIFF library.

   The caller will probably want to free the sub directory structure after
   returning from this call, since otherwise once written out, the user
   is likely to forget about it and leave data lying around.
*/
toff_t
TIFFWritePrivateDataSubDirectory(TIFF* tif,
				 uint32 pdir_fieldsset[], int pdir_fields_last,
				 TIFFFieldInfo *field_info,
				 int (*getFieldFn)(TIFF *tif, ttag_t tag, ...))
{
	uint16 dircount;
	uint32 diroff, nextdiroff;
	ttag_t tag;
	uint32 nfields;
	tsize_t dirsize;
	char* data;
	TIFFDirEntry* dir;
	u_long b, *fields, fields_size;
	toff_t directory_offset;
	TIFFFieldInfo* fip;

	/*
	 * Deleted out all of the encoder flushing and such code from here -
	 * not necessary for subdirectories.
	 */

	/* Finish writing out any image data. */
	TIFFFlushData(tif);

	/*
	 * Size the directory so that we can calculate
	 * offsets for the data items that aren't kept
	 * in-place in each field.
	 */
	nfields = 0;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
	for (b = 0; b <= pdir_fields_last; b++)
		if (FieldSet(pdir_fieldsset, b))
			/* Deleted code to make size of first 4 tags 2
			   instead of 1. */
			nfields += 1;
	dirsize = nfields * sizeof (TIFFDirEntry);
	data = (char*) _TIFFmalloc(dirsize);
	if (data == NULL) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
		    "Cannot write private subdirectory, out of space");
		return (0);
	}
	/*
	 * Place directory in data section of the file. If there isn't one
	 * yet, place it at the end of the file. The directory is treated as
	 * data, so we don't link it into the directory structure at all.
	 */
	if (tif->tif_dataoff == 0)
	    tif->tif_dataoff =(TIFFSeekFile(tif, (toff_t) 0, SEEK_END)+1) &~ 1;
	diroff = tif->tif_dataoff;
	tif->tif_dataoff = (toff_t)(
	    diroff + sizeof (uint16) + dirsize + sizeof (toff_t));
	if (tif->tif_dataoff & 1)
		tif->tif_dataoff++;
	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
	/*tif->tif_curdir++;*/
	dir = (TIFFDirEntry*) data;
	/*
	 * Setup external form of directory
	 * entries and write data items.
	 */
	/*
	 * We make a local copy of the fieldsset here so that we don't mess
	 * up the original one when we call ResetFieldBit(). But I'm not sure
	 * why the original code calls ResetFieldBit(), since we're already
	 * going through the fields in order...
	 *
	 * fields_size is the number of uint32's we will need to hold the
	 * bit-mask for all of the fields. If our highest field number is
	 * 100, then we'll need 100 / (8*4)+1 == 4 uint32's to hold the
	 * fieldset.
	 *
	 * Unlike the original code, we allocate fields dynamically based
	 * on the requested pdir_fields_last value, allowing private
	 * data subdirectories to contain more than the built-in code's limit
	 * of 95 tags in a directory.
	 */
	fields_size = pdir_fields_last / (8*sizeof(uint32)) + 1;
	fields = _TIFFmalloc(fields_size*sizeof(uint32));
	_TIFFmemcpy(fields, pdir_fieldsset, fields_size * sizeof(uint32));

	/* Deleted "write out extra samples tag" code here. */

	/* Deleted code for checking a billion little special cases for the
	 * standard TIFF tags. Should add a general mechanism for overloading
	 * write function for each field, just like Brian kept telling me!!!
	 */
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
	for (fip = field_info; fip->field_tag; fip++) {
		/* Deleted code to check for FIELD_IGNORE!! */
		if (/* fip->field_bit == FIELD_IGNORE || */
		    !FieldSet(fields, fip->field_bit))
			continue;
		if (!TIFFWriteNormalSubTag(tif, dir, fip, getFieldFn))
			goto bad;
		dir++;
		ResetFieldBit(fields, fip->field_bit);
	}

	/* Now we've written all of the referenced data, and are about to
	   write the main directory structure, so grab the tif_dataoff value
	   now so we can remember where we wrote the directory. */
	directory_offset = tif->tif_dataoff;

	/*
	 * Write directory.
	 */
	dircount = (uint16) nfields;
	/* Deleted code to link to the next directory - we set it to zero! */
	nextdiroff = 0;
	if (tif->tif_flags & TIFF_SWAB) {
		/*
		 * The file's byte order is opposite to the
		 * native machine architecture.  We overwrite
		 * the directory information with impunity
		 * because it'll be released below after we
		 * write it to the file.  Note that all the
		 * other tag construction routines assume that
		 * we do this byte-swapping; i.e. they only
		 * byte-swap indirect data.
		 */
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		for (dir = (TIFFDirEntry*) data; dircount; dir++, dircount--) {
			TIFFSwabArrayOfShort(&dir->tdir_tag, 2);
			TIFFSwabArrayOfLong(&dir->tdir_count, 2);
		}
		dircount = (uint16) nfields;
		TIFFSwabShort(&dircount);
		TIFFSwabLong(&nextdiroff);
	}

	(void) TIFFSeekFile(tif, tif->tif_dataoff, SEEK_SET);
	if (!WriteOK(tif, &dircount, sizeof (dircount))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory count");
		goto bad;
	}
	if (!WriteOK(tif, data, dirsize)) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory contents");
		goto bad;
	}
	if (!WriteOK(tif, &nextdiroff, sizeof (nextdiroff))) {
		TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Error writing private subdirectory link");
		goto bad;
	}
	tif->tif_dataoff += sizeof(dircount) + dirsize + sizeof(nextdiroff);

	_TIFFfree(data);
	_TIFFfree(fields);
	tif->tif_flags &= ~TIFF_DIRTYDIRECT;

#if (0)
	/* This stuff commented out because I don't think we want it for
	   subdirectories, but I could be wrong. */
	(*tif->tif_cleanup)(tif);

	/*
	 * Reset directory-related state for subsequent
	 * directories.
	 */
	TIFFDefaultDirectory(tif);
	tif->tif_curoff = 0;
	tif->tif_row = (uint32) -1;
	tif->tif_curstrip = (tstrip_t) -1;
#endif

	return (directory_offset);
bad:
	_TIFFfree(data);
	_TIFFfree(fields);
	return (0);
}
Пример #9
0
/*
 * Write an array of ``type'' values for a specified tag (i.e. this is a tag
 * which is allowed to have different types, e.g. SMaxSampleType).
 * Internally the data values are represented as double since a double can
 * hold any of the TIFF tag types (yes, this should really be an abstract
 * type tany_t for portability).  The data is converted into the specified
 * type in a temporary buffer and then handed off to the appropriate array
 * writer.
 */
static int
TIFFWriteAnyArray(TIFF* tif,
    TIFFDataType type, ttag_t tag, TIFFDirEntry* dir, uint32 n, double* v)
{
	char buf[10 * sizeof(double)];
	char* w = buf;
	int i, status = 0;

	if (n * TIFFDataWidth(type) > sizeof buf)
		w = (char*) _TIFFmalloc(n * TIFFDataWidth(type));
	switch (type) {
	case TIFF_BYTE:
		{ unsigned char* bp = (unsigned char*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (unsigned char) v[i];
		  dir->tdir_tag = tag;
		  dir->tdir_type = (short) type;
		  dir->tdir_count = n;
		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
			goto out;
		}
		break;
	case TIFF_SBYTE:
		{ signed char* bp = (signed char*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (signed char) v[i];
		  dir->tdir_tag = tag;
		  dir->tdir_type = (short) type;
		  dir->tdir_count = n;
		  if (!TIFFWriteByteArray(tif, dir, (char*) bp))
			goto out;
		}
		break;
	case TIFF_SHORT:
		{ uint16* bp = (uint16*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (uint16) v[i];
		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
				goto out;
		}
		break;
	case TIFF_SSHORT:
		{ int16* bp = (int16*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (int16) v[i];
		  if (!TIFFWriteShortArray(tif, type, tag, dir, n, (uint16*)bp))
			goto out;
		}
		break;
	case TIFF_LONG:
		{ uint32* bp = (uint32*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (uint32) v[i];
		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, bp))
			goto out;
		}
		break;
	case TIFF_SLONG:
		{ int32* bp = (int32*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (int32) v[i];
		  if (!TIFFWriteLongArray(tif, type, tag, dir, n, (uint32*) bp))
			goto out;
		}
		break;
	case TIFF_FLOAT:
		{ float* bp = (float*) w;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
		  for (i = 0; i < n; i++)
			bp[i] = (float) v[i];
		  if (!TIFFWriteFloatArray(tif, type, tag, dir, n, bp))
			goto out;
		}
		break;
	case TIFF_DOUBLE:
		return (TIFFWriteDoubleArray(tif, type, tag, dir, n, v));
	default:
		/* TIFF_NOTYPE */
		/* TIFF_ASCII */
		/* TIFF_UNDEFINED */
		/* TIFF_RATIONAL */
		/* TIFF_SRATIONAL */
		goto out;
	}
	status = 1;
 out:
	if (w != buf)
		_TIFFfree(w);
	return (status);
}
Пример #10
0
void
PSRawDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	uint32 *bc;
	uint32 bufsize;
	int breaklen = MAXLINE, cc;
	uint16 fillorder;
	unsigned char *tf_buf;
	unsigned char *cp, c;
	tstrip_t s;

#if defined( EXP_ASCII85ENCODER )
	int			ascii85_l;		/* Length, in bytes, of ascii85_p[] data */
	uint8		*	ascii85_p = 0;		/* Holds ASCII85 encoded data */
#endif

	(void) w; (void) h;
	TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
	TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);

	/*
	 * Find largest strip:
	 */

	bufsize = bc[0];

	for ( s = 0; ++s < tf_numberstrips; ) {
		if ( bc[s] > bufsize )
			bufsize = bc[s];
	}

	tf_buf = (unsigned char*) _TIFFmalloc(bufsize);
	if (tf_buf == NULL) {
		TIFFError(filename, "No space for strip buffer");
		return;
	}

#if defined( EXP_ASCII85ENCODER )
	if ( ascii85 ) {
	    /*
	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
	     * that it is allocated with sufficient room to hold the
	     * encoded data (5*bufsize/4) plus the EOD marker (+8)
	     * and formatting line breaks.  The line breaks are more
	     * than taken care of by using 6*bufsize/4 rather than
	     * 5*bufsize/4.
	     */

	    ascii85_p = _TIFFmalloc( (bufsize+(bufsize/2)) + 8 );

	    if ( !ascii85_p ) {
		_TIFFfree( tf_buf );

		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
		return;
	    }
	}
#endif

	for (s = 0; s < tf_numberstrips; s++) {
		cc = TIFFReadRawStrip(tif, s, tf_buf, bc[s]);
		if (cc < 0) {
			TIFFError(filename, "Can't read strip");
			break;
		}
		if (fillorder == FILLORDER_LSB2MSB)
			TIFFReverseBits(tf_buf, cc);
		if (!ascii85) {
			for (cp = tf_buf; cc > 0; cc--) {
				DOBREAK(breaklen, 1, fd);
				c = *cp++;
				PUTHEX(c, fd);
			}
			fputs(">\n", fd);
			breaklen = MAXLINE;
		} else {
		        Ascii85Init();
#if defined( EXP_ASCII85ENCODER )
			ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, tf_buf, cc );

			if ( ascii85_l > 0 )
				fwrite( ascii85_p, ascii85_l, 1, fd );
#else
			for (cp = tf_buf; cc > 0; cc--)
				Ascii85Put(*cp++, fd);
			Ascii85Flush(fd);
#endif	/* EXP_ASCII85ENCODER */
		}
	}
	_TIFFfree((char *) tf_buf);

#if defined( EXP_ASCII85ENCODER )
	if ( ascii85_p )
		_TIFFfree( ascii85_p );
#endif
}
Пример #11
0
int
PS_Lvl2page(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	uint16 fillorder;
	int use_rawdata, tiled_image, breaklen;
	uint32 chunk_no, num_chunks, *bc;
	unsigned char *buf_data, *cp;
	tsize_t chunk_size, byte_count;

#if defined( EXP_ASCII85ENCODER )
	int			ascii85_l;		/* Length, in bytes, of ascii85_p[] data */
	uint8		*	ascii85_p = 0;		/* Holds ASCII85 encoded data */
#endif

	PS_Lvl2colorspace(fd, tif);
	use_rawdata = PS_Lvl2ImageDict(fd, tif, w, h);

	fputs("%%BeginData:\n", fd);
	fputs("exec\n", fd);

	tiled_image = TIFFIsTiled(tif);
	if (tiled_image) {
		num_chunks = TIFFNumberOfTiles(tif);
		TIFFGetField(tif, TIFFTAG_TILEBYTECOUNTS, &bc);
	} else {
		num_chunks = TIFFNumberOfStrips(tif);
		TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &bc);
	}

	if (use_rawdata) {
		chunk_size = bc[0];
		for (chunk_no = 1; chunk_no < num_chunks; chunk_no++)
			if (bc[chunk_no] > chunk_size)
				chunk_size = bc[chunk_no];
	} else {
		if (tiled_image)
			chunk_size = TIFFTileSize(tif);
		else
			chunk_size = TIFFStripSize(tif);
	}
	buf_data = (unsigned char *)_TIFFmalloc(chunk_size);
	if (!buf_data) {
		TIFFError(filename, "Can't alloc %u bytes for %s.",
			chunk_size, tiled_image ? "tiles" : "strips");
		return(FALSE);
	}

#if defined( EXP_ASCII85ENCODER )
	if ( ascii85 ) {
	    /*
	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
	     * that it is allocated with sufficient room to hold the
	     * encoded data (5*chunk_size/4) plus the EOD marker (+8)
	     * and formatting line breaks.  The line breaks are more
	     * than taken care of by using 6*chunk_size/4 rather than
	     * 5*chunk_size/4.
	     */

	    ascii85_p = _TIFFmalloc( (chunk_size+(chunk_size/2)) + 8 );

	    if ( !ascii85_p ) {
		_TIFFfree( buf_data );

		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
		return ( FALSE );
	    }
	}
#endif

	TIFFGetFieldDefaulted(tif, TIFFTAG_FILLORDER, &fillorder);
	for (chunk_no = 0; chunk_no < num_chunks; chunk_no++) {
		if (ascii85)
			Ascii85Init();
		else
			breaklen = 36;
		if (use_rawdata) {
			if (tiled_image)
				byte_count = TIFFReadRawTile(tif, chunk_no,
						  buf_data, chunk_size);
			else
				byte_count = TIFFReadRawStrip(tif, chunk_no,
						  buf_data, chunk_size);
			if (fillorder == FILLORDER_LSB2MSB)
			    TIFFReverseBits(buf_data, byte_count);
		} else {
			if (tiled_image)
				byte_count = TIFFReadEncodedTile(tif,
						chunk_no, buf_data,
						chunk_size);
			else
				byte_count = TIFFReadEncodedStrip(tif,
						chunk_no, buf_data,
						chunk_size);
		}
		if (byte_count < 0) {
			TIFFError(filename, "Can't read %s %d.",
				tiled_image ? "tile" : "strip", chunk_no);
			if (ascii85)
				Ascii85Put('\0', fd);
		}

		if (ascii85) {
#if defined( EXP_ASCII85ENCODER )
			ascii85_l = Ascii85EncodeBlock(ascii85_p, 1, buf_data, byte_count );

			if ( ascii85_l > 0 )
				fwrite( ascii85_p, ascii85_l, 1, fd );
#else
			for (cp = buf_data; byte_count > 0; byte_count--)
				Ascii85Put(*cp++, fd);
#endif
		}
		else
		{
			for (cp = buf_data; byte_count > 0; byte_count--) {
				putc(hex[((*cp)>>4)&0xf], fd);
				putc(hex[(*cp)&0xf], fd);
				cp++;

				if (--breaklen <= 0) {
					putc('\n', fd);
					breaklen = 36;
				}
			}
		}

		if ( !ascii85 ) {
			if ( level2 )
				putc( '>', fd );
			putc('\n', fd);
		}
#if !defined( EXP_ASCII85ENCODER )
		else
			Ascii85Flush(fd);
#endif
	}

#if defined( EXP_ASCII85ENCODER )
	if ( ascii85_p )
	    _TIFFfree( ascii85_p );
#endif
       
	_TIFFfree(buf_data);
	fputs("%%EndData\n", fd);
	return(TRUE);
}
Пример #12
0
void
PSDataBW(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	int breaklen = MAXLINE;
	unsigned char* tf_buf;
	unsigned char* cp;
	tsize_t stripsize = TIFFStripSize(tif);
	tstrip_t s;

#if defined( EXP_ASCII85ENCODER )
	int			ascii85_l;		/* Length, in bytes, of ascii85_p[] data */
	uint8		*	ascii85_p = 0;		/* Holds ASCII85 encoded data */
#endif

	(void) w; (void) h;
	tf_buf = (unsigned char *) _TIFFmalloc(stripsize);
	if (tf_buf == NULL) {
		TIFFError(filename, "No space for scanline buffer");
		return;
	}

#if defined( EXP_ASCII85ENCODER )
	if ( ascii85 ) {
	    /*
	     * Allocate a buffer to hold the ASCII85 encoded data.  Note
	     * that it is allocated with sufficient room to hold the
	     * encoded data (5*stripsize/4) plus the EOD marker (+8)
	     * and formatting line breaks.  The line breaks are more
	     * than taken care of by using 6*stripsize/4 rather than
	     * 5*stripsize/4.
	     */

	    ascii85_p = _TIFFmalloc( (stripsize+(stripsize/2)) + 8 );

	    if ( !ascii85_p ) {
		_TIFFfree( tf_buf );

		TIFFError( filename, "Cannot allocate ASCII85 encoding buffer." );
		return;
	    }
	}
#endif

	if (ascii85)
	        Ascii85Init();

	for (s = 0; s < TIFFNumberOfStrips(tif); s++) {
		int cc = TIFFReadEncodedStrip(tif, s, tf_buf, stripsize);
		if (cc < 0) {
			TIFFError(filename, "Can't read strip");
			break;
		}
		cp = tf_buf;
		if (photometric == PHOTOMETRIC_MINISWHITE) {
			for (cp += cc; --cp >= tf_buf;)
				*cp = ~*cp;
			cp++;
		}
		if (ascii85) {
#if defined( EXP_ASCII85ENCODER )
			ascii85_l = Ascii85EncodeBlock( ascii85_p, 1, cp, cc );

			if ( ascii85_l > 0 )
			    fwrite( ascii85_p, ascii85_l, 1, fd );
#else
			while (cc-- > 0)
				Ascii85Put(*cp++, fd);
#endif /* EXP_ASCII85_ENCODER */
		} else {
			while (cc-- > 0) {
				unsigned char c = *cp++;
				DOBREAK(breaklen, 1, fd);
				PUTHEX(c, fd);
			}
		}
	}

	if ( !ascii85 )
	{
	    if ( level2 )
	        fputs(">\n", fd);
	}
#if !defined( EXP_ASCII85ENCODER )
	else
	    Ascii85Flush(fd);
#else
	if ( ascii85_p )
	    _TIFFfree( ascii85_p );
#endif

	_TIFFfree(tf_buf);
}
Пример #13
0
void
PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	uint16 *rmap, *gmap, *bmap;
	uint32 row;
	int breaklen = MAXLINE, cc, nc;
	unsigned char *tf_buf;
	unsigned char *cp, c;

	(void) w;
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		TIFFError(filename, "Palette image w/o \"Colormap\" tag");
		return;
	}
	switch (bitspersample) {
	case 8:	case 4: case 2: case 1:
		break;
	default:
		TIFFError(filename, "Depth %d not supported", bitspersample);
		return;
	}
	nc = 3 * (8 / bitspersample);
	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
	if (tf_buf == NULL) {
		TIFFError(filename, "No space for scanline buffer");
		return;
	}
	if (checkcmap(tif, 1<<bitspersample, rmap, gmap, bmap) == 16) {
		int i;
#define	CVT(x)		(((x) * 255) / ((1U<<16)-1))
		for (i = (1<<bitspersample)-1; i >= 0; i--) {
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
#undef CVT
	}
	for (row = 0; row < h; row++) {
		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
			break;
		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
			DOBREAK(breaklen, nc, fd);
			switch (bitspersample) {
			case 8:
				c = *cp++; PUTRGBHEX(c, fd);
				break;
			case 4:
				c = *cp++; PUTRGBHEX(c&0xf, fd);
				c >>= 4;   PUTRGBHEX(c, fd);
				break;
			case 2:
				c = *cp++; PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c, fd);
				break;
			case 1:
				c = *cp++; PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c, fd);
				break;
			}
		}
	}
	_TIFFfree((char *) tf_buf);
}
Пример #14
0
int
ReadFloat32TIFF(char *pp_file)
{
	TIFF           *lp_tif;
	float          *lp_pixels;
	float          *lp_tiffdata;
	int             lv_nstrips;
	int             lv_stripsize;
	int             lv_counter;
	int             lv_pixel;
	int             lv_npixels;
	uint16          lv_bitsper;
	tdata_t         lp_buf;
	tstrip_t        lv_strip;
	char           *tmp;

	if (lp_tif = TIFFOpen(pp_file, "r"))
	{
		TIFFGetField(lp_tif, TIFFTAG_BITSPERSAMPLE, &lv_bitsper);
		if (lv_bitsper != 32)
		{
			fprintf(stderr, "Depth Image is not 32 bit float (it's %d)!\n", lv_bitsper);
			TIFFClose(lp_tif);
			return 0;
		}
		TIFFGetField(lp_tif, TIFFTAG_IMAGEWIDTH, &gv_width);
		TIFFGetField(lp_tif, TIFFTAG_IMAGELENGTH, &gv_height);

		gp_data = malloc(gv_width * gv_height * sizeof(float));

		lv_pixel = 0;
		lv_npixels = gv_width * gv_height;
		if (lp_tif)
		{
			lv_stripsize = TIFFStripSize(lp_tif) / 4;
			lv_nstrips = TIFFNumberOfStrips(lp_tif);
			lp_buf = _TIFFmalloc(TIFFStripSize(lp_tif));
			lv_counter = 0;
			for (lv_strip = 0; lv_strip < lv_nstrips; lv_strip++)
			{
				TIFFReadEncodedStrip(lp_tif, lv_strip, lp_buf, (tsize_t) - 1);
				lp_tiffdata = (float *) lp_buf;
				for (lv_pixel = 0; lv_pixel < lv_stripsize; lv_pixel++)
				{
					if (lv_counter < lv_npixels)
						gp_data[lv_counter] = lp_tiffdata[lv_pixel];
					if (gp_data[lv_counter] > gv_max)
						gv_max = gp_data[lv_counter];
					if (gp_data[lv_counter] < gv_min)
						gv_min = gp_data[lv_counter];

					lv_counter++;
				}
			}
			_TIFFfree(lp_buf);
		}
		TIFFClose(lp_tif);
	} else
		return 0;
	return 1;
}
Пример #15
0
static int
cvt_by_tile( TIFF *in, TIFF *out )

{
    uint32* raster;			/* retrieve RGBA image */
    uint32  width, height;		/* image width & height */
    uint32  tile_width, tile_height;
    uint32  row, col;
    uint32  *wrk_line;
    int	    ok = 1;

    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);

    if( !TIFFGetField(in, TIFFTAG_TILEWIDTH, &tile_width)
        || !TIFFGetField(in, TIFFTAG_TILELENGTH, &tile_height) ) {
        TIFFError(TIFFFileName(in), "Source image not tiled");
        return (0);
    }
    
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tile_width );
    TIFFSetField(out, TIFFTAG_TILELENGTH, tile_height );

    /*
     * Allocate tile buffer
     */
    raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
    if (raster == 0) {
        TIFFError(TIFFFileName(in), "No space for raster buffer");
        return (0);
    }

    /*
     * Allocate a scanline buffer for swapping during the vertical
     * mirroring pass.
     */
    wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32));
    if (!wrk_line) {
        TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
        ok = 0;
    }
    
    /*
     * Loop over the tiles.
     */
    for( row = 0; ok && row < height; row += tile_height )
    {
        for( col = 0; ok && col < width; col += tile_width )
        {
            uint32 i_row;

            /* Read the tile into an RGBA array */
            if (!TIFFReadRGBATile(in, col, row, raster)) {
                ok = 0;
                break;
            }


	    /*
	     * XXX: raster array has 4-byte unsigned integer type, that is why
	     * we should rearrange it here.
	     */
#if HOST_BIGENDIAN
	    TIFFSwabArrayOfLong(raster, tile_width * tile_height);
#endif

            /*
             * For some reason the TIFFReadRGBATile() function chooses the
             * lower left corner as the origin.  Vertically mirror scanlines.
             */
            for( i_row = 0; i_row < tile_height / 2; i_row++ )
            {
                uint32	*top_line, *bottom_line;

                top_line = raster + tile_width * i_row;
                bottom_line = raster + tile_width * (tile_height-i_row-1);

                _TIFFmemcpy(wrk_line, top_line, 4*tile_width);
                _TIFFmemcpy(top_line, bottom_line, 4*tile_width);
                _TIFFmemcpy(bottom_line, wrk_line, 4*tile_width);
            }

            /*
             * Write out the result in a tile.
             */

            if( TIFFWriteEncodedTile( out,
                                      TIFFComputeTile( out, col, row, 0, 0),
                                      raster,
                                      4 * tile_width * tile_height ) == -1 )
            {
                ok = 0;
                break;
            }
        }
    }

    _TIFFfree( raster );
    _TIFFfree( wrk_line );

    return ok;
}
Пример #16
0
bool KPWriteImage::write2TIFF(const QString& destPath)
{
    uint32 w    = d->width;
    uint32 h    = d->height;
    uchar* data = (uchar*)d->data.data();

    // TIFF error handling. If an errors/warnings occurs during reading,
    // libtiff will call these methods

    TIFFSetWarningHandler(kipi_tiff_warning);
    TIFFSetErrorHandler(kipi_tiff_error);

    // Open target file

    TIFF *tif = TIFFOpen(QFile::encodeName(destPath), "w");
    if (!tif)
    {
        kDebug( 51000 ) << "Failed to open TIFF file for writing" << endl;
        return false;
    }

    int bitsDepth = d->sixteenBit ? 16 : 8;

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH,          w);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH,         h);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC,         PHOTOMETRIC_RGB);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG,        PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_ORIENTATION,         ORIENTATION_TOPLEFT);
    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT,      RESUNIT_NONE);
    TIFFSetField(tif, TIFFTAG_COMPRESSION,         COMPRESSION_ADOBE_DEFLATE);
    TIFFSetField(tif, TIFFTAG_ZIPQUALITY,          9);
    // NOTE : this tag values aren't defined in libtiff 3.6.1. '2' is PREDICTOR_HORIZONTAL.
    //        Use horizontal differencing for images which are
    //        likely to be continuous tone. The TIFF spec says that this
    //        usually leads to better compression.
    //        See this url for more details:
    //        http://www.awaresystems.be/imaging/tiff/tifftags/predictor.html
    TIFFSetField(tif, TIFFTAG_PREDICTOR,           2);

    if (d->hasAlpha)
    {
        TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 4);
        TIFFSetField(tif, TIFFTAG_EXTRASAMPLES,    EXTRASAMPLE_ASSOCALPHA);
    }
    else
    {
        TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
    }

    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE,       (uint16)bitsDepth);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,        TIFFDefaultStripSize(tif, 0));

    // Store Iptc data.
    QByteArray ba2 = d->metadata.getIptc(true);
#if defined(TIFFTAG_PHOTOSHOP)
    TIFFSetField (tif, TIFFTAG_PHOTOSHOP, (uint32)ba2.size(), (uchar *)ba2.data());
#endif

    // Store Xmp data.
    QByteArray ba3 = d->metadata.getXmp();
#if defined(TIFFTAG_XMLPACKET)
    TIFFSetField(tif, TIFFTAG_XMLPACKET, (uint32)ba3.size(), (uchar *)ba3.data());
#endif

    // Standard Exif Ascii tags (available with libtiff 3.6.1)

    tiffSetExifAsciiTag(tif, TIFFTAG_DOCUMENTNAME,     d->metadata, "Exif.Image.DocumentName");
    tiffSetExifAsciiTag(tif, TIFFTAG_IMAGEDESCRIPTION, d->metadata, "Exif.Image.ImageDescription");
    tiffSetExifAsciiTag(tif, TIFFTAG_MAKE,             d->metadata, "Exif.Image.Make");
    tiffSetExifAsciiTag(tif, TIFFTAG_MODEL,            d->metadata, "Exif.Image.Model");
    tiffSetExifAsciiTag(tif, TIFFTAG_DATETIME,         d->metadata, "Exif.Image.DateTime");
    tiffSetExifAsciiTag(tif, TIFFTAG_ARTIST,           d->metadata, "Exif.Image.Artist");
    tiffSetExifAsciiTag(tif, TIFFTAG_COPYRIGHT,        d->metadata, "Exif.Image.Copyright");

    QString libtiffver(TIFFLIB_VERSION_STR);
    libtiffver.replace('\n', ' ');
    QString soft = d->kipipluginsVer;
    soft.append(QString(" ( %1 )").arg(libtiffver));
    TIFFSetField(tif, TIFFTAG_SOFTWARE, (const char*)soft.toAscii().data());

    // Write ICC profil.
    if (!d->iccProfile.isEmpty())
    {
#if defined(TIFFTAG_ICCPROFILE)
        TIFFSetField(tif, TIFFTAG_ICCPROFILE, (uint32)d->iccProfile.size(),
                     (uchar *)d->iccProfile.data());
#endif
    }

    // Write full image data in tiff directory IFD0

    uchar  *pixel;
    double  alpha_factor;
    uint32  x, y;
    uint8   r8, g8, b8, a8=0;
    uint16  r16, g16, b16, a16=0;
    int     i=0;

    uint8 *buf = (uint8 *)_TIFFmalloc(TIFFScanlineSize(tif));
    if (!buf)
    {
        kDebug( 51000 ) << "Cannot allocate memory buffer for main TIFF image." << endl;
        TIFFClose(tif);
        return false;
    }

    for (y = 0; y < h; y++)
    {
        if (cancel())
        {
            _TIFFfree(buf);
            TIFFClose(tif);
            return false;
        }

        i = 0;

        for (x = 0; x < w; x++)
        {
            pixel = &data[((y * w) + x) * bytesDepth()];

            if ( d->sixteenBit )        // 16 bits image.
            {
                b16 = (uint16)(pixel[0]+256*pixel[1]);
                g16 = (uint16)(pixel[2]+256*pixel[3]);
                r16 = (uint16)(pixel[4]+256*pixel[5]);

                if (d->hasAlpha)
                {
                    // TIFF makes you pre-mutiply the rgb components by alpha

                    a16          = (uint16)(pixel[6]+256*pixel[7]);
                    alpha_factor = ((double)a16 / 65535.0);
                    r16          = (uint16)(r16*alpha_factor);
                    g16          = (uint16)(g16*alpha_factor);
                    b16          = (uint16)(b16*alpha_factor);
                }

                // This might be endian dependent

                buf[i++] = (uint8)(r16);
                buf[i++] = (uint8)(r16 >> 8);
                buf[i++] = (uint8)(g16);
                buf[i++] = (uint8)(g16 >> 8);
                buf[i++] = (uint8)(b16);
                buf[i++] = (uint8)(b16 >> 8);

                if (d->hasAlpha)
                {
                    buf[i++] = (uint8)(a16) ;
                    buf[i++] = (uint8)(a16 >> 8) ;
                }
            }
            else                            // 8 bits image.
            {
Пример #17
0
static int
cvt_by_strip( TIFF *in, TIFF *out )

{
    uint32* raster;			/* retrieve RGBA image */
    uint32  width, height;		/* image width & height */
    uint32  row;
    uint32  *wrk_line;
    int	    ok = 1;

    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);

    if( !TIFFGetField(in, TIFFTAG_ROWSPERSTRIP, &rowsperstrip) ) {
        TIFFError(TIFFFileName(in), "Source image not in strips");
        return (0);
    }
    
    TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

    /*
     * Allocate strip buffer
     */
    raster = (uint32*)_TIFFmalloc(width * rowsperstrip * sizeof (uint32));
    if (raster == 0) {
        TIFFError(TIFFFileName(in), "No space for raster buffer");
        return (0);
    }

    /*
     * Allocate a scanline buffer for swapping during the vertical
     * mirroring pass.
     */
    wrk_line = (uint32*)_TIFFmalloc(width * sizeof (uint32));
    if (!wrk_line) {
        TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
        ok = 0;
    }
    
    /*
     * Loop over the strips.
     */
    for( row = 0; ok && row < height; row += rowsperstrip )
    {
        int	rows_to_write, i_row;

        /* Read the strip into an RGBA array */
        if (!TIFFReadRGBAStrip(in, row, raster)) {
            ok = 0;
            break;
        }

	/*
	 * XXX: raster array has 4-byte unsigned integer type, that is why
	 * we should rearrange it here.
	 */
#if HOST_BIGENDIAN
	TIFFSwabArrayOfLong(raster, width * rowsperstrip);
#endif

        /*
         * Figure out the number of scanlines actually in this strip.
         */
        if( row + rowsperstrip > height )
            rows_to_write = height - row;
        else
            rows_to_write = rowsperstrip;

        /*
         * For some reason the TIFFReadRGBAStrip() function chooses the
         * lower left corner as the origin.  Vertically mirror scanlines.
         */

        for( i_row = 0; i_row < rows_to_write / 2; i_row++ )
        {
            uint32	*top_line, *bottom_line;

            top_line = raster + width * i_row;
            bottom_line = raster + width * (rows_to_write-i_row-1);

            _TIFFmemcpy(wrk_line, top_line, 4*width);
            _TIFFmemcpy(top_line, bottom_line, 4*width);
            _TIFFmemcpy(bottom_line, wrk_line, 4*width);
        }

        /*
         * Write out the result in a strip
         */

        if( TIFFWriteEncodedStrip( out, row / rowsperstrip, raster,
                                   4 * rows_to_write * width ) == -1 )
        {
            ok = 0;
            break;
        }
    }

    _TIFFfree( raster );
    _TIFFfree( wrk_line );

    return ok;
}
Пример #18
0
BOOL tiff_read_exif_tags(TIFF *tif, TagLib::MDMODEL md_model, FIBITMAP *dib) {
    int  i;
    short count;

	TagLib& tagLib = TagLib::instance();

	TIFFDirectory *td = &tif->tif_dir;
    
	count = (short) TIFFGetTagListCount(tif);
    for(i = 0; i < count; i++) {
        ttag_t tag = TIFFGetTagListEntry(tif, i);
        const TIFFFieldInfo *fip;
        uint32 value_count;
        int mem_alloc = 0;
        void *raw_data;

		if(tag == TIFFTAG_EXIFIFD) continue;

		// get the tag key - use NULL to avoid reading GeoTIFF tags
		const char *key = tagLib.getTagFieldName(md_model, (WORD)tag, NULL);
		if(key == NULL) continue;
        
		fip = TIFFFieldWithTag(tif, tag);
        if(fip == NULL) continue;
		
		if(fip->field_passcount) {
			if (fip->field_readcount != TIFF_VARIABLE2) {
				// assume TIFF_VARIABLE
				uint16 value_count16;
				if(TIFFGetField(tif, tag, &value_count16, &raw_data) != 1) continue;
				value_count = value_count16;
			} else {
				if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1) continue;
			}
		} else {
			if (fip->field_readcount == TIFF_VARIABLE || fip->field_readcount == TIFF_VARIABLE2) {
				value_count = 1;
			} else if (fip->field_readcount == TIFF_SPP) {
				value_count = td->td_samplesperpixel;
			} else {
				value_count = fip->field_readcount;
			}
			if (fip->field_type == TIFF_ASCII 
				|| fip->field_readcount == TIFF_VARIABLE
				|| fip->field_readcount == TIFF_VARIABLE2
				|| fip->field_readcount == TIFF_SPP
				|| value_count > 1) {
				if(TIFFGetField(tif, tag, &raw_data) != 1) continue;
			} else {
				raw_data = _TIFFmalloc(_TIFFDataSize(fip->field_type) * value_count);
				mem_alloc = 1;
				if(TIFFGetField(tif, tag, raw_data) != 1) {
					_TIFFfree(raw_data);
					continue;
				}
			}
		}
		
		// create a tag
		FITAG *fitag = FreeImage_CreateTag();
		if(!fitag) {
			if(mem_alloc)
				_TIFFfree(raw_data);
			return FALSE;
		}

		FreeImage_SetTagID(fitag, (WORD)tag);
		FreeImage_SetTagKey(fitag, key);

		switch(fip->field_type) {
			case TIFF_BYTE:
				FreeImage_SetTagType(fitag, FIDT_BYTE);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_UNDEFINED:
				FreeImage_SetTagType(fitag, FIDT_UNDEFINED);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_SBYTE:
				FreeImage_SetTagType(fitag, FIDT_SBYTE);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_SHORT:
				FreeImage_SetTagType(fitag, FIDT_SHORT);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_SSHORT:
				FreeImage_SetTagType(fitag, FIDT_SSHORT);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_LONG:
				FreeImage_SetTagType(fitag, FIDT_LONG);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_IFD:
				FreeImage_SetTagType(fitag, FIDT_IFD);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_SLONG:
				FreeImage_SetTagType(fitag, FIDT_SLONG);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_RATIONAL:
			{
				// LibTIFF converts rational to floats : reconvert floats to rationals
				DWORD *rvalue = (DWORD*)malloc(2 * value_count * sizeof(DWORD));
				for(uint32 i = 0; i < value_count; i++) {
					float *fv = (float*)raw_data;
					FIRational rational(fv[i]);
					rvalue[2*i] = rational.getNumerator();
					rvalue[2*i+1] = rational.getDenominator();
				}
				FreeImage_SetTagType(fitag, FIDT_RATIONAL);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, rvalue);
				free(rvalue);
			}
			break;

			case TIFF_SRATIONAL:
			{
				// LibTIFF converts rational to floats : reconvert floats to rationals
				LONG *rvalue = (LONG*)malloc(2 * value_count * sizeof(LONG));
				for(uint32 i = 0; i < value_count; i++) {
					float *fv = (float*)raw_data;
					FIRational rational(fv[i]);
					rvalue[2*i] = rational.getNumerator();
					rvalue[2*i+1] = rational.getDenominator();
				}
				FreeImage_SetTagType(fitag, FIDT_RATIONAL);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, rvalue);
				free(rvalue);
			}
			break;

			case TIFF_FLOAT:
				FreeImage_SetTagType(fitag, FIDT_FLOAT);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			case TIFF_DOUBLE:
				FreeImage_SetTagType(fitag, FIDT_DOUBLE);
				FreeImage_SetTagLength(fitag, TIFFDataWidth(fip->field_type) * value_count);
				FreeImage_SetTagCount(fitag, value_count);
				FreeImage_SetTagValue(fitag, raw_data);
				break;

			default:
			{
				size_t length = strlen((char*)raw_data) + 1;
				FreeImage_SetTagType(fitag, FIDT_ASCII);
				FreeImage_SetTagLength(fitag, (DWORD)length);
				FreeImage_SetTagCount(fitag, (DWORD)length);
				FreeImage_SetTagValue(fitag, raw_data);
			}
			break;
		}

		const char *description = tagLib.getTagDescription(md_model, (WORD)tag);
		if(description) {
			FreeImage_SetTagDescription(fitag, description);
		}
		// store the tag
		FreeImage_SetMetadata(tagLib.getFreeImageModel(md_model), dib, FreeImage_GetTagKey(fitag), fitag);

		// destroy the tag
		FreeImage_DeleteTag(fitag);
	
		if(mem_alloc)
			_TIFFfree(raw_data);
    }

	return TRUE;

}
Пример #19
0
/*
 * Open a TIFF file with a Unicode filename, for read/writing.
 */
TIFF*
TIFFOpenW(const wchar_t *name, const char *mode)
{
    static const char module[] = "TIFFOpenW";
    thandle_t         fd;
    int               m;
    DWORD             dwMode;
    int               mbsize;
    char              *mbname;
    TIFF              *tif;

    m = _TIFFgetMode(mode, module);

    switch (m)
    {
    case O_RDONLY:                  dwMode = OPEN_EXISTING; break;

    case O_RDWR:                    dwMode = OPEN_ALWAYS;   break;

    case O_RDWR | O_CREAT:            dwMode = OPEN_ALWAYS;   break;

    case O_RDWR | O_TRUNC:            dwMode = CREATE_ALWAYS; break;

    case O_RDWR | O_CREAT | O_TRUNC:    dwMode = CREATE_ALWAYS; break;

    default:                        return ((TIFF*)0);
    }

    fd = (thandle_t)CreateFileW(name,
                                (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
                                FILE_SHARE_READ, NULL, dwMode,
                                (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
                                NULL);
    if (fd == INVALID_HANDLE_VALUE)
    {
        TIFFErrorExt(0, module, "%S: Cannot open", name);
        return ((TIFF*)0);
    }

    mbname = NULL;
    mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
    if (mbsize > 0)
    {
        mbname = (char*)_TIFFmalloc(mbsize);
        if (!mbname)
        {
            TIFFErrorExt(0, module,
                         "Can't allocate space for filename conversion buffer");
            return ((TIFF*)0);
        }

        WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
                            NULL, NULL);
    }

    tif = TIFFFdOpen((int)fd,
                     (mbname != NULL) ? mbname : "<unknown>", mode);
    if (!tif)
        CloseHandle(fd);

    _TIFFfree(mbname);

    return tif;
}
Пример #20
0
int
main(int argc, char* argv[])
{
	uint16 photometric = 0;
	uint32 rowsperstrip = (uint32) -1;
	double resolution = -1;
	unsigned char *buf = NULL;
	tsize_t linebytes = 0;
	uint16 spp = 1;
	uint16 bpp = 8;
	TIFF *out;
	FILE *in;
	unsigned int w, h, prec, row;
	char *infile;
	int c;
	extern int optind;
	extern char* optarg;

	if (argc < 2) {
	    fprintf(stderr, "%s: Too few arguments\n", argv[0]);
	    usage();
	}
	while ((c = getopt(argc, argv, "c:r:R:")) != -1)
		switch (c) {
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
		case 'r':		/* rows/strip */
			rowsperstrip = atoi(optarg);
			break;
		case 'R':		/* resolution */
			resolution = atof(optarg);
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}

	if (optind + 2 < argc) {
	    fprintf(stderr, "%s: Too many arguments\n", argv[0]);
	    usage();
	}

	/*
	 * If only one file is specified, read input from
	 * stdin; otherwise usage is: ppm2tiff input output.
	 */
	if (argc - optind > 1) {
		infile = argv[optind++];
		in = fopen(infile, "rb");
		if (in == NULL) {
			fprintf(stderr, "%s: Can not open.\n", infile);
			return (-1);
		}
	} else {
		infile = "<stdin>";
		in = stdin;
#if defined(HAVE_SETMODE) && defined(O_BINARY)
		setmode(fileno(stdin), O_BINARY);
#endif
	}

	if (fgetc(in) != 'P')
		BadPPM(infile);
	switch (fgetc(in)) {
		case '4':			/* it's a PBM file */
			bpp = 1;
			spp = 1;
			photometric = PHOTOMETRIC_MINISWHITE;
			break;
		case '5':			/* it's a PGM file */
			bpp = 8;
			spp = 1;
			photometric = PHOTOMETRIC_MINISBLACK;
			break;
		case '6':			/* it's a PPM file */
			bpp = 8;
			spp = 3;
			photometric = PHOTOMETRIC_RGB;
			if (compression == COMPRESSION_JPEG &&
			    jpegcolormode == JPEGCOLORMODE_RGB)
				photometric = PHOTOMETRIC_YCBCR;
			break;
		default:
			BadPPM(infile);
	}

	/* Parse header */
	while(1) {
		if (feof(in))
			BadPPM(infile);
		c = fgetc(in);
		/* Skip whitespaces (blanks, TABs, CRs, LFs) */
		if (strchr(" \t\r\n", c))
			continue;

		/* Check for comment line */
		if (c == '#') {
			do {
			    c = fgetc(in);
			} while(!strchr("\r\n", c) || feof(in));
			continue;
		}

		ungetc(c, in);
		break;
	}
	switch (bpp) {
	case 1:
		if (fscanf(in, " %u %u", &w, &h) != 2)
			BadPPM(infile);
		if (fgetc(in) != '\n')
			BadPPM(infile);
		break;
	case 8:
		if (fscanf(in, " %u %u %u", &w, &h, &prec) != 3)
			BadPPM(infile);
		if (fgetc(in) != '\n' || prec != 255)
			BadPPM(infile);
		break;
	}
	out = TIFFOpen(argv[optind], "w");
	if (out == NULL)
		return (-4);
	TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) w);
	TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) h);
	TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, spp);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bpp);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
	TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
	switch (compression) {
	case COMPRESSION_JPEG:
		TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
		TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
		break;
	case COMPRESSION_LZW:
	case COMPRESSION_DEFLATE:
		if (predictor != 0)
			TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
		break;
        case COMPRESSION_CCITTFAX3:
		TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, g3opts);
		break;
	}
	switch (bpp) {
		case 1:
			linebytes = (spp * w + (8 - 1)) / 8;
			if (rowsperstrip == (uint32) -1) {
				TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, h);
			} else {
				TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
				    TIFFDefaultStripSize(out, rowsperstrip));
			}
			break;
		case 8:
			linebytes = spp * w;
			TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
			    TIFFDefaultStripSize(out, rowsperstrip));
			break;
	}
	if (TIFFScanlineSize(out) > linebytes)
		buf = (unsigned char *)_TIFFmalloc(linebytes);
	else
		buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
	if (resolution > 0) {
		TIFFSetField(out, TIFFTAG_XRESOLUTION, resolution);
		TIFFSetField(out, TIFFTAG_YRESOLUTION, resolution);
		TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
	}
	for (row = 0; row < h; row++) {
		if (fread(buf, linebytes, 1, in) != 1) {
			fprintf(stderr, "%s: scanline %lu: Read error.\n",
			    infile, (unsigned long) row);
			break;
		}
		if (TIFFWriteScanline(out, buf, row, 0) < 0)
			break;
	}
	(void) TIFFClose(out);
	if (buf)
		_TIFFfree(buf);
	return (0);
}
Пример #21
0
int
main(int argc, char* argv[])
{
	uint16 bitspersample, shortv;
	uint32 imagewidth, imagelength;
	uint16 config = PLANARCONFIG_CONTIG;
	uint32 rowsperstrip = (uint32) -1;
	uint16 photometric = PHOTOMETRIC_RGB;
	uint16 *rmap, *gmap, *bmap;
	uint32 row;
	int cmap = -1;
	TIFF *in, *out;
	int c;
	extern int optind;
	extern char* optarg;

	while ((c = getopt(argc, argv, "C:c:p:r:")) != -1)
		switch (c) {
		case 'C':		/* force colormap interpretation */
			cmap = atoi(optarg);
			break;
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
		case 'p':		/* planar configuration */
			if (streq(optarg, "separate"))
				config = PLANARCONFIG_SEPARATE;
			else if (streq(optarg, "contig"))
				config = PLANARCONFIG_CONTIG;
			else
				usage();
			break;
		case 'r':		/* rows/strip */
			rowsperstrip = atoi(optarg);
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	if (argc - optind != 2)
		usage();
	in = TIFFOpen(argv[optind], "r");
	if (in == NULL)
		return (-1);
	if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) ||
	    shortv != PHOTOMETRIC_PALETTE) {
		fprintf(stderr, "%s: Expecting a palette image.\n",
		    argv[optind]);
		return (-1);
	}
	if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		fprintf(stderr,
		    "%s: No colormap (not a valid palette image).\n",
		    argv[optind]);
		return (-1);
	}
	bitspersample = 0;
	TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	if (bitspersample != 8) {
		fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
		    argv[optind]);
		return (-1);
	}
	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-2);
	cpTags(in, out);
	TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imagewidth);
	TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
	if (compression != (uint16)-1)
		TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
	else
		TIFFGetField(in, TIFFTAG_COMPRESSION, &compression);
	switch (compression) {
	case COMPRESSION_JPEG:
		if (jpegcolormode == JPEGCOLORMODE_RGB)
			photometric = PHOTOMETRIC_YCBCR;
		else
			photometric = PHOTOMETRIC_RGB;
		TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
		TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
		break;
	case COMPRESSION_LZW:
	case COMPRESSION_DEFLATE:
		if (predictor != 0)
			TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
		break;
	}
	TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
	    rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip));
	(void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
	if (cmap == -1)
		cmap = checkcmap(1<<bitspersample, rmap, gmap, bmap);
	if (cmap == 16) {
		/*
		 * Convert 16-bit colormap to 8-bit.
		 */
		int i;

		for (i = (1<<bitspersample)-1; i >= 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
	}
	{ unsigned char *ibuf, *obuf;
	  register unsigned char* pp;
	  register uint32 x;
	  ibuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(in));
	  obuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(out));
	  switch (config) {
	  case PLANARCONFIG_CONTIG:
		for (row = 0; row < imagelength; row++) {
			if (!TIFFReadScanline(in, ibuf, row, 0))
				goto done;
			pp = obuf;
			for (x = 0; x < imagewidth; x++) {
				*pp++ = (unsigned char) rmap[ibuf[x]];
				*pp++ = (unsigned char) gmap[ibuf[x]];
				*pp++ = (unsigned char) bmap[ibuf[x]];
			}
			if (!TIFFWriteScanline(out, obuf, row, 0))
				goto done;
		}
		break;
	  case PLANARCONFIG_SEPARATE:
		for (row = 0; row < imagelength; row++) {
			if (!TIFFReadScanline(in, ibuf, row, 0))
				goto done;
			for (pp = obuf, x = 0; x < imagewidth; x++)
				*pp++ = (unsigned char) rmap[ibuf[x]];
			if (!TIFFWriteScanline(out, obuf, row, 0))
				goto done;
			for (pp = obuf, x = 0; x < imagewidth; x++)
				*pp++ = (unsigned char) gmap[ibuf[x]];
			if (!TIFFWriteScanline(out, obuf, row, 0))
				goto done;
			for (pp = obuf, x = 0; x < imagewidth; x++)
				*pp++ = (unsigned char) bmap[ibuf[x]];
			if (!TIFFWriteScanline(out, obuf, row, 0))
				goto done;
		}
		break;
	  }
	  _TIFFfree(ibuf);
	  _TIFFfree(obuf);
	}
done:
	(void) TIFFClose(in);
	(void) TIFFClose(out);
	return (0);
}
Пример #22
0
int
copyFaxFile(TIFF* tifin, TIFF* tifout)
{
	uint32 row;
	uint32 linesize = TIFFhowmany8(xsize);
	uint16 badrun;
	int ok;

	tifin->tif_rawdatasize = (tmsize_t)TIFFGetFileSize(tifin);
	if (tifin->tif_rawdatasize == 0) {
		TIFFError(tifin->tif_name, "Empty input file");
		return (0);
	}
	tifin->tif_rawdata = _TIFFmalloc(tifin->tif_rawdatasize);
	if (tifin->tif_rawdata == NULL) {
		TIFFError(tifin->tif_name, "Not enough memory");
		return (0);
	}
	if (!ReadOK(tifin, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
		TIFFError(tifin->tif_name, "Read error at scanline 0");
		return (0);
	}
	tifin->tif_rawcp = tifin->tif_rawdata;
	tifin->tif_rawcc = tifin->tif_rawdatasize;

	(*tifin->tif_setupdecode)(tifin);
	(*tifin->tif_predecode)(tifin, (tsample_t) 0);
	tifin->tif_row = 0;
	badfaxlines = 0;
	badfaxrun = 0;

	_TIFFmemset(refbuf, 0, linesize);
	row = 0;
	badrun = 0;		/* current run of bad lines */
	while (tifin->tif_rawcc > 0) {
		ok = (*tifin->tif_decoderow)(tifin, (tdata_t) rowbuf, 
					     linesize, 0);
		if (!ok) {
			badfaxlines++;
			badrun++;
			/* regenerate line from previous good line */
			_TIFFmemcpy(rowbuf, refbuf, linesize);
		} else {
			if (badrun > badfaxrun)
				badfaxrun = badrun;
			badrun = 0;
			_TIFFmemcpy(refbuf, rowbuf, linesize);
		}
		tifin->tif_row++;

		if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
			fprintf(stderr, "%s: Write error at row %ld.\n",
			    tifout->tif_name, (long) row);
			break;
		}
		row++;
		if (stretch) {
			if (TIFFWriteScanline(tifout, rowbuf, row, 0) < 0) {
				fprintf(stderr, "%s: Write error at row %ld.\n",
				    tifout->tif_name, (long) row);
				break;
			}
			row++;
		}
	}
	if (badrun > badfaxrun)
		badfaxrun = badrun;
	_TIFFfree(tifin->tif_rawdata);
	return (row);
}
Пример #23
0
int main(int argc, char *argv[]){

	float planeseparation;
	planeseparation = 100;

	TIFF *image, *output;
	unsigned int i;
	unsigned int width, length, offset, height;
	unsigned short bps, spp;
	float k, pixelsize, pinholedist;
	tsize_t scanlinesize, objsize;

	pixelsize = 6.45;
	k = ( 2 * M_PI ) / 0.780241;

	if(argc < 2){
		printf("You didn't provide the correct input\n");
		return(1);
	}


	if((image = TIFFOpen(argv[1], "r")) == NULL){
		printf("Error Opening the image\n");
		return(1);
	}

	scanlinesize = TIFFScanlineSize(image);
	TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bps);
	TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp);
	TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
	TIFFGetField(image, TIFFTAG_IMAGELENGTH, &length);
	height = length / 2;
	printf("Image Properties: ");
	printf("BitsPerSample: %u, SamplesPerPixel: %u, Image Width: %u, Image Length: %u\n", bps, spp, width, length);


	objsize = (scanlinesize) / (width * spp);

	uint16 *image1, *image2;
	uint16 *buffer;
	image1 = _TIFFmalloc(objsize * width * height);
	image2 = _TIFFmalloc(objsize * width * height);
	buffer = _TIFFmalloc(objsize * width);


        if( image1 == NULL || image2 == NULL || buffer == NULL ){
		fprintf(stderr, "An Error occured while allocating memory for the images\n");
		return(0);
	}

//	printf("Now to load the data from the provided image\n");

	for( i = 0; i < (height - 1); i++){
		TIFFReadScanline(image, buffer, i,0);
		memcpy(&image1[i * width], buffer, scanlinesize);
	}

	for( i = (height); i < length; i++){
		TIFFReadScanline(image, buffer, i, 0);
		memcpy(&image2[( i - height ) * width], buffer, scanlinesize);
	}

	long *longimg1, *longimg2;
	float *fimg1, *fimg2;

	longimg1 = malloc(sizeof(long) * width * height);
	longimg2 = malloc(sizeof(long) * width * height);
	fimg1 = malloc(sizeof(float) * width * height);
	fimg2 = malloc(sizeof(float) * width * height);

        for(offset = 0; offset < (width * height); offset++){
                longimg1[offset] = (long)image1[offset];
                longimg2[offset] = (long)image2[offset];
        }

	for(offset = 0; offset < (width * height); offset++){
		fimg1[offset] = (float)longimg1[offset];
		fimg2[offset] = (float)longimg2[offset];
	}

	free(image1);
	free(image2);
	free(longimg1);
	free(longimg2);

    cuComplex *tsub;
    tsub = malloc(sizeof(cuComplex) * width * height);

    for(offset = 0; offset < (width * height); offset++){
                tsub[offset].x = fimg1[offset] - fimg2[offset];
                tsub[offset].y = 0;
    }

	if((output = TIFFOpen("sub.tiff", "w")) == NULL){
                printf("Error opening image\n");
                return(1);
    }
	writerealimage(output, width, height, tsub, scanlinesize);

//	Now we need to expand the size of the subtracted image by a factor t
	int scalefactor = 2;
	unsigned int newwidth, newheight, oldoffset;
	newwidth = scalefactor * width;
	newheight = (scalefactor * height);
	cuComplex *sub;
	sub = malloc(sizeof(cuComplex) * newwidth * newheight);

	for(unsigned int x = 0; x < newwidth; x++){
		for(unsigned int y = 0; y < newheight; y++){
			oldoffset = width * floor((y / scalefactor)) + floor((x / scalefactor));
			offset = newwidth * y + x;

			sub[offset].x = tsub[oldoffset].x;
			sub[offset].y = tsub[oldoffset].y;
			}
	}
	free(tsub);

//	Now ensuring that things don't break changing the values of width & height to reflect the expanded matrices
	width = newwidth;
	height = newheight;

	/* Calculating the mean value of the subtracted image and subtract it */
	float sum = 0;
	for(offset = 0; offset < (width * height); offset++){
		sum += sub[offset].x;	
	}
	sum = (sum / (width * height));

	for(offset = 0; offset < (width * height); offset++){
		sub[offset].x -= sum;
	}
   	free(fimg1);
	free(fimg2);

	pinholedist = 57738; /* Distance to the central pixel of the sensor in micron */

	cuComplex *referencewave;

	referencewave = malloc(sizeof(cuComplex) * width * height);	

	gpurefwavecalc(referencewave, width, height, pinholedist,k,pixelsize);


	/* Dividing the Subtracted Image by the Reference Wave */

	cuComplex *reducedhologram;
	reducedhologram = malloc(sizeof(cuComplex) * width * height);

	for(offset = 0; offset < (width * height); offset++){
		reducedhologram[offset].x = (sub[offset].x * referencewave[offset].x) / ((referencewave[offset].x * referencewave[offset].x) + (referencewave[offset].y * referencewave[offset].y));

		reducedhologram[offset].y = (sub[offset].x * referencewave[offset].y) / ((referencewave[offset].x * referencewave[offset].x) + (referencewave[offset].y * referencewave[offset].y));


	}

	/* Starting Fourier Transform stuff */

	cuComplex *tredhologram;
	tredhologram = malloc(sizeof(cuComplex) * width * height);
	gpufouriertransform(reducedhologram, tredhologram, width, height);


 	/* Doing another fourier transform, to see if the input and output are the same */
	cuComplex *itredhologram;
	itredhologram = malloc(sizeof(cuComplex) * width * height);
	gpuifouriertransform(tredhologram, itredhologram, width, height);

	/* Propagating the transformed image */
	cuComplex *propagatedimage, *ipropagatedimage;
	float *absipropagatedimage;
	propagatedimage = malloc(sizeof(cuComplex) * width * height);
	ipropagatedimage = malloc(sizeof(cuComplex) * width * height);
	absipropagatedimage = malloc(sizeof(float) * width * height);
	float dist, maxdist;
	char absdist[50];
	unsigned char *rgbbuffer;
	maxdist = pinholedist;

	rgbbuffer = malloc(sizeof(unsigned char)* width * height * 3);

	/* GLFW Interface Stuff */

	if(!glfwInit()){
		exit(EXIT_FAILURE);
	}

	if(!glfwOpenWindow(width,height,0,0,0,0,0,0, GLFW_WINDOW)){
		glfwTerminate();
		exit(EXIT_FAILURE);
	}
	int windowwidth, windowheight;

	/* Propagation Loop */
	float scale = 1;
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	GLuint tex_id = 0;  glGenTextures(1, &tex_id);

	while(dist < maxdist){
	glfwPollEvents();
	glfwGetWindowSize(&windowwidth, &windowheight);
	glViewport(0, 0, windowwidth, windowheight);

	/* Propagation Loop */
	for(dist = 30000; dist <= maxdist; dist = dist + planeseparation){
		glfwSwapBuffers();
		if(glfwGetKey(GLFW_KEY_KP_ADD)){
			printf("Increasing the Brightness\n");
	        scale*= 1.25;
		}
		if(glfwGetKey(GLFW_KEY_KP_SUBTRACT)){
			printf("Reducing the Brightness\n");
			scale/= 1.25;
		}

		snprintf( absdist, 50, "PropagatedDistance: %f micron", dist);
		glfwSetWindowTitle(absdist);	
		gpupropagate(tredhologram, propagatedimage, width, height, k, pixelsize,dist, scanlinesize, scalefactor);
		gpuifouriertransform(propagatedimage, ipropagatedimage, width, height);

		for(offset = 0; offset < (width * height); offset++){
		absipropagatedimage[offset] = sqrtf( (ipropagatedimage[offset].x * ipropagatedimage[offset].x) + (ipropagatedimage[offset].y * ipropagatedimage[offset].y));
		}

		normalise_and_convert_8(absipropagatedimage, width * height,scale, rgbbuffer);

		glBindTexture(GL_TEXTURE_2D, tex_id);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbbuffer);

		/* Drawing the results in opengl */
		glDisable(GL_LIGHTING);
		glDisable(GL_CULL_FACE);
		glDisable(GL_DEPTH_TEST);
		glEnable(GL_TEXTURE_2D);
		glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgbbuffer);

		glBegin(GL_TRIANGLE_STRIP);

		glTexCoord2f(0,0); glVertex3f(0,0,0); glTexCoord2f(1,0); glVertex3f(1,0,0); glTexCoord2f(0,1);
		glVertex3f(0,1,0); glTexCoord2f(1,1); glVertex3f(1,1,0);

		glEnd();

		glfwSwapBuffers();
	}
}

	glfwTerminate();

	/* Freeing stuff that has been allocated to the host */

	_TIFFfree(buffer);
	TIFFClose(image);

	return(0);
}
Пример #24
0
int
main(int argc, char* argv[])
{
	FILE *in;
	TIFF *out = NULL;
        FAX_Client_Data client_data;
	TIFFErrorHandler whandler = NULL;
	int compression_in = COMPRESSION_CCITTFAX3;
	int compression_out = COMPRESSION_CCITTFAX3;
	int fillorder_in = FILLORDER_LSB2MSB;
	int fillorder_out = FILLORDER_LSB2MSB;
	uint32 group3options_in = 0;	/* 1d-encoded */
	uint32 group3options_out = 0;	/* 1d-encoded */
	uint32 group4options_in = 0;	/* compressed */
	uint32 group4options_out = 0;	/* compressed */
	uint32 defrowsperstrip = (uint32) 0;
	uint32 rowsperstrip;
	int photometric_in = PHOTOMETRIC_MINISWHITE;
	int photometric_out = PHOTOMETRIC_MINISWHITE;
	int mode = FAXMODE_CLASSF;
	int rows;
	int c;
	int pn, npages;
	float resY = 196.0;

#if !HAVE_DECL_OPTARG
	extern int optind;
	extern char* optarg;
#endif

	while ((c = getopt(argc, argv, "R:X:o:r:1234ABLMPUW5678abcflmprsuvwz?")) != -1)
		switch (c) {
			/* input-related options */
		case '3':		/* input is g3-encoded */
			compression_in = COMPRESSION_CCITTFAX3;
			break;
		case '4':		/* input is g4-encoded */
			compression_in = COMPRESSION_CCITTFAX4;
			break;
		case 'U':		/* input is uncompressed (g3 and g4) */
			group3options_in |= GROUP3OPT_UNCOMPRESSED;
			group4options_in |= GROUP4OPT_UNCOMPRESSED;
			break;
		case '1':		/* input is 1d-encoded (g3 only) */
			group3options_in &= ~GROUP3OPT_2DENCODING;
			break;
		case '2':		/* input is 2d-encoded (g3 only) */
			group3options_in |= GROUP3OPT_2DENCODING;
			break;
		case 'P':	/* input has not-aligned EOL (g3 only) */
			group3options_in &= ~GROUP3OPT_FILLBITS;
			break;
		case 'A':		/* input has aligned EOL (g3 only) */
			group3options_in |= GROUP3OPT_FILLBITS;
			break;
		case 'W':		/* input has 0 mean white */
			photometric_in = PHOTOMETRIC_MINISWHITE;
			break;
		case 'B':		/* input has 0 mean black */
			photometric_in = PHOTOMETRIC_MINISBLACK;
			break;
		case 'L':		/* input has lsb-to-msb fillorder */
			fillorder_in = FILLORDER_LSB2MSB;
			break;
		case 'M':		/* input has msb-to-lsb fillorder */
			fillorder_in = FILLORDER_MSB2LSB;
			break;
		case 'R':		/* input resolution */
			resY = (float) atof(optarg);
			break;
		case 'X':		/* input width */
			xsize = (uint32) atoi(optarg);
			break;

			/* output-related options */
		case '7':		/* generate g3-encoded output */
			compression_out = COMPRESSION_CCITTFAX3;
			break;
		case '8':		/* generate g4-encoded output */
			compression_out = COMPRESSION_CCITTFAX4;
			break;
		case 'u':	/* generate uncompressed output (g3 and g4) */
			group3options_out |= GROUP3OPT_UNCOMPRESSED;
			group4options_out |= GROUP4OPT_UNCOMPRESSED;
			break;
		case '5':	/* generate 1d-encoded output (g3 only) */
			group3options_out &= ~GROUP3OPT_2DENCODING;
			break;
		case '6':	/* generate 2d-encoded output (g3 only) */
			group3options_out |= GROUP3OPT_2DENCODING;
			break;
		case 'c':		/* generate "classic" g3 format */
			mode = FAXMODE_CLASSIC;
			break;
		case 'f':		/* generate Class F format */
			mode = FAXMODE_CLASSF;
			break;
		case 'm':		/* output's fillorder is msb-to-lsb */
			fillorder_out = FILLORDER_MSB2LSB;
			break;
		case 'l':		/* output's fillorder is lsb-to-msb */
			fillorder_out = FILLORDER_LSB2MSB;
			break;
		case 'o':
			out = TIFFOpen(optarg, "w");
			if (out == NULL) {
				fprintf(stderr,
				    "%s: Can not create or open %s\n",
				    argv[0], optarg);
				return EXIT_FAILURE;
			}
			break;
		case 'a':	/* generate EOL-aligned output (g3 only) */
			group3options_out |= GROUP3OPT_FILLBITS;
			break;
		case 'p':	/* generate not EOL-aligned output (g3 only) */
			group3options_out &= ~GROUP3OPT_FILLBITS;
			break;
		case 'r':		/* rows/strip */
			defrowsperstrip = atol(optarg);
			break;
		case 's':		/* stretch image by dup'ng scanlines */
			stretch = 1;
			break;
		case 'w':		/* undocumented -- for testing */
			photometric_out = PHOTOMETRIC_MINISWHITE;
			break;
		case 'b':		/* undocumented -- for testing */
			photometric_out = PHOTOMETRIC_MINISBLACK;
			break;
		case 'z':		/* undocumented -- for testing */
			compression_out = COMPRESSION_LZW;
			break;
		case 'v':		/* -v for info */
			verbose++;
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	npages = argc - optind;
	if (npages < 1)
		usage();

	rowbuf = _TIFFmalloc(TIFFhowmany8(xsize));
	refbuf = _TIFFmalloc(TIFFhowmany8(xsize));
	if (rowbuf == NULL || refbuf == NULL) {
		fprintf(stderr, "%s: Not enough memory\n", argv[0]);
		return (EXIT_FAILURE);
	}

	if (out == NULL) {
		out = TIFFOpen("fax.tif", "w");
		if (out == NULL) {
			fprintf(stderr, "%s: Can not create fax.tif\n",
			    argv[0]);
			return (EXIT_FAILURE);
		}
	}
		
	faxTIFF = TIFFClientOpen("(FakeInput)", "w",
	/* TIFFClientOpen() fails if we don't set existing value here */
				 TIFFClientdata(out),
				 TIFFGetReadProc(out), TIFFGetWriteProc(out),
				 TIFFGetSeekProc(out), TIFFGetCloseProc(out),
				 TIFFGetSizeProc(out), TIFFGetMapFileProc(out),
				 TIFFGetUnmapFileProc(out));
	if (faxTIFF == NULL) {
		fprintf(stderr, "%s: Can not create fake input file\n",
		    argv[0]);
		return (EXIT_FAILURE);
	}
	TIFFSetMode(faxTIFF, O_RDONLY);
	TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH,	xsize);
	TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL,	1);
	TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE,	1);
	TIFFSetField(faxTIFF, TIFFTAG_FILLORDER,	fillorder_in);
	TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG,	PLANARCONFIG_CONTIG);
	TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC,	photometric_in);
	TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION,	resY);
	TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT,	RESUNIT_INCH);
	
	/* NB: this must be done after directory info is setup */
	TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in);
	if (compression_in == COMPRESSION_CCITTFAX3)
		TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in);
	else if (compression_in == COMPRESSION_CCITTFAX4)
		TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in);
	for (pn = 0; optind < argc; pn++, optind++) {
		in = fopen(argv[optind], "rb");
		if (in == NULL) {
			fprintf(stderr,
			    "%s: %s: Can not open\n", argv[0], argv[optind]);
			continue;
		}
#if defined(_WIN32) && defined(USE_WIN32_FILEIO)
                client_data.fh = _get_osfhandle(fileno(in));
#else
                client_data.fd = fileno(in);
#endif
                TIFFSetClientdata(faxTIFF, (thandle_t) &client_data);
		TIFFSetFileName(faxTIFF, (const char*)argv[optind]);
		TIFFSetField(out, TIFFTAG_IMAGEWIDTH, xsize);
		TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
		TIFFSetField(out, TIFFTAG_COMPRESSION, compression_out);
		TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric_out);
		TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
		TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
		switch (compression_out) {
			/* g3 */
			case COMPRESSION_CCITTFAX3:
			TIFFSetField(out, TIFFTAG_GROUP3OPTIONS,
				     group3options_out);
			TIFFSetField(out, TIFFTAG_FAXMODE, mode);
			rowsperstrip =
				(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
			break;

			/* g4 */
			case COMPRESSION_CCITTFAX4:
			TIFFSetField(out, TIFFTAG_GROUP4OPTIONS,
				     group4options_out);
			TIFFSetField(out, TIFFTAG_FAXMODE, mode);
			rowsperstrip =
				(defrowsperstrip)?defrowsperstrip:(uint32)-1L;
			break;

			default:
			rowsperstrip = (defrowsperstrip) ?
				defrowsperstrip : TIFFDefaultStripSize(out, 0);
		}
		TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
		TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
		TIFFSetField(out, TIFFTAG_FILLORDER, fillorder_out);
		TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff");
		TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0);
		if (!stretch) {
			TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
			TIFFSetField(out, TIFFTAG_YRESOLUTION, resY);
		} else
			TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.);
		TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
		TIFFSetField(out, TIFFTAG_PAGENUMBER, pn, npages);

		if (!verbose)
		    whandler = TIFFSetWarningHandler(NULL);
		rows = copyFaxFile(faxTIFF, out);
		fclose(in);
		if (!verbose)
		    (void) TIFFSetWarningHandler(whandler);

		TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows);

		if (verbose) {
			fprintf(stderr, "%s:\n", argv[optind]);
			fprintf(stderr, "%d rows in input\n", rows);
			fprintf(stderr, "%ld total bad rows\n",
			    (long) badfaxlines);
			fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun);
		}
		if (compression_out == COMPRESSION_CCITTFAX3 &&
		    mode == FAXMODE_CLASSF) {
			TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines);
			TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ?
			    CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN);
			TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun);
		}
		TIFFWriteDirectory(out);
	}
	TIFFClose(out);
	_TIFFfree(rowbuf);
	_TIFFfree(refbuf);
	return (EXIT_SUCCESS);
}
Пример #25
0
  /******************************************************************************
   * Read an image in TIFF file. If image is 10-16 bit gray scale then
   * the buffer in commonImage_t image is filled with 16 bit (short) 
   * data (so the data won't be packed over several bytes)
   */
int readTIFF (const char *path, commonImage_t *image, bool verbose )
{
  if (path == NULL || image == NULL)
    return -1;

  int rval = 0;
  TIFF *tif = TIFFOpen( path, "r" );

  if (tif) {
    tsize_t scanline;
    char *buf;
    uint32 row, col;
    uint16 spp, bps, photo;

    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &image->height );
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &image->width );

    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps);
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo);

    if (verbose){
      std::cout << "Image height:" << image->height << " width:" 
		<< image->width << " bps:" << bps << " spp: " << spp<< std::endl;
    }

    //Note that no bit packing is supported. ie only full bytes are read
    if (bps == 8 && spp == 1)
      image->mode = Gray8bpp;
    else if (bps > 8 && bps < 17 && spp == 1)
      image->mode = Gray16bpp;
    else if (bps > 17 && bps < 33 && spp == 1) //OBS no support for 24bps separately
      image->mode = Gray32bpp;
    else if (bps == 8 && spp == 3)
      image->mode = RGB8bpp;
    else if (bps == 8 && spp == 4)
      image->mode = RGBA8bpp;
    else{
      if (verbose)
	std::cerr << "commonImage::readTIFF unsupported image type encountered" << std::endl;
    }    

    scanline = TIFFScanlineSize(tif);
    buf =(char*) _TIFFmalloc(scanline*sizeof(char) );
    image->data = (char*) _TIFFmalloc(scanline*sizeof(char)*image->height );

    if (!buf || !image->data){
      if (verbose)
	std::cerr << "commonImage::readTIFF could not allocate memory" << std::endl;
      rval = -2;
    }
    else{
      char *ptOut = (char*)(image->data);
      for (row = 0; row < image->height ; row++)
	{
	  TIFFReadScanline(tif, buf, row);
	  memcpy( ptOut, buf, scanline );
	  ptOut += scanline;
	}
      _TIFFfree(buf);
      TIFFClose(tif);
    }
  }
  else {
    if (verbose)
      std::cerr << "Error while opening file: " << path << std::endl;
    rval = -1;
  }
 
  return rval;

}
Пример #26
0
TIFFField*
_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
{
	TIFFField *fld;
	(void) tif;

	fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField));
	if (fld == NULL)
	    return NULL;
	_TIFFmemset(fld, 0, sizeof(TIFFField));

	fld->field_tag = tag;
	fld->field_readcount = TIFF_VARIABLE2;
	fld->field_writecount = TIFF_VARIABLE2;
	fld->field_type = field_type;
	fld->reserved = 0;
	switch (field_type)
	{
		case TIFF_BYTE:
		case TIFF_UNDEFINED:
			fld->set_field_type = TIFF_SETGET_C32_UINT8;
			fld->get_field_type = TIFF_SETGET_C32_UINT8;
			break;
		case TIFF_ASCII:
			fld->set_field_type = TIFF_SETGET_C32_ASCII;
			fld->get_field_type = TIFF_SETGET_C32_ASCII;
			break;
		case TIFF_SHORT:
			fld->set_field_type = TIFF_SETGET_C32_UINT16;
			fld->get_field_type = TIFF_SETGET_C32_UINT16;
			break;
		case TIFF_LONG:
			fld->set_field_type = TIFF_SETGET_C32_UINT32;
			fld->get_field_type = TIFF_SETGET_C32_UINT32;
			break;
		case TIFF_RATIONAL:
		case TIFF_SRATIONAL:
		case TIFF_FLOAT:
			fld->set_field_type = TIFF_SETGET_C32_FLOAT;
			fld->get_field_type = TIFF_SETGET_C32_FLOAT;
			break;
		case TIFF_SBYTE:
			fld->set_field_type = TIFF_SETGET_C32_SINT8;
			fld->get_field_type = TIFF_SETGET_C32_SINT8;
			break;
		case TIFF_SSHORT:
			fld->set_field_type = TIFF_SETGET_C32_SINT16;
			fld->get_field_type = TIFF_SETGET_C32_SINT16;
			break;
		case TIFF_SLONG:
			fld->set_field_type = TIFF_SETGET_C32_SINT32;
			fld->get_field_type = TIFF_SETGET_C32_SINT32;
			break;
		case TIFF_DOUBLE:
			fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
			fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
			break;
		case TIFF_IFD:
		case TIFF_IFD8:
			fld->set_field_type = TIFF_SETGET_C32_IFD8;
			fld->get_field_type = TIFF_SETGET_C32_IFD8;
			break;
		case TIFF_LONG8:
			fld->set_field_type = TIFF_SETGET_C32_UINT64;
			fld->get_field_type = TIFF_SETGET_C32_UINT64;
			break;
		case TIFF_SLONG8:
			fld->set_field_type = TIFF_SETGET_C32_SINT64;
			fld->get_field_type = TIFF_SETGET_C32_SINT64;
			break;
		default:
			fld->set_field_type = TIFF_SETGET_UNDEFINED;
			fld->get_field_type = TIFF_SETGET_UNDEFINED;
			break;
	}
	fld->field_bit = FIELD_CUSTOM;
	fld->field_oktochange = TRUE;
	fld->field_passcount = TRUE;
	fld->field_name = (char *) _TIFFmalloc(32);
	if (fld->field_name == NULL) {
	    _TIFFfree(fld);
	    return NULL;
	}
	fld->field_subfields = NULL;

	/* 
	 * note that this name is a special sign to TIFFClose() and
	 * _TIFFSetupFields() to free the field
	 */
	sprintf(fld->field_name, "Tag %d", (int) tag);

	return fld;    
}
Пример #27
0
bool CxImageTIF::Decode(CxFile * hFile)
{
	//Comment this line if you need more information on errors
	// TIFFSetErrorHandler(NULL);	//<Patrick Hoffmann>

	//Open file and fill the TIFF structure
	// m_tif = TIFFOpen(imageFileName,"rb");
	TIFF* m_tif = _TIFFOpenEx(hFile, "rb");

	uint32 height=0;
	uint32 width=0;
	uint16 bitspersample=1;
	uint16 samplesperpixel=1;
	uint32 rowsperstrip=(DWORD)-1;
	uint16 photometric=0;
	uint16 compression=1;
	uint16 orientation=ORIENTATION_TOPLEFT; //<vho>
	uint16 res_unit; //<Trifon>
	uint32 x, y;
	float resolution, offset;
	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";

	// <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping
	// info.nNumFrames=0;
	// while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++;
	info.nNumFrames = TIFFNumberOfDirectories(m_tif);

	if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame))
		throw "Error: page not present in TIFF file";			

	//get image info
	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);
	TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation);

	if (info.nEscape == -1) {
		// Return output dimensions only
		head.biWidth = width;
		head.biHeight = height;
		throw "output dimensions returned";
	}

	TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit);
	if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution))
	{
		if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
		SetXDPI((long)resolution);
	}
	if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution))
	{
		if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f);
		SetYDPI((long)resolution);
	}

	if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset))	info.xOffset = (long)offset;
	if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset))	info.yOffset = (long)offset;

	head.biClrUsed=0;
	info.nBkgndIndex =-1;

	if (rowsperstrip>height){
		rowsperstrip=height;
		TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
	}

	isRGB = (bitspersample >= 8) &&
		(photometric == PHOTOMETRIC_RGB) ||
		(photometric == PHOTOMETRIC_YCBCR) ||
		(photometric == PHOTOMETRIC_SEPARATED) ||
		(photometric == PHOTOMETRIC_LOGL) ||
		(photometric == PHOTOMETRIC_LOGLUV);

	if (isRGB){
		head.biBitCount=24;
	}else{
		if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)){
			if	(bitspersample == 1){
				head.biBitCount=1;		//B&W image
				head.biClrUsed =2;
			} else if (bitspersample == 4) {
				head.biBitCount=4;		//16 colors gray scale
				head.biClrUsed =16;
			} else {
				head.biBitCount=8;		//gray scale
				head.biClrUsed =256;
			}
		} else if (bitspersample == 4) {
			head.biBitCount=4;			// 16 colors
			head.biClrUsed=16;
		} else {
			head.biBitCount=8;			//256 colors
			head.biClrUsed=256;
		}
	}

	if (info.nEscape) throw "Cancelled"; // <vho> - cancel decoding

	Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF);	//image creation
	if (!pDib) throw "CxImageTIF can't create image";

#if CXIMAGE_SUPPORT_ALPHA
	if (samplesperpixel==4) AlphaCreate();	//add alpha support for 32bpp tiffs
	if (samplesperpixel==2 && bitspersample==8) AlphaCreate();	//add alpha support for 8bpp + alpha
#endif //CXIMAGE_SUPPORT_ALPHA

	TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression);
	SetCodecOption(compression); // <DPR> save original compression type

	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 = info.pImage;
		for (y = 0; y < height; y++) {

			if (info.nEscape){ // <vho> - cancel decoding
				_TIFFfree(raster);
				throw "Cancelled";
			}

			bits = bits2;
			for (x = 0; x < width; x++) {
				*bits++ = (BYTE)TIFFGetB(row[x]);
				*bits++ = (BYTE)TIFFGetG(row[x]);
				*bits++ = (BYTE)TIFFGetR(row[x]);
#if CXIMAGE_SUPPORT_ALPHA
				if (samplesperpixel==4) AlphaSet(x,y,(BYTE)TIFFGetA(row[x]));
#endif //CXIMAGE_SUPPORT_ALPHA
			}
			row += width;
			bits2 += 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 (DWORD i=0; i<head.biClrUsed; i++){
							pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(i*(255/(head.biClrUsed-1)));
						}
					} else {
						for (DWORD i=0; i<head.biClrUsed; i++){
							pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (BYTE)(255-i*(255/(head.biClrUsed-1)));
						}
					}
				}
				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,head.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);
		long bitsize= TIFFStripSize(m_tif);
		//verify bitsize: could be wrong if StripByteCounts is missing.
		if (bitsize>(long)(head.biSizeImage*samplesperpixel)) bitsize=head.biSizeImage*samplesperpixel;

		int tiled_image = TIFFIsTiled(m_tif);
		uint32 tw, tl;
		BYTE* tilebuf;
		if (tiled_image){
			TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw);
			TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl);
			rowsperstrip = tl;
			bitsize = TIFFTileSize(m_tif) * (int)(1+width/tw);
			tilebuf = (BYTE*)malloc(TIFFTileSize(m_tif));
		}
		
		bits = (BYTE*)malloc(bitsize);
		if (bits==NULL){
			throw "CxImageTIF can't allocate memory";
		}

		for (ys = 0; ys < height; ys += rowsperstrip) {

			if (info.nEscape){ // <vho> - cancel decoding
				free(bits);
				throw "Cancelled";
			}

			nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip);

			if (tiled_image){
				uint32 imagew = TIFFScanlineSize(m_tif);
				uint32 tilew  = TIFFTileRowSize(m_tif);
				int iskew = imagew - tilew;
				uint8* bufp = (uint8*) bits;

				uint32 colb = 0;
				for (uint32 col = 0; col < width; col += tw) {
					if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){
						free(tilebuf);
						free(bits);
						throw "Corrupted tiled TIFF file!";
					}

					if (colb + tw > imagew) {
						uint32 owidth = imagew - colb;
						uint32 oskew = tilew - owidth;
						TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew );
					} else {
						TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0);
					}
					colb += tilew;
				}

			} else {
				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++) {
				long offset=(nrow-y-1)*line;
				if (bitspersample==16) for (DWORD xi=0;xi<width;xi++) bits[xi+offset]=bits[xi*2+offset+1];
				if (samplesperpixel==1) { //simple 8bpp image
					memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,info.dwEffWidth);
				} else if (samplesperpixel==2) { //8bpp image with alpha layer
					int xi=0;
					int ii=0;
					int yi=height-ys-nrow+y;
					while (ii<line){
						SetPixelIndex(xi,yi,bits[ii+offset]);
#if CXIMAGE_SUPPORT_ALPHA
						AlphaSet(xi,yi,bits[ii+offset+1]);
#endif //CXIMAGE_SUPPORT_ALPHA
						ii+=2;
						xi++;
						if (xi>=(int)width){
							yi--;
							xi=0;
						}
					}
				} else { //photometric==PHOTOMETRIC_CIELAB
					if (head.biBitCount!=24){ //fix image
						Create(width,height,24,CXIMAGE_FORMAT_TIF);
#if CXIMAGE_SUPPORT_ALPHA
						if (samplesperpixel==4) AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
					}

					int xi=0;
					int ii=0;
					int yi=height-ys-nrow+y;
					RGBQUAD c;
					int l,a,b,bitsoffset;
					double p,cx,cy,cz,cr,cg,cb;
					while (ii<line){
						bitsoffset = ii*samplesperpixel+offset;
						l=bits[bitsoffset];
						a=bits[bitsoffset+1];
						b=bits[bitsoffset+2];
						if (a>127) a-=256;
						if (b>127) b-=256;
						// lab to xyz
						p = (l/2.55 + 16) / 116.0;
						cx = pow( p + a * 0.002, 3);
						cy = pow( p, 3);
						cz = pow( p - b * 0.005, 3);
						// white point
						cx*=0.95047;
						//cy*=1.000;
						cz*=1.0883;
						// xyz to rgb
						cr =  3.240479 * cx - 1.537150 * cy - 0.498535 * cz;
						cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz;
						cb =  0.055648 * cx - 0.204043 * cy + 1.057311 * cz;

						if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055;
							else            cr = 12.92 * cr;
						if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055;
							else            cg = 12.92 * cg;
						if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055;
							else            cb = 12.92 * cb;

						c.rgbRed  =(BYTE)max(0,min(255,(int)(cr*255)));
						c.rgbGreen=(BYTE)max(0,min(255,(int)(cg*255)));
						c.rgbBlue =(BYTE)max(0,min(255,(int)(cb*255)));

						SetPixelColor(xi,yi,c);
#if CXIMAGE_SUPPORT_ALPHA
						if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]);
#endif //CXIMAGE_SUPPORT_ALPHA
						ii++;
						xi++;
						if (xi>=(int)width){
							yi--;
							xi=0;
						}
					}
				}
			}
		}
		free(bits);
		if (tiled_image) free(tilebuf);

		switch(orientation){
		case ORIENTATION_TOPRIGHT: /* row 0 top, col 0 rhs */
			Mirror();
			break;
		case ORIENTATION_BOTRIGHT: /* row 0 bottom, col 0 rhs */
			Flip();
			Mirror();
			break;
		case ORIENTATION_BOTLEFT: /* row 0 bottom, col 0 lhs */
			Flip();
			break;
		case ORIENTATION_LEFTTOP: /* row 0 lhs, col 0 top */
			RotateRight();
			Mirror();
			break;
		case ORIENTATION_RIGHTTOP: /* row 0 rhs, col 0 top */
			RotateLeft();
			break;
		case ORIENTATION_RIGHTBOT: /* row 0 rhs, col 0 bottom */
			RotateLeft();
			Mirror();
			break;
		case ORIENTATION_LEFTBOT: /* row 0 lhs, col 0 bottom */
			RotateRight();
			break;
		}

	}
  } catch (char *message) {
	  strncpy(info.szLastError,message,255);
	  if (m_tif) TIFFClose(m_tif);
	  if (info.nEscape==-1) return true;
	  return false;
  }
	TIFFClose(m_tif);
	return true;
}
Пример #28
0
void
TIFFCleanup(TIFF* tif)
{
	/*
         * Flush buffered data and directory (if dirty).
         */
	if (tif->tif_mode != O_RDONLY)
		TIFFFlush(tif);
	(*tif->tif_cleanup)(tif);
	TIFFFreeDirectory(tif);

	if (tif->tif_dirlist)
		_TIFFfree(tif->tif_dirlist);

	/*
         * Clean up client info links.
         */
	while( tif->tif_clientinfo )
	{
		TIFFClientInfoLink *link = tif->tif_clientinfo;

		tif->tif_clientinfo = link->next;
		_TIFFfree( link->name );
		_TIFFfree( link );
	}

	if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
		_TIFFfree(tif->tif_rawdata);
	if (isMapped(tif))
		TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);

	/*
         * Clean up custom fields.
         */
	if (tif->tif_fields && tif->tif_nfields > 0) {
		uint32 i;

		for (i = 0; i < tif->tif_nfields; i++) {
			TIFFField *fld = tif->tif_fields[i];
			if (fld->field_bit == FIELD_CUSTOM &&
			    strncmp("Tag ", fld->field_name, 4) == 0) {
				_TIFFfree(fld->field_name);
				_TIFFfree(fld);
			}
		}

		_TIFFfree(tif->tif_fields);
	}

        if (tif->tif_nfieldscompat > 0) {
                uint32 i;

                for (i = 0; i < tif->tif_nfieldscompat; i++) {
                        if (tif->tif_fieldscompat[i].allocated_size)
                                _TIFFfree(tif->tif_fieldscompat[i].fields);
                }
                _TIFFfree(tif->tif_fieldscompat);
        }

	_TIFFfree(tif);
}
Пример #29
0
void
rasterize(int interleaved, char* mode)
{
    register unsigned long row;
    unsigned char *newras;
    unsigned char *ras;
    TIFF *tif;
    tstrip_t strip;
    tsize_t stripsize;

    if ((newras = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) {
        fprintf(stderr, "not enough memory for image\n");
        return;
    }
#define DRAWSEGMENT(offset, step) {			\
        for (row = offset; row < height; row += step) {	\
            _TIFFmemcpy(newras + row*width, ras, width);\
            ras += width;                            	\
        }						\
    }
    ras = raster;
    if (interleaved) {
        DRAWSEGMENT(0, 8);
        DRAWSEGMENT(4, 8);
        DRAWSEGMENT(2, 4);
        DRAWSEGMENT(1, 2);
    } else 
        DRAWSEGMENT(0, 1);
#undef DRAWSEGMENT

    tif = TIFFOpen(imagename, mode);
    if (!tif) {
	TIFFError(imagename,"Can not open output image");
	exit(-1);
    }
    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) width);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) height);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 
	rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip));
    TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
    switch (compression) {
    case COMPRESSION_LZW:
    case COMPRESSION_DEFLATE:
	    if (predictor != 0)
		    TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
	    break;
    }
    TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    strip = 0;
    stripsize = TIFFStripSize(tif);
    for (row=0; row<height; row += rowsperstrip) {
	if (rowsperstrip > height-row) {
	    rowsperstrip = height-row;
	    stripsize = TIFFVStripSize(tif, rowsperstrip);
	}
	if (TIFFWriteEncodedStrip(tif, strip, newras+row*width, stripsize) < 0)
	    break;
	strip++;
    }
    TIFFClose(tif);

    _TIFFfree(newras);
}
Пример #30
0
// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void TiffUtilities::freeTiffImageBuffer(unsigned char* buffer)
{
  _TIFFfree(buffer);
}