Example #1
0
void
rasterize(int interleaved, char* mode)
{
    register unsigned long row;
    unsigned char *newras;
    unsigned char *ras;
    TIFF *tif;
    tstrip_t strip;
    tsize_t stripsize;

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

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

    _TIFFfree(newras);
}
Example #2
0
 void close_tif () {
     if (m_tif) {
         TIFFClose (m_tif);
         m_tif = NULL;
     }
 }
Example #3
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);
}
Example #4
0
int
main(int argc, char* argv[])
{
    TIFF *tiff;
    int  arg_index;

    if (argc < 2)
        usage();

    tiff = TIFFOpen(argv[argc-1], "r+");
    if (tiff == NULL)
        return 2;

    for( arg_index = 1; arg_index < argc-1; arg_index++ ) {
        if (strcmp(argv[arg_index],"-s") == 0 && arg_index < argc-3) {
            const TIFFFieldInfo *fip;
            const char *tagname;

            arg_index++;
            tagname = argv[arg_index];
            fip = GetField(tiff, tagname);

            if (!fip)
                return 3;

            arg_index++;
            if (fip->field_type == TIFF_ASCII) {
                if (TIFFSetField(tiff, fip->field_tag, argv[arg_index]) != 1)
                    fprintf( stderr, "Failed to set %s=%s\n",
                             fip->field_name, argv[arg_index] );
            } else if (fip->field_writecount > 0) {
                int     ret = 1;
                short   wc;

                if (fip->field_writecount == TIFF_VARIABLE)
                        wc = atoi(argv[arg_index++]);
                else
                        wc = fip->field_writecount;

                if (argc - arg_index < wc) {
                    fprintf( stderr,
                             "Number of tag values is not enough. "
                             "Expected %d values for %s tag, got %d\n",
                             wc, fip->field_name, argc - arg_index);
                    return 4;
                }
                    
                if (wc > 1) {
                        int     i, size;
                        void    *array;

                        switch (fip->field_type) {
                                /*
                                 * XXX: We can't use TIFFDataWidth()
                                 * to determine the space needed to store
                                 * the value. For TIFF_RATIONAL values
                                 * TIFFDataWidth() returns 8, but we use 4-byte
                                 * float to represent rationals.
                                 */
                                case TIFF_BYTE:
                                case TIFF_ASCII:
                                case TIFF_SBYTE:
                                case TIFF_UNDEFINED:
				default:
                                    size = 1;
                                    break;

                                case TIFF_SHORT:
                                case TIFF_SSHORT:
                                    size = 2;
                                    break;

                                case TIFF_LONG:
                                case TIFF_SLONG:
                                case TIFF_FLOAT:
                                case TIFF_IFD:
                                case TIFF_RATIONAL:
                                case TIFF_SRATIONAL:
                                    size = 4;
                                    break;

                                case TIFF_DOUBLE:
                                    size = 8;
                                    break;
                        }

                        array = _TIFFmalloc(wc * size);
                        if (!array) {
                                fprintf(stderr, "No space for %s tag\n",
                                        tagname);
                                return 4;
                        }

                        switch (fip->field_type) {
                            case TIFF_BYTE:
                                for (i = 0; i < wc; i++)
                                    ((uint8 *)array)[i] = atoi(argv[arg_index+i]);
                                break;
                            case TIFF_SHORT:
                                for (i = 0; i < wc; i++)
                                    ((uint16 *)array)[i] = atoi(argv[arg_index+i]);
                                break;
                            case TIFF_SBYTE:
                                for (i = 0; i < wc; i++)
                                    ((int8 *)array)[i] = atoi(argv[arg_index+i]);
                                break;
                            case TIFF_SSHORT:
                                for (i = 0; i < wc; i++)
                                    ((int16 *)array)[i] = atoi(argv[arg_index+i]);
                                break;
                            case TIFF_LONG:
                                for (i = 0; i < wc; i++)
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
                                break;
                            case TIFF_SLONG:
                            case TIFF_IFD:
                                for (i = 0; i < wc; i++)
                                    ((uint32 *)array)[i] = atol(argv[arg_index+i]);
                                break;
                            case TIFF_DOUBLE:
                                for (i = 0; i < wc; i++)
                                    ((double *)array)[i] = atof(argv[arg_index+i]);
                                break;
                            case TIFF_RATIONAL:
                            case TIFF_SRATIONAL:
                            case TIFF_FLOAT:
                                for (i = 0; i < wc; i++)
                                    ((float *)array)[i] = (float)atof(argv[arg_index+i]);
                                break;
                            default:
                                break;
                        }
                
                        if (fip->field_passcount) {
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   wc, array);
                        } else {
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   array);
                        }

                        _TIFFfree(array);
                } else {
                        switch (fip->field_type) {
                            case TIFF_BYTE:
                            case TIFF_SHORT:
                            case TIFF_SBYTE:
                            case TIFF_SSHORT:
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   atoi(argv[arg_index++]));
                                break;
                            case TIFF_LONG:
                            case TIFF_SLONG:
                            case TIFF_IFD:
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   atol(argv[arg_index++]));
                                break;
                            case TIFF_DOUBLE:
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   atof(argv[arg_index++]));
                                break;
                            case TIFF_RATIONAL:
                            case TIFF_SRATIONAL:
                            case TIFF_FLOAT:
                                ret = TIFFSetField(tiff, fip->field_tag,
                                                   (float)atof(argv[arg_index++]));
                                break;
                            default:
                                break;
                        }
                }

                if (ret != 1)
                    fprintf(stderr, "Failed to set %s\n", fip->field_name);
                arg_index += wc;
            }
        } else if (strcmp(argv[arg_index],"-sf") == 0 && arg_index < argc-3) {
            FILE    *fp;
            const TIFFFieldInfo *fip;
            char    *text;
            int     len;

            arg_index++;
            fip = GetField(tiff, argv[arg_index]);

            if (!fip)
                return 3;

            if (fip->field_type != TIFF_ASCII) {
                fprintf( stderr,
                         "Only ASCII tags can be set from file. "
                         "%s is not ASCII tag.\n", fip->field_name );
                return 5;
            }

            arg_index++;
            fp = fopen( argv[arg_index], "rt" );
            if(fp == NULL) {
                perror( argv[arg_index] );
                continue;
            }

            text = (char *) malloc(1000000);
            len = fread( text, 1, 999999, fp );
            text[len] = '\0';

            fclose( fp );

            if(TIFFSetField( tiff, fip->field_tag, text ) != 1) {
                fprintf(stderr, "Failed to set %s from file %s\n", 
                        fip->field_name, argv[arg_index]);
            }

            _TIFFfree( text );
            arg_index++;
        } else {
            fprintf(stderr, "Unrecognised option: %s\n",
                    argv[arg_index]);
            usage();
        }
    }

    TIFFRewriteDirectory(tiff);
    TIFFClose(tiff);
    return 0;
}
Example #5
0
int
main(int argc, char* argv[])
{
	uint16 defconfig = (uint16) -1;
	uint16 deffillorder = 0;
	uint32 deftilewidth = (uint32) -1;
	uint32 deftilelength = (uint32) -1;
	uint32 defrowsperstrip = (uint32) -1;
	uint32 diroff = 0;
	TIFF* in;
	TIFF* out;
	const char* mode = "w";
	int c;
	extern int optind;
	extern char* optarg;

	while ((c = getopt(argc, argv, "c:f:l:o:p:r:w:e:g:4:aistd8")) != -1)
		switch (c) {
		case 'a':		/* append to output */
			mode = "a";
			break;
		case '8':		/* append to output */
			mode = "w8";
			break;
		case 'd':		/* down cast 8bit to 4bit */
                        convert_8_to_4 = 1;
			break;
		case 'c':		/* compression scheme */
			if (!processCompressOptions(optarg))
				usage();
			break;
                case 'e':
                        worldfile = optarg;
                        break;
		case 'f':		/* fill order */
			if (streq(optarg, "lsb2msb"))
				deffillorder = FILLORDER_LSB2MSB;
			else if (streq(optarg, "msb2lsb"))
				deffillorder = FILLORDER_MSB2LSB;
			else
				usage();
			break;
		case 'i':		/* ignore errors */
			ignore = TRUE;
			break;
		case 'g':		/* GeoTIFF metadata file */
			geofile = optarg;
			break;
		case '4':	       
			proj4_string = optarg;
			break;
		case 'l':		/* tile length */
			outtiled = TRUE;
			deftilelength = atoi(optarg);
			break;
		case 'o':		/* initial directory offset */
			diroff = strtoul(optarg, NULL, 0);
			break;
		case 'p':		/* planar configuration */
			if (streq(optarg, "separate"))
				defconfig = PLANARCONFIG_SEPARATE;
			else if (streq(optarg, "contig"))
				defconfig = PLANARCONFIG_CONTIG;
			else
				usage();
			break;
		case 'r':		/* rows/strip */
			defrowsperstrip = atoi(optarg);
			break;
		case 's':		/* generate stripped output */
			outtiled = FALSE;
			break;
		case 't':		/* generate tiled output */
			outtiled = TRUE;
			break;
		case 'w':		/* tile width */
			outtiled = TRUE;
			deftilewidth = atoi(optarg);
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	if (argc - optind < 2)
		usage();
	out = TIFFOpen(argv[argc-1], mode);
	if (out == NULL)
		return (-2);
	for (; optind < argc-1 ; optind++) {
		in = TIFFOpen(argv[optind], "r");
		if (in == NULL)
			return (-3);
		if (diroff != 0 && !TIFFSetSubDirectory(in, diroff)) {
			TIFFError(TIFFFileName(in),
			    "Error, setting subdirectory at %#x", diroff);
			(void) TIFFClose(out);
			return (1);
		}
		do {
			config = defconfig;
			compression = defcompression;
			predictor = defpredictor;
			fillorder = deffillorder;
			rowsperstrip = defrowsperstrip;
			tilewidth = deftilewidth;
			tilelength = deftilelength;
			g3opts = defg3opts;
			if (!tiffcp(in, out) || !TIFFWriteDirectory(out)) {
				(void) TIFFClose(out);
				return (1);
			}
		} while (TIFFReadDirectory(in));
		(void) TIFFClose(in);
	}
	(void) TIFFClose(out);
	return (0);
}
Example #6
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;


	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);
	for (pn = 0; optind < argc; pn++, optind++) {
		in = fopen(argv[optind], "r" BINMODE);
		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);
}
Example #7
0
void
XTIFFClose(TIFF *tif)
{
    TIFFClose(tif);
}
Example #8
0
        WriteResult::WriteStatus writeTIFStream(std::ostream& fout, const osg::Image& img) const
        {
            //Code is based from the following article on CodeProject.com
            //http://www.codeproject.com/bitmap/BitmapsToTiffs.asp

            TIFF *image;
            int samplesPerPixel;
            int bitsPerSample;
            uint16 photometric;

            image = TIFFClientOpen("outputstream", "w", (thandle_t)&fout,
                                    libtiffOStreamReadProc, //Custom read function
                                    libtiffOStreamWriteProc, //Custom write function
                                    libtiffOStreamSeekProc, //Custom seek function
                                    libtiffStreamCloseProc, //Custom close function
                                    libtiffOStreamSizeProc, //Custom size function
                                    libtiffStreamMapProc, //Custom map function
                                    libtiffStreamUnmapProc); //Custom unmap function

            if(image == NULL)
            {
                return WriteResult::ERROR_IN_WRITING_FILE;
            }

            switch(img.getPixelFormat()) {
                case GL_DEPTH_COMPONENT:
                case GL_LUMINANCE:
                case GL_ALPHA:
                    photometric = PHOTOMETRIC_MINISBLACK;
                    samplesPerPixel = 1;
                    break;
                case GL_LUMINANCE_ALPHA:
                    photometric = PHOTOMETRIC_MINISBLACK;
                    samplesPerPixel = 2;
                    break;
                case GL_RGB:
                    photometric = PHOTOMETRIC_RGB;
                    samplesPerPixel = 3;
                    break;
                case GL_RGBA:
                    photometric = PHOTOMETRIC_RGB;
                    samplesPerPixel = 4;
                    break;
                default:
                    return WriteResult::ERROR_IN_WRITING_FILE;
                    break;
            }

            switch(img.getDataType()){
                case GL_FLOAT:
                    TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
                    TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1);
                    bitsPerSample = 32;
                    break;
                case GL_SHORT:
                    TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
                    bitsPerSample = 16;
                    break;
                default:
                    bitsPerSample = 8;
                    break;
            }

            TIFFSetField(image, TIFFTAG_IMAGEWIDTH,img.s());
            TIFFSetField(image, TIFFTAG_IMAGELENGTH,img.t());
            TIFFSetField(image, TIFFTAG_BITSPERSAMPLE,bitsPerSample);
            TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL,samplesPerPixel);
            TIFFSetField(image, TIFFTAG_PHOTOMETRIC, photometric);
            TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
            TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
            TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);

            //uint32 rowsperstrip = TIFFDefaultStripSize(image, -1);
            //TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip);

            // Write the information to the file
            for(int i = 0; i < img.t(); ++i) {
                TIFFWriteScanline(image,(tdata_t)img.data(0,img.t()-i-1),i,0);
            }

            // Close the file
            TIFFClose(image);

            return WriteResult::FILE_SAVED;
        }
Example #9
0
GthImage *
_cairo_image_surface_create_from_tiff (GInputStream  *istream,
				       GthFileData   *file_data,
				       int            requested_size,
				       int           *original_width_p,
				       int           *original_height_p,
				       gboolean      *loaded_original_p,
				       gpointer       user_data,
				       GCancellable  *cancellable,
				       GError       **error)
{
	GthImage		*image;
	Handle			 handle;
	TIFF			*tif;
	gboolean		 first_directory;
	int			 best_directory;
	int        		 max_width, max_height, min_diff;
	uint32			 image_width;
	uint32			 image_height;
	uint32			 spp;
	uint16			 extrasamples;
	uint16			*sampleinfo;
	uint16			 orientation;
	char			 emsg[1024];
	cairo_surface_t		*surface;
	cairo_surface_metadata_t*metadata;
	uint32			*raster;

	image = gth_image_new ();
	handle.cancellable = cancellable;
	handle.size = 0;

	if ((file_data != NULL) && (file_data->info != NULL)) {
		handle.istream = g_buffered_input_stream_new (istream);
		handle.size = g_file_info_get_size (file_data->info);
	}
	else {
		void  *data;
		gsize  size;

		/* read the whole stream to get the file size */

		if (! _g_input_stream_read_all (istream, &data, &size, cancellable, error))
			return image;
		handle.istream = g_memory_input_stream_new_from_data (data, size, g_free);
		handle.size = size;
	}


	TIFFSetErrorHandler (tiff_error_handler);
	TIFFSetWarningHandler (tiff_error_handler);

	tif = TIFFClientOpen ("gth-tiff-reader", "r",
			      &handle,
	                      tiff_read,
	                      tiff_write,
	                      tiff_seek,
	                      tiff_close,
	                      tiff_size,
	                      NULL,
	                      NULL);

	if (tif == NULL) {
		g_object_unref (handle.istream);
		g_set_error_literal (error,
				     GDK_PIXBUF_ERROR,
				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
				     "Couldn't allocate memory for writing TIFF file");
		return image;
	}

	/* find the best image to load */

	first_directory = TRUE;
	best_directory = -1;
	max_width = -1;
	max_height = -1;
	min_diff = 0;
	do {
		int width;
		int height;

		if (TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &width) != 1)
			continue;
		if (TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &height) != 1)
			continue;

		if (! TIFFRGBAImageOK (tif, emsg))
			continue;

		if (width > max_width) {
			max_width = width;
			max_height = height;
			if (requested_size <= 0)
				best_directory = TIFFCurrentDirectory (tif);
		}

		if (requested_size > 0) {
			int diff = abs (requested_size - width);

			if (first_directory) {
				min_diff = diff;
				best_directory = TIFFCurrentDirectory (tif);
			}
			else if (diff < min_diff) {
				min_diff = diff;
				best_directory = TIFFCurrentDirectory (tif);
			}
		}

		first_directory = FALSE;
	}
	while (TIFFReadDirectory (tif));

	if (best_directory == -1) {
		TIFFClose (tif);
		g_object_unref (handle.istream);
		g_set_error_literal (error,
				     G_IO_ERROR,
				     G_IO_ERROR_INVALID_DATA,
				     "Invalid TIFF format");
		return image;
	}

	/* read the image */

	TIFFSetDirectory (tif, best_directory);
	TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &image_width);
	TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &image_height);
	TIFFGetField (tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
	TIFFGetFieldDefaulted (tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
	if (TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation) != 1)
		orientation = ORIENTATION_TOPLEFT;

	if (original_width_p)
		*original_width_p = max_width;
	if (original_height_p)
		*original_height_p = max_height;
	if (loaded_original_p)
		*loaded_original_p = (max_width == image_width);

	surface = _cairo_image_surface_create (CAIRO_FORMAT_ARGB32, image_width, image_height);
	if (surface == NULL) {
		TIFFClose (tif);
		g_object_unref (handle.istream);
		g_set_error_literal (error,
				     GDK_PIXBUF_ERROR,
				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
				     "Couldn't allocate memory for writing TIFF file");
		return image;
	}

	metadata = _cairo_image_surface_get_metadata (surface);
	_cairo_metadata_set_has_alpha (metadata, (extrasamples == 1) || (spp == 4));
	_cairo_metadata_set_original_size (metadata, max_width, max_height);

	raster = (uint32*) _TIFFmalloc (image_width * image_height * sizeof (uint32));
	if (raster == NULL) {
		cairo_surface_destroy (surface);
		TIFFClose (tif);
		g_object_unref (handle.istream);
		g_set_error_literal (error,
				     GDK_PIXBUF_ERROR,
				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
				     "Couldn't allocate memory for writing TIFF file");
		return image;
	}

	if (TIFFReadRGBAImageOriented (tif, image_width, image_height, raster, orientation, 0)) {
		guchar *surface_row;
		int     line_step;
		int     x, y, temp;
		guchar  r, g, b, a;
		uint32 *src_pixel;

		surface_row = _cairo_image_surface_flush_and_get_data (surface);
		line_step = cairo_image_surface_get_stride (surface);
		src_pixel = raster;
		for (y = 0; y < image_height; y++) {
			guchar *dest_pixel = surface_row;

			if (g_cancellable_is_cancelled (cancellable))
				goto stop_loading;

			for (x = 0; x < image_width; x++) {
				r = TIFFGetR (*src_pixel);
				g = TIFFGetG (*src_pixel);
				b = TIFFGetB (*src_pixel);
				a = TIFFGetA (*src_pixel);
				CAIRO_SET_RGBA (dest_pixel, r, g, b, a);

				dest_pixel += 4;
				src_pixel += 1;
			}

			surface_row += line_step;
		}
	}

stop_loading:

	cairo_surface_mark_dirty (surface);
	if (! g_cancellable_is_cancelled (cancellable))
		gth_image_set_cairo_surface (image, surface);

	_TIFFfree (raster);
	cairo_surface_destroy (surface);
	TIFFClose (tif);
	g_object_unref (handle.istream);

	return image;
}
Example #10
0
TIFF*
TIFFClientOpen(
	const char* name, const char* mode,
	thandle_t clientdata,
	TIFFReadWriteProc readproc,
	TIFFReadWriteProc writeproc,
	TIFFSeekProc seekproc,
	TIFFCloseProc closeproc,
	TIFFSizeProc sizeproc,
	TIFFMapFileProc mapproc,
	TIFFUnmapFileProc unmapproc
)
{
	static const char module[] = "TIFFClientOpen";
	TIFF *tif;
	int m, bigendian;
	const char* cp;

	m = _TIFFgetMode(mode, module);
	if (m == -1)
		goto bad2;
	tif = (TIFF *)_TIFFmalloc(sizeof (TIFF) + strlen(name) + 1);
	if (tif == NULL) {
		TIFFError(module, "%s: Out of memory (TIFF structure)", name);
		goto bad2;
	}
	_TIFFmemset(tif, 0, sizeof (*tif));
	tif->tif_name = (char *)tif + sizeof (TIFF);
	strcpy(tif->tif_name, name);
	tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
	tif->tif_curdir = (tdir_t) -1;		/* non-existent directory */
	tif->tif_curoff = 0;
	tif->tif_curstrip = (tstrip_t) -1;	/* invalid strip */
	tif->tif_row = (uint32) -1;		/* read/write pre-increment */
	tif->tif_clientdata = clientdata;
	if (!readproc || !writeproc || !seekproc || !closeproc
			|| !sizeproc || !mapproc || !unmapproc) {
		TIFFError(module, "One of the client procedures are NULL pointer");
		goto bad3;
	}
	tif->tif_readproc = readproc;
	tif->tif_writeproc = writeproc;
	tif->tif_seekproc = seekproc;
	tif->tif_closeproc = closeproc;
	tif->tif_sizeproc = sizeproc;
	tif->tif_mapproc = mapproc;
	tif->tif_unmapproc = unmapproc;
	_TIFFSetDefaultCompressionState(tif);	/* setup default state */
	/*
	 * Default is to return data MSB2LSB and enable the
	 * use of memory-mapped files and strip chopping when
	 * a file is opened read-only.
	 */
	tif->tif_flags = FILLORDER_MSB2LSB;
	if (m == O_RDONLY )
            tif->tif_flags |= TIFF_MAPPED;

#ifdef STRIPCHOP_DEFAULT
	if (m == O_RDONLY || m == O_RDWR)
		tif->tif_flags |= STRIPCHOP_DEFAULT;
#endif

	{ union { int32 i; char c[4]; } u; u.i = 1; bigendian = u.c[0] == 0; }
	/*
	 * Process library-specific flags in the open mode string.
	 * The following flags may be used to control intrinsic library
	 * behaviour that may or may not be desirable (usually for
	 * compatibility with some application that claims to support
	 * TIFF but only supports some braindead idea of what the
	 * vendor thinks TIFF is):
	 *
	 * 'l'		use little-endian byte order for creating a file
	 * 'b'		use big-endian byte order for creating a file
	 * 'L'		read/write information using LSB2MSB bit order
	 * 'B'		read/write information using MSB2LSB bit order
	 * 'H'		read/write information using host bit order
	 * 'M'		enable use of memory-mapped files when supported
	 * 'm'		disable use of memory-mapped files
	 * 'C'		enable strip chopping support when reading
	 * 'c'		disable strip chopping support
	 *
	 * The use of the 'l' and 'b' flags is strongly discouraged.
	 * These flags are provided solely because numerous vendors,
	 * typically on the PC, do not correctly support TIFF; they
	 * only support the Intel little-endian byte order.  This
	 * support is not configured by default because it supports
	 * the violation of the TIFF spec that says that readers *MUST*
	 * support both byte orders.  It is strongly recommended that
	 * you not use this feature except to deal with busted apps
	 * that write invalid TIFF.  And even in those cases you should
	 * bang on the vendors to fix their software.
	 *
	 * The 'L', 'B', and 'H' flags are intended for applications
	 * that can optimize operations on data by using a particular
	 * bit order.  By default the library returns data in MSB2LSB
	 * bit order for compatibility with older versions of this
	 * library.  Returning data in the bit order of the native cpu
	 * makes the most sense but also requires applications to check
	 * the value of the FillOrder tag; something they probabyl do
	 * not do right now.
	 *
	 * The 'M' and 'm' flags are provided because some virtual memory
	 * systems exhibit poor behaviour when large images are mapped.
	 * These options permit clients to control the use of memory-mapped
	 * files on a per-file basis.
	 *
	 * The 'C' and 'c' flags are provided because the library support
	 * for chopping up large strips into multiple smaller strips is not
	 * application-transparent and as such can cause problems.  The 'c'
	 * option permits applications that only want to look at the tags,
	 * for example, to get the unadulterated TIFF tag information.
	 */
	for (cp = mode; *cp; cp++)
		switch (*cp) {
		case 'b':
			if ((m&O_CREAT) && !bigendian)
				tif->tif_flags |= TIFF_SWAB;
			break;
		case 'l':
			if ((m&O_CREAT) && bigendian)
				tif->tif_flags |= TIFF_SWAB;
			break;
		case 'B':
			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
			    FILLORDER_MSB2LSB;
			break;
		case 'L':
			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
			    FILLORDER_LSB2MSB;
			break;
		case 'H':
			tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
			    HOST_FILLORDER;
			break;
		case 'M':
			if (m == O_RDONLY)
				tif->tif_flags |= TIFF_MAPPED;
			break;
		case 'm':
			if (m == O_RDONLY)
				tif->tif_flags &= ~TIFF_MAPPED;
			break;
		case 'C':
			if (m == O_RDONLY)
				tif->tif_flags |= TIFF_STRIPCHOP;
			break;
		case 'c':
			if (m == O_RDONLY)
				tif->tif_flags &= ~TIFF_STRIPCHOP;
			break;
		}
	/*
	 * Read in TIFF header.
	 */
	if (!ReadOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
		if (tif->tif_mode == O_RDONLY) {
			TIFFError(name, "Cannot read TIFF header");
			goto bad;
		}
		/*
		 * Setup header and write.
		 */
		tif->tif_header.tiff_magic = tif->tif_flags & TIFF_SWAB
		    ? (bigendian ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN)
		    : (bigendian ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN);
		tif->tif_header.tiff_version = TIFF_VERSION;
		if (tif->tif_flags & TIFF_SWAB)
			TIFFSwabShort(&tif->tif_header.tiff_version);
		tif->tif_header.tiff_diroff = 0;	/* filled in later */

                /*
                 * This seek shouldn't be necessary, but I have had some
                 * crazy problems with a failed fseek() on Solaris leaving
                 * the current file pointer out of whack when an fwrite()
                 * is done. 
                 */
                TIFFSeekFile( tif, 0, SEEK_SET );

		if (!WriteOK(tif, &tif->tif_header, sizeof (TIFFHeader))) {
			TIFFError(name, "Error writing TIFF header");
			goto bad;
		}
		/*
		 * Setup the byte order handling.
		 */
		TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
		/*
		 * Setup default directory.
		 */
		if (!TIFFDefaultDirectory(tif))
			goto bad;
		tif->tif_diroff = 0;
		tif->tif_dirlist = NULL;
		tif->tif_dirnumber = 0;
		return (tif);
	}
	/*
	 * Setup the byte order handling.
	 */
	if (tif->tif_header.tiff_magic != TIFF_BIGENDIAN &&
	    tif->tif_header.tiff_magic != TIFF_LITTLEENDIAN) {
		TIFFError(name,  "Not a TIFF file, bad magic number %d (0x%x)",
		    tif->tif_header.tiff_magic,
		    tif->tif_header.tiff_magic);
		goto bad;
	}
	TIFFInitOrder(tif, tif->tif_header.tiff_magic, bigendian);
	/*
	 * Swap header if required.
	 */
	if (tif->tif_flags & TIFF_SWAB) {
		TIFFSwabShort(&tif->tif_header.tiff_version);
		TIFFSwabLong(&tif->tif_header.tiff_diroff);
	}
	/*
	 * Now check version (if needed, it's been byte-swapped).
	 * Note that this isn't actually a version number, it's a
	 * magic number that doesn't change (stupid).
	 */
	if (tif->tif_header.tiff_version != TIFF_VERSION) {
		TIFFError(name,
		    "Not a TIFF file, bad version number %d (0x%x)",
		    tif->tif_header.tiff_version,
		    tif->tif_header.tiff_version); 
		goto bad;
	}
	tif->tif_flags |= TIFF_MYBUFFER;
	tif->tif_rawcp = tif->tif_rawdata = 0;
	tif->tif_rawdatasize = 0;
	/*
	 * Setup initial directory.
	 */
	switch (mode[0]) {
	case 'r':
		tif->tif_nextdiroff = tif->tif_header.tiff_diroff;
		/*
		 * Try to use a memory-mapped file if the client
		 * has not explicitly suppressed usage with the
		 * 'm' flag in the open mode (see above).
		 */
		if ((tif->tif_flags & TIFF_MAPPED) &&
	!TIFFMapFileContents(tif, (tdata_t*) &tif->tif_base, &tif->tif_size))
			tif->tif_flags &= ~TIFF_MAPPED;
		if (TIFFReadDirectory(tif)) {
			tif->tif_rawcc = -1;
			tif->tif_flags |= TIFF_BUFFERSETUP;
			return (tif);
		}
		break;
	case 'a':
		/*
		 * New directories are automatically append
		 * to the end of the directory chain when they
		 * are written out (see TIFFWriteDirectory).
		 */
		if (!TIFFDefaultDirectory(tif))
			goto bad;
		return (tif);
	}
bad:
	tif->tif_mode = O_RDONLY;	/* XXX avoid flush */
	TIFFClose(tif);
	return ((TIFF*)0);
bad2:
	(void) (*closeproc)(clientdata);
bad3:
	return ((TIFF*)0);
}
Example #11
0
unsigned char *
simage_tiff_load(std::istream& fin,
                 int& width_ret,
                 int& height_ret,
                 int& numComponents_ret,
                 uint16& bitspersample)
{
    TIFF *in;
    uint16 dataType;
    uint16 samplesperpixel;
    uint16 photometric;
    uint32 w, h;
    uint16 config;
    uint16* red;
    uint16* green;
    uint16* blue;
    unsigned char *inbuf = NULL;
    tsize_t rowsize;
    uint32 row;
    int format;
    unsigned char *buffer;
    int width;
    int height;
    unsigned char *currPtr;

    TIFFSetErrorHandler(tiff_error);
    TIFFSetWarningHandler(tiff_warn);

    in = TIFFClientOpen("inputstream", "r", (thandle_t)&fin,
            libtiffStreamReadProc, //Custom read function
            libtiffStreamWriteProc, //Custom write function
            libtiffStreamSeekProc, //Custom seek function
            libtiffStreamCloseProc, //Custom close function
            libtiffStreamSizeProc, //Custom size function
            libtiffStreamMapProc, //Custom map function
            libtiffStreamUnmapProc); //Custom unmap function

    if (in == NULL)
    {
        tifferror = ERR_OPEN;
        return NULL;
    }
    if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) == 1)
    {
        if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE &&
            photometric != PHOTOMETRIC_MINISWHITE &&
            photometric != PHOTOMETRIC_MINISBLACK)
        {
            OSG_NOTICE << "Photometric type "<<photometric<<" not handled; can only handle Grayscale, RGB and Palette images" << std::endl;
            TIFFClose(in);
            tifferror = ERR_UNSUPPORTED;
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel) == 1)
    {
        if (samplesperpixel != 1 &&
            samplesperpixel != 2 &&
            samplesperpixel != 3 &&
            samplesperpixel != 4)
        {
            OSG_DEBUG << "Bad samples/pixel" << std::endl;
            tifferror = ERR_UNSUPPORTED;
            TIFFClose(in);
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 1)
    {
         if (bitspersample != 8 && bitspersample != 16 && bitspersample != 32)
        {
            OSG_NOTICE << "can only handle 8, 16 and 32 bit samples" << std::endl;
            TIFFClose(in);
            tifferror = ERR_UNSUPPORTED;
            return NULL;
        }
    }
    else
    {
        tifferror = ERR_READ;
        TIFFClose(in);
        return NULL;
    }

    if (TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w) != 1 ||
        TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h) != 1 ||
        TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config) != 1)
    {
        TIFFClose(in);
        tifferror = ERR_READ;
        return NULL;
    }


    TIFFGetField(in, TIFFTAG_DATATYPE, &dataType);
    OSG_INFO<<"TIFFTAG_DATATYPE="<<dataType<<std::endl;


    /*
    if (photometric == PHOTOMETRIC_MINISWHITE ||
        photometric == PHOTOMETRIC_MINISBLACK)
        format = 1;
    else
        format = 3;
    */
    // if it has a palette, data returned is 3 byte rgb
    // so set format to 3.
    if (photometric == PHOTOMETRIC_PALETTE)
        format = 3;
    else
        format = samplesperpixel * bitspersample / 8;


    int bytespersample = bitspersample / 8;
    int bytesperpixel = bytespersample * samplesperpixel;

    OSG_INFO<<"format="<<format<<std::endl;
    OSG_INFO<<"bytespersample="<<bytespersample<<std::endl;
    OSG_INFO<<"bytesperpixel="<<bytesperpixel<<std::endl;

    buffer = new unsigned char [w*h*format];

    if (!buffer)
    {
        tifferror = ERR_MEM;
        TIFFClose(in);
        return NULL;
    }

    // initialize memory
    for(unsigned char* ptr=buffer;ptr<buffer+w*h*format;++ptr) *ptr = 0;

    width = w;
    height = h;

    currPtr = buffer + (h-1)*w*format;

    tifferror = ERR_NO_ERROR;

    switch (pack(photometric, config))
    {
        case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_SEPARATE):
        case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_SEPARATE):
            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                invert_row(currPtr, inbuf, samplesperpixel*w, photometric == PHOTOMETRIC_MINISWHITE, bitspersample);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
        case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
            if (TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue) != 1)
                tifferror = ERR_READ;
            /* */
            /* Convert 16-bit colormap to 8-bit (unless it looks */
            /* like an old-style 8-bit colormap). */
            /* */
            if (!tifferror && checkcmap(1<<bitspersample, red, green, blue) == 16)
            {
                int i;
                for (i = (1<<bitspersample)-1; i >= 0; i--)
                {
                    red[i] = CVT(red[i]);
                    green[i] = CVT(green[i]);
                    blue[i] = CVT(blue[i]);
                }
            }

            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                remap_row(currPtr, inbuf, w, red, green, blue);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
            inbuf = new unsigned char [TIFFScanlineSize(in)];
            for (row = 0; row < h; row++)
            {
                if (TIFFReadScanline(in, inbuf, row, 0) < 0)
                {
                    tifferror = ERR_READ;
                    break;
                }
                memcpy(currPtr, inbuf, format*w);
                currPtr -= format*w;
            }
            break;

        case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
            rowsize = TIFFScanlineSize(in);
            inbuf = new unsigned char [format*rowsize];
            for (row = 0; !tifferror && row < h; row++)
            {
                int s;
                for (s = 0; s < format; s++)
                {
                    if (TIFFReadScanline(in, (tdata_t)(inbuf+s*rowsize), (uint32)row, (tsample_t)s) < 0)
                    {
                        tifferror = ERR_READ; break;
                    }
                }
                if (!tifferror)
                {
                    if (format==3) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, w, format, bitspersample);
                    else if (format==4) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, inbuf+3*rowsize, w, format, bitspersample);
                    currPtr -= format*w;
                }
            }
            break;
        default:
            tifferror = ERR_UNSUPPORTED;
            break;
    }

    if (inbuf) delete [] inbuf;
    TIFFClose(in);

    if (tifferror)
    {
        if (buffer) delete [] buffer;
        return NULL;
    }
    width_ret = width;
    height_ret = height;
    if (photometric == PHOTOMETRIC_PALETTE)
        numComponents_ret = format;
    else
        numComponents_ret = samplesperpixel;

    return buffer;
}
int
main(int argc, char* argv[])
{
	TIFF *in, *out;
	uint16 samplesperpixel, bitspersample = 1, shortv;
	float floatv;
	char thing[1024];
	uint32 rowsperstrip = (uint32) -1;
	int onestrip = 0;
	uint16 fillorder = 0;
	int c;
	extern int optind;
	extern char *optarg;

	while ((c = getopt(argc, argv, "c:f:r:t:")) != -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 'r':		/* rows/strip */
			rowsperstrip = atoi(optarg);
			onestrip = 0;
			break;
		case 't':
			threshold = atoi(optarg);
			if (threshold < 0)
				threshold = 0;
			else if (threshold > 255)
				threshold = 255;
			break;
		case '?':
			usage();
			/*NOTREACHED*/
		}
	if (argc - optind < 2)
		usage();
	in = TIFFOpen(argv[optind], "r");
	if (in == NULL)
		return (-1);
	TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
	if (samplesperpixel != 1) {
		fprintf(stderr, "%s: Not a b&w image.\n", argv[0]);
		return (-1);
	}
	TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
	if (bitspersample != 8) {
		fprintf(stderr,
		    " %s: Sorry, only handle 8-bit samples.\n", argv[0]);
		return (-1);
	}
	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-1);
	CopyField(TIFFTAG_IMAGEWIDTH, imagewidth);
	TIFFGetField(in, TIFFTAG_IMAGELENGTH, &imagelength);
	TIFFSetField(out, TIFFTAG_IMAGELENGTH, imagelength-1);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
	if (fillorder)
		TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
	else
		CopyField(TIFFTAG_FILLORDER, shortv);
	sprintf(thing, "Dithered B&W version of %s", argv[optind]);
	TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
	CopyField(TIFFTAG_PHOTOMETRIC, shortv);
	CopyField(TIFFTAG_ORIENTATION, shortv);
	CopyField(TIFFTAG_XRESOLUTION, floatv);
	CopyField(TIFFTAG_YRESOLUTION, floatv);
	CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
	if (onestrip)
		rowsperstrip = imagelength-1;
	else
		rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip);
	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
	switch (compression) {
	case COMPRESSION_CCITTFAX3:
		TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options);
		break;
	case COMPRESSION_LZW:
	case COMPRESSION_DEFLATE:
		if (predictor)
			TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
		break;
	}
	fsdither(in, out);
	TIFFClose(in);
	TIFFClose(out);
	return (0);
}
Example #13
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);
}
Example #14
0
bimage *bimageOpenTIFF(const char *filename) {
  if (!tiffInitialized) {
    tiffInit();
  }

  bimage *im = NULL;
  TIFF *tif = TIFFOpen(filename, "r");
  if (!tif) {
    return NULL;
  }

  uint32_t w, h;
  uint16_t depth, channels, fmt;

  TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &depth);
  TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &channels);
  TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &fmt);

  if (fmt == SAMPLEFORMAT_IEEEFP) {
    depth =
        depth == 32 ? BIMAGE_F32 : depth == 64 ? BIMAGE_F64 : BIMAGE_UNKNOWN;
  } else if (fmt == SAMPLEFORMAT_COMPLEXIEEEFP) {
    depth = depth == 32 ? BIMAGE_C32 : BIMAGE_UNKNOWN;
  } else if (fmt == SAMPLEFORMAT_UINT) {
    depth = depth == 8
                ? BIMAGE_U8
                : depth == 16 ? BIMAGE_U16
                              : depth == 32 ? BIMAGE_U32 : BIMAGE_UNKNOWN;
  } else {
    goto error0;
  }

  im = bimageCreate(w, h, depth | channels);
  if (!im) {
    goto error0;
  }

  tstrip_t strip;
  tdata_t *buf = bAlloc(TIFFStripSize(tif));
  if (!buf) {
    goto error0;
  }

  for (strip = 0; strip < TIFFNumberOfStrips(tif); strip++) {
    tsize_t n = TIFFReadEncodedStrip(tif, strip, buf, -1);
    if (n <= 0) {
      goto error1;
    }

    memcpy(im->data + TIFFStripSize(tif) * strip, buf, n);
  }

  bFree(buf);
  TIFFClose(tif);
  return im;

error1:
  bFree(buf);
error0:
  if (im)
    bimageRelease(im);
  TIFFClose(tif);
  return NULL;
}
Example #15
0
int ReadTIFF(const char* const filename,
             WebPPicture* const pic, int keep_alpha,
             Metadata* const metadata) {
  TIFF* const tif = TIFFOpen(filename, "r");
  uint32 width, height;
  uint32* raster;
  int ok = 0;
  tdir_t dircount;

  if (tif == NULL) {
    fprintf(stderr, "Error! Cannot open TIFF file '%s'\n", filename);
    return 0;
  }

  dircount = TIFFNumberOfDirectories(tif);
  if (dircount > 1) {
    fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n"
                    "Only the first will be used, %d will be ignored.\n",
                    dircount - 1);
  }

  if (!(TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) &&
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height))) {
    fprintf(stderr, "Error! Cannot retrieve TIFF image dimensions.\n");
    return 0;
  }
  raster = (uint32*)_TIFFmalloc(width * height * sizeof(*raster));
  if (raster != NULL) {
    if (TIFFReadRGBAImageOriented(tif, width, height, raster,
                                  ORIENTATION_TOPLEFT, 1)) {
      const int stride = width * sizeof(*raster);
      pic->width = width;
      pic->height = height;
      // TIFF data is ABGR
#ifdef __BIG_ENDIAN__
      TIFFSwabArrayOfLong(raster, width * height);
#endif
      pic->use_argb = 1;
      ok = keep_alpha
         ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
         : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
    }
    _TIFFfree(raster);
  } else {
    fprintf(stderr, "Error allocating TIFF RGBA memory!\n");
  }

  if (ok) {
    if (metadata != NULL) {
      ok = ExtractMetadataFromTIFF(tif, metadata);
      if (!ok) {
        fprintf(stderr, "Error extracting TIFF metadata!\n");
        MetadataFree(metadata);
        WebPPictureFree(pic);
      }
    }
  }

  TIFFClose(tif);
  return ok;
}
Example #16
0
static x3f_return_t write_camera_profiles(x3f_t *x3f, char *wb,
					  const camera_profile_t *profiles,
					  int num,
					  TIFF *tiff)
{
  FILE *tiff_file;
  uint32_t *profile_offsets;
  int i;

  assert(num >= 1);
  if (!write_camera_profile(x3f, wb, &profiles[0], tiff))
    return X3F_ARGUMENT_ERROR;
  TIFFSetField(tiff, TIFFTAG_ASSHOTPROFILENAME, profiles[0].name);
  if (num == 1) return X3F_OK;

  profile_offsets = alloca((num-1)*sizeof(uint32_t));

  tiff_file = fdopen(dup(TIFFFileno(tiff)), "w+b");
  if (!tiff_file) return X3F_OUTFILE_ERROR;

  for (i=1; i < num; i++) {
    FILE *tmp;
    TIFF *tmp_tiff;
#define BUFSIZE 1024
    char buf[BUFSIZE];
    int offset, count;

    if (!(tmp = tmpfile())) {
      fclose(tiff_file);
      return X3F_OUTFILE_ERROR;
    }
    if (!(tmp_tiff = TIFFFdOpen(dup(fileno(tmp)), "", "wb"))) { /* Big endian */
      fclose(tmp);
      fclose(tiff_file);
      return X3F_OUTFILE_ERROR;
    }
    if (!write_camera_profile(x3f, wb, &profiles[i], tmp_tiff)) {
      fclose(tmp);
      TIFFClose(tmp_tiff);
      fclose(tiff_file);
      return X3F_ARGUMENT_ERROR;
    }
    TIFFWriteDirectory(tmp_tiff);
    TIFFClose(tmp_tiff);

    fseek(tiff_file, 0, SEEK_END);
    offset = (ftell(tiff_file)+1) & ~1; /* 2-byte alignment */
    fseek(tiff_file, offset, SEEK_SET);
    profile_offsets[i-1] = offset;

    fputs("MMCR", tiff_file);	/* DNG camera profile magic in big endian */
    fseek(tmp, 4, SEEK_SET);	/* Skip over the standard TIFF magic */

    while((count = fread(buf, 1, BUFSIZE, tmp)))
      fwrite(buf, 1, count, tiff_file);

    fclose(tmp);
  }

  fclose(tiff_file);
  TIFFSetField(tiff, TIFFTAG_EXTRACAMERAPROFILES, num-1, profile_offsets);
  return X3F_OK;
}
Example #17
0
/*  tiffWriter
 *  ----------
 *  Write the gd image as a tiff file (called by gdImageTiffCtx)
 *  Parameters are:
 *  image:    gd image structure;
 *  out:      the stream where to write
 *  bitDepth: depth in bits of each pixel
 */
void tiffWriter(gdImagePtr image, gdIOCtx *out, int bitDepth)
{
	int x, y;
	int i;
	int r, g, b, a;
	TIFF *tiff;
	int width, height;
	int color;
	char *scan;
	int samplesPerPixel = 3;
	int bitsPerSample;
	int transparentColorR = -1;
	int transparentColorG = -1;
	int transparentColorB = -1;
	uint16 extraSamples[1];
	uint16 *colorMapRed = NULL;
	uint16 *colorMapGreen = NULL;
	uint16 *colorMapBlue = NULL;

	tiff_handle *th;

	th = new_tiff_handle(out);
	if (!th) {
		return;
	}
	extraSamples[0] = EXTRASAMPLE_ASSOCALPHA;

	/* read in the width/height of gd image */
	width = gdImageSX(image);
	height = gdImageSY(image);

	/* reset clip region to whole image */
	gdImageSetClip(image, 0, 0, width, height);

	/* handle old-style single-colour mapping to 100% transparency */
	if(image->transparent != -1) {
		/* set our 100% transparent colour value */
		transparentColorR = gdImageRed(image, image->transparent);
		transparentColorG = gdImageGreen(image, image->transparent);
		transparentColorB = gdImageBlue(image, image->transparent);
	}

	/* Open tiff file writing routines, but use special read/write/seek
	 * functions so that tiff lib writes correct bits of tiff content to
	 * correct areas of file opened and modifieable by the gdIOCtx functions
	 */
	tiff = TIFFClientOpen("", "w", th,	tiff_readproc,
			      tiff_writeproc,
			      tiff_seekproc,
			      tiff_closeproc,
			      tiff_sizeproc,
			      tiff_mapproc,
			      tiff_unmapproc);

	TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
	TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
	TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
	TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC,
		     (bitDepth == 24) ? PHOTOMETRIC_RGB : PHOTOMETRIC_PALETTE);

	bitsPerSample = (bitDepth == 24 || bitDepth == 8) ? 8 : 1;
	TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bitsPerSample);

	/* build the color map for 8 bit images */
	if(bitDepth != 24) {
		colorMapRed   = (uint16 *) gdMalloc(3 * (1 << bitsPerSample));
		if (!colorMapRed) {
			gdFree(th);
			return;
		}
		colorMapGreen = (uint16 *) gdMalloc(3 * (1 << bitsPerSample));
		if (!colorMapGreen) {
			gdFree(colorMapRed);
			gdFree(th);
			return;
		}
		colorMapBlue  = (uint16 *) gdMalloc(3 *  (1 << bitsPerSample));
		if (!colorMapBlue) {
			gdFree(colorMapRed);
			gdFree(colorMapGreen);
			gdFree(th);
			return;
		}

		for(i = 0; i < image->colorsTotal; i++) {
			colorMapRed[i]   = gdImageRed(image,i) + (gdImageRed(image,i) * 256);
			colorMapGreen[i] = gdImageGreen(image,i)+(gdImageGreen(image,i)*256);
			colorMapBlue[i]  = gdImageBlue(image,i) + (gdImageBlue(image,i)*256);
		}

		TIFFSetField(tiff, TIFFTAG_COLORMAP, colorMapRed, colorMapGreen,
			     colorMapBlue);
		samplesPerPixel = 1;
	}

	/* here, we check if the 'save alpha' flag is set on the source gd image */
	if ((bitDepth == 24) &&
	    (image->saveAlphaFlag || image->transparent != -1)) {
		/* so, we need to store the alpha values too!
		 * Also, tell TIFF what the extra sample means (associated alpha) */
		samplesPerPixel = 4;
		TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
		TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, extraSamples);
	} else {
		TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
	}

	TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);

	if(overflow2(width, samplesPerPixel)) {
		if (colorMapRed)   gdFree(colorMapRed);
		if (colorMapGreen) gdFree(colorMapGreen);
		if (colorMapBlue)  gdFree(colorMapBlue);
		gdFree(th);
		return;
	}

	if(!(scan = (char *)gdMalloc(width * samplesPerPixel))) {
		if (colorMapRed)   gdFree(colorMapRed);
		if (colorMapGreen) gdFree(colorMapGreen);
		if (colorMapBlue)  gdFree(colorMapBlue);
		gdFree(th);
		return;
	}

	/* loop through y-coords, and x-coords */
	for(y = 0; y < height; y++) {
		for(x = 0; x < width; x++) {
			/* generate scan line for writing to tiff */
			color = gdImageGetPixel(image, x, y);

			a = (127 - gdImageAlpha(image, color)) * 2;
			a = (a == 0xfe) ? 0xff : a & 0xff;
			b = gdImageBlue(image, color);
			g = gdImageGreen(image, color);
			r = gdImageRed(image, color);

			/* if this pixel has the same RGB as the transparent colour,
			 * then set alpha fully transparent */
			if (transparentColorR == r &&
			    transparentColorG == g &&
			    transparentColorB == b) {
				a = 0x00;
			}

			if(bitDepth != 24) {
				/* write out 1 or 8 bit value in 1 byte
				 * (currently treats 1bit as 8bit) */
				scan[(x * samplesPerPixel) + 0] = color;
			} else {
				/* write out 24 bit value in 3 (or 4 if transparent) bytes */
				if(image->saveAlphaFlag || image->transparent != -1) {
					scan[(x * samplesPerPixel) + 3] = a;
				}

				scan[(x * samplesPerPixel) + 2] = b;
				scan[(x * samplesPerPixel) + 1] = g;
				scan[(x * samplesPerPixel) + 0] = r;
			}
		}

		/* Write the scan line to the tiff */
		if(TIFFWriteEncodedStrip(tiff, y, scan, width * samplesPerPixel) == -1) {
			if (colorMapRed)   gdFree(colorMapRed);
			if (colorMapGreen) gdFree(colorMapGreen);
			if (colorMapBlue)  gdFree(colorMapBlue);
			gdFree(th);
			/* error handler here */
			gd_error("Could not create TIFF\n");
			return;
		}
	}

	/* now cloase and free up resources */
	TIFFClose(tiff);
	gdFree(scan);
	gdFree(th);

	if(bitDepth != 24) {
		gdFree(colorMapRed);
		gdFree(colorMapGreen);
		gdFree(colorMapBlue);
	}
}
Example #18
0
/* extern */
x3f_return_t x3f_dump_raw_data_as_dng(x3f_t *x3f,
				      char *outfilename,
				      int denoise,
				      char *wb,
				      int compress)
{
  x3f_return_t ret;
  int fd = open(outfilename, O_RDWR | BINMODE | O_CREAT | O_TRUNC, 0444);
  TIFF *f_out;
  uint64_t sub_ifds[1] = {0};
#define THUMBSIZE 100
  uint8_t thumbnail[3*THUMBSIZE];

  double sensor_iso, capture_iso;
  double gain[3], gain_inv[3], gain_inv_mat[9];
  float as_shot_neutral[3], camera_calibration1[9];
  float black_level[3];
  uint32_t active_area[4];
  x3f_area16_t image;
  x3f_image_levels_t ilevels;
  int row;

  if (fd == -1) return X3F_OUTFILE_ERROR;
  if (!(f_out = TIFFFdOpen(fd, outfilename, "w"))) {
    close(fd);
    return X3F_OUTFILE_ERROR;
  }

  if (wb == NULL) wb = x3f_get_wb(x3f);
  if (!x3f_get_image(x3f, &image, &ilevels, NONE, 0, denoise, wb) ||
      image.channels != 3) {
    TIFFClose(f_out);
    return X3F_ARGUMENT_ERROR;
  }

  TIFFSetField(f_out, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
  TIFFSetField(f_out, TIFFTAG_IMAGEWIDTH, THUMBSIZE);
  TIFFSetField(f_out, TIFFTAG_IMAGELENGTH, THUMBSIZE);
  TIFFSetField(f_out, TIFFTAG_ROWSPERSTRIP, THUMBSIZE);
  TIFFSetField(f_out, TIFFTAG_SAMPLESPERPIXEL, 3);
  TIFFSetField(f_out, TIFFTAG_BITSPERSAMPLE, 8);
  TIFFSetField(f_out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  TIFFSetField(f_out, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
  TIFFSetField(f_out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  TIFFSetField(f_out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  TIFFSetField(f_out, TIFFTAG_DNGVERSION, "\001\004\000\000");
  TIFFSetField(f_out, TIFFTAG_DNGBACKWARDVERSION,
	       compress ? "\001\004\000\000" : "\001\003\000\000");
  TIFFSetField(f_out, TIFFTAG_SUBIFD, 1, sub_ifds);

  if (x3f_get_camf_float(x3f, "SensorISO", &sensor_iso) &&
      x3f_get_camf_float(x3f, "CaptureISO", &capture_iso)) {
    double baseline_exposure = log2(capture_iso/sensor_iso);
    TIFFSetField(f_out, TIFFTAG_BASELINEEXPOSURE, baseline_exposure);
  }

  ret = write_camera_profiles(x3f, wb, camera_profiles,
			      sizeof(camera_profiles)/sizeof(camera_profile_t),
			      f_out);
  if (ret != X3F_OK) {
    x3f_printf(ERR, "Could not write camera profiles\n");
    TIFFClose(f_out);
    free(image.buf);
    return ret;
  }

  if (!x3f_get_gain(x3f, wb, gain)) {
    x3f_printf(ERR, "Could not get gain for white balance: %s\n", wb);
    TIFFClose(f_out);
    free(image.buf);
    return X3F_ARGUMENT_ERROR;
  }
  x3f_3x1_invert(gain, gain_inv);
  vec_double_to_float(gain_inv, as_shot_neutral, 3);
  TIFFSetField(f_out, TIFFTAG_ASSHOTNEUTRAL, 3, as_shot_neutral);

#define WB_D65 "Overcast"
  if (!x3f_get_gain(x3f, WB_D65, gain)) {
    x3f_printf(ERR, "Could not get gain for white balance: %s\n", WB_D65);
    TIFFClose(f_out);
    free(image.buf);
    return X3F_ARGUMENT_ERROR;
  }
  x3f_3x1_invert(gain, gain_inv);
  x3f_3x3_diag(gain_inv, gain_inv_mat);
  vec_double_to_float(gain_inv_mat, camera_calibration1, 9);
  TIFFSetField(f_out, TIFFTAG_CAMERACALIBRATION1, 9, camera_calibration1);

  memset(thumbnail, 0, 3*THUMBSIZE); /* TODO: Thumbnail is all black */
  for (row=0; row < THUMBSIZE; row++)
    TIFFWriteScanline(f_out, thumbnail, row, 0);

  TIFFWriteDirectory(f_out);

  TIFFSetField(f_out, TIFFTAG_SUBFILETYPE, 0);
  TIFFSetField(f_out, TIFFTAG_IMAGEWIDTH, image.columns);
  TIFFSetField(f_out, TIFFTAG_IMAGELENGTH, image.rows);
  TIFFSetField(f_out, TIFFTAG_ROWSPERSTRIP, 32);
  TIFFSetField(f_out, TIFFTAG_SAMPLESPERPIXEL, 3);
  TIFFSetField(f_out, TIFFTAG_BITSPERSAMPLE, 16);
  TIFFSetField(f_out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  TIFFSetField(f_out, TIFFTAG_COMPRESSION,
	       compress ? COMPRESSION_ADOBE_DEFLATE : COMPRESSION_NONE);
  TIFFSetField(f_out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_LINEARRAW);
  /* Prevent further chroma denoising in DNG processing software */
  TIFFSetField(f_out, TIFFTAG_CHROMABLURRADIUS, 0.0);

  vec_double_to_float(ilevels.black, black_level, 3);
  TIFFSetField(f_out, TIFFTAG_BLACKLEVEL, 3, black_level);
  TIFFSetField(f_out, TIFFTAG_WHITELEVEL, 3, ilevels.white);

  if (!write_spatial_gain(x3f, &image, wb, f_out))
    x3f_printf(WARN, "WARNING: could not get spatial gain\n");

  if (get_camf_rect_as_dngrect(x3f, "ActiveImageArea", &image, 1, active_area))
    TIFFSetField(f_out, TIFFTAG_ACTIVEAREA, active_area);

  for (row=0; row < image.rows; row++)
    TIFFWriteScanline(f_out, image.data + image.row_stride*row, row, 0);

  TIFFWriteDirectory(f_out);
  TIFFClose(f_out);
  free(image.buf);

  return X3F_OK;
}
int main(int argc, char **argv)
{
    int             bits_per_pixel = 8, cmsize, i, j, k,
                    cmap_index, chunk_size = 32, nchunks = 16;
    unsigned char * scan_line;
    uint16          *red, *green, *blue;
    TIFF *          tif;

    programName = argv[0];

    if (argc != 4)
        Usage();

    if (!strcmp(argv[1], "-depth"))
         bits_per_pixel = atoi(argv[2]);
    else
         Usage();

    switch (bits_per_pixel) {
        case 8:
            nchunks = 16;
            chunk_size = 32;
            break;
        case 4:
            nchunks = 4;
            chunk_size = 128;
            break;
        case 2:
            nchunks = 2;
            chunk_size = 256;
            break;
	case 1:
	    nchunks = 2;
	    chunk_size = 256;
	    break;
        default:
            Usage();
    }

    if (bits_per_pixel != 1) {
	cmsize = nchunks * nchunks;
    } else {
	cmsize = 2;
    }
    red = (uint16 *) malloc(cmsize * sizeof(uint16));
    green = (uint16 *) malloc(cmsize * sizeof(uint16));
    blue = (uint16 *) malloc(cmsize * sizeof(uint16));

    switch (bits_per_pixel) {
    case 8:
        for (i = 0; i < cmsize; i++) {
            if (i < 32)
                red[i] = 0;
            else if (i < 64)
                red[i] = SCALE(36);
            else if (i < 96)
                red[i] = SCALE(73);
            else if (i < 128)
                red[i] = SCALE(109);
            else if (i < 160)
                red[i] = SCALE(146);
            else if (i < 192)
                red[i] = SCALE(182);
            else if (i < 224)
                red[i] = SCALE(219);
            else if (i < 256)
                red[i] = SCALE(255);

            if ((i % 32) < 4)
                green[i] = 0;
            else if (i < 8)
                green[i] = SCALE(36);
            else if ((i % 32) < 12)
                green[i] = SCALE(73);
            else if ((i % 32) < 16)
                green[i] = SCALE(109);
            else if ((i % 32) < 20)
                green[i] = SCALE(146);
            else if ((i % 32) < 24)
                green[i] = SCALE(182);
            else if ((i % 32) < 28)
                green[i] = SCALE(219);
            else if ((i % 32) < 32)
                green[i] = SCALE(255);

            if ((i % 4) == 0)
                blue[i] = SCALE(0);
            else if ((i % 4) == 1)
                blue[i] = SCALE(85);
            else if ((i % 4) == 2)
                blue[i] = SCALE(170);
            else if ((i % 4) == 3)
                blue[i] = SCALE(255);
        }
        break;
    case 4:
        red[0] = SCALE(255);
        green[0] = 0;
        blue[0] = 0;

        red[1] = 0;
        green[1] = SCALE(255);
        blue[1] = 0;

        red[2] = 0;
        green[2] = 0;
        blue[2] = SCALE(255);

        red[3] = SCALE(255);
        green[3] = SCALE(255);
        blue[3] = SCALE(255);

        red[4] = 0;
        green[4] = SCALE(255);
        blue[4] = SCALE(255);

        red[5] = SCALE(255);
        green[5] = 0;
        blue[5] = SCALE(255);

        red[6] = SCALE(255);
        green[6] = SCALE(255);
        blue[6] = 0;

        red[7] = 0;
        green[7] = 0;
        blue[7] = 0;

        red[8] = SCALE(176);
        green[8] = SCALE(224);
        blue[8] = SCALE(230);
        red[9] = SCALE(100);
        green[9] = SCALE(149);
        blue[9] = SCALE(237);
        red[10] = SCALE(46);
        green[10] = SCALE(139);
        blue[10] = SCALE(87);
        red[11] = SCALE(160);
        green[11] = SCALE(82);
        blue[11] = SCALE(45);
        red[12] = SCALE(238);
        green[12] = SCALE(130);
        blue[12] = SCALE(238);
        red[13] = SCALE(176);
        green[13] = SCALE(48);
        blue[13] = SCALE(96);
        red[14] = SCALE(50);
        green[14] = SCALE(205);
        blue[14] = SCALE(50);
        red[15] = SCALE(240);
        green[15] = SCALE(152);
        blue[15] = SCALE(35);
        break;
    case 2:
        red[0] = SCALE(255);
        green[0] = 0;
        blue[0] = 0;

        red[1] = 0;
        green[1] = SCALE(255);
        blue[1] = 0;

        red[2] = 0;
        green[2] = 0;
        blue[2] = SCALE(255);
        red[3] = SCALE(255);
        green[3] = SCALE(255);
        blue[3] = SCALE(255);
        break;
    case 1:
        red[0] = 0;
        green[0] = 0;
        blue[0] = 0;

        red[1] = SCALE(255);
        green[1] = SCALE(255);
        blue[1] = SCALE(255);
        break;
    }

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

    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, WIDTH);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, HEIGHT);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bits_per_pixel);
    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_NONE);
    TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);

    scan_line = (unsigned char *) malloc(WIDTH / (8 / bits_per_pixel));

    for (i = 0; i < HEIGHT; i++) {
        for (j = 0, k = 0; j < WIDTH;) {
            cmap_index = (j / chunk_size) + ((i / chunk_size) * nchunks);

            switch (bits_per_pixel) {
            case 8:
                scan_line[k++] = cmap_index;
                j++;
                break;
            case 4:
                scan_line[k++] = (cmap_index << 4) + cmap_index;
                j += 2;
                break;
            case 2:
                scan_line[k++] = (cmap_index << 6) + (cmap_index << 4)
                    + (cmap_index << 2) + cmap_index;
                j += 4;
                break;
	    case 1:
		scan_line[k++] =
			((j / chunk_size) == (i / chunk_size)) ? 0x00 : 0xff;
		j += 8;
		break;
            }
        }
        TIFFWriteScanline(tif, scan_line, i, 0);
    }

    free(scan_line);
    TIFFClose(tif);
    return 0;
}
Example #20
0
int dt_imageio_tiff_read(dt_imageio_tiff_t *tiff, uint8_t *out)
{
  TIFFClose(tiff->handle);
  return 1;
}
Example #21
0
int vglPrintTiffInfo(char* inFilename, char* msg){
  if (msg){
    printf("====== %s:\n", msg);
  }
  else
  {
    printf("====== vglPrintTiffInfo:\n");
  }

  TIFF* tif = TIFFOpen(inFilename, "r"); 

  if (tif == NULL){
    fprintf(stderr, "%s:%s: Error: File %s not found.\n", __FILE__, __FUNCTION__, inFilename);
    return 1;
  }
  if (tif) { 
    uint32 w, h; 
    uint16 bps, spp, photo, config, pageNumber, numberPages;
    uint32 subfileType;

    tdir_t dirCount;

    tstrip_t stripMax;
    tstrip_t istrip; 
    tsize_t stripSize;

    tsize_t npixels; 
    tsize_t pixelSize; 
    
    tdata_t raster; 
    tsize_t result, offset;
    char* rasterc;

    uint32    iw, ih; 
    int i;

    do{
      TIFFPrintDirectory(tif, stdout, 255);
    }
    while(TIFFReadDirectory(tif));

    printf("TIFFScanlineSize = %ld\n", (long int) TIFFScanlineSize(tif));
    printf("TIFFRasterScanlineSize = %ld\n", (long int) TIFFRasterScanlineSize(tif));
    printf("TIFFStripSize = %ld\n", (long int) TIFFStripSize(tif));
    printf("TIFFNumberOfStrips = %d\n", TIFFNumberOfStrips(tif));
    printf("TIFFVStripSize = %ld\n", (long int) TIFFVStripSize(tif,0));

    printf("TIFFTileRowSize = %ld\n", (long int) TIFFTileRowSize(tif));
    printf("TIFFTileSize = %ld\n", (long int) TIFFTileSize(tif));
    printf("TIFFNumberOfTiles = %d\n", TIFFNumberOfTiles(tif));
    printf("TIFFVTileSize = %ld\n", (long int) TIFFVTileSize(tif,0));

    printf("TIFFDefaultStripSize = %d\n", TIFFDefaultStripSize(tif,0));

    printf("TIFFFileno = %d\n", TIFFFileno(tif));
    printf("TIFFGetMode = %d\n", TIFFGetMode(tif));
    printf("TIFFIsTiled = %d\n", TIFFIsTiled(tif));
    printf("TIFFIsByteSwapped = %d\n", TIFFIsByteSwapped(tif));
    printf("TIFFRGBAImageOK = %d\n", TIFFRGBAImageOK(tif, (char*)"TIFFRGBAImageOK mesg\n"));



    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); 
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); 
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bps);
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &spp);
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photo); 
    TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
    TIFFGetField(tif, TIFFTAG_PAGENUMBER, &pageNumber, &numberPages);
    TIFFGetField(tif, TIFFTAG_SUBFILETYPE, &subfileType);

    stripSize = TIFFStripSize(tif);
    stripMax = TIFFNumberOfStrips(tif);
    switch(bps){
      case 8:
        pixelSize = 1;
        break;
      case 16:
        pixelSize = 2;
        break;
      default:
        pixelSize = 0;
        break;
    }
    dirCount = tif_DirCount(tif);

    printf("size = %lu, w = %d, h = %d, spp = %d, bps = %d, pixelSize = %ld\n", sizeof(w), w, h, spp, bps, (long int) pixelSize);
    printf("Page Number = %d\n", pageNumber);
    printf("Number Pages = %d\n", numberPages);
    printf("Photometric interpretation = %d\n", photo);
    printf("Planar configuration = %d\n", config);
    printf("stripSize = %ld, stripMax = %d\n", (long int) stripSize, stripMax);
    printf("Number of directories = %d\n", dirCount);
    printf("Subfile type = %d\n", subfileType);

    //printbin((char*)&w, sizeof(w));
    //printbin((char*)&h, sizeof(h));


    //raster = tif_ReadData(tif);
    //tif_PrintAsc(tif, raster, (char*)"ascimg.txt");

    TIFFClose(tif); 
  } 
  return 0;
}
Example #22
0
int write_image (dt_imageio_module_data_t *d_tmp, const char *filename, const void *in_void, void *exif, int exif_len, int imgid)
{
  dt_imageio_tiff_t *d=(dt_imageio_tiff_t*)d_tmp;
  // Fetch colorprofile into buffer if wanted
  uint8_t *profile = NULL;
  uint32_t profile_len = 0;
  int rc = 0;

  if(imgid > 0)
  {
    cmsHPROFILE out_profile = dt_colorspaces_create_output_profile(imgid);
    cmsSaveProfileToMem(out_profile, 0, &profile_len);
    if (profile_len > 0)
    {
      profile=malloc(profile_len);
      cmsSaveProfileToMem(out_profile, profile, &profile_len);
    }
    dt_colorspaces_cleanup_profile(out_profile);
  }

  // Create tiff image
  TIFF *tif=TIFFOpen(filename,"wb");
  if(d->bpp == 8) TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
  else            TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
  TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
  TIFFSetField(tif, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
  if(profile!=NULL)
    TIFFSetField(tif, TIFFTAG_ICCPROFILE, profile_len, profile);
  TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, d->width);
  TIFFSetField(tif, TIFFTAG_IMAGELENGTH, d->height);
  TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  TIFFSetField(tif, TIFFTAG_PREDICTOR, 1);		// Reference www.awaresystems.be/imaging/tiff/tifftags/predictor.html
  TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
  TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, DT_TIFFIO_STRIPE);
  TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
  TIFFSetField(tif, TIFFTAG_XRESOLUTION, 300.0);
  TIFFSetField(tif, TIFFTAG_YRESOLUTION, 300.0);
  TIFFSetField(tif, TIFFTAG_ZIPQUALITY, 9);

  const uint8_t  *in8 =(const uint8_t  *)in_void;
  const uint16_t *in16=(const uint16_t *)in_void;
  if(d->bpp == 16)
  {
    uint32_t rowsize=(d->width*3)*sizeof(uint16_t);
    uint32_t stripesize=rowsize*DT_TIFFIO_STRIPE;
    uint16_t *rowdata = (uint16_t *)malloc(stripesize);
    uint16_t *wdata = rowdata;
    uint32_t stripe=0;
    // uint32_t insize=((d->width*d->height)*3)*sizeof(uint16_t);
    // while(stripedata<(in8+insize)-(stripesize)) {
    // TIFFWriteEncodedStrip(tif,stripe++,stripedata,stripesize);
    // stripedata+=stripesize;
    // }
    for (int y = 0; y < d->height; y++)
    {
      for(int x=0; x<d->width; x++)
        for(int k=0; k<3; k++)
        {
          (wdata)[0] = in16[4*d->width*y + 4*x + k];
          wdata++;
        }
      if((wdata-stripesize/sizeof(uint16_t))==rowdata)
      {
        TIFFWriteEncodedStrip(tif,stripe++,rowdata,rowsize*DT_TIFFIO_STRIPE);
        wdata=rowdata;
      }
    }
    if((wdata-stripesize/sizeof(uint16_t))!=rowdata)
      TIFFWriteEncodedStrip(tif,stripe,rowdata,(wdata-rowdata)*sizeof(uint16_t));
    TIFFClose(tif);
    free(rowdata);
  }
  else
  {
    uint32_t rowsize=(d->width*3)*sizeof(uint8_t);
    uint32_t stripesize=rowsize*DT_TIFFIO_STRIPE;
    uint8_t *rowdata = (uint8_t *)malloc(stripesize);
    uint8_t *wdata = rowdata;
    uint32_t stripe=0;

    for (int y = 0; y < d->height; y++)
    {
      for(int x=0; x<d->width; x++)
        for(int k=0; k<3; k++)
        {
          (wdata)[0] = in8[4*d->width*y + 4*x + k];
          wdata++;
        }
      if((wdata-stripesize)==rowdata)
      {
        TIFFWriteEncodedStrip(tif,stripe++,rowdata,rowsize*DT_TIFFIO_STRIPE);
        wdata=rowdata;
      }
    }
    if((wdata-stripesize)!=rowdata)
      TIFFWriteEncodedStrip(tif,stripe,rowdata,wdata-rowdata);
    TIFFClose(tif);
    free(rowdata);
  }

  if(exif)
    rc = dt_exif_write_blob(exif,exif_len,filename);

  free(profile);

  /*
   * Until we get symbolic error status codes, if rc is 1, return 0.
   */
  return ((rc == 1) ? 0 : 1);
}
int FileReadTIF(Tcl_Interp *interp,
		Tcl_Channel chan,
		CONST char *fileName,
		Tcl_Obj *format,
		Tk_PhotoHandle imageHandle,
		int destX, int destY,
		int width, int height,
		int srcX, int srcY)
{
    int nBytes, h;
    int nLines;                   /* actual number of scan lines read
                                   * for each image block pointed at
                                   * by pixelPtr */
    int nDefBlockLines;           /* default number of scan lines to be read
                                   * for each image block pointed at
                                   * by pixelPtr */
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    unsigned long fileImgHeight, fileImgWidth;
    unsigned short bitspersample;
    unsigned short photometrictype;

    short n;
    unsigned long row;
    unsigned long startrow;
    unsigned long pixelPtrIndex;
    TIFF *tif;
    TIFFErrorHandler prev_handler; /* Current TIFF error handler  */
    static TIFFErrorHandler temp_handler = tkTIFFErrorHandler;
                                   /* Temporary TIFF error handler
                                      (is used to avoid output of
                                       libtiff error messages to stderr) */

    prev_handler = TIFFSetErrorHandler(temp_handler);

    tif = TIFFOpen(fileName, "r");
    if (tif == NULL) {
        printf("FileReadTIF: Problem reading TIF file !");
	Tcl_AppendResult(interp, "couldn't read TIF header from file \"",
		fileName, "\"", NULL);
        TIFFSetErrorHandler(prev_handler);
        return TCL_ERROR;
    }

    /* test entry !!! */
    /*
    printf("\nFileReadTIF: file name     = %s", fileName);
    printf("\nFileReadTIF: height        = %d", height);
    printf("\nFileReadTIF: width         = %d", width);
    */
    /* obtain dimensions of (first) image in TIFF file */
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &fileImgHeight);
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &fileImgWidth);
    /* test entry !!! */
    /*
     printf("\nFileReadTIF: image height  = %d", fileImgHeight);
     printf("\nFileReadTIF: image width   = %d\n", fileImgWidth);
    */


    if ((fileImgWidth <= 0) || (fileImgHeight <= 0)) {
	Tcl_AppendResult(interp, "TIF image file \"", fileName,
		"\" has dimension(s) <= 0", (char *) NULL);
	return TCL_ERROR;
    }

    if ((srcX + width) > fileImgWidth) {
	width = fileImgWidth - srcX;
    }
    if ((srcY + height) > fileImgHeight) {
	height = fileImgHeight - srcY;
    }
    if ((width <= 0) || (height <= 0)
	|| (srcX >= fileImgWidth) || (srcY >= fileImgHeight)) {
	return TCL_OK;
    }


    /*
       determine type of TIFF image: PhotometricInterpretation
       WhiteIsZero       => 0 (bw or grayscale image)
       BlackIsZero       => 1 (bw or grayscale image)
       RGB Model         => 2 (RGB full color model)
       Color Palette     => 3
       Transparency Mask => 4
    */
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometrictype);
    /* test entry !!! */
    if ((photometrictype == 0) || (photometrictype == 1) || (photometrictype == 3)) {
        /*
           bw or grayscale image
        */
        TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
        /* test entry !!! */
	/*
        printf("\nFileReadTIF: bits / sample = %d", bitspersample);
	*/
        block.pixelSize = 1;
        block.offset[0] = 0;
        block.offset[1] = 0;
        block.offset[2] = 0;
    } else if (photometrictype == 2) {
        /*
           RGB full color image

           note: - bitspersample is always = 8
                 - there is no color map
        */
        block.pixelSize = 3;
        block.offset[0] = 0;
        block.offset[1] = 1;
        block.offset[2] = 2;
    } else {
        Tcl_AppendResult(interp, "photometric interpretation >2 ",
            "(palette color and transparency mask) ",
            "not yet supported", NULL);
        TIFFSetErrorHandler(prev_handler);
        return TCL_ERROR;
    }

    /* block.width = width; */
    height = fileImgHeight;
    width = fileImgWidth;
    block.width = fileImgWidth;
    block.pitch = block.pixelSize * fileImgWidth;
    /* test entry !!! */
    /*
    printf("\nFileReadTIF: height        = %d", height);
    printf("\nFileReadTIF: width         = %d", width);
    printf("\nFileReadTIF: fileImgWidth         = %d", fileImgWidth);
    */
    /* the following two values should be identical */
    /*
    printf("\nFileReadTIF: block.pitch     = %d", block.pitch);
    printf("\nFileReadTIF: block.pixelSize = %d", block.pixelSize);
    printf("\nFileReadTIF: scanline size   = %d", TIFFScanlineSize(tif));
    */
    Tk_PhotoExpand(imageHandle, destX + width, destY + height);

    /*
    if (srcY > 0) {
	fseek(f, (long) (srcY * block.pitch), SEEK_CUR);
    }
    */

    nDefBlockLines = (MAX_MEMORY + block.pitch - 1) / block.pitch;
    nLines = nDefBlockLines;
    nLines = height;
    if (nLines > height) {
        nLines = height;
    }
    if (nLines <= 0) {
        nLines = 1;
    }

    /* determine the required buffer size by calling TIFFScanlineSize */
    nBytes = nLines * block.pitch;
    /*
    printf("\nFileReadTIF: nLines        = %d", nLines);
    printf("\nFileReadTIF: nBytes        = %d", nBytes);
    */
    pixelPtr = (unsigned char *) ckalloc((unsigned)nBytes);
    block.pixelPtr = pixelPtr + srcX * block.pixelSize;

    n = 0;
    for (h = height; h > 0; h -= nLines) {
        n++;
        startrow = (n-1) * nLines;
        if (nLines > h) {
            nLines = h;
            nBytes = nLines * block.pitch;
        }
        for (row = startrow; row < (startrow + nLines); row++) {
            /* read the data for the spezified row into the buffer */
            pixelPtrIndex = row*block.pitch - (n-1)*nDefBlockLines*block.pitch;
            /* test entry !!! */
            /* printf("\nFileReadTIF: pixelPtr_Indx = %d", pixelPtrIndex); */
            TIFFReadScanline(tif, &(pixelPtr[pixelPtrIndex]), row, 1);
        }
	block.height = nLines;

	Tk_PhotoPutBlock(imageHandle, &block, destX, destY, width, nLines, TK_PHOTO_COMPOSITE_SET);
	destY += nLines;
    }


    ckfree((char *) pixelPtr);

    TIFFClose(tif);
    /* test entry !!! */
    /*
    printf("\nFileReadTIF: TIF file closed !");
    */
    TIFFSetErrorHandler(prev_handler);

    return TCL_OK;



}
Example #24
0
File: sgi2tiff.c Project: aosm/tcl
int
main(int argc, char* argv[])
{
	IMAGE *in;
	TIFF *out;
	int c;
	extern int optind;
	extern char* optarg;

	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);
}
Example #25
0
int
main(int argc, char **argv)
{
	TIFF		*tif;
	unsigned int	i;
	unsigned char	buf[3] = { 0, 127, 255 };
        (void) argc;
        (void) argv;

	/* 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, 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, 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_ROWSPERSTRIP, rows_per_strip)) {
		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, long_tags[i].tag,
				  long_tags[i].value)) {
			fprintf(stderr, "Can't set tag %d.\n",
				(int)long_tags[i].tag);
			goto failure;
		}
	}

	/* Write dummy pixel data. */
	if (TIFFWriteScanline(tif, buf, 0, 0) == -1) {
		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;
	}

	if (CheckLongField(tif, TIFFTAG_IMAGEWIDTH, width) < 0)
		goto failure;

	if (CheckLongField(tif, TIFFTAG_IMAGELENGTH, length) < 0)
		goto failure;

	if (CheckLongField(tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip) < 0)
		goto failure;

	for (i = 0; i < NTAGS; i++) {
		if (CheckLongField(tif, long_tags[i].tag,
				   long_tags[i].value) < 0)
			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;
}
Example #26
0
int ImagingLibTiffDecode(Imaging im, ImagingCodecState state, UINT8* buffer, Py_ssize_t bytes) {
    TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
    char *filename = "tempfile.tif";
    char *mode = "r";
    TIFF *tiff;

    /* buffer is the encoded file, bytes is the length of the encoded file */
    /*     it all ends up in state->buffer, which is a uint8* from Imaging.h */

    TRACE(("in decoder: bytes %d\n", bytes));
    TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
           state->x, state->y, state->ystep));
    TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
           state->xoff, state->yoff));
    TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
    TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
    TRACE(("State->Buffer: %c%c%c%c\n", (char)state->buffer[0], (char)state->buffer[1],(char)state->buffer[2], (char)state->buffer[3]));
    TRACE(("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
           im->mode, im->type, im->bands, im->xsize, im->ysize));
    TRACE(("Image: image8 %p, image32 %p, image %p, block %p \n",
           im->image8, im->image32, im->image, im->block));
    TRACE(("Image: pixelsize: %d, linesize %d \n",
           im->pixelsize, im->linesize));

    dump_state(clientstate);
    clientstate->size = bytes;
    clientstate->eof = clientstate->size;
    clientstate->loc = 0;
    clientstate->data = (tdata_t)buffer;
    clientstate->flrealloc = 0;
    dump_state(clientstate);

    TIFFSetWarningHandler(NULL);
    TIFFSetWarningHandlerExt(NULL);

    if (clientstate->fp) {
        TRACE(("Opening using fd: %d\n",clientstate->fp));
        lseek(clientstate->fp,0,SEEK_SET); // Sometimes, I get it set to the end.
        tiff = TIFFFdOpen(clientstate->fp, filename, mode);
    } else {
        TRACE(("Opening from string\n"));
        tiff = TIFFClientOpen(filename, mode,
                              (thandle_t) clientstate,
                              _tiffReadProc, _tiffWriteProc,
                              _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
                              _tiffMapProc, _tiffUnmapProc);
    }

    if (!tiff){
        TRACE(("Error, didn't get the tiff\n"));
        state->errcode = IMAGING_CODEC_BROKEN;
        return -1;
    }

    if (clientstate->ifd){
        int rv;
        uint32 ifdoffset = clientstate->ifd;
        TRACE(("reading tiff ifd %u\n", ifdoffset));
        rv = TIFFSetSubDirectory(tiff, ifdoffset);
        if (!rv){
            TRACE(("error in TIFFSetSubDirectory"));
            return -1;
        }
    }

    if (TIFFIsTiled(tiff)) {
        UINT32 x, y, tile_y, row_byte_size;
        UINT32 tile_width, tile_length, current_tile_width;
        UINT8 *new_data;

        TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tile_width);
        TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tile_length);

        // We could use TIFFTileSize, but for YCbCr data it returns subsampled data size
        row_byte_size = (tile_width * state->bits + 7) / 8;
        state->bytes = row_byte_size * tile_length;

        /* overflow check for malloc */
        if (state->bytes > INT_MAX - 1) {
            state->errcode = IMAGING_CODEC_MEMORY;
            TIFFClose(tiff);
            return -1;
        }

        /* realloc to fit whole tile */
        new_data = realloc (state->buffer, state->bytes);
        if (!new_data) {
            state->errcode = IMAGING_CODEC_MEMORY;
            TIFFClose(tiff);
            return -1;
        }

        state->buffer = new_data;

        TRACE(("TIFFTileSize: %d\n", state->bytes));

        for (y = state->yoff; y < state->ysize; y += tile_length) {
            for (x = state->xoff; x < state->xsize; x += tile_width) {
                if (ReadTile(tiff, x, y, (UINT32*) state->buffer) == -1) {
                    TRACE(("Decode Error, Tile at %dx%d\n", x, y));
                    state->errcode = IMAGING_CODEC_BROKEN;
                    TIFFClose(tiff);
                    return -1;
                }

                TRACE(("Read tile at %dx%d; \n\n", x, y));

                current_tile_width = min(tile_width, state->xsize - x);

                // iterate over each line in the tile and stuff data into image
                for (tile_y = 0; tile_y < min(tile_length, state->ysize - y); tile_y++) {
                    TRACE(("Writing tile data at %dx%d using tile_width: %d; \n", tile_y + y, x, current_tile_width));

                    // UINT8 * bbb = state->buffer + tile_y * row_byte_size;
                    // TRACE(("chars: %x%x%x%x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));

                    state->shuffle((UINT8*) im->image[tile_y + y] + x * im->pixelsize,
                       state->buffer + tile_y * row_byte_size,
                       current_tile_width
                    );
                }
            }
        }
    } else {
        UINT32 strip_row, row_byte_size;
        UINT8 *new_data;
        UINT32 rows_per_strip;

        TIFFGetField(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip);
        TRACE(("RowsPerStrip: %u \n", rows_per_strip));

        // We could use TIFFStripSize, but for YCbCr data it returns subsampled data size
        row_byte_size = (state->xsize * state->bits + 7) / 8;
        state->bytes = rows_per_strip * row_byte_size;

        TRACE(("StripSize: %d \n", state->bytes));

        /* realloc to fit whole strip */
        new_data = realloc (state->buffer, state->bytes);
        if (!new_data) {
            state->errcode = IMAGING_CODEC_MEMORY;
            TIFFClose(tiff);
            return -1;
        }

        state->buffer = new_data;

        for (; state->y < state->ysize; state->y += rows_per_strip) {
            if (ReadStrip(tiff, state->y, (UINT32 *)state->buffer) == -1) {
                TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, state->y, 0)));
                state->errcode = IMAGING_CODEC_BROKEN;
                TIFFClose(tiff);
                return -1;
            }

            TRACE(("Decoded strip for row %d \n", state->y));

            // iterate over each row in the strip and stuff data into image
            for (strip_row = 0; strip_row < min(rows_per_strip, state->ysize - state->y); strip_row++) {
                TRACE(("Writing data into line %d ; \n", state->y + strip_row));

                // UINT8 * bbb = state->buffer + strip_row * (state->bytes / rows_per_strip);
                // TRACE(("chars: %x %x %x %x\n", ((UINT8 *)bbb)[0], ((UINT8 *)bbb)[1], ((UINT8 *)bbb)[2], ((UINT8 *)bbb)[3]));

                state->shuffle((UINT8*) im->image[state->y + state->yoff + strip_row] +
                               state->xoff * im->pixelsize,
                               state->buffer + strip_row * row_byte_size,
                               state->xsize);
            }
        }
    }

    TIFFClose(tiff);
    TRACE(("Done Decoding, Returning \n"));
    // Returning -1 here to force ImageFile.load to break, rather than
    // even think about looping back around.
    return -1;
}
Example #27
0
void
TIFFInput::readspec (bool read_meta)
{
    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);

    if (read_meta) {
        // clear the whole m_spec and start fresh
        m_spec = ImageSpec ((int)width, (int)height, (int)nchans);
    } else {
        // assume m_spec is valid, except for things that might differ
        // between MIP levels
        m_spec.width = (int)width;
        m_spec.height = (int)height;
        m_spec.depth = (int)depth;
        m_spec.full_x = 0;
        m_spec.full_y = 0;
        m_spec.full_z = 0;
        m_spec.full_width = (int)width;
        m_spec.full_height = (int)height;
        m_spec.full_depth = (int)depth;
        m_spec.nchannels = (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:
    case 6:
        // Make 1, 2, 4, 6 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 10:
    case 12:
    case 14:
        // Make 10, 12, 14 bpp look like 16 bit images
    case 16:
        if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT16);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT16);
        else if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::HALF); // not to spec, but why not?
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    case 32:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::FLOAT);
        else if (sampleformat == SAMPLEFORMAT_UINT)
            m_spec.set_format (TypeDesc::UINT32);
        else if (sampleformat == SAMPLEFORMAT_INT)
            m_spec.set_format (TypeDesc::INT32);
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    case 64:
        if (sampleformat == SAMPLEFORMAT_IEEEFP)
            m_spec.set_format (TypeDesc::DOUBLE);
        else
            m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    default:
        m_spec.set_format (TypeDesc::UNKNOWN);
        break;
    }

    // If we've been instructed to skip reading metadata, because it is
    // guaranteed to be identical to what we already have in m_spec,
    // skip everything following.
    if (! read_meta)
        return;

    // 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 ();
        // FIXME - what about palette + extra (alpha?) channels?  Is that
        // allowed?  And if so, ever encountered in the wild?
    }

    TIFFGetFieldDefaulted (m_tif, TIFFTAG_PLANARCONFIG, &m_planarconfig);
    m_separate = (m_planarconfig == PLANARCONFIG_SEPARATE &&
                  m_spec.nchannels > 1 &&
                  m_photometric != PHOTOMETRIC_PALETTE);
    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? 

    // Do we care about fillorder?  No, the TIFF spec says, "We
    // recommend that FillOrder=2 (lsb-to-msb) be used only in
    // special-purpose applications".  So OIIO will assume msb-to-lsb
    // convention until somebody finds a TIFF file in the wild that
    // breaks this assumption.

    // 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";
    }

    unsigned short *sampleinfo = NULL;
    unsigned short extrasamples = 0;
    TIFFGetFieldDefaulted (m_tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &sampleinfo);
    // std::cerr << "Extra samples = " << extrasamples << "\n";
    bool alpha_is_unassociated = false;  // basic assumption
    if (extrasamples) {
        // If the TIFF ExtraSamples tag was specified, use that to figure
        // out the meaning of alpha.
        int colorchannels = 3;
        if (m_photometric == PHOTOMETRIC_MINISWHITE ||
              m_photometric == PHOTOMETRIC_MINISBLACK ||
              m_photometric == PHOTOMETRIC_PALETTE ||
              m_photometric == PHOTOMETRIC_MASK)
            colorchannels = 1;
        for (int i = 0, c = colorchannels;
             i < extrasamples && c < m_spec.nchannels;  ++i, ++c) {
            // std::cerr << "   extra " << i << " " << sampleinfo[i] << "\n";
            if (sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA) {
                // This is the alpha channel, associated as usual
                m_spec.alpha_channel = c;
            } else if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA) {
                // This is the alpha channel, but color is unassociated
                m_spec.alpha_channel = c;
                alpha_is_unassociated = true;
                m_spec.attribute ("oiio:UnassociatedAlpha", 1);
            } else {
                DASSERT (sampleinfo[i] == EXTRASAMPLE_UNSPECIFIED);
                // This extra channel is not alpha at all.  Undo any
                // assumptions we previously made about this channel.
                if (m_spec.alpha_channel == c) {
                    m_spec.channelnames[c] = Strutil::format("channel%d", c);
                    m_spec.alpha_channel = -1;
                }
            }
        }
        if (m_spec.alpha_channel >= 0)
            m_spec.channelnames[m_spec.alpha_channel] = "A";
    }
    // Will we need to do alpha conversions?
    m_convert_alpha = (m_spec.alpha_channel >= 0 && alpha_is_unassociated &&
                       ! m_keep_unassociated_alpha);

    // N.B. we currently ignore the following TIFF fields:
    // 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);
        FILE *fd = Filesystem::fopen (m_filename, "rm");
        m_tif = (fd) ? TIFFFdOpen (fileno (fd), m_filename.c_str(), "rm"): NULL;
        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
}
Example #28
0
int ImagingLibTiffEncode(Imaging im, ImagingCodecState state, UINT8* buffer, int bytes) {
    /* One shot encoder. Encode everything to the tiff in the clientstate.
       If we're running off of a FD, then run once, we're good, everything
       ends up in the file, we close and we're done.

       If we're going to memory, then we need to write the whole file into memory, then
       parcel it back out to the pystring buffer bytes at a time.

    */

    TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
    TIFF *tiff = clientstate->tiff;

    TRACE(("in encoder: bytes %d\n", bytes));
    TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
           state->x, state->y, state->ystep));
    TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
           state->xoff, state->yoff));
    TRACE(("State: bits %d, bytes %d \n", state->bits, state->bytes));
    TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
    TRACE(("State->Buffer: %c%c%c%c\n", (char)state->buffer[0], (char)state->buffer[1],(char)state->buffer[2], (char)state->buffer[3]));
    TRACE(("Image: mode %s, type %d, bands: %d, xsize %d, ysize %d \n",
           im->mode, im->type, im->bands, im->xsize, im->ysize));
    TRACE(("Image: image8 %p, image32 %p, image %p, block %p \n",
           im->image8, im->image32, im->image, im->block));
    TRACE(("Image: pixelsize: %d, linesize %d \n",
           im->pixelsize, im->linesize));

    dump_state(clientstate);

    if (state->state == 0) {
        TRACE(("Encoding line bt line"));
        while(state->y < state->ysize){
            state->shuffle(state->buffer,
                           (UINT8*) im->image[state->y + state->yoff] +
                           state->xoff * im->pixelsize,
                           state->xsize);

            if (TIFFWriteScanline(tiff, (tdata_t)(state->buffer), (uint32)state->y, 0) == -1) {
                TRACE(("Encode Error, row %d\n", state->y));
                state->errcode = IMAGING_CODEC_BROKEN;
                TIFFClose(tiff);
                if (!clientstate->fp){
                    free(clientstate->data);
                }
                return -1;
            }
            state->y++;
        }

        if (state->y == state->ysize) {
            state->state=1;

            TRACE(("Flushing \n"));
            if (!TIFFFlush(tiff)) {
                TRACE(("Error flushing the tiff"));
                // likely reason is memory.
                state->errcode = IMAGING_CODEC_MEMORY;
                TIFFClose(tiff);
                if (!clientstate->fp){
                    free(clientstate->data);
                }
                return -1;
            }
            TRACE(("Closing \n"));
            TIFFClose(tiff);
            // reset the clientstate metadata to use it to read out the buffer.
            clientstate->loc = 0;
            clientstate->size = clientstate->eof; // redundant?
        }
    }

    if (state->state == 1 && !clientstate->fp) {
        int read = (int)_tiffReadProc(clientstate, (tdata_t)buffer, (tsize_t)bytes);
        TRACE(("Buffer: %p: %c%c%c%c\n", buffer, (char)buffer[0], (char)buffer[1],(char)buffer[2], (char)buffer[3]));
        if (clientstate->loc == clientstate->eof) {
            TRACE(("Hit EOF, calling an end, freeing data"));
            state->errcode = IMAGING_CODEC_END;
            free(clientstate->data);
        }
        return read;
    }

    state->errcode = IMAGING_CODEC_END;
    return 0;
}
Example #29
0
int tiff_write(char filename[], uint32 *raster, uint32 nrow, uint32 ncol) {
  int i,j;
  long stripsperimage = 0;
  long rasterbase;
  unsigned char *tmpStorage;
  unsigned char *tmpPtr;
  TIFF* tif = TIFFOpen(filename, "w");
  if (tif) {
    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, ncol);
    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, nrow);
    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3);
    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
    TIFFSetField(tif, TIFFTAG_COMPRESSION, 1); /* none */
    TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
    TIFFSetField(tif, TIFFTAG_XRESOLUTION, 1200.0);
    TIFFSetField(tif, TIFFTAG_YRESOLUTION, 1200.0);
    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);

    /* calculate the number of strips we want in the TIFF file */
    stripsperimage = nrow * ncol / 8000;
    if(stripsperimage < 1)
      stripsperimage = 1;
    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, stripsperimage);

    tmpStorage = (unsigned char *)malloc(sizeof(unsigned char) * ncol * 3);
    if(!tmpStorage) {
      fprintf(stderr, "Memory allocation error\n");
      TIFFClose(tif);
      return(-1);
    }
    if (raster != NULL) {
      for(i=0;i<nrow;i++) {
	rasterbase = (nrow - i - 1) * ncol;
	for(j=0;j<ncol*3;) {
	  tmpPtr = (unsigned char *)&(raster[rasterbase]);
#if INTEL
	  tmpStorage[j] = tmpPtr[0];
	  j++;
	  tmpStorage[j] = tmpPtr[1];
	  j++;
	  tmpStorage[j] = tmpPtr[2];
	  j++;
#elif
	  tmpStorage[j] = tmpPtr[3];
	  j++;
	  tmpStorage[j] = tmpPtr[2];
	  j++;
	  tmpStorage[j] = tmpPtr[1];
	  j++;
#endif
	  rasterbase++;
	}
	if (TIFFWriteScanline(tif, tmpStorage, i, 0) != 1) {
	  fprintf(stderr, "Unable to write scanline %d\n",i);
	  return(-1);
	}
      }

      TIFFClose(tif);
      return(0);
    }
    else {
      TIFFClose(tif);
      fprintf(stderr, "image is NULL\n");
      return(-1);
    }
  }
  else {
    fprintf(stderr, "Unable to open %s for writing\n",filename);
    return(-1);
  }
}
Example #30
0
TifWriter::~TifWriter() {
  if (m_tiff) TIFFClose(m_tiff);

  delete[] m_lineBuffer;
  delete m_properties;
}