GPS4Palm

Source Code Documentation


imginfo.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: imginfo_8c-source.html,v $
00004  *
00005  * Image File Information Functions
00006  *
00007  * Note: For GIF, the code has been taken from gifread.c.
00008  *       FOR PNG, the code has been taken from pngdec.c.
00009  *
00010  * This program is Copyright (C) 03/2005 Matthias Prinke
00011  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00012  * In particular, this program is free software and comes WITHOUT
00013  * ANY WARRANTY.
00014  *
00015  * $Author: mp $
00016  *
00017  * $Date: 2007-10-08 20:40:33 $
00018  *
00019  * $Revision: 1.1.2.1 $
00020  *
00021  * $Log: imginfo_8c-source.html,v $
00021  * Revision 1.1.2.1  2007-10-08 20:40:33  mp
00021  * updated for gps4palm V0.9.5 beta
00021  *
00022  * Revision 1.1  2005-05-14 12:31:29  mp
00023  * initial version
00024  *
00025  *
00026  ****************************************************************************/ 
00027 #include <PalmOS.h>
00028 #include "file_io.h"
00029 #include "imginfo.h"
00030 #include "stringil.h"
00031 
00032 #define USAT(a,b)       (((b)<<8)|(a))
00033 #define BS              1440
00034 
00035 /* Mark's macros to extract big-endian short and long ints: */
00036 typedef unsigned char uch;
00037 typedef unsigned short ush;
00038 typedef unsigned long ulg;
00039 #define SH(p) ((ush)(uch)((p)[1]) | ((ush)(uch)((p)[0]) << 8))
00040 #define LG(p) ((ulg)(SH((p)+2)) | ((ulg)(SH(p)) << 16))
00041 
00042 /* magic bytes to determine image type */
00043 const char png_magic[]    = "\211PNG\r\n\032\n";
00044 const char gif87a_magic[] = "GIF87a";
00045 const char gif89a_magic[] = "GIF89a";
00046 const char jpeg_magic[]   = "\xFF\xD8"; /* 0xFF 0xD8 (SOI - Start of Image) */
00047 
00048 
00049 Boolean imginfo(FileDescrType fd, UInt8 *type, UInt16 *width, UInt16 *height)
00050 {
00051   unsigned char         buf[24];
00052   unsigned int          mapmax;
00053   unsigned int          i;
00054   long int              sz;
00055   
00056   fread(fd, buf, 8);
00057   
00058   if (strncmp(buf, png_magic, strlen((char *)png_magic)) == 0) {
00059     /* file is a PNG */
00060     *type = IMGTYPE_PNG;
00061 
00062     /* search for IHDR */
00063     while (!feof(fd)) {
00064 
00065       if (8 != fread(fd, buf, 8))
00066         break;
00067       sz = LG(buf);
00068       (void) memcpy(buf, &buf[4], 4);
00069 
00070       buf[4] = 0;
00071 
00072       /*------* 
00073        | IHDR | 
00074        *------*/
00075       if (strcmp(buf, "IHDR") == 0) {
00076 
00077         fread(fd, buf, sz + 4);
00078 
00079         *width  = LG(buf);
00080         *height = LG(buf + 4);
00081         rewind(fd);
00082         return false;
00083 
00084       } else {
00085         /* BYPASS REST OF UNKNOWN RECORD */
00086         i = 0;
00087         while (sz > i) {
00088           sz -= i;
00089           i = (sz > BS) ? BS : sz;
00090           fread(fd, buf, i);
00091         }
00092         fread(fd, buf, 4);  /* crc */
00093       }
00094     } /* while (!feof()) */
00095     rewind(fd);
00096     return true;
00097     
00098   } else if (strncmp(buf, gif87a_magic, strlen((char *)gif87a_magic)) == 0 ||
00099              strncmp(buf, gif89a_magic, strlen((char *)gif89a_magic)) == 0) {
00100     rewind(fd);
00101 
00102     /* file is a GIF */
00103     *type = IMGTYPE_GIF;
00104   
00105     fread(fd, buf, 13);
00106     
00107     /* read past colormap */
00108     mapmax = 2 << (buf[10] & 0x07);
00109   
00110     if (buf[10] & 0x80) {
00111       /* Global CMap */
00112       fseek(fd, mapmax * 3, SEEK_CUR);
00113     }
00114   
00115     /* skip optional extension blocks (GIF89a) */
00116     while (true) {
00117       if (fread(fd, buf, 1) == 0) {
00118         /* error: end of file */
00119         rewind(fd);
00120         return true;
00121       }
00122       if (buf[0] == ',') {
00123         /* Image Separator found */
00124         break;
00125       } else if (buf[0] == '!') {
00126         /* Extension Introducer found */
00127         fread(fd, buf, 1);
00128         if (buf[0] == 0xFE) {
00129           /* Plain Text Extension */
00130           /* read until Block Terminator found */
00131           do {
00132             fread(fd, buf, 1);
00133           } while (buf[0] != '\0');
00134         } else {
00135           /* any other extension, next byte: Block Size */
00136           fread(fd, buf, 1);
00137           for (i = buf[0] + 1; i > 0; i--) {
00138             /* read complete block and Block Terminator */
00139             fread(fd, buf, 1);
00140           }
00141         }
00142       } else {
00143         /* Invalid Data */
00144         rewind(fd);
00145         return true;
00146       }
00147     } /* while (true) */
00148 
00149     /* read remaining bytes of Image Descriptor */
00150     fread(fd, &buf[1], 9);
00151     
00152     *width  = USAT(buf[5], buf[6]);
00153     *height = USAT(buf[7], buf[8]);
00154     rewind(fd);
00155     return false;
00156     
00157   } else if (strncmp(buf, jpeg_magic, strlen((char *)jpeg_magic)) == 0) {
00158     /* file is a JPEG */
00159     *type = IMGTYPE_JPEG;
00160         
00161     /* currently not supported */
00162     *width  = 0;
00163     *height = 0;
00164     rewind(fd);
00165     return false;
00166     
00167   } else {
00168     /* file type is unknown */
00169     *type = IMGTYPE_UNKNOWN;
00170     rewind(fd);
00171     return true;
00172     
00173   }
00174 }

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke