[Swfdec] libswfdec/jpeg libswfdec/swfdec_image.c
David Schleef
ds at kemper.freedesktop.org
Tue Apr 17 13:21:15 PDT 2007
libswfdec/jpeg/jpeg.c | 1
libswfdec/swfdec_image.c | 109 ++++++++++++++++++++++++++++++++++-------------
2 files changed, 79 insertions(+), 31 deletions(-)
New commits:
diff-tree 27f1a42be2f4852795a514b6b64681013ae29cfe (from 19631e716804aede3bd480fd7c99c7342185fdeb)
Author: Debian User <ds at gromit.(none)>
Date: Tue Apr 17 13:21:12 2007 -0700
Fix the spurious SOI and EOI markers by copying JPEG data into a
temporary buffer and make sure it has the correct markers.
diff --git a/libswfdec/jpeg/jpeg.c b/libswfdec/jpeg/jpeg.c
index 448db4b..0c648c2 100644
--- a/libswfdec/jpeg/jpeg.c
+++ b/libswfdec/jpeg/jpeg.c
@@ -532,7 +532,6 @@ jpeg_decoder_error(JpegDecoder *dec, cha
va_end (varargs);
SWFDEC_ERROR("decoder error: %s", dec->error_message);
- abort();
dec->error = TRUE;
}
diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c
index 3ca16b1..daabe0e 100644
--- a/libswfdec/swfdec_image.c
+++ b/libswfdec/swfdec_image.c
@@ -127,42 +127,87 @@ tag_func_define_bits_jpeg (SwfdecSwfDeco
return SWFDEC_STATUS_OK;
}
+/**
+ * swfdec_jpeg_decode_argb:
+ *
+ * This is a wrapper around jpeg_decode_argb() that takes two segments,
+ * strips off (sometimes bogus) start-of-image and end-of-image codes,
+ * concatenates them, and puts new SOI and EOI codes on the resulting
+ * buffer. This makes a real JPEG image out of the crap in SWF files.
+ */
+static gboolean
+swfdec_jpeg_decode_argb (unsigned char *data1, int length1,
+ unsigned char *data2, int length2,
+ void *outdata, int *width, int *height)
+{
+ unsigned char *tmpdata;
+ int tmplength;
+ gboolean ret;
+
+ while (length1 >= 2 && data1[0] == 0xff &&
+ (data1[1] == 0xd9 || data1[1] == 0xd8)) {
+ data1 += 2;
+ length1 -= 2;
+ }
+ while (length1 >= 2 && data1[length1-2] == 0xff &&
+ (data1[length1-1] == 0xd9 || data1[length1-1] == 0xd8)) {
+ length1 -= 2;
+ }
+
+ if (data2) {
+ while (length2 >= 2 && data2[0] == 0xff &&
+ (data2[1] == 0xd9 || data2[1] == 0xd8)) {
+ data2 += 2;
+ length2 -= 2;
+ }
+ while (length2 >= 2 && data2[length2-2] == 0xff &&
+ (data2[length2-1] == 0xd9 || data2[length2-1] == 0xd8)) {
+ length2 -= 2;
+ }
+ } else {
+ length2 = 0;
+ }
+
+ tmplength = length1 + length2 + 4;
+ tmpdata = g_malloc (tmplength);
+
+ tmpdata[0] = 0xff;
+ tmpdata[1] = 0xd8;
+ memcpy (tmpdata + 2, data1, length1);
+ memcpy (tmpdata + 2 + length1, data2, length2);
+ tmpdata[2 + length1 + length2] = 0xff;
+ tmpdata[2 + length1 + length2 + 1] = 0xd9;
+
+ ret = jpeg_decode_argb (tmpdata, tmplength, outdata, width, height);
+
+ g_free(tmpdata);
+
+ return ret;
+}
+
static void
swfdec_image_jpeg_load (SwfdecImage *image)
{
- JpegDecoder *dec;
-
- dec = jpeg_decoder_new ();
+ gboolean ret;
if (image->jpegtables) {
- if (image->jpegtables->data[0] != 0xff || image->jpegtables->data[1] != 0xd8) {
- SWFDEC_ERROR("not jpeg %02x %02x",
- image->jpegtables->data[0], image->jpegtables->data[1]);
- jpeg_decoder_free (dec);
- return;
- }
- jpeg_decoder_addbits (dec, image->jpegtables->data,
- image->jpegtables->length);
- }
- if (image->raw_data->data[0] != 0xff || image->raw_data->data[1] != 0xd8) {
- SWFDEC_ERROR("not jpeg %02x %02x",
- image->raw_data->data[0], image->raw_data->data[1]);
- jpeg_decoder_free (dec);
- return;
+ ret = swfdec_jpeg_decode_argb (
+ image->jpegtables->data, image->jpegtables->length,
+ image->raw_data->data, image->raw_data->length,
+ (void *)&image->data, &image->width, &image->height);
+ } else {
+ ret = swfdec_jpeg_decode_argb (
+ image->raw_data->data, image->raw_data->length,
+ NULL, 0,
+ (void *)&image->data, &image->width, &image->height);
}
- jpeg_decoder_addbits (dec, image->raw_data->data,
- image->raw_data->length);
- jpeg_decoder_decode (dec);
- jpeg_decoder_get_image_size (dec, &image->width, &image->height);
- if (image->width == 0 || image->height == 0) {
- jpeg_decoder_free (dec);
+
+ if (!ret) {
return;
}
swfdec_cached_load (SWFDEC_CACHED (image), 4 * image->width * image->height);
- image->data = jpeg_decoder_get_argb_image (dec);
image->rowstride = image->width * 4;
- jpeg_decoder_free (dec);
SWFDEC_LOG (" width = %d", image->width);
SWFDEC_LOG (" height = %d", image->height);
@@ -191,10 +236,12 @@ tag_func_define_bits_jpeg_2 (SwfdecSwfDe
static void
swfdec_image_jpeg2_load (SwfdecImage *image)
{
- jpeg_decode_argb (image->raw_data->data, image->raw_data->length,
- (void *)&image->data, &image->width, &image->height);
+ gboolean ret;
- if (image->data == NULL) {
+ ret = swfdec_jpeg_decode_argb (image->raw_data->data, image->raw_data->length,
+ NULL, 0,
+ (void *)&image->data, &image->width, &image->height);
+ if (!ret) {
return;
}
@@ -231,6 +278,7 @@ swfdec_image_jpeg3_load (SwfdecImage *im
SwfdecBits bits;
SwfdecBuffer *buffer;
int jpeg_length;
+ gboolean ret;
swfdec_bits_init (&bits, image->raw_data);
@@ -239,11 +287,12 @@ swfdec_image_jpeg3_load (SwfdecImage *im
if (buffer == NULL)
return;
- jpeg_decode_argb (buffer->data, buffer->length,
+ ret = swfdec_jpeg_decode_argb (buffer->data, buffer->length,
+ NULL, 0,
(void *)&image->data, &image->width, &image->height);
swfdec_buffer_unref (buffer);
- if (image->data == NULL) {
+ if (!ret) {
return;
}
More information about the Swfdec
mailing list