Esempio n. 1
0
/*
 * Construct any mapping table used
 * by the associated put routine.
 */
static int
buildMap(TIFFRGBAImage* img)
{
    switch (img->photometric) {
    case PHOTOMETRIC_RGB:
    case PHOTOMETRIC_YCBCR:
    case PHOTOMETRIC_SEPARATED:
    if (img->bitspersample == 8)
    break;
    /* fall thru... */
    case PHOTOMETRIC_MINISBLACK:
    case PHOTOMETRIC_MINISWHITE:
    if (!setupMap(img))
    return (0);
    break;
    case PHOTOMETRIC_PALETTE:
    /*
     * Convert 16-bit colormap to 8-bit (unless it looks
     * like an old-style 8-bit colormap).
     */
    if (checkcmap(img) == 16)
    cvtcmap(img);
    else
    TIFFWarning(TIFFFileName(img->tif), "Assuming 8-bit colormap");
    /*
     * Use mapping table and colormap to construct
     * unpacking tables for samples < 8 bits.
     */
    if (img->bitspersample <= 8 && !makecmap(img))
    return (0);
    break;
    }
    return (1);
}
Esempio n. 2
0
int
main(int argc, char* argv[])
{
    uint16 bitspersample, shortv;
    uint32 imagewidth, imagelength;
    uint16 config = PLANARCONFIG_CONTIG;
    uint32 rowsperstrip = (uint32) -1;
    uint16 photometric = PHOTOMETRIC_RGB;
    uint16 *rmap, *gmap, *bmap;
    uint32 row;
    int cmap = -1;
    TIFF *in, *out;
    int c;
    extern int optind;
    extern char* optarg;

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

        for (i = (1<<bitspersample)-1; i >= 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
            rmap[i] = CVT(rmap[i]);
            gmap[i] = CVT(gmap[i]);
            bmap[i] = CVT(bmap[i]);
        }
    }
    {   unsigned char *ibuf, *obuf;
        register unsigned char* pp;
        register uint32 x;
        ibuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(in));
        obuf = (unsigned char*)_TIFFmalloc(TIFFScanlineSize(out));
        switch (config) {
        case PLANARCONFIG_CONTIG:
            for (row = 0; row < imagelength; row++) {
                if (!TIFFReadScanline(in, ibuf, row, 0))
                    goto done;
                pp = obuf;
                for (x = 0; x < imagewidth; x++) {
                    *pp++ = rmap[ibuf[x]];
                    *pp++ = gmap[ibuf[x]];
                    *pp++ = bmap[ibuf[x]];
                }
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
            }
            break;
        case PLANARCONFIG_SEPARATE:
            for (row = 0; row < imagelength; row++) {
                if (!TIFFReadScanline(in, ibuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = rmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = gmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
                for (pp = obuf, x = 0; x < imagewidth; x++)
                    *pp++ = bmap[ibuf[x]];
                if (!TIFFWriteScanline(out, obuf, row, 0))
                    goto done;
            }
            break;
        }
        _TIFFfree(ibuf);
        _TIFFfree(obuf);
    }
done:
    (void) TIFFClose(in);
    (void) TIFFClose(out);
    return (0);
}
Esempio n. 3
0
Image *Read (IStream *file, const Image::ReadOptions& options)
{
    int                   nrow;
    int                   result = 0;
    long                  LineSize;
    TIFF                  *tif;
    Image                 *image ;
    uint16                BitsPerSample;
    uint16                BytesPerSample = 1;
    uint16                PhotometricInterpretation;
    uint16                SamplePerPixel;
    uint16                Orientation;
    uint32                RowsPerStrip;
    unsigned int          width;
    unsigned int          height;

    // TODO - TIFF files probably have some gamma info in them by default, but we're currently ignorant about that.
    // Until that is fixed, use whatever the user has chosen as default.
    GammaCurvePtr gamma;
    if (options.gammacorrect && options.defaultGamma)
        gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma);

    // [CLi] TIFF is specified to use associated (= premultiplied) alpha, so that's the preferred mode to use for the image container unless the user overrides
    // (e.g. to handle a non-compliant file).
    bool premul = true;
    if (options.premultiplyOverride)
        premul = options.premultiply;

    // Rather than have libTIFF complain about tags it doesn't understand,
    // we just suppress all the warnings.
    TIFFSetWarningHandler(SuppressTIFFWarnings);
    TIFFSetErrorHandler(SuppressTIFFWarnings);

    // Open and do initial processing
    tif = TIFFClientOpen("Dummy File Name", "r", file,
        Tiff_Read, Tiff_Write, Tiff_Seek, Tiff_Close,
        Tiff_Size, Tiff_Map, Tiff_Unmap);
    if (!tif)
        return (NULL) ;

    // Get basic information about the image
    int ExtraSamples, ExtraSampleInfo;
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
    TIFFGetField(tif, TIFFTAG_ORIENTATION, &Orientation);
    TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &ExtraSamples, &ExtraSampleInfo);

    // don't support more than 16 bits per sample
    if (BitsPerSample == 16)
    {
        BytesPerSample = 2 ;
        options.warnings.push_back ("Warning: reading 16 bits/sample TIFF file; components crunched to 8");
    }

    LineSize = TIFFScanlineSize(tif);
    assert (SamplePerPixel == (int) (LineSize / width) / BytesPerSample);
    // SamplePerPixel = (int)(LineSize / width);

#if 0
    // For now we are ignoring the orientation of the image...
    switch (Orientation)
    {
    case ORIENTATION_TOPLEFT:
        break;
    case ORIENTATION_TOPRIGHT:
        break;
    case ORIENTATION_BOTRIGHT:
        break;
    case ORIENTATION_BOTLEFT:
        break;
    case ORIENTATION_LEFTTOP:
        break;
    case ORIENTATION_RIGHTTOP:
        break;
    case ORIENTATION_RIGHTBOT:
        break;
    case ORIENTATION_LEFTBOT:
        break;
    default:
        break;
    }
#endif

    //PhotometricInterpretation = 2 image is RGB
    //PhotometricInterpretation = 3 image have a color palette
    if (PhotometricInterpretation == PHOTOMETRIC_PALETTE && (TIFFIsTiled(tif) == 0))
    {
        uint16 *red, *green, *blue;

        //load the palette
        int cmap_len = (1 << BitsPerSample);

        TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);

        vector<Image::RGBMapEntry> colormap ;
        Image::RGBMapEntry entry;

        // I may be mistaken, but it appears that alpha/opacity information doesn't
        // appear in a Paletted Tiff image.  Well - if it does, it's not as easy to
        // get at as RGB.
        // Read the palette
        // Is the palette 16 or 8 bits ?
        if (checkcmap(cmap_len, red, green, blue) == 16)
        {
            for (int i=0;i<cmap_len;i++)
            {
                entry.red   = IntDecode(gamma, red[i],   65535);
                entry.green = IntDecode(gamma, green[i], 65535);
                entry.blue  = IntDecode(gamma, blue[i],  65535);
                colormap.push_back (entry);
            }
        }
        else
        {
            for (int i=0;i<cmap_len;i++)
            {
                entry.red   = IntDecode(gamma, red[i],   255);
                entry.green = IntDecode(gamma, green[i], 255);
                entry.blue  = IntDecode(gamma, blue[i],  255);
                colormap.push_back (entry);
            }
        }

        Image::ImageDataType imagetype = options.itype;
        if (imagetype == Image::Undefined)
            imagetype = Image::Colour_Map;
        image = Image::Create (width, height, imagetype, colormap) ;
        image->SetPremultiplied(premul); // specify whether the color map data has premultiplied alpha

        boost::scoped_array<unsigned char> buf (new unsigned char [TIFFStripSize(tif)]);

        //read the tiff lines and save them in the image
        //with RGB mode, we have to change the order of the 3 samples RGB <=> BGR
        for (int row=0;row<height;row+=RowsPerStrip)
        {
            nrow = (row + (int)RowsPerStrip > height ? height - row : RowsPerStrip);
            TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf.get(), nrow * LineSize);
            for (int l = 0, offset = 0; l < nrow ; l++, offset += LineSize)
                for (int x = 0 ; x < width ; x++)
                    image->SetIndexedValue (x, row+l, buf[offset+x]) ;
        }
    }
    else
    {
        // Allocate the row buffers for the image
        boost::scoped_array<uint32> buf (new uint32 [width * height]) ;

        Image::ImageDataType imagetype = options.itype;
        if (imagetype == Image::Undefined)
            imagetype = ( GammaCurve::IsNeutral(gamma) ? Image::RGBA_Int8 : Image::RGBA_Gamma8 );
        image = Image::Create (width, height, imagetype) ;
        image->SetPremultiplied(premul); // set desired storage mode regarding alpha premultiplication
        image->TryDeferDecoding(gamma, 255); // try to have gamma adjustment being deferred until image evaluation.

        TIFFReadRGBAImage(tif, width, height, buf.get(), 0);
        uint32 abgr, *tbuf = buf.get();
        for (int i=height-1;i>=0;i--)
        {
            for (int j=0;j<width;j++)
            {
                abgr = *tbuf++;
                unsigned int b = (unsigned char)TIFFGetB(abgr);
                unsigned int g = (unsigned char)TIFFGetG(abgr);
                unsigned int r = (unsigned char)TIFFGetR(abgr);
                unsigned int a = (unsigned char)TIFFGetA(abgr);
                SetEncodedRGBAValue(image, j, i, gamma, 255, r, g, b, a, premul) ;
            }
        }
    }

    TIFFClose(tif);

    return (image) ;
}
Esempio n. 4
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;
}
Esempio n. 5
0
int
main(int argc, char* argv[])
{
	uint32 rowsperstrip = (uint32) -1;
	TIFF *in, *out;
	uint32 w, h;
	uint16 samplesperpixel;
	uint16 bitspersample;
	uint16 config;
	uint16 photometric;
	uint16* red;
	uint16* green;
	uint16* blue;
	tsize_t rowsize;
	register uint32 row;
	register tsample_t s;
	unsigned char *inbuf, *outbuf;
	char thing[1024];
	int c;
	extern int optind;
	extern char *optarg;

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

	out = TIFFOpen(argv[optind+1], "w");
	if (out == NULL)
		return (-1);
	cpTags(in, out);
	TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
	TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
	TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	if (compression != (uint16) -1) {
		TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
		switch (compression) {
		case COMPRESSION_JPEG:
			TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
			TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
			break;
		case COMPRESSION_LZW:
		case COMPRESSION_DEFLATE:
			if (predictor != 0)
				TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
			break;
		}
	}
	TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
	sprintf(thing, "B&W version of %s", argv[optind]);
	TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
	TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
	outbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(out));
	TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
	    TIFFDefaultStripSize(out, rowsperstrip));

#define	pack(a,b)	((a)<<8 | (b))
	switch (pack(photometric, config)) {
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG):
	case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE):
		TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue);
		/*
		 * Convert 16-bit colormap to 8-bit (unless it looks
		 * like an old-style 8-bit colormap).
		 */
		if (checkcmap(in, 1<<bitspersample, red, green, blue) == 16) {
			int i;
#define	CVT(x)		(((x) * 255L) / ((1L<<16)-1))
			for (i = (1<<bitspersample)-1; i >= 0; i--) {
				red[i] = CVT(red[i]);
				green[i] = CVT(green[i]);
				blue[i] = CVT(blue[i]);
			}
#undef CVT
		}
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresspalette(outbuf, inbuf, w, red, green, blue);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG):
		inbuf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(in));
		for (row = 0; row < h; row++) {
			if (TIFFReadScanline(in, inbuf, row, 0) < 0)
				break;
			compresscontig(outbuf, inbuf, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE):
		rowsize = TIFFScanlineSize(in);
		inbuf = (unsigned char *)_TIFFmalloc(3*rowsize);
		for (row = 0; row < h; row++) {
			for (s = 0; s < 3; s++)
				if (TIFFReadScanline(in,
				    inbuf+s*rowsize, row, s) < 0)
					 return (-1);
			compresssep(outbuf,
			    inbuf, inbuf+rowsize, inbuf+2*rowsize, w);
			if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
				break;
		}
		break;
	}
#undef pack
	TIFFClose(out);
	return (0);
}
Esempio n. 6
0
void PLTIFFDecoder::doLoColor (TIFF * tif, PLBmpBase * pBmp)
{
  uint16  BitsPerSample;
  uint16  SamplePerPixel;
  int32  LineSize;
  int16  PhotometricInterpretation;
  int  row;
  PLBYTE  *pBits;

  TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
  TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel);
  TIFFGetFieldDefaulted(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);

  if (PhotometricInterpretation!=PHOTOMETRIC_MINISWHITE &&
      PhotometricInterpretation!=PHOTOMETRIC_MINISBLACK &&
      PhotometricInterpretation!=PHOTOMETRIC_PALETTE)
  {
    PhotometricInterpretation = PHOTOMETRIC_MINISWHITE;
    Trace(2,"unexpected PhotometricInterpretation, default to PHOTOMETRIC_MINISWHITE");
  }

  LineSize = TIFFScanlineSize(tif); //Number of bytes in one line

  PLPixel32 pPal[256];

  pBits = new PLBYTE [LineSize]; // enough for 16-bits per pixel
  if (pBits == NULL)
    raiseError (PL_ERRNO_MEMORY, "Out of memory allocating TIFF buffer.");

  // phase one: build color map
  if (BitsPerSample < 16) {
    if /* monochrome (=bitonal) or grayscale */
      (PhotometricInterpretation == PHOTOMETRIC_MINISWHITE ||
       PhotometricInterpretation == PHOTOMETRIC_MINISBLACK)
      {
        int numColors = 1 << BitsPerSample;
        PLBYTE step = static_cast<PLBYTE>(255 / (numColors-1));
        PLBYTE *pb = (PLBYTE *) (pPal);
        int offset = sizeof(PLPixel32);
        if (PhotometricInterpretation == PHOTOMETRIC_MINISWHITE)
        {
          pb += (numColors-1) * sizeof(PLPixel32);
          offset = -offset;
        }
        // warning: the following ignores possible halftone hints
        for (int i = 0; i < numColors; ++i, pb += offset)
        {
          pb[PL_RGBA_RED] = pb[PL_RGBA_GREEN] = pb[PL_RGBA_BLUE] = static_cast<PLBYTE>(i * step);
          pb[PL_RGBA_ALPHA] = 255;
        }

      }
    //PhotometricInterpretation = 2 image is RGB
    //PhotometricInterpretation = 3 image has a color palette
    else if (PhotometricInterpretation == PHOTOMETRIC_PALETTE)
    {
      uint16* red;
      uint16* green;
      uint16* blue;
      int16 Palette16Bits;

      // we get pointers to libtiff-owned colormaps
      TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);

      //Is the palette 16 or 8 bits ?
      Palette16Bits = checkcmap(1<<BitsPerSample, red, green, blue) == 16;

      //load the palette in the DIB
      for (int i = 0; i < 1<<BitsPerSample; ++i)
      {
        PLBYTE *pb = (PLBYTE *) ((pPal)+i);
        pb[PL_RGBA_RED  ] = (PLBYTE) (Palette16Bits ? CVT(  red[i]) :   red[i]);
        pb[PL_RGBA_GREEN] = (PLBYTE) (Palette16Bits ? CVT(green[i]) : green[i]);
        pb[PL_RGBA_BLUE ] = (PLBYTE) (Palette16Bits ? CVT( blue[i]) :  blue[i]);
        pb[PL_RGBA_ALPHA] = 255;
      }
    }
    else
      Trace( 2, "unexpected PhotometricInterpretation in PLTIFFDecoder::DoLoColor()" );
  }
  // phase two: read image itself

  //generally, TIFF images are ordered from upper-left to bottom-right
  // we implicitly assume PLANARCONFIG_CONTIG
  PLBYTE **pLineArray = pBmp->GetLineArray();  

  if (BitsPerSample > 16)
    Trace( 2, "unexpected bit-depth in PLTIFFDecoder::DoLoColor()" );
  else for ( row = 0; row < GetHeight(); ++row )
    {
      uint16 x;
      int status = TIFFReadScanline( tif, pBits, row, 0 );
      if (status == -1 && row < GetHeight()  / 3)
      {
        delete [] pBits;
        // we should maybe free the BMP memory as well...
        raiseError (PL_ERRINTERNAL, m_szLastErr);
      }
      /*
      if (BitsPerSample == 1)  // go ahead, waste space ;-)
        for (x=0; x < imageWidth; ++x)
          pLineArray[row][x] = pBits[x / 8] & (128 >> (x & 7)) ? 1 : 0;
      else */
      if (BitsPerSample == 4)
      {
        for (x=0; x < GetWidth() / 2; ++x)
        {
          pLineArray[row][2*x  ] = (pBits[x] & 0xf0) >> 4;
          pLineArray[row][2*x+1] = (pBits[x] & 0x0f);
        }
        // odd number of pixels
        if (GetWidth() & 1)
          pLineArray[row][GetWidth()-1] = (pBits[x] & 0xf0) >> 4;
      } else if (BitsPerSample == 16) {
          PLASSERT (SamplePerPixel == 1); // can't do 16-bit with alpha yet
          PLPixel16 **pLineArray16 = pBmp->GetLineArray16();
          memcpy( pLineArray16[row], pBits, LineSize );
      } else //if (BitsPerSample == 8 || BitsPerSample == 1)
        if (SamplePerPixel == 1)
          memcpy( pLineArray[row], pBits, LineSize );
        else
        {
          // We've got an 8 bit image with an alpha channel.
          // Ignore the alpha channel.
          PLASSERT (BitsPerSample == 8);
          for (x=0; x < GetWidth(); ++x)
            pLineArray[row][x] = pBits[x*2];
        }
    }
Esempio n. 7
0
HDIB LoadTIFFinDIB(LPSTR lpFileName)
{
    TIFF          *tif;
    unsigned long imageLength;
    unsigned long imageWidth;
    unsigned int  BitsPerSample;
    unsigned long LineSize;
    unsigned int  SamplePerPixel;
    unsigned long RowsPerStrip;
    int           PhotometricInterpretation;
    long          nrow;
    unsigned long row;
    char          *buf;
    LPBITMAPINFOHEADER lpDIB;
    HDIB          hDIB;
    char          *lpBits;
    HGLOBAL       hStrip;
    int           i,l;
    int           Align;

    tif = TIFFOpen(lpFileName, "r");

    if (!tif)
        goto TiffOpenError;

    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
    TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);

    LineSize = TIFFScanlineSize(tif); //Number of byte in ine line

    SamplePerPixel = (int) (LineSize/imageWidth);

    //Align = Number of byte to add at the end of each line of the DIB
    Align = 4 - (LineSize % 4);
    if (Align == 4)	Align = 0;


    //Create a new DIB
    hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
                     (BitsPerSample*SamplePerPixel));
    lpDIB  = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
    if (!lpDIB)
        goto OutOfDIBMemory;

    if (lpDIB)
        lpBits = FindDIBBits((LPSTR) lpDIB);

    //In the tiff file the lines are save from up to down
    //In a DIB the lines must be save from down to up
    if (lpBits)
    {
        lpBits = FindDIBBits((LPSTR) lpDIB);
        lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
        //now lpBits pointe on the bottom line

        hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
        buf = GlobalLock(hStrip);

        if (!buf)
            goto OutOfBufMemory;

        //PhotometricInterpretation = 2 image is RGB
        //PhotometricInterpretation = 3 image have a color palette
        if (PhotometricInterpretation == 3)
        {
            uint16* red;
            uint16* green;
            uint16* blue;
            int16 i;
            LPBITMAPINFO lpbmi;
            int   Palette16Bits;

            TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue);

            //Is the palette 16 or 8 bits ?
            if (checkcmap(1<<BitsPerSample, red, green, blue) == 16)
                Palette16Bits = TRUE;
            else
                Palette16Bits = FALSE;

            lpbmi = (LPBITMAPINFO)lpDIB;

            //load the palette in the DIB
            for (i = (1<<BitsPerSample)-1; i >= 0; i--)
            {
                if (Palette16Bits)
                {
                    lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]);
                    lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]);
                    lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]);
                }
                else
                {
                    lpbmi->bmiColors[i].rgbRed = (BYTE) red[i];
                    lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i];
                    lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i];
                }
            }

        }

        //read the tiff lines and save them in the DIB
        //with RGB mode, we have to change the order of the 3 samples RGB
        <=> BGR
        for (row = 0; row < imageLength; row += RowsPerStrip)
        {
            nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
                    RowsPerStrip);
            if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
                                     buf, nrow*LineSize)==-1)
            {
                goto TiffReadError;
            }
            else
            {
                for (l = 0; l < nrow; l++)
                {
                    if (SamplePerPixel  == 3)
                        for (i=0; i< (int) (imageWidth); i++)
                        {
                            lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
                                                           PerPixel+2];
                            lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
                                                           PerPixel+1];
                            lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
                                                           PerPixel+0];
                        }
                    else
                        memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
                               imageWidth*SamplePerPixel);

                    lpBits-=imageWidth*SamplePerPixel+Align;

                }
            }
        }
        GlobalUnlock(hStrip);
        GlobalFree(hStrip);
        GlobalUnlock(hDIB);
        TIFFClose(tif);
    }
Esempio n. 8
0
boolean TIFFRasterImpl::gt(u_long w, u_long h) {
    u_short minsamplevalue;
    u_short maxsamplevalue;
    u_short planarconfig;
    RGBvalue* Map = nil;

    if (!TIFFGetField(tif_, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue)) {
	minsamplevalue = 0;
    }
    if (!TIFFGetField(tif_, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue)) {
	maxsamplevalue = (1<<bitspersample_)-1;
    }
    switch (photometric_) {
    case PHOTOMETRIC_RGB:
	if (minsamplevalue == 0 && maxsamplevalue == 255) {
	    break;
	}
	/* fall thru... */
    case PHOTOMETRIC_MINISBLACK:
    case PHOTOMETRIC_MINISWHITE: {
	register int x, range;

	range = maxsamplevalue - minsamplevalue;
	Map = new RGBvalue[range + 1];
	if (Map == nil) {
	    TIFFError(
		TIFFFileName(tif_),
		"No space for photometric conversion table"
	    );
	    return false;
	}
	if (photometric_ == PHOTOMETRIC_MINISWHITE) {
	    for (x = 0; x <= range; x++) {
		Map[x] = ((range - x) * 255) / range;
	    }
	} else {
	    for (x = 0; x <= range; x++) {
		Map[x] = (x * 255) / range;
	    }
	}
	if (photometric_ != PHOTOMETRIC_RGB && bitspersample_ != 8) {
	    /*
	     * Use photometric mapping table to construct
	     * unpacking tables for samples < 8 bits.
	     */
	    if (!makebwmap(Map)) {
		return false;
	    }
	    delete Map;			/* no longer need Map, free it */
	    Map = nil;
	}
	break;
    }
    case PHOTOMETRIC_PALETTE:
	if (!TIFFGetField(
	    tif_, TIFFTAG_COLORMAP, &redcmap_, &greencmap_, &bluecmap_)
	) {
	    TIFFError(TIFFFileName(tif_), "Missing required \"Colormap\" tag");
	    return (false);
	}
	/*
	 * Convert 16-bit colormap to 8-bit (unless it looks
	 * like an old-style 8-bit colormap).
	 */
	if (
	    checkcmap(
		1 << bitspersample_, redcmap_, greencmap_, bluecmap_
	    ) == 16
	) {
	    int i;
	    for (i = (1 << bitspersample_) - 1; i > 0; i--) {
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
		redcmap_[i] = (u_short) CVT(redcmap_[i]);
		greencmap_[i] = (u_short) CVT(greencmap_[i]);
		bluecmap_[i] = (u_short) CVT(bluecmap_[i]);
	    }
	}
	if (bitspersample_ <= 8) {
	    /*
	     * Use mapping table and colormap to construct
	     * unpacking tables for samples < 8 bits.
	     */
	    if (!makecmap(redcmap_, greencmap_, bluecmap_)) {
		return false;
	    }
	}
	break;
    }
    TIFFGetField(tif_, TIFFTAG_PLANARCONFIG, &planarconfig);
    boolean e;
    if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel_ > 1) {
	e = TIFFIsTiled(tif_) ?
	    gtTileSeparate(Map, h, w) : gtStripSeparate(Map, h, w);
    } else {
	e = TIFFIsTiled(tif_) ? 
	    gtTileContig(Map, h, w) : gtStripContig(Map, h, w);
    }
    delete Map;
    return e;
}
Esempio n. 9
0
static void
PS_Lvl2colorspace(FILE* fd, TIFF* tif)
{
	uint16 *rmap, *gmap, *bmap;
	int i, num_colors;
	const char * colorspace_p;

	switch ( photometric )
	{
	case PHOTOMETRIC_SEPARATED:
		colorspace_p = "CMYK";
		break;

	case PHOTOMETRIC_RGB:
		colorspace_p = "RGB";
		break;

	default:
		colorspace_p = "Gray";
	}

	/*
	 * Set up PostScript Level 2 colorspace according to
	 * section 4.8 in the PostScript refenence manual.
	 */
	fputs("% PostScript Level 2 only.\n", fd);
	if (photometric != PHOTOMETRIC_PALETTE) {
		if (photometric == PHOTOMETRIC_YCBCR) {
		    /* MORE CODE HERE */
		}
		fprintf(fd, "/Device%s setcolorspace\n", colorspace_p );
		return;
	}

	/*
	 * Set up an indexed/palette colorspace
	 */
	num_colors = (1 << bitspersample);
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		TIFFError(filename,
			"Palette image w/o \"Colormap\" tag");
		return;
	}
	if (checkcmap(tif, num_colors, rmap, gmap, bmap) == 16) {
		/*
		 * Convert colormap to 8-bits values.
		 */
#define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
		for (i = 0; i < num_colors; i++) {
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
#undef CVT
	}
	fprintf(fd, "[ /Indexed /DeviceRGB %d", num_colors - 1);
	if (ascii85) {
		Ascii85Init();
		fputs("\n<~", fd);
		ascii85breaklen -= 2;
	} else
		fputs(" <", fd);
	for (i = 0; i < num_colors; i++) {
		if (ascii85) {
			Ascii85Put(rmap[i], fd);
			Ascii85Put(gmap[i], fd);
			Ascii85Put(bmap[i], fd);
		} else {
			fputs((i % 8) ? " " : "\n  ", fd);
			fprintf(fd, "%02x%02x%02x",
			    rmap[i], gmap[i], bmap[i]);
		}
	}
	if (ascii85)
		Ascii85Flush(fd);
	else
		fputs(">\n", fd);
	fputs("] setcolorspace\n", fd);
}
Esempio n. 10
0
void
PSDataPalette(FILE* fd, TIFF* tif, uint32 w, uint32 h)
{
	uint16 *rmap, *gmap, *bmap;
	uint32 row;
	int breaklen = MAXLINE, cc, nc;
	unsigned char *tf_buf;
	unsigned char *cp, c;

	(void) w;
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
		TIFFError(filename, "Palette image w/o \"Colormap\" tag");
		return;
	}
	switch (bitspersample) {
	case 8:	case 4: case 2: case 1:
		break;
	default:
		TIFFError(filename, "Depth %d not supported", bitspersample);
		return;
	}
	nc = 3 * (8 / bitspersample);
	tf_buf = (unsigned char *) _TIFFmalloc(tf_bytesperrow);
	if (tf_buf == NULL) {
		TIFFError(filename, "No space for scanline buffer");
		return;
	}
	if (checkcmap(tif, 1<<bitspersample, rmap, gmap, bmap) == 16) {
		int i;
#define	CVT(x)		(((x) * 255) / ((1U<<16)-1))
		for (i = (1<<bitspersample)-1; i >= 0; i--) {
			rmap[i] = CVT(rmap[i]);
			gmap[i] = CVT(gmap[i]);
			bmap[i] = CVT(bmap[i]);
		}
#undef CVT
	}
	for (row = 0; row < h; row++) {
		if (TIFFReadScanline(tif, tf_buf, row, 0) < 0)
			break;
		for (cp = tf_buf, cc = 0; cc < tf_bytesperrow; cc++) {
			DOBREAK(breaklen, nc, fd);
			switch (bitspersample) {
			case 8:
				c = *cp++; PUTRGBHEX(c, fd);
				break;
			case 4:
				c = *cp++; PUTRGBHEX(c&0xf, fd);
				c >>= 4;   PUTRGBHEX(c, fd);
				break;
			case 2:
				c = *cp++; PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c&0x3, fd);
				c >>= 2;   PUTRGBHEX(c, fd);
				break;
			case 1:
				c = *cp++; PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c&0x1, fd);
				c >>= 1;   PUTRGBHEX(c, fd);
				break;
			}
		}
	}
	_TIFFfree((char *) tf_buf);
}