added jpeg3 extraction support to swfextract
authorMatthias Kramm <kramm@quiss.org>
Mon, 17 May 2010 01:10:34 +0000 (18:10 -0700)
committerMatthias Kramm <kramm@quiss.org>
Mon, 17 May 2010 01:10:34 +0000 (18:10 -0700)
lib/devices/record.c
lib/jpeg.c
lib/jpeg.h
lib/modules/swfbits.c
src/swfextract.c

index 3485840..a09cbbc 100644 (file)
@@ -781,7 +781,6 @@ static void replay(struct _gfxdevice*dev, gfxdevice_t*out, reader_t*r, gfxfontli
                msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name);
                gfxfont_t*font = readFont(r, &state);
                if(!gfxfontlist_hasfont(*fontlist, font)) {
                msg("<trace> replay: ADDFONT out=%08x(%s)", out, out->name);
                gfxfont_t*font = readFont(r, &state);
                if(!gfxfontlist_hasfont(*fontlist, font)) {
-                   printf("%08x / %08x: font %s is new\n", out, *fontlist, font->id);
                    *fontlist = gfxfontlist_addfont(*fontlist, font);
                    out->addfont(out, font);
                } else {
                    *fontlist = gfxfontlist_addfont(*fontlist, font);
                    out->addfont(out, font);
                } else {
index 1c5e91c..21cc0f7 100644 (file)
@@ -288,12 +288,11 @@ void mem_term_source (j_decompress_ptr cinfo)
     //printf("term %d\n", size - mgr->bytes_in_buffer);
 }
 
     //printf("term %d\n", size - mgr->bytes_in_buffer);
 }
 
-int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char*dest, int width, int height)
+int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char**dest, int*width, int*height)
 {
     struct jpeg_decompress_struct cinfo;
     struct jpeg_error_mgr jerr;
     struct jpeg_source_mgr mgr;
 {
     struct jpeg_decompress_struct cinfo;
     struct jpeg_error_mgr jerr;
     struct jpeg_source_mgr mgr;
-    int y,x;
 
     data = _data;
     size = _size;
 
     data = _data;
     size = _size;
@@ -312,12 +311,27 @@ int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char*dest, int w
     cinfo.src = &mgr;
 
     jpeg_read_header(&cinfo, TRUE);
     cinfo.src = &mgr;
 
     jpeg_read_header(&cinfo, TRUE);
+    cinfo.out_color_space == JCS_RGB;
     jpeg_start_decompress(&cinfo);
     jpeg_start_decompress(&cinfo);
+  
+    *width = cinfo.output_width;
+    *height = cinfo.output_height;
+    *dest = malloc(cinfo.output_width * cinfo.output_height * 4); 
 
 
-    for(y=0;y<height;y++) {
-       unsigned char*j = &dest[width*y*3];
-       jpeg_read_scanlines(&cinfo,&j,1);
+    unsigned char*scanline = malloc(cinfo.output_width * 4);
+    int y;
+    for(y=0;y<cinfo.output_height;y++) {
+       unsigned char*to = &(*dest)[cinfo.output_width*y*4];
+       jpeg_read_scanlines(&cinfo,&scanline,1);
+       int x;
+       for(x=0;x<cinfo.output_width;x++) {
+           to[x*4 + 0] = 255;
+           to[x*4 + 1] = scanline[x*3 + 0];
+           to[x*4 + 2] = scanline[x*3 + 1];
+           to[x*4 + 3] = scanline[x*3 + 2];
+       }
     }
     }
+    free(scanline);
 
     jpeg_finish_decompress(&cinfo);
     jpeg_destroy_decompress(&cinfo);
 
     jpeg_finish_decompress(&cinfo);
     jpeg_destroy_decompress(&cinfo);
index ef4f4d2..90f9fea 100644 (file)
@@ -12,7 +12,7 @@ int jpeg_save_gray(unsigned char*data, int width, int height, int quality, const
 int jpeg_save_to_file(unsigned char*data, int width, int height, int quality, FILE*fi);
 int jpeg_save_to_mem(unsigned char*data, int width, int height, int quality, unsigned char*dest, int destsize);
 int jpeg_load(const char*filename, unsigned char**dest, int*width, int*height);
 int jpeg_save_to_file(unsigned char*data, int width, int height, int quality, FILE*fi);
 int jpeg_save_to_mem(unsigned char*data, int width, int height, int quality, unsigned char*dest, int destsize);
 int jpeg_load(const char*filename, unsigned char**dest, int*width, int*height);
-int jpeg_load_from_mem(unsigned char*_data, int size, unsigned char*dest, int width, int height);
+int jpeg_load_from_mem(unsigned char*_data, int _size, unsigned char**dest, int*width, int*height);
 void jpeg_get_size(const char *fname, int *width, int *height);
 
 #ifdef __cplusplus
 void jpeg_get_size(const char *fname, int *width, int *height);
 
 #ifdef __cplusplus
index c2dcf25..84a3b50 100644 (file)
@@ -1152,6 +1152,7 @@ int swf_SetJPEGBits3(TAG * tag, U16 width, U16 height, RGBA * bitmap, int qualit
 #endif
 
 
 #endif
 
 
+#define NO_LOSSLESS
 /* expects mem to be non-premultiplied */
 TAG* swf_AddImage(TAG*tag, int bitid, RGBA*mem, int width, int height, int quality)
 {
 /* expects mem to be non-premultiplied */
 TAG* swf_AddImage(TAG*tag, int bitid, RGBA*mem, int width, int height, int quality)
 {
index a162e45..47bcbe7 100644 (file)
@@ -25,6 +25,8 @@
 #include "../lib/rfxswf.h"
 #include "../lib/args.h"
 #include "../lib/log.h"
 #include "../lib/rfxswf.h"
 #include "../lib/args.h"
 #include "../lib/log.h"
+#include "../lib/jpeg.h"
+#include "../lib/png.h"
 #ifdef HAVE_ZLIB_H
 #ifdef HAVE_LIBZ
 #include "zlib.h"
 #ifdef HAVE_ZLIB_H
 #ifdef HAVE_LIBZ
 #include "zlib.h"
@@ -682,13 +684,23 @@ int handlejpeg(TAG*tag)
     char name[80];
     char*filename = name;
     FILE*fi;
     char name[80];
     char*filename = name;
     FILE*fi;
-    
-    prepare_name(name, sizeof(name), "pic", "jpg", GET16(tag->data));
-    if(numextracts==1) {
-       filename = destfilename;
-       if(!strcmp(filename,"output.swf"))
-           filename = "output.jpg";
+   
+    if(tag->id != ST_DEFINEBITSJPEG3) {
+       prepare_name(name, sizeof(name), "pic", "jpg", GET16(tag->data));
+       if(numextracts==1) {
+           filename = destfilename;
+           if(!strcmp(filename,"output.swf"))
+               filename = "output.jpg";
+       }
+    } else {
+       prepare_name(name, sizeof(name), "pic", "png", GET16(tag->data));
+       if(numextracts==1) {
+           filename = destfilename;
+           if(!strcmp(filename,"output.swf"))
+               filename = "output.png";
+       }
     }
     }
+
     /* swf jpeg images have two streams, which both start with ff d8 and
        end with ff d9. The following code handles sorting the middle
        <ff d9 ff d8> bytes out, so that one stream remains */
     /* swf jpeg images have two streams, which both start with ff d8 and
        end with ff d9. The following code handles sorting the middle
        <ff d9 ff d8> bytes out, so that one stream remains */
@@ -719,18 +731,34 @@ int handlejpeg(TAG*tag)
     }
     else if(tag->id == ST_DEFINEBITSJPEG3 && tag->len>6) {
        U32 end = GET32(&tag->data[2])+6;
     }
     else if(tag->id == ST_DEFINEBITSJPEG3 && tag->len>6) {
        U32 end = GET32(&tag->data[2])+6;
-       int pos = findjpegboundary(&tag->data[6], tag->len-6);
-       if(pos<0) {
-            fi = save_fopen(filename, "wb");
-            fwrite(&tag->data[6], end-6, 1, fi);
-            fclose(fi);
-        } else {
-            pos+=6;
-            fi = save_fopen(filename, "wb");
-            fwrite(&tag->data[6], pos-6, 1, fi);
-            fwrite(&tag->data[pos+4], end-(pos+4), 1, fi);
-            fclose(fi);
-        }
+       int pos = findjpegboundary(&tag->data[6], end);
+       if(end >= tag->len) {
+           msg("<error> zlib data out of bounds in definebitsjpeg3");
+           return 0;
+       }
+        if(pos) {
+           /* TODO: do we actually need this? */
+           memmove(&tag->data[pos], &tag->data[pos+4], end-(pos+4));
+       }
+       unsigned char*image;
+       int width=0, height=0;
+       jpeg_load_from_mem(&tag->data[6], end-6, &image, &width, &height);
+
+       uLongf datalen = width*height;
+       Bytef *data = malloc(datalen);
+
+       int error = uncompress(data, &datalen, &tag->data[end], (uLong)(tag->len - end));
+       if(error != Z_OK) {
+         fprintf(stderr, "Zlib error %d\n", error);
+         return 0;
+       }
+       int t, size = width*height;
+       for(t=0;t<size;t++) {
+           image[t*4+0] = data[t];
+       }
+       free(data);
+       writePNG(filename, image, width, height);
+       free(image);
     }
     else {
        int id = GET16(tag->data);
     }
     else {
        int id = GET16(tag->data);