Пример #1
0
int
main(int argc, char* argv[])
{
	TIFF *in, *out;
	int c;
	extern int optind;
	extern char *optarg;

	while ((c = getopt(argc, argv, "c:h:r:v:z")) != -1)
		switch (c) {
		case 'c':
			if (streq(optarg, "none"))
			    compression = COMPRESSION_NONE;
			else if (streq(optarg, "packbits"))
			    compression = COMPRESSION_PACKBITS;
			else if (streq(optarg, "lzw"))
			    compression = COMPRESSION_LZW;
			else if (streq(optarg, "jpeg"))
			    compression = COMPRESSION_JPEG;
			else if (streq(optarg, "zip"))
			    compression = COMPRESSION_ADOBE_DEFLATE;
			else
			    usage(-1);
			break;
		case 'h':
			horizSubSampling = atoi(optarg);
			break;
		case 'v':
			vertSubSampling = atoi(optarg);
			break;
		case 'r':
			rowsperstrip = atoi(optarg);
			break;
		case 'z':	/* CCIR Rec 601-1 w/ headroom/footroom */
			refBlackWhite[0] = 16.;
			refBlackWhite[1] = 235.;
			refBlackWhite[2] = 128.;
			refBlackWhite[3] = 240.;
			refBlackWhite[4] = 128.;
			refBlackWhite[5] = 240.;
			break;
		case '?':
			usage(0);
			/*NOTREACHED*/
		}
	if (argc - optind < 2)
		usage(-1);
	out = TIFFOpen(argv[argc-1], "w");
	if (out == NULL)
		return (-2);
	setupLumaTables();
	for (; optind < argc-1; optind++) {
		in = TIFFOpen(argv[optind], "r");
		if (in != NULL) {
			do {
				if (!tiffcvt(in, out) ||
				    !TIFFWriteDirectory(out)) {
					(void) TIFFClose(out);
					return (1);
				}
			} while (TIFFReadDirectory(in));
			(void) TIFFClose(in);
		}
	}
	(void) TIFFClose(out);
	return (0);
}
Пример #2
0
int
create_image_striped(const char *name, uint32 width, uint32 length,
		      uint32 rowsperstrip, uint16 compression,
		      uint16 spp, uint16 bps, uint16 photometric,
		      uint16 sampleformat, uint16 planarconfig,
		      const tdata_t array, const tsize_t size)
{
	TIFF		*tif;

	/* Test whether we can write tags. */
	tif = TIFFOpen(name, "w");
	if (!tif)
		goto openfailure;

	if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width)) {
		fprintf (stderr, "Can't set ImageWidth tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, length)) {
		fprintf (stderr, "Can't set ImageLength tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps)) {
		fprintf (stderr, "Can't set BitsPerSample tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp)) {
		fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip)) {
		fprintf (stderr, "Can't set RowsPerStrip tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planarconfig)) {
		fprintf (stderr, "Can't set PlanarConfiguration tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) {
		fprintf (stderr, "Can't set PhotometricInterpretation tag.\n");
		goto failure;
	}

	if (write_strips(tif, array, size) < 0) {
		fprintf (stderr, "Can't write image data.\n");
		goto failure;
	}

	TIFFClose(tif);
	return 0;

failure:
	TIFFClose(tif);
openfailure:
	fprintf (stderr, "Can't create test TIFF file %s:\n"
"    ImageWidth=%ld, ImageLength=%ld, RowsPerStrip=%ld, Compression=%d,\n"
"    BitsPerSample=%d, SamplesPerPixel=%d, SampleFormat=%d,\n"
"    PlanarConfiguration=%d, PhotometricInterpretation=%d.\n",
		 name, (long) width, (long) length, (long) rowsperstrip,
                 compression, bps, spp, sampleformat, planarconfig,
		 photometric);
	return -1;
}
Пример #3
0
int
read_image_striped(const char *name, uint32 width, uint32 length,
		    uint32 rowsperstrip, uint16 compression,
		    uint16 spp, uint16 bps, uint16 photometric,
		    uint16 sampleformat, uint16 planarconfig,
		    const tdata_t array, const tsize_t size)
{
	TIFF		*tif;
	uint16		value_u16;
	uint32		value_u32;

	/* Test whether we can read written values. */
	tif = TIFFOpen(name, "r");
	if (!tif)
		goto openfailure;
	
	if (TIFFIsTiled(tif)) {
		fprintf (stderr, "Can't read image %s, it is tiled.\n",
			 name);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &value_u32)
	    || value_u32 != width) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_IMAGEWIDTH);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &value_u32)
	    || value_u32 != length) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_IMAGELENGTH);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &value_u16)
	    || value_u16 != bps) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_BITSPERSAMPLE);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &value_u16)
	    || value_u16 != photometric) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_PHOTOMETRIC);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &value_u16)
	    || value_u16 != spp) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_SAMPLESPERPIXEL);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &value_u32)
	    || value_u32 != rowsperstrip) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_ROWSPERSTRIP);
		goto failure;
	}
	if (!TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &value_u16)
	    || value_u16 != planarconfig) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_PLANARCONFIG);
		goto failure;
	}

	if (read_strips(tif, array, size) < 0) {
		fprintf (stderr, "Can't read image data.\n");
		goto failure;
	}

	TIFFClose(tif);
	return 0;

failure:
	TIFFClose(tif);
openfailure:
	fprintf (stderr, "Can't read test TIFF file %s:\n"
"    ImageWidth=%ld, ImageLength=%ld, RowsPerStrip=%ld, Compression=%d,\n"
"    BitsPerSample=%d, SamplesPerPixel=%d, SampleFormat=%d,\n"
"    PlanarConfiguration=%d, PhotometricInterpretation=%d.\n",
		 name, (long) width, (long) length, (long) rowsperstrip,
                 compression, bps, spp, sampleformat, planarconfig,
		 photometric);
	return -1;
}
Пример #4
0
/*
 * PURPOSE:
 * To read DNMI/TIFF palette color files containing either classed satellite
 * imagery or radar imagery.
 *
 * RETURN VALUES:
 * 0 - Normal and correct ending
 * 2 - This is not a Palette-color image
 *
 * NOTE:
 * Requires access to libtiff.
 *
 * AUTHOR:
 * Øystein Godøy, DNMI/FOU, 21/07/1999
 * MODIFICATION:
 * Øystein Godøy, DNMI/FOU, 27/03/2001
 * Corrected some memory allocation and freeing problems connected to
 * strtok actually changing the string it operates on.
 */
int fm_MITIFF_read_imagepal(char *infile, unsigned char *image[], 
    fmio_mihead *ginfo, fmio_mihead_pal *palinfo) {
    
    char *where="MITIFF_read_imagepal";
    TIFF *in;
    int i, status, size;
    short pmi;
    unsigned int fieldlen, currlen, nextlen, taglen;
    uint16 *red, *green, *blue;
    char *description, *o_description;
    char *currfield, *nextfield, *field, *pt;
    char *o_currfield, *o_nextfield, *o_field;
    char *fieldname[FMIO_FIELDS]={
	"Satellite:", 
	"Date and Time:", 
	"SatDir:", 
	"Channels:", 
	"In this file:", 
	"Xsize:", 
	"Ysize:", 
	"Map projection:", 
	"TrueLat:", 
	"GridRot:", 
	"Xunit:", 
	"Yunit:", 
	"NPX:", 
	"NPY:", 
	"Ax:", 
	"Ay:", 
	"Bx:", 
	"By:", 
	"COLOR INFO:"
    };

    /*
     * Open TIFF files and initialize IFD
     */
    
    in=TIFFOpen(infile, "rc");
    if (!in) {
	printf(" This is no TIFF file! \n");
	return(FM_IO_ERR);
    }

    /*
     * Test whether this is a color palette image or not. If so another
     * function should be used.
     */
    status = TIFFGetField(in, 262, &pmi);
    if (pmi != 3) {
	return(FM_IO_ERR);
    }

    status = TIFFGetField(in, 320, &red, &green, &blue);
    if (status != 1) {
	return(FM_IO_ERR);
    }
    for (i=0; i<256; i++) {
	palinfo->cmap[0][i] = red[i];
	palinfo->cmap[1][i] = green[i];
	palinfo->cmap[2][i] = blue[i];
    }

    description = (char *) malloc(FMIO_TIFFHEAD*sizeof(char));
    if (!description) fmerrmsg(where,"Memory allocation failed"); 
    o_description = description;
    TIFFGetField(in, 270, &description);
    /*
     * Lead through the filed tags defined, except for the last one which will
     * create a segmentation fault if it is used. This is processed after the
     * loop.
     */
    currfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char));
    if (!currfield) fmerrmsg(where,"Memory allocation failed"); 
    o_currfield = currfield;
    nextfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char));
    if (!nextfield) fmerrmsg(where,"Memory allocation failed"); 
    o_nextfield = nextfield;
    for (i=0; i<FMIO_FIELDS-1; i++) {
	pt = strstr(description, fieldname[i]);
	sprintf(currfield, "%s", pt);
	currlen = strlen(currfield);
	pt = strstr(description, fieldname[i+1]);
	sprintf(nextfield, "%s", pt);
	nextlen = strlen(nextfield);
	taglen = strlen(fieldname[i]);
	fieldlen = currlen-nextlen-taglen;
	field = (char *) malloc((fieldlen+1)*sizeof(char));
	if (!field) fmerrmsg(where,"Memory allocation failed");
	o_field = field;
	currfield += taglen;
	strncpy(field, currfield, fieldlen);
	fillhead(field, fieldname[i], ginfo);
	free(o_field);
    }
    /*
     * The last part of the information header is treated as one single string
     * and is extracted as the remaining part and processed in a suitable way
     * later...
     */
    pt = strstr(description, fieldname[FMIO_FIELDS-1]);
    sprintf(currfield, "%s", pt);
    currlen = strlen(currfield);
    nextlen = strlen(description);
    taglen = strlen(fieldname[FMIO_FIELDS-1]);
    /*
    fieldlen = nextlen-currlen-taglen;
    field = (char *) malloc((fieldlen+1)*sizeof(char));
    */
    fieldlen = nextlen-currlen-taglen;
    field = (char *) malloc((currlen+1)*sizeof(char));
    if (!field) fmerrmsg(where,"Memory allocation failed");
    o_field = field;
    /*
     * Beware here, in order to help C keep track of which memory to free
     * later, currfield should be reduced by taglen imediately or better a new
     * work string should be used, but for now this solution is chosen...
     */
    currfield += taglen;
    /*
    strncpy(field, currfield, fieldlen);
    */
    strncpy(field, currfield, currlen);
    currfield -= taglen;
    /*
    printf(" %d-%d-%d-%d\n",currlen,nextlen,taglen,fieldlen);
    printf("%s\n\n%s\n",currfield, field);
    printf("%d - %d\n",strlen(currfield),strlen(field));
    */
    fillhead_imagepal(field, fieldname[FMIO_FIELDS-1], palinfo); 
    free(o_field);
    free(o_currfield);
    free(o_nextfield);
    free(o_description);
    /*
     * Read image data into matrix.
     */
    TIFFGetField(in, 256, &ginfo->xsize);
    TIFFGetField(in, 257, &ginfo->ysize);
    size = ginfo->xsize*ginfo->ysize;
  
    /*
     * Memory allocated for image data in this function (*image) is freed 
     * in function main process.
     */
    if (ginfo->zsize > FMIO_MAXCHANNELS) {
	printf("\n\tNOT ENOUGH POINTERS AVAILABLE TO HOLD DATA!\n");
	return(FM_IO_ERR);
    }
    for (i=0; i<ginfo->zsize; i++) {
	image[i] = (unsigned char *) malloc((size+1)*sizeof(char));
	if (!image[i]) fmerrmsg(where,"Memory allocation failed");
	status = TIFFReadRawStrip(in, 0, *image, size);
	if (status == -1) return(FM_IO_ERR);
	if (TIFFReadDirectory(in) == 0) break;
    }

    if (ginfo->zsize != (i+1)) {
	printf("\n\tERROR READING MULTIPLE SUBFILES!\n");
	return(FM_IO_ERR);
    }
    
    TIFFClose(in);
    return(FM_OK);
}
Пример #5
0
int fm_MITIFF_read(char *infile, unsigned char *image[], 
    fmio_mihead *ginfo) {
    
    char *where="MITIFF_read";
    TIFF *in;
    int i, status, size;
    short pmi;
    unsigned int fieldlen, currlen, nextlen, taglen;
    char *description, *o_description;
    char *currfield, *nextfield, *field, *pt;
    char *o_currfield, *o_nextfield, *o_field;
    char *fieldname[FMIO_FIELDS]={
	"Satellite:", 
	"Date and Time:", 
	"SatDir:", 
	"Channels:", 
	"In this file:", 
	"Xsize:", 
	"Ysize:", 
	"Map projection:", 
	"TrueLat:", 
	"GridRot:", 
	"Xunit:", 
	"Yunit:", 
	"NPX:", 
	"NPY:", 
	"Ax:", 
	"Ay:", 
	"Bx:", 
	"By:", 
	"Calibration"
    };

    /*
     * Open TIFF files and initialize IFD
     */
    
    in=TIFFOpen(infile, "rc");
    if (!in) {
	printf(" This is no TIFF file! \n");
	return(FM_IO_ERR);
    }

    /*
     * Test whether this is a color palette image or not. If so another
     * function should be used.
     */
    status = TIFFGetField(in, 262, &pmi);
    if (pmi == 3) {
	return(FM_IO_ERR);
    }

    description = (char *) malloc(1024*sizeof(char));
    if (!description) fmerrmsg(where,"Memory allocation failed");
    o_description = description;
    TIFFGetField(in, 270, &description);
    currfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char));
    if (!currfield) fmerrmsg(where,"Memory allocation failed"); 
    o_currfield = currfield;
    nextfield = (char *) malloc(FMIO_TIFFHEAD*sizeof(char));
    if (!nextfield) fmerrmsg(where,"Memory allocation failed"); 
    o_nextfield = nextfield;
    for (i=0; i<FMIO_FIELDS-1; i++) {
	pt = strstr(description, fieldname[i]);
	sprintf(currfield, "%s", pt);
	currlen = strlen(currfield);
	pt = strstr(description, fieldname[i+1]);
	sprintf(nextfield, "%s", pt);
	nextlen = strlen(nextfield);
	taglen = strlen(fieldname[i]);
	fieldlen = currlen-nextlen-taglen;
	field = (char *) calloc(fieldlen+1, sizeof(char));
	if (!field) fmerrmsg(where,"Memory allocation failed");
	o_field = field;
	currfield += taglen;
	strncpy(field, currfield, fieldlen);
	fillhead(field, fieldname[i], ginfo);
	free(o_field);
    }
    free(o_currfield);
    free(o_nextfield);
    free(o_description); 
    
    /*
     * Read image data into matrix.
     */
    TIFFGetField(in, 256, &ginfo->xsize);
    TIFFGetField(in, 257, &ginfo->ysize);
    size = ginfo->xsize*ginfo->ysize;
  
    /*
     * Memory allocated for image data in this function (*image) is freed 
     * in function main process.
     */
    if (ginfo->zsize > FMIO_MAXCHANNELS) {
	printf("\n\tNOT ENOUGH POINTERS AVAILABLE TO HOLD DATA!\n");
	return(FM_IO_ERR);
    }
    for (i=0; i<ginfo->zsize; i++) {
	image[i] = (unsigned char *) malloc((size+1)*sizeof(char));
	if (!image[i]) fmerrmsg(where,"Memory allocation failed");
	status = TIFFReadRawStrip(in, 0, image[i], size);
	if (status == -1) return(FM_IO_ERR);
	if (TIFFReadDirectory(in) == 0) break;
    }

    if (ginfo->zsize != (i+1)) {
	printf("\n\tERROR READING MULTIPLE SUBFILES!\n");
	return(FM_IO_ERR);
    }
    
    TIFFClose(in);
    return(FM_OK);
}
Пример #6
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);
	cpTags(in, out);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	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);
}
Пример #7
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);
}
Пример #8
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 (TIFFWriteEncodedStrip(tif, strip, newras+row*width, stripsize) < 0)
	    break;
	strip++;
    }
    TIFFClose(tif);

    _TIFFfree(newras);
}
Пример #9
0
bool
TIFFOutput::open (const std::string &name, const ImageSpec &userspec,
                  OpenMode mode)
{
    if (mode == AppendMIPLevel) {
        error ("%s does not support MIP levels", format_name());
        return false;
    }

    close ();  // Close any already-opened file
    m_spec = userspec;  // Stash the spec

    // Check for things this format doesn't support
    if (m_spec.width < 1 || m_spec.height < 1) {
        error ("Image resolution must be at least 1x1, you asked for %d x %d",
               m_spec.width, m_spec.height);
        return false;
    }
    if (m_spec.tile_width) {
       if (m_spec.tile_width  % 16 != 0 ||
           m_spec.tile_height % 16 != 0 ||
           m_spec.tile_height == 0) {
          error("Tile size must be a multiple of 16, you asked for %d x %d", m_spec.tile_width, m_spec.tile_height);
          return false;
       }
    }
    if (m_spec.depth < 1)
        m_spec.depth = 1;

    // Open the file
#ifdef _WIN32
    std::wstring wname = Strutil::utf8_to_utf16 (name);
    m_tif = TIFFOpenW (wname.c_str(), mode == AppendSubimage ? "a" : "w");
#else
    m_tif = TIFFOpen (name.c_str(), mode == AppendSubimage ? "a" : "w");
#endif
    if (! m_tif) {
        error ("Can't open \"%s\" for output.", name.c_str());
        return false;
    }

    // N.B. Clamp position at 0... TIFF is internally incapable of having
    // negative origin.
    TIFFSetField (m_tif, TIFFTAG_XPOSITION, (float)std::max (0, m_spec.x));
    TIFFSetField (m_tif, TIFFTAG_YPOSITION, (float)std::max (0, m_spec.y));

    TIFFSetField (m_tif, TIFFTAG_IMAGEWIDTH, m_spec.width);
    TIFFSetField (m_tif, TIFFTAG_IMAGELENGTH, m_spec.height);

    // Handle display window or "full" size. Note that TIFF can't represent
    // nonzero offsets of the full size, so we may need to expand the
    // display window to encompass the origin.
    if ((m_spec.full_width != 0 || m_spec.full_height != 0) &&
        (m_spec.full_width != m_spec.width || m_spec.full_height != m_spec.height ||
         m_spec.full_x != 0 || m_spec.full_y != 0)) {
        TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, m_spec.full_width+m_spec.full_x);
        TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, m_spec.full_height+m_spec.full_y);
    }

    if (m_spec.tile_width) {
        TIFFSetField (m_tif, TIFFTAG_TILEWIDTH, m_spec.tile_width);
        TIFFSetField (m_tif, TIFFTAG_TILELENGTH, m_spec.tile_height);
    } else {
        // Scanline images must set rowsperstrip
        TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 32);
    }
    TIFFSetField (m_tif, TIFFTAG_SAMPLESPERPIXEL, m_spec.nchannels);
    int orientation = m_spec.get_int_attribute("Orientation", 1);
    TIFFSetField (m_tif, TIFFTAG_ORIENTATION, orientation);
    
    m_bitspersample = m_spec.get_int_attribute ("oiio:BitsPerSample");
    int sampformat;
    switch (m_spec.format.basetype) {
    case TypeDesc::INT8:
        m_bitspersample = 8;
        sampformat = SAMPLEFORMAT_INT;
        break;
    case TypeDesc::UINT8:
        if (m_bitspersample != 2 && m_bitspersample != 4)
            m_bitspersample = 8;
        sampformat = SAMPLEFORMAT_UINT;
        break;
    case TypeDesc::INT16:
        m_bitspersample = 16;
        sampformat = SAMPLEFORMAT_INT;
        break;
    case TypeDesc::UINT16:
        if (m_bitspersample != 10 && m_bitspersample != 12)
            m_bitspersample = 16;
        sampformat = SAMPLEFORMAT_UINT;
        break;
    case TypeDesc::INT32:
        m_bitspersample = 32;
        sampformat = SAMPLEFORMAT_INT;
        break;
    case TypeDesc::UINT32:
        m_bitspersample = 32;
        sampformat = SAMPLEFORMAT_UINT;
        break;
    case TypeDesc::HALF:
        // Adobe extension, see http://chriscox.org/TIFFTN3d1.pdf
        // Unfortunately, Nuke 9.0, and probably many other apps we care
        // about, cannot read 16 bit float TIFFs correctly. Revisit this
        // again in future releases. (comment added Feb 2015)
        // For now, the default is to NOT write this (instead writing float)
        // unless the "tiff:half" attribute is nonzero -- use the global
        // OIIO attribute, but override with a specific attribute for this
        // file.
        if (m_spec.get_int_attribute("tiff:half", OIIO::get_int_attribute("tiff:half"))) {
            m_bitspersample = 16;
        } else {
            // Silently change requests for unsupported 'half' to 'float'
            m_bitspersample = 32;
            m_spec.set_format (TypeDesc::FLOAT);
        }
        sampformat = SAMPLEFORMAT_IEEEFP;
        break;
    case TypeDesc::FLOAT:
        m_bitspersample = 32;
        sampformat = SAMPLEFORMAT_IEEEFP;
        break;
    case TypeDesc::DOUBLE:
        m_bitspersample = 64;
        sampformat = SAMPLEFORMAT_IEEEFP;
        break;
    default:
        // Everything else, including UNKNOWN -- default to 8 bit
        m_bitspersample = 8;
        sampformat = SAMPLEFORMAT_UINT;
        m_spec.set_format (TypeDesc::UINT8);
        break;
    }
    TIFFSetField (m_tif, TIFFTAG_BITSPERSAMPLE, m_bitspersample);
    TIFFSetField (m_tif, TIFFTAG_SAMPLEFORMAT, sampformat);

    m_photometric = (m_spec.nchannels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK);

    string_view comp = m_spec.get_string_attribute("Compression", "zip");
    if (Strutil::iequals (comp, "jpeg") &&
        (m_spec.format != TypeDesc::UINT8 || m_spec.nchannels != 3)) {
        comp = "zip";   // can't use JPEG for anything but 3xUINT8
    }
    m_compression = tiff_compression_code (comp);
    TIFFSetField (m_tif, TIFFTAG_COMPRESSION, m_compression);

    // Use predictor when using compression
    if (m_compression == COMPRESSION_LZW || m_compression == COMPRESSION_ADOBE_DEFLATE) {
        if (m_spec.format == TypeDesc::FLOAT || m_spec.format == TypeDesc::DOUBLE || m_spec.format == TypeDesc::HALF) {
            TIFFSetField (m_tif, TIFFTAG_PREDICTOR, PREDICTOR_FLOATINGPOINT);
            // N.B. Very old versions of libtiff did not support this
            // predictor.  It's possible that certain apps can't read
            // floating point TIFFs with this set.  But since it's been
            // documented since 2005, let's take our chances.  Comment
            // out the above line if this is problematic.
        }
        else if (m_bitspersample == 8 || m_bitspersample == 16) {
            // predictors not supported for unusual bit depths (e.g. 10)
            TIFFSetField (m_tif, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
        }
        if (m_compression == COMPRESSION_ADOBE_DEFLATE) {
            int q = m_spec.get_int_attribute ("tiff:zipquality", -1);
            if (q >= 0)
                TIFFSetField (m_tif, TIFFTAG_ZIPQUALITY, OIIO::clamp(q, 1, 9));
        }
    } else if (m_compression == COMPRESSION_JPEG) {
        TIFFSetField (m_tif, TIFFTAG_JPEGQUALITY,
                      m_spec.get_int_attribute("CompressionQuality", 95));
        TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 64);
        m_spec.attribute ("tiff:RowsPerStrip", 64);
        if (m_photometric == PHOTOMETRIC_RGB) {
            // Compression works so much better when we ask the library to
            // auto-convert RGB to YCbCr.
            TIFFSetField (m_tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
            m_photometric = PHOTOMETRIC_YCBCR;
        }
    }
    m_outputchans = m_spec.nchannels;
    if (m_photometric == PHOTOMETRIC_RGB) {
        // There are a few ways in which we allow allow the user to specify
        // translation to different photometric types.
        string_view photo = m_spec.get_string_attribute("tiff:ColorSpace");
        if (Strutil::iequals (photo, "CMYK") ||
            Strutil::iequals (photo, "color separated")) {
            // User has requested via the "tiff:ColorSpace" attribute that
            // the file be written as color separated channels.
            m_photometric = PHOTOMETRIC_SEPARATED;
            if (m_spec.format != TypeDesc::UINT8 || m_spec.format != TypeDesc::UINT16) {
                m_spec.format = TypeDesc::UINT8;
                m_bitspersample = 8;
                TIFFSetField (m_tif, TIFFTAG_BITSPERSAMPLE, m_bitspersample);
                TIFFSetField (m_tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
            }
            if (source_is_rgb(m_spec)) {
                // Case: RGB -> CMYK, do the conversions per pixel
                m_convert_rgb_to_cmyk = true;
                m_outputchans = 4;  // output 4, not 4 chans
                TIFFSetField (m_tif, TIFFTAG_SAMPLESPERPIXEL, m_outputchans);
                TIFFSetField (m_tif, TIFFTAG_INKSET, INKSET_CMYK);
            } else if (source_is_cmyk(m_spec)) {
                // Case: CMYK -> CMYK (do not transform)
                m_convert_rgb_to_cmyk = false;
                TIFFSetField (m_tif, TIFFTAG_INKSET, INKSET_CMYK);
            } else {
                // Case: arbitrary inks
                m_convert_rgb_to_cmyk = false;
                TIFFSetField (m_tif, TIFFTAG_INKSET, INKSET_MULTIINK);
                std::string inknames;
                for (int i = 0; i < m_spec.nchannels; ++i) {
                    if (i)
                        inknames.insert (inknames.size(), 1, '\0');
                    if (i < (int)m_spec.channelnames.size())
                        inknames.insert (inknames.size(), m_spec.channelnames[i]);
                    else
                        inknames.insert (inknames.size(), Strutil::format("ink%d", i));
                }
                TIFFSetField (m_tif, TIFFTAG_INKNAMES, int(inknames.size()+1), &inknames[0]);
                TIFFSetField (m_tif, TIFFTAG_NUMBEROFINKS, m_spec.nchannels);
            }
        }
    }

    TIFFSetField (m_tif, TIFFTAG_PHOTOMETRIC, m_photometric);

    // ExtraSamples tag
    if (m_spec.nchannels > 3 && m_photometric != PHOTOMETRIC_SEPARATED) {
        bool unass = m_spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
        short e = m_spec.nchannels-3;
        std::vector<unsigned short> extra (e);
        for (int c = 0;  c < e;  ++c) {
            if (m_spec.alpha_channel == (c+3))
                extra[c] = unass ? EXTRASAMPLE_UNASSALPHA : EXTRASAMPLE_ASSOCALPHA;
            else
                extra[c] = EXTRASAMPLE_UNSPECIFIED;
        }
        TIFFSetField (m_tif, TIFFTAG_EXTRASAMPLES, e, &extra[0]);
    }

    ParamValue *param;
    const char *str = NULL;

    // Did the user request separate planar configuration?
    m_planarconfig = PLANARCONFIG_CONTIG;
    if ((param = m_spec.find_attribute("planarconfig", TypeDesc::STRING)) ||
        (param = m_spec.find_attribute("tiff:planarconfig", TypeDesc::STRING))) {
        str = *(char **)param->data();
        if (str && Strutil::iequals (str, "separate"))
            m_planarconfig = PLANARCONFIG_SEPARATE;
    }
    // Can't deal with the headache of separate image planes when using
    // bit packing, or CMYK. Just punt by forcing contig in those cases.
    if (m_bitspersample != spec().format.size()*8 ||
            m_photometric == PHOTOMETRIC_SEPARATED)
        m_planarconfig = PLANARCONFIG_CONTIG;
    if (m_planarconfig == PLANARCONFIG_SEPARATE) {
        if (! m_spec.tile_width) {
            // I can only seem to make separate planarconfig work when
            // rowsperstrip is 1.
            TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 1);
        }
    }
    TIFFSetField (m_tif, TIFFTAG_PLANARCONFIG, m_planarconfig);

    // Automatically set date field if the client didn't supply it.
    if (! m_spec.find_attribute("DateTime")) {
        time_t now;
        time (&now);
        struct tm mytm;
        Sysutil::get_local_time (&now, &mytm);
        std::string date = Strutil::format ("%4d:%02d:%02d %02d:%02d:%02d",
                               mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday,
                               mytm.tm_hour, mytm.tm_min, mytm.tm_sec);
        m_spec.attribute ("DateTime", date);
    }

    // Write ICC profile, if we have anything
    const ParamValue* icc_profile_parameter = m_spec.find_attribute(ICC_PROFILE_ATTR);
    if (icc_profile_parameter != NULL) {
        unsigned char *icc_profile = (unsigned char*)icc_profile_parameter->data();
        uint32 length = icc_profile_parameter->type().size();
        if (icc_profile && length)
            TIFFSetField (m_tif, TIFFTAG_ICCPROFILE, length, icc_profile);
    }

    if (Strutil::iequals (m_spec.get_string_attribute ("oiio:ColorSpace"), "sRGB"))
        m_spec.attribute ("Exif:ColorSpace", 1);

    // Deal with missing XResolution or YResolution, or a PixelAspectRatio
    // that contradicts them.
    float X_density = m_spec.get_float_attribute ("XResolution", 1.0f);
    float Y_density = m_spec.get_float_attribute ("YResolution", 1.0f);
    float aspect = m_spec.get_float_attribute ("PixelAspectRatio", 1.0f);
    if (X_density < 1.0f || Y_density < 1.0f || aspect*X_density != Y_density) {
        if (X_density < 1.0f || Y_density < 1.0f) {
            X_density = Y_density = 1.0f;
            m_spec.attribute ("ResolutionUnit", "none");
        }
        m_spec.attribute ("XResolution", X_density);
        m_spec.attribute ("YResolution", X_density * aspect);
    }

    // Deal with all other params
    for (size_t p = 0;  p < m_spec.extra_attribs.size();  ++p)
        put_parameter (m_spec.extra_attribs[p].name().string(),
                       m_spec.extra_attribs[p].type(),
                       m_spec.extra_attribs[p].data());

    std::vector<char> iptc;
    encode_iptc_iim (m_spec, iptc);
    if (iptc.size()) {
        iptc.resize ((iptc.size()+3) & (0xffff-3));  // round up
        TIFFSetField (m_tif, TIFFTAG_RICHTIFFIPTC, iptc.size()/4, &iptc[0]);
    }

    std::string xmp = encode_xmp (m_spec, true);
    if (! xmp.empty())
        TIFFSetField (m_tif, TIFFTAG_XMLPACKET, xmp.size(), xmp.c_str());
    
    TIFFCheckpointDirectory (m_tif);  // Ensure the header is written early
    m_checkpointTimer.start(); // Initialize the to the fileopen time
    m_checkpointItems = 0; // Number of tiles or scanlines we've written

    m_dither = (m_spec.format == TypeDesc::UINT8) ?
                    m_spec.get_int_attribute ("oiio:dither", 0) : 0;

    return true;
}
Пример #10
0
int
main(int argc, char* argv[])
{
	IMAGE *in;
	TIFF *out;
	int c;
#if !HAVE_DECL_OPTARG
	extern int optind;
	extern char* optarg;
#endif

	while ((c = getopt(argc, argv, "c:p:r:")) != -1)
		switch (c) {
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
		case 'f':		/* fill order */
			if (streq(optarg, "lsb2msb"))
				fillorder = FILLORDER_LSB2MSB;
			else if (streq(optarg, "msb2lsb"))
				fillorder = FILLORDER_MSB2LSB;
			else
				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 = iopen(argv[optind], "r");
	if (in == NULL)
		return (-1);
	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-2);
	TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) in->xsize);
	TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) in->ysize);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
	TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
	if (in->zsize == 1)
		photometric = PHOTOMETRIC_MINISBLACK;
	else
		photometric = PHOTOMETRIC_RGB;
	switch (compression) {
	case COMPRESSION_JPEG:
		if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
			photometric = PHOTOMETRIC_YCBCR;
		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);
	if (fillorder != 0)
		TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
	TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize);
	if (in->zsize > 3) {
	    uint16 v[1];
	    v[0] = EXTRASAMPLE_UNASSALPHA;
	    TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
	}
	TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16) in->min);
	TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16) in->max);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
	if (config != PLANARCONFIG_SEPARATE)
		TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
		    TIFFDefaultStripSize(out, rowsperstrip));
	else			/* force 1 row/strip for library limitation */
		TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L);
	if (in->name[0] != '\0')
		TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name);
	if (config == PLANARCONFIG_CONTIG)
		cpContig(in, out);
	else
		cpSeparate(in, out);
	(void) iclose(in);
	(void) TIFFClose(out);
	return (0);
}
Пример #11
0
void colorengine::threadFunc()
{
    std::unique_ptr<float> regdata(new float[width_*height_]);

    std::vector<float> scalar_constant(3);
    scalar_constant.push_back(0);
    scalar_constant.push_back(0);
    scalar_constant.push_back(0);

    _XTIFFInitialize();
    rawdata_tiff = TIFFOpen(raw_tiff_path.c_str(), "w");
    TIFFSetField(rawdata_tiff, TIFFTAG_NFILTERS, filter_->nfilters());
    TIFFSetField(rawdata_tiff, TIFFTAG_NLIGHTS, nlights_);

    for (auto filter_index = 0; filter_index < filter_->nfilters(); ++filter_index) {
        std::vector<float> cmf = filter_->cmfValues(filter_->wavelengthAtPos(filter_index));
        float illuminant = filter_->illuminantValue(filter_->wavelengthAtPos(filter_index));
        for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) {
            scalar_constant[xyz_index] += cmf[xyz_index] * illuminant;
        }
    }
    int page_index = 0;
    for (int filter_index = 0; filter_index < filter_->nfilters(); ++filter_index) {  
        for (int light_index = 0; light_index < nlights_; ++light_index) {
            std::shared_ptr<unsigned short> data = data_queue_.pop();
            if (cancel_) {
                return;
            }
            std::unique_ptr<float> floatdata(new float[width_*height_]);

            for (auto y = 0; y < height_; ++y) {
                for (auto x = 0; x < width_; ++x) {
                    if (data.get()[y*width_+x] - bias_data.get()[y*width_+x] < 0) {
                        data.get()[y*width_+x] = 0;
                    } else {
                        data.get()[y*width_+x] -= bias_data.get()[y*width_+x];
                    }
                }
            }
            for (auto y = 0; y < height_; ++y) {
                for (auto x = 0; x <width_; ++x) {
                    if (flat_data[light_index]->filterData(filter_index)[y*width_+x] == 0) {
                        floatdata.get()[y*width_+x] = 0;
                    } else {
                        floatdata.get()[y*width_+x] = (float)data.get()[y*width_+x] / (float)flat_data[light_index]->filterData(filter_index)[y*width_+x];
                    }
                }
            }
            // subtract bias, divide flat field
            cv::Mat floatdatamat(height_, width_, CV_32F, floatdata.get());
            // Normalize data to a white reference

            std::vector<float> values;

            for (auto y = wtpt_rect_.y(); y < wtpt_rect_.y() + wtpt_rect_.size().height(); ++y) {
                for (auto x = wtpt_rect_.x(); x < wtpt_rect_.x() + wtpt_rect_.size().width(); ++x) {
                    values.push_back(floatdata.get()[y*width_+x]);
                }
            }
            std::nth_element(values.begin(), values.begin()+(values.size()/2), values.end()); // median sort in constant time
            float measured_wtpt = values[values.size()/2];

            for (auto y = 0; y < height_; ++y) {
                for (auto x = 0; x < width_; ++x) {
                    floatdata.get()[y*width_+x] /= (measured_wtpt / absolute_wtpt_values_[filter_index]);
                }
            }

            if (filter_index == 0) { // use first filter as registration target
                for (auto y = 0; y < height_; ++y) {
                    for (auto x = 0; x < width_; ++x) {
                        regdata.get()[y*width_+x] = floatdata.get()[y*width_+x];
                    }
                }
                cv::Mat regdatamat(height_, width_, CV_32F, regdata.get());

            } else {                // Register image to regtarget_data
                // Phase-correlate based registration algorithm to align image planes based on two concentric circle targets
                // Concentric targets are used because of their non-repeating nature; phase correlate gets tripped up by repeating patterns as the peaks can be matched at errant points

                //cv::mat construction is efficient and does not copy data.  Initialize registration target from our regdata


                cv::Mat registerTo(height_, width_, CV_32F, regdata.get());
                cv::Mat reg0_source, reg0_target, reg1_source, reg1_target;
                cv::Mat reg0_sourcef, reg0_targetf, reg1_sourcef, reg1_targetf;

                // These cv::Mats' are our registration targets; selected by the user in the main application.

                //reg0_source = registration target 0 on the image that is going to be registered
                //reg0_target = registration target 1 on the image that is going to be registered to
                reg0_sourcef = floatdatamat(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width()));
                reg0_targetf = registerTo(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width()));// - (reg_size/2), regtargets[0].y + (reg_size/2)), cv::Range(regtargets[0].x - (reg_size/2), regtargets[0].x + (reg_size/2)));
                reg1_sourcef = floatdatamat(cv::Range(regtargets[1].y(), regtargets[1].y() + regtargets[1].size().height()), cv::Range(regtargets[1].x(), regtargets[1].x() + regtargets[1].size().width()));// - (reg_size/2), regtargets[1].y + (reg_size/2)), cv::Range(regtargets[1].x - (reg_size/2), regtargets[1].x + (reg_size/2)));
                reg1_targetf = registerTo(cv::Range(regtargets[1].y(), regtargets[1].y() + regtargets[1].size().height()), cv::Range(regtargets[1].x(), regtargets[1].x() + regtargets[1].size().width()));// - (reg_size/2), regtargets[1].y + (reg_size/2)), cv::Range(regtargets[1].x - (reg_size/2), regtargets[1].x + (reg_size/2)));

                double min, max;
                cv::Point minLoc, maxLoc;

                cv::minMaxLoc(reg0_sourcef, &min, &max, &minLoc, &maxLoc);
                reg0_sourcef *= 255/max;
                cv::minMaxLoc(reg1_sourcef, &min, &max, &minLoc, &maxLoc);
                reg1_sourcef *= 255/max;
                cv::minMaxLoc(reg0_targetf, &min, &max, &minLoc, &maxLoc);
                reg0_targetf *= 255/max;
                cv::minMaxLoc(reg1_targetf, &min, &max, &minLoc, &maxLoc);
                reg1_targetf *= 255/max;

                reg0_sourcef.convertTo(reg0_source, CV_8U);
                reg0_targetf.convertTo(reg0_target, CV_8U);
                reg1_sourcef.convertTo(reg1_source, CV_8U);
                reg1_targetf.convertTo(reg1_target, CV_8U);

                cv::adaptiveThreshold(reg0_source, reg0_source, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2);
                cv::adaptiveThreshold(reg0_target, reg0_target, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2);
                cv::adaptiveThreshold(reg1_source, reg1_source, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2);
                cv::adaptiveThreshold(reg1_target, reg1_target, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 11, 2);

                reg0_source.convertTo(reg0_source, CV_32F);
                reg1_source.convertTo(reg1_source, CV_32F);
                reg0_target.convertTo(reg0_target, CV_32F);
                reg1_target.convertTo(reg1_target, CV_32F);

                reg0_sourcef /= 255;
                reg0_targetf /= 255;
                reg1_sourcef /= 255;
                reg1_targetf /= 255;

                cv::Point2d offset_center = cv::phaseCorrelate(reg0_source, reg0_target);
                cv::Point2d offset_corner = cv::phaseCorrelate(reg1_source, reg1_target);

                float r, r_prime, deltaX, deltaY;

                deltaX = offset_corner.x - offset_center.x;
                deltaY = offset_corner.y - offset_center.y;

                r = pow((regtargets[1].center().x() - regtargets[0].center().x()), 2) + pow((regtargets[1].center().y() - regtargets[0].center().y()), 2);
                r = sqrt(r);

                r_prime = pow((regtargets[1].center().x() - regtargets[0].center().x() + deltaX), 2) + pow((regtargets[1].center().y() - regtargets[0].center().y() + deltaY), 2);
                r_prime = sqrt(r_prime);


                float scale = r_prime / r;
                float trans_x = (floatdatamat.size().width  / 2) * (1-scale);
                float trans_y = (floatdatamat.size().height / 2) * (1-scale);

                std::vector<float> matrix_data(6);
                matrix_data[0] = scale;
                matrix_data[1] = 0;
                matrix_data[2] = trans_x;
                matrix_data[3] = 0;
                matrix_data[4] = scale;
                matrix_data[5] = trans_y;

                cv::Mat affine(2, 3, CV_32F, matrix_data.data());
                cv::Mat scaled;
                cv::warpAffine(floatdatamat, scaled, affine, floatdatamat.size());

                cv::Mat scaled_target = scaled(cv::Range(regtargets[0].y(), regtargets[0].y() + regtargets[0].size().height()), cv::Range(regtargets[0].x(), regtargets[0].x() + regtargets[0].size().width()));
                cv::Point2d translation_offset = cv::phaseCorrelate(scaled_target, reg0_target);


                matrix_data[2] += translation_offset.x;
                matrix_data[5] += translation_offset.y;

                cv::warpAffine(floatdatamat, floatdatamat, affine, floatdatamat.size());
            }
            if (raw_tiff_path.size() > 0) {
                TIFFSetField(rawdata_tiff, TIFFTAG_IMAGEWIDTH, width_);
                TIFFSetField(rawdata_tiff, TIFFTAG_IMAGELENGTH, height_);
                TIFFSetField(rawdata_tiff, TIFFTAG_BITSPERSAMPLE, sizeof(float) * 8);
                TIFFSetField(rawdata_tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
                TIFFSetField(rawdata_tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
                TIFFSetField(rawdata_tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
                TIFFSetField(rawdata_tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
                TIFFSetField(rawdata_tiff, TIFFTAG_SUBFILETYPE, FILETYPE_PAGE);
                TIFFSetField(rawdata_tiff, TIFFTAG_WTPTVAL, absolute_wtpt_values_[filter_index]);
                TIFFSetField(rawdata_tiff, TIFFTAG_WTPTMEASURED, measured_wtpt);
                TIFFSetField(rawdata_tiff, TIFFTAG_PAGENUMBER, page_index);

                for (auto row = 0; row < height_; ++row) {
                    TIFFWriteScanline(rawdata_tiff, &floatdata.get()[row*width_], row);
                }
                TIFFWriteDirectory(rawdata_tiff);
                ++page_index;
            }

            int wavelength = filter_->wavelengthAtPos(filter_index);
            std::vector<float> cmf = filter_->cmfValues(wavelength);
            float illuminant = filter_->illuminantValue(wavelength);
            for (auto y = 0; y < height_; ++y) {
                for (auto x = 0; x < width_; ++x) {
                    for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) {
                        xyz_data[light_index].get()->filterData(xyz_index)[y*width_+x] += floatdata.get()[y*width_+x] * cmf[xyz_index] * illuminant;
                    }
                }
            }
        }
    }
    if (raw_tiff_path.size() > 0) {
        TIFFClose(rawdata_tiff);
    }
    // Scale xyz data by scalar constant
    for (auto light = 0; light < nlights_; ++light) {
        for (auto y = 0; y < height_; ++y) {
            for (auto x = 0; x < width_; ++x) {
                for (auto xyz_index = 0; xyz_index < 3; ++xyz_index) {
                     xyz_data[light].get()->filterData(xyz_index)[y*width_+x] /= scalar_constant[xyz_index];
                }
            }
        }
    }


    std::vector<XYZImage*> xyz_ptr;
    for (auto i = 0; i < xyz_data.size(); ++i) {
        xyz_ptr.push_back(xyz_data[i].get());
    }
    std::vector<float> weights(nlights_);
    for (auto weight = 0; weight < weights.size(); ++weight) {
       weights[weight] = 1.0 / float(nlights_);
    }

    master_xyz = std::shared_ptr<XYZImage>(new XYZImage(xyz_ptr, nlights_, weights));
}
Пример #12
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);
		}
	    }
      }
Пример #13
0
bool
TIFFOutput::open (const std::string &name, const ImageSpec &userspec,
                  OpenMode mode)
{
    if (mode == AppendMIPLevel) {
        error ("%s does not support MIP levels", format_name());
        return false;
    }

    close ();  // Close any already-opened file
    m_spec = userspec;  // Stash the spec

    // Check for things this format doesn't support
    if (m_spec.width < 1 || m_spec.height < 1) {
        error ("Image resolution must be at least 1x1, you asked for %d x %d",
               m_spec.width, m_spec.height);
        return false;
    }
    if (m_spec.tile_width) {
       if (m_spec.tile_width  % 16 != 0 ||
           m_spec.tile_height % 16 != 0 ||
           m_spec.tile_height == 0) {
          error("Tile size must be a multiple of 16, you asked for %d x %d", m_spec.tile_width, m_spec.tile_height);
          return false;
       }
    }
    if (m_spec.depth < 1)
        m_spec.depth = 1;

    // Open the file
#ifdef _WIN32
    std::wstring wname = Strutil::utf8_to_utf16 (name);
    m_tif = TIFFOpenW (wname.c_str(), mode == AppendSubimage ? "a" : "w");
#else
    m_tif = TIFFOpen (name.c_str(), mode == AppendSubimage ? "a" : "w");
#endif
    if (! m_tif) {
        error ("Can't open \"%s\" for output.", name.c_str());
        return false;
    }

    // N.B. Clamp position at 0... TIFF is internally incapable of having
    // negative origin.
    TIFFSetField (m_tif, TIFFTAG_XPOSITION, (float)std::max (0, m_spec.x));
    TIFFSetField (m_tif, TIFFTAG_YPOSITION, (float)std::max (0, m_spec.y));

    TIFFSetField (m_tif, TIFFTAG_IMAGEWIDTH, m_spec.width);
    TIFFSetField (m_tif, TIFFTAG_IMAGELENGTH, m_spec.height);
    if ((m_spec.full_width != 0 || m_spec.full_height != 0) &&
        (m_spec.full_width != m_spec.width || m_spec.full_height != m_spec.height)) {
        TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, m_spec.full_width);
        TIFFSetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, m_spec.full_height);
    }
    if (m_spec.tile_width) {
        TIFFSetField (m_tif, TIFFTAG_TILEWIDTH, m_spec.tile_width);
        TIFFSetField (m_tif, TIFFTAG_TILELENGTH, m_spec.tile_height);
    } else {
        // Scanline images must set rowsperstrip
        TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 32);
    }
    TIFFSetField (m_tif, TIFFTAG_SAMPLESPERPIXEL, m_spec.nchannels);
    int orientation = m_spec.get_int_attribute("Orientation", 1);
    TIFFSetField (m_tif, TIFFTAG_ORIENTATION, orientation);
    
    int bps, sampformat;
    switch (m_spec.format.basetype) {
    case TypeDesc::INT8:
        bps = 8;
        sampformat = SAMPLEFORMAT_INT;
        break;
    case TypeDesc::UINT8:
        bps = 8;
        sampformat = SAMPLEFORMAT_UINT;
        break;
    case TypeDesc::INT16:
        bps = 16;
        sampformat = SAMPLEFORMAT_INT;
        break;
    case TypeDesc::UINT16:
        bps = 16;
        sampformat = SAMPLEFORMAT_UINT;
        break;
    case TypeDesc::HALF:
        // Silently change requests for unsupported 'half' to 'float'
        m_spec.set_format (TypeDesc::FLOAT);
    case TypeDesc::FLOAT:
        bps = 32;
        sampformat = SAMPLEFORMAT_IEEEFP;
        break;
    case TypeDesc::DOUBLE:
        bps = 64;
        sampformat = SAMPLEFORMAT_IEEEFP;
        break;
    default:
        // Everything else, including UNKNOWN -- default to 8 bit
        bps = 8;
        sampformat = SAMPLEFORMAT_UINT;
        m_spec.set_format (TypeDesc::UINT8);
        break;
    }
    TIFFSetField (m_tif, TIFFTAG_BITSPERSAMPLE, bps);
    TIFFSetField (m_tif, TIFFTAG_SAMPLEFORMAT, sampformat);

    int photo = (m_spec.nchannels > 1 ? PHOTOMETRIC_RGB : PHOTOMETRIC_MINISBLACK);
    TIFFSetField (m_tif, TIFFTAG_PHOTOMETRIC, photo);

    // ExtraSamples tag
    if (m_spec.nchannels > 3) {
        bool unass = m_spec.get_int_attribute("oiio:UnassociatedAlpha", 0);
        short e = m_spec.nchannels-3;
        std::vector<unsigned short> extra (e);
        for (int c = 0;  c < e;  ++c) {
            if (m_spec.alpha_channel == (c+3))
                extra[c] = unass ? EXTRASAMPLE_UNASSALPHA : EXTRASAMPLE_ASSOCALPHA;
            else
                extra[c] = EXTRASAMPLE_UNSPECIFIED;
        }
        TIFFSetField (m_tif, TIFFTAG_EXTRASAMPLES, e, &extra[0]);
    }

    // Default to LZW compression if no request came with the user spec
    if (! m_spec.find_attribute("compression"))
        m_spec.attribute ("compression", "lzw");

    ImageIOParameter *param;
    const char *str = NULL;

    // Did the user request separate planar configuration?
    m_planarconfig = PLANARCONFIG_CONTIG;
    if ((param = m_spec.find_attribute("planarconfig", TypeDesc::STRING)) ||
        (param = m_spec.find_attribute("tiff:planarconfig", TypeDesc::STRING))) {
        str = *(char **)param->data();
        if (str && Strutil::iequals (str, "separate")) {
            m_planarconfig = PLANARCONFIG_SEPARATE;
            if (! m_spec.tile_width) {
                // I can only seem to make separate planarconfig work when
                // rowsperstrip is 1.
                TIFFSetField (m_tif, TIFFTAG_ROWSPERSTRIP, 1);
            }
        }
    }
    TIFFSetField (m_tif, TIFFTAG_PLANARCONFIG, m_planarconfig);

    // Automatically set date field if the client didn't supply it.
    if (! m_spec.find_attribute("DateTime")) {
        time_t now;
        time (&now);
        struct tm mytm;
        Sysutil::get_local_time (&now, &mytm);
        std::string date = Strutil::format ("%4d:%02d:%02d %2d:%02d:%02d",
                               mytm.tm_year+1900, mytm.tm_mon+1, mytm.tm_mday,
                               mytm.tm_hour, mytm.tm_min, mytm.tm_sec);
        m_spec.attribute ("DateTime", date);
    }

    // Write ICC profile, if we have anything
    const ImageIOParameter* icc_profile_parameter = m_spec.find_attribute(ICC_PROFILE_ATTR);
    if (icc_profile_parameter != NULL) {
        unsigned char *icc_profile = (unsigned char*)icc_profile_parameter->data();
        uint32 length = icc_profile_parameter->type().size();
        if (icc_profile && length)
            TIFFSetField (m_tif, TIFFTAG_ICCPROFILE, length, icc_profile);
    }

    if (Strutil::iequals (m_spec.get_string_attribute ("oiio:ColorSpace"), "sRGB"))
        m_spec.attribute ("Exif:ColorSpace", 1);

    // Deal with all other params
    for (size_t p = 0;  p < m_spec.extra_attribs.size();  ++p)
        put_parameter (m_spec.extra_attribs[p].name().string(),
                       m_spec.extra_attribs[p].type(),
                       m_spec.extra_attribs[p].data());

    std::vector<char> iptc;
    encode_iptc_iim (m_spec, iptc);
    if (iptc.size()) {
        iptc.resize ((iptc.size()+3) & (0xffff-3));  // round up
        TIFFSetField (m_tif, TIFFTAG_RICHTIFFIPTC, iptc.size()/4, &iptc[0]);
    }

    std::string xmp = encode_xmp (m_spec, true);
    if (! xmp.empty())
        TIFFSetField (m_tif, TIFFTAG_XMLPACKET, xmp.size(), xmp.c_str());
    
    TIFFCheckpointDirectory (m_tif);  // Ensure the header is written early
    m_checkpointTimer.start(); // Initialize the to the fileopen time
    m_checkpointItems = 0; // Number of tiles or scanlines we've written

    m_dither = (m_spec.format == TypeDesc::UINT8) ?
                    m_spec.get_int_attribute ("oiio:dither", 0) : 0;

    return true;
}
Пример #14
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);
}
Пример #15
0
void
TIFFInput::readspec ()
{
    uint32 width = 0, height = 0, depth = 0;
    unsigned short nchans = 1;
    TIFFGetField (m_tif, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField (m_tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_IMAGEDEPTH, &depth);
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLESPERPIXEL, &nchans);

    m_spec = ImageSpec ((int)width, (int)height, (int)nchans);

    float x = 0, y = 0;
    TIFFGetField (m_tif, TIFFTAG_XPOSITION, &x);
    TIFFGetField (m_tif, TIFFTAG_YPOSITION, &y);
    m_spec.x = (int)x;
    m_spec.y = (int)y;
    m_spec.z = 0;
    // FIXME? - TIFF spec describes the positions as in resolutionunit.
    // What happens if this is not unitless pixels?  Are we interpreting
    // it all wrong?

    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLWIDTH, &width) == 1
          && width > 0)
        m_spec.full_width = width;
    if (TIFFGetField (m_tif, TIFFTAG_PIXAR_IMAGEFULLLENGTH, &height) == 1
          && height > 0)
        m_spec.full_height = height;

    if (TIFFIsTiled (m_tif)) {
        TIFFGetField (m_tif, TIFFTAG_TILEWIDTH, &m_spec.tile_width);
        TIFFGetField (m_tif, TIFFTAG_TILELENGTH, &m_spec.tile_height);
        TIFFGetFieldDefaulted (m_tif, TIFFTAG_TILEDEPTH, &m_spec.tile_depth);
    } else {
        m_spec.tile_width = 0;
        m_spec.tile_height = 0;
        m_spec.tile_depth = 0;
    }

    m_bitspersample = 8;
    TIFFGetField (m_tif, TIFFTAG_BITSPERSAMPLE, &m_bitspersample);
    m_spec.attribute ("oiio:BitsPerSample", (int)m_bitspersample);

    unsigned short sampleformat = SAMPLEFORMAT_UINT;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_SAMPLEFORMAT, &sampleformat);
    switch (m_bitspersample) {
    case 1:
    case 2:
    case 4:
        // Make 1, 2, 4 bpp look like byte images
    case 8:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT8);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT8);
        else m_spec.set_format (TypeDesc::UINT8);  // punt
        break;
    case 16:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT16);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT16);
        break;
    case 32:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::FLOAT);
        break;
    case 64:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::DOUBLE);
        break;
    default:
        m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    }

    // Use the table for all the obvious things that can be mindlessly
    // shoved into the image spec.
    for (int i = 0;  tiff_tag_table[i].name;  ++i)
        find_tag (tiff_tag_table[i].tifftag,
                  tiff_tag_table[i].tifftype, tiff_tag_table[i].name);

    // Now we need to get fields "by hand" for anything else that is less
    // straightforward...

    m_photometric = (m_spec.nchannels == 1 ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB);
    TIFFGetField (m_tif, TIFFTAG_PHOTOMETRIC, &m_photometric);
    m_spec.attribute ("tiff:PhotometricInterpretation", (int)m_photometric);
    if (m_photometric == PHOTOMETRIC_PALETTE) {
        // Read the color map
        unsigned short *r = NULL, *g = NULL, *b = NULL;
        TIFFGetField (m_tif, TIFFTAG_COLORMAP, &r, &g, &b);
        ASSERT (r != NULL && g != NULL && b != NULL);
        m_colormap.clear ();
        m_colormap.insert (m_colormap.end(), r, r + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), g, g + (1 << m_bitspersample));
        m_colormap.insert (m_colormap.end(), b, b + (1 << m_bitspersample));
        // Palette TIFF images are always 3 channels (to the client)
        m_spec.nchannels = 3;
        m_spec.default_channel_names ();
    }

    TIFFGetFieldDefaulted (m_tif, TIFFTAG_PLANARCONFIG, &m_planarconfig);
    m_spec.attribute ("tiff:PlanarConfiguration", (int)m_planarconfig);
    if (m_planarconfig == PLANARCONFIG_SEPARATE)
        m_spec.attribute ("planarconfig", "separate");
    else
        m_spec.attribute ("planarconfig", "contig");

    int compress = 0;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_COMPRESSION, &compress);
    m_spec.attribute ("tiff:Compression", compress);
    switch (compress) {
    case COMPRESSION_NONE :
        m_spec.attribute ("compression", "none");
        break;
    case COMPRESSION_LZW :
        m_spec.attribute ("compression", "lzw");
        break;
    case COMPRESSION_CCITTRLE :
        m_spec.attribute ("compression", "ccittrle");
        break;
    case COMPRESSION_DEFLATE :
    case COMPRESSION_ADOBE_DEFLATE :
        m_spec.attribute ("compression", "zip");
        break;
    case COMPRESSION_PACKBITS :
        m_spec.attribute ("compression", "packbits");
        break;
    default:
        break;
    }

    int rowsperstrip = -1;
    if (! m_spec.tile_width) {
        TIFFGetField (m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
        if (rowsperstrip > 0)
            m_spec.attribute ("tiff:RowsPerStrip", rowsperstrip);
    }

    // The libtiff docs say that only uncompressed images, or those with
    // rowsperstrip==1, support random access to scanlines.
    m_no_random_access = (compress != COMPRESSION_NONE && rowsperstrip != 1);

    short resunit = -1;
    TIFFGetField (m_tif, TIFFTAG_RESOLUTIONUNIT, &resunit);
    switch (resunit) {
    case RESUNIT_NONE : m_spec.attribute ("ResolutionUnit", "none"); break;
    case RESUNIT_INCH : m_spec.attribute ("ResolutionUnit", "in"); break;
    case RESUNIT_CENTIMETER : m_spec.attribute ("ResolutionUnit", "cm"); break;
    }

    get_matrix_attribute ("worldtocamera", TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA);
    get_matrix_attribute ("worldtoscreen", TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN);
    get_int_attribute ("tiff:subfiletype", TIFFTAG_SUBFILETYPE);
    // FIXME -- should subfiletype be "conventionized" and used for all
    // plugins uniformly? 

    // FIXME: do we care about fillorder for 1-bit and 4-bit images?

    // Special names for shadow maps
    char *s = NULL;
    TIFFGetField (m_tif, TIFFTAG_PIXAR_TEXTUREFORMAT, &s);
    if (s)
        m_emulate_mipmap = true;
    if (s && ! strcmp (s, "Shadow")) {
        for (int c = 0;  c < m_spec.nchannels;  ++c)
            m_spec.channelnames[c] = "z";
    }

    // N.B. we currently ignore the following TIFF fields:
    // ExtraSamples
    // GrayResponseCurve GrayResponseUnit
    // MaxSampleValue MinSampleValue
    // NewSubfileType SubfileType(deprecated)
    // Colorimetry fields

    // Search for an EXIF IFD in the TIFF file, and if found, rummage 
    // around for Exif fields.
#if TIFFLIB_VERSION > 20050912    /* compat with old TIFF libs - skip Exif */
    int exifoffset = 0;
    if (TIFFGetField (m_tif, TIFFTAG_EXIFIFD, &exifoffset) &&
            TIFFReadEXIFDirectory (m_tif, exifoffset)) {
        for (int i = 0;  exif_tag_table[i].name;  ++i)
            find_tag (exif_tag_table[i].tifftag, exif_tag_table[i].tifftype,
                      exif_tag_table[i].name);
        // I'm not sure what state TIFFReadEXIFDirectory leaves us.
        // So to be safe, close and re-seek.
        TIFFClose (m_tif);
        m_tif = TIFFOpen (m_filename.c_str(), "rm");
        TIFFSetDirectory (m_tif, m_subimage);

        // A few tidbits to look for
        ImageIOParameter *p;
        if ((p = m_spec.find_attribute ("Exif:ColorSpace", TypeDesc::INT))) {
            // Exif spec says that anything other than 0xffff==uncalibrated
            // should be interpreted to be sRGB.
            if (*(const int *)p->data() != 0xffff)
                m_spec.attribute ("oiio::ColorSpace", "sRGB");
        }
    }
#endif

#if TIFFLIB_VERSION >= 20051230
    // Search for IPTC metadata in IIM form -- but older versions of
    // libtiff botch the size, so ignore it for very old libtiff.
    int iptcsize = 0;
    const void *iptcdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_RICHTIFFIPTC, &iptcsize, &iptcdata)) {
        std::vector<uint32> iptc ((uint32 *)iptcdata, (uint32 *)iptcdata+iptcsize);
        if (TIFFIsByteSwapped (m_tif))
            TIFFSwabArrayOfLong ((uint32*)&iptc[0], iptcsize);
        decode_iptc_iim (&iptc[0], iptcsize*4, m_spec);
    }
#endif

    // Search for an XML packet containing XMP (IPTC, Exif, etc.)
    int xmlsize = 0;
    const void *xmldata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_XMLPACKET, &xmlsize, &xmldata)) {
        // std::cerr << "Found XML data, size " << xmlsize << "\n";
        if (xmldata && xmlsize) {
            std::string xml ((const char *)xmldata, xmlsize);
            decode_xmp (xml, m_spec);
        }
    }

#if 0
    // Experimental -- look for photoshop data
    int photoshopsize = 0;
    const void *photoshopdata = NULL;
    if (TIFFGetField (m_tif, TIFFTAG_PHOTOSHOP, &photoshopsize, &photoshopdata)) {
        std::cerr << "Found PHOTOSHOP data, size " << photoshopsize << "\n";
        if (photoshopdata && photoshopsize) {
//            std::string photoshop ((const char *)photoshopdata, photoshopsize);
//            std::cerr << "PHOTOSHOP:\n" << photoshop << "\n---\n";
        }
    }
#endif
}
Пример #16
0
int
main(int argc, char* argv[])
{
    uint32	width = 0, length = 0, linebytes, bufsize;
    uint32	nbands = 1;		    /* number of bands in input image*/
    off_t	hdr_size = 0;		    /* size of the header to skip */
    TIFFDataType dtype = TIFF_BYTE;
    int16	depth = 1;		    /* bytes per pixel in input image */
    int	swab = 0;		    /* byte swapping flag */
    InterleavingType interleaving = 0;  /* interleaving type flag */
    uint32  rowsperstrip = (uint32) -1;
    uint16	photometric = PHOTOMETRIC_MINISBLACK;
    uint16	config = PLANARCONFIG_CONTIG;
    uint16	fillorder = FILLORDER_LSB2MSB;
    int	fd;
    char	*outfilename = NULL;
    TIFF	*out;

    uint32 row, col, band;
    int	c;
    unsigned char *buf = NULL, *buf1 = NULL;
    extern int optind;
    extern char* optarg;

    while ((c = getopt(argc, argv, "c:r:H:w:l:b:d:LMp:si:o:h")) != -1) {
        switch (c) {
        case 'c':		/* compression scheme */
            if (!processCompressOptions(optarg))
                usage();
            break;
        case 'r':		/* rows/strip */
            rowsperstrip = atoi(optarg);
            break;
        case 'H':		/* size of input image file header */
            hdr_size = atoi(optarg);
            break;
        case 'w':		/* input image width */
            width = atoi(optarg);
            break;
        case 'l':		/* input image length */
            length = atoi(optarg);
            break;
        case 'b':		/* number of bands in input image */
            nbands = atoi(optarg);
            break;
        case 'd':		/* type of samples in input image */
            if (strncmp(optarg, "byte", 4) == 0)
                dtype = TIFF_BYTE;
            else if (strncmp(optarg, "short", 5) == 0)
                dtype = TIFF_SHORT;
            else if  (strncmp(optarg, "long", 4) == 0)
                dtype = TIFF_LONG;
            else if  (strncmp(optarg, "sbyte", 5) == 0)
                dtype = TIFF_SBYTE;
            else if  (strncmp(optarg, "sshort", 6) == 0)
                dtype = TIFF_SSHORT;
            else if  (strncmp(optarg, "slong", 5) == 0)
                dtype = TIFF_SLONG;
            else if  (strncmp(optarg, "float", 5) == 0)
                dtype = TIFF_FLOAT;
            else if  (strncmp(optarg, "double", 6) == 0)
                dtype = TIFF_DOUBLE;
            else
                dtype = TIFF_BYTE;
            depth = TIFFDataWidth(dtype);
            break;
        case 'L':		/* input has lsb-to-msb fillorder */
            fillorder = FILLORDER_LSB2MSB;
            break;
        case 'M':		/* input has msb-to-lsb fillorder */
            fillorder = FILLORDER_MSB2LSB;
            break;
        case 'p':		/* photometric interpretation */
            if (strncmp(optarg, "miniswhite", 10) == 0)
                photometric = PHOTOMETRIC_MINISWHITE;
            else if (strncmp(optarg, "minisblack", 10) == 0)
                photometric = PHOTOMETRIC_MINISBLACK;
            else if (strncmp(optarg, "rgb", 3) == 0)
                photometric = PHOTOMETRIC_RGB;
            else if (strncmp(optarg, "cmyk", 4) == 0)
                photometric = PHOTOMETRIC_SEPARATED;
            else if (strncmp(optarg, "ycbcr", 5) == 0)
                photometric = PHOTOMETRIC_YCBCR;
            else if (strncmp(optarg, "cielab", 6) == 0)
                photometric = PHOTOMETRIC_CIELAB;
            else if (strncmp(optarg, "icclab", 6) == 0)
                photometric = PHOTOMETRIC_ICCLAB;
            else if (strncmp(optarg, "itulab", 6) == 0)
                photometric = PHOTOMETRIC_ITULAB;
            else
                photometric = PHOTOMETRIC_MINISBLACK;
            break;
        case 's':		/* do we need to swap bytes? */
            swab = 1;
            break;
        case 'i':		/* type of interleaving */
            if (strncmp(optarg, "pixel", 4) == 0)
                interleaving = PIXEL;
            else if  (strncmp(optarg, "band", 6) == 0)
                interleaving = BAND;
            else
                interleaving = 0;
            break;
        case 'o':
            outfilename = optarg;
            break;
        case 'h':
            usage();
        default:
            break;
        }
    }

    if (argc - optind < 2)
        usage();

    fd = open(argv[optind], O_RDONLY|O_BINARY, 0);
    if (fd < 0) {
        fprintf(stderr, "%s: %s: Cannot open input file.\n",
                argv[0], argv[optind]);
        return (-1);
    }

    if (guessSize(fd, dtype, hdr_size, nbands, swab, &width, &length) < 0)
        return 1;

    if (outfilename == NULL)
        outfilename = argv[optind+1];
    out = TIFFOpen(outfilename, "w");
    if (out == NULL) {
        fprintf(stderr, "%s: %s: Cannot open file for output.\n",
                argv[0], outfilename);
        return (-1);
    }
    TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
    TIFFSetField(out, TIFFTAG_IMAGELENGTH, length);
    TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
    TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, nbands);
    TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, depth * 8);
    TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
    TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
    TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
    switch (dtype) {
    case TIFF_BYTE:
    case TIFF_SHORT:
    case TIFF_LONG:
        TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
        break;
    case TIFF_SBYTE:
    case TIFF_SSHORT:
    case TIFF_SLONG:
        TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
        break;
    case TIFF_FLOAT:
    case TIFF_DOUBLE:
        TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
        break;
    default:
        TIFFSetField(out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_VOID);
        break;
    }
    if (compression == (uint16) -1)
        compression = COMPRESSION_PACKBITS;
    TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
    switch (compression) {
    case COMPRESSION_JPEG:
        if (photometric == PHOTOMETRIC_RGB
                && jpegcolormode == JPEGCOLORMODE_RGB)
            photometric = PHOTOMETRIC_YCBCR;
        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;
    }
    switch(interleaving) {
    case BAND:				/* band interleaved data */
        linebytes = width * depth;
        buf = (unsigned char *)_TIFFmalloc(linebytes);
        break;
    case PIXEL:				/* pixel interleaved data */
    default:
        linebytes = width * nbands * depth;
        break;
    }
    bufsize = width * nbands * depth;
    buf1 = (unsigned char *)_TIFFmalloc(bufsize);

    rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
    if (rowsperstrip > length) {
        rowsperstrip = length;
    }
    TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip );

    lseek(fd, hdr_size, SEEK_SET);		/* Skip the file header */
    for (row = 0; row < length; row++) {
        switch(interleaving) {
        case BAND:			/* band interleaved data */
            for (band = 0; band < nbands; band++) {
                lseek(fd,
                      hdr_size + (length*band+row)*linebytes,
                      SEEK_SET);
                if (read(fd, buf, linebytes) < 0) {
                    fprintf(stderr,
                            "%s: %s: scanline %lu: Read error.\n",
                            argv[0], argv[optind],
                            (unsigned long) row);
                    break;
                }
                if (swab)	/* Swap bytes if needed */
                    swapBytesInScanline(buf, width, dtype);
                for (col = 0; col < width; col++)
                    memcpy(buf1 + (col*nbands+band)*depth,
                           buf + col * depth, depth);
            }
            break;
        case PIXEL:			/* pixel interleaved data */
        default:
            if (read(fd, buf1, bufsize) < 0) {
                fprintf(stderr,
                        "%s: %s: scanline %lu: Read error.\n",
                        argv[0], argv[optind],
                        (unsigned long) row);
                break;
            }
            if (swab)		/* Swap bytes if needed */
                swapBytesInScanline(buf1, width, dtype);
            break;
        }

        if (TIFFWriteScanline(out, buf1, row, 0) < 0) {
            fprintf(stderr,	"%s: %s: scanline %lu: Write error.\n",
                    argv[0], outfilename, (unsigned long) row);
            break;
        }
    }
    if (buf)
        _TIFFfree(buf);
    if (buf1)
        _TIFFfree(buf1);
    TIFFClose(out);
    return (0);
}
Пример #17
0
// Internal function used to save the Tiff.
ILboolean iSaveTiffInternal(char *Filename)
{
	ILenum	Format;
	ILenum	Compression;
	ILuint	ixLine;
	TIFF	*File;
	char	Description[512];
	ILimage	*TempImage;

	if(iCurImage == NULL) {
		ilSetError(IL_ILLEGAL_OPERATION);
		return IL_FALSE;
	}


	if (iGetHint(IL_COMPRESSION_HINT) == IL_USE_COMPRESSION)
		Compression = COMPRESSION_PACKBITS;
	else
		Compression = COMPRESSION_NONE;

	if (iCurImage->Format == IL_COLOUR_INDEX) {
		if (ilGetBppPal(iCurImage->Pal.PalType) == 4)  // Preserve the alpha.
			TempImage = iConvertImage(iCurImage, IL_RGBA, IL_UNSIGNED_BYTE);
		else
			TempImage = iConvertImage(iCurImage, IL_RGB, IL_UNSIGNED_BYTE);

		if (TempImage == NULL) {
			return IL_FALSE;
		}
	}
	else {
		TempImage = iCurImage;
	}
	
	File = TIFFOpen(Filename, "w");
	//File = iTIFFOpen("w");
	if (File == NULL) {
		ilSetError(IL_COULD_NOT_OPEN_FILE);
		return IL_FALSE;
	}

	sprintf(Description, "Tiff generated by %s", ilGetString(IL_VERSION_NUM));

	TIFFSetField(File, TIFFTAG_IMAGEWIDTH, TempImage->Width);
	TIFFSetField(File, TIFFTAG_IMAGELENGTH, TempImage->Height);
	TIFFSetField(File, TIFFTAG_COMPRESSION, Compression);
	TIFFSetField(File, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
	TIFFSetField(File, TIFFTAG_BITSPERSAMPLE, TempImage->Bpc << 3);
	TIFFSetField(File, TIFFTAG_SAMPLESPERPIXEL, TempImage->Bpp);
	TIFFSetField(File, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(File, TIFFTAG_ROWSPERSTRIP, 1);
	TIFFSetField(File, TIFFTAG_SOFTWARE, ilGetString(IL_VERSION_NUM));
	/*TIFFSetField(File, TIFFTAG_DOCUMENTNAME,
						iGetString(IL_TIF_DOCUMENTNAME_STRING) ?
						iGetString(IL_TIF_DOCUMENTNAME_STRING) : FileName);*/
	if (iGetString(IL_TIF_DOCUMENTNAME_STRING))
		TIFFSetField(File, TIFFTAG_DOCUMENTNAME, iGetString(IL_TIF_DOCUMENTNAME_STRING));
	if (iGetString(IL_TIF_AUTHNAME_STRING))
		TIFFSetField(File, TIFFTAG_ARTIST, iGetString(IL_TIF_AUTHNAME_STRING));
	if (iGetString(IL_TIF_HOSTCOMPUTER_STRING))
		TIFFSetField(File, TIFFTAG_HOSTCOMPUTER,
					iGetString(IL_TIF_HOSTCOMPUTER_STRING));
	if (iGetString(IL_TIF_DESCRIPTION_STRING))
		TIFFSetField(File, TIFFTAG_IMAGEDESCRIPTION,
					iGetString(IL_TIF_DESCRIPTION_STRING));
	TIFFSetField(File, TIFFTAG_DATETIME, iMakeString());


        // 24/4/2003
        // Orientation flag is not always supported ( Photoshop, ...), orient the image data 
        // and set it always to normal view
        TIFFSetField(File, TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT );
        if( TempImage->Origin != IL_ORIGIN_UPPER_LEFT ) {
            ILubyte *Data = iGetFlipped(TempImage);
            ifree( (void*)TempImage->Data );
            TempImage->Data = Data;
        }
        
        /*
	TIFFSetField(File, TIFFTAG_ORIENTATION,
		TempImage->Origin == IL_ORIGIN_UPPER_LEFT ? ORIENTATION_TOPLEFT : ORIENTATION_BOTLEFT);
        */
        
	Format = TempImage->Format;
	if (Format == IL_BGR || Format == IL_BGRA)
		ilSwapColours();

	for (ixLine = 0; ixLine < TempImage->Height; ++ixLine) {
		if (TIFFWriteScanline(File, TempImage->Data + ixLine * TempImage->Bps, ixLine, 0) < 0) {
			TIFFClose(File);
			ilSetError(IL_LIB_TIFF_ERROR);
			return IL_FALSE;
		}
	}

	if (Format == IL_BGR || Format == IL_BGRA)
		ilSwapColours();

	if (TempImage != iCurImage)
		ilCloseImage(TempImage);

	TIFFClose(File);

	return IL_TRUE;
}
Пример #18
0
int main(int argc, char **argv)
{
    char *          input_file = NULL;
    double          image_gamma = TIFF_GAMMA;
    int             i, j;
    TIFF *          tif;
    unsigned char * scan_line;
    uint16          red[CMSIZE], green[CMSIZE], blue[CMSIZE];
    float	    refblackwhite[2*3];

    programName = argv[0];

    switch (argc) {
    case 2:
        image_gamma = TIFF_GAMMA;
        input_file = argv[1];
        break;
    case 4:
        if (!strcmp(argv[1], "-gamma")) {
            image_gamma = atof(argv[2]);
            input_file = argv[3];
        } else
            Usage();
        break;
    default:
        Usage();
    }

    for (i = 0; i < CMSIZE; i++) {
        if (i == 0)
            red[i] = green[i] = blue[i] = 0;
        else {
            red[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
            green[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
            blue[i] = ROUND((pow(i / 255.0, 1.0 / image_gamma) * 65535.0));
        }
    }
    refblackwhite[0] = 0.0; refblackwhite[1] = 255.0;
    refblackwhite[2] = 0.0; refblackwhite[3] = 255.0;
    refblackwhite[4] = 0.0; refblackwhite[5] = 255.0;

    if ((tif = TIFFOpen(input_file, "w")) == NULL) {
        fprintf(stderr, "can't open %s as a TIFF file\n", input_file);
        exit(0);
    }

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
#ifdef notdef
    TIFFSetField(tif, TIFFTAG_WHITEPOINT, whitex, whitey);
    TIFFSetField(tif, TIFFTAG_PRIMARYCHROMATICITIES, primaries);
#endif
    TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE, refblackwhite);
    TIFFSetField(tif, TIFFTAG_TRANSFERFUNCTION, red, green, blue);

    scan_line = (unsigned char *) malloc(WIDTH * 3);

    for (i = 0; i < 255; i++) {
        for (j = 0; j < 75; j++) {
             scan_line[j * 3] = 255;
             scan_line[(j * 3) + 1] = 255 - i;
             scan_line[(j * 3) + 2] = 255 - i;
        }
        for (j = 75; j < 150; j++) {
             scan_line[j * 3] = 255 - i;
             scan_line[(j * 3) + 1] = 255;
             scan_line[(j * 3) + 2] = 255 - i;
        }
        for (j = 150; j < 225; j++) {
             scan_line[j * 3] = 255 - i;
             scan_line[(j * 3) + 1] = 255 - i;
             scan_line[(j * 3) + 2] = 255;
        }
        for (j = 225; j < 300; j++) {
             scan_line[j * 3] = (i - 1) / 2;
             scan_line[(j * 3) + 1] = (i - 1) / 2;
             scan_line[(j * 3) + 2] = (i - 1) / 2;
        }
        for (j = 300; j < 375; j++) {
             scan_line[j * 3] = 255 - i;
             scan_line[(j * 3) + 1] = 255;
             scan_line[(j * 3) + 2] = 255;
        }
        for (j = 375; j < 450; j++) {
             scan_line[j * 3] = 255;
             scan_line[(j * 3) + 1] = 255 - i;
             scan_line[(j * 3) + 2] = 255;
        }
        for (j = 450; j < 525; j++) {
             scan_line[j * 3] = 255;
             scan_line[(j * 3) + 1] = 255;
             scan_line[(j * 3) + 2] = 255 - i;
        }
        TIFFWriteScanline(tif, scan_line, i, 0);
    }
    for (i = 255; i < 512; i++) {
        for (j = 0; j < 75; j++) {
             scan_line[j * 3] = i;
             scan_line[(j * 3) + 1] = 0;
             scan_line[(j * 3) + 2] = 0;
        }
        for (j = 75; j < 150; j++) {
             scan_line[j * 3] = 0;
             scan_line[(j * 3) + 1] = i;
             scan_line[(j * 3) + 2] = 0;
        }
        for (j = 150; j < 225; j++) {
             scan_line[j * 3] = 0;
             scan_line[(j * 3) + 1] = 0;
             scan_line[(j * 3) + 2] = i;
        }
        for (j = 225; j < 300; j++) {
             scan_line[j * 3] = (i - 1) / 2;
             scan_line[(j * 3) + 1] = (i - 1) / 2;
             scan_line[(j * 3) + 2] = (i - 1) / 2;
        }
        for (j = 300; j < 375; j++) {
             scan_line[j * 3] = 0;
             scan_line[(j * 3) + 1] = i;
             scan_line[(j * 3) + 2] = i;
        }
        for (j = 375; j < 450; j++) {
             scan_line[j * 3] = i;
             scan_line[(j * 3) + 1] = 0;
             scan_line[(j * 3) + 2] = i;
        }
        for (j = 450; j < 525; j++) {
             scan_line[j * 3] = i;
             scan_line[(j * 3) + 1] = i;
             scan_line[(j * 3) + 2] = 0;
        }
        TIFFWriteScanline(tif, scan_line, i, 0);
    }

    free(scan_line);
    TIFFClose(tif);
    exit(0);
}
Пример #19
0
int main( int argc, char ** argv )

{
    int		anOverviews[100];   /* TODO: un-hardwire array length, flexible allocate */
    int		nOverviewCount = 0;
    int		bUseSubIFD = 0;
    TIFF	*hTIFF;
    const char  *pszResampling = "nearest";

/* -------------------------------------------------------------------- */
/*      Usage:                                                          */
/* -------------------------------------------------------------------- */
    if( argc < 2 )
    {
        printf( "Usage: addtiffo [-r {nearest,average,mode}]\n"
                "                tiff_filename [resolution_reductions]\n"
                "\n"
                "Example:\n"
                " %% addtiffo abc.tif 2 4 8 16\n" );
        return( 1 );
    }

    while( argv[1][0] == '-' )
    {
        if( strcmp(argv[1],"-subifd") == 0 )
        {
            bUseSubIFD = 1;
            argv++;
            argc--;
        }
        else if( strcmp(argv[1],"-r") == 0 )
        {
            argv += 2;
            argc -= 2;
            pszResampling = *argv;
        }
        else
        {
            fprintf( stderr, "Incorrect parameters\n" );
            return( 1 );
        }
    }

    /* TODO: resampling mode parameter needs to be encoded in an integer from this point on */

/* -------------------------------------------------------------------- */
/*      Collect the user requested reduction factors.                   */
/* -------------------------------------------------------------------- */
    while( nOverviewCount < argc - 2 && nOverviewCount < 100 )
    {
        anOverviews[nOverviewCount] = atoi(argv[nOverviewCount+2]);
        if( anOverviews[nOverviewCount] <= 0)
        {
            fprintf( stderr, "Incorrect parameters\n" );
            return(1);
        }
        nOverviewCount++;
    }

/* -------------------------------------------------------------------- */
/*      Default to four overview levels.  It would be nicer if it       */
/*      defaulted based on the size of the source image.                */
/* -------------------------------------------------------------------- */
    /* TODO: make it default based on the size of the source image */
    if( nOverviewCount == 0 )
    {
        nOverviewCount = 4;

        anOverviews[0] = 2;
        anOverviews[1] = 4;
        anOverviews[2] = 8;
        anOverviews[3] = 16;
    }

/* -------------------------------------------------------------------- */
/*      Build the overview.                                             */
/* -------------------------------------------------------------------- */
    hTIFF = TIFFOpen( argv[1], "r+" );
    if( hTIFF == NULL )
    {
        fprintf( stderr, "TIFFOpen(%s) failed.\n", argv[1] );
        return( 1 );
    }

    TIFFBuildOverviews( hTIFF, nOverviewCount, anOverviews, bUseSubIFD,
                        pszResampling, NULL, NULL );

    TIFFClose( hTIFF );

/* -------------------------------------------------------------------- */
/*      Optionally test for memory leaks.                               */
/* -------------------------------------------------------------------- */
#ifdef DBMALLOC
    malloc_dump(1);
#endif

    return( 0 );
}
Пример #20
0
int
main(int argc, char **argv)
{
	TIFF		*tif;
	int		i;
	unsigned char	buf[3] = { 0, 127, 255 };
	char		*value;

	/* Test whether we can write tags. */
	tif = TIFFOpen(filename, "w");
	if (!tif) {
		fprintf (stderr, "Can't create test TIFF file %s.\n", filename);
		return 1;
	}

	if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, 1)) {
		fprintf (stderr, "Can't set ImageWidth tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, 1)) {
		fprintf (stderr, "Can't set ImageLength tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8)) {
		fprintf (stderr, "Can't set BitsPerSample tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3)) {
		fprintf (stderr, "Can't set SamplesPerPixel tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG)) {
		fprintf (stderr, "Can't set PlanarConfiguration tag.\n");
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB)) {
		fprintf (stderr, "Can't set PhotometricInterpretation tag.\n");
		goto failure;
	}

	for (i = 0; i < NTAGS; i++) {
		if (!TIFFSetField(tif, ascii_tags[i].tag,
				  ascii_tags[i].value)) {
			fprintf(stderr, "Can't set tag %d.\n",
				(int)ascii_tags[i].tag);
			goto failure;
		}
	}

	/* InkNames tag has special form, so we handle it separately. */
	if (!TIFFSetField(tif, TIFFTAG_NUMBEROFINKS, 3)) {
		fprintf (stderr, "Can't set tag %d.\n", TIFFTAG_NUMBEROFINKS);
		goto failure;
	}
	if (!TIFFSetField(tif, TIFFTAG_INKNAMES, ink_names_size, ink_names)) {
		fprintf (stderr, "Can't set tag %d.\n", TIFFTAG_INKNAMES);
		goto failure;
	}

	/* Write dummy pixel data. */
	if (!TIFFWriteScanline(tif, buf, 0, 0) < 0) {
		fprintf (stderr, "Can't write image data.\n");
		goto failure;
	}

	TIFFClose(tif);
	
	/* Ok, now test whether we can read written values. */
	tif = TIFFOpen(filename, "r");
	if (!tif) {
		fprintf (stderr, "Can't open test TIFF file %s.\n", filename);
		return 1;
	}

	for (i = 0; i < NTAGS; i++) {
		if (!TIFFGetField(tif, ascii_tags[i].tag, &value)
		    || strcmp(value, ascii_tags[i].value)) {
			fprintf(stderr, "Can't get tag %d.\n",
				(int)ascii_tags[i].tag);
			goto failure;
		}
	}

	if (!TIFFGetField(tif, TIFFTAG_INKNAMES, &value)
	    || memcmp(value, ink_names, ink_names_size)) {
		fprintf (stderr, "Can't get tag %d.\n", TIFFTAG_INKNAMES);
		goto failure;
	}

	TIFFClose(tif);
	
	/* All tests passed; delete file and exit with success status. */
	unlink(filename);
	return 0;

failure:
	/* Something goes wrong; close file and return unsuccessful status. */
	TIFFClose(tif);
	unlink(filename);
	return 1;
}