Benjamin Otte
2007-Feb-06 03:18 UTC
[Swfdec] Branch 'interpreter' - 8 commits - libswfdec/swfdec_bits.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_edittext.c libswfdec/swfdec_image.c libswfdec/swfdec_image.h libswfdec/swfdec_pattern.c libswfdec/swfdec_sprite.c test/dump.c test/swfdec-extract.c test/swfdec_out.c test/swfedit_token.c
libswfdec/swfdec_bits.c | 4 libswfdec/swfdec_color.c | 41 +++--- libswfdec/swfdec_color.h | 29 +++- libswfdec/swfdec_edittext.c | 2 libswfdec/swfdec_image.c | 269 +++++++++++++++++++++++--------------------- libswfdec/swfdec_image.h | 9 - libswfdec/swfdec_pattern.c | 29 +--- libswfdec/swfdec_sprite.c | 7 - test/dump.c | 34 +++++ test/swfdec-extract.c | 14 ++ test/swfdec_out.c | 14 +- test/swfedit_token.c | 12 - 12 files changed, 276 insertions(+), 188 deletions(-) New commits: diff-tree a86c50354559053bfdba86f13cdf8ec9c455205a (from parents) Merge: 940ef9614313d253bb9282e26f48968b4af13c85 d7db95f092791ed1e81ad2d2e4f9e3fb345d6f79 Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 18:39:22 2007 +0100 Merge branch 'master' into interpreter Conflicts: libswfdec/swfdec_image.c diff --cc libswfdec/swfdec_bits.c index f3ea7c4,5013e49..21172f2 @@@ -482,13 -450,13 +482,13 @@@ g = swfdec_bits_get_u8 (bits); b = swfdec_bits_get_u8 (bits); - return SWF_COLOR_COMBINE (r, g, b, 0xff); + return SWFDEC_COLOR_COMBINE (r, g, b, 0xff); } -unsigned int +SwfdecColor swfdec_bits_get_rgba (SwfdecBits * bits) { - int r, g, b, a; + unsigned int r, g, b, a; r = swfdec_bits_get_u8 (bits); g = swfdec_bits_get_u8 (bits); diff --cc libswfdec/swfdec_image.c index 23602c4,224e101..53dad98 @@@ -290,18 -288,19 +267,17 @@@ swfdec_image_jpeg3_load (SwfdecImage *image) { JpegRGBDecoder *dec; - unsigned char *image_data; unsigned char *alpha_data; SwfdecBits bits; - int len; + SwfdecBuffer *buffer; int jpeg_length; - bits.buffer = image->raw_data; - bits.ptr = image->raw_data->data; - bits.idx = 0; - bits.end = bits.ptr + image->raw_data->length; - - bits.ptr += 2; + swfdec_bits_init (&bits, image->raw_data); jpeg_length = swfdec_bits_get_u32 (&bits); + buffer = swfdec_bits_get_buffer (&bits, jpeg_length); + if (buffer == NULL) + return; dec = jpeg_rgb_decoder_new (); @@@ -318,15 -316,13 +294,13 @@@ &image->rowstride, &image->width, &image->height); jpeg_rgb_decoder_free (dec); - bits.ptr += jpeg_length; - - alpha_data = lossless (bits.ptr, bits.end - bits.ptr, &len); + buffer = swfdec_bits_get_buffer (&bits, -1); + alpha_data = lossless (buffer->data, buffer->length, image->width * image->height); + swfdec_buffer_unref (buffer); - merge_alpha (image, image_data, alpha_data); + merge_alpha (image, image->data, alpha_data); g_free (alpha_data); - swfdec_image_create_surface (image, image_data); - SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height); } @@@ -356,13 -348,20 +326,12 @@@ swfdec_image_lossless_load (SwfdecImage *image) { int format; - int color_table_size; + guint color_table_size; unsigned char *ptr; - int len; - unsigned char *endptr; SwfdecBits bits; - unsigned char *image_data = NULL; int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2); - bits.buffer = image->raw_data; - bits.ptr = image->raw_data->data; - bits.idx = 0; - bits.end = bits.ptr + image->raw_data->length; - endptr = bits.ptr + bits.buffer->length; - - bits.ptr += 2; + swfdec_bits_init (&bits, image->raw_data); format = swfdec_bits_get_u8 (&bits); SWFDEC_LOG (" format = %d", format); @@@ -384,29 -383,31 +353,29 @@@ if (image->width == 0 || image->height == 0) return; swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); - ptr = lossless (bits.ptr, endptr - bits.ptr, &len); - bits.ptr = endptr; if (format == 3) { - unsigned char *color_table; unsigned char *indexed_data; - int i; + guint i; + unsigned int rowstride = (image->width + 3) & ~3; - image_data = g_malloc (4 * image->width * image->height); + image->data = g_malloc (4 * image->width * image->height); image->rowstride = image->width * 4; - color_table = g_malloc (color_table_size * 4); - if (have_alpha) { + ptr = lossless (bits.ptr, bits.end - bits.ptr, + color_table_size * 4 + rowstride * image->height); for (i = 0; i < color_table_size; i++) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN - color_table[i * 4 + 0] = ptr[i * 4 + 2]; - color_table[i * 4 + 1] = ptr[i * 4 + 1]; - color_table[i * 4 + 2] = ptr[i * 4 + 0]; - color_table[i * 4 + 3] = ptr[i * 4 + 3]; + guint8 tmp = ptr[i * 4 + 0]; + ptr[i * 4 + 0] = ptr[i * 4 + 2]; + ptr[i * 4 + 2] = tmp; #else - color_table[i * 4 + 0] = ptr[i * 4 + 3]; - color_table[i * 4 + 1] = ptr[i * 4 + 0]; - color_table[i * 4 + 2] = ptr[i * 4 + 1]; - color_table[i * 4 + 3] = ptr[i * 4 + 2]; + guint8 tmp = ptr[i * 4 + 3]; + ptr[i * 4 + 3] = ptr[i * 4 + 2]; + ptr[i * 4 + 2] = ptr[i * 4 + 1]; + ptr[i * 4 + 1] = ptr[i * 4 + 0]; + ptr[i * 4 + 0] = tmp; #endif } indexed_data = ptr + color_table_size * 4; @@@ -432,70 -427,55 +401,51 @@@ } indexed_data = ptr + color_table_size * 3; } - swfdec_image_colormap_decode (image, image_data, indexed_data, + swfdec_image_colormap_decode (image, image->data, indexed_data, - color_table, color_table_size); + ptr, color_table_size); - g_free (color_table); g_free (ptr); -- } -- if (format == 4) { - unsigned char *p = ptr; ++ } else if (format == 4) { int i, j; unsigned int c; unsigned char *idata; ++ guint8 *p; if (have_alpha) { SWFDEC_INFO("16bit images aren't allowed to have alpha, ignoring"); have_alpha = FALSE; } - ptr = lossless (bits.ptr, bits.end - bits.ptr, 2 * image->width * image->height); - image_data = g_malloc (4 * image->width * image->height); - idata = image_data; ++ p = ptr = lossless (bits.ptr, bits.end - bits.ptr, 2 * image->width * image->height); + image->data = g_malloc (4 * image->width * image->height); + idata = image->data; image->rowstride = image->width * 4; /* 15 bit packed */ for (j = 0; j < image->height; j++) { for (i = 0; i < image->width; i++) { - c = ptr[1] | (ptr[0] << 8); - #if G_BYTE_ORDER == G_LITTLE_ENDIAN - idata[0] = (c << 3) | ((c >> 2) & 0x7); - idata[1] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); - idata[2] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); - idata[3] = 0xff; - #else - idata[3] = (c << 3) | ((c >> 2) & 0x7); - idata[2] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); - idata[1] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); - idata[0] = 0xff; - #endif + c = p[1] | (p[0] << 8); + idata[SWFDEC_COLOR_INDEX_BLUE] = (c << 3) | ((c >> 2) & 0x7); + idata[SWFDEC_COLOR_INDEX_GREEN] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); + idata[SWFDEC_COLOR_INDEX_RED] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); + idata[SWFDEC_COLOR_INDEX_ALPHA] = 0xff; - p += 2; + ptr += 2; idata += 4; } } g_free (ptr); } if (format == 5) { - - image_data = lossless (bits.ptr, bits.end - bits.ptr, 4 * image->width * image->height); - image->rowstride = image->width * 4; - - #if G_BYTE_ORDER == G_LITTLE_ENDIAN - { - int i, j; - /* image is stored in 0RGB format. We use ARGB/BGRA. */ - for (j = 0; j < image->height; j++) { - for (i = 0; i < image->width; i++) { - ptr[0] = ptr[3]; - ptr[1] = ptr[2]; - ptr[2] = ptr[1]; - ptr[3] = 255; - ptr += 4; - } + int i, j; - - image->data = ptr; - image->rowstride = image->width * 4; - ++ ptr = image->data = lossless (bits.ptr, bits.end - bits.ptr, 4 * image->width * image->height); + /* image is stored in 0RGB format. We use ARGB/BGRA. */ + for (j = 0; j < image->height; j++) { + for (i = 0; i < image->width; i++) { + *((guint32 *) ptr) = GUINT32_FROM_BE (*((guint32 *) ptr)); + ptr += 4; } } - #endif } - - swfdec_image_create_surface (image, image_data); } int diff --cc test/dump.c index 9ee0524,9ee0524..efddeee @@@ -1,7 -1,7 +1,7 @@@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> -- * 2006 Benjamin Otte <otte@gnome.org> ++ * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@@ -34,6 -34,6 +34,7 @@@ #include <libswfdec/swfdec_button.h> #include <libswfdec/swfdec_edittext.h> #include <libswfdec/swfdec_font.h> ++#include <libswfdec/swfdec_image.h> #include <libswfdec/swfdec_movie.h> #include <libswfdec/swfdec_player_internal.h> #include <libswfdec/swfdec_root_movie.h> @@@ -287,6 -287,6 +288,34 @@@ } } ++const char * ++get_image_type_name (SwfdecImageType type) ++{ ++ switch (type) { ++ case SWFDEC_IMAGE_TYPE_JPEG: ++ return "JPEG with global table"; ++ case SWFDEC_IMAGE_TYPE_JPEG2: ++ return "JPEG"; ++ case SWFDEC_IMAGE_TYPE_JPEG3: ++ return "JPEG with alpha"; ++ case SWFDEC_IMAGE_TYPE_LOSSLESS: ++ return "lossless"; ++ case SWFDEC_IMAGE_TYPE_LOSSLESS2: ++ return "lossless with alpha"; ++ default: ++ g_assert_not_reached (); ++ return "Unknown"; ++ } ++} ++ ++static void ++dump_image (SwfdecImage *image) ++{ ++ cairo_surface_destroy (swfdec_image_create_surface (image)); ++ g_print (" %s %u x %u\n", get_image_type_name (image->type), ++ image->width, image->height); ++} ++ static void dump_objects (SwfdecSwfDecoder *s) { @@@ -301,6 -301,6 +330,9 @@@ g_print (" extents: %g %g %g %g\n", graphic->extents.x0, graphic->extents.y0, graphic->extents.x1, graphic->extents.y1); } ++ if (SWFDEC_IS_IMAGE (c)) { ++ dump_image (SWFDEC_IMAGE (c)); ++ } if (SWFDEC_IS_SPRITE (c)) { dump_sprite (SWFDEC_SPRITE (c)); } diff --cc test/swfdec-extract.c index ac79124,b4a2951..47e8234 @@@ -258,8 -269,11 +269,11 @@@ } else if (SWFDEC_IS_GRAPHIC (character)) { if (!export_graphic (SWFDEC_GRAPHIC (character), argv[3])) ret = 1; + } else if (SWFDEC_IS_IMAGE (character)) { + if (!export_image (SWFDEC_IMAGE (character), argv[3])) + ret = 1; } else { - g_printerr ("id %ld does not specify an exportable object", id); + g_printerr ("id %ld does not specify an exportable object\n", id); ret = 1; } diff --cc test/swfdec_out.c index bf7aa9e,0000000..0719b0f mode 100644,000000..100644 @@@ -1,258 -1,0 +1,258 @@@ +/* Swfdec + * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include "swfdec_out.h" + +SwfdecOut * +swfdec_out_open (void) +{ + SwfdecOut *out = g_new0 (SwfdecOut, 1); + + out->data = g_malloc (SWFDEC_OUT_INITIAL); + out->ptr = out->data; + out->end = out->data + SWFDEC_OUT_INITIAL; + + return out; +} + +static void +swfdec_out_syncbits (SwfdecOut *out) +{ + g_return_if_fail (out != NULL); + + if (out->idx > 0) { + out->ptr++; + out->idx = 0; + } +} + +SwfdecBuffer * +swfdec_out_close (SwfdecOut *out) +{ + SwfdecBuffer *buffer; + + g_return_val_if_fail (out != NULL, NULL); + + swfdec_out_syncbits (out); + + buffer = swfdec_buffer_new (); + buffer->data = out->data; + buffer->length = out->ptr - out->data; + + g_free (out); + + return buffer; +} + +unsigned int +swfdec_out_left (SwfdecOut *out) +{ + g_return_val_if_fail (out != NULL, 0); + + return (out->end - out->ptr) * 8 - out->idx; +} + +void +swfdec_out_ensure_bits (SwfdecOut *out, unsigned int bits) +{ + unsigned int current, taken, needed; + + g_return_if_fail (out != NULL); + + current = swfdec_out_left (out); + if (current >= bits) + return; + taken = out->ptr - out->data; + needed = (bits - current + 7) / 8; + needed += SWFDEC_OUT_STEP; + needed -= needed % SWFDEC_OUT_STEP; + needed += out->end - out->data; + out->data = g_realloc (out->data, needed); + out->ptr = out->data + taken; + out->end = out->data + needed; +} + +void +swfdec_out_prepare_bytes (SwfdecOut *out, unsigned int bytes) +{ + g_return_if_fail (out != NULL); + + swfdec_out_syncbits (out); + swfdec_out_ensure_bits (out, bytes * 8); +} + +void +swfdec_out_put_buffer (SwfdecOut *out, SwfdecBuffer *buffer) +{ + g_return_if_fail (out != NULL); + + swfdec_out_prepare_bytes (out, buffer->length); + memcpy (out->ptr, buffer->data, buffer->length); + out->ptr += buffer->length; +} + +void +swfdec_out_put_u8 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT8); + + swfdec_out_prepare_bytes (out, 1); + *out->ptr = i; + out->ptr++; +} + +void +swfdec_out_put_u16 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT16); + + swfdec_out_prepare_bytes (out, 2); + *(guint16 *)out->ptr = GUINT16_TO_LE (i); + out->ptr += 2; +} + +void +swfdec_out_put_u32 (SwfdecOut *out, guint i) +{ + g_return_if_fail (i <= G_MAXUINT32); + + swfdec_out_prepare_bytes (out, 4); + *(guint32 *)out->ptr = GUINT32_TO_LE (i); + out->ptr += 4; +} + +void +swfdec_out_put_bit (SwfdecOut *out, gboolean bit) +{ + g_return_if_fail (out != NULL); + + swfdec_out_put_bits (out, bit ? 1 : 0, 1); +} + +void +swfdec_out_put_bits (SwfdecOut *out, guint bits, guint n_bits) +{ + g_return_if_fail (out != NULL); + + swfdec_out_ensure_bits (out, n_bits); + + /* FIXME: implement this less braindead */ + while (n_bits) { + guint bits_now = MIN (n_bits, 8 - out->idx); + guint value = bits >> (n_bits - bits_now); + + /* clear data if necessary */ + if (out->idx == 0) + *out->ptr = 0; + value &= (1 << bits_now) - 1; + value <<= 8 - out->idx - bits_now; + *out->ptr |= value; + out->idx += bits_now; + g_assert (out->idx <= 8); + if (out->idx == 8) { + out->ptr ++; + out->idx = 0; + } + n_bits -= bits_now; + } +} + +void +swfdec_out_put_sbits (SwfdecOut *out, int bits, guint n_bits) +{ + g_return_if_fail (out != NULL); + swfdec_out_put_bits (out, bits, n_bits); +} + +static guint +swfdec_out_bits_required (guint x) +{ + guint ret = 0; + + while (x > 0) { + x >>= 1; + ret++; + } + return ret; +} + +static guint +swfdec_out_sbits_required (int x) +{ + if (x < 0) + x = -x; + return swfdec_out_bits_required (x) + 1; +} + +void +swfdec_out_put_rect (SwfdecOut *out, SwfdecRect *rect) +{ + int x0, x1, y0, y1; + guint req, tmp; + + g_return_if_fail (out != NULL); + g_return_if_fail (rect != NULL); + + x0 = rect->x0; + y0 = rect->y0; + x1 = rect->x1; + y1 = rect->y1; + req = swfdec_out_sbits_required (x0); + tmp = swfdec_out_sbits_required (y0); + req = MAX (req, tmp); + tmp = swfdec_out_sbits_required (x1); + req = MAX (req, tmp); + tmp = swfdec_out_sbits_required (y1); + req = MAX (req, tmp); + swfdec_out_syncbits (out); + swfdec_out_put_bits (out, req, 5); + swfdec_out_put_sbits (out, x0, req); + swfdec_out_put_sbits (out, x1, req); + swfdec_out_put_sbits (out, y0, req); + swfdec_out_put_sbits (out, y1, req); + swfdec_out_syncbits (out); +} + +void +swfdec_out_put_rgb (SwfdecOut *out, SwfdecColor color) +{ + g_return_if_fail (out != NULL); + - swfdec_out_put_u8 (out, SWF_COLOR_R (color)); - swfdec_out_put_u8 (out, SWF_COLOR_G (color)); - swfdec_out_put_u8 (out, SWF_COLOR_B (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); +} + +void +swfdec_out_put_rgba (SwfdecOut *out, SwfdecColor color) +{ + g_return_if_fail (out != NULL); + - swfdec_out_put_u8 (out, SWF_COLOR_R (color)); - swfdec_out_put_u8 (out, SWF_COLOR_G (color)); - swfdec_out_put_u8 (out, SWF_COLOR_B (color)); - swfdec_out_put_u8 (out, SWF_COLOR_A (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_R (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_G (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_B (color)); ++ swfdec_out_put_u8 (out, SWFDEC_COLOR_A (color)); +} + diff --cc test/swfedit_token.c index 8c8b075,0000000..f3f2bcc mode 100644,000000..100644 @@@ -1,573 -1,0 +1,573 @@@ +/* Swfedit + * Copyright (C) 2007 Benjamin Otte <otte@gnome.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, to_string to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include <gtk/gtk.h> +#include <libswfdec/swfdec_buffer.h> +#include <libswfdec/swfdec_color.h> +#include "swfedit_token.h" + +/*** CONVERTERS ***/ + +static gboolean +swfedit_parse_hex (const char *s, guint *result) +{ + guint byte; + + if (s[0] >= '0' && s[0] <= '9') + byte = s[0] - '0'; + else if (s[0] >= 'a' && s[0] <= 'f') + byte = s[0] + 10 - 'a'; + else if (s[0] >= 'A' && s[0] <= 'F') + byte = s[0] + 10 - 'A'; + else + return FALSE; + s++; + byte *= 16; + if (s[0] >= '0' && s[0] <= '9') + byte += s[0] - '0'; + else if (s[0] >= 'a' && s[0] <= 'f') + byte += s[0] + 10 - 'a'; + else if (s[0] >= 'A' && s[0] <= 'F') + byte += s[0] + 10 - 'A'; + else + return FALSE; + *result = byte; + return TRUE; +} + +static gboolean +swfedit_binary_from_string (const char *s, gpointer* result) +{ + GByteArray *array = g_byte_array_new (); + guint byte; + guint8 add; + + while (g_ascii_isspace (*s)) s++; + do { + if (!swfedit_parse_hex (s, &byte)) + break; + s += 2; + add = byte; + g_byte_array_append (array, &add, 1); + while (g_ascii_isspace (*s)) s++; + } while (*s != '\0'); + if (*s == '\0') { + SwfdecBuffer *buffer = swfdec_buffer_new (); + buffer->length = array->len; + buffer->data = array->data; + g_byte_array_free (array, FALSE); + *result = buffer; + return TRUE; + } + g_byte_array_free (array, TRUE); + return FALSE; +} + +static char * +swfedit_binary_to_string (gconstpointer value) +{ + guint i; + const SwfdecBuffer *buffer = value; + GString *string = g_string_new (""); + + for (i = 0; i < buffer->length; i++) { + if (i && i % 4 == 0) + g_string_append_c (string, ' '); + g_string_append_printf (string, "%02X", buffer->data[i]); + } + return g_string_free (string, FALSE); +} + +static gboolean +swfedit_from_string_unsigned (const char *s, gulong max, gpointer* result) +{ + char *end; + gulong u; + + g_assert (max <= G_MAXUINT); + u = strtoul (s, &end, 10); + if (*end != '\0') + return FALSE; + if (u > max) + return FALSE; + *result = GUINT_TO_POINTER (u); + return TRUE; +} + +static gboolean +swfedit_uint8_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT8, result); +} + +static gboolean +swfedit_uint16_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT16, result); +} + +static gboolean +swfedit_uint32_from_string (const char *s, gpointer* result) +{ + return swfedit_from_string_unsigned (s, G_MAXUINT32, result); +} + +static char * +swfedit_to_string_unsigned (gconstpointer value) +{ + return g_strdup_printf ("%u", GPOINTER_TO_UINT (value)); +} + +static gboolean +swfedit_rect_from_string (const char *s, gpointer* result) +{ + return FALSE; +} + +static char * +swfedit_rect_to_string (gconstpointer value) +{ + const SwfdecRect *rect = value; + + return g_strdup_printf ("%d, %d, %d, %d", (int) rect->x0, (int) rect->y0, + (int) rect->x1, (int) rect->y1); +} + +static gboolean +swfedit_rgb_from_string (const char *s, gpointer* result) +{ + guint r, g, b; + if (strlen (s) != 6) + return FALSE; + if (!swfedit_parse_hex (s, &r)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &g)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &b)) + return FALSE; - *result = GUINT_TO_POINTER (SWF_COLOR_COMBINE (r, g, b, 0xFF)); ++ *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, 0xFF)); + return TRUE; +} + +static char * +swfedit_rgb_to_string (gconstpointer value) +{ + guint c = GPOINTER_TO_UINT (value); + - return g_strdup_printf ("%02X%02X%02X", SWF_COLOR_R (c), - SWF_COLOR_G (c), SWF_COLOR_B (c)); ++ return g_strdup_printf ("%02X%02X%02X", SWFDEC_COLOR_R (c), ++ SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c)); +} + +static gboolean +swfedit_rgba_from_string (const char *s, gpointer* result) +{ + guint r, g, b, a; + if (strlen (s) != 8) + return FALSE; + if (!swfedit_parse_hex (s, &a)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &r)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &g)) + return FALSE; + s += 2; + if (!swfedit_parse_hex (s, &b)) + return FALSE; - *result = GUINT_TO_POINTER (SWF_COLOR_COMBINE (r, g, b, a)); ++ *result = GUINT_TO_POINTER (SWFDEC_COLOR_COMBINE (r, g, b, a)); + return TRUE; +} + +static char * +swfedit_rgba_to_string (gconstpointer value) +{ + guint c = GPOINTER_TO_UINT (value); + - return g_strdup_printf ("%02X%02X%02X%02X", SWF_COLOR_R (c), - SWF_COLOR_G (c), SWF_COLOR_B (c), SWF_COLOR_A (c)); ++ return g_strdup_printf ("%02X%02X%02X%02X", SWFDEC_COLOR_R (c), ++ SWFDEC_COLOR_G (c), SWFDEC_COLOR_B (c), SWFDEC_COLOR_A (c)); +} + +struct { + gboolean (* from_string) (const char *s, gpointer *); + char * (* to_string) (gconstpointer value); + void (* free) (gpointer value); +} converters[SWFEDIT_N_TOKENS] = { + { NULL, NULL, g_object_unref }, + { swfedit_binary_from_string, swfedit_binary_to_string, (GDestroyNotify) swfdec_buffer_unref }, + { swfedit_uint8_from_string, swfedit_to_string_unsigned, NULL }, + { swfedit_uint16_from_string, swfedit_to_string_unsigned, NULL }, + { swfedit_uint32_from_string, swfedit_to_string_unsigned, NULL }, + { swfedit_rect_from_string, swfedit_rect_to_string, g_free }, + { swfedit_rgb_from_string, swfedit_rgb_to_string, NULL }, + { swfedit_rgba_from_string, swfedit_rgba_to_string, NULL }, +}; + +/*** GTK_TREE_MODEL ***/ + +#if 0 +# define REPORT g_print ("%s\n", G_STRFUNC) +#else +# define REPORT +#endif +static GtkTreeModelFlags +swfedit_token_get_flags (GtkTreeModel *tree_model) +{ + REPORT; + return 0; +} + +static gint +swfedit_token_get_n_columns (GtkTreeModel *tree_model) +{ + SwfeditToken *token = SWFEDIT_TOKEN (tree_model); + + REPORT; + return token->tokens->len; +} + +static GType +swfedit_token_get_column_type (GtkTreeModel *tree_model, gint index_) +{ + REPORT; + switch (index_) { + case SWFEDIT_COLUMN_NAME: + return G_TYPE_STRING; + case SWFEDIT_COLUMN_VALUE_VISIBLE: + return G_TYPE_BOOLEAN; + case SWFEDIT_COLUMN_VALUE: + return G_TYPE_STRING; + default: + break; + } + g_assert_not_reached (); + return G_TYPE_NONE; +} + +static gboolean +swfedit_token_get_iter (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreePath *path) +{ + SwfeditToken *token = SWFEDIT_TOKEN (tree_model); + guint i = gtk_tree_path_get_indices (path)[0]; + SwfeditTokenEntry *entry; + + REPORT; + if (i > token->tokens->len) + return FALSE; + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (gtk_tree_path_get_depth (path) > 1) { + GtkTreePath *new; + int j; + int *indices; + gboolean ret; + + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + new = gtk_tree_path_new (); + indices = gtk_tree_path_get_indices (path); + for (j = 1; j < gtk_tree_path_get_depth (path); j++) { + gtk_tree_path_append_index (new, indices[j]); + } + ret = swfedit_token_get_iter (GTK_TREE_MODEL (entry->value), iter, new); + gtk_tree_path_free (new); + return ret; + } else { + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (i); + return TRUE; + } +} + +static GtkTreePath * +swfedit_token_get_path (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + GtkTreePath *path = gtk_tree_path_new_from_indices (GPOINTER_TO_INT (iter->user_data2), -1); + + REPORT; + while (token->parent) { + guint i; + SwfeditToken *parent = token->parent; + for (i = 0; i < parent->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + continue; + if (entry->value == token) + break; + } + gtk_tree_path_prepend_index (path, i); + token = parent; + } + return path; +} + +static void +swfedit_token_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, + gint column, GValue *value) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + switch (column) { + case SWFEDIT_COLUMN_NAME: + g_value_init (value, G_TYPE_STRING); + g_value_set_string (value, entry->name); + return; + case SWFEDIT_COLUMN_VALUE_VISIBLE: + g_value_init (value, G_TYPE_BOOLEAN); + g_value_set_boolean (value, converters[entry->type].to_string != NULL); + return; + case SWFEDIT_COLUMN_VALUE: + g_value_init (value, G_TYPE_STRING); + if (converters[entry->type].to_string) + g_value_take_string (value, converters[entry->type].to_string (entry->value)); + return; + default: + break; + } + g_assert_not_reached (); +} + +static gboolean +swfedit_token_iter_next (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + + REPORT; + if ((guint) GPOINTER_TO_INT (iter->user_data2) + 1 >= token->tokens->len) + return FALSE; + + iter->user_data2++; + return TRUE; +} + +static gboolean +swfedit_token_iter_children (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *parent) +{ + SwfeditToken *token; + SwfeditTokenEntry *entry; + + REPORT; + if (parent) { + token = SWFEDIT_TOKEN (parent->user_data); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + token = entry->value; + } else { + token = SWFEDIT_TOKEN (tree_model); + } + if (token->tokens->len == 0) + return FALSE; + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (0); + return TRUE; +} + +static gboolean +swfedit_token_iter_has_child (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + return entry->type == SWFEDIT_TOKEN_OBJECT && SWFEDIT_TOKEN (entry->value)->tokens->len > 0; +} + +static gint +swfedit_token_iter_n_children (GtkTreeModel *tree_model, GtkTreeIter *iter) +{ + SwfeditToken *token = SWFEDIT_TOKEN (iter->user_data); + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (iter->user_data2)); + + REPORT; + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return 0; + + token = entry->value; + return token->tokens->len; +} + +static gboolean +swfedit_token_iter_nth_child (GtkTreeModel *tree_model, GtkTreeIter *iter, + GtkTreeIter *parent, gint n) +{ + SwfeditToken *token; + SwfeditTokenEntry *entry; + + REPORT; + if (parent) { + token = SWFEDIT_TOKEN (parent->user_data); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, GPOINTER_TO_INT (parent->user_data2)); + + if (entry->type != SWFEDIT_TOKEN_OBJECT) + return FALSE; + + token = entry->value; + } else { + token = SWFEDIT_TOKEN (tree_model); + } + if ((guint) n >= token->tokens->len) + return FALSE; + iter->stamp = 0; /* FIXME */ + iter->user_data = token; + iter->user_data2 = GINT_TO_POINTER (n); + return TRUE; +} + +static gboolean +swfedit_token_iter_parent (GtkTreeModel *tree_model, GtkTreeIter *iter, GtkTreeIter *child) +{ + guint i; + SwfeditToken *token = SWFEDIT_TOKEN (child->user_data); + SwfeditToken *parent = token->parent; + + REPORT; + if (parent == NULL) + return FALSE; + + for (i = 0; i < parent->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (parent->tokens, SwfeditTokenEntry, i); + if (entry->type != SWFEDIT_TOKEN_OBJECT) + continue; + if (entry->value == token) + break; + } + iter->stamp = 0; /* FIXME */ + iter->user_data = parent; + iter->user_data2 = GINT_TO_POINTER (i); + return TRUE; +} + +static void +swfedit_token_tree_model_init (GtkTreeModelIface *iface) +{ + iface->get_flags = swfedit_token_get_flags; + iface->get_n_columns = swfedit_token_get_n_columns; + iface->get_column_type = swfedit_token_get_column_type; + iface->get_iter = swfedit_token_get_iter; + iface->get_path = swfedit_token_get_path; + iface->get_value = swfedit_token_get_value; + iface->iter_next = swfedit_token_iter_next; + iface->iter_children = swfedit_token_iter_children; + iface->iter_has_child = swfedit_token_iter_has_child; + iface->iter_n_children = swfedit_token_iter_n_children; + iface->iter_nth_child = swfedit_token_iter_nth_child; + iface->iter_parent = swfedit_token_iter_parent; +} + +/*** SWFEDIT_TOKEN ***/ + +G_DEFINE_TYPE_WITH_CODE (SwfeditToken, swfedit_token, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL, swfedit_token_tree_model_init)) + +static void +swfedit_token_dispose (GObject *object) +{ + SwfeditToken *token = SWFEDIT_TOKEN (object); + guint i; + + for (i = 0; i < token->tokens->len; i++) { + SwfeditTokenEntry *entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + g_free (entry->name); + if (converters[entry->type].free) + converters[entry->type].free (entry->value); + } + g_array_free (token->tokens, TRUE); + + G_OBJECT_CLASS (swfedit_token_parent_class)->dispose (object); +} + +static void +swfedit_token_class_init (SwfeditTokenClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->dispose = swfedit_token_dispose; +} + +static void +swfedit_token_init (SwfeditToken *token) +{ + token->tokens = g_array_new (FALSE, FALSE, sizeof (SwfeditTokenEntry)); +} + +SwfeditToken * +swfedit_token_new (void) +{ + SwfeditToken *token; + + token = g_object_new (SWFEDIT_TYPE_TOKEN, NULL); + return token; +} + +void +swfedit_token_add (SwfeditToken *token, const char *name, SwfeditTokenType type, gpointer value) +{ + SwfeditTokenEntry entry = { NULL, type, value }; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (name != NULL); + g_return_if_fail (type < SWFEDIT_N_TOKENS); + + entry.name = g_strdup (name); + g_array_append_val (token->tokens, entry); +} + +void +swfedit_token_set (SwfeditToken *token, GtkTreeIter *iter, const char *value) +{ + GtkTreeModel *model; + SwfeditTokenEntry *entry; + guint i; + gpointer new; + GtkTreePath *path; + + g_return_if_fail (SWFEDIT_IS_TOKEN (token)); + g_return_if_fail (iter != NULL); + g_return_if_fail (value != NULL); + + model = GTK_TREE_MODEL (token); + token = iter->user_data; + i = GPOINTER_TO_UINT (iter->user_data2); + entry = &g_array_index (token->tokens, SwfeditTokenEntry, i); + if (converters[entry->type].from_string == NULL) + return; + if (!converters[entry->type].from_string (value, &new)) + return; + if (converters[entry->type].free != NULL) + converters[entry->type].free (entry->value); + entry->value = new; + + path = gtk_tree_model_get_path (model, iter); + gtk_tree_model_row_changed (model, path, iter); + gtk_tree_path_free (path); +} + diff-tree d7db95f092791ed1e81ad2d2e4f9e3fb345d6f79 (from ad56f27f4cc82a6913a7adcf05704b2cb91e6c61) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 16:14:23 2007 +0100 export images, too diff --git a/test/swfdec-extract.c b/test/swfdec-extract.c index bea068e..b4a2951 100644 --- a/test/swfdec-extract.c +++ b/test/swfdec-extract.c @@ -35,6 +35,7 @@ #include <libswfdec/swfdec_audio_stream.h> #include <libswfdec/swfdec_button.h> #include <libswfdec/swfdec_graphic.h> +#include <libswfdec/swfdec_image.h> #include <libswfdec/swfdec_player_internal.h> #include <libswfdec/swfdec_root_movie.h> #include <libswfdec/swfdec_sound.h> @@ -206,6 +207,16 @@ export_graphic (SwfdecGraphic *graphic, return surface_destroy_for_type (surface, filename); } +static gboolean +export_image (SwfdecImage *image, const char *filename) +{ + cairo_surface_t *surface = swfdec_image_create_surface (image); + + if (surface == NULL) + return FALSE; + return surface_destroy_for_type (surface, filename); +} + static void usage (const char *app) { @@ -258,6 +269,9 @@ main (int argc, char *argv[]) } else if (SWFDEC_IS_GRAPHIC (character)) { if (!export_graphic (SWFDEC_GRAPHIC (character), argv[3])) ret = 1; + } else if (SWFDEC_IS_IMAGE (character)) { + if (!export_image (SWFDEC_IMAGE (character), argv[3])) + ret = 1; } else { g_printerr ("id %ld does not specify an exportable object", id); ret = 1; diff-tree ad56f27f4cc82a6913a7adcf05704b2cb91e6c61 (from 32e4b86c8fac7b199a4f2d210f0ec6d67347091c) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 16:14:13 2007 +0100 add debugging message when parsing color transforms diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c index 074bb37..246776a 100644 --- a/libswfdec/swfdec_sprite.c +++ b/libswfdec/swfdec_sprite.c @@ -364,6 +364,11 @@ swfdec_spriteseg_place_object_2 (SwfdecS } if (has_color_transform) { swfdec_bits_get_color_transform (bits, &content->color_transform); + SWFDEC_LOG (" color transform = %d %d %d %d %d %d %d %d", + content->color_transform.ra, content->color_transform.rb, + content->color_transform.ga, content->color_transform.gb, + content->color_transform.ba, content->color_transform.bb, + content->color_transform.aa, content->color_transform.ab); } swfdec_bits_syncbits (bits); if (has_ratio) { diff-tree 32e4b86c8fac7b199a4f2d210f0ec6d67347091c (from 2399ad61b0ffc8fcbd1c395dc841deec152e29e4) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 14:53:42 2007 +0100 rename swfdec_image_get_surface* to swfdec_image_create_surface* - The renamed functions give out a reference to the surface now. - Ensure that surfaces created by those functions get unreffed properly - Add an obvious optimization by not applying the color transform if the transform is the identity transform diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c index e276508..224e101 100644 --- a/libswfdec/swfdec_image.c +++ b/libswfdec/swfdec_image.c @@ -647,7 +647,7 @@ swfdec_image_create_surface (SwfdecImage } cairo_surface_t * -swfdec_image_get_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans) +swfdec_image_create_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans) { static const cairo_user_data_key_t key; cairo_surface_t *surface; @@ -659,6 +659,10 @@ swfdec_image_get_surface_transformed (Sw g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL); g_return_val_if_fail (trans != NULL, NULL); + /* obvious optimization */ + if (swfdec_color_transform_is_identity (trans)) + return swfdec_image_create_surface (image); + if (!swfdec_image_ensure_loaded (image)) return NULL; diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h index ad40181..3c1e71e 100644 --- a/libswfdec/swfdec_image.h +++ b/libswfdec/swfdec_image.h @@ -66,8 +66,8 @@ struct _SwfdecImageClass { GType swfdec_image_get_type (void); -cairo_surface_t * swfdec_image_get_surface (SwfdecImage * image); -cairo_surface_t * swfdec_image_get_surface_transformed +cairo_surface_t * swfdec_image_create_surface (SwfdecImage * image); +cairo_surface_t * swfdec_image_create_surface_transformed (SwfdecImage * image, const SwfdecColorTransform *trans); diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 938f827..536698a 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -266,9 +266,10 @@ swfdec_image_pattern_paint (SwfdecPatter cairo_matrix_t mat; cairo_surface_t *surface; - surface = swfdec_image_get_surface_transformed (image->image, trans); + surface = swfdec_image_create_surface_transformed (image->image, trans); cairo_append_path (cr, (cairo_path_t *) path); pattern = cairo_pattern_create_for_surface (surface); + cairo_surface_destroy (surface); swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio); cairo_pattern_set_matrix (pattern, &mat); cairo_pattern_set_extend (pattern, image->extend); @@ -626,7 +627,7 @@ swfdec_pattern_to_string (SwfdecPattern if (SWFDEC_IS_IMAGE_PATTERN (pattern)) { SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pattern); if (image->image->width == 0) - swfdec_image_get_surface (image->image); + cairo_surface_destroy (swfdec_image_create_surface (image->image)); return g_strdup_printf ("%ux%u image %u (%s, %s)", image->image->width, image->image->height, SWFDEC_CHARACTER (image->image)->id, image->extend == CAIRO_EXTEND_REPEAT ? "repeat" : "no repeat", diff-tree 2399ad61b0ffc8fcbd1c395dc841deec152e29e4 (from 180879c4af107625b53f37ba8bcc990eb20baf8b) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 14:49:54 2007 +0100 add swfdec_color_transform_is_identity useful for optimizations diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c index 7761653..73276a0 100644 --- a/libswfdec/swfdec_color.c +++ b/libswfdec/swfdec_color.c @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -125,6 +125,13 @@ swfdec_color_transform_init_color (Swfde trans->ab = SWFDEC_COLOR_A (color); } +gboolean +swfdec_color_transform_is_identity (const SwfdecColorTransform * trans) +{ + return trans->ra == 256 && trans->ga == 256 && trans->ba == 256 && trans->aa == 256 && + trans->rb == 0 && trans->gb == 0 && trans->bb == 0 && trans->ab == 0; +} + /** * swfdec_color_transform_chain: * @dest: #SwfdecColorTransform to take the result diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h index b38c269..46fdea4 100644 --- a/libswfdec/swfdec_color.h +++ b/libswfdec/swfdec_color.h @@ -72,6 +72,7 @@ SwfdecColor swfdec_color_apply_morph (Sw void swfdec_color_set_source (cairo_t *cr, SwfdecColor color); void swfdec_color_transform_init_identity (SwfdecColorTransform * trans); void swfdec_color_transform_init_color (SwfdecColorTransform *trans, SwfdecColor color); +gboolean swfdec_color_transform_is_identity (const SwfdecColorTransform * trans); void swfdec_color_transform_chain (SwfdecColorTransform *dest, const SwfdecColorTransform *last, const SwfdecColorTransform *first); unsigned int swfdec_color_apply_transform (unsigned int in, diff-tree 180879c4af107625b53f37ba8bcc990eb20baf8b (from fa335acfbd3526f57dfb66c68e59334a79d90901) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 14:33:59 2007 +0100 rework images to be correctly color transformed - use new SWFDEC_COLOR_INDEX variables when decoding - avoids #if - ditch caching as we might need the unpremultiplied image for color transforms - implement swfdec_image_get_surface_transformed - use it in the image pattern diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c index 0cf6502..e276508 100644 --- a/libswfdec/swfdec_image.c +++ b/libswfdec/swfdec_image.c @@ -50,7 +50,10 @@ swfdec_image_unload (SwfdecCached *cache if (image->surface) { cairo_surface_destroy (image->surface); image->surface = NULL; + } else if (image->data) { + g_free (image->data); } + image->data = NULL; } static void @@ -185,24 +188,9 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco } static void -swfdec_image_create_surface (SwfdecImage *image, guint8 *data, gboolean has_alpha) -{ - static const cairo_user_data_key_t key; - - g_assert (image->surface == NULL); - - image->surface = cairo_image_surface_create_for_data (data, - has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, - image->width, image->height, image->rowstride); - cairo_surface_set_user_data (image->surface, &key, data, - g_free); -} - -static void swfdec_image_jpeg_load (SwfdecImage *image) { JpegRGBDecoder *dec; - unsigned char *image_data; dec = jpeg_rgb_decoder_new (); @@ -217,10 +205,9 @@ swfdec_image_jpeg_load (SwfdecImage *ima return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); - jpeg_rgb_decoder_get_image (dec, &image_data, + jpeg_rgb_decoder_get_image (dec, &image->data, &image->rowstride, NULL, NULL); jpeg_rgb_decoder_free (dec); - swfdec_image_create_surface (image, image_data, FALSE); SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height); @@ -252,7 +239,6 @@ static void swfdec_image_jpeg2_load (SwfdecImage *image) { JpegRGBDecoder *dec; - unsigned char *image_data; dec = jpeg_rgb_decoder_new (); @@ -265,10 +251,9 @@ swfdec_image_jpeg2_load (SwfdecImage *im return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); - jpeg_rgb_decoder_get_image (dec, &image_data, + jpeg_rgb_decoder_get_image (dec, &image->data, &image->rowstride, &image->width, &image->height); jpeg_rgb_decoder_free (dec); - swfdec_image_create_surface (image, image_data, FALSE); SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height); @@ -303,7 +288,6 @@ static void swfdec_image_jpeg3_load (SwfdecImage *image) { JpegRGBDecoder *dec; - unsigned char *image_data; unsigned char *alpha_data; SwfdecBits bits; int len; @@ -328,7 +312,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im return; } swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height); - jpeg_rgb_decoder_get_image (dec, &image_data, + jpeg_rgb_decoder_get_image (dec, &image->data, &image->rowstride, &image->width, &image->height); jpeg_rgb_decoder_free (dec); @@ -336,11 +320,9 @@ swfdec_image_jpeg3_load (SwfdecImage *im alpha_data = lossless (bits.ptr, bits.end - bits.ptr, &len); - merge_alpha (image, image_data, alpha_data); + merge_alpha (image, image->data, alpha_data); g_free (alpha_data); - swfdec_image_create_surface (image, image_data, TRUE); - SWFDEC_LOG (" width = %d", image->width); SWFDEC_LOG (" height = %d", image->height); } @@ -355,11 +337,7 @@ merge_alpha (SwfdecImage * image, unsign for (y = 0; y < image->height; y++) { p = image_data + y * image->rowstride; for (x = 0; x < image->width; x++) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - p[3] = *alpha; -#else - p[0] = *alpha; -#endif + p[SWFDEC_COLOR_INDEX_ALPHA] = *alpha; p += 4; alpha++; } @@ -375,7 +353,6 @@ swfdec_image_lossless_load (SwfdecImage int len; unsigned char *endptr; SwfdecBits bits; - unsigned char *image_data = NULL; int have_alpha = (image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2); bits.buffer = image->raw_data; @@ -414,7 +391,7 @@ swfdec_image_lossless_load (SwfdecImage unsigned char *indexed_data; int i; - image_data = g_malloc (4 * image->width * image->height); + image->data = g_malloc (4 * image->width * image->height); image->rowstride = image->width * 4; color_table = g_malloc (color_table_size * 4); @@ -450,7 +427,7 @@ swfdec_image_lossless_load (SwfdecImage } indexed_data = ptr + color_table_size * 3; } - swfdec_image_colormap_decode (image, image_data, indexed_data, + swfdec_image_colormap_decode (image, image->data, indexed_data, color_table, color_table_size); g_free (color_table); @@ -467,25 +444,18 @@ swfdec_image_lossless_load (SwfdecImage have_alpha = FALSE; } - image_data = g_malloc (4 * image->width * image->height); - idata = image_data; + image->data = g_malloc (4 * image->width * image->height); + idata = image->data; image->rowstride = image->width * 4; /* 15 bit packed */ for (j = 0; j < image->height; j++) { for (i = 0; i < image->width; i++) { c = p[1] | (p[0] << 8); -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - idata[0] = (c << 3) | ((c >> 2) & 0x7); - idata[1] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); - idata[2] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); - idata[3] = 0xff; -#else - idata[3] = (c << 3) | ((c >> 2) & 0x7); - idata[2] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); - idata[1] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); - idata[0] = 0xff; -#endif + idata[SWFDEC_COLOR_INDEX_BLUE] = (c << 3) | ((c >> 2) & 0x7); + idata[SWFDEC_COLOR_INDEX_GREEN] = ((c >> 2) & 0xf8) | ((c >> 7) & 0x7); + idata[SWFDEC_COLOR_INDEX_RED] = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); + idata[SWFDEC_COLOR_INDEX_ALPHA] = 0xff; p += 2; idata += 4; } @@ -495,26 +465,17 @@ swfdec_image_lossless_load (SwfdecImage if (format == 5) { int i, j; - image_data = ptr; + image->data = ptr; image->rowstride = image->width * 4; - if (!have_alpha) { - /* image is stored in 0RGB format. We use ARGB/BGRA. */ - for (j = 0; j < image->height; j++) { - for (i = 0; i < image->width; i++) { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - ptr[0] = ptr[3]; - ptr[1] = ptr[2]; - ptr[2] = ptr[1]; - ptr[3] = 255; -#endif - ptr += 4; - } + /* image is stored in 0RGB format. We use ARGB/BGRA. */ + for (j = 0; j < image->height; j++) { + for (i = 0; i < image->width; i++) { + *((guint32 *) ptr) = GUINT32_FROM_BE (*((guint32 *) ptr)); + ptr += 4; } } } - - swfdec_image_create_surface (image, image_data, have_alpha); } int @@ -592,68 +553,131 @@ swfdec_image_colormap_decode (SwfdecImag } } +static gboolean +swfdec_image_ensure_loaded (SwfdecImage *image) +{ + if (image->data == NULL) { + switch (image->type) { + case SWFDEC_IMAGE_TYPE_JPEG: + swfdec_image_jpeg_load (image); + break; + case SWFDEC_IMAGE_TYPE_JPEG2: + swfdec_image_jpeg2_load (image); + break; + case SWFDEC_IMAGE_TYPE_JPEG3: + swfdec_image_jpeg3_load (image); + break; + case SWFDEC_IMAGE_TYPE_LOSSLESS: + swfdec_image_lossless_load (image); + break; + case SWFDEC_IMAGE_TYPE_LOSSLESS2: + swfdec_image_lossless_load (image); + break; + case SWFDEC_IMAGE_TYPE_UNKNOWN: + default: + g_assert_not_reached (); + break; + } + if (image->data == NULL) { + SWFDEC_WARNING ("failed to load image data"); + return FALSE; + } + } else { + swfdec_cached_use (SWFDEC_CACHED (image)); + } + return TRUE; +} + +static void +swfdec_image_premultiply (guint8 *data, guint n) +{ + guint i; + + for (i = 0; i < n; i++, data += 4) { + if (data[SWFDEC_COLOR_INDEX_ALPHA] == 0xFF) + continue; + if (data[SWFDEC_COLOR_INDEX_ALPHA] == 0) { + data[SWFDEC_COLOR_INDEX_RED] = data[SWFDEC_COLOR_INDEX_GREEN] = data[SWFDEC_COLOR_INDEX_BLUE] = 0; + } else { + data[SWFDEC_COLOR_INDEX_RED] = (guint) data[SWFDEC_COLOR_INDEX_RED] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255; + data[SWFDEC_COLOR_INDEX_GREEN] = (guint) data[SWFDEC_COLOR_INDEX_GREEN] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255; + data[SWFDEC_COLOR_INDEX_BLUE] = (guint) data[SWFDEC_COLOR_INDEX_BLUE] * data[SWFDEC_COLOR_INDEX_ALPHA] / 255; + } + } +} + +static gboolean +swfdec_image_has_alpha (SwfdecImage *image) +{ + return image->type == SWFDEC_IMAGE_TYPE_LOSSLESS2 || + image->type == SWFDEC_IMAGE_TYPE_JPEG3; +} + cairo_surface_t * -swfdec_image_get_surface (SwfdecImage *image) +swfdec_image_create_surface (SwfdecImage *image) { + static const cairo_user_data_key_t key; + g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL); + if (!swfdec_image_ensure_loaded (image)) + return NULL; if (image->surface) { - swfdec_cached_use (SWFDEC_CACHED (image)); + cairo_surface_reference (image->surface); return image->surface; } - switch (image->type) { - case SWFDEC_IMAGE_TYPE_JPEG: - swfdec_image_jpeg_load (image); - break; - case SWFDEC_IMAGE_TYPE_JPEG2: - swfdec_image_jpeg2_load (image); - break; - case SWFDEC_IMAGE_TYPE_JPEG3: - swfdec_image_jpeg3_load (image); - break; - case SWFDEC_IMAGE_TYPE_LOSSLESS: - swfdec_image_lossless_load (image); - break; - case SWFDEC_IMAGE_TYPE_LOSSLESS2: - swfdec_image_lossless_load (image); - break; - case SWFDEC_IMAGE_TYPE_UNKNOWN: - default: - g_assert_not_reached (); - break; + if (swfdec_image_has_alpha (image)) { + cairo_surface_t *surface; + guint8 *data; + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + image->width, image->height); + /* FIXME: only works if rowstride == image->width * 4 */ + data = cairo_image_surface_get_data (surface); + memcpy (data, image->data, image->width * image->height * 4); + swfdec_image_premultiply (data, image->width * image->height); + return surface; + } else { + image->surface = cairo_image_surface_create_for_data (image->data, + CAIRO_FORMAT_RGB24, image->width, image->height, image->rowstride); + cairo_surface_set_user_data (image->surface, &key, image->data, g_free); + cairo_surface_reference (image->surface); + return image->surface; } - - return image->surface; } cairo_surface_t * -swfdec_image_get_surface_for_target (SwfdecImage *image, cairo_surface_t *target) +swfdec_image_get_surface_transformed (SwfdecImage *image, const SwfdecColorTransform *trans) { - cairo_surface_t *current, *similar; - cairo_t *copy; - cairo_content_t content; - - current = swfdec_image_get_surface (image); - if (cairo_surface_get_type (current) == cairo_surface_get_type (target)) - return current; - - /* FIXME: we might want to create multiple surfaces here if there's multiple - * live rendering sources. Right now, this is the quick fix, that transforms - * the cache to the most recent used type */ - if (cairo_surface_get_type (current) == CAIRO_SURFACE_TYPE_IMAGE && - cairo_image_surface_get_format (current) == CAIRO_FORMAT_RGB24) - content = CAIRO_CONTENT_COLOR; - else - content = CAIRO_CONTENT_COLOR_ALPHA; - similar = cairo_surface_create_similar (target, - content, - image->width, image->height); - copy = cairo_create (similar); - cairo_set_source_surface (copy, current, 0, 0); - cairo_paint (copy); - cairo_destroy (copy); - cairo_surface_destroy (current); - image->surface = similar; - return similar; + static const cairo_user_data_key_t key; + cairo_surface_t *surface; + guint8 *tdata; + const guint8 *sdata; + guint i, n; + gboolean has_alpha = FALSE; + + g_return_val_if_fail (SWFDEC_IS_IMAGE (image), NULL); + g_return_val_if_fail (trans != NULL, NULL); + + if (!swfdec_image_ensure_loaded (image)) + return NULL; + + tdata = g_try_malloc (image->width * image->height * 4); + if (!tdata) { + SWFDEC_ERROR ("failed to allocate memory for transformed image"); + return NULL; + } + sdata = image->data; + n = image->width * image->height; + for (i = 0; i < n; i++) { + ((guint32 *) tdata)[i] = swfdec_color_apply_transform (((guint32 *) sdata)[i], trans); + has_alpha |= tdata[4 * i + SWFDEC_COLOR_INDEX_ALPHA] != 0xFF; + } + if (has_alpha) + swfdec_image_premultiply (tdata, n); + surface = cairo_image_surface_create_for_data (tdata, + has_alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, + image->width, image->height, image->width * 4); + cairo_surface_set_user_data (surface, &key, tdata, g_free); + return surface; } diff --git a/libswfdec/swfdec_image.h b/libswfdec/swfdec_image.h index bcd22f0..ad40181 100644 --- a/libswfdec/swfdec_image.h +++ b/libswfdec/swfdec_image.h @@ -48,10 +48,11 @@ typedef enum { struct _SwfdecImage { SwfdecCached cached; - cairo_surface_t * surface; /* surface that is on-demand loaded */ + guint8 * data; /* image data in CAIRO_FORMAT_ARGB32 but NOT premultiplied */ int width; int height; int rowstride; + cairo_surface_t * surface; /* surface that owns the data pointer or NULL (doesn't always work) */ SwfdecImageType type; SwfdecBuffer * jpegtables; @@ -66,9 +67,9 @@ struct _SwfdecImageClass { GType swfdec_image_get_type (void); cairo_surface_t * swfdec_image_get_surface (SwfdecImage * image); -cairo_surface_t * swfdec_image_get_surface_for_target +cairo_surface_t * swfdec_image_get_surface_transformed (SwfdecImage * image, - cairo_surface_t * target); + const SwfdecColorTransform *trans); int swfdec_image_jpegtables (SwfdecSwfDecoder * s); int tag_func_define_bits_jpeg (SwfdecSwfDecoder * s); diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index 2a614b0..938f827 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -263,14 +263,11 @@ swfdec_image_pattern_paint (SwfdecPatter { SwfdecImagePattern *image = SWFDEC_IMAGE_PATTERN (pat); cairo_pattern_t *pattern; - SwfdecColor color; cairo_matrix_t mat; cairo_surface_t *surface; - surface = swfdec_image_get_surface_for_target (image->image, - cairo_get_target (cr)); + surface = swfdec_image_get_surface_transformed (image->image, trans); cairo_append_path (cr, (cairo_path_t *) path); - color = swfdec_color_apply_transform (0xFFFFFFFF, trans); pattern = cairo_pattern_create_for_surface (surface); swfdec_matrix_morph (&mat, &pat->start_transform, &pat->end_transform, ratio); cairo_pattern_set_matrix (pattern, &mat); @@ -278,14 +275,7 @@ swfdec_image_pattern_paint (SwfdecPatter cairo_pattern_set_filter (pattern, image->filter); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); - if (SWFDEC_COLOR_A (color) < 255) { - cairo_save (cr); - cairo_clip (cr); - cairo_paint_with_alpha (cr, SWFDEC_COLOR_A (color) / 255.); - cairo_restore (cr); - } else { - cairo_fill (cr); - } + cairo_fill (cr); } static void diff-tree fa335acfbd3526f57dfb66c68e59334a79d90901 (from 251f13c696e0c8c8eb10534d0ed9407d7fd26d19) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 14:29:48 2007 +0100 update SwfdecColor format from RGBA to ARGB This makes SwfdecColor match a pixel in an image in CAIRO_FORMAT_ARGB32 diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h index 07870c3..b38c269 100644 --- a/libswfdec/swfdec_color.h +++ b/libswfdec/swfdec_color.h @@ -1,7 +1,7 @@ /* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> - * 2006 Benjamin Otte <otte@gnome.org> + * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,8 @@ #include <libswfdec/swfdec_types.h> +/* Pixel value in the same colorspace as cairo - endian-dependant ARGB. + * The alpha pixel must be present */ typedef unsigned int SwfdecColor; struct _SwfdecColorTransform { @@ -46,11 +48,25 @@ struct swfdec_gradient_struct SwfdecGradientEntry array[1]; }; -#define SWFDEC_COLOR_COMBINE(r,g,b,a) (((r)<<24) | ((g)<<16) | ((b)<<8) | (a)) -#define SWFDEC_COLOR_R(x) (((x)>>24)&0xff) -#define SWFDEC_COLOR_G(x) (((x)>>16)&0xff) -#define SWFDEC_COLOR_B(x) (((x)>>8)&0xff) -#define SWFDEC_COLOR_A(x) ((x)&0xff) +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define SWFDEC_COLOR_INDEX_ALPHA (3) +#define SWFDEC_COLOR_INDEX_RED (2) +#define SWFDEC_COLOR_INDEX_GREEN (1) +#define SWFDEC_COLOR_INDEX_BLUE (0) +#elif G_BYTE_ORDER == G_BIG_ENDIAN +#define SWFDEC_COLOR_INDEX_ALPHA (0) +#define SWFDEC_COLOR_INDEX_RED (1) +#define SWFDEC_COLOR_INDEX_GREEN (2) +#define SWFDEC_COLOR_INDEX_BLUE (3) +#else +#error "Unknown byte order" +#endif + +#define SWFDEC_COLOR_COMBINE(r,g,b,a) (((a)<<24) | ((r)<<16) | ((g)<<8) | (b)) +#define SWFDEC_COLOR_A(x) (((x)>>24)&0xff) +#define SWFDEC_COLOR_R(x) (((x)>>16)&0xff) +#define SWFDEC_COLOR_G(x) (((x)>>8)&0xff) +#define SWFDEC_COLOR_B(x) ((x)&0xff) SwfdecColor swfdec_color_apply_morph (SwfdecColor start, SwfdecColor end, unsigned int ratio); void swfdec_color_set_source (cairo_t *cr, SwfdecColor color); diff-tree 251f13c696e0c8c8eb10534d0ed9407d7fd26d19 (from 12bf86eb10e873ca735fad310d7ab9e517f6662b) Author: Benjamin Otte <otte@gnome.org> Date: Sun Feb 4 13:07:18 2007 +0100 s/SWF_COLOR/SWFDEC_COLOR/ fight wrong prefixes! diff --git a/libswfdec/swfdec_bits.c b/libswfdec/swfdec_bits.c index fb18394..5013e49 100644 --- a/libswfdec/swfdec_bits.c +++ b/libswfdec/swfdec_bits.c @@ -450,7 +450,7 @@ swfdec_bits_get_color (SwfdecBits * bits g = swfdec_bits_get_u8 (bits); b = swfdec_bits_get_u8 (bits); - return SWF_COLOR_COMBINE (r, g, b, 0xff); + return SWFDEC_COLOR_COMBINE (r, g, b, 0xff); } unsigned int @@ -463,7 +463,7 @@ swfdec_bits_get_rgba (SwfdecBits * bits) b = swfdec_bits_get_u8 (bits); a = swfdec_bits_get_u8 (bits); - return SWF_COLOR_COMBINE (r, g, b, a); + return SWFDEC_COLOR_COMBINE (r, g, b, a); } SwfdecGradient * diff --git a/libswfdec/swfdec_color.c b/libswfdec/swfdec_color.c index 0d8a8be..7761653 100644 --- a/libswfdec/swfdec_color.c +++ b/libswfdec/swfdec_color.c @@ -40,20 +40,20 @@ swfdec_color_apply_morph (SwfdecColor st return end; start_ratio = 65535 - ratio; end_ratio = ratio; - r = (SWF_COLOR_R (start) * start_ratio + SWF_COLOR_R (end) * end_ratio) / 65535; - g = (SWF_COLOR_G (start) * start_ratio + SWF_COLOR_G (end) * end_ratio) / 65535; - b = (SWF_COLOR_B (start) * start_ratio + SWF_COLOR_B (end) * end_ratio) / 65535; - a = (SWF_COLOR_A (start) * start_ratio + SWF_COLOR_A (end) * end_ratio) / 65535; + r = (SWFDEC_COLOR_R (start) * start_ratio + SWFDEC_COLOR_R (end) * end_ratio) / 65535; + g = (SWFDEC_COLOR_G (start) * start_ratio + SWFDEC_COLOR_G (end) * end_ratio) / 65535; + b = (SWFDEC_COLOR_B (start) * start_ratio + SWFDEC_COLOR_B (end) * end_ratio) / 65535; + a = (SWFDEC_COLOR_A (start) * start_ratio + SWFDEC_COLOR_A (end) * end_ratio) / 65535; - return SWF_COLOR_COMBINE (r, g, b, a); + return SWFDEC_COLOR_COMBINE (r, g, b, a); } void swfdec_color_set_source (cairo_t *cr, SwfdecColor color) { cairo_set_source_rgba (cr, - SWF_COLOR_R (color) / 255.0, SWF_COLOR_G (color) / 255.0, - SWF_COLOR_B (color) / 255.0, SWF_COLOR_A (color) / 255.0); + SWFDEC_COLOR_R (color) / 255.0, SWFDEC_COLOR_G (color) / 255.0, + SWFDEC_COLOR_B (color) / 255.0, SWFDEC_COLOR_A (color) / 255.0); } unsigned int @@ -61,10 +61,10 @@ swfdec_color_apply_transform (unsigned i { int r, g, b, a; - r = SWF_COLOR_R (in); - g = SWF_COLOR_G (in); - b = SWF_COLOR_B (in); - a = SWF_COLOR_A (in); + r = SWFDEC_COLOR_R (in); + g = SWFDEC_COLOR_G (in); + b = SWFDEC_COLOR_B (in); + a = SWFDEC_COLOR_A (in); SWFDEC_LOG ("in rgba %d,%d,%d,%d", r, g, b, a); @@ -80,7 +80,7 @@ swfdec_color_apply_transform (unsigned i SWFDEC_LOG ("out rgba %d,%d,%d,%d", r, g, b, a); - return SWF_COLOR_COMBINE (r, g, b, a); + return SWFDEC_COLOR_COMBINE (r, g, b, a); } /** @@ -116,13 +116,13 @@ void swfdec_color_transform_init_color (SwfdecColorTransform *trans, SwfdecColor color) { trans->ra = 0; - trans->rb = SWF_COLOR_R (color); + trans->rb = SWFDEC_COLOR_R (color); trans->ga = 0; - trans->gb = SWF_COLOR_G (color); + trans->gb = SWFDEC_COLOR_G (color); trans->ba = 0; - trans->bb = SWF_COLOR_B (color); + trans->bb = SWFDEC_COLOR_B (color); trans->aa = 0; - trans->ab = SWF_COLOR_A (color); + trans->ab = SWFDEC_COLOR_A (color); } /** diff --git a/libswfdec/swfdec_color.h b/libswfdec/swfdec_color.h index 39e48fe..07870c3 100644 --- a/libswfdec/swfdec_color.h +++ b/libswfdec/swfdec_color.h @@ -46,11 +46,11 @@ struct swfdec_gradient_struct SwfdecGradientEntry array[1]; }; -#define SWF_COLOR_COMBINE(r,g,b,a) (((r)<<24) | ((g)<<16) | ((b)<<8) | (a)) -#define SWF_COLOR_R(x) (((x)>>24)&0xff) -#define SWF_COLOR_G(x) (((x)>>16)&0xff) -#define SWF_COLOR_B(x) (((x)>>8)&0xff) -#define SWF_COLOR_A(x) ((x)&0xff) +#define SWFDEC_COLOR_COMBINE(r,g,b,a) (((r)<<24) | ((g)<<16) | ((b)<<8) | (a)) +#define SWFDEC_COLOR_R(x) (((x)>>24)&0xff) +#define SWFDEC_COLOR_G(x) (((x)>>16)&0xff) +#define SWFDEC_COLOR_B(x) (((x)>>8)&0xff) +#define SWFDEC_COLOR_A(x) ((x)&0xff) SwfdecColor swfdec_color_apply_morph (SwfdecColor start, SwfdecColor end, unsigned int ratio); void swfdec_color_set_source (cairo_t *cr, SwfdecColor color); diff --git a/libswfdec/swfdec_edittext.c b/libswfdec/swfdec_edittext.c index d38b33a..37727eb 100644 --- a/libswfdec/swfdec_edittext.c +++ b/libswfdec/swfdec_edittext.c @@ -148,7 +148,7 @@ tag_func_define_edit_text (SwfdecSwfDeco SWFDEC_LOG (" color = %u", text->color); } else { SWFDEC_WARNING ("FIXME: figure out default color"); - text->color = SWF_COLOR_COMBINE (255, 255, 255, 255); + text->color = SWFDEC_COLOR_COMBINE (255, 255, 255, 255); } if (has_max_length) { text->max_length = swfdec_bits_get_u16 (b); diff --git a/libswfdec/swfdec_pattern.c b/libswfdec/swfdec_pattern.c index f8902ef..2a614b0 100644 --- a/libswfdec/swfdec_pattern.c +++ b/libswfdec/swfdec_pattern.c @@ -278,10 +278,10 @@ swfdec_image_pattern_paint (SwfdecPatter cairo_pattern_set_filter (pattern, image->filter); cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); - if (SWF_COLOR_A (color) < 255) { + if (SWFDEC_COLOR_A (color) < 255) { cairo_save (cr); cairo_clip (cr); - cairo_paint_with_alpha (cr, SWF_COLOR_A (color) / 255.); + cairo_paint_with_alpha (cr, SWFDEC_COLOR_A (color) / 255.); cairo_restore (cr); } else { cairo_fill (cr); @@ -368,8 +368,8 @@ swfdec_gradient_pattern_paint (SwfdecPat gradient->gradient->array[i + 1].ratio * ratio; offset /= 65535 * 255; cairo_pattern_add_color_stop_rgba (pattern, offset, - SWF_COLOR_R(color) / 255.0, SWF_COLOR_G(color) / 255.0, - SWF_COLOR_B(color) / 255.0, SWF_COLOR_A(color) / 255.0); + SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0, + SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0); } } else { for (i = 0; i < gradient->gradient->n_gradients; i++){ @@ -377,8 +377,8 @@ swfdec_gradient_pattern_paint (SwfdecPat trans); offset = gradient->gradient->array[i].ratio / 255.0; cairo_pattern_add_color_stop_rgba (pattern, offset, - SWF_COLOR_R(color) / 255.0, SWF_COLOR_G(color) / 255.0, - SWF_COLOR_B(color) / 255.0, SWF_COLOR_A(color) / 255.0); + SWFDEC_COLOR_R(color) / 255.0, SWFDEC_COLOR_G(color) / 255.0, + SWFDEC_COLOR_B(color) / 255.0, SWFDEC_COLOR_A(color) / 255.0); } } cairo_set_source (cr, pattern); @@ -460,7 +460,7 @@ swfdec_pattern_parse (SwfdecSwfDecoder * if (paint_id == 65535) { /* FIXME: someone explain this magic paint id here */ pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL); - SWFDEC_COLOR_PATTERN (pattern)->start_color = SWF_COLOR_COMBINE (0, 255, 255, 255); + SWFDEC_COLOR_PATTERN (pattern)->start_color = SWFDEC_COLOR_COMBINE (0, 255, 255, 255); SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color; swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL); pattern->end_transform = pattern->start_transform; @@ -540,7 +540,7 @@ swfdec_pattern_parse_morph (SwfdecSwfDec if (paint_id == 65535) { /* FIXME: someone explain this magic paint id here */ pattern = g_object_new (SWFDEC_TYPE_COLOR_PATTERN, NULL); - SWFDEC_COLOR_PATTERN (pattern)->start_color = SWF_COLOR_COMBINE (0, 255, 255, 255); + SWFDEC_COLOR_PATTERN (pattern)->start_color = SWFDEC_COLOR_COMBINE (0, 255, 255, 255); SWFDEC_COLOR_PATTERN (pattern)->end_color = SWFDEC_COLOR_PATTERN (pattern)->start_color; swfdec_bits_get_matrix (bits, &pattern->start_transform, NULL); swfdec_bits_get_matrix (bits, &pattern->end_transform, NULL); diff --git a/libswfdec/swfdec_sprite.c b/libswfdec/swfdec_sprite.c index 9201218..074bb37 100644 --- a/libswfdec/swfdec_sprite.c +++ b/libswfdec/swfdec_sprite.c @@ -503,7 +503,7 @@ swfdec_sprite_set_n_frames (SwfdecSprite sprite->frames[i].sound_samples = 44100 * 256 / rate; } /* default bg is white */ - sprite->frames[0].bg_color = SWF_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF); + sprite->frames[0].bg_color = SWFDEC_COLOR_COMBINE (0xFF, 0xFF, 0xFF, 0xFF); SWFDEC_LOG ("n_frames = %d", sprite->n_frames); }
Apparently Analagous Threads
- 109 commits - configure.ac libswfdec/js libswfdec/Makefile.am libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_buffer.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_codec_screen.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h
- 9 commits - libswfdec/js libswfdec/swfdec_bits.c libswfdec/swfdec_bits.h libswfdec/swfdec_codec_screen.c libswfdec/swfdec_image.c libswfdec/swfdec_script.c test/Makefile.am test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_file.c
- 21 commits - configure.ac libswfdec/swfdec_audio_event.c libswfdec/swfdec_bits.c libswfdec/swfdec_button_movie.c libswfdec/swfdec_color.c libswfdec/swfdec_color.h libswfdec/swfdec_compiler.c libswfdec/swfdec_edittext.c libswfdec/swfdec_image.c
- 7 commits - libswfdec/swfdec_image.c libswfdec/swfdec_script.c libswfdec/swfdec_script.h test/Makefile.am test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_list.c test/swfedit_tag.c test/swfedit_token.c test/swfedit_token.h test/swfscript.c
- 12 commits - configure.ac doc/swfdec.types Makefile.am test/crashfinder.c test/dump.c test/Makefile.am test/swfdec-extract.c test/swfdec_out.c test/swfdec_out.h test/swfedit.c test/swfedit_file.c test/swfedit_file.h test/swfedit_list.c test/swfedit_list.h