[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