Back to index

plt-scheme  4.2.1
gd_gd.c
Go to the documentation of this file.
00001 
00002 #ifdef HAVE_CONFIG_H
00003 #include "config.h"
00004 #endif
00005 
00006 #include <stdio.h>
00007 #include <math.h>
00008 #include <string.h>
00009 #include <stdlib.h>
00010 #include "gd.h"
00011 
00012 #define TRUE 1
00013 #define FALSE 0
00014 
00015 /* Exported functions: */
00016 extern void gdImageGd (gdImagePtr im, FILE * out);
00017 
00018 
00019 /* Use this for commenting out debug-print statements. */
00020 /* Just use the first '#define' to allow all the prints... */
00021 /*#define GD2_DBG(s) (s) */
00022 #define GD2_DBG(s)
00023 
00024 /* */
00025 /* Shared code to read color tables from gd file. */
00026 /* */
00027 int
00028 _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
00029 {
00030   int i;
00031   if (gd2xFlag)
00032     {
00033       int trueColorFlag;
00034       if (!gdGetByte (&trueColorFlag, in))
00035        {
00036          goto fail1;
00037        }
00038       /* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12.
00039          Beginning in 2.0.12 truecolor is indicated by the initial 2-byte
00040          signature. */
00041       if (trueColorFlag != im->trueColor)
00042        {
00043          goto fail1;
00044        }
00045       /* This should have been a word all along */
00046       if (!im->trueColor)
00047        {
00048          if (!gdGetWord (&im->colorsTotal, in))
00049            {
00050              goto fail1;
00051            }
00052        }
00053       /* Int to accommodate truecolor single-color transparency */
00054       if (!gdGetInt (&im->transparent, in))
00055        {
00056          goto fail1;
00057        }
00058     }
00059   else
00060     {
00061       if (!gdGetByte (&im->colorsTotal, in))
00062        {
00063          goto fail1;
00064        }
00065       if (!gdGetWord (&im->transparent, in))
00066        {
00067          goto fail1;
00068        }
00069       if (im->transparent == 257)
00070        {
00071          im->transparent = (-1);
00072        }
00073     }
00074   GD2_DBG (printf
00075           ("Pallette had %d colours (T=%d)\n", im->colorsTotal,
00076            im->transparent));
00077   if (im->trueColor)
00078     {
00079       return TRUE;
00080     }
00081   for (i = 0; (i < gdMaxColors); i++)
00082     {
00083       if (!gdGetByte (&im->red[i], in))
00084        {
00085          goto fail1;
00086        }
00087       if (!gdGetByte (&im->green[i], in))
00088        {
00089          goto fail1;
00090        }
00091       if (!gdGetByte (&im->blue[i], in))
00092        {
00093          goto fail1;
00094        }
00095       if (gd2xFlag)
00096        {
00097          if (!gdGetByte (&im->alpha[i], in))
00098            {
00099              goto fail1;
00100            }
00101        }
00102     }
00103 
00104   for (i = 0; (i < im->colorsTotal); i++)
00105     {
00106       im->open[i] = 0;
00107     };
00108 
00109   return TRUE;
00110 fail1:
00111   return FALSE;
00112 }
00113 
00114 /* */
00115 /* Use the common basic header info to make the image object. */
00116 /* */
00117 static gdImagePtr
00118 _gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
00119 {
00120   gdImagePtr im;
00121   int gd2xFlag = 0;
00122   int trueColorFlag = 0;
00123   if (!gdGetWord (sx, in))
00124     {
00125       goto fail1;
00126     }
00127   if ((*sx == 65535) || (*sx == 65534))
00128     {
00129       /* This is a gd 2.0 .gd file */
00130       gd2xFlag = 1;
00131       /* 2.0.12: 65534 signals a truecolor .gd file. 
00132          There is a slight redundancy here but we can
00133          live with it. */
00134       if (*sx == 65534)
00135        {
00136          trueColorFlag = 1;
00137        }
00138       if (!gdGetWord (sx, in))
00139        {
00140          goto fail1;
00141        }
00142     }
00143   if (!gdGetWord (sy, in))
00144     {
00145       goto fail1;
00146     }
00147 
00148   GD2_DBG (printf ("Image is %dx%d\n", *sx, *sy));
00149   if (trueColorFlag)
00150     {
00151       im = gdImageCreateTrueColor (*sx, *sy);
00152     }
00153   else
00154     {
00155       im = gdImageCreate (*sx, *sy);
00156     }
00157   if (!_gdGetColors (in, im, gd2xFlag))
00158     {
00159       goto fail2;
00160     }
00161 
00162   return im;
00163 fail2:
00164   gdImageDestroy (im);
00165 fail1:
00166   return 0;
00167 }
00168 
00169 gdImagePtr
00170 gdImageCreateFromGd (FILE * inFile)
00171 {
00172   gdImagePtr im;
00173   gdIOCtx *in;
00174 
00175   in = gdNewFileCtx (inFile);
00176   im = gdImageCreateFromGdCtx (in);
00177 
00178   in->gd_free (in);
00179 
00180   return im;
00181 }
00182 
00183 gdImagePtr
00184 gdImageCreateFromGdCtx (gdIOCtxPtr in)
00185 {
00186   int sx, sy;
00187   int x, y;
00188   gdImagePtr im;
00189 
00190   /* Read the header */
00191   im = _gdCreateFromFile (in, &sx, &sy);
00192 
00193   if (im == NULL)
00194     {
00195       goto fail1;
00196     };
00197 
00198   /* Then the data... */
00199   /* 2.0.12: support truecolor properly in .gd as well as in .gd2.
00200      Problem reported by Andreas Pfaller. */
00201   if (im->trueColor)
00202     {
00203       for (y = 0; (y < sy); y++)
00204        {
00205          for (x = 0; (x < sx); x++)
00206            {
00207              int pix;
00208              if (!gdGetInt (&pix, in))
00209               {
00210                 goto fail2;
00211               }
00212              im->tpixels[y][x] = pix;
00213            }
00214        }
00215     }
00216   else
00217     {
00218       for (y = 0; (y < sy); y++)
00219        {
00220          for (x = 0; (x < sx); x++)
00221            {
00222              int ch;
00223              ch = gdGetC (in);
00224              if (ch == EOF)
00225               {
00226                 goto fail2;
00227               }
00228              /* ROW-MAJOR IN GD 1.3 */
00229              im->pixels[y][x] = ch;
00230            }
00231        }
00232     }
00233   return im;
00234 
00235 fail2:
00236   gdImageDestroy (im);
00237 fail1:
00238   return 0;
00239 }
00240 
00241 void
00242 _gdPutColors (gdImagePtr im, gdIOCtx * out)
00243 {
00244   int i;
00245 
00246   gdPutC (im->trueColor, out);
00247   if (!im->trueColor)
00248     {
00249       gdPutWord (im->colorsTotal, out);
00250     }
00251   gdPutInt (im->transparent, out);
00252   if (!im->trueColor)
00253     {
00254       for (i = 0; (i < gdMaxColors); i++)
00255        {
00256          gdPutC ((unsigned char) im->red[i], out);
00257          gdPutC ((unsigned char) im->green[i], out);
00258          gdPutC ((unsigned char) im->blue[i], out);
00259          gdPutC ((unsigned char) im->alpha[i], out);
00260        }
00261     }
00262 }
00263 
00264 static void
00265 _gdPutHeader (gdImagePtr im, gdIOCtx * out)
00266 {
00267   /* 65535 indicates this is a gd 2.x .gd file. 
00268      2.0.12: 65534 indicates truecolor. */
00269   if (im->trueColor)
00270     {
00271       gdPutWord (65534, out);
00272     }
00273   else
00274     {
00275       gdPutWord (65535, out);
00276     }
00277   gdPutWord (im->sx, out);
00278   gdPutWord (im->sy, out);
00279 
00280   _gdPutColors (im, out);
00281 
00282 }
00283 
00284 static void
00285 _gdImageGd (gdImagePtr im, gdIOCtx * out)
00286 {
00287   int x, y;
00288 
00289   _gdPutHeader (im, out);
00290 
00291   for (y = 0; (y < im->sy); y++)
00292     {
00293       for (x = 0; (x < im->sx); x++)
00294        {
00295          /* ROW-MAJOR IN GD 1.3 */
00296          if (im->trueColor)
00297            {
00298              gdPutInt (im->tpixels[y][x], out);
00299            }
00300          else
00301            {
00302              gdPutC ((unsigned char) im->pixels[y][x], out);
00303            }
00304        }
00305     }
00306 }
00307 
00308 void
00309 gdImageGd (gdImagePtr im, FILE * outFile)
00310 {
00311   gdIOCtx *out = gdNewFileCtx (outFile);
00312   _gdImageGd (im, out);
00313   out->gd_free (out);
00314 }
00315 
00316 void *
00317 gdImageGdPtr (gdImagePtr im, int *size)
00318 {
00319   void *rv;
00320   gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
00321   _gdImageGd (im, out);
00322   rv = gdDPExtractData (out, size);
00323   out->gd_free (out);
00324   return rv;
00325 }