source: GTP/trunk/Lib/Vis/Preprocessing/src/mixkit/MxRaster-tiff.cxx @ 1097

Revision 1097, 3.6 KB checked in by mattausch, 18 years ago (diff)
Line 
1/************************************************************************
2
3  TIFF support is optional.  Only PNM support is guaranteed to be
4  available.  Since it is optional, the TIFF code is contained here in a
5  separate source file.
6
7  Copyright (C) 1998 Michael Garland.  See "COPYING.txt" for details.
8 
9  $Id: MxRaster-tiff.cxx,v 1.1 2002/09/24 16:53:54 wimmer Exp $
10
11 ************************************************************************/
12
13#include "stdmix.h"
14#include "MxRaster.h"
15
16
17#ifdef MIX_HAVE_LIBTIFF
18#include <tiffio.h>
19
20////////////////////////////////////////////////////////////////////////
21//
22// TIFF output
23//
24static
25bool __tiff_write(TIFF *tif, const MxRaster& img)
26{
27    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, img.width());
28    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, img.height());
29
30    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
31    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, img.channels());
32    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
33    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
34    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
35
36    // Turn on LZW compression.  Shhhhh!  Don't tell Unisys!
37    TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
38    //
39    // Predictors:
40    //     1 (default) -- No predictor
41    //     2           -- Horizontal differencing
42    TIFFSetField(tif, TIFFTAG_PREDICTOR, 2);
43
44    uint32 scanline_size = img.channels() * img.width();
45    if( TIFFScanlineSize(tif) != scanline_size )
46    {
47        mxmsg_signal(MXMSG_WARN,
48                     "Mismatch with library's expected scanline size!",
49                     "tiff_write");
50        return false;
51    }
52
53    TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, -1));
54
55    char *scanline_buf = new char[scanline_size];
56
57    const unsigned char *scanline = img;
58    for(uint32 y=0; y<img.height(); y++)
59    {
60        memcpy(scanline_buf, scanline, scanline_size);
61        // NOTE: TIFFWriteScanline modifies the buffer you pass it.
62        //       Thus, we need to copy stuff out of the raster first.
63        TIFFWriteScanline(tif, scanline_buf, y, 0);
64        scanline += scanline_size;
65    }
66    delete[] scanline_buf;
67
68    return true;
69}
70
71bool tiff_write(const char *filename, const MxRaster& img)
72{
73    TIFF *tif = TIFFOpen(filename, "w");
74    if( !tif ) return false;
75
76    bool result = __tiff_write(tif, img);
77
78    TIFFClose(tif);
79
80    return result;
81}
82
83////////////////////////////////////////////////////////////////////////
84//
85// TIFF input
86//
87static
88void unpack_tiff_raster(uint32 *raster, MxRaster *img, uint npixels)
89{
90    unsigned char *pix = img[0];
91   
92    for(uint i=0; i<npixels; i++)
93    {
94        *pix++ = TIFFGetR(raster[i]);
95        *pix++ = TIFFGetG(raster[i]);
96        *pix++ = TIFFGetB(raster[i]);
97    }
98}
99
100static
101MxRaster *__tiff_read(TIFF *tif)
102{
103    uint32 w, h;
104    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
105    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
106
107    uint npixels = w*h;
108
109    uint32 *raster = (uint32 *)_TIFFmalloc(npixels * sizeof(uint32));
110    if( !raster ) return NULL;
111
112    TIFFReadRGBAImage(tif, w, h, raster, true);
113
114    MxRaster *img = new MxRaster(w, h, 3);
115    unpack_tiff_raster(raster, img, npixels);
116
117    _TIFFfree(raster);
118
119    return img;
120}
121
122MxRaster *tiff_read(const char *filename)
123{
124    TIFF *tif = TIFFOpen(filename, "r");
125    if( !tif ) return NULL;
126
127    MxRaster *img = __tiff_read(tif);
128
129    TIFFClose(tif);
130
131    return img;
132}
133
134#else
135
136bool tiff_write(const char *, const MxRaster&) { return false; }
137MxRaster *tiff_read(const char *) { return NULL; }
138
139#endif
Note: See TracBrowser for help on using the repository browser.