Back to index

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