Back to index

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