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

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

Added modified SAGE sources

  • Property svn:executable set to *
RevLine 
[4]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#include <stdio.h>
38#include <memory.h>
39#include <unistd.h>
40#include <fcntl.h>
41
42#include "imginfo.h"
43
44#include <image.h>
45#include <tiffio.h>
46#include <rasterfile.h>
47#include <softpic.h>
48
49/*
50 * Generic image-information routine.
51 * Given a file name, fills in an "imginfo" structure,
52 * and returns the type of image.
53 */
54
55
56char *imgtypename[] = {
57        "unknown", "tiff", "sgi", "ras", "soft", "gif", "pnm", "raw", "jpeg", NULL
58};
59
60#define MAXMAGIC  6
61
62struct imgdesc {
63        short magiclen; /* Bytes in magic number.  -1 terminates known list. */
64        char magic[MAXMAGIC];   /* magic number */
65        int  (*getinfo)(); /* getinfo(filename) loads our global vars */
66};
67
68static int tiffinfo(), sgiinfo(), rasinfo(), softinfo(), gifinfo(),
69        pnminfo(), rawinfo(), jpeginfo();
70
71static struct imgdesc known[] = {
72        { 2, { 'M','M' }, tiffinfo },           /* Big-endian Tiff */
73        { 2, { 'I','I' }, tiffinfo },           /* Little-endian */
74        { 2, { 0x01,0xDA }, sgiinfo },          /* SGI */
75        { 4, { 0x59,0xA6,0x6A,0x95 }, rasinfo }, /* Sun */
76        { 4, { 0x53,0x80,0xF6,0x34 }, softinfo }, /* SoftImage */
77        { 5, { 'G','I','F','8','7' }, gifinfo }, /* GIF */
78        { 5, { 'G','I','F','8','9' }, gifinfo }, /* GIF */
79        { 4, { 0xff, 0xd8, 0xff, 0xe0 }, jpeginfo }, /* JPEG */
80        { 1, { 'P' }, pnminfo },                /* PBM/PGM/PPM */
81        { 0, { 0 }, rawinfo },                  /* raw + imginfo header */
82        { -1, { 0 }, NULL }
83};
84
85extern int pnm_getint( FILE * );
86
87int
88getimginfo(fname, info)
89    char *fname;
90    struct imginfo *info;
91{
92    register struct imgdesc *p;
93    int fd;
94    struct imginfo dummy;
95    char buf[MAXMAGIC];
96
97    if(info == NULL)
98        info = &dummy;
99
100    memset(info, 0, sizeof(struct imginfo));    /* Zero all fields */
101    if((fd = open(fname, 0)) < 0) {
102        fprintf(stderr, "%s: ", fname);
103        fflush(stderr);
104        perror("cannot open");
105        return I_UNKNOWN;
106    }
107    memset(buf, -1, MAXMAGIC);
108    (void) read(fd, buf, MAXMAGIC);
109    for(p = known; ; p++) {
110        if(p->magiclen < 0 ||
111            ((p->magiclen == 0 || memcmp(p->magic, buf, p->magiclen) == 0)
112             && (*p->getinfo)(info, fname, fd) == 0))
113            break;
114    }
115    close(fd);
116    return info->kind;
117}
118
119/*
120 * Type-specific interpreters
121 */
122
123static int
124softinfo(info, fname, fd)
125    register struct imginfo *info;
126    char *fname;
127    int fd;
128{
129    struct softpict pic;
130    struct softpack packet;
131    int fields = 0;
132
133    lseek(fd, sizeof(struct softhdr), 0);
134    if(read(fd, &pic, sizeof(struct softpict)) != sizeof(struct softpict) ||
135                pic.id != SPICT_MAGIC)
136        return -1;
137    info->xsize = pic.width;
138    info->ysize = pic.height;
139    do {
140        if(read(fd, &packet, sizeof(struct softpack)) != sizeof(struct softpack))
141            return -1;
142        packet.fields &= (SPICT_R|SPICT_G|SPICT_B|SPICT_A);
143        if(packet.fields) {
144            info->sampbits = packet.nbits;
145            fields |= packet.fields;
146        }
147    } while(packet.chained);
148
149    for(info->nsamp = 0; fields != 0; fields >>= 1)
150        info->nsamp += (fields & 1);
151
152    info->mapsize = info->mapsamp = 0;
153    info->kind = I_SOFT;
154    return 0;
155}
156
157/* big-endian to native conversions */
158
159static uint16 betohs( uint16 bes )
160{
161    static int one = 1;
162    return (*(char *)&one == 0)
163        ? bes
164        : ((bes>>8)&0xFF) | (bes&0xFF)<<8;
165}
166
167static int
168sgiinfo(info, fname, fd)
169    register struct imginfo *info;
170    char *fname;
171    int fd;
172{
173    IMAGE imghdr;
174
175    (void) lseek(fd, 0L, 0);
176    (void) read(fd, &imghdr, sizeof(imghdr));
177
178    info->xsize = betohs( imghdr.xsize );
179    info->ysize = betohs( imghdr.ysize );
180    info->nsamp = betohs( imghdr.zsize );
181    info->sampbits = 8;
182    info->mapsize = info->mapsamp = 0;
183    info->kind = I_SGI;
184    return 0;
185}
186
187static int
188rasinfo(info, fname, fd)
189    register struct imginfo *info;
190    char *fname;
191    int fd;
192{
193    struct rasterfile ras;
194
195    lseek(fd, 0L, 0);
196    if(read(fd, &ras, sizeof(ras)) != sizeof(ras))
197        return -1;
198    info->xsize = ras.ras_width;
199    info->ysize = ras.ras_height;
200    info->sampbits = ras.ras_depth == 24 ? 8 : ras.ras_depth;
201    if(ras.ras_maptype != RMT_NONE) {
202        info->mapsize = ras.ras_maplength / 3;
203        info->mapsamp = 3;
204        info->nsamp = 1;
205    } else {
206        info->mapsize = info->mapsamp = 0;
207        info->nsamp = (ras.ras_depth == 24) ? 3 : 1;
208    }
209    info->kind = I_SUNRAS;
210    return 0;
211}
212
213
214static int
215tiffinfo(info, fname, fd)
216    register struct imginfo *info;
217    char *fname;
218    int fd;
219{
220    TIFF *tif;
221    uint16 photometric;
222    uint16 bits = 8;
223    uint16 nsamp = 1;
224    uint32 xsize, ysize;
225
226    tif = TIFFOpen(fname, "r");
227    if(tif == NULL)
228        return -1;
229
230    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &xsize);
231    info->xsize = xsize;
232    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &ysize);
233    info->ysize = ysize;
234    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits);
235    info->sampbits = bits;
236    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &nsamp);
237    info->nsamp = nsamp;
238    if(TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric) &&
239                        photometric == PHOTOMETRIC_PALETTE) {
240        info->mapsize = 1 << info->sampbits;
241        info->mapsamp = 3;
242    } else {
243        info->mapsize = info->mapsamp = 0;
244    }
245    info->kind = I_TIFF;
246    TIFFClose(tif);
247    return 0;
248}
249
250static int
251gifinfo(info, fname, fd)
252register struct imginfo *info;
253char *fname;
254int fd;
255{
256   unsigned char tmp[10], ch, a, b;
257
258   lseek(fd, 0L, 0);
259   read(fd, tmp, 6);                            /* skip magic # */
260   if(tmp[5] != 'a' && tmp[5] != 'A')           /* "GIF87A" or "GIF87a" */
261      return -1;
262   read(fd, &a, 1);
263   read(fd, &b, 1);
264   info->xsize = a + 0x100 * b;
265   read(fd, &a, 1);
266   read(fd, &b, 1);
267   info->ysize = a + 0x100 * b;
268   read(fd, &ch, 1);
269   info->sampbits = (ch & 7) + 1;
270   info->mapsize = 1 << info->sampbits;
271   info->mapsamp = 3;
272   info->nsamp = 1;
273   info->kind = I_GIF;
274   return 0;
275}
276
277#include <jpeglib.h>
278
279static int
280jpeginfo( struct imginfo *info, char *fname, int fd )
281{
282   struct jpeg_decompress_struct jp[1];
283   struct jpeg_error_mgr jerr[1];
284   FILE *jf = fdopen( fd, "r" );
285   int fail = -1;
286
287   if(jf == NULL)
288        return -1;
289   lseek( fd, 0, 0 );
290   jp->err = jpeg_std_error( jerr );
291   jpeg_create_decompress( jp );
292   jpeg_stdio_src( jp, jf );
293   if(jpeg_read_header( jp, TRUE ) != JPEG_HEADER_OK)
294        goto done;
295
296   jpeg_calc_output_dimensions( jp );
297   info->xsize = jp->output_width;
298   info->ysize = jp->output_height;
299   info->nsamp = jp->output_components;
300   info->mapsize = 0;
301   info->mapsamp = 0;
302   info->sampbits = 8;
303   info->kind = I_JPEG;
304   fail = 0;
305 done:
306   jpeg_destroy( (j_common_ptr)jp );
307   fclose(jf);
308   return fail;
309}
310
311static int
312rawinfo(info, fname, fd)
313    register struct imginfo *info;
314    char *fname;
315    int fd;
316{
317    char buf[256];
318    register int i, n;
319
320    for(n = sizeof(buf)-1; (i = read(fd, buf+sizeof(buf)-1-n, n)) > 0; n -= i)
321        ;
322
323    n = sizeof(buf)-1 - n;
324    if(n <= 0)
325        return -1;
326    buf[n] = '\0';
327    if(sscanf(buf, "%*s %d %d %d %d %d %d",
328                &info->xsize, &info->ysize, &info->nsamp, &info->mapsize,
329                &info->mapsamp, &info->sampbits) == 6) {
330        info->kind = I_RAW;
331        return 0;
332    }
333    return -1;
334}
335
336static int
337pnminfo(info, fname, fd)
338    register struct imginfo *info;
339    char *fname;
340    int fd;
341{
342    FILE *f = fdopen(fd, "r");
343    int c;
344
345    fseek(f, 1L, 0);
346    c = fgetc(f);
347    info->mapsize = info->mapsamp = 0;
348    switch(c) {
349    case '1': case '4':
350        info->sampbits = 1;
351        info->nsamp = 1;
352        break;
353    case '2': case '5':
354        info->sampbits = 8;
355        info->nsamp = 1;
356        break;
357    case '3': case '6':
358        info->sampbits = 8;
359        info->nsamp = 3;
360        break;
361    default:
362        return -1;
363    }
364
365    info->xsize = pnm_getint(f);
366    info->ysize = pnm_getint(f);
367    fclose(f);
368    if(info->xsize <= 0 || info->ysize <= 0)
369        return -1;
370
371    info->kind = I_PNM;
372    return 0;
373}
374
375int
376pnm_skipwhite(f)
377    register FILE *f;
378{
379    register int c;
380
381    for(;;) {
382        switch(c = fgetc(f)) {
383        case '#':
384            do { c = fgetc(f); } while(c != '\n' && c != EOF);
385            if(c == EOF)
386                return EOF;
387            break;
388        case ' ': case '\t': case '\n': case '\r': break;
389
390        case EOF: return EOF;
391        default:
392            ungetc(c, f);
393            return c;
394        }
395    }
396}
397
398int
399pnm_getint(f)
400    register FILE *f;
401{
402    register int n = 0;
403    register int c;
404    register int neg = 0;
405
406    switch(pnm_skipwhite(f)) {
407    case '-': neg = 1;
408    case '+': fgetc(f);
409    }
410    while((c = fgetc(f)) >= '0' && c <= '9')
411        n = n*10 + c-'0';
412    if(c != EOF)
413        ungetc(c, f);
414    return neg ? -n : n;
415}
Note: See TracBrowser for help on using the repository browser.