Пример #1
0
void term_destination(j_compress_ptr cinfo)
{
	my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
	size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;

	/* Write any data remaining in the buffer */
	if(datacount > 0) {
		if(gdPutBuf(dest->buffer, datacount, dest->outfile) != datacount) {
			ERREXIT(cinfo, JERR_FILE_WRITE);
		}
	}
}
Пример #2
0
safeboolean empty_output_buffer(j_compress_ptr cinfo)
{
	my_dest_ptr dest = (my_dest_ptr)cinfo->dest;

	if(gdPutBuf(dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) != (size_t)OUTPUT_BUF_SIZE) {
		ERREXIT(cinfo, JERR_FILE_WRITE);
	}

	dest->pub.next_output_byte = dest->buffer;
	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;

	return TRUE;
}
Пример #3
0
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 = 0;
  int idxSize;
  t_chunk_info *chunkIdx = NULL;
  int posSave;
  int bytesPerPixel = im->trueColor ? 4 : 1;
  int compMax = 0;

  /*printf("Trying to write GD2 file\n"); */

  /* */
  /* Force fmt to a valid value since we don't return anything. */
  /* */
  if ((fmt != GD2_FMT_RAW) && (fmt != GD2_FMT_COMPRESSED))
    {
      fmt = im->trueColor ? GD2_FMT_TRUECOLOR_COMPRESSED : GD2_FMT_COMPRESSED;
    };
  if (im->trueColor)
    {
      fmt += 2;
    }
  /* */
  /* 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 large - 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 (gd2_compressed (fmt))
    {
      /* */
      /* 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);
			if (!chunkData) {
				goto fail;
			}
      compData = gdCalloc (compMax, 1);
			if (!compData) {
				goto fail;
			}

      /* */
      /* 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);
      if (!chunkIdx) {
        goto fail;
      }
    };

  _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 (gd2_compressed (fmt))
		{
		  for (x = xlo; x < xhi; x++)
		    {
		      /* 2.0.11: use truecolor pixel array. TBB */
		      /*GD2_DBG(printf("%d...",x)); */
		      if (im->trueColor)
			{
			  int p = im->tpixels[y][x];
			  chunkData[chunkLen++] = gdTrueColorGetAlpha (p);
			  chunkData[chunkLen++] = gdTrueColorGetRed (p);
			  chunkData[chunkLen++] = gdTrueColorGetGreen (p);
			  chunkData[chunkLen++] = gdTrueColorGetBlue (p);
			}
		      else
			{
			  int p = im->pixels[y][x];
			  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 (gd2_compressed (fmt))
	    {
	      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)
		    {
			fprintf(stderr, "gd write error\n");
		    };
		};
	    };
	};
    };
  if (gd2_compressed (fmt))
    {
      /* 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);
    };

  /*printf("Memory block size is %d\n",gdTell(out)); */
fail:
  GD2_DBG (printf ("Freeing memory\n"));

	if (chunkData) {
		gdFree (chunkData);
	}
	if (compData) {
		gdFree (compData);
	} 
	if (chunkIdx) {
		gdFree (chunkIdx);
	}
  GD2_DBG (printf ("Done\n"));

}
Пример #4
0
static void gdPngWriteData(png_structp png_ptr,
	png_bytep data, png_size_t length)
{
	gdPutBuf(data, length, (gdIOCtx *)
		png_get_io_ptr(png_ptr));
}
Пример #5
0
static void
GIFEncode(gdIOCtxPtr fp, int GWidth, int GHeight, int GInterlace, int Background, int Transparent, int BitsPerPixel, int *Red, int *Green, int *Blue, gdImagePtr im)
{
        int B;
        int RWidth, RHeight;
        int LeftOfs, TopOfs;
        int Resolution;
        int ColorMapSize;
        int InitCodeSize;
        int i;
		GifCtx ctx;

		memset(&ctx, 0, sizeof(ctx));
        ctx.Interlace = GInterlace;
		ctx.in_count = 1;

        ColorMapSize = 1 << BitsPerPixel;

        RWidth = ctx.Width = GWidth;
        RHeight = ctx.Height = GHeight;
        LeftOfs = TopOfs = 0;

        Resolution = BitsPerPixel;

        /*
         * Calculate number of bits we are expecting
         */
        ctx.CountDown = (long)ctx.Width * (long)ctx.Height;

        /*
         * Indicate which pass we are on (if interlace)
         */
        ctx.Pass = 0;

        /*
         * The initial code size
         */
        if( BitsPerPixel <= 1 )
                InitCodeSize = 2;
        else
                InitCodeSize = BitsPerPixel;

        /*
         * Set up the current x and y position
         */
        ctx.curx = ctx.cury = 0;

        /*
         * Write the Magic header
         */
        gdPutBuf(Transparent < 0 ? "GIF87a" : "GIF89a", 6, fp );

        /*
         * Write out the screen width and height
         */
        gifPutWord( RWidth, fp );
        gifPutWord( RHeight, fp );

        /*
         * Indicate that there is a global colour map
         */
        B = 0x80;       /* Yes, there is a color map */

        /*
         * OR in the resolution
         */
        B |= (Resolution - 1) << 5;

        /*
         * OR in the Bits per Pixel
         */
        B |= (BitsPerPixel - 1);

        /*
         * Write it out
         */
        gdPutC( B, fp );

        /*
         * Write out the Background colour
         */
        gdPutC( Background, fp );

        /*
         * Byte of 0's (future expansion)
         */
        gdPutC( 0, fp );

        /*
         * Write out the Global Colour Map
         */
        for( i=0; i<ColorMapSize; ++i ) {
                gdPutC( Red[i], fp );
                gdPutC( Green[i], fp );
                gdPutC( Blue[i], fp );
        }

	/*
	 * Write out extension for transparent colour index, if necessary.
	 */
	if ( Transparent >= 0 ) {
	    gdPutC( '!', fp );
	    gdPutC( 0xf9, fp );
	    gdPutC( 4, fp );
	    gdPutC( 1, fp );
	    gdPutC( 0, fp );
	    gdPutC( 0, fp );
	    gdPutC( (unsigned char) Transparent, fp );
	    gdPutC( 0, fp );
	}

        /*
         * Write an Image separator
         */
        gdPutC( ',', fp );

        /*
         * Write the Image header
         */

        gifPutWord( LeftOfs, fp );
        gifPutWord( TopOfs, fp );
        gifPutWord( ctx.Width, fp );
        gifPutWord( ctx.Height, fp );

        /*
         * Write out whether or not the image is interlaced
         */
        if( ctx.Interlace )
                gdPutC( 0x40, fp );
        else
                gdPutC( 0x00, fp );

        /*
         * Write out the initial code size
         */
        gdPutC( InitCodeSize, fp );

        /*
         * Go and actually compress the data
         */
        compress( InitCodeSize+1, fp, im, &ctx );

        /*
         * Write out a Zero-length packet (to end the series)
         */
        gdPutC( 0, fp );

        /*
         * Write the GIF file terminator
         */
        gdPutC( ';', fp );
}
Пример #6
0
/*
  Function: gdImageGifAnimBeginCtx

    Like <gdImageGifAnimBegin> except that it outputs to <gdIOCtx>.
    See <gdImageGifAnimBegin>.

  Parameters:

    im          - The reference image
    out         - Pointer to the output <gdIOCtx>.
    GlobalCM    - Global colormap flag: 1 -> yes, 0 -> no, -1 -> do default
    Loops       - Loop count; 0 -> infinite, -1 means no loop

  Returns:

    Nothing.

*/
BGD_DECLARE(void) gdImageGifAnimBeginCtx(gdImagePtr im, gdIOCtxPtr out, int GlobalCM, int Loops)
{
	int B;
	int RWidth, RHeight;
	int Resolution;
	int ColorMapSize;
	int BitsPerPixel;
	int Background = 0;
	int i;

	/* Default is to use global color map */
	if (GlobalCM < 0) {
		GlobalCM = 1;
	}

	BitsPerPixel = colorstobpp(im->colorsTotal);
	ColorMapSize = 1 << BitsPerPixel;

	RWidth = im->sx;
	RHeight = im->sy;

	Resolution = BitsPerPixel;

	/* Write the Magic header */
	gdPutBuf("GIF89a", 6, out);

	/* Write out the screen width and height */
	gifPutWord(RWidth, out);
	gifPutWord(RHeight, out);

	/* Indicate that there is a global colour map */
	B = GlobalCM ? 0x80 : 0;

	/* OR in the resolution */
	B |= (Resolution - 1) << 4;

	/* OR in the Bits per Pixel */
	B |= (BitsPerPixel - 1);

	/* Write it out */
	gdPutC(B, out);

	/* Write out the Background colour */
	gdPutC(Background, out);

	/* Byte of 0's (future expansion) */
	gdPutC(0, out);

	/* Write out the Global Colour Map */
	if(GlobalCM) {
		for(i = 0; i < ColorMapSize; ++i) {
			gdPutC(im->red[i], out);
			gdPutC(im->green[i], out);
			gdPutC(im->blue[i], out);
		}
	}

	if(Loops >= 0) {
		gdPutBuf("!\377\13NETSCAPE2.0\3\1", 16, out);
		gifPutWord(Loops, out);
		gdPutC(0, out);
	}
}