+/* jpeg_source_mgr functions */
+static void tag_init_source(struct jpeg_decompress_struct *cinfo)
+{
+ TAG*tag = (TAG*)cinfo->client_data;
+ swf_SetTagPos(tag, 2);
+ cinfo->src->bytes_in_buffer = 0;
+}
+static boolean tag_fill_input_buffer(struct jpeg_decompress_struct *cinfo)
+{
+ TAG*tag = (TAG*)cinfo->client_data;
+ if(tag->data[tag->pos+0] == 0xff &&
+ tag->data[tag->pos+1] == 0xd9 &&
+ tag->data[tag->pos+2] == 0xff &&
+ tag->data[tag->pos+3] == 0xd8) {
+ tag->pos += 4;
+ }
+ if(tag->pos >= tag->len) {
+ cinfo->src->next_input_byte = 0;
+ cinfo->src->bytes_in_buffer = 0;
+ return 0;
+ }
+ cinfo->src->next_input_byte = &tag->data[tag->pos];
+ cinfo->src->bytes_in_buffer = 1;//tag->len - tag->pos;
+ tag->pos += 1;
+ return 1;
+}
+static void tag_skip_input_data(struct jpeg_decompress_struct *cinfo, long count)
+{
+ TAG*tag = (TAG*)cinfo->client_data;
+ cinfo->src->next_input_byte = 0;
+ cinfo->src->bytes_in_buffer = 0;
+ tag->pos += count;
+}
+static boolean tag_resync_to_restart(struct jpeg_decompress_struct *cinfo, int desired)
+{
+ return jpeg_resync_to_restart(cinfo, desired);
+}
+static void tag_term_source(struct jpeg_decompress_struct *cinfo)
+{
+ TAG*tag = (TAG*)cinfo->client_data;
+}
+RGBA* swf_JPEG2TagToImage(TAG*tag, int*width, int*height)
+{
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ struct jpeg_source_mgr mgr;
+ RGBA * dest;
+ int y;
+ *width = 0;
+ *height = 0;
+
+ if(tag->id == ST_DEFINEBITSJPEG) {
+ fprintf(stderr, "rfxswf: extracting from definebitsjpeg not yet supported");
+ return 0;
+ }
+ if(tag->id == ST_DEFINEBITSJPEG3) {
+ fprintf(stderr, "rfxswf: extracting from definebitsjpeg3 not yet supported");
+ return 0;
+ }
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+
+ cinfo.client_data = (void*)tag;
+ cinfo.src = &mgr;
+ cinfo.src->init_source = tag_init_source;
+ cinfo.src->fill_input_buffer = tag_fill_input_buffer;
+ cinfo.src->skip_input_data = tag_skip_input_data;
+ cinfo.src->resync_to_restart = jpeg_resync_to_restart;
+ cinfo.src->term_source = tag_term_source;
+ cinfo.out_color_space = JCS_RGB;
+
+ jpeg_read_header(&cinfo, TRUE);
+ *width = cinfo.image_width;
+ *height = cinfo.image_height;
+ dest = rfx_alloc(sizeof(RGBA)*cinfo.image_width*cinfo.image_height);
+
+ jpeg_start_decompress(&cinfo);
+ for (y=0;y<cinfo.output_height;y++) {
+ RGBA* line = &dest[y*cinfo.image_width];
+ U8* to = (U8*)line;
+ int x;
+ jpeg_read_scanlines(&cinfo,&to,1);
+ for(x=cinfo.output_width-1;x>=0;--x) {
+ int r = to[x*3+0];
+ int g = to[x*3+1];
+ int b = to[x*3+2];
+ line[x].r = r;
+ line[x].g = g;
+ line[x].b = b;
+ line[x].a = 255;
+ }
+ }
+
+ jpeg_finish_decompress(&cinfo);
+
+ jpeg_destroy_decompress(&cinfo);
+ return dest;
+}
+
+
+#endif // HAVE_JPEGLIB