~ubuntu-branches/ubuntu/karmic/tiff/karmic-security

« back to all changes in this revision

Viewing changes to contrib/ras/tif2ras.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabio M. Di Nitto
  • Date: 2004-10-14 07:57:59 UTC
  • Revision ID: james.westby@ubuntu.com-20041014075759-a77e7zuaetya8cp0
Tags: upstream-3.6.1
ImportĀ upstreamĀ versionĀ 3.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef lint
 
2
static char id[] = "$Id: tif2ras.c,v 1.2 1999/11/28 20:15:36 mwelles Exp $"; 
 
3
#endif
 
4
/*-
 
5
 * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster.
 
6
 *
 
7
 * Copyright (c) 1990 by Sun Microsystems, Inc.
 
8
 *
 
9
 * Author: Patrick J. Naughton
 
10
 * naughton@wind.sun.com
 
11
 *
 
12
 * Permission to use, copy, modify, and distribute this software and its
 
13
 * documentation for any purpose and without fee is hereby granted,
 
14
 * provided that the above copyright notice appear in all copies and that
 
15
 * both that copyright notice and this permission notice appear in
 
16
 * supporting documentation.
 
17
 *
 
18
 * This file is provided AS IS with no warranties of any kind.  The author
 
19
 * shall have no liability with respect to the infringement of copyrights,
 
20
 * trade secrets or any patents by this file or any part thereof.  In no
 
21
 * event will the author be liable for any lost revenue or profits or
 
22
 * other special, indirect and consequential damages.
 
23
 *
 
24
 * Comments and additions should be sent to the author:
 
25
 *
 
26
 *                     Patrick J. Naughton
 
27
 *                     Sun Microsystems
 
28
 *                     2550 Garcia Ave, MS 14-40
 
29
 *                     Mountain View, CA 94043
 
30
 *                     (415) 336-1080
 
31
 *
 
32
 * Revision History:
 
33
 * 10-Jan-89: Created.
 
34
 * 06-Mar-90: Change to byte encoded rasterfiles.
 
35
 *            fix bug in call to ReadScanline().
 
36
 *            fix bug in CVT() macro.
 
37
 *            fix assignment of td, (missing &).
 
38
 *
 
39
 * Description:
 
40
 *   This program takes a MicroSoft/Aldus "Tagged Image File Format" image or
 
41
 * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)].  The
 
42
 * output file may be standard output, but the input TIFF file must be a real
 
43
 * file since seek(2) is used.
 
44
 */
 
45
 
 
46
#include <stdio.h>
 
47
#include <pixrect/pixrect_hs.h>
 
48
#include "tiffio.h"
 
49
 
 
50
typedef int boolean;
 
51
#define True (1)
 
52
#define False (0)
 
53
#define CVT(x)          (((x) * 255) / ((1L<<16)-1))
 
54
 
 
55
boolean     Verbose = False;
 
56
char       *pname;              /* program name (used for error messages) */
 
57
 
 
58
void
 
59
error(s1, s2)
 
60
    char       *s1,
 
61
               *s2;
 
62
{
 
63
    fprintf(stderr, s1, pname, s2);
 
64
    exit(1);
 
65
}
 
66
 
 
67
void
 
68
usage()
 
69
{
 
70
    error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
 
71
}
 
72
 
 
73
 
 
74
main(argc, argv)
 
75
    int         argc;
 
76
    char       *argv[];
 
77
{
 
78
    char       *inf = NULL;
 
79
    char       *outf = NULL;
 
80
    FILE       *fp;
 
81
    long        width,
 
82
                height;
 
83
    int         depth,
 
84
                numcolors;
 
85
    register TIFF *tif;
 
86
    TIFFDirectory *td;
 
87
    register u_char *inp,
 
88
               *outp;
 
89
    register int col,
 
90
                i;
 
91
    register long row;
 
92
    u_char     *Map = NULL;
 
93
    u_char     *buf;
 
94
    short       bitspersample;
 
95
    short       samplesperpixel;
 
96
    short       photometric;
 
97
    u_short    *redcolormap,
 
98
               *bluecolormap,
 
99
               *greencolormap;
 
100
 
 
101
    Pixrect    *pix;            /* The Sun Pixrect */
 
102
    colormap_t  Colormap;       /* The Pixrect Colormap */
 
103
    u_char      red[256],
 
104
                green[256],
 
105
                blue[256];
 
106
 
 
107
    setbuf(stderr, NULL);
 
108
    pname = argv[0];
 
109
 
 
110
    while (--argc) {
 
111
        if ((++argv)[0][0] == '-')
 
112
            switch (argv[0][1]) {
 
113
            case 'v':
 
114
                Verbose = True;
 
115
                break;
 
116
            case 'q':
 
117
                usage();
 
118
                break;
 
119
            default:
 
120
                fprintf(stderr, "%s: illegal option -%c.\n", pname,
 
121
                        argv[0][1]);
 
122
                exit(1);
 
123
            }
 
124
        else if (inf == NULL)
 
125
            inf = argv[0];
 
126
        else if (outf == NULL)
 
127
            outf = argv[0];
 
128
        else
 
129
            usage();
 
130
 
 
131
    }
 
132
 
 
133
    if (inf == NULL)
 
134
        error("%s: can't read input file from a stream.\n", NULL);
 
135
 
 
136
    if (Verbose)
 
137
        fprintf(stderr, "Reading %s...", inf);
 
138
 
 
139
    tif = TIFFOpen(inf, "r");
 
140
 
 
141
    if (tif == NULL)
 
142
        error("%s: error opening TIFF file %s", inf);
 
143
 
 
144
    if (Verbose)
 
145
        TIFFPrintDirectory(tif, stderr, True, False, False);
 
146
    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
 
147
    if (bitspersample > 8)
 
148
        error("%s: can't handle more than 8-bits per sample\n", NULL);
 
149
 
 
150
    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
 
151
    switch (samplesperpixel) {
 
152
    case 1:
 
153
        if (bitspersample == 1)
 
154
            depth = 1;
 
155
        else
 
156
            depth = 8;
 
157
        break;
 
158
    case 3:
 
159
    case 4:
 
160
        depth = 24;
 
161
        break;
 
162
    default:
 
163
        error("%s: only handle 1-channel gray scale or 3-channel color\n");
 
164
    }
 
165
 
 
166
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
 
167
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
 
168
 
 
169
    if (Verbose)
 
170
        fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
 
171
    if (Verbose)
 
172
        fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
 
173
                bitspersample, samplesperpixel);
 
174
 
 
175
    pix = mem_create(width, height, depth);
 
176
    if (pix == (Pixrect *) NULL)
 
177
        error("%s: can't allocate memory for output pixrect...\n", NULL);
 
178
 
 
179
    numcolors = (1 << bitspersample);
 
180
 
 
181
    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
 
182
    if (numcolors == 2) {
 
183
        if (Verbose)
 
184
            fprintf(stderr, "monochrome ");
 
185
        Colormap.type = RMT_NONE;
 
186
        Colormap.length = 0;
 
187
        Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
 
188
    } else {
 
189
        switch (photometric) {
 
190
        case PHOTOMETRIC_MINISBLACK:
 
191
            if (Verbose)
 
192
                fprintf(stderr, "%d graylevels (min=black), ", numcolors);
 
193
            Map = (u_char *) malloc(numcolors * sizeof(u_char));
 
194
            for (i = 0; i < numcolors; i++)
 
195
                Map[i] = (255 * i) / numcolors;
 
196
            Colormap.type = RMT_EQUAL_RGB;
 
197
            Colormap.length = numcolors;
 
198
            Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
 
199
            break;
 
200
        case PHOTOMETRIC_MINISWHITE:
 
201
            if (Verbose)
 
202
                fprintf(stderr, "%d graylevels (min=white), ", numcolors);
 
203
            Map = (u_char *) malloc(numcolors * sizeof(u_char));
 
204
            for (i = 0; i < numcolors; i++)
 
205
                Map[i] = 255 - ((255 * i) / numcolors);
 
206
            Colormap.type = RMT_EQUAL_RGB;
 
207
            Colormap.length = numcolors;
 
208
            Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
 
209
            break;
 
210
        case PHOTOMETRIC_RGB:
 
211
            if (Verbose)
 
212
                fprintf(stderr, "truecolor ");
 
213
            Colormap.type = RMT_NONE;
 
214
            Colormap.length = 0;
 
215
            Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
 
216
            break;
 
217
        case PHOTOMETRIC_PALETTE:
 
218
            if (Verbose)
 
219
                fprintf(stderr, "colormapped ");
 
220
            Colormap.type = RMT_EQUAL_RGB;
 
221
            Colormap.length = numcolors;
 
222
            memset(red, 0, sizeof(red));
 
223
            memset(green, 0, sizeof(green));
 
224
            memset(blue, 0, sizeof(blue));
 
225
            TIFFGetField(tif, TIFFTAG_COLORMAP,
 
226
                &redcolormap, &greencolormap, &bluecolormap);
 
227
            for (i = 0; i < numcolors; i++) {
 
228
                red[i] = (u_char) CVT(redcolormap[i]);
 
229
                green[i] = (u_char) CVT(greencolormap[i]);
 
230
                blue[i] = (u_char) CVT(bluecolormap[i]);
 
231
            }
 
232
            Colormap.map[0] = red;
 
233
            Colormap.map[1] = green;
 
234
            Colormap.map[2] = blue;
 
235
            break;
 
236
        case PHOTOMETRIC_MASK:
 
237
            error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
 
238
            break;
 
239
        case PHOTOMETRIC_DEPTH:
 
240
            error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
 
241
            break;
 
242
        default:
 
243
            error("%s: unknown photometric (cmap): %d\n", photometric);
 
244
        }
 
245
    }
 
246
 
 
247
    buf = (u_char *) malloc(TIFFScanlineSize(tif));
 
248
    if (buf == NULL)
 
249
        error("%s: can't allocate memory for scanline buffer...\n", NULL);
 
250
 
 
251
    for (row = 0; row < height; row++) {
 
252
        if (TIFFReadScanline(tif, buf, row, 0) < 0)
 
253
            error("%s: bad data read on line: %d\n", row);
 
254
        inp = buf;
 
255
        outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
 
256
        switch (photometric) {
 
257
        case PHOTOMETRIC_RGB:
 
258
            if (samplesperpixel == 4)
 
259
                for (col = 0; col < width; col++) {
 
260
                    *outp++ = *inp++;   /* Blue */
 
261
                    *outp++ = *inp++;   /* Green */
 
262
                    *outp++ = *inp++;   /* Red */
 
263
                    inp++;      /* skip alpha channel */
 
264
                }
 
265
            else
 
266
                for (col = 0; col < width; col++) {
 
267
                    *outp++ = *inp++;   /* Blue */
 
268
                    *outp++ = *inp++;   /* Green */
 
269
                    *outp++ = *inp++;   /* Red */
 
270
                }
 
271
            break;
 
272
        case PHOTOMETRIC_MINISWHITE:
 
273
        case PHOTOMETRIC_MINISBLACK:
 
274
            switch (bitspersample) {
 
275
            case 1:
 
276
                for (col = 0; col < ((width + 7) / 8); col++)
 
277
                    *outp++ = *inp++;
 
278
                break;
 
279
            case 2:
 
280
                for (col = 0; col < ((width + 3) / 4); col++) {
 
281
                    *outp++ = (*inp >> 6) & 3;
 
282
                    *outp++ = (*inp >> 4) & 3;
 
283
                    *outp++ = (*inp >> 2) & 3;
 
284
                    *outp++ = *inp++ & 3;
 
285
                }
 
286
                break;
 
287
            case 4:
 
288
                for (col = 0; col < width / 2; col++) {
 
289
                    *outp++ = *inp >> 4;
 
290
                    *outp++ = *inp++ & 0xf;
 
291
                }
 
292
                break;
 
293
            case 8:
 
294
                for (col = 0; col < width; col++)
 
295
                    *outp++ = *inp++;
 
296
                break;
 
297
            default:
 
298
                error("%s: bad bits/sample: %d\n", bitspersample);
 
299
            }
 
300
            break;
 
301
        case PHOTOMETRIC_PALETTE:
 
302
            memcpy(outp, inp, width);
 
303
            break;
 
304
        default:
 
305
            error("%s: unknown photometric (write): %d\n", photometric);
 
306
        }
 
307
    }
 
308
 
 
309
    free((char *) buf);
 
310
 
 
311
    if (Verbose)
 
312
        fprintf(stderr, "done.\n");
 
313
 
 
314
    if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
 
315
        outf = "Standard Output";
 
316
        fp = stdout;
 
317
    } else {
 
318
        if (!(fp = fopen(outf, "w")))
 
319
            error("%s: %s couldn't be opened for writing.\n", outf);
 
320
    }
 
321
 
 
322
    if (Verbose)
 
323
        fprintf(stderr, "Writing rasterfile in %s...", outf);
 
324
 
 
325
    if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
 
326
        error("%s: error writing Sun Rasterfile: %s\n", outf);
 
327
 
 
328
    if (Verbose)
 
329
        fprintf(stderr, "done.\n");
 
330
 
 
331
    pr_destroy(pix);
 
332
 
 
333
    if (fp != stdout)
 
334
        fclose(fp);
 
335
 
 
336
    exit(0);
 
337
}