⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gd_gd2.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   * gd_gd2.c   *   * Implements the I/O and support for the GD2 format.   *   * Changing the definition of GD2_DBG (below) will cause copious messages   * to be displayed while it processes requests.   *   * Designed, Written & Copyright 1999, Philip Warner.   * */#include <stdio.h>#include <errno.h>#include <math.h>#include <string.h>#include <stdlib.h>#include <zlib.h>#include "gd.h"#include "gdhelpers.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)typedef struct  {    int offset;    int size;  }t_chunk_info;extern int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag);extern void _gdPutColors (gdImagePtr im, gdIOCtx * out);/* *//* Read the extra info in the gd2 header. *//* */staticint_gd2GetHeader (gdIOCtxPtr in, int *sx, int *sy, int *cs, int *vers, int *fmt, int *ncx, int *ncy, t_chunk_info ** chunkIdx){  int i;  int ch;  char id[5];  t_chunk_info *cidx;  int sidx;  int nc;  GD2_DBG (printf ("Reading gd2 header info\n"));  for (i = 0; i < 4; i++)    {      ch = gdGetC (in);      if (ch == EOF)	{	  goto fail1;	};      id[i] = ch;    };  id[4] = 0;  GD2_DBG (printf ("Got file code: %s\n", id));  /* Equiv. of 'magick'.  */  if (strcmp (id, GD2_ID) != 0)    {      GD2_DBG (printf ("Not a valid gd2 file\n"));      goto fail1;    };  /* Version */  if (gdGetWord (vers, in) != 1)    {      goto fail1;    };  GD2_DBG (printf ("Version: %d\n", *vers));  if ((*vers != 1) && (*vers != 2))    {      GD2_DBG (printf ("Bad version: %d\n", *vers));      goto fail1;    };  /* Image Size */  if (!gdGetWord (sx, in))    {      GD2_DBG (printf ("Could not get x-size\n"));      goto fail1;    }  if (!gdGetWord (sy, in))    {      GD2_DBG (printf ("Could not get y-size\n"));      goto fail1;    }  GD2_DBG (printf ("Image is %dx%d\n", *sx, *sy));  /* Chunk Size (pixels, not bytes!) */  if (gdGetWord (cs, in) != 1)    {      goto fail1;    };  GD2_DBG (printf ("ChunkSize: %d\n", *cs));  if ((*cs < GD2_CHUNKSIZE_MIN) || (*cs > GD2_CHUNKSIZE_MAX))    {      GD2_DBG (printf ("Bad chunk size: %d\n", *cs));      goto fail1;    };  /* Data Format */  if (gdGetWord (fmt, in) != 1)    {      goto fail1;    };  GD2_DBG (printf ("Format: %d\n", *fmt));  if ((*fmt != GD2_FMT_RAW) && (*fmt != GD2_FMT_COMPRESSED))    {      GD2_DBG (printf ("Bad data format: %d\n", *fmt));      goto fail1;    };  /* # of chunks wide */  if (gdGetWord (ncx, in) != 1)    {      goto fail1;    };  GD2_DBG (printf ("%d Chunks Wide\n", *ncx));  /* # of chunks high */  if (gdGetWord (ncy, in) != 1)    {      goto fail1;    };  GD2_DBG (printf ("%d Chunks vertically\n", *ncy));  if ((*fmt) == GD2_FMT_COMPRESSED)    {      nc = (*ncx) * (*ncy);      GD2_DBG (printf ("Reading %d chunk index entries\n", nc));      sidx = sizeof (t_chunk_info) * nc;      cidx = gdCalloc (sidx, 1);      for (i = 0; i < nc; i++)	{	  if (gdGetInt (&cidx[i].offset, in) != 1)	    {	      goto fail1;	    };	  if (gdGetInt (&cidx[i].size, in) != 1)	    {	      goto fail1;	    };	};      *chunkIdx = cidx;    };  GD2_DBG (printf ("gd2 header complete\n"));  return 1;fail1:  return 0;}static  gdImagePtr_gd2CreateFromFile (gdIOCtxPtr in, int *sx, int *sy,		    int *cs, int *vers, int *fmt,		    int *ncx, int *ncy, t_chunk_info ** cidx){  gdImagePtr im;  if (_gd2GetHeader (in, sx, sy, cs, vers, fmt, ncx, ncy, cidx) != 1)    {      GD2_DBG (printf ("Bad GD2 header\n"));      goto fail1;    }  im = gdImageCreate (*sx, *sy);  if (im == NULL)    {      GD2_DBG (printf ("Could not create gdImage\n"));      goto fail1;    };  if (!_gdGetColors (in, im, (*vers) == 2))    {      GD2_DBG (printf ("Could not read color palette\n"));      goto fail2;    }  GD2_DBG (printf ("Image palette completed: %d colours\n", im->colorsTotal));  return im;fail2:  gdImageDestroy (im);  return 0;fail1:  return 0;}staticint_gd2ReadChunk (int offset, char *compBuf, int compSize, char *chunkBuf, uLongf * chunkLen, gdIOCtx * in){  int zerr;  if (gdTell (in) != offset)    {      GD2_DBG (printf ("Positioning in file to %d\n", offset));      gdSeek (in, offset);    }  else    {      GD2_DBG (printf ("Already Positioned in file to %d\n", offset));    };  /* Read and uncompress an entire chunk. */  GD2_DBG (printf ("Reading file\n"));  if (gdGetBuf (compBuf, compSize, in) != compSize)    {      return FALSE;    };  GD2_DBG (printf ("Got %d bytes. Uncompressing into buffer of %d bytes\n", compSize, *chunkLen));  zerr = uncompress ((unsigned char *) chunkBuf, chunkLen,		     (unsigned char *) compBuf, compSize);  if (zerr != Z_OK)    {      GD2_DBG (printf ("Error %d from uncompress\n", zerr));      return FALSE;    };  GD2_DBG (printf ("Got chunk\n"));  return TRUE;}gdImagePtrgdImageCreateFromGd2 (FILE * inFile){  gdIOCtx *in = gdNewFileCtx (inFile);  gdImagePtr im;  im = gdImageCreateFromGd2Ctx (in);  in->free (in);  return im;}gdImagePtrgdImageCreateFromGd2Ctx (gdIOCtxPtr in){  int sx, sy;  int i;  int ncx, ncy, nc, cs, cx, cy;  int x, y, ylo, yhi, xlo, xhi;  int ch, vers, fmt;  t_chunk_info *chunkIdx = NULL;	/* So we can gdFree it with impunity. */  unsigned char *chunkBuf = NULL;	/* So we can gdFree it with impunity. */  int chunkNum = 0;  int chunkMax;  uLongf chunkLen;  int chunkPos;  int compMax;  int bytesPerPixel;  char *compBuf = NULL;		/* So we can gdFree it with impunity. */  gdImagePtr im;  /* Get the header */  im = _gd2CreateFromFile (in, &sx, &sy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx);  if (im == NULL)    {      return 0;    };  bytesPerPixel = im->trueColor ? 4 : 1;  nc = ncx * ncy;  if (fmt == GD2_FMT_COMPRESSED)    {      /* Find the maximum compressed chunk size. */      compMax = 0;      for (i = 0; (i < nc); i++)	{	  if (chunkIdx[i].size > compMax)	    {	      compMax = chunkIdx[i].size;	    };	};      compMax++;      /* Allocate buffers */      chunkMax = cs * bytesPerPixel * cs;      chunkBuf = gdCalloc (chunkMax, 1);      compBuf = gdCalloc (compMax, 1);      GD2_DBG (printf ("Largest compressed chunk is %d bytes\n", compMax));    };/*      if ( (ncx != sx / cs) || (ncy != sy / cs)) { *//*              goto fail2; *//*      }; */  /* Read the data... */  for (cy = 0; (cy < ncy); cy++)    {      for (cx = 0; (cx < ncx); cx++)	{	  ylo = cy * cs;	  yhi = ylo + cs;	  if (yhi > im->sy)	    {	      yhi = im->sy;	    };	  GD2_DBG (printf ("Processing Chunk %d (%d, %d), y from %d to %d\n", chunkNum, cx, cy, ylo, yhi));	  if (fmt == GD2_FMT_COMPRESSED)	    {	      chunkLen = chunkMax;	      if (!_gd2ReadChunk (chunkIdx[chunkNum].offset,				  compBuf,				  chunkIdx[chunkNum].size,				  chunkBuf, &chunkLen, in))		{		  GD2_DBG (printf ("Error reading comproessed chunk\n"));		  goto fail2;		};	      chunkPos = 0;	    };	  for (y = ylo; (y < yhi); y++)	    {	      xlo = cx * cs;	      xhi = xlo + cs;	      if (xhi > im->sx)		{		  xhi = im->sx;		};	      /*GD2_DBG(printf("y=%d: ",y)); */	      if (fmt == GD2_FMT_RAW)		{		  for (x = xlo; x < xhi; x++)		    {		      if (im->trueColor)			{			  if (!gdGetInt (&im->tpixels[y][x], in))			    {			      /*printf("EOF while reading\n"); */			      /*gdImageDestroy(im); */			      /*return 0; */			      im->tpixels[y][x] = 0;			    }			}		      else			{			  int ch;			  if (!gdGetByte (&ch, in))			    {			      /*printf("EOF while reading\n"); */			      /*gdImageDestroy(im); */			      /*return 0; */			      ch = 0;			    }			  im->pixels[y][x] = ch;			}		    }		}	      else		{		  for (x = xlo; x < xhi; x++)		    {		      if (im->trueColor)			{			  /* 2.0.1: work around a gcc bug by being verbose.			     TBB */			  int a = chunkBuf[chunkPos++] << 24;			  int r = chunkBuf[chunkPos++] << 16;			  int g = chunkBuf[chunkPos++] << 8;			  int b = chunkBuf[chunkPos++];			  im->pixels[y][x] = a + r + g + b;			}		      else			{			  im->pixels[y][x] = chunkBuf[chunkPos++];			}		    };		};	      /*GD2_DBG(printf("\n")); */	    };	  chunkNum++;	};    };  GD2_DBG (printf ("Freeing memory\n"));  gdFree (chunkBuf);  gdFree (compBuf);  gdFree (chunkIdx);  GD2_DBG (printf ("Done\n"));  return im;fail2:  gdImageDestroy (im);  gdFree (chunkBuf);  gdFree (compBuf);  gdFree (chunkIdx);  return 0;}gdImagePtrgdImageCreateFromGd2Part (FILE * inFile, int srcx, int srcy, int w, int h){  gdImagePtr im;  gdIOCtx *in = gdNewFileCtx (inFile);  im = gdImageCreateFromGd2PartCtx (in, srcx, srcy, w, h);  in->free (in);  return im;}gdImagePtrgdImageCreateFromGd2PartCtx (gdIOCtx * in, int srcx, int srcy, int w, int h){  int scx, scy, ecx, ecy, fsx, fsy;  int nc, ncx, ncy, cs, cx, cy;  int x, y, ylo, yhi, xlo, xhi;  int dstart, dpos;  int i;  int ch, vers, fmt;  t_chunk_info *chunkIdx = NULL;  char *chunkBuf = NULL;  int chunkNum;  int chunkMax;  uLongf chunkLen;  int chunkPos;  int compMax;  char *compBuf = NULL;  gdImagePtr im;  /* */  /* The next few lines are basically copied from gd2CreateFromFile */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -