static void _cairo_png_data_destroy (CairoPngData *cairo_png_data) { png_destroy_write_struct (&cairo_png_data->png_ptr, &cairo_png_data->png_info_ptr); gth_buffer_data_free (cairo_png_data->buffer_data, FALSE); g_free (cairo_png_data); }
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; }
static void _cairo_webp_data_destroy (CairoWebpData *cairo_webp_data) { gth_buffer_data_free (cairo_webp_data->buffer_data, ! cairo_webp_data->success); g_free (cairo_webp_data); }