Example #1
0
/* create wbmp
 * -----------
 * create an empty wbmp
 */
Wbmp *createwbmp(int width, int height, int color)
{
	int i;
	Wbmp *wbmp;

	if((wbmp = (Wbmp *)gdMalloc(sizeof (Wbmp))) == NULL) {
		return (NULL);
	}

	if(overflow2(sizeof(int), width)) {
		gdFree(wbmp);
		return NULL;
	}

	if(overflow2(sizeof(int) * width, height)) {
		gdFree(wbmp);
		return NULL;
	}

	if((wbmp->bitmap = (int *)gdMalloc(sizeof(int) * width * height)) == NULL) {
		gdFree(wbmp);
		return NULL;
	}

	wbmp->width = width;
	wbmp->height = height;

	for(i = 0; i < width * height; wbmp->bitmap[i++] = color);

	return wbmp;
}
Example #2
0
/* grow (or shrink) dynamic pointer */
static int
gdReallocDynamic (dynamicPtr * dp, int required)
{
  void *newPtr;

  /* First try gdRealloc().  If that doesn't work, make a new
     memory block and copy. */
  if ((newPtr = gdRealloc (dp->data, required)))
    {
      dp->realSize = required;
      dp->data = newPtr;
      return TRUE;
    }

  /* create a new pointer */
  newPtr = gdMalloc (required);
  if (!newPtr)
    {
      dp->dataGood = FALSE;
      return FALSE;
    }

  /* copy the old data into it */
  memcpy (newPtr, dp->data, dp->logicalSize);
  gdFree (dp->data);
  dp->data = newPtr;

  dp->realSize = required;
  return TRUE;
}
Example #3
0
BGD_DECLARE(gdIOCtx *) gdNewDynamicCtxEx (int initialSize, void *data, int freeOKFlag)
{
  dpIOCtx *ctx;
  dynamicPtr *dp;

  ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
  if (ctx == NULL)
    {
      return NULL;
    }

  dp = newDynamic (initialSize, data, freeOKFlag);
  if (!dp)
    {
      gdFree (ctx);
      return NULL;
    };

  ctx->dp = dp;

  ctx->ctx.getC = dynamicGetchar;
  ctx->ctx.putC = dynamicPutchar;

  ctx->ctx.getBuf = dynamicGetbuf;
  ctx->ctx.putBuf = dynamicPutbuf;

  ctx->ctx.seek = dynamicSeek;
  ctx->ctx.tell = dynamicTell;

  ctx->ctx.gd_free = gdFreeDynamicCtx;

  return (gdIOCtx *) ctx;
}
Example #4
0
/* return data as a dynamic pointer */
BGD_DECLARE(gdIOCtx *) gdNewFileCtx(FILE *f)
{
	fileIOCtx *ctx;

	if (f == NULL) return NULL;
	ctx = (fileIOCtx *)gdMalloc(sizeof(fileIOCtx));
	if(ctx == NULL) {
		return NULL;
	}

	ctx->f = f;

	ctx->ctx.getC = fileGetchar;
	ctx->ctx.putC = filePutchar;

	ctx->ctx.getBuf = fileGetbuf;
	ctx->ctx.putBuf = filePutbuf;

	ctx->ctx.tell = fileTell;
	ctx->ctx.seek = fileSeek;

	ctx->ctx.gd_free = gdFreeFileCtx;

	return (gdIOCtx *)ctx;
}
Example #5
0
/* *********************************************************************

 * InitDynamic - Return a dynamically resizable void*
 *
 * *********************************************************************
 */
static int
allocDynamic (dynamicPtr * dp, int initialSize, void *data)
{

  if (data == NULL)
    {
      dp->logicalSize = 0;
      dp->dataGood = FALSE;
      dp->data = gdMalloc (initialSize);
    }
  else
    {
      dp->logicalSize = initialSize;
      dp->dataGood = TRUE;
      dp->data = data;
    }

  if (dp->data != NULL)
    {
      dp->realSize = initialSize;
      dp->dataGood = TRUE;
      dp->pos = 0;
      return TRUE;
    }
  else
    {
      dp->realSize = 0;
      return FALSE;
    }
}
Example #6
0
int
main ()
{
  unsigned char input[BUFSIZ];
  unsigned char *output;
  unsigned char *str;
  int c, i = 0;

  while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
    input[i++] = c;
  input[i] = '\0';

  printf ("input : %d bytes\n", strlen ((const char *) input));
  printf ("output: %d bytes\n", strwidth (input));

  output = (unsigned char *) gdMalloc (BUFSIZ);
  any2eucjp (output, input, BUFSIZ);
  str = output;
  while (*str != '\0')
    putchar (*(str++));
  putchar ('\n');
  gdFree (output);

  return 0;
}
Example #7
0
/*!	\brief Reads a TGA header.
 *	Reads the header block from a binary TGA file populating the referenced TGA structure.
 *	\param ctx Pointer to TGA binary file
 *	\param tga Pointer to TGA structure
 *	\return int 1 on sucess, -1 on failure	
 */
int read_header_tga(gdIOCtx *ctx, oTga *tga) {

	unsigned char header[18];

	if (gdGetBuf(header, sizeof(header), ctx) < 18) {
		fprintf(stderr, "fail to read header");
		return -1;	
	}

	tga->identsize = header[0];
	tga->colormaptype = header[1];
	tga->imagetype = header[2];
	tga->colormapstart = header[3] + (header[4] << 8);
	tga->colormaplength = header[5] + (header[6] << 8);
	tga->colormapbits = header[7];
	tga->xstart = header[8] + (header[9] << 8);
	tga->ystart = header[10] + (header[11] << 8);
	tga->width = header[12] + (header[13] << 8);
	tga->height = header[14] + (header[15] << 8);
	tga->bits = header[16];
	tga->alphabits = header[17] & 0x0f;
	tga->fliph = (header[17] & 0x10) ? 1 : 0;
	tga->flipv = (header[17] & 0x20) ? 0 : 1;

#if DEBUG 
	printf("format bps: %i\n", tga->bits);
	printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv);
	printf("alpha: %i\n", tga->alphabits);
	printf("wxh: %i %i\n", tga->width, tga->height);
#endif 

	switch(tga->bits) {
		case 8:
		case 16:
		case 24:
		case 32:
			break;
		default:
			fprintf(stderr, "bps %i not supported", tga->bits);
			return -1;
			break;
	}

	tga->ident = NULL;

	if (tga->identsize > 0) {
		tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char));
		if(tga->ident == NULL) {
			return -1;
		}

		gdGetBuf( &( tga->ident ), tga->identsize, ctx );
	}

	return 1;
}
Example #8
0
BGD_DECLARE(void *) gdImageGifAnimEndPtr(int *size)
{
	char *rv = (char *) gdMalloc(1);
	if(!rv) {
		return 0;
	}
	*rv = ';';
	*size = 1;
	return (void *)rv;
}
Example #9
0
void * gdCacheGet(gdCache_head_t *head, void *keydata)
{
	int i = 0;
	gdCache_element_t *elem, *prev = NULL, *prevprev = NULL;
	void *userdata;

	elem = head->mru;
	while(elem) {
		if((*(head->gdCacheTest))(elem->userdata, keydata)) {
			if(i) {
				/* if not already most-recently-used */
				/* relink to top of list */
				prev->next = elem->next;
				elem->next = head->mru;
				head->mru = elem;
			}

			return elem->userdata;
		}

		prevprev = prev;
		prev = elem;
		elem = elem->next;
		i++;
	}

	userdata = (*(head->gdCacheFetch))(&(head->error), keydata);
	if(!userdata) {
		/* if there was an error in the fetch then don't cache */
		return NULL;
	}

	if(i < head->size) {
		/* cache still growing - add new elem */
		elem = (gdCache_element_t *)gdMalloc(sizeof(gdCache_element_t));
		if(!elem) {
			(*(head->gdCacheRelease)) (userdata);
			return NULL;
 		}
	} else {
		/* cache full - replace least-recently-used */
		/* preveprev becomes new end of list */
		prevprev->next = NULL;
		elem = prev;
		(*(head->gdCacheRelease))(elem->userdata);
	}

	/* relink to top of list */
	elem->next = head->mru;
	head->mru = elem;
	elem->userdata = userdata;

	return userdata;
}
Example #10
0
/* return data as a dynamic pointer */
static dynamicPtr * newDynamic (int initialSize, void *data, int freeOKFlag)
{
	dynamicPtr *dp;
	dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));

	allocDynamic (dp, initialSize, data);

	dp->pos = 0;
	dp->freeOK = freeOKFlag;

	return dp;
}
Example #11
0
static void *
cacheFetch( char **error, void *key )
{
	key_value_t *map;

	map = (key_value_t *)gdMalloc(sizeof(key_value_t));
	map->key = *(int *)key;
	map->value = 3;

	*error = NULL;
	return (void *)map;
}
Example #12
0
unsigned int
strwidth (unsigned char *s)
{
  unsigned char *t;
  unsigned int i;

  t = (unsigned char *) gdMalloc (BUFSIZ);
  any2eucjp (t, s, BUFSIZ);
  i = strlen (t);
  gdFree (t);
  return i;
}
Example #13
0
/*!	\brief Reads a TGA header.
 *	Reads the header block from a binary TGA file populating the referenced TGA structure.
 *	\param ctx Pointer to TGA binary file
 *	\param tga Pointer to TGA structure
 *	\return int 1 on sucess, -1 on failure
 */
int read_header_tga(gdIOCtx *ctx, oTga *tga)
{

	unsigned char header[18];

	if (gdGetBuf(header, sizeof(header), ctx) < 18) {
		gd_error("fail to read header");
		return -1;
	}

	tga->identsize = header[0];
	tga->colormaptype = header[1];
	tga->imagetype = header[2];
	tga->colormapstart = header[3] + (header[4] << 8);
	tga->colormaplength = header[5] + (header[6] << 8);
	tga->colormapbits = header[7];
	tga->xstart = header[8] + (header[9] << 8);
	tga->ystart = header[10] + (header[11] << 8);
	tga->width = header[12] + (header[13] << 8);
	tga->height = header[14] + (header[15] << 8);
	tga->bits = header[16];
	tga->alphabits = header[17] & 0x0f;
	tga->fliph = (header[17] & 0x10) ? 1 : 0;
	tga->flipv = (header[17] & 0x20) ? 0 : 1;

#if DEBUG
	printf("format bps: %i\n", tga->bits);
	printf("flip h/v: %i / %i\n", tga->fliph, tga->flipv);
	printf("alpha: %i\n", tga->alphabits);
	printf("wxh: %i %i\n", tga->width, tga->height);
#endif

	if (!((tga->bits == TGA_BPP_24 && tga->alphabits == 0)
		|| (tga->bits == TGA_BPP_32 && tga->alphabits == 8)))
	{
		gd_error_ex(GD_WARNING, "gd-tga: %u bits per pixel with %u alpha bits not supported\n",
			tga->bits, tga->alphabits);
		return -1;
	}

	tga->ident = NULL;

	if (tga->identsize > 0) {
		tga->ident = (char *) gdMalloc(tga->identsize * sizeof(char));
		if(tga->ident == NULL) {
			return -1;
		}

		gdGetBuf(tga->ident, tga->identsize, ctx);
	}

	return 1;
}
Example #14
0
/* bring the palette colors in im2 to be closer to im1
 *
 */
BGD_DECLARE(int) gdImageColorMatch (gdImagePtr im1, gdImagePtr im2)
{
	unsigned long *buf; /* stores our calculations */
	unsigned long *bp; /* buf ptr */
	int color, rgb;
	int x,y;
	int count;

	if (!im1->trueColor) {
		return -1; /* im1 must be True Color */
	}
	if (im2->trueColor) {
		return -2; /* im2 must be indexed */
	}
	if ((im1->sx != im2->sx) || (im1->sy != im2->sy)) {
		return -3; /* the images are meant to be the same dimensions */
	}
	if (im2->colorsTotal < 1) {
		return -4; /* At least 1 color must be allocated */
	}

	buf = (unsigned long *)gdMalloc(sizeof(unsigned long) * 5 * im2->colorsTotal);
	memset (buf, 0, sizeof(unsigned long) * 5 * im2->colorsTotal );

	for (x=0; x < im1->sx; x++) {
		for( y=0; y<im1->sy; y++ ) {
			color = im2->pixels[y][x];
			rgb = im1->tpixels[y][x];
			bp = buf + (color * 5);
			(*(bp++))++;
			*(bp++) += gdTrueColorGetRed(rgb);
			*(bp++) += gdTrueColorGetGreen(rgb);
			*(bp++) += gdTrueColorGetBlue(rgb);
			*(bp++) += gdTrueColorGetAlpha(rgb);
		}
	}
	bp = buf;
	for (color=0; color < im2->colorsTotal; color++) {
		count = *(bp++);
		if( count > 0 ) {
			im2->red[color]		= *(bp++) / count;
			im2->green[color]	= *(bp++) / count;
			im2->blue[color]	= *(bp++) / count;
			im2->alpha[color]	= *(bp++) / count;
		} else {
			bp += 4;
		}
	}
	gdFree(buf);
	return 0;
}
Example #15
0
void gdClipSetAdd(gdImagePtr im,gdClipRectanglePtr rect)
{	gdClipRectanglePtr more;

	if (im->clip == 0)
	{	im->clip = gdMalloc (sizeof (gdClipSet));
		if (im->clip == 0) return;
		im->clip->max = 8;
		im->clip->count = 0;
		im->clip->list = gdMalloc (im->clip->max * sizeof (gdClipRectangle));
		if (im->clip->list == 0)
		{	gdFree (im->clip);
			im->clip = 0;
			return;
		}
	}
	if (im->clip->count == im->clip->max)
	{	more = gdRealloc (im->clip->list,(im->clip->max + 8) * sizeof (gdClipRectangle));
		if (more == 0) return;
		im->clip->max += 8;
	}
	im->clip->list[im->clip->count] = (*rect);
	im->clip->count++;
}
Example #16
0
/* create a new cache */
gdCache_head_t *
gdCacheCreate(
	int					size,
	gdCacheTestFn_t		gdCacheTest,
	gdCacheFetchFn_t	gdCacheFetch,
	gdCacheReleaseFn_t	gdCacheRelease ) 
{
	gdCache_head_t *head; 

	head = (gdCache_head_t *)gdMalloc(sizeof(gdCache_head_t));
	head->mru = NULL;
	head->size = size;
	head->gdCacheTest = gdCacheTest;
	head->gdCacheFetch = gdCacheFetch;
	head->gdCacheRelease = gdCacheRelease;
	return head;
}
Example #17
0
/* return data as a dynamic pointer */
static dynamicPtr *
newDynamic (int initialSize, void *data)
{
  dynamicPtr *dp;
  dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
  if (dp == NULL)
    {
      return NULL;
    }

  if (!allocDynamic (dp, initialSize, data))
    return NULL;

  dp->pos = 0;

  return dp;
}
Example #18
0
/* return data as a dynamic pointer */
static dynamicPtr *newDynamic(int initialSize, void *data, int freeOKFlag)
{
	dynamicPtr *dp;

	dp = (dynamicPtr *) gdMalloc(sizeof (dynamicPtr));
	if(dp == NULL) {
		return NULL;
	}

	if(!allocDynamic(dp, initialSize, data)) {
		gdFree(dp);
		return NULL;
	}

	dp->pos = 0;
	dp->freeOK = freeOKFlag;

	return dp;
}
Example #19
0
/* return data as a dynamic pointer */
gdIOCtx * gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
{
	ssIOCtxPtr ctx;

	ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));

	ctx->src = src;
	ctx->snk = snk;

	ctx->ctx.getC = sourceGetchar;
	ctx->ctx.getBuf = sourceGetbuf;

	ctx->ctx.putC = sinkPutchar;
	ctx->ctx.putBuf = sinkPutbuf;

	ctx->ctx.tell = NULL;
	ctx->ctx.seek = NULL;

	ctx->ctx.gd_free = gdFreeSsCtx;

	return (gdIOCtx *) ctx;
}
Example #20
0
tiff_handle * new_tiff_handle(gdIOCtx *g)
{
	tiff_handle * t;

	if (!g) {
		fprintf(stderr, "Cannot create a new tiff handle, missing Ctx argument");
		return NULL;
	}

	t = (tiff_handle *) gdMalloc(sizeof(tiff_handle));
	if (!t) {
		fprintf(stderr, "Failed to allocate a new tiff handle");
		return NULL;
	}

	t->size = 0;
	t->pos = 0;
	t->ctx = g;
	t->written = 0;

	return t;
}
Example #21
0
/*
	Function: gdImageCreateFromTgaCtx

	Creates a gdImage from a gdIOCtx referencing a TGA binary file.

	Parameters:
		ctx - Pointer to a gdIOCtx structure
 */
BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtx* ctx)
{
	int bitmap_caret = 0;
	oTga *tga = NULL;
	/*	int pixel_block_size = 0;
		int image_block_size = 0; */
	volatile gdImagePtr image = NULL;
	int x = 0;
	int y = 0;

	tga = (oTga *) gdMalloc(sizeof(oTga));
	if (!tga) {
		return NULL;
	}

	tga->bitmap = NULL;
	tga->ident = NULL;

	if (read_header_tga(ctx, tga) < 0) {
		free_tga(tga);
		return NULL;
	}

	/*TODO: Will this be used?
		pixel_block_size = tga->bits / 8;
		image_block_size = (tga->width * tga->height) * pixel_block_size;
	*/

	if (read_image_tga(ctx, tga) < 0) {
		free_tga(tga);
		return NULL;
	}

	image = gdImageCreateTrueColor((int)tga->width, (int)tga->height );

	if (image == 0) {
		free_tga( tga );
		return NULL;
	}

	/*!	\brief Populate GD image object
	 *  Copy the pixel data from our tga bitmap buffer into the GD image
	 *  Disable blending and save the alpha channel per default
	 */
	if (tga->alphabits) {
		gdImageAlphaBlending(image, 0);
		gdImageSaveAlpha(image, 1);
	}

	/* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */
	for (y = 0; y < tga->height; y++) {
		register int *tpix = image->tpixels[y];
		for ( x = 0; x < tga->width; x++, tpix++) {
			if (tga->bits == TGA_BPP_24) {
				*tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]);
				bitmap_caret += 3;
			} else if (tga->bits == TGA_BPP_32 && tga->alphabits) {
				register int a = tga->bitmap[bitmap_caret + 3];

				*tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1));
				bitmap_caret += 4;
			}
		}
	}

	if (tga->flipv && tga->fliph) {
		gdImageFlipBoth(image);
	} else if (tga->flipv) {
		gdImageFlipVertical(image);
	} else if (tga->fliph) {
		gdImageFlipHorizontal(image);
	}

	free_tga(tga);

	return image;
}
Example #22
0
/*!	\brief Reads a TGA image data into buffer.
 *	Reads the image data block from a binary TGA file populating the referenced TGA structure.
 *	\param ctx Pointer to TGA binary file
 *	\param tga Pointer to TGA structure
 *	\return int 0 on sucess, -1 on failure
 */
int read_image_tga( gdIOCtx *ctx, oTga *tga )
{
	int pixel_block_size = (tga->bits / 8);
	int image_block_size = (tga->width * tga->height) * pixel_block_size;
	uint8_t* decompression_buffer = NULL;
	unsigned char* conversion_buffer = NULL;
	int buffer_caret = 0;
	int bitmap_caret = 0;
	int i = 0;
	int encoded_pixels;

	if(overflow2(tga->width, tga->height)) {
		return -1;
	}

	if(overflow2(tga->width * tga->height, pixel_block_size)) {
		return -1;
	}

	if(overflow2(image_block_size, sizeof(int))) {
		return -1;
	}

	/*! \todo Add more image type support.
	 */
	if (tga->imagetype != TGA_TYPE_RGB && tga->imagetype != TGA_TYPE_RGB_RLE)
		return -1;

	/*!	\brief Allocate memmory for image block
	 *  Allocate a chunk of memory for the image block to be passed into.
	 */
	tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(int));
	if (tga->bitmap == NULL)
		return -1;

	switch (tga->imagetype) {
	case TGA_TYPE_RGB:
		/*! \brief Read in uncompressed RGB TGA
		 *  Chunk load the pixel data from an uncompressed RGB type TGA.
		 */
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
		if (conversion_buffer == NULL) {
			return -1;
		}

		if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) {
			gd_error("gd-tga: premature end of image data\n");
			gdFree(conversion_buffer);
			return -1;
		}

		while (buffer_caret < image_block_size) {
			tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		gdFree(conversion_buffer);
		break;

	case TGA_TYPE_RGB_RLE:
		/*! \brief Read in RLE compressed RGB TGA
		 *  Chunk load the pixel data from an RLE compressed RGB type TGA.
		 */
		decompression_buffer = (uint8_t*) gdMalloc(image_block_size * sizeof(uint8_t));
		if (decompression_buffer == NULL) {
			return -1;
		}
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
		if (conversion_buffer == NULL) {
			gd_error("gd-tga: premature end of image data\n");
			gdFree( decompression_buffer );
			return -1;
		}

		if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) {
			gdFree(conversion_buffer);
			gdFree(decompression_buffer);
			return -1;
		}

		buffer_caret = 0;

		while( buffer_caret < image_block_size) {
			decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		buffer_caret = 0;

		while( bitmap_caret < image_block_size ) {
			
			if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 );
				buffer_caret++;

				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) {
					gdFree( decompression_buffer );
					gdFree( conversion_buffer );
					return -1;
				}

				for (i = 0; i < encoded_pixels; i++) {
					memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size);
					bitmap_caret += pixel_block_size;
				}
				buffer_caret += pixel_block_size;

			} else {
				encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
				buffer_caret++;

				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) {
					gdFree( decompression_buffer );
					gdFree( conversion_buffer );
					return -1;
				}

				memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size);
				bitmap_caret += (encoded_pixels * pixel_block_size);
				buffer_caret += (encoded_pixels * pixel_block_size);
			}
		}
		gdFree( decompression_buffer );
		gdFree( conversion_buffer );
		break;
	}

	return 1;
}
Example #23
0
File: gdxpm.c Project: johlim/study
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
{
	XpmInfo info;
	XpmImage image;
	unsigned int i, j, k, number, len;
	char buf[5];
	gdImagePtr im = 0;
	int *pointer;
	int red = 0, green = 0, blue = 0;
	int *colors;
	int ret;

	ret = XpmReadFileToXpmImage(filename, &image, &info);
	if(ret != XpmSuccess) {
		return 0;
	}

	number = image.ncolors;
	if(overflow2(sizeof(int), number)) {
		goto done;
	}

	colors = (int *)gdMalloc(sizeof(int) * number);
	if(colors == NULL) {
		goto done;
	}

	if(!(im = gdImageCreate(image.width, image.height))) {
		gdFree(colors);
		goto done;
	}

	for(i = 0; i < number; i++) {
		char *c_color = image.colorTable[i].c_color;
		if(strcmp(c_color, "None") == 0) {
		  colors[i] = gdImageGetTransparent(im);
		  if(colors[i] == -1) colors[i] = gdImageColorAllocate(im, 0, 0, 0);
		  if(colors[i] != -1) gdImageColorTransparent(im, colors[i]);
		  continue;
		}
		len = strlen(c_color);
		if(len < 1) continue;
		if(c_color[0] == '#') {
			switch(len) {
			case 4:
				buf[2] = '\0';
				buf[0] = buf[1] = c_color[1];
				red = strtol(buf, NULL, 16);

				buf[0] = buf[1] = c_color[2];
				green = strtol(buf, NULL, 16);

				buf[0] = buf[1] = c_color[3];
				blue = strtol(buf, NULL, 16);
				break;

			case 7:
				buf[2] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				red = strtol(buf, NULL, 16);

				buf[0] = c_color[3];
				buf[1] = c_color[4];
				green = strtol(buf, NULL, 16);

				buf[0] = c_color[5];
				buf[1] = c_color[6];
				blue = strtol(buf, NULL, 16);
				break;

			case 10:
				buf[3] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				buf[2] = c_color[3];
				red = strtol(buf, NULL, 16);
				red /= 64;

				buf[0] = c_color[4];
				buf[1] = c_color[5];
				buf[2] = c_color[6];
				green = strtol(buf, NULL, 16);
				green /= 64;

				buf[0] = c_color[7];
				buf[1] = c_color[8];
				buf[2] = c_color[9];
				blue = strtol(buf, NULL, 16);
				blue /= 64;
				break;

			case 13:
				buf[4] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				buf[2] = c_color[3];
				buf[3] = c_color[4];
				red = strtol(buf, NULL, 16);
				red /= 256;

				buf[0] = c_color[5];
				buf[1] = c_color[6];
				buf[2] = c_color[7];
				buf[3] = c_color[8];
				green = strtol(buf, NULL, 16);
				green /= 256;

				buf[0] = c_color[9];
				buf[1] = c_color[10];
				buf[2] = c_color[11];
				buf[3] = c_color[12];
				blue = strtol(buf, NULL, 16);
				blue /= 256;
				break;
			}
		} else if(!gdColorMapLookup(GD_COLOR_MAP_X11, c_color, &red, &green, &blue)) {
			continue;
		}

		colors[i] = gdImageColorResolve(im, red, green, blue);
	}

	pointer = (int *)image.data;

	for(i = 0; i < image.height; i++) {
		for(j = 0; j < image.width; j++) {
			k = *pointer++;
			gdImageSetPixel(im, j, i, colors[k]);
		}
	}

	gdFree(colors);

 done:
	XpmFreeXpmImage(&image);
	XpmFreeXpmInfo(&info);
	return im;
}
Example #24
0
/*  tiffWriter
 *  ----------
 *  Write the gd image as a tiff file (called by gdImageTiffCtx)
 *  Parameters are:
 *  image:    gd image structure;
 *  out:      the stream where to write
 *  bitDepth: depth in bits of each pixel
 */
BGD_DECLARE(void) tiffWriter(gdImagePtr image, gdIOCtx *out, int bitDepth)
{
	int x, y;
	int i;
	int r, g, b, a;
	TIFF *tiff;
	int width, height;
	int color;
	char *scan;
	int samplesPerPixel = 3;
	int bitsPerSample;
	int transparentColorR = -1;
	int transparentColorG = -1;
	int transparentColorB = -1;
	uint16 extraSamples[1];
	uint16 *colorMapRed = 0;
	uint16 *colorMapGreen = 0;
	uint16 *colorMapBlue = 0;

	tiff_handle *th;

	th = new_tiff_handle(out);
	if (!th) {
		return;
	}
	extraSamples[0] = EXTRASAMPLE_ASSOCALPHA;

	/* read in the width/height of gd image */
	width = gdImageSX(image);
	height = gdImageSY(image);

	/* reset clip region to whole image */
	gdImageSetClip(image, 0, 0, width, height);

	/* handle old-style single-colour mapping to 100% transparency */
	if(image->transparent != 0xffffffff) {
		/* set our 100% transparent colour value */
		transparentColorR = gdImageRed(image, image->transparent);
		transparentColorG = gdImageGreen(image, image->transparent);
		transparentColorB = gdImageBlue(image, image->transparent);
	}

	/* Open tiff file writing routines, but use special read/write/seek
	 * functions so that tiff lib writes correct bits of tiff content to
	 * correct areas of file opened and modifieable by the gdIOCtx functions
	 */
	tiff = TIFFClientOpen("", "w", th,	tiff_readproc,
										tiff_writeproc,
										tiff_seekproc,
										tiff_closeproc,
										tiff_sizeproc,
										tiff_mapproc,
										tiff_unmapproc);

	TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
	TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
	TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
	TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
	TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC,
					(bitDepth == 24) ? PHOTOMETRIC_RGB : PHOTOMETRIC_PALETTE);

	bitsPerSample = (bitDepth == 24 || bitDepth == 8) ? 8 : 1;
	TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, bitsPerSample);

	/* build the color map for 8 bit images */
	if(bitDepth != 24) {
		colorMapRed   = (uint16 *) gdMalloc(3 * (1 << bitsPerSample));
		if (!colorMapRed) {
			return;
		}
		colorMapGreen = (uint16 *) gdMalloc(3 * (1 << bitsPerSample));
		if (!colorMapGreen) {
			return;
		}
		colorMapBlue  = (uint16 *) gdMalloc(3 *  (1 << bitsPerSample));
		if (!colorMapBlue) {
			return;
		}

		for(i = 0; i < image->colorsTotal; i++) {
			colorMapRed[i]   = gdImageRed(image,i) + (gdImageRed(image,i) * 256);
			colorMapGreen[i] = gdImageGreen(image,i)+(gdImageGreen(image,i)*256);
			colorMapBlue[i]  = gdImageBlue(image,i) + (gdImageBlue(image,i)*256);
		}

		TIFFSetField(tiff, TIFFTAG_COLORMAP, colorMapRed, colorMapGreen,
															colorMapBlue);
		samplesPerPixel = 1;
	}

	/* here, we check if the 'save alpha' flag is set on the source gd image */
	if(	(bitDepth == 24) &&
		(image->saveAlphaFlag || image->transparent != 0xffffffff)) {
		/* so, we need to store the alpha values too!
		 * Also, tell TIFF what the extra sample means (associated alpha) */
		samplesPerPixel = 4;
		TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
		TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, extraSamples);
	} else {
		TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
	}

	TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);

	if(overflow2(width, samplesPerPixel)) {
		return;
	}

	if(!(scan = (char *)gdMalloc(width * samplesPerPixel))) {
		return;
	}

	/* loop through y-coords, and x-coords */
	for(y = 0; y < height; y++) {
		for(x = 0; x < width; x++) {
			/* generate scan line for writing to tiff */
			color = gdImageGetPixel(image, x, y);

			a = (127 - gdImageAlpha(image, color)) * 2;
			a = (a == 0xfe) ? 0xff : a & 0xff;
			b = gdImageBlue(image, color);
			g = gdImageGreen(image, color);
			r = gdImageRed(image, color);

			/* if this pixel has the same RGB as the transparent colour,
			 * then set alpha fully transparent */
			if(	transparentColorR == r &&
				transparentColorG == g &&
				transparentColorB == b
			) {
				a = 0x00;
			}

			if(bitDepth != 24) {
				/* write out 1 or 8 bit value in 1 byte
				 * (currently treats 1bit as 8bit) */
				scan[(x * samplesPerPixel) + 0] = color;
			} else {
				/* write out 24 bit value in 3 (or 4 if transparent) bytes */
				if(image->saveAlphaFlag || image->transparent != 0xffffffff) {
					scan[(x * samplesPerPixel) + 3] = a;
				}

				scan[(x * samplesPerPixel) + 2] = b;
				scan[(x * samplesPerPixel) + 1] = g;
				scan[(x * samplesPerPixel) + 0] = r;
			}
		}

		/* Write the scan line to the tiff */
		if(TIFFWriteEncodedStrip(tiff, y, scan, width * samplesPerPixel) == -1){
			/* error handler here */
			fprintf(stderr, "Could not create TIFF\n");
			return;
		}
	}

	/* now cloase and free up resources */
	TIFFClose(tiff);
	gdFree(scan);
	gdFree(th);

	if(bitDepth != 24) {
		gdFree(colorMapRed);
		gdFree(colorMapGreen);
		gdFree(colorMapBlue);
	}
}
Example #25
0
/* readwbmp
 * -------
 * Actually reads the WBMP format from an open file descriptor
 * It goes along by returning a pointer to a WBMP struct.
 */
int readwbmp(int (*getin) (void *in), void *in, Wbmp **return_wbmp)
{
	int row, col, byte, pel, pos;
	Wbmp *wbmp;

	if((wbmp = (Wbmp *)gdMalloc(sizeof(Wbmp))) == NULL) {
		return -1;
	}

	wbmp->type = getin(in);
	if(wbmp->type != 0) {
		gdFree(wbmp);
		return -1;
	}

	if(skipheader(getin, in)) {
		return -1;
	}

	wbmp->width = getmbi(getin, in);
	if(wbmp->width == -1) {
		gdFree(wbmp);
		return -1;
	}

	wbmp->height = getmbi(getin, in);
	if(wbmp->height == -1) {
		gdFree(wbmp);
		return -1;
	}

#ifdef __DEBUG
	printf("W: %d, H: %d\n", wbmp->width, wbmp->height);
#endif

	if(	overflow2(sizeof(int), wbmp->width) ||
		overflow2(sizeof(int) * wbmp->width, wbmp->height)) {
		gdFree(wbmp);
		return -1;
	}

	if((wbmp->bitmap = (int *)gdMalloc(sizeof(int) * wbmp->width * wbmp->height)) == NULL) {
		gdFree(wbmp);
		return -1;
	}

#ifdef __DEBUG
	printf("DATA CONSTRUCTED\n");
#endif

	pos = 0;
	for(row = 0; row < wbmp->height; row++) {
		for(col = 0; col < wbmp->width;) {
			byte = getin(in);

			for(pel = 7; pel >= 0; pel--) {
				if(col++ < wbmp->width) {
					if(byte & 1 << pel) {
						wbmp->bitmap[pos] = WBMP_WHITE;
					} else {
						wbmp->bitmap[pos] = WBMP_BLACK;
					}
					pos++;
				}
			}
		}
	}

	*return_wbmp = wbmp;

	return 0;
}
Example #26
0
/*!	\brief Reads a TGA image data into buffer.
 *	Reads the image data block from a binary TGA file populating the referenced TGA structure.
 *	\param ctx Pointer to TGA binary file
 *	\param tga Pointer to TGA structure
 *	\return int 0 on sucess, -1 on failure	
 */
int read_image_tga( gdIOCtx *ctx, oTga *tga ) {
	int pixel_block_size = (tga->bits / 8);
	int image_block_size = (tga->width * tga->height) * pixel_block_size;
	byte* decompression_buffer = NULL;
	unsigned char* conversion_buffer = NULL;
	int buffer_caret = 0;
	int bitmap_caret = 0;
	int i = 0;
	int j = 0;
	byte encoded_pixels;

	if(overflow2(tga->width, tga->height)) {
		return -1;
	}

	if(overflow2(tga->width * tga->height, pixel_block_size)) {
		return -1;
	}

	if(overflow2(image_block_size, sizeof(byte))) {
		return -1;
	}

	/*!	\brief Allocate memmory for image block
	 *  Allocate a chunk of memory for the image block to be passed into.
	 */
	tga->bitmap = (int *) gdMalloc(image_block_size * sizeof(byte));
	if (tga->bitmap == NULL) {
		return -1;
	}

	/*! \todo Add image type support
	 *  Add support for this image type.
	 */
	if (tga->imagetype == TGA_TYPE_INDEXED) {
		return -1;
	}

	/*! \todo Add image type support
	 *  Add support for this image type.
	 */
	if (tga->imagetype == TGA_TYPE_INDEXED_RLE) {
		return -1;
	}

	/*! \brief Read in uncompressed RGB TGA
	 *  Chunk load the pixel data from an uncompressed RGB type TGA.
	 */
	if (tga->imagetype == TGA_TYPE_RGB) {
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));
		if (conversion_buffer == NULL) {
			gdFree(conversion_buffer);
			return -1;
		}

		gdGetBuf(conversion_buffer, image_block_size, ctx);

		while (buffer_caret < image_block_size) { 
			tga->bitmap[buffer_caret] = (int) conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		gdFree( conversion_buffer );
	}

	/*! \brief Read in RLE compressed RGB TGA
	 *  Chunk load the pixel data from an RLE compressed RGB type TGA.
	 */
	if (tga->imagetype == TGA_TYPE_RGB_RLE) {
		decompression_buffer = (byte*) gdMalloc(image_block_size * sizeof(byte));
		if (decompression_buffer == NULL) {
			gdFree( decompression_buffer );
			return -1;
		}
		conversion_buffer = (unsigned char *) gdMalloc(image_block_size * sizeof(unsigned char));  
		if (conversion_buffer == NULL) {
			gdFree( decompression_buffer );
			gdFree( conversion_buffer );
			return -1;
		}

		gdGetBuf( conversion_buffer, image_block_size, ctx );

		buffer_caret = 0;

		while( buffer_caret < image_block_size ) { 
			decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret];
			buffer_caret++;
		}

		buffer_caret = 0;

		while( bitmap_caret < image_block_size ) {

			if ((decompression_buffer[buffer_caret] & TGA_RLE_FLAG) == TGA_RLE_FLAG) {
				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & 127 ) + 1 );
				buffer_caret++;

				for (i = 0; i < encoded_pixels; i++) {
					for (j = 0; j < pixel_block_size; j++, bitmap_caret++) {
						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
					}
				}
				buffer_caret += pixel_block_size;
			} else {
				encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
				buffer_caret++;

				for (i = 0; i < encoded_pixels; i++) {
					for( j = 0; j < pixel_block_size; j++, bitmap_caret++ ) {
						tga->bitmap[ bitmap_caret ] = decompression_buffer[ buffer_caret + j ];
					}
					buffer_caret += pixel_block_size;
				}
			}
		}

		gdFree( decompression_buffer );
		gdFree( conversion_buffer );

	}

	/*!	\todo Add image type support
	 *  Add support for this image type.
	 */
	if( tga->imagetype == TGA_TYPE_GREYSCALE ) {
		return -1;
	}

	/*!	\todo Add image type support
	 *  Add support for this image type.
	 */
	if( tga->imagetype == TGA_TYPE_GREYSCALE_RLE ) {
		return -1;
	}

	return 0;
}
Example #27
0
/* This routine is based in part on the Chapter 13 demo code in "PNG: The
 *  Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html).
 */
gdImagePtr gdImageCreateFromPngCtx(gdIOCtx *infile)
{
    png_byte sig[8];
    png_structp png_ptr;
    png_infop info_ptr;
    png_uint_32 width, height, rowbytes;
    int bit_depth, color_type, interlace_type;
    int num_palette, num_trans;
    png_colorp palette;
    png_color_16p trans_gray_rgb;
    png_bytep trans;
    png_bytep image_data = NULL;
    png_bytepp row_pointers = NULL;
    gdImagePtr im = NULL;
    int i, j, *open;
    volatile int transparent = -1;
    volatile int palette_allocated = FALSE;

    /* Make sure the signature can't match by dumb luck -- TBB */
    /* GRR: isn't sizeof(infile) equal to the size of the pointer? */
    memset(infile, 0, sizeof(infile));

    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead */
    gdGetBuf(sig, 8, infile);
    if (!png_check_sig(sig, 8))
        return NULL;   /* bad signature */

#ifndef PNG_SETJMP_NOT_SUPPORTED
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, &gdPngJmpbufStruct,
      gdPngErrorHandler, NULL);
#else
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
#endif
    if (png_ptr == NULL) {
        fprintf(stderr, "gd-png error: cannot allocate libpng main struct\n");
        return NULL;
    }

    info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL) {
        fprintf(stderr, "gd-png error: cannot allocate libpng info struct\n");
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return NULL;
    }

    /* we could create a second info struct here (end_info), but it's only
     * useful if we want to keep pre- and post-IDAT chunk info separated
     * (mainly for PNG-aware image editors and converters) */

    /* setjmp() must be called in every non-callback function that calls a
     * PNG-reading libpng function */
#ifndef PNG_SETJMP_NOT_SUPPORTED
    if (setjmp(gdPngJmpbufStruct.jmpbuf)) {
        fprintf(stderr, "gd-png error: setjmp returns error condition\n");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return NULL;
    }
#endif

    png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */

    png_set_read_fn(png_ptr, (void *)infile, gdPngReadData);
    png_read_info(png_ptr, info_ptr);  /* read all PNG info up to image data */

    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
      &interlace_type, NULL, NULL);

    if (bit_depth == 16)
        png_set_strip_16(png_ptr);
    else if (bit_depth < 8)
        png_set_packing(png_ptr);   /* expand to 1 byte per pixel */

    if (color_type & PNG_COLOR_MASK_ALPHA) {
         fprintf(stderr, "gd-png warning: alpha channel not supported\n");
         png_set_strip_alpha(png_ptr);
    }

    switch (color_type) {
        case PNG_COLOR_TYPE_PALETTE:
            png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
#ifdef DEBUG
            fprintf(stderr, "gd-png color_type is palette, colors: %d\n",
                num_palette);
#endif /* DEBUG */
            if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
                int real_num_trans = 0, idx_first_trans = -1;
                int min_trans = 256, idx_min_trans = -1;

                png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
                for (i = 0;  i < num_trans;  ++i) {
                    if (trans[i] < 255) {
                        ++real_num_trans;
                        if (idx_first_trans < 0)
                            idx_first_trans = i;
                        if (trans[i] < min_trans) {
                            min_trans = trans[i];
                            idx_min_trans = i;
                        }
                    }
                }
                if (real_num_trans > 0) {
                    if (real_num_trans > 1 || trans[idx_first_trans] != 0) {
                        fprintf(stderr, "gd-png warning: only single-color, "
                          "100%% transparency supported\n");
                        transparent = idx_min_trans;
                    } else {
                        transparent = idx_first_trans;
                    }
                }
            }
            break;

        case PNG_COLOR_TYPE_GRAY:
        case PNG_COLOR_TYPE_GRAY_ALPHA:
            /* create a fake palette and check for single-shade transparency */
            if ((palette = (png_colorp)gdMalloc(256*sizeof(png_color))) == NULL) {
                fprintf(stderr, "gd-png error: cannot allocate gray palette\n");
                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
                return NULL;
            }
            palette_allocated = TRUE;
            if (bit_depth < 8)
            {
              num_palette = 1<<bit_depth;
              for (i = 0;  i < 256;  ++i)
              {
                j = (255*i)/(num_palette-1);
                palette[i].red = palette[i].green = palette[i].blue = j;
              }
            }
            else
            {
            num_palette = 256;
              for (i = 0;  i < 256;  ++i)
              {
                palette[i].red = palette[i].green = palette[i].blue = i;
              }
            }
            if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
                png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
                if (bit_depth == 16)  /* png_set_strip_16() not yet in effect */
                    transparent = trans_gray_rgb->gray >> 8;
                else
                    transparent = trans_gray_rgb->gray;
                /* Note slight error in 16-bit case:  up to 256 16-bit shades
                 * may get mapped to a single 8-bit shade, and only one of them
                 * is supposed to be transparent.  IOW, both opaque pixels and
                 * transparent pixels will be mapped into the transparent entry.
                 * There is no particularly good way around this in the case
                 * that all 256 8-bit shades are used, but one could write some
                 * custom 16-bit code to handle the case where there are gdFree
                 * palette entries.  This error will be extremely rare in
                 * general, though.  (Quite possibly there is only one such
                 * image in existence.) */
            }
            break;

        case PNG_COLOR_TYPE_RGB:
        case PNG_COLOR_TYPE_RGB_ALPHA:
            /* allocate a palette and check for single-shade transparency */
            if ((palette = (png_colorp)gdMalloc(256*sizeof(png_color))) == NULL) {
                fprintf(stderr, "gd-png error: cannot allocate RGB palette\n");
                png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
                return NULL;
            }
            palette_allocated = TRUE;
            num_palette = 256;
            if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
                png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
                if (bit_depth == 16) {   /* png_set_strip_16() not yet active */
                    palette[0].red   = trans_gray_rgb->red   >> 8;
                    palette[0].green = trans_gray_rgb->green >> 8;
                    palette[0].blue  = trans_gray_rgb->blue  >> 8;
                } else {
Example #28
0
File: gdxpm.c Project: kanbang/Colt
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm (char *filename)
{
  XpmInfo info;
  XpmImage image;
  int i, j, k, number;
  char buf[5];
  gdImagePtr im = 0;
  int *pointer;
  int red = 0, green = 0, blue = 0;
  int *colors;
  int ret;

  ret = XpmReadFileToXpmImage (filename, &image, &info);
  if (ret != XpmSuccess)
    return 0;

  if (!(im = gdImageCreate (image.width, image.height)))
    return 0;

  number = image.ncolors;
  colors = (int *) gdMalloc (sizeof (int) * number);
  if (colors == NULL)
    return (0);
  for (i = 0; i < number; i++)
    {
      switch (strlen (image.colorTable[i].c_color))
	{
	case 4:
	  buf[1] = '\0';
	  buf[0] = image.colorTable[i].c_color[1];
	  red = strtol (buf, NULL, 16);

	  buf[0] = image.colorTable[i].c_color[3];
	  green = strtol (buf, NULL, 16);

	  buf[0] = image.colorTable[i].c_color[5];
	  blue = strtol (buf, NULL, 16);
	  break;
	case 7:
	  buf[2] = '\0';
	  buf[0] = image.colorTable[i].c_color[1];
	  buf[1] = image.colorTable[i].c_color[2];
	  red = strtol (buf, NULL, 16);

	  buf[0] = image.colorTable[i].c_color[3];
	  buf[1] = image.colorTable[i].c_color[4];
	  green = strtol (buf, NULL, 16);

	  buf[0] = image.colorTable[i].c_color[5];
	  buf[1] = image.colorTable[i].c_color[6];
	  blue = strtol (buf, NULL, 16);
	  break;
	case 10:
	  buf[3] = '\0';
	  buf[0] = image.colorTable[i].c_color[1];
	  buf[1] = image.colorTable[i].c_color[2];
	  buf[2] = image.colorTable[i].c_color[3];
	  red = strtol (buf, NULL, 16);
	  red /= 64;

	  buf[0] = image.colorTable[i].c_color[4];
	  buf[1] = image.colorTable[i].c_color[5];
	  buf[2] = image.colorTable[i].c_color[6];
	  green = strtol (buf, NULL, 16);
	  green /= 64;

	  buf[0] = image.colorTable[i].c_color[7];
	  buf[1] = image.colorTable[i].c_color[8];
	  buf[2] = image.colorTable[i].c_color[9];
	  blue = strtol (buf, NULL, 16);
	  blue /= 64;
	  break;
	case 13:
	  buf[4] = '\0';
	  buf[0] = image.colorTable[i].c_color[1];
	  buf[1] = image.colorTable[i].c_color[2];
	  buf[2] = image.colorTable[i].c_color[3];
	  buf[3] = image.colorTable[i].c_color[4];
	  red = strtol (buf, NULL, 16);
	  red /= 256;

	  buf[0] = image.colorTable[i].c_color[5];
	  buf[1] = image.colorTable[i].c_color[6];
	  buf[2] = image.colorTable[i].c_color[7];
	  buf[3] = image.colorTable[i].c_color[8];
	  green = strtol (buf, NULL, 16);
	  green /= 256;

	  buf[0] = image.colorTable[i].c_color[9];
	  buf[1] = image.colorTable[i].c_color[10];
	  buf[2] = image.colorTable[i].c_color[11];
	  buf[3] = image.colorTable[i].c_color[12];
	  blue = strtol (buf, NULL, 16);
	  blue /= 256;
	  break;
	}


      colors[i] = gdImageColorResolve (im, red, green, blue);
      if (colors[i] == -1)
	fprintf (stderr, "ARRRGH\n");
    }

  pointer = (int *) image.data;
  for (i = 0; i < image.height; i++)
    {
      for (j = 0; j < image.width; j++)
	{
	  k = *pointer++;
	  gdImageSetPixel (im, j, i, colors[k]);
	}
    }
  gdFree (colors);
  return (im);
}
Example #29
0
/* This routine is based in part on the Chapter 13 demo code in "PNG: The
 *  Definitive Guide" (http://www.cdrom.com/pub/png/pngbook.html).
 */
gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
{
  png_byte sig[8];
#ifdef PNG_SETJMP_SUPPORTED
  jmpbuf_wrapper jbw;
#endif
  png_structp png_ptr;
  png_infop info_ptr;
  png_uint_32 width, height, rowbytes, w, h;
  int bit_depth, color_type, interlace_type;
  int num_palette, num_trans;
  png_colorp palette;
  png_color_16p trans_gray_rgb;
  png_color_16p trans_color_rgb;
  png_bytep trans;
  volatile png_bytep image_data = NULL;
  volatile png_bytepp row_pointers = NULL;
  gdImagePtr im = NULL;
  int i, j, *open = NULL;
  volatile int transparent = -1;
  volatile int palette_allocated = FALSE;


  /* Make sure the signature can't match by dumb luck -- TBB */
  /* GRR: isn't sizeof(infile) equal to the size of the pointer? */
  memset (sig, 0, sizeof(sig));

    /* first do a quick check that the file really is a PNG image; could
     * have used slightly more general png_sig_cmp() function instead
     */
  if (gdGetBuf(sig, 8, infile) < 8) {
    return NULL;
  }

  if (png_sig_cmp(sig, 0, 8) != 0) { /* bad signature */
    return NULL;
  }

#ifdef PNG_SETJMP_SUPPORTED
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, &jbw, gdPngErrorHandler, NULL);
#else
  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
#endif
  if (png_ptr == NULL) {
    php_gd_error("gd-png error: cannot allocate libpng main struct");
    return NULL;
  }

  info_ptr = png_create_info_struct(png_ptr);
  if (info_ptr == NULL) {
    php_gd_error("gd-png error: cannot allocate libpng info struct");
    png_destroy_read_struct (&png_ptr, NULL, NULL);

    return NULL;
  }

  /* we could create a second info struct here (end_info), but it's only
   * useful if we want to keep pre- and post-IDAT chunk info separated
   * (mainly for PNG-aware image editors and converters)
   */

  /* setjmp() must be called in every non-callback function that calls a
   * PNG-reading libpng function
   */
#ifdef PNG_SETJMP_SUPPORTED
  if (setjmp(jbw.jmpbuf)) {
    php_gd_error("gd-png error: setjmp returns error condition");
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    return NULL;
  }
#endif

  png_set_sig_bytes(png_ptr, 8);  /* we already read the 8 signature bytes */

  png_set_read_fn(png_ptr, (void *) infile, gdPngReadData);
  png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */

  png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL);
  if ((color_type == PNG_COLOR_TYPE_RGB) || (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
    || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
    im = gdImageCreateTrueColor((int) width, (int) height);
  } else {
    im = gdImageCreate((int) width, (int) height);
  }
  if (im == NULL) {
    php_gd_error("gd-png error: cannot allocate gdImage struct");
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

    return NULL;
  }

  if (bit_depth == 16) {
    png_set_strip_16(png_ptr);
  } else if (bit_depth < 8) {
    png_set_packing (png_ptr); /* expand to 1 byte per pixel */
  }

  /* setjmp() must be called in every non-callback function that calls a
   * PNG-reading libpng function
   */
#ifdef PNG_SETJMP_SUPPORTED
  if (setjmp(jbw.jmpbuf)) {
    php_gd_error("gd-png error: setjmp returns error condition");
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    gdFree(image_data);
    gdFree(row_pointers);
    if (im) {
      gdImageDestroy(im);
    }
    return NULL;
  }
#endif

  switch (color_type) {
    case PNG_COLOR_TYPE_PALETTE:
      png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
      if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) {
        /* gd 2.0: we support this rather thoroughly now. Grab the
         * first fully transparent entry, if any, as the value of
         * the simple-transparency index, mostly for backwards
         * binary compatibility. The alpha channel is where it's
         * really at these days.
         */
        int firstZero = 1;
        png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL);
        for (i = 0; i < num_trans; ++i) {
          im->alpha[i] = gdAlphaMax - (trans[i] >> 1);
          if ((trans[i] == 0) && (firstZero)) {
            transparent = i;
            firstZero = 0;
          }
        }
      }
      break;
    case PNG_COLOR_TYPE_GRAY:
      /* create a fake palette and check for single-shade transparency */
      if ((palette = (png_colorp) gdMalloc (256 * sizeof (png_color))) == NULL) {
        php_gd_error("gd-png error: cannot allocate gray palette");
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);

        return NULL;
      }
      palette_allocated = TRUE;
      if (bit_depth < 8) {
        num_palette = 1 << bit_depth;
        for (i = 0; i < 256; ++i) {
          j = (255 * i) / (num_palette - 1);
          palette[i].red = palette[i].green = palette[i].blue = j;
        }
      } else {
        num_palette = 256;
        for (i = 0; i < 256; ++i) {
          palette[i].red = palette[i].green = palette[i].blue = i;
        }
      }
      if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
        png_get_tRNS(png_ptr, info_ptr, NULL, NULL, &trans_gray_rgb);
        if (bit_depth == 16) {  /* png_set_strip_16() not yet in effect */
          transparent = trans_gray_rgb->gray >> 8;
        } else {
          transparent = trans_gray_rgb->gray;
        }
        /* Note slight error in 16-bit case:  up to 256 16-bit shades
         * may get mapped to a single 8-bit shade, and only one of them
         * is supposed to be transparent.  IOW, both opaque pixels and
         * transparent pixels will be mapped into the transparent entry.
         * There is no particularly good way around this in the case
         * that all 256 8-bit shades are used, but one could write some
         * custom 16-bit code to handle the case where there are gdFree
         * palette entries.  This error will be extremely rare in
         * general, though.  (Quite possibly there is only one such
         * image in existence.)
         */
      }