void ZLEwlImageManager::convertImageDirectBmp(const std::string &stringData, ZLImageData &data) const {
	int xres, yres, w, h, spp, bps;

	const char *p = stringData.c_str();

	BMPFileHeader file_hdr;
	BMPInfoHeader info_hdr;
	enum BMPType bmp_type;

	uint32  clr_tbl_size, n_clr_elems = 3;
	unsigned char *clr_tbl;

	uint32	row, stride;

	unsigned char* xdata = 0;

	ZLIntegerOption myDitherAlgo(ZLCategoryKey::LOOK_AND_FEEL, "Options", "DitherAlgo", 0);
	register int dalgo = myDitherAlgo.value();

	memcpy(file_hdr.bType, p, 2);

	if(file_hdr.bType[0] != 'B' || file_hdr.bType[1] != 'M') {
		fprintf(stderr, "File is not a BMP\n");
		goto bad;
	}

	/* -------------------------------------------------------------------- */
	/*      Read the BMPFileHeader. We need iOffBits value only             */
	/* -------------------------------------------------------------------- */
	memcpy(&file_hdr.iOffBits, p+10, 4);

	file_hdr.iSize = stringData.length();

	/* -------------------------------------------------------------------- */
	/*      Read the BMPInfoHeader.                                         */
	/* -------------------------------------------------------------------- */

	memcpy(&info_hdr.iSize, p+BFH_SIZE, 4);

	if (info_hdr.iSize == BIH_WIN4SIZE)
		bmp_type = BMPT_WIN4;
	else if (info_hdr.iSize == BIH_OS21SIZE)
		bmp_type = BMPT_OS21;
	else if (info_hdr.iSize == BIH_OS22SIZE || info_hdr.iSize == 16)
		bmp_type = BMPT_OS22;
	else
		bmp_type = BMPT_WIN5;

	if (bmp_type == BMPT_WIN4 || bmp_type == BMPT_WIN5 || bmp_type == BMPT_OS22) {
		p = stringData.c_str() + BFH_SIZE + 4;
		memcpy(&info_hdr.iWidth, p, 4);
		p += 4;
		memcpy(&info_hdr.iHeight, p, 4);
		p += 4;
		memcpy(&info_hdr.iPlanes, p, 2);
		p += 2;
		memcpy(&info_hdr.iBitCount, p, 2);
		p += 2;
		memcpy(&info_hdr.iCompression, p, 4);
		p += 4;
		memcpy(&info_hdr.iSizeImage, p, 4);
		p += 4;
		memcpy(&info_hdr.iXPelsPerMeter, p, 4);
		p += 4;
		memcpy(&info_hdr.iYPelsPerMeter, p, 4);
		p += 4;
		memcpy(&info_hdr.iClrUsed, p, 4);
		p += 4;
		memcpy(&info_hdr.iClrImportant, p, 4);
		p += 4;
		memcpy(&info_hdr.iRedMask, p, 4);
		p += 4;
		memcpy(&info_hdr.iGreenMask, p, 4);
		p += 4;
		memcpy(&info_hdr.iBlueMask, p, 4);
		p += 4;
		memcpy(&info_hdr.iAlphaMask, p, 4);
		p += 4;
		n_clr_elems = 4;
		xres = ((double)info_hdr.iXPelsPerMeter * 2.54 + 0.05) / 100;
		yres = ((double)info_hdr.iYPelsPerMeter * 2.54 + 0.05) / 100;
	}

	if (bmp_type == BMPT_OS22) {
		/* 
		 * FIXME: different info in different documents
		 * regarding this!
		 */
		n_clr_elems = 3;
	}

	if (bmp_type == BMPT_OS21) {
		int16  iShort;

		memcpy(&iShort, p, 2);
		p += 2;
		info_hdr.iWidth = iShort;
		memcpy(&iShort, p, 2);
		p += 2;
		info_hdr.iHeight = iShort;
		memcpy(&iShort, p, 2);
		p += 2;
		info_hdr.iPlanes = iShort;
		memcpy(&iShort, p, 2);
		p += 2;
		info_hdr.iBitCount = iShort;
		info_hdr.iCompression = BMPC_RGB;
		n_clr_elems = 3;
	}

	if (info_hdr.iBitCount != 1  && info_hdr.iBitCount != 4  &&
			info_hdr.iBitCount != 8  && info_hdr.iBitCount != 16 &&
			info_hdr.iBitCount != 24 && info_hdr.iBitCount != 32) {
		fprintf(stderr, "Cannot process BMP file with bit count %d\n",
				info_hdr.iBitCount);
		//   close(fd);
		return;
	}

	w = info_hdr.iWidth;
	h = (info_hdr.iHeight > 0) ? info_hdr.iHeight : -info_hdr.iHeight;

	data.init(w, h);

	switch (info_hdr.iBitCount)
	{
		case 1:
		case 4:
		case 8:
			spp = 1;
			bps = info_hdr.iBitCount;

			/* Allocate memory for colour table and read it. */
			if (info_hdr.iClrUsed)
				clr_tbl_size = ((uint32)(1 << bps) < info_hdr.iClrUsed) ?
					1 << bps : info_hdr.iClrUsed;
			else
				clr_tbl_size = 1 << bps;
			clr_tbl = (unsigned char *)
				_TIFFmalloc(n_clr_elems * clr_tbl_size);
			if (!clr_tbl) {
				fprintf(stderr, "Can't allocate space for color table\n");
				goto bad;
			}

			/*printf ("n_clr_elems: %d, clr_tbl_size: %d\n",
			  n_clr_elems, clr_tbl_size); */

			p = stringData.c_str() + BFH_SIZE + info_hdr.iSize;
			memcpy(clr_tbl, p, n_clr_elems * clr_tbl_size);

			/*for(clr = 0; clr < clr_tbl_size; ++clr) {
			  printf ("%d: r: %d g: %d b: %d\n",
			  clr,
			  clr_tbl[clr*n_clr_elems+2],
			  clr_tbl[clr*n_clr_elems+1],
			  clr_tbl[clr*n_clr_elems]);
			  }*/
			break;

		case 16:
		case 24:
			spp = 3;
			bps = info_hdr.iBitCount / spp;
			break;

		case 32:
			spp = 3;
			bps = 8;
			break;

		default:
			break;
	}

	stride = (w * spp * bps + 7) / 8;
	/*printf ("w: %d, h: %d, spp: %d, bps: %d, colorspace: %d\n",
	 *w, *h, *spp, *bps, info_hdr.iCompression); */

	// detect old style bitmask images
	if (info_hdr.iCompression == BMPC_RGB && info_hdr.iBitCount == 16)
	{
		/*printf ("implicit non-RGB image\n"); */
		info_hdr.iCompression = BMPC_BITFIELDS;
		info_hdr.iBlueMask = 0x1f;
		info_hdr.iGreenMask = 0x1f << 5;
		info_hdr.iRedMask = 0x1f << 10;
	}

	/* -------------------------------------------------------------------- */
	/*  Read uncompressed image data.                                       */
	/* -------------------------------------------------------------------- */

	switch (info_hdr.iCompression) {
		case BMPC_BITFIELDS:
			// we convert those to RGB for easier use
			bps = 8;
			stride = (w * spp * bps + 7) / 8;
		case BMPC_RGB:
			{
				uint32 file_stride = ((w * info_hdr.iBitCount + 7) / 8 + 3) / 4 * 4;

				/*printf ("bitcount: %d, stride: %d, file stride: %d\n",
				  info_hdr.iBitCount, stride, file_stride);

				  printf ("red mask: %x, green mask: %x, blue mask: %x\n",
				  info_hdr.iRedMask, info_hdr.iGreenMask, info_hdr.iBlueMask); */

				xdata = (unsigned char*)_TIFFmalloc (stride * h);

				if (!xdata) {
					fprintf(stderr, "Can't allocate space for image buffer\n");
					goto bad1;
				}

				for (row = 0; row < (unsigned)h; row++) {
					uint32 offset;

					if (info_hdr.iHeight > 0)
						offset = file_hdr.iOffBits + (h - row - 1) * file_stride;
					else
						offset = file_hdr.iOffBits + row * file_stride;

					//	if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
					//	  fprintf(stderr, "scanline %lu: Seek error\n", (unsigned long) row);
					//	}
					p = stringData.c_str() + offset;

					memcpy(xdata + stride*row, p, stride);

					// convert to RGB
					if (info_hdr.iCompression == BMPC_BITFIELDS)
					{

						unsigned char* row_ptr = xdata + stride*row;
						unsigned char* r16_ptr = row_ptr + file_stride - 2;
						unsigned char* rgb_ptr = row_ptr + stride - 3;

						int r_shift = last_bit_set (info_hdr.iRedMask) - 7;
						int g_shift = last_bit_set (info_hdr.iGreenMask) - 7;
						int b_shift = last_bit_set (info_hdr.iBlueMask) - 7;


						char *c = ((ZLEwlImageData&)data).getImageData() + w * row;
						for (int i=0 ; rgb_ptr >= row_ptr; r16_ptr -= 2, rgb_ptr -= 3, i++)
						{
							int val = (r16_ptr[0] << 0) + (r16_ptr[1] << 8);
							if (r_shift > 0)
								rgb_ptr[0] = (val & info_hdr.iRedMask) >> r_shift;
							else
								rgb_ptr[0] = (val & info_hdr.iRedMask) << -r_shift;
							if (g_shift > 0)
								rgb_ptr[1] = (val & info_hdr.iGreenMask) >> g_shift;
							else
								rgb_ptr[1] = (val & info_hdr.iGreenMask) << -g_shift;
							if (b_shift > 0)
								rgb_ptr[2] = (val & info_hdr.iBlueMask) >> b_shift;
							else
								rgb_ptr[2] = (val & info_hdr.iBlueMask) << -b_shift;


							unsigned char x = rgb_ptr[0] * 0.299 +
								rgb_ptr[1] * 0.587 +
								rgb_ptr[2] * 0.114;

							if(dalgo == 1)
								*c++ = Dither2BitColor(x, i, row);
							else
								*c++ = x;
						}
					}
Esempio n. 2
0
static int
cpContig(IMAGE* in, TIFF* out)
{
	tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
	short *r = NULL;
	int x, y;

	if (in->zsize == 3) {
		short *g, *b;

		r = (short *)_TIFFmalloc(3 * in->xsize * sizeof (short));
		g = r + in->xsize;
		b = g + in->xsize;
		for (y = in->ysize-1; y >= 0; y--) {
			uint8* pp = (uint8*) buf;

			getrow(in, r, y, 0);
			getrow(in, g, y, 1);
			getrow(in, b, y, 2);
			for (x = 0; x < in->xsize; x++) {
				pp[0] = r[x];
				pp[1] = g[x];
				pp[2] = b[x];
				pp += 3;
			}
			if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
				goto bad;
		}
	} else if (in->zsize == 4) {
		short *g, *b, *a;

		r = (short *)_TIFFmalloc(4 * in->xsize * sizeof (short));
		g = r + in->xsize;
		b = g + in->xsize;
		a = b + in->xsize;
		for (y = in->ysize-1; y >= 0; y--) {
			uint8* pp = (uint8*) buf;

			getrow(in, r, y, 0);
			getrow(in, g, y, 1);
			getrow(in, b, y, 2);
			getrow(in, a, y, 3);
			for (x = 0; x < in->xsize; x++) {
				pp[0] = r[x];
				pp[1] = g[x];
				pp[2] = b[x];
				pp[3] = a[x];
				pp += 4;
			}
			if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
				goto bad;
		}
	} else {
		uint8* pp = (uint8*) buf;

		r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
		for (y = in->ysize-1; y >= 0; y--) {
			getrow(in, r, y, 0);
			for (x = in->xsize-1; x >= 0; x--)
				pp[x] = r[x];
			if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
				goto bad;
		}
	}
	if (r)
		_TIFFfree(r);
	_TIFFfree(buf);
	return (1);
bad:
	if (r)
		_TIFFfree(r);
	_TIFFfree(buf);
	return (0);
}
int
main(int argc, char* argv[])
{
	uint32 rowsperstrip = (uint32) -1;
	TIFF *in, *out;
	uint32 w, h;
	uint16 samplesperpixel;
	uint16 bitspersample;
	uint16 config;
	uint16 photometric;
	uint16* red;
	uint16* green;
	uint16* blue;
	tsize_t rowsize;
	register uint32 row;
	register tsample_t s;
	unsigned char *inbuf, *outbuf;
	char thing[1024];
	int c;
	extern int optind;
	extern char *optarg;

	while ((c = getopt(argc, argv, "c:r:R:G:B:")) != -1)
		switch (c) {
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
		case 'r':		/* rows/strip */
			rowsperstrip = atoi(optarg);
			break;
		case 'R':
			RED = PCT(atoi(optarg));
			break;
		case 'G':
			GREEN = PCT(atoi(optarg));
			break;
		case 'B':
			BLUE = PCT(atoi(optarg));
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	if (argc - optind < 2)
		usage();
	in = TIFFOpen(argv[optind], "r");
	if (in == NULL)
		return (-1);
	photometric = 0;
	TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric);
	if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE ) {
		fprintf(stderr,
	    "%s: Bad photometric; can only handle RGB and Palette images.\n",
		    argv[optind]);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	if (samplesperpixel != 1 && samplesperpixel != 3) {
		fprintf(stderr, "%s: Bad samples/pixel %u.\n",
		    argv[optind], samplesperpixel);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	if (bitspersample != 8) {
		fprintf(stderr,
		    " %s: Sorry, only handle 8-bit samples.\n", argv[optind]);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w);
	TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h);
	TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);

	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-1);
	TIFFSetField(out, TIFFTAG_IMAGEWIDTH, w);
	TIFFSetField(out, TIFFTAG_IMAGELENGTH, h);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	cpTags(in, out);
	if (compression != (uint16) -1) {
		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;
		}
	}
	TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
	sprintf(thing, "B&W version of %s", argv[optind]);
	TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
	TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
	outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
	    TIFFDefaultStripSize(out, rowsperstrip));

#define	pack(a,b)	((a)<<8 | (b))
	switch (pack(photometric, config)) {
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
		TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue);
		/*
		 * Convert 16-bit colormap to 8-bit (unless it looks
		 * like an old-style 8-bit colormap).
		 */
		if (checkcmap(in, 1<<bitspersample, red, green, blue) == 16) {
			int i;
#define	CVT(x)		(((x) * 255L) / ((1L<<16)-1))
			for (i = (1<<bitspersample)-1; i >= 0; i--) {
				red[i] = CVT(red[i]);
				green[i] = CVT(green[i]);
				blue[i] = CVT(blue[i]);
			}
#undef CVT
		}
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresspalette(outbuf, inbuf, w, red, green, blue);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresscontig(outbuf, inbuf, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
		rowsize = TIFFScanlineSize(in);
		inbuf = (unsigned char *)_TIFFmalloc(3*rowsize);
		for (row = 0; row < h; row++) {
			for (s = 0; s < 3; s++)
				if (TIFFReadScanline(in,
				    inbuf+s*rowsize, row, s) < 0)
					 return (-1);
			compresssep(outbuf,
			    inbuf, inbuf+rowsize, inbuf+2*rowsize, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	}
#undef pack
	TIFFClose(out);
	return (0);
}
UInt8Image *tiff_to_band_byte_image (TIFF *tif, int num_bands)
{
  // Get the raster width and height of the image.
  uint32  width;
  uint32  height;
  tsize_t scanlineSize;
  uint16  planarConfiguration;
  uint16  bitsPerSample;
  uint16  sampleFormat;
  int band;
  uint32  offset;
  uint8   *sample;

  // Get TIFF image boundary, planar configuration, and data type info
  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarConfiguration);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
  TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
  if (num_bands > 1) {
    asfRequire(planarConfiguration == PLANARCONFIG_CONTIG,
              "\nTIFFs with multi-plane data not supported\n");
  }
  if (sampleFormat != SAMPLEFORMAT_UINT  &&
      sampleFormat != SAMPLEFORMAT_INT   &&
      sampleFormat != SAMPLEFORMAT_IEEEFP)
  {
    asfPrintWarning("TIFFTAG_SAMPLEFORMAT is missing or an unsupported type.  The import\n"
        "will continue but the data type will be assumed according to how many\n"
        "bits per sample exist.  This may cause unexpected results:\n"
        "    8-bits: Unsigned Integer8 (uint8) data is assumed.\n"
        "   16-bits: Signed Integer16 (int16) data is assumed.\n"
        "   32-bits: IEEE 32-Bit Floating Point (float) is assumed.\n"
        "     Other: Unsupported.\n");
  }

  // FIXME: Use resampling to reduce 16- and 32-bit data down to 8-bit byte data...
  // This situation/need is not expected to happen, or at least very rarely.
  if (bitsPerSample > 8) {
    asfPrintWarning("Image contains 16- or 32-bit data but is being imported as an 8-bit (byte) image.\n"
        "Truncation of data values may occur.\n");
  }

  // Pull the actual image data out of the TIFF and store it as a
  // byte image.
  UInt8Image *bim = uint8_image_new (width, height * num_bands);
  if (bim == NULL) return bim; // But note to you: uint8_image_new() asserts on a g_new() if it fails
  offset = height;

  // Allocate a buffer for a line of pixels.
  scanlineSize = TIFFScanlineSize(tif);
  tdata_t buf = _TIFFmalloc (scanlineSize);
  sample = (uint8*)MALLOC(sizeof(uint8)*num_bands);

  uint32 current_row;
  for (current_row = 0 ; current_row < height; current_row++) {
    asfLineMeter(current_row, height);
    TIFFReadScanline (tif, buf, current_row, 0);
    uint32 current_column;
    for (current_column = 0 ; current_column < width ; current_column++) {
      // Read chunky-formatted data, e.g. greyscale values or rgb interlaced values
      switch(bitsPerSample) {
        case 8:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((uint8*)buf)[(current_column*num_bands)+band]);
          }
          break;
        case 16:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((uint16*)buf)[(current_column*num_bands)+band]);
          }
          break;
        case 32:
          for (band = 0; band < num_bands; band++) {
            sample[band] =
                (uint8)(((float*)buf)[(current_column*num_bands)+band]);
          }
          break;
        default:
          asfPrintError("\nUnsupported TIFF pixel data type\n");
      }
      for (band = 0; band < num_bands; band++) {
        // Write a band-sequential float image file for ASF internal use
        uint8_image_set_pixel (bim, current_column, (band*offset)+current_row,
                               sample[band]);
      }
    }
  }
  if (buf) _TIFFfree(buf);
  FREE(sample);

  return bim;
}
Esempio n. 5
0
main(int argc, char* argv[])
{
  TIFF* tif;
  uint8 r,g,b,a,i,bpp;
  FILE *rgbf;
  char rgbfile[50];

  if (argc!=2 && argc!=3) {
    printf("Usage: %s [-32] filename.tiff\n",argv[0]);
    exit(1);
  }

  if (argc==2) bpp=16; else bpp=32;

  tif = TIFFOpen(argv[1], "r");
  if (tif) {
    uint32 w, h, pixel,rgba32_pixel;
    uint16 rgba16_pixel;
    size_t npixels;
    uint32* raster;
    int n;
    
    strcpy(rgbfile,argv[1]);
    strcpy((char*)strrchr(rgbfile,'.'),".rgb");
    rgbf=fopen(rgbfile,"wb");
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
    npixels = w * h;
    raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));
    if (raster != NULL) {
      if (TIFFReadRGBAImage(tif,w,h,raster,0)) {
	int mw,mh;
	// save rgb data to file
	fputc((w>>8)&0xFF,rgbf); fputc(w&0xFF,rgbf); // u16 w,h header
	fputc((h>>8)&0xFF,rgbf); fputc(h&0xFF,rgbf);
	for (n=0; n<4; n++) fputc(0x0,rgbf); // alignment
	for (mh=h-1; mh>=0; mh--)
	  for (mw=0; mw<w; mw++) 
	    {
	      pixel=raster[w*mh+mw];
	      r=TIFFGetR(pixel);
	      g=TIFFGetG(pixel);
	      b=TIFFGetB(pixel);
	      a=TIFFGetA(pixel);
	      if (bpp==16)
		{
		  rgba16_pixel=PACK_RGBA5551(r,g,b,a);
	      // use white as the mask
	      // if (r==0xff && g==0xff && b==0xff) a|=1; else a&=~(uint16)1;
	      // if (a==0xcff) rgba16_pixel|=1; else rgba16_pixel&=~(uint16)1;
		  fputc((rgba16_pixel>>8)&0xFF,rgbf);
		  fputc(rgba16_pixel&0xFF,rgbf);
		}
	      else
		{
		  // rgba32_pixel=PACK_RGBA8888(r,g,b,a);
		  fputc(r,rgbf);
		  fputc(g,rgbf);
		  fputc(b,rgbf);
		  fputc(a,rgbf);
		}
	    }
      }
Esempio n. 6
0
int
TIFFInitZIP(TIFF* tif, int scheme)
{
	static const char module[] = "TIFFInitZIP";
	ZIPState* sp;

	assert( (scheme == COMPRESSION_DEFLATE)
		|| (scheme == COMPRESSION_ADOBE_DEFLATE));

	/*
	 * Merge codec-specific tag information.
	 */
	if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
		TIFFErrorExt(tif->tif_clientdata, module,
			     "Merging Deflate codec-specific tags failed");
		return 0;
	}

	/*
	 * Allocate state block so tag methods have storage to record values.
	 */
	tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
	if (tif->tif_data == NULL)
		goto bad;
	sp = ZState(tif);
	sp->stream.zalloc = NULL;
	sp->stream.zfree = NULL;
	sp->stream.opaque = NULL;
	sp->stream.data_type = Z_BINARY;

	/*
	 * Override parent get/set field methods.
	 */
	sp->vgetparent = tif->tif_tagmethods.vgetfield;
	tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
	sp->vsetparent = tif->tif_tagmethods.vsetfield;
	tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */

	/* Default values for codec-specific fields */
	sp->zipquality = Z_DEFAULT_COMPRESSION;	/* default comp. level */
	sp->state = 0;

	/*
	 * Install codec methods.
	 */
	tif->tif_fixuptags = ZIPFixupTags; 
	tif->tif_setupdecode = ZIPSetupDecode;
	tif->tif_predecode = ZIPPreDecode;
	tif->tif_decoderow = ZIPDecode;
	tif->tif_decodestrip = ZIPDecode;
	tif->tif_decodetile = ZIPDecode;  
	tif->tif_setupencode = ZIPSetupEncode;
	tif->tif_preencode = ZIPPreEncode;
	tif->tif_postencode = ZIPPostEncode;
	tif->tif_encoderow = ZIPEncode;
	tif->tif_encodestrip = ZIPEncode;
	tif->tif_encodetile = ZIPEncode;
	tif->tif_cleanup = ZIPCleanup;
	/*
	 * Setup predictor setup.
	 */
	(void) TIFFPredictorInit(tif);
	return (1);
bad:
	TIFFErrorExt(tif->tif_clientdata, module,
		     "No space for ZIP state block");
	return (0);
}
void import_radarsat2(const char *inBaseName, radiometry_t radiometry,
		      const char *outBaseName, int ampOnly)
{
  FILE *fp;
  radarsat2_meta *radarsat2;
  meta_parameters *meta;
  char **inDataNames=NULL, inDataName[1024], *inMetaName=NULL;
  char *outDataName=NULL, str[512];
  float *amp = NULL, *phase = NULL, *tmp = NULL, re, im;
  int band, sample;

  // Check radiometry
  if (radiometry != r_AMP) {
    asfPrintWarning("Radiometry other than AMPLITUDE is currently not "
		    "supported.\n");
    radiometry = r_AMP;
  }
  
  if (!fileExists(inBaseName))
    inMetaName = appendExt(inBaseName, ".xml");
  else {
    inMetaName = (char *) MALLOC(sizeof(char)*1024);
    strcpy(inMetaName, inBaseName);
  }
  outDataName = appendExt(outBaseName, ".img");

  radarsat2 = read_radarsat2_meta(inMetaName);
  asfPrintStatus("   DataType: %s, ProductType: %s\n",
		 radarsat2->dataType, radarsat2->productType);
  if (strcmp_case(radarsat2->dataType, "COMPLEX") != 0)
    asfPrintError("Currently only complex data supported!\n");
  meta = radarsat2meta(radarsat2);
  meta_write(meta, outDataName);

  // Let's check the GeoTIFF data.
  // Unfortunately, there is no identifier in the GeoTIFF that would identify
  // the data as Radarsat-2 data.
  //
  // The only thing that we can actually do is to look whether the data in the
  // GeoTIFF file fit the general bill. We can the image dimensions. The data
  // needs to have 2 bands (I and Q) and 16 bit. The citation geokey needs to
  // be the really non-descriptive "Uncorrected Satellite Data".

  TIFF *tiff = NULL;
  GTIF *gtif = NULL;
  data_type_t data_type;
  short sample_format, bits_per_sample, planar_config;
  short num_bands;
  int is_scanline_format, is_palette_color_tiff, wrong=FALSE;
  char *error_message = (char *) MALLOC(sizeof(char)*2048);

  inDataNames = extract_band_names(meta->general->basename, 
				   meta->general->band_count);
  fp = FOPEN(outDataName, "wb");

  int band_count = radarsat2->band_count;
  if (ampOnly) {
    strcpy(meta->general->bands, "AMP");
    meta->general->band_count = 1;
    band_count = 1;
  }
  for (band=0; band<band_count; band++) {

    // path from the xml (metadata) file
    char *path = get_dirname(inBaseName);
    if (strlen(path)>0) {
      strcpy(inDataName, path);
      if (inDataName[strlen(inDataName)-1] != '/')
        strcat(inDataName, "/");
    }
    else
      strcpy(inDataName, "");
    free(path);
    strcat(inDataName, inDataNames[band]);

    tiff = XTIFFOpen(inDataName, "r");
    if (!tiff)
      asfPrintError("Could not open data file (%s)\n", inDataName);
    gtif = GTIFNew(tiff);
    if (!gtif)
      asfPrintError("Could not read GeoTIFF keys from data file (%s)\n",
		    inDataName);

    // Check image dimensions
    uint32 tif_sample_count;
    uint32 tif_line_count;

    TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &tif_line_count);
    TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &tif_sample_count);
    if ((meta->general->sample_count != tif_sample_count) ||
	(meta->general->line_count != tif_line_count))
      asfPrintError(error_message, 
		    "Problem with image dimensions. Was looking for %d lines "
		    "and %d samples.\nFound %ld lines and %ld samples instead!"
		    "\n", 
		    meta->general->line_count, meta->general->sample_count, 
		    tif_line_count, tif_sample_count);

    // Check general TIFF tags
    get_tiff_data_config(tiff, &sample_format, &bits_per_sample, &planar_config,
			 &data_type, &num_bands, &is_scanline_format, 
			 &is_palette_color_tiff, REPORT_LEVEL_WARNING);

    // The specs say the data is supposed to be unsigned but it is not.
    // Let is pass as long as we are talking about integer data here
    strcpy(error_message, "");
    if (sample_format != SAMPLEFORMAT_UINT && 
	sample_format != SAMPLEFORMAT_INT) {
      strcat(error_message, 
	     "Problem with sampling format. Was looking for integer, ");
      if (sample_format == SAMPLEFORMAT_COMPLEXIEEEFP)
	strcat(error_message, "found complex floating point instead!\n");
      else if (sample_format == SAMPLEFORMAT_COMPLEXINT)
	strcat(error_message, "found complex integer instead!\n");
      else if (sample_format == SAMPLEFORMAT_IEEEFP)
	strcat(error_message, "found floating point instead!\n");
      else if (sample_format == SAMPLEFORMAT_VOID)
	strcat(error_message, "found void instead!\n");
      wrong = TRUE;
    }
    if (bits_per_sample != 16) {
      sprintf(str, "Problem with bits per sample. Was looking for 16, found %d "
	      "instead!\n", bits_per_sample);
      strcat(error_message, str);
      wrong = TRUE;
    }
    if (data_type != INTEGER16) {
      strcat(error_message, "Problem with data type. Was looking INTEGER16, ");
      if (data_type == ASF_BYTE)
	strcat(error_message, "found BYTE instead!\n");
      else if (data_type == INTEGER32)
	strcat(error_message, "found INTEGER32 instead!\n");
      else if (data_type == REAL32)
	strcat(error_message, "found REAL32 instead!\n");
      else if (data_type == REAL64)
	strcat(error_message, "found REAL64 instead!\n");
      else if (data_type == COMPLEX_BYTE)
	strcat(error_message, "found COMPLEX_BYTE instead!\n");
      else if (data_type == COMPLEX_INTEGER16)
	strcat(error_message, "found COMPLEX_INTEGER16 instead!\n");
      else if (data_type == COMPLEX_INTEGER32)
	strcat(error_message, "found COMPLEX_INTEGER32 instead!\n");
      else if (data_type == COMPLEX_REAL32)
	strcat(error_message, "found COMPLEX_REAL32 instead!\n");
      else if (data_type == COMPLEX_REAL64)
	strcat(error_message, "found COMPLEX_REAL64 instead!\n");
      wrong = TRUE;
    }
    if (num_bands != 2) {
      sprintf(str, "Problem with number of bands. Was looking for 2, "
	      "found %d instead!\n", num_bands);
      strcat(error_message, str);
      wrong = TRUE;
    }
    if (wrong)
      asfPrintError(error_message);

    // Check GTCitationGeoKey
    char *citation = NULL;
    int citation_length, typeSize;
    tagtype_t citation_type;

    citation_length = GTIFKeyInfo(gtif, GTCitationGeoKey, &typeSize,
				  &citation_type);
    if (citation_length > 0) {
      citation = (char *) MALLOC(citation_length * typeSize);
      GTIFKeyGet(gtif, GTCitationGeoKey, citation, 0, citation_length);
      if (citation && 
	  strcmp_case(citation, "UNCORRECTED SATELLITE DATA") != 0) {
	asfPrintError("Problem with GTCitationGeoKey. Was looking for "
		      "'Uncorrected Satellite Data',\nfound '%s' instead!\n", 
		      citation);
      }
    }
    else
      asfPrintError("Problem with GTCitationGeoKey. Was looking for "
		    "'Uncorrected Satellite Data',\ndid not find any key!\n");

    tiff_type_t tiffInfo;
    get_tiff_type(tiff, &tiffInfo);
    if (tiffInfo.format != SCANLINE_TIFF &&
	tiffInfo.format != STRIP_TIFF    &&
	tiffInfo.format != TILED_TIFF)
      asfPrintError("Can't read the GeoTIFF file (%s). Unrecognized TIFF "
		    "type!\n", inDataNames[band]);

    // If we made it here, we are reasonably sure that we have the file that
    // we are looking for.
    asfPrintStatus("\n   Importing %s ...\n", inDataNames[band]);

    uint32 scanlineSize = TIFFScanlineSize(tiff);
    tdata_t *tiff_real_buf = _TIFFmalloc(scanlineSize);
    tdata_t *tiff_imag_buf = _TIFFmalloc(scanlineSize);
    if (!tiff_real_buf || !tiff_imag_buf)
      asfPrintError("Can't allocate buffer for reading TIFF lines!\n");

    amp = (float *) MALLOC(sizeof(float)*meta->general->sample_count);
    phase = (float *) MALLOC(sizeof(float)*meta->general->sample_count);

    // Check whether we need to flip the image in any fashion
    int flip_vertical = FALSE;
    if (strcmp_case(radarsat2->lineTimeOrdering, "DECREASING") == 0) {
      asfPrintStatus("   Data will be flipped vertically while ingesting!\n");
      flip_vertical = TRUE;
    }
    int flip_horizontal = FALSE;
    if (strcmp_case(radarsat2->pixelTimeOrdering, "DECREASING") == 0) {
      asfPrintStatus("   Data will be flipped horizontally while ingesting!\n");
      flip_horizontal = TRUE;
    }
    if (flip_horizontal)
      tmp = (float *) MALLOC(sizeof(float)*meta->general->sample_count);

    // FIXME: still need to implement flipping vertically
    // Read file line by line
    uint32 row;
    int sample_count = meta->general->sample_count;
    int line_count = meta->general->line_count;
    for (row=0; row<(uint32)meta->general->line_count; row++) {
      asfLineMeter(row, meta->general->line_count);
      if (flip_vertical) {
	switch (tiffInfo.format) 
	  {
	  case SCANLINE_TIFF:
	    TIFFReadScanline(tiff, tiff_real_buf, line_count-row-1, 0);
	    TIFFReadScanline(tiff, tiff_imag_buf, line_count-row-1, 1);
	    break;
	  case STRIP_TIFF:
	    ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, 
					 line_count-row-1, 0);
	    ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, 
					 line_count-row-1, 1);
	    break;
	  case TILED_TIFF:
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, 
					   line_count-row-1, 0);
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, 
					   line_count-row-1, 1);
	    break;
	  default:
	    asfPrintError("Can't read this TIFF format!\n");
	    break;
	  }
      }
      else {
	switch (tiffInfo.format) 
	  {
	  case SCANLINE_TIFF:
	    TIFFReadScanline(tiff, tiff_real_buf, row, 0);
	    TIFFReadScanline(tiff, tiff_imag_buf, row, 1);
	    break;
	  case STRIP_TIFF:
	    ReadScanline_from_TIFF_Strip(tiff, tiff_real_buf, row, 0);
	    ReadScanline_from_TIFF_Strip(tiff, tiff_imag_buf, row, 1);
	    break;
	  case TILED_TIFF:
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_real_buf, row, 0);
	    ReadScanline_from_TIFF_TileRow(tiff, tiff_imag_buf, row, 1);
	    break;
	  default:
	    asfPrintError("Can't read this TIFF format!\n");
	    break;
	  }
      }
      for (sample=0; sample<sample_count; sample++) {
	switch (sample_format)
	  {
	  case SAMPLEFORMAT_UINT:
	    re = (float)(((uint16*)tiff_real_buf)[sample]);
	    im = (float)(((uint16*)tiff_imag_buf)[sample]);
	    break;
	  case SAMPLEFORMAT_INT:
	    re = (float)(((int16*)tiff_real_buf)[sample]);
	    im = (float)(((int16*)tiff_imag_buf)[sample]);
	    break;
	  }
	amp[sample] = sqrt(re*re + im*im);
	phase[sample] = atan2(im, re);
      }
      if (flip_horizontal) {
	for (sample=0; sample<sample_count; sample++)
	  tmp[sample] = amp[sample];
	for (sample=0; sample<sample_count; sample++)
	  amp[sample] = tmp[sample_count-sample-1];
      }
	  
      put_band_float_line(fp, meta, band*2, (int)row, amp);
      if (!ampOnly)
	put_band_float_line(fp, meta, band*2+1, (int)row, phase);
    }
      
    FREE(amp);
    FREE(phase);
    if (tmp)
      FREE(tmp);
    _TIFFfree(tiff_real_buf);
    _TIFFfree(tiff_imag_buf);
    GTIFFree(gtif);
    XTIFFClose(tiff);
  }

  // update the name field with directory name
  char *path = get_dirname(inBaseName);
  if (strlen(path)<=0)
    path = g_get_current_dir();
  char *p = path, *q = path;
  while (q) {
    if ((q = strchr(p, DIR_SEPARATOR)) != NULL)
      p = q+1;
  }
  sprintf(meta->general->basename, "%s", p);
  FREE(path);
  meta_write(meta, outDataName);

  meta_free(meta);
  FREE(radarsat2);
  FCLOSE(fp);
}
Esempio n. 8
0
int read_tiff(const char *filename, int *nlines, int *nsamps,
              unsigned char **data)
{
  TIFF *tiff = XTIFFOpen(filename, "r");
  if (!tiff) {
    return FALSE;
  }

  uint32 width;
  uint32 height;
  TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height);
  TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width);

  *nlines = (int)height;
  *nsamps = (int)width;

  unsigned char *dest = CALLOC(width*height*3, sizeof(unsigned char));

  data_type_t data_type;
  tiff_data_config_t data_config;
  int num_bands, is_scanline_format, is_palette_color_tiff;
  uint32 row;

  // Determine what type of TIFF this is (scanline/strip/tiled)
  if (get_tiff_data_config(tiff,
                           &data_config.sample_format,
                           &data_config.bits_per_sample,
                           &data_config.planar_config,
                           &data_type,
                           &data_config.samples_per_pixel,
                           &is_scanline_format,
                           &is_palette_color_tiff,
                           REPORT_LEVEL_NONE))
  {
    return FALSE;
  }
  num_bands = data_config.samples_per_pixel;

  tiff_type_t tiffInfo;
  get_tiff_type(tiff, &tiffInfo);
  if (tiffInfo.imageCount > 1) {
    ; // Only first image in multi-image files will be utilized - WARN the user here?
  }
  if (tiffInfo.imageCount < 1) {
    // TIFF contains zero images ...fail
    return FALSE;
  }
  if (tiffInfo.format != SCANLINE_TIFF &&
      tiffInfo.format != STRIP_TIFF    &&
      tiffInfo.format != TILED_TIFF)
  {
    // Unrecognized TIFF type
    return FALSE;
  }
  if (tiffInfo.volume_tiff) {
    // 3-dimensional (a 'volume tiff') found ...this is unsupported
    return FALSE;
  }
  if (num_bands > 1 &&
      data_config.planar_config != PLANARCONFIG_CONTIG &&
      data_config.planar_config != PLANARCONFIG_SEPARATE)
  {
    // Invalid planar configuration setting found in TIFF file...
    return FALSE;
  }

  uint32 scanlineSize = TIFFScanlineSize(tiff);
  if (scanlineSize <= 0) {
    // Invalid scanline size found in TIFF file...
    return FALSE;
  }

  if (data_config.bits_per_sample != 8)
    return FALSE;

  int is_rgb = data_config.samples_per_pixel >= 3;

  // Populate the buffer with actual data
  if (is_rgb) {
    // TIFF read buffer (red band)
    tdata_t *rtif_buf = _TIFFmalloc(scanlineSize);
    // TIFF read buffer (green band) 
    tdata_t *gtif_buf = _TIFFmalloc(scanlineSize); 
    // TIFF read buffer (blue band)
    tdata_t *btif_buf = _TIFFmalloc(scanlineSize); 

    if (!rtif_buf || !gtif_buf || !btif_buf)
      return FALSE;

    for (row=0; row < height; row++) {
      // Read a scanline and populate r, g, and b tiff buffers
      // NOTE: Empty bands will have the no_data value populated in the
      //tiff buffer
      read_tiff_rgb_scanline(tiff, tiffInfo.format, &data_config,
                             row, scanlineSize, width,
                             0, 1, 2,
                             rtif_buf, gtif_buf, btif_buf);
      // Interleave the rgb values into an rgb buffer
      interleave_byte_rgbScanlines_to_byte_buff(dest,
                                                rtif_buf, gtif_buf, btif_buf,
                                                0, 1, 2,
                                                row, width, &data_config);
    }

    _TIFFfree(rtif_buf);
    _TIFFfree(gtif_buf);
    _TIFFfree(btif_buf);
  }
  else { // is greyscale
    // TIFF read buffer (interleaved bands)
    tdata_t *tif_buf  = _TIFFmalloc(scanlineSize); 
    if (!tif_buf)
      return FALSE;

    for (row=0; row < height; row++) {
      // Read a scanline into a tiff buffer (using first non-blank band as
      // the greyscale image)
      // NOTE: Since displaying a greyscale band specifically selects a band,
      // empty or not, the selected band is read as-is.
      read_tiff_greyscale_scanline(tiff, tiffInfo.format, &data_config,
                                   row, scanlineSize, width, 0, tif_buf);
      copy_byte_scanline_to_byte_buff(dest, tif_buf,
                                      row, width, &data_config);
    }

    _TIFFfree(tif_buf);
  }

  *data = dest;
  return TRUE;
}
Esempio n. 9
0
static int ReadScanline_from_ContiguousRGB_TIFF(TIFF *tiff, uint32 row, uint32 sample_count,
                                         int band_r, int band_g, int band_b,
                                         tdata_t *rtif_buf, tdata_t *gtif_buf, tdata_t *btif_buf)
{
  data_type_t data_type;
  tiff_data_config_t data_config;
  int num_bands, is_scanline_format, is_palette_color_tiff;

  // Determine what type of TIFF this is (scanline/strip/tiled)
  if (get_tiff_data_config(tiff,
      &data_config.sample_format,
      &data_config.bits_per_sample,
      &data_config.planar_config,
      &data_type,
      &data_config.samples_per_pixel,
      &is_scanline_format,
      &is_palette_color_tiff,
      REPORT_LEVEL_NONE))
  {
    return FALSE;
  }
  num_bands = data_config.samples_per_pixel;
  if (num_bands < 3) {
    return FALSE;
  }
  if (data_config.planar_config != PLANARCONFIG_CONTIG) {
    return FALSE;
  }
  uint32 scanlineSize = TIFFScanlineSize(tiff);
  if (scanlineSize <= 0) {
    return FALSE;
  }
  tdata_t *tif_buf = _TIFFmalloc(scanlineSize);

  TIFFReadScanline(tiff, tif_buf, row, 0); // Read RGB scanline (the band number is ignored for PLANARCONFIG_CONTIG)
  int s;
  for (s=0; s<sample_count; s++) {
    switch(data_config.bits_per_sample) {
      case 8:
        switch(data_config.sample_format) {
          case SAMPLEFORMAT_UINT:
            ((uint8*)rtif_buf)[s] = (uint8)(((uint8*)tif_buf)[s*num_bands+band_r]);
            ((uint8*)gtif_buf)[s] = (uint8)(((uint8*)tif_buf)[s*num_bands+band_g]);
            ((uint8*)btif_buf)[s] = (uint8)(((uint8*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_INT:
            ((int8*)rtif_buf)[s] = (int8)(((int8*)tif_buf)[s*num_bands+band_r]);
            ((int8*)gtif_buf)[s] = (int8)(((int8*)tif_buf)[s*num_bands+band_g]);
            ((int8*)btif_buf)[s] = (int8)(((int8*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_IEEEFP:
          default:
            _TIFFfree(tif_buf);
            return FALSE;
            break;
        }
        break;
      case 16:
        switch(data_config.sample_format) {
          case SAMPLEFORMAT_UINT:
            ((uint16*)rtif_buf)[s] = (uint16)(((uint16*)tif_buf)[s*num_bands+band_r]);
            ((uint16*)gtif_buf)[s] = (uint16)(((uint16*)tif_buf)[s*num_bands+band_g]);
            ((uint16*)btif_buf)[s] = (uint16)(((uint16*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_INT:
            ((int16*)rtif_buf)[s] = (int16)(((int16*)tif_buf)[s*num_bands+band_r]);
            ((int16*)gtif_buf)[s] = (int16)(((int16*)tif_buf)[s*num_bands+band_g]);
            ((int16*)btif_buf)[s] = (int16)(((int16*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_IEEEFP:
          default:
            _TIFFfree(tif_buf);
            return FALSE;
            break;
        }
        break;
      case 32:
        switch(data_config.sample_format) {
          case SAMPLEFORMAT_UINT:
            ((uint32*)rtif_buf)[s] = (uint32)(((uint32*)tif_buf)[s*num_bands+band_r]);
            ((uint32*)gtif_buf)[s] = (uint32)(((uint32*)tif_buf)[s*num_bands+band_g]);
            ((uint32*)btif_buf)[s] = (uint32)(((uint32*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_INT:
            ((long*)rtif_buf)[s] = (long)(((long*)tif_buf)[s*num_bands+band_r]);
            ((long*)gtif_buf)[s] = (long)(((long*)tif_buf)[s*num_bands+band_g]);
            ((long*)btif_buf)[s] = (long)(((long*)tif_buf)[s*num_bands+band_b]);
            break;
          case SAMPLEFORMAT_IEEEFP:
            ((float*)rtif_buf)[s] = (float)(((float*)tif_buf)[s*num_bands+band_r]);
            ((float*)gtif_buf)[s] = (float)(((float*)tif_buf)[s*num_bands+band_g]);
            ((float*)btif_buf)[s] = (float)(((float*)tif_buf)[s*num_bands+band_b]);
            break;
          default:
            _TIFFfree(tif_buf);
            return FALSE;
            break;
        }
        break;
      default:
        _TIFFfree(tif_buf);
        return FALSE;
        break;
    }
  }
  _TIFFfree(tif_buf);

  return TRUE;
}
Esempio n. 10
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);
}
Esempio n. 11
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);
}
Esempio n. 12
0
int
main(int argc, char* argv[])
{
	FILE *in;
	TIFF *out = NULL;
	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;
	extern int optind;
	extern char* optarg;


#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 */
	while ((c = getopt(argc, argv, "R:X:o: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);
#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 (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)
                TIFFSetClientdata(faxTIFF, (thandle_t)_get_osfhandle(fileno(in)));
#else
                TIFFSetClientdata(faxTIFF, (thandle_t)fileno(in));
#endif
		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);
}
Esempio n. 13
0
int
copyFaxFile(TIFF* tifin, TIFF* tifout)
{
	uint32 row;
	uint32 linesize = TIFFhowmany8(xsize);
	uint16 badrun;
	int ok;

	tifin->tif_rawdatasize = (tmsize_t)TIFFGetFileSize(tifin);
	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 */
#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 */
	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);
}
Esempio n. 14
0
static int
tiffcmp(TIFF* tif1, TIFF* tif2)
{
	uint16 config1, config2;
	tsize_t size1;
	uint32 s, row;
	unsigned char *buf1, *buf2;

	if (!CheckShortTag(tif1, tif2, TIFFTAG_BITSPERSAMPLE, "BitsPerSample"))
		return (0);
	if (!CheckShortTag(tif1, tif2, TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel"))
		return (0);
	if (!CheckLongTag(tif1, tif2, TIFFTAG_IMAGEWIDTH, "ImageWidth"))
		return (0);
	if (!cmptags(tif1, tif2))
		return (1);
	(void) TIFFGetField(tif1, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	(void) TIFFGetField(tif1, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	(void) TIFFGetField(tif1, TIFFTAG_IMAGEWIDTH, &imagewidth);
	(void) TIFFGetField(tif1, TIFFTAG_IMAGELENGTH, &imagelength);
	(void) TIFFGetField(tif1, TIFFTAG_PLANARCONFIG, &config1);
	(void) TIFFGetField(tif2, TIFFTAG_PLANARCONFIG, &config2);
	buf1 = (unsigned char *)_TIFFmalloc(size1 = TIFFScanlineSize(tif1));
	buf2 = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif2));
	if (buf1 == NULL || buf2 == NULL) {
		fprintf(stderr, "No space for scanline buffers\n");
		exit(-1);
	}
	if (config1 != config2 && bitspersample != 8 && samplesperpixel > 1) {
		fprintf(stderr,
"Can't handle different planar configuration w/ different bits/sample\n");
		goto bad;
	}
#define	pack(a,b)	((a)<<8)|(b)
	switch (pack(config1, config2)) {
	case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG):
		for (row = 0; row < imagelength; row++) {
			if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
				checkEOF(tif2, row, -1)
			for (s = 0; s < samplesperpixel; s++) {
				if (TIFFReadScanline(tif1, buf1, row, s) < 0)
					checkEOF(tif1, row, s)
				SeparateCompare(1, s, row, buf2, buf1);
			}
		}
		break;
	case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE):
		for (row = 0; row < imagelength; row++) {
			if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
				checkEOF(tif1, row, -1)
			for (s = 0; s < samplesperpixel; s++) {
				if (TIFFReadScanline(tif2, buf2, row, s) < 0)
					checkEOF(tif2, row, s)
				SeparateCompare(0, s, row, buf1, buf2);
			}
		}
		break;
	case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE):
		for (s = 0; s < samplesperpixel; s++)
			for (row = 0; row < imagelength; row++) {
				if (TIFFReadScanline(tif1, buf1, row, s) < 0)
					checkEOF(tif1, row, s)
				if (TIFFReadScanline(tif2, buf2, row, s) < 0)
					checkEOF(tif2, row, s)
				ContigCompare(s, row, buf1, buf2, size1);
			}
		break;
	case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG):
		for (row = 0; row < imagelength; row++) {
			if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
				checkEOF(tif1, row, -1)
			if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
				checkEOF(tif2, row, -1)
			ContigCompare(-1, row, buf1, buf2, size1);
		}
		break;
	}
	if (buf1) _TIFFfree(buf1);
	if (buf2) _TIFFfree(buf2);
	return (1);
bad:
	if (stopondiff)
		exit(1);
	if (buf1) _TIFFfree(buf1);
	if (buf2) _TIFFfree(buf2);
	return (0);
}