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

📄 gd_gd2.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* - we change the file size, so don't want to use the code directly. */  /*   but we do need to know the file size. */  /* */  if (_gd2GetHeader (in, &fsx, &fsy, &cs, &vers, &fmt, &ncx, &ncy, &chunkIdx) != 1)    {      goto fail1;    }  GD2_DBG (printf ("File size is %dx%d\n", fsx, fsy));  /* This is the difference - make a file based on size of chunks. */  im = gdImageCreate (w, h);  if (im == NULL)    {      goto fail1;    };  if (!_gdGetColors (in, im, vers == 2))    {      goto fail2;    }  GD2_DBG (printf ("Image palette completed: %d colours\n", im->colorsTotal));  /* Process the header info */  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++;      if (im->trueColor)	{	  chunkMax = cs * cs * 4;	}      else	{	  chunkMax = cs * cs;	}      chunkBuf = gdCalloc (chunkMax, 1);      compBuf = gdCalloc (compMax, 1);    };/*      Don't bother with this... *//*      if ( (ncx != sx / cs) || (ncy != sy / cs)) { *//*              goto fail2; *//*      }; */  /* Work out start/end chunks */  scx = srcx / cs;  scy = srcy / cs;  if (scx < 0)    {      scx = 0;    };  if (scy < 0)    {      scy = 0;    };  ecx = (srcx + w) / cs;  ecy = (srcy + h) / cs;  if (ecx >= ncx)    {      ecx = ncx - 1;    };  if (ecy >= ncy)    {      ecy = ncy - 1;    };  /* Remember file position of image data. */  dstart = gdTell (in);  GD2_DBG (printf ("Data starts at %d\n", dstart));  /* Loop through the chunks. */  for (cy = scy; (cy <= ecy); cy++)    {      ylo = cy * cs;      yhi = ylo + cs;      if (yhi > fsy)	{	  yhi = fsy;	};      for (cx = scx; (cx <= ecx); cx++)	{	  xlo = cx * cs;	  xhi = xlo + cs;	  if (xhi > fsx)	    {	      xhi = fsx;	    };	  GD2_DBG (printf ("Processing Chunk (%d, %d), from %d to %d\n", cx, cy, ylo, yhi));	  if (fmt == GD2_FMT_RAW)	    {	      GD2_DBG (printf ("Using raw format data\n"));	      if (im->trueColor)		{		  dpos = (cy * (cs * fsx) + cx * cs * (yhi - ylo) * 4) + dstart;		}	      else		{		  dpos = cy * (cs * fsx) + cx * cs * (yhi - ylo) + dstart;		}	      if (gdSeek (in, dpos) != 0)		{		  printf ("Error from seek: %d\n", errno);		  goto fail2;		};	      GD2_DBG (printf ("Reading (%d, %d) from position %d\n", cx, cy, dpos - dstart));	    }	  else	    {	      chunkNum = cx + cy * ncx;	      chunkLen = chunkMax;	      if (!_gd2ReadChunk (chunkIdx[chunkNum].offset,				  compBuf,				  chunkIdx[chunkNum].size,				  chunkBuf, &chunkLen, in))		{		  printf ("Error reading comproessed chunk\n");		  goto fail2;		};	      chunkPos = 0;	      GD2_DBG (printf ("Reading (%d, %d) from chunk %d\n", cx, cy, chunkNum));	    };	  GD2_DBG (printf ("   into (%d, %d) - (%d, %d)\n", xlo, ylo, xhi, yhi));	  for (y = ylo; (y < yhi); y++)	    {	      for (x = xlo; x < xhi; x++)		{		  if (fmt == GD2_FMT_RAW)		    {		      if (im->trueColor)			{			  if (!gdGetInt (&ch, in))			    {			      ch = 0;			      /*printf("EOF while reading file\n"); */			      /*goto fail2; */			    }			}		      else			{			  ch = gdGetC (in);			  if (ch == EOF)			    {			      ch = 0;			      /*printf("EOF while reading file\n"); */			      /*goto fail2; */			    }			}		    }		  else		    {		      if (im->trueColor)			{			  ch = chunkBuf[chunkPos++] << 24 +			    chunkBuf[chunkPos++] << 16 +			    chunkBuf[chunkPos++] << 8 +			    chunkBuf[chunkPos++];			}		      else			{			  ch = chunkBuf[chunkPos++];			}		    };		  /* Only use a point that is in the image. */		  if ((x >= srcx) && (x < (srcx + w)) && (x < fsx) && (x >= 0)		  && (y >= srcy) && (y < (srcy + h)) && (y < fsy) && (y >= 0)		    )		    {		      im->pixels[y - srcy][x - srcx] = ch;		    }		};	    };	};    };  gdFree (chunkBuf);  gdFree (compBuf);  gdFree (chunkIdx);  return im;fail2:  gdImageDestroy (im);fail1:  gdFree (chunkBuf);  gdFree (compBuf);  gdFree (chunkIdx);  return 0;}staticvoid_gd2PutHeader (gdImagePtr im, gdIOCtx * out, int cs, int fmt, int cx, int cy){  int i;  /* Send the gd2 id, to verify file format. */  for (i = 0; i < 4; i++)    {      gdPutC ((unsigned char) (GD2_ID[i]), out);    };  /* */  /* We put the version info first, so future versions can easily change header info. */  /* */  gdPutWord (GD2_VERS, out);  gdPutWord (im->sx, out);  gdPutWord (im->sy, out);  gdPutWord (cs, out);  gdPutWord (fmt, out);  gdPutWord (cx, out);  gdPutWord (cy, out);}static void_gdImageGd2 (gdImagePtr im, gdIOCtx * out, int cs, int fmt){  int ncx, ncy, cx, cy;  int x, y, ylo, yhi, xlo, xhi;  int chunkLen;  int chunkNum = 0;  char *chunkData = NULL;	/* So we can gdFree it with impunity. */  char *compData = NULL;	/* So we can gdFree it with impunity. */  uLongf compLen;  int idxPos;  int idxSize;  t_chunk_info *chunkIdx = NULL;  int posSave;  int bytesPerPixel = im->trueColor ? 4 : 1;  int compMax;  /*printf("Trying to write GD2 file\n"); */  /* */  /* Force fmt to a valid value since we don't return anything. */  /* */  if ((fmt == 0) || ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED)))    {      fmt = GD2_FMT_COMPRESSED;    };  /* */  /* Make sure chunk size is valid. These are arbitrary values; 64 because it seems */  /* a little silly to expect performance improvements on a 64x64 bit scale, and  */  /* 4096 because we buffer one chunk, and a 16MB buffer seems a little largei - it may be */  /* OK for one user, but for another to read it, they require the buffer. */  /* */  if (cs == 0)    {      cs = GD2_CHUNKSIZE;    }  else if (cs < GD2_CHUNKSIZE_MIN)    {      cs = GD2_CHUNKSIZE_MIN;    }  else if (cs > GD2_CHUNKSIZE_MAX)    {      cs = GD2_CHUNKSIZE_MAX;    };  /* Work out number of chunks. */  ncx = im->sx / cs + 1;  ncy = im->sy / cs + 1;  /* Write the standard header. */  _gd2PutHeader (im, out, cs, fmt, ncx, ncy);  if (fmt == GD2_FMT_COMPRESSED)    {      /* */      /* Work out size of buffer for compressed data, If CHUNKSIZE is large, */      /* then these will be large! */      /* */      /* The zlib notes say output buffer size should be (input size) * 1.01 * 12 */      /* - we'll use 1.02 to be paranoid. */      /* */      compMax = cs * bytesPerPixel * cs * 1.02 + 12;      /* */      /* Allocate the buffers.  */      /* */      chunkData = gdCalloc (cs * bytesPerPixel * cs, 1);      compData = gdCalloc (compMax, 1);      /* */      /* Save the file position of chunk index, and allocate enough space for */      /* each chunk_info block . */      /* */      idxPos = gdTell (out);      idxSize = ncx * ncy * sizeof (t_chunk_info);      GD2_DBG (printf ("Index size is %d\n", idxSize));      gdSeek (out, idxPos + idxSize);      chunkIdx = gdCalloc (idxSize * sizeof (t_chunk_info), 1);    };  _gdPutColors (im, out);  GD2_DBG (printf ("Size: %dx%d\n", im->sx, im->sy));  GD2_DBG (printf ("Chunks: %dx%d\n", ncx, ncy));  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 (%dx%d), y from %d to %d\n", cx, cy, ylo, yhi));	  chunkLen = 0;	  for (y = ylo; (y < yhi); y++)	    {	      /*GD2_DBG(printf("y=%d: ",y)); */	      xlo = cx * cs;	      xhi = xlo + cs;	      if (xhi > im->sx)		{		  xhi = im->sx;		};	      if (fmt == GD2_FMT_COMPRESSED)		{		  for (x = xlo; x < xhi; x++)		    {		      int p = im->pixels[y][x];		      /*GD2_DBG(printf("%d...",x)); */		      if (im->trueColor)			{			  chunkData[chunkLen++] = gdTrueColorGetAlpha (p);			  chunkData[chunkLen++] = gdTrueColorGetRed (p);			  chunkData[chunkLen++] = gdTrueColorGetGreen (p);			  chunkData[chunkLen++] = gdTrueColorGetBlue (p);			}		      else			{			  chunkData[chunkLen++] = p;			}		    };		}	      else		{		  for (x = xlo; x < xhi; x++)		    {		      /*GD2_DBG(printf("%d, ",x)); */		      if (im->trueColor)			{			  gdPutInt (im->tpixels[y][x], out);			}		      else			{			  gdPutC ((unsigned char) im->pixels[y][x], out);			}		    };		};	      /*GD2_DBG(printf("y=%d done.\n",y)); */	    };	  if (fmt == GD2_FMT_COMPRESSED)	    {	      compLen = compMax;	      if (compress ((unsigned char *)			    &compData[0], &compLen,			    (unsigned char *) &chunkData[0],			    chunkLen) != Z_OK)		{		  printf ("Error from compressing\n");		}	      else		{		  chunkIdx[chunkNum].offset = gdTell (out);		  chunkIdx[chunkNum++].size = compLen;		  GD2_DBG (printf ("Chunk %d size %d offset %d\n", chunkNum, chunkIdx[chunkNum - 1].size, chunkIdx[chunkNum - 1].offset));		  if (gdPutBuf (compData, compLen, out) <= 0)		    {		      /* Any alternate suggestions for handling this? */		      printf ("Error %d on write\n", errno);		    };		};	    };	};    };  if (fmt == GD2_FMT_COMPRESSED)    {      /* Save the position, write the index, restore position (paranoia). */      GD2_DBG (printf ("Seeking %d to write index\n", idxPos));      posSave = gdTell (out);      gdSeek (out, idxPos);      GD2_DBG (printf ("Writing index\n"));      for (x = 0; x < chunkNum; x++)	{	  GD2_DBG (printf ("Chunk %d size %d offset %d\n", x, chunkIdx[x].size, chunkIdx[x].offset));	  gdPutInt (chunkIdx[x].offset, out);	  gdPutInt (chunkIdx[x].size, out);	};      /* We don't use fwrite for *endian reasons. */      /*fwrite(chunkIdx, sizeof(int)*2, chunkNum, out); */      gdSeek (out, posSave);    };  GD2_DBG (printf ("Freeing memory\n"));  gdFree (chunkData);  gdFree (compData);  gdFree (chunkIdx);  GD2_DBG (printf ("Done\n"));  /*printf("Memory block size is %d\n",gdTell(out)); */}voidgdImageGd2 (gdImagePtr im, FILE * outFile, int cs, int fmt){  gdIOCtx *out = gdNewFileCtx (outFile);  _gdImageGd2 (im, out, cs, fmt);  out->free (out);}void *gdImageGd2Ptr (gdImagePtr im, int cs, int fmt, int *size){  void *rv;  gdIOCtx *out = gdNewDynamicCtx (2048, NULL);  _gdImageGd2 (im, out, cs, fmt);  rv = gdDPExtractData (out, size);  out->free (out);  return rv;}

⌨️ 快捷键说明

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