Exemple #1
0
int TGA_Write(char *filename, Image_t *Image, int rle)
{
	FILE *stream;
	unsigned char IDLength=0;
	unsigned char ColorMapType=0, ColorMapStart=0, ColorMapLength=0, ColorMapDepth=0;
	unsigned short XOffset=0, YOffset=0, Width=Image->Width, Height=Image->Height;
	unsigned char Depth=(unsigned char)Image->Depth, ImageDescriptor=0, ImageType;

	switch(Image->Depth)
	{
		case 32:
		case 24:
		case 16:
			ImageType=rle?10:2;
			break;

		case 8:
			ImageType=rle?11:3;
			break;

		default:
			return 0;
	}

	if((stream=fopen(filename, "wb"))==NULL)
		return 0;

	fwrite(&IDLength, sizeof(unsigned char), 1, stream);
	fwrite(&ColorMapType, sizeof(unsigned char), 1, stream);
	fwrite(&ImageType, sizeof(unsigned char), 1, stream);
	fwrite(&ColorMapStart, sizeof(unsigned short), 1, stream);
	fwrite(&ColorMapLength, sizeof(unsigned short), 1, stream);
	fwrite(&ColorMapDepth, sizeof(unsigned char), 1, stream);
	fwrite(&XOffset, sizeof(unsigned short), 1, stream);
	fwrite(&XOffset, sizeof(unsigned short), 1, stream);
	fwrite(&Width, sizeof(unsigned short), 1, stream);
	fwrite(&Height, sizeof(unsigned short), 1, stream);
	fwrite(&Depth, sizeof(unsigned char), 1, stream);
	fwrite(&ImageDescriptor, sizeof(unsigned char), 1, stream);

	if(rle)
	{
		unsigned char *ptr;
		int i, bpp=Depth>>3;

		for(i=0, ptr=Image->Data;i<Height;i++, ptr+=Width*bpp)
			rle_write(ptr, Width, bpp, stream);
	}
	else
Exemple #2
0
static gboolean
_cairo_surface_write_as_tga (cairo_surface_t  *image,
			     char            **buffer,
			     gsize            *buffer_size,
			     char            **keys,
			     char            **values,
			     GError          **error)
{
	GthBufferData *buffer_data;
	int            out_bpp = 0;
	int            row;
	guchar         header[18];
	guchar         footer[26];
	gboolean       rle_compression;
	gboolean       alpha;
	guchar        *pixels, *ptr, *buf;
	int            width, height;
	int            rowstride;

	rle_compression = TRUE;

	if (keys && *keys) {
		char **kiter = keys;
		char **viter = values;

		while (*kiter) {
			if (strcmp (*kiter, "compression") == 0) {
				if (*viter == NULL) {
					g_set_error (error,
						     GDK_PIXBUF_ERROR,
						     GDK_PIXBUF_ERROR_BAD_OPTION,
						     "Must specify a compression type");
					return FALSE;
				}

				if (strcmp (*viter, "none") == 0)
					rle_compression = FALSE;

				else if (strcmp (*viter, "rle") == 0)
					rle_compression = TRUE;

				else {
					g_set_error (error,
						     GDK_PIXBUF_ERROR,
						     GDK_PIXBUF_ERROR_BAD_OPTION,
						     "Unsupported compression type passed to the TGA saver");
					return FALSE;
				}
			}
			else {
				g_warning ("Bad option name '%s' passed to the TGA saver", *kiter);
				return FALSE;
			}

			++kiter;
			++viter;
		}
	}

	width     = cairo_image_surface_get_width (image);
	height    = cairo_image_surface_get_height (image);
	alpha     = _cairo_image_surface_get_has_alpha (image);
	pixels    = _cairo_image_surface_flush_and_get_data (image);
	rowstride = cairo_image_surface_get_stride (image);

	buffer_data = gth_buffer_data_new ();

	/* write the header */

	header[0] = 0; /* No image identifier / description */
	header[1] = 0;
	header[2] = rle_compression ? 10 : 2;
	header[3] = header[4] = header[5] = header[6] = header[7] = 0;
	header[8]  = header[9]  = 0; /* xorigin */
	header[10] = header[11] = 0; /* yorigin */
	header[12] = width % 256;
	header[13] = width / 256;
	header[14] = height % 256;
	header[15] = height / 256;
	if (alpha) {
		out_bpp = 4;
		header[16] = 32; /* bpp */
		header[17] = 0x28; /* alpha + orientation */
	}
	else {
		out_bpp = 3;
		header[16] = 24; /* bpp */
		header[17] = 0x20; /* alpha + orientation */
	}
	gth_buffer_data_write (buffer_data, header, sizeof (header), error);

	/* allocate a small buffer to convert image data */
	buf = g_try_malloc (width * out_bpp * sizeof (guchar));
	if (! buf) {
		g_set_error_literal (error,
				     GDK_PIXBUF_ERROR,
				     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
				     _("Insufficient memory"));
		return FALSE;
	}

	ptr = pixels;
	for (row = 0; row < height; ++row) {
		_cairo_copy_line_as_rgba_little_endian (buf, ptr, width, alpha);

		if (rle_compression)
			rle_write (buffer_data, buf, width, out_bpp, error);
		else
			gth_buffer_data_write (buffer_data, buf, width * out_bpp, error);

		ptr += rowstride;
	}

	g_free (buf);

	/* write the footer  */

	memset (footer, 0, 8); /* No extensions, no developer directory */
	memcpy (footer + 8, magic, sizeof (magic)); /* magic signature */
	gth_buffer_data_write (buffer_data, footer, sizeof (footer), error);

	gth_buffer_data_get (buffer_data, buffer, buffer_size);
	gth_buffer_data_free (buffer_data, FALSE);

	return TRUE;
}
Exemple #3
0
static gboolean
_gdk_pixbuf_save_as_tga (GdkPixbuf   *pixbuf,
			 const char  *filename,
			 char       **keys,
			 char       **values,
			 GError     **error)
{
	FILE      *fp;
	int        out_bpp = 0;
	int        row;
	guchar     header[18];
	guchar     footer[26];
	gboolean   rle_compression;
	gboolean   alpha;
	guchar    *pixels, *ptr, *buf;
	int        width, height;
	int        rowstride;

	rle_compression = TRUE;

	if (keys && *keys) {
		char **kiter = keys;
		char **viter = values;

		while (*kiter) {
			if (strcmp (*kiter, "compression") == 0) {
				if (*viter == NULL) {
					g_set_error (error,
						     GDK_PIXBUF_ERROR,
						     GDK_PIXBUF_ERROR_BAD_OPTION,
						     "Must specify a compression type");
					return FALSE;
				}

				if (strcmp (*viter, "none") == 0)
					rle_compression = FALSE;

				else if (strcmp (*viter, "rle") == 0)
					rle_compression = TRUE;

				else {
					g_set_error (error,
						     GDK_PIXBUF_ERROR,
						     GDK_PIXBUF_ERROR_BAD_OPTION,
						     "Unsupported compression type passed to the TGA saver");
					return FALSE;
				}
			} else {
				g_warning ("Bad option name '%s' passed to the TGA saver", *kiter);
				return FALSE;
			}

			++kiter;
			++viter;
		}
	}

	width     = gdk_pixbuf_get_width (pixbuf);
	height    = gdk_pixbuf_get_height (pixbuf);
	alpha     = gdk_pixbuf_get_has_alpha (pixbuf);
	pixels    = gdk_pixbuf_get_pixels (pixbuf);
	rowstride = gdk_pixbuf_get_rowstride (pixbuf);

	if ((fp = fopen (filename, "wb")) == NULL) {
		g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_FAILED,
			     "Can't write image to file '%s'",
			     filename);
		return FALSE;
	}

	header[0] = 0; /* No image identifier / description */

	header[1]= 0;
	header[2]= rle_compression ? 10 : 2;
	header[3] = header[4] = header[5] = header[6] = header[7] = 0;

	header[8]  = header[9]  = 0; /* xorigin */
	header[10] = header[11] = 0; /* yorigin */

	header[12] = width % 256;
	header[13] = width / 256;

	header[14] = height % 256;
	header[15] = height / 256;

	if (alpha) {
		out_bpp = 4;
		header[16] = 32; /* bpp */
		header[17] = 0x28; /* alpha + orientation */
	} else {
		out_bpp = 3;
		header[16] = 24; /* bpp */
		header[17] = 0x20; /* alpha + orientation */
	}

	/* write header to front of file */
	fwrite (header, sizeof (header), 1, fp);

	/* allocate a small buffer to convert image data */
	buf = g_try_malloc (width * out_bpp * sizeof (guchar));
	if (! buf) {
		g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
			     "Couldn't allocate memory for writing TGA file '%s'",
			     filename);
		return FALSE;
	}

	ptr = pixels;

	for (row = 0; row < height; ++row) {
		bgr2rgb (buf, ptr, width, out_bpp, alpha);

		if (rle_compression)
			rle_write (fp, buf, width, out_bpp);
		else
			fwrite (buf, width * out_bpp, 1, fp);

		ptr += rowstride;
	}

	g_free (buf);

	/* footer must be the last thing written to file */
	memset (footer, 0, 8); /* No extensions, no developer directory */
	memcpy (footer + 8, magic, sizeof (magic)); /* magic signature */
	fwrite (footer, sizeof (footer), 1, fp);

	fclose (fp);

	return TRUE;
}