source: trunk/src/testing/app/bitplay/libimg/tiffdata.c @ 4

Revision 4, 11.5 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

  • Property svn:executable set to *
Line 
1/******************************************************************************
2 * SAGE - Scalable Adaptive Graphics Environment
3 *
4 * Copyright (C) 2004 Electronic Visualization Laboratory,
5 * University of Illinois at Chicago
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above
15 *    copyright notice, this list of conditions and the following disclaimer
16 *    in the documentation and/or other materials provided with the distribution.
17 *  * Neither the name of the University of Illinois at Chicago nor
18 *    the names of its contributors may be used to endorse or promote
19 *    products derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Direct questions, comments etc about SAGE to http://www.evl.uic.edu/cavern/forum/
34 *
35 *****************************************************************************/
36
37#ifndef lint
38static char sccsid[] = "@(#)sgigt.c     1.8 4/25/89";
39#endif
40
41#include <stdio.h>
42#include <gl.h>
43#include <gl/device.h>
44#include "tiffio.h"
45#include "imginfo.h"
46
47static u_long   *raster;                        /* displayable image */
48static u_short  bitspersample;
49static u_short  samplesperpixel;
50static u_short  photometric;
51static u_short  orientation;
52static u_short  *redcmap, *greencmap, *bluecmap;/* colormap for palette images */
53
54#define rgba(r, g, b, a)        ((a)<<24 | (b)<<16 | (g)<<8 | (r))
55#define rgbi(r, g, b)           (0xFF000000 | (b)<<16 | (g)<<8 | (r))
56
57IMG *
58TIFFmakedisp(fname)
59        char *fname;
60{
61        TIFF *tif;
62        short width, height;
63        register IMG *im;
64
65        tif = TIFFOpen(fname, "r");
66        if(tif == NULL)
67            return NULL;
68
69        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
70        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
71        im = (IMG *)malloc(sizeof(IMG));
72        im->type = IT_LONG;
73        im->rowbytes = sizeof(long) * width;
74        im->xsize = width;
75        im->ysize = height;
76        im->data = (unsigned char *)malloc(im->rowbytes * height);
77        if(im->data == NULL) {
78            fprintf(stderr, "Can't malloc %d bytes of memory for image\n",
79                im->rowbytes * height);
80            exit(2);
81        }
82        if(tiffgt(tif, width, height, (u_long *)im->data) == 0) {
83            free(im->data);
84            free(im);
85            im = NULL;
86        }
87        TIFFClose(tif);
88        return im;
89}
90
91RGBvalue **BWmap;
92
93static
94tiffgt(tif, w, h, raster)
95        TIFF *tif;
96        int w, h;
97        u_long *raster;
98{
99        u_short minsamplevalue, maxsamplevalue, planarconfig;
100        RGBvalue *Map;
101        int e;
102
103        if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
104                switch (samplesperpixel) {
105                case 1:
106                        photometric = PHOTOMETRIC_MINISBLACK;
107                        break;
108                case 3: case 4:
109                        photometric = PHOTOMETRIC_RGB;
110                        break;
111                default:
112                        fprintf(stderr, "Missing needed \"%s\" tag.\n",
113                            "PhotometricInterpretation");
114                        return (0);
115                }
116                printf("No \"PhotometricInterpretation\" tag, assuming %s.\n",
117                    photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
118        }
119        if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel))
120                samplesperpixel = 1;
121        if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample))
122                bitspersample = 8;
123        if (!TIFFGetField(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue))
124                minsamplevalue = 0;
125        if (!TIFFGetField(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue))
126                maxsamplevalue = (1<<bitspersample)-1;
127        Map = NULL;
128        switch (photometric) {
129        case PHOTOMETRIC_RGB:
130        case PHOTOMETRIC_MINISBLACK:
131                if (minsamplevalue == 0 && maxsamplevalue == 255)
132                        break;
133                /* fall thru... */
134        case PHOTOMETRIC_MINISWHITE: {
135                register int x, range;
136
137                range = maxsamplevalue - minsamplevalue + 1;
138                Map = (RGBvalue *)malloc(range * sizeof (RGBvalue));
139                if (Map == NULL) {
140                        fprintf(stderr,
141                            "No space for photometric conversion table.\n");
142                        return (0);
143                }
144                if (photometric == PHOTOMETRIC_MINISWHITE) {
145                        for (x = 0; x < range; x++)
146                                Map[x] = ((range - x) * 255) / range;
147                } else {
148                        for (x = 0; x < range; x++)
149                                Map[x] = (x * 255) / range;
150                }
151                if (bitspersample < 8 && photometric != PHOTOMETRIC_RGB) {
152                        if (!makebwmap(Map))
153                                return (0);
154                        /* no longer need Map, free it */
155                        free((char *)Map);
156                        Map = NULL;
157                }
158                break;
159        }
160        case PHOTOMETRIC_PALETTE:
161                if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
162                    &redcmap, &greencmap, &bluecmap)) {
163                        fprintf(stderr, "Missing required \"Colormap\" tag.\n");
164                        return (0);
165                }
166                break;
167        }
168        TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
169        if (planarconfig == PLANARCONFIG_SEPARATE)
170                e = gtseparate(tif, raster, Map, h, w);
171        else
172                e = gtcontig(tif, raster, Map, h, w);
173        if (Map)
174                free((char *)Map);
175        return (e);
176}
177
178setorientation(tif, h)
179        TIFF *tif;
180        int h;
181{
182        int y;
183
184        if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation))
185                orientation = ORIENTATION_TOPLEFT;
186        switch (orientation) {
187        case ORIENTATION_BOTRIGHT:
188        case ORIENTATION_RIGHTBOT:      /* XXX */
189        case ORIENTATION_LEFTBOT:       /* XXX */
190                printf("Warning, using bottom-left orientation.\n");
191                orientation = ORIENTATION_BOTLEFT;
192                /* fall thru... */
193        case ORIENTATION_BOTLEFT:
194                y = 0;
195                break;
196        case ORIENTATION_TOPRIGHT:
197        case ORIENTATION_RIGHTTOP:      /* XXX */
198        case ORIENTATION_LEFTTOP:       /* XXX */
199                printf("Warning, using top-left orientation.\n");
200                orientation = ORIENTATION_TOPLEFT;
201                /* fall thru... */
202        case ORIENTATION_TOPLEFT:
203                y = h-1;
204                break;
205        }
206        return (y);
207}
208
209gtcontig(tif, raster, Map, h, w)
210        TIFF *tif;
211        u_long *raster;
212        register RGBvalue *Map;
213        int h, w;
214{
215        register u_char *pp;
216        register u_long *cp;
217        register int x;
218        int scanline, row, y;
219        u_char *buf;
220
221        buf = (u_char *)malloc(TIFFScanlineSize(tif));
222        if (buf == 0) {
223                fprintf(stderr, "No space for scanline buffer\n");
224                return (0);
225        }
226        y = setorientation(tif, h);
227        for (row = 0; row < h; row++) {
228                if (TIFFReadScanline(tif, buf, row, 0) < 0)
229                        break;
230                pp = buf;
231                cp = raster + y*w;
232                switch (photometric) {
233                case PHOTOMETRIC_RGB:
234                    rgb:
235                        switch (bitspersample) {
236                        case 8:
237                                if (Map) {
238                                        for (x = w; x-- > 0;) {
239                                                pp[0] = Map[pp[0]];
240                                                pp[1] = Map[pp[1]];
241                                                pp[2] = Map[pp[2]];
242                                                pp += samplesperpixel;
243                                        }
244                                        pp = buf;
245                                }
246                                if(samplesperpixel == 4) {
247                                    for(x = w; --x >= 0; pp += 4)
248                                        *cp++ = rgba(pp[0], pp[1], pp[2],pp[3]);
249                                } else {
250                                    for (x = w; x-- > 0; pp += samplesperpixel)
251                                        *cp++ = rgbi(pp[0], pp[1], pp[2]);
252                                }
253                                break;
254                        case 16: {
255                                register u_short *wp;
256
257                                if (Map) {
258                                        wp = (u_short *)pp;
259                                        for (x = w; x-- > 0;) {
260                                                wp[0] = Map[wp[0]];
261                                                wp[1] = Map[wp[1]];
262                                                wp[2] = Map[wp[2]];
263                                                wp += samplesperpixel;
264                                        }
265                                }
266                                wp = (u_short *)pp;
267                                for (x = w; x-- > 0;) {
268                                        *cp++ = rgbi(wp[0], wp[1], wp[2]);
269                                        wp += samplesperpixel;
270                                }
271                                break;
272                        }
273                        }
274                        break;
275                case PHOTOMETRIC_PALETTE:
276                        for (x = w; x-- > 0;) {
277                                RGBvalue c = *pp++;
278                                *cp++ = rgbi(redcmap[c],
279                                    greencmap[c], bluecmap[c]);
280                        }
281                        break;
282                case PHOTOMETRIC_MINISWHITE:
283                case PHOTOMETRIC_MINISBLACK:
284                        if(samplesperpixel > 1)
285                                goto rgb;
286
287                        if (bitspersample == 8) {
288                                register RGBvalue c;
289
290                                for (x = w; x-- > 0;) {
291                                        c = Map[*pp++];
292                                        *cp++ = rgbi(c, c, c);
293                                }
294                        } else
295                                gtbw(bitspersample, w, cp, pp);
296                        break;
297                }
298                y += (orientation == ORIENTATION_TOPLEFT ? -1 : 1);
299        }
300        return (1);
301}
302
303gtseparate(tif, raster, Map, h, w)
304        TIFF *tif;
305        u_long *raster;
306        register RGBvalue *Map;
307        int h, w;
308{
309        register u_long *cp;
310        register int x;
311        u_char *red;
312        int scanline, row, y;
313
314        scanline = TIFFScanlineSize(tif);
315        switch (samplesperpixel) {
316        case 1:
317                red = (u_char *)malloc(scanline);
318                break;
319        case 3: case 4:
320                red = (u_char *)malloc(4*scanline);
321                break;
322        }
323        y = setorientation(tif, h);
324        for (row = 0; row < h; row++) {
325                cp = raster + y*w;
326                if (TIFFReadScanline(tif, red, row, 0) < 0)
327                        break;
328                switch (photometric) {
329                case PHOTOMETRIC_RGB: {
330                        register u_char *r, *g, *b, *a;
331
332                        r = red;
333                        if (TIFFReadScanline(tif, g = r + scanline, row, 1) < 0)
334                                break;
335                        if (TIFFReadScanline(tif, b = g + scanline, row, 2) < 0)
336                                break;
337                        if(samplesperpixel == 4) {
338                            a = b + scanline;
339                            if(TIFFReadScanline(tif, a, row, 3) < 0)
340                                break;
341                        }
342                        switch (bitspersample) {
343                        case 8:
344                            if(samplesperpixel == 4) {
345                                for(x = w; --x >= 0; )
346                                    *cp++ = rgba(*r++, *g++, *b++, *a++);
347                            } else {
348                                for (x = w; x-- > 0;)
349                                        *cp++ = rgbi(*r++, *g++, *b++);
350                            }
351                                break;
352                        case 16:
353#define wp(x)   ((u_short *)(x))
354                                for (x = 0; x < w; x++)
355                                        *cp++ = rgbi(
356                                            Map[wp(r)[x]],
357                                            Map[wp(g)[x]],
358                                            Map[wp(b)[x]]);
359                                break;
360#undef  wp
361                        }
362                        break;
363                }
364                case PHOTOMETRIC_PALETTE: {
365                        register u_char *pp = red;
366                        for (x = w; x-- > 0;) {
367                                RGBvalue c = *pp++;
368                                *cp++ = rgbi(redcmap[c],
369                                    greencmap[c], bluecmap[c]);
370                        }
371                        break;
372                }
373                case PHOTOMETRIC_MINISWHITE:
374                case PHOTOMETRIC_MINISBLACK:
375                        if (bitspersample == 8) {
376                                register u_short *pp = (u_short *)red;
377                                register RGBvalue c;
378
379                                for (x = w; x-- > 0;) {
380                                        c = Map[*pp++];
381                                        *cp++ = rgbi(c, c, c);
382                                }
383                        } else
384                                gtbw(bitspersample, w, Map, cp, red);
385                        break;
386                }
387                y += (orientation == ORIENTATION_TOPLEFT ? -1 : 1);
388        }
389        if (red)
390                free(red);
391        return (1);
392}
393
394/*
395 * Greyscale images with less than 8 bits/sample are handled
396 * with a table to avoid lots of shits and masks.  The table
397 * is setup so that gtbw (below) can retrieve 8/bitspersample
398 * pixel values simply by indexing into the table with one
399 * number.
400 */
401makebwmap(Map)
402        RGBvalue *Map;
403{
404        register int i;
405        int nsamples = 8 / bitspersample;
406        register RGBvalue *p;
407
408        BWmap = (RGBvalue **)malloc(
409            256*sizeof (RGBvalue *)+(256*nsamples*sizeof(RGBvalue)));
410        if (BWmap == NULL) {
411                fprintf(stderr, "No space for B&W mapping table.\n");
412                return (0);
413        }
414        p = (RGBvalue *)(BWmap + 256);
415        for (i = 0; i < 256; i++) {
416                BWmap[i] = p;
417                switch (bitspersample) {
418                case 1:
419                        *p++ = Map[i>>7];
420                        *p++ = Map[(i>>6)&1];
421                        *p++ = Map[(i>>5)&1];
422                        *p++ = Map[(i>>4)&1];
423                        *p++ = Map[(i>>3)&1];
424                        *p++ = Map[(i>>2)&1];
425                        *p++ = Map[(i>>1)&1];
426                        *p++ = Map[i&1];
427                        break;
428                case 2:
429                        *p++ = Map[i>>6];
430                        *p++ = Map[(i>>4)&3];
431                        *p++ = Map[(i>>2)&3];
432                        *p++ = Map[i&3];
433                        break;
434                case 4:
435                        *p++ = Map[i>>4];
436                        *p++ = Map[i&0xf];
437                        break;
438                }
439        }
440        return (1);
441}
442
443#define REPEAT8(op)     REPEAT4(op); REPEAT4(op)
444#define REPEAT4(op)     REPEAT2(op); REPEAT2(op)
445#define REPEAT2(op)     op; op
446
447gtbw(bitspersample, w, cp, pp)
448        int bitspersample, w;
449        register u_long *cp;
450        register u_char *pp;
451{
452        register RGBvalue c, *bw;
453        register int x;
454
455        switch (bitspersample) {
456        case 1:
457                for (x = w; x > 0; x -= 8) {
458                        bw = BWmap[*pp++];
459                        REPEAT8(c = *bw++; *cp++ = rgbi(c, c, c));
460                }
461                break;
462        case 2:
463                for (x = w; x > 0; x -= 4) {
464                        bw = BWmap[*pp++];
465                        REPEAT4(c = *bw++; *cp++ = rgbi(c, c, c));
466                }
467                break;
468        case 4:
469                for (x = w; x > 0; x -= 2) {
470                        bw = BWmap[*pp++];
471                        REPEAT2(c = *bw++; *cp++ = rgbi(c, c, c));
472                }
473                break;
474        }
475}
Note: See TracBrowser for help on using the repository browser.