#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include "gd.h"#define TRUE 1#define FALSE 0/* Use this for commenting out debug-print statements. *//* Just use the first '#define' to allow all the prints... *//*#define GD2_DBG(s) (s) */#define GD2_DBG(s)/* *//* Shared code to read color tables from gd file. *//* */int_gdGetColors(gdIOCtx*in,gdImagePtrim,intgd2xFlag){inti;if(gd2xFlag){inttrueColorFlag;if(!gdGetByte(&trueColorFlag,in)){gotofail1;}/* 2.0.12: detect bad truecolor .gd files created by pre-2.0.12. Beginning in 2.0.12 truecolor is indicated by the initial 2-byte signature. */if(trueColorFlag!=im->trueColor){gotofail1;}/* This should have been a word all along */if(!im->trueColor){if(!gdGetWord(&im->colorsTotal,in)){gotofail1;}if(im->colorsTotal>gdMaxColors){gotofail1;}}/* Int to accommodate truecolor single-color transparency */if(!gdGetInt(&im->transparent,in)){gotofail1;}}else{if(!gdGetByte(&im->colorsTotal,in)){gotofail1;}if(!gdGetWord(&im->transparent,in)){gotofail1;}if(im->transparent==257){im->transparent=(-1);}}GD2_DBG(printf("Palette had %d colours (T=%d)\n",im->colorsTotal,im->transparent));if(im->trueColor){returnTRUE;}for(i=0;(i<gdMaxColors);i++){if(!gdGetByte(&im->red[i],in)){gotofail1;}if(!gdGetByte(&im->green[i],in)){gotofail1;}if(!gdGetByte(&im->blue[i],in)){gotofail1;}if(gd2xFlag){if(!gdGetByte(&im->alpha[i],in)){gotofail1;}}}for(i=0;(i<im->colorsTotal);i++){im->open[i]=0;};returnTRUE;fail1:returnFALSE;}/* *//* Use the common basic header info to make the image object. *//* */staticgdImagePtr_gdCreateFromFile(gdIOCtx*in,int*sx,int*sy){gdImagePtrim;intgd2xFlag=0;inttrueColorFlag=0;if(!gdGetWord(sx,in)){gotofail1;}if((*sx==65535)||(*sx==65534)){/* This is a gd 2.0 .gd file */gd2xFlag=1;/* 2.0.12: 65534 signals a truecolor .gd file. There is a slight redundancy here but we can live with it. */if(*sx==65534){trueColorFlag=1;}if(!gdGetWord(sx,in)){gotofail1;}}if(!gdGetWord(sy,in)){gotofail1;}GD2_DBG(printf("Image is %dx%d\n",*sx,*sy));if(trueColorFlag){im=gdImageCreateTrueColor(*sx,*sy);}else{im=gdImageCreate(*sx,*sy);}if(!im){gotofail1;}if(!_gdGetColors(in,im,gd2xFlag)){gotofail2;}returnim;fail2:gdImageDestroy(im);fail1:return0;}BGD_DECLARE(gdImagePtr)gdImageCreateFromGd(FILE*inFile){gdImagePtrim;gdIOCtx*in;in=gdNewFileCtx(inFile);if(in==NULL)returnNULL;im=gdImageCreateFromGdCtx(in);in->gd_free(in);returnim;}BGD_DECLARE(gdImagePtr)gdImageCreateFromGdPtr(intsize,void*data){gdImagePtrim;gdIOCtx*in=gdNewDynamicCtxEx(size,data,0);if(!in)return0;im=gdImageCreateFromGdCtx(in);in->gd_free(in);returnim;}BGD_DECLARE(gdImagePtr)gdImageCreateFromGdCtx(gdIOCtxPtrin){intsx,sy;intx,y;gdImagePtrim;/* Read the header */im=_gdCreateFromFile(in,&sx,&sy);if(im==NULL){gotofail1;};/* Then the data... *//* 2.0.12: support truecolor properly in .gd as well as in .gd2. Problem reported by Andreas Pfaller. */if(im->trueColor){for(y=0;(y<sy);y++){for(x=0;(x<sx);x++){intpix;if(!gdGetInt(&pix,in)){gotofail2;}im->tpixels[y][x]=pix;}}}else{for(y=0;(y<sy);y++){for(x=0;(x<sx);x++){intch;ch=gdGetC(in);if(ch==EOF){gotofail2;}/* ROW-MAJOR IN GD 1.3 */im->pixels[y][x]=ch;}}}returnim;fail2:gdImageDestroy(im);fail1:return0;}void_gdPutColors(gdImagePtrim,gdIOCtx*out){inti;gdPutC(im->trueColor,out);if(!im->trueColor){gdPutWord(im->colorsTotal,out);}gdPutInt(im->transparent,out);if(!im->trueColor){for(i=0;(i<gdMaxColors);i++){gdPutC((unsignedchar)im->red[i],out);gdPutC((unsignedchar)im->green[i],out);gdPutC((unsignedchar)im->blue[i],out);gdPutC((unsignedchar)im->alpha[i],out);}}}staticvoid_gdPutHeader(gdImagePtrim,gdIOCtx*out){/* 65535 indicates this is a gd 2.x .gd file. 2.0.12: 65534 indicates truecolor. */if(im->trueColor){gdPutWord(65534,out);}else{gdPutWord(65535,out);}gdPutWord(im->sx,out);gdPutWord(im->sy,out);_gdPutColors(im,out);}staticvoid_gdImageGd(gdImagePtrim,gdIOCtx*out){intx,y;_gdPutHeader(im,out);for(y=0;(y<im->sy);y++){for(x=0;(x<im->sx);x++){/* ROW-MAJOR IN GD 1.3 */if(im->trueColor){gdPutInt(im->tpixels[y][x],out);}else{gdPutC((unsignedchar)im->pixels[y][x],out);}}}}BGD_DECLARE(void)gdImageGd(gdImagePtrim,FILE*outFile){gdIOCtx*out=gdNewFileCtx(outFile);if(out==NULL)return;_gdImageGd(im,out);out->gd_free(out);}BGD_DECLARE(void*)gdImageGdPtr(gdImagePtrim,int*size){void*rv;gdIOCtx*out=gdNewDynamicCtx(2048,NULL);if(out==NULL)returnNULL;_gdImageGd(im,out);rv=gdDPExtractData(out,size);out->gd_free(out);returnrv;}