GPS4Palm

Source Code Documentation


pngdec.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * $RCSfile: pngdec_8c-source.html,v $
00004  *
00005  * PNG Image Decoder
00006  *
00007  * created: 2002-12-15
00008  *
00009  * History:
00010  * 2002-12-15:  imported from the program PiNGer which is
00011  *                part of the ZBoxZ application suite (Rev. 0.30)
00012  *                by Tom Zerucha.
00013  * 2002-12-30:  added progress bar, modified status messages,
00014  *                fixed cleanPNG() to work when called after early abort 
00015  *
00016  * This program is Copyright (C) 12/2002 Matthias Prinke
00017  * <matthias.prinke@surfeu.de> and covered by GNU's GPL.
00018  * In particular, this program is free software and comes WITHOUT
00019  * ANY WARRANTY.
00020  *
00021  * $Author: mp $
00022  *
00023  * $Date: 2007-10-08 20:40:34 $
00024  *
00025  * $Revision: 1.7.2.1 $
00026  *
00027  * $Log: pngdec_8c-source.html,v $
00027  * Revision 1.7.2.1  2007-10-08 20:40:34  mp
00027  * updated for gps4palm V0.9.5 beta
00027  *
00028  * Revision 1.9  2005-05-15 10:41:02  mp
00029  * added parameter fd to most functions
00030  *
00031  * Revision 1.8  2005/05/14 12:27:14  mp
00032  * added parameter fd to fclose(), fread(), and feof()
00033  *
00034  * Revision 1.7  2005/05/13 18:29:26  mp
00035  * modified decoding abortion
00036  *
00037  * Revision 1.6  2004/11/27 10:16:26  mp
00038  * replaced ErrFatalDisplay() by Die() for memory allocation failures
00039  *
00040  * Revision 1.5  2004/11/24 21:20:02  mp
00041  * moved static function declarations from header to implementation file
00042  *
00043  * Revision 1.4  2004/03/10 17:18:24  mp
00044  * added progressbar.h
00045  *
00046  * Revision 1.3  2003/12/27 12:09:19  mp
00047  * repeated calling og cleanPNG() now handled properly
00048  *
00049  * Revision 1.2  2003/10/18 16:11:51  mp
00050  * renamed ImgInfo to gPrefs
00051  *
00052  * Revision 1.1.1.1  2003/07/14 18:59:29  mp
00053  * Imported GPS4Palm to CVS revision control.
00054  *
00055  *
00056  ****************************************************************************/
00057 #include <PalmOS.h>
00058 #include <Unix/sys_types.h>
00059 #include "stringil.h"
00060 #include "common.h"
00061 #include "pngdec.h"
00062 #include "SysZLib.h"
00063 #include "file_io.h"            /* fread(), feof(), fclose */
00064 #include "Utils.h"              /* Die() */
00065 #include "progressbar.h"
00066 
00067 #define QUIET
00068 
00069 extern PrefsType        gPrefs;
00070 
00071 /* Mark's macros to extract big-endian short and long ints: */
00072 typedef unsigned char uch;
00073 typedef unsigned short ush;
00074 typedef unsigned long ulg;
00075 #define SH(p) ((ush)(uch)((p)[1]) | ((ush)(uch)((p)[0]) << 8))
00076 #define LG(p) ((ulg)(SH((p)+2)) | ((ulg)(SH(p)) << 16))
00077 
00078 #define BS 1440
00079 #define OBS (3*BS)
00080 unsigned char buffer[BS];
00081 static uch outbuf[OBS];
00082 
00083 extern Boolean color;
00084 
00085 unsigned short int w, h;
00086 unsigned short int bitdisp, bdepth, ityp, lace, nplte = 0, gskip =
00087   1, bskip, bandh;
00088 
00089 static long sz;
00090 
00091 int trspflg = 0;
00092 
00093 static unsigned short int bkgdr = 0x80;
00094 static unsigned short int bkgdg = 0x80;
00095 static unsigned short int bkgdb = 0x80;
00096 
00097 static unsigned short int tspr = 0;
00098 static unsigned short int tspg = 0;
00099 static unsigned short int tspb = 0;
00100 
00101 static unsigned short int bkgdy = 0x80;
00102 static unsigned short int tspy = 0;
00103 
00104 LocalID lid;
00105 DmOpenRef scratch;
00106 
00107 char **lines, *lcur, *editln;
00108 
00109 unsigned char cmap[256], r[256], g[256], b[256], a[256];
00110 unsigned int mapmax = 0;
00111 RGBColorType map[256];
00112 
00113 
00114 /* Static Functions */
00115 static void filter(unsigned char *curr, unsigned char *prev,
00116                         int filter, int bpp, int llen)          PNGDEC_SECTION;
00117 static int getcmap(unsigned int r, unsigned int g,
00118                         unsigned int b, unsigned int a)         PNGDEC_SECTION;
00119 static int doidat(FileDescrType fd)                             PNGDEC_SECTION;
00120 static void doihdr(FileDescrType fd)                            PNGDEC_SECTION;
00121 static void doprefix(FileDescrType fd)                          PNGDEC_SECTION;
00122 
00123 
00124 /**************************************************/
00125 static
00126 void filter(unsigned char *curr, unsigned char *prev, int filter,
00127                    int bpp, int llen)
00128 {
00129   unsigned char *curr0 = curr, *prev0, *zp = NULL;
00130   int a, b, c, pa, pb, pc;
00131 
00132   if (filter > 1 && !prev) {
00133     zp = malloc(llen);
00134     bzero(zp, llen);
00135     prev = zp;
00136   }
00137 
00138   switch (filter) {
00139 
00140   case 1:
00141     curr += bpp;
00142     llen -= bpp;
00143     prev = curr0;
00144   case 2:
00145     while (llen--)
00146       *curr++ += *prev++;
00147   case 0:
00148     break;
00149 
00150   case 3:
00151     while (bpp-- && llen--)
00152       *curr++ += *prev++ >> 1;
00153     while (llen--)
00154       *curr++ += (*prev++ + *curr0++) >> 1;
00155     break;
00156 
00157   case 4:
00158     prev0 = prev;
00159     while (bpp-- && llen--)
00160       *curr++ += *prev++;
00161     while (llen--) {
00162       a = *curr0++, b = *prev++, c = *prev0++;
00163 
00164       pa = abs(b - c);
00165       pb = abs(a - c);
00166       pc = abs(a + b - (c << 1));
00167 
00168       *curr++ += (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
00169     }
00170     break;
00171   }
00172   if (zp)
00173     free(zp);
00174 }
00175 
00176  /* for color to grey (of 65536): R=13926 - 54, G=46884 - 183, B=4725 - 18 */
00177 /**************************************************/
00178 /* these are unsigned ints, but are actually 8 bit values */
00179 static
00180 int getcmap(unsigned int r, unsigned int g, unsigned int b, unsigned int a)
00181 {
00182 
00183   /* a is transparency and is not used yet, or if == 0xff has no effect */
00184   if( trspflg ) {
00185     if (!a || (a == 255 && ityp == 2 && r == tspr && g == tspg && b == tspb)) {
00186       r = bkgdr;
00187       g = bkgdg;
00188       b = bkgdb;
00189     } else if (a < 255) {
00190       r = (bkgdr * (255 - a) + r * a) >> 8; /* should really be /255 */
00191       g = (bkgdg * (255 - a) + g * a) >> 8;
00192       b = (bkgdb * (255 - a) + b * a) >> 8;
00193     }
00194   }
00195 
00196   if (color) {
00197     map[mapmax].r = r;
00198     map[mapmax].g = g;
00199     map[mapmax].b = b;
00200     map[mapmax].index = mapmax;
00201     return mapmax++;
00202   } else
00203     return (r * 54 + g * 183 + b * 18) >> 8;
00204 }
00205 
00206 /**************************************************/
00207 static
00208 int doidat(FileDescrType fd)
00209 {
00210   /* static */
00211   unsigned char *p;             /* always points to next filter byte */
00212   int cur_x, cur_y, cur_pass, cur_xoff, cur_yoff, cur_xskip, cur_yskip, chunk =
00213     0;
00214   long cur_width, cur_linebytes;
00215   z_stream zstrm;
00216   Word dbrec;
00217   VoidHand hand;
00218   long i, j, k;
00219   unsigned char *eod;
00220   int err = Z_OK;
00221 
00222 
00223   j = (sz > BS) ? BS : sz;
00224   fread(fd, buffer, (size_t) j);
00225   sz -= j;
00226 
00227   memset(&zstrm, 0, sizeof(zstrm));
00228   zstrm.next_in = buffer;
00229   zstrm.avail_in = j;
00230   zstrm.next_out = p = outbuf;
00231   zstrm.avail_out = OBS;
00232 
00233   inflateInit(&zstrm);
00234 
00235   cur_y = 0;
00236   cur_pass = 1;                 /* interlace pass:  1 through 7 */
00237   cur_xoff = cur_yoff = 0;
00238   cur_xskip = cur_yskip = lace ? 8 : 1;
00239   cur_width = (w + cur_xskip - 1) / cur_xskip; /* round up */
00240   cur_linebytes = ((cur_width * bitdisp + 7) >> 3) + 1; /* round, fltr */
00241 
00242   lid = DmFindDatabase(0, "ZBOXZSCRATCHPAD");
00243   if (!lid) {
00244     DmCreateDatabase(0, "ZBOXZSCRATCHPAD", 'BOXR', 'DATA', false);
00245     lid = DmFindDatabase(0, "ZBOXZSCRATCHPAD");
00246   }
00247   scratch = DmOpenDatabase(0, lid, dmModeReadWrite);
00248   if (!scratch)
00249     ErrDisplay("Could not access scratchpad");
00250 
00251   editln = malloc(w+8); /* +8 for interleave overflow */
00252   bandh = 49152 / w;
00253   lines = malloc((h + bandh - 1) / bandh * 4);
00254 
00255   for (i = 0; i < h; i += bandh) {
00256     dbrec = 65535;
00257     hand = DmNewRecord(scratch, &dbrec, w * bandh);
00258     if (!hand)
00259       Die("Out of Memory (pngdec)!");
00260     lines[i / bandh] = MemHandleLock(hand);
00261   }
00262 
00263   for (i = 0; i < nplte; i++)
00264     cmap[i] = getcmap(r[i], g[i], b[i], a[i]);
00265 
00266   k = (1 << bitdisp) - 1;
00267   while (err != Z_STREAM_END) {
00268 
00269     err = inflate(&zstrm, Z_PARTIAL_FLUSH);
00270     eod = outbuf + OBS - zstrm.avail_out;
00271 
00272     {
00273       EventType event;
00274       EvtGetEvent(&event, 0);
00275       if (event.eType == penDownEvent && event.screenY < 160) {
00276         inflateEnd(&zstrm);
00277         return 1;
00278       }
00279     }
00280 
00281     while (p + cur_linebytes <= eod) {
00282 
00283       if( p[0] )
00284         filter(&p[1], cur_y ? &p[1 - cur_linebytes] : NULL, p[0],
00285                (bitdisp + 7) >> 3, cur_linebytes - 1);
00286 
00287       cur_x = cur_xoff;
00288       lcur = lines[cur_y / bandh];
00289       lcur += w * (cur_y % bandh);
00290       (void) memcpy(editln, lcur, w);
00291 
00292       switch (ityp) {
00293 
00294       case 2:
00295         if (bitdisp == 16)
00296           for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip)
00297             editln[cur_x] = getcmap(p[j], p[j + 2], p[j + 4], 0xff);
00298         else
00299           for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip) 
00300             editln[cur_x] = getcmap(p[j], p[j + 1], p[j + 2], 0xff);
00301         break;
00302       case 6:
00303         if (bitdisp == 16)
00304           for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip)
00305             editln[cur_x] = getcmap(p[j], p[j + 2], p[j + 4], p[j + 6]);
00306         else
00307           for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip)
00308             editln[cur_x] = getcmap(p[j], p[j + 1], p[j + 2], p[j + 3]);
00309         break;
00310 
00311       case 3:
00312         if (bitdisp == 8 && gskip == 1) {
00313           /* optimized copy colormap entry direct */
00314           unsigned char *s = &p[1];
00315           j = cur_linebytes - 1;
00316           if (color)
00317             while( j-- ) {
00318               editln[cur_x] = *s++;
00319               cur_x += cur_xskip;
00320             }
00321           else               /* still need to go through cmap */
00322             while( j-- ) {
00323               editln[cur_x] = cmap[*s++];
00324               cur_x += cur_xskip;
00325             }
00326         } else
00327           for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip)
00328             for (i = 8 - bskip; i >= 0; i -= bskip)
00329               editln[cur_x] = cmap[((p[j] >> i) & k) << (8 - bskip)];
00330         break;
00331       case 0:
00332       case 4:                  /* if grey == trsp then sub bkgdy */
00333 
00334         if (bitdisp == 8 && gskip == 1) {
00335           /* optimized copy colormap entry direct */
00336           unsigned char *s = &p[1];
00337           j = cur_linebytes - 1;
00338           while( j-- ) {
00339             editln[cur_x] = *s++;
00340             cur_x += cur_xskip;
00341           }
00342         }
00343         else
00344         for (j = 1; j < cur_linebytes; j += gskip, cur_x += cur_xskip)
00345           for (i = 8 - bskip; i >= 0; i -= bskip)
00346             editln[cur_x] = ((p[j] >> i) & k) << (8 - bskip);
00347         break;
00348       }
00349 
00350       DmWrite(lines[cur_y / bandh], w * (cur_y % bandh), editln, w);
00351 
00352       p += cur_linebytes;
00353       cur_y += cur_yskip;
00354 
00355 #ifndef QUIET
00356       {
00357         char buf[5];
00358         StrIToA(buf, chunk);
00359         WinDrawChars(buf, strlen(buf), 25, 0);
00360       }
00361 #endif
00362       
00363       progressbar(80 /* ypos */, chunk++ /* val */, h /* total */);
00364       
00365       if (lace) {
00366         while (cur_y >= h) {    /* may loop if very short image */
00367           ++cur_pass;
00368           if (cur_pass & 1) {   /* beginning an odd pass */
00369             cur_yoff = cur_xoff;
00370             cur_xoff = 0;
00371             cur_xskip >>= 1;
00372           } else {              /* beginning an even pass */
00373             if (cur_pass == 2)
00374               cur_xoff = 4;
00375             else {
00376               cur_xoff = cur_yoff >> 1;
00377               cur_yskip >>= 1;
00378             }
00379             cur_yoff = 0;
00380           }
00381           cur_y = cur_yoff;
00382           /* effective width is reduced if even pass: subtract cur_xoff */
00383           cur_width = (w - cur_xoff + cur_xskip - 1) / cur_xskip;
00384           cur_linebytes = ((cur_width * bitdisp + 7) >> 3) + 1;
00385         }
00386       } else if (cur_y >= h) {
00387         break;
00388       }
00389     }                           /*p<eod */
00390 
00391     if (err != Z_OK && err != Z_STREAM_END) {
00392       char buf[8];
00393       StrIToA(buf, err);
00394       strcat(buf, " |");
00395       WinDrawChars(buf, strlen(buf), 80, 0);
00396       inflateEnd(&zstrm);
00397       SysTaskDelay(300);
00398       return 1;
00399     }
00400 
00401     if (err != Z_OK)
00402       break;
00403 
00404     /* fix p leaving a history line */
00405     i = eod - p + cur_linebytes;
00406     (void) memcpy(outbuf, p - cur_linebytes, i);
00407     zstrm.next_out = outbuf + i;
00408     zstrm.avail_out = OBS - i;
00409     p = outbuf + cur_linebytes;
00410 
00411     if (zstrm.avail_in > BS / 2)
00412       continue;
00413 
00414     (void) memcpy(buffer, zstrm.next_in, zstrm.avail_in);
00415     zstrm.next_in = buffer;
00416 
00417     if (!sz) {
00418       char buf[12];
00419       fread(fd, buf, 12);    /*crc,siz,IDAT */
00420       sz = LG(&buf[4]);
00421 #ifndef QUIET
00422       WinDrawChars(&buf[8], 4, 0, 0);
00423 #endif
00424     }
00425 
00426     i = BS - zstrm.avail_in;
00427     j = (sz > i) ? i : sz;
00428     fread(fd, &buffer[zstrm.avail_in], j);
00429 
00430     sz -= j;
00431     zstrm.avail_in += j;
00432 
00433   }
00434   inflateEnd(&zstrm);
00435   /*  fread(fd, buffer, 4); */
00436   return 0;
00437 }
00438 
00439 /**************************************************/
00440 char *pngty[] =
00441   { "Gray", "Unk1", "RGB ", "CMAP", "GryA", "Unk5", "RGBA", "Unk7" };
00442 
00443 static
00444 void doihdr(FileDescrType fd)
00445 {
00446   int i;
00447 #ifndef QUIET
00448   char buf[20];
00449 #endif
00450   /* search for IHDR */
00451   while (!feof(fd)) {
00452 
00453     if (8 != fread(fd, buffer, 8))
00454       break;
00455     sz = LG(buffer);
00456     (void) memcpy(buffer, &buffer[4], 4);
00457 #ifndef QUIET    
00458     WinDrawChars(buffer, 4, 0, 0);
00459 #endif
00460     buffer[4] = 0;
00461 
00462     /*------* 
00463      | IHDR | 
00464      *------*/
00465     if (strcmp(buffer, "IHDR") == 0) {
00466 
00467       fread(fd, buffer, sz + 4);
00468 
00469       w = LG(buffer);
00470       h = LG(buffer + 4);
00471       bitdisp = (unsigned char) buffer[8];
00472       bdepth = bitdisp;
00473       ityp = (unsigned char) buffer[9];
00474       lace = (unsigned char) buffer[12];
00475 
00476       StrPrintF(gPrefs.imgtype, "PNG Type%d (%s) %s", ityp, pngty[ityp],
00477                   (lace) ? "Interlaced" : "");
00478 
00479       {
00480         Char    buf[40];
00481         
00482         StrPrintF(buf, "%d x %d", w, h);
00483         WinDrawChars(buf, StrLen(buf), 0, 24);
00484       }
00485 
00486 #ifndef QUIET
00487       WinDrawChars("Depth", 5, 1, 60);
00488       StrIToA(buf, bitdisp);
00489       WinDrawChars(buf, strlen(buf), 30, 60);
00490 
00491       WinDrawChars("/", 2, 45, 0);
00492 
00493       WinDrawChars("Type", 4, 1, 15);
00494       StrIToA(buf, ityp);
00495       WinDrawChars(buf, strlen(buf), 30, 15);
00496       WinDrawChars(pngty[ityp], 4, 40, 15);
00497 
00498       if (lace) {
00499         WinDrawChars("Interlaced", 10, 0, 75);
00500         StrIToA(buf, h * 15 / 8);
00501         WinDrawChars(buf, strlen(buf), 50, 0);
00502       } else {
00503         StrIToA(buf, h);
00504         WinDrawChars(buf, strlen(buf), 50, 0);
00505       }
00506 #endif
00507 
00508       switch (ityp) {
00509       case 0:
00510         if (bitdisp == 16)
00511           gskip = 2;
00512         for (i = 0; i < 256; i++) /* for the IIIc */
00513           r[i] = g[i] = b[i] = i;
00514         memset(a, 0xff, 256);
00515         nplte = 256;
00516         break;
00517       case 2:
00518         if (bitdisp == 16)
00519           gskip = 6;
00520         else
00521           gskip = 3;
00522         bitdisp *= 3;           /* RGB */
00523         break;
00524       case 4:
00525         if (bitdisp == 16)
00526           gskip = 4;
00527         else
00528           gskip = 2;
00529         bitdisp *= 2;           /* gray+alpha */
00530         for (i = 0; i < 256; i++) /* for the IIIc */
00531           r[i] = g[i] = b[i] = i;
00532         memset(a, 0xff, 256);
00533         nplte = 256;
00534         break;
00535       case 6:
00536         if (bitdisp == 16)
00537           gskip = 8;
00538         else
00539           gskip = 4;
00540         bitdisp *= 4;           /* RGBA */
00541         break;
00542       }
00543       bskip = bitdisp / gskip;
00544       break;
00545 
00546     } else {
00547       /* BYPASS REST OF UNKNOWN RECORD */
00548       i = 0;
00549       while (sz > i) {
00550         sz -= i;
00551         i = (sz > BS) ? BS : sz;
00552         fread(fd, buffer, i);
00553       }
00554       fread(fd, buffer, 4);  /* crc */
00555     }
00556   }
00557 }
00558 
00559 /**************************************************/
00560 static
00561 void doprefix(FileDescrType fd)
00562 {
00563   int i, j;
00564   unsigned char *c;
00565 
00566   /* Look for IDAT and other used chunks */
00567   while (!feof(fd)) {
00568 
00569     if (8 != fread(fd, buffer, 8))
00570       break;
00571     sz = LG(buffer);
00572     (void) memcpy(buffer, &buffer[4], 4);
00573     buffer[4] = 0;
00574 #ifndef QUIET    
00575     WinDrawChars(buffer, 4, 0, 0);
00576 #endif
00577     c = buffer;
00578 
00579     if (strcmp(buffer, "IDAT") == 0)
00580       break;
00581 
00582     else if (strcmp(buffer, "PLTE") == 0) {
00583       fread(fd, buffer, sz + 4);
00584       nplte = sz / 3;
00585 
00586       /* save palette and do later with alpha and bkgd */
00587       for (i = j = 0; i < nplte; i++, j += 3) {
00588         r[i] = *c++;
00589         g[i] = *c++;
00590         b[i] = *c++;
00591       }
00592       memset(a, 0xff, nplte);
00593     }
00594     /* The next two must occur after PLTE */
00595     else if (strcmp(buffer, "tRNS") == 0) {
00596       /* Swap bKGD gray for tRNS gray (if no other background) */
00597       trspflg = 1;
00598 
00599       fread(fd, buffer, sz + 4);
00600       switch (ityp) {
00601       case 0:
00602         tspy = SH(buffer);      /* transparent gray value */
00603         break;
00604       case 3:
00605         c = buffer;
00606         for (i = 0; i < sz; ++i)
00607           a[i] = *c++;
00608         break;
00609       case 2:                  /* RGB */
00610         tspr = SH(c);
00611         c += 2;
00612         tspg = SH(c);
00613         c += 2;
00614         tspb = SH(c);
00615         if (bdepth == 16) {
00616           tspr >>= 8;
00617           tspg >>= 8;
00618           tspb >>= 8;
00619         }
00620         break;
00621       }
00622 
00623     } else if (strcmp(buffer, "bKGD") == 0) {
00624       fread(fd, buffer, sz + 4);
00625       switch (ityp) {
00626       case 0:
00627       case 4:
00628         bkgdy = SH(c);
00629         if (bdepth == 16)
00630           bkgdy >>= 8;
00631         break;
00632       case 3:
00633         bkgdr = r[*c];
00634         bkgdg = g[*c];
00635         bkgdb = b[*c];
00636         break;
00637       case 2:
00638       case 6:
00639         bkgdr = SH(c);
00640         c += 2;
00641         bkgdg = SH(c);
00642         c += 2;
00643         bkgdb = SH(c);
00644         if (bdepth == 16) {
00645           bkgdr >>= 8;
00646           bkgdg >>= 8;
00647           bkgdb >>= 8;
00648         }
00649         break;
00650       }
00651     } else if (strcmp(buffer, "IEND") == 0) {
00652       break;
00653     } else {
00654       /* BYPASS REST OF UNIMPLEMENTED RECORD */
00655       i = 0;
00656       while (sz > i) {
00657         sz -= i;
00658         i = (sz > BS) ? BS : sz;
00659         fread(fd, buffer, i);
00660       }
00661       fread(fd, buffer,  4);  /* crc */
00662     }
00663   }
00664 }
00665 
00666 /**************************************************/
00667 void cleanPNG(void)
00668 {
00669   int i;
00670   
00671   if (lines) {
00672     for (i = 0; i < h; i += bandh)
00673       MemPtrUnlock(lines[i / bandh]);
00674   }
00675   
00676   if (scratch) {
00677     while (DmNumRecords(scratch))
00678       DmRemoveRecord(scratch, 0);
00679     DmCloseDatabase(scratch);
00680     scratch = 0; 
00681   }
00682   
00683   if (lines) {
00684     free(lines);
00685     lines = 0;
00686   }
00687   
00688   if (editln) {
00689     free(editln);
00690     editln = 0;
00691   }
00692 }
00693 
00694 /**************************************************/
00695 static unsigned char PNGmagic[] = "\211PNG\r\n\032\n";
00696 
00697 int doPNG(FileDescrType fd)
00698 {
00699   unsigned char magic[8];
00700   int i;
00701   
00702   lines = NULL;
00703   editln = NULL;
00704   scratch = 0;
00705 
00706   fread(fd, magic, 8);
00707   if (memcmp(magic, PNGmagic, 8)) {
00708     fclose(fd);
00709     return 1;
00710   }
00711 
00712   doihdr(fd);
00713 
00714   for (i = 0; i < 256; i++)
00715     cmap[i] = i;
00716 
00717   doprefix(fd);
00718 
00719   if ((!nplte && ityp == 3) || strcmp(buffer, "IDAT")) {
00720     fclose(fd);
00721     return 1;
00722   }
00723 
00724   ZLSetup;
00725   EvtResetAutoOffTimer();
00726   i = doidat(fd);
00727   EvtResetAutoOffTimer();
00728   ZLTeardown;
00729   fclose(fd);
00730 
00731   if (i) {
00732     cleanPNG();
00733     return 1;
00734   }
00735   return 0;
00736 }

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