David Schleef
2007-Apr-17 13:12 UTC
[Swfdec] 8 commits - configure.ac doc/Makefile.am libswfdec/jpeg libswfdec/swfdec_debug.h libswfdec/swfdec_image.c
configure.ac | 20 doc/Makefile.am | 2 libswfdec/jpeg/Makefile.am | 28 libswfdec/jpeg/bits.h | 120 --- libswfdec/jpeg/jpeg.c | 1129 +++++++++++++++++++++---------------- libswfdec/jpeg/jpeg.h | 58 + libswfdec/jpeg/jpeg_bits.c | 154 +++++ libswfdec/jpeg/jpeg_bits.h | 32 + libswfdec/jpeg/jpeg_huffman.c | 76 -- libswfdec/jpeg/jpeg_huffman.h | 12 libswfdec/jpeg/jpeg_internal.h | 66 +- libswfdec/jpeg/jpeg_markers.h | 44 + libswfdec/jpeg/jpeg_rgb_decoder.c | 27 libswfdec/jpeg/jpeg_rgb_decoder.h | 18 libswfdec/jpeg/jpeg_rgb_internal.h | 36 + libswfdec/jpeg/jpeg_tables.c | 54 + libswfdec/jpeg/test.c | 109 --- libswfdec/jpeg/test_rgb.c | 129 ---- libswfdec/swfdec_debug.h | 2 libswfdec/swfdec_image.c | 45 - 20 files changed, 1165 insertions(+), 996 deletions(-) New commits: diff-tree 19631e716804aede3bd480fd7c99c7342185fdeb (from parents) Merge: d1286cd2f4661ef0d50e2e22d8f1d4e84dabee4d b9d433487b5fa18d9b53e4bd7eed3801b62fde3e Author: Debian User <ds@gromit.(none)> Date: Tue Apr 17 12:17:41 2007 -0700 Merge branch 'master' of git+ssh://git.freedesktop.org/git/swfdec diff-tree d1286cd2f4661ef0d50e2e22d8f1d4e84dabee4d (from 0e753f61522c8c732621630a05bec095a8cd01b3) Author: Debian User <ds@gromit.(none)> Date: Tue Apr 17 12:17:13 2007 -0700 Copy over updated JPEG decoder from Cog. diff --git a/libswfdec/jpeg/Makefile.am b/libswfdec/jpeg/Makefile.am index 14f2cf8..7dd3152 100644 --- a/libswfdec/jpeg/Makefile.am +++ b/libswfdec/jpeg/Makefile.am @@ -1,21 +1,19 @@ noinst_LTLIBRARIES = libjpeg.la -noinst_PROGRAMS = jpeg_test jpeg_rgb_test -libjpeg_la_SOURCES = jpeg.c huffman.c jpeg_rgb_decoder.c -libjpeg_la_CFLAGS = $(GLOBAL_CFLAGS) $(LIBOIL_CFLAGS) +libjpeg_la_SOURCES = \ + jpeg.c \ + jpeg_bits.c \ + jpeg_huffman.c \ + jpeg_rgb_decoder.c \ + jpeg_tables.c + +noinst_HEADERS = \ + jpeg.h \ + jpeg_bits.h \ + jpeg_huffman.h \ + jpeg_rgb_decoder.h -noinst_HEADERS = bits.h huffman.h jpeg.h jpeg_debug.h \ - jpeg_internal.h - - - -jpeg_test_SOURCES = test.c -jpeg_test_CFLAGS = $(GLOBAL_CFLAGS) $(LIBOIL_CFLAGS) -jpeg_test_LDADD = libjpeg.la $(LIBOIL_LIBS) - -jpeg_rgb_test_SOURCES = test_rgb.c -jpeg_rgb_test_CFLAGS = $(GLOBAL_CFLAGS) $(LIBOIL_CFLAGS) -jpeg_rgb_test_LDADD = libjpeg.la $(LIBOIL_LIBS) +libjpeg_la_CFLAGS = $(GLOBAL_CFLAGS) $(GLIB_CFLAGS) $(LIBOIL_CFLAGS) -I$(srcdir)/.. diff --git a/libswfdec/jpeg/bits.h b/libswfdec/jpeg/bits.h deleted file mode 100644 index 95f4e90..0000000 --- a/libswfdec/jpeg/bits.h +++ /dev/null @@ -1,120 +0,0 @@ - -#ifndef __BITS_H__ -#define __BITS_H__ - -typedef struct bits_struct bits_t; -struct bits_struct { - unsigned char *ptr; - int idx; - unsigned char *end; -}; - -static inline int bits_needbits(bits_t *b, int n_bytes) -{ - if(b->ptr==NULL)return 1; - if(b->ptr + n_bytes > b->end)return 1; - - return 0; -} - -static inline int getbit(bits_t *b) -{ - int r; - - r = ((*b->ptr)>>(7-b->idx))&1; - - b->idx++; - if(b->idx>=8){ - b->ptr++; - b->idx = 0; - } - - return r; -} - -static inline unsigned int getbits(bits_t *b, int n) -{ - unsigned long r = 0; - int i; - - for(i=0;i<n;i++){ - r <<=1; - r |= getbit(b); - } - - return r; -} - -static inline unsigned int peekbits(bits_t *b, int n) -{ - bits_t tmp = *b; - - return getbits(&tmp, n); -} - -static inline int getsbits(bits_t *b, int n) -{ - unsigned long r = 0; - int i; - - if(n==0)return 0; - r = -getbit(b); - for(i=1;i<n;i++){ - r <<=1; - r |= getbit(b); - } - - return r; -} - -static inline unsigned int peek_u8(bits_t *b) -{ - return *b->ptr; -} - -static inline unsigned int get_u8(bits_t *b) -{ - return *b->ptr++; -} - -static inline unsigned int get_u16(bits_t *b) -{ - unsigned int r; - - r = b->ptr[0] | (b->ptr[1]<<8); - b->ptr+=2; - - return r; -} - -static inline unsigned int get_be_u16(bits_t *b) -{ - unsigned int r; - - r = (b->ptr[0]<<8) | b->ptr[1]; - b->ptr+=2; - - return r; -} - -static inline unsigned int get_u32(bits_t *b) -{ - unsigned int r; - - r = b->ptr[0] | (b->ptr[1]<<8) | (b->ptr[2]<<16) | (b->ptr[3]<<24); - b->ptr+=4; - - return r; -} - -static inline void syncbits(bits_t *b) -{ - if(b->idx){ - b->ptr++; - b->idx=0; - } - -} - -#endif - diff --git a/libswfdec/jpeg/huffman.c b/libswfdec/jpeg/huffman.c deleted file mode 100644 index 6fb04ca..0000000 --- a/libswfdec/jpeg/huffman.c +++ /dev/null @@ -1,197 +0,0 @@ - -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <liboil/liboil.h> -//#include <liboil/liboildebug.h> - -#define OIL_DEBUG(...) do { } while (0) - -#include "huffman.h" -#include "jpeg_debug.h" - -#define DEBUG printf - -/* misc helper function definitions */ - -static char *sprintbits (char *str, unsigned int bits, int n); - - -#define TRUE 1 -#define FALSE 0 - -void -huffman_table_dump (HuffmanTable * table) -{ - unsigned int n_bits; - unsigned int code; - char str[33]; - int i; - HuffmanEntry *entry; - - OIL_DEBUG ("dumping huffman table %p", table); - for (i = 0; i < table->len; i++) { - entry = table->entries + i; - n_bits = entry->n_bits; - code = entry->symbol >> (16 - n_bits); - sprintbits (str, code, n_bits); - OIL_DEBUG ("%s --> %d", str, entry->value); - } -} - -HuffmanTable * -huffman_table_new (void) -{ - HuffmanTable *table; - - table = malloc (sizeof(HuffmanTable)); - memset (table, 0, sizeof(HuffmanTable)); - - return table; -} - -void -huffman_table_free (HuffmanTable * table) -{ - free (table); -} - -void -huffman_table_add (HuffmanTable * table, uint32_t code, int n_bits, int value) -{ - HuffmanEntry *entry = table->entries + table->len; - - entry->value = value; - entry->symbol = code << (16 - n_bits); - entry->mask = 0xffff ^ (0xffff >> n_bits); - entry->n_bits = n_bits; - - table->len++; -} - -unsigned int -huffman_table_decode_jpeg (HuffmanTable * tab, bits_t * bits) -{ - unsigned int code; - int i; - char str[33]; - HuffmanEntry *entry; - - code = peekbits (bits, 16); - for (i = 0; i < tab->len; i++) { - entry = tab->entries + i; - if ((code & entry->mask) == entry->symbol) { - code = getbits (bits, entry->n_bits); - sprintbits (str, code, entry->n_bits); - OIL_DEBUG ("%s --> %d", str, entry->value); - return entry->value; - } - } - printf ("huffman sync lost"); - - return -1; -} - -int -huffman_table_decode_macroblock (short *block, HuffmanTable * dc_tab, - HuffmanTable * ac_tab, bits_t * bits) -{ - int r, s, x, rs; - int k; - char str[33]; - - memset (block, 0, sizeof (short) * 64); - - s = huffman_table_decode_jpeg (dc_tab, bits); - if (s < 0) - return -1; - x = getbits (bits, s); - if ((x >> (s - 1)) == 0) { - x -= (1 << s) - 1; - } - OIL_DEBUG ("s=%d (block[0]=%d)", s, x); - block[0] = x; - - for (k = 1; k < 64; k++) { - rs = huffman_table_decode_jpeg (ac_tab, bits); - if (rs < 0) { - OIL_DEBUG ("huffman error"); - return -1; - } - if (bits->ptr > bits->end) { - OIL_DEBUG ("overrun"); - return -1; - } - s = rs & 0xf; - r = rs >> 4; - if (s == 0) { - if (r == 15) { - OIL_DEBUG ("r=%d s=%d (skip 16)", r, s); - k += 15; - } else { - OIL_DEBUG ("r=%d s=%d (eob)", r, s); - break; - } - } else { - k += r; - if (k >= 64) { - printf ("macroblock overrun"); - return -1; - } - x = getbits (bits, s); - sprintbits (str, x, s); - if ((x >> (s - 1)) == 0) { - x -= (1 << s) - 1; - } - block[k] = x; - OIL_DEBUG ("r=%d s=%d (%s -> block[%d]=%d)", r, s, str, k, x); - } - } - return 0; -} - -int -huffman_table_decode (HuffmanTable * dc_tab, HuffmanTable * ac_tab, - bits_t * bits) -{ - short zz[64]; - int ret; - int i; - short *q; - - while (bits->ptr < bits->end) { - ret = huffman_table_decode_macroblock (zz, dc_tab, ac_tab, bits); - if (ret < 0) - return -1; - - q = zz; - for (i = 0; i < 8; i++) { - DEBUG ("%3d %3d %3d %3d %3d %3d %3d %3d", - q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7]); - q += 8; - } - } - - return 0; -} - -/* misc helper functins */ - -static char * -sprintbits (char *str, unsigned int bits, int n) -{ - int i; - int bit = 1 << (n - 1); - - for (i = 0; i < n; i++) { - str[i] = (bits & bit) ? '1' : '0'; - bit >>= 1; - } - str[i] = 0; - - return str; -} diff --git a/libswfdec/jpeg/huffman.h b/libswfdec/jpeg/huffman.h deleted file mode 100644 index e3bd94a..0000000 --- a/libswfdec/jpeg/huffman.h +++ /dev/null @@ -1,37 +0,0 @@ - -#ifndef _HUFFMAN_H_ -#define _HUFFMAN_H_ - -#include <liboil/liboil-stdint.h> - -#include "bits.h" - -typedef struct _HuffmanEntry HuffmanEntry; -typedef struct _HuffmanTable HuffmanTable; - -struct _HuffmanEntry { - unsigned int symbol; - unsigned int mask; - int n_bits; - unsigned char value; -}; - -struct _HuffmanTable { - int len; - HuffmanEntry entries[256]; -}; - - -void huffman_table_dump(HuffmanTable *table); -HuffmanTable *huffman_table_new(void); -void huffman_table_free(HuffmanTable *table); -void huffman_table_add(HuffmanTable *table, uint32_t code, int n_bits, - int value); -unsigned int huffman_table_decode_jpeg(HuffmanTable *tab, bits_t *bits); -int huffman_table_decode_macroblock(short *block, HuffmanTable *dc_tab, - HuffmanTable *ac_tab, bits_t *bits); -int huffman_table_decode(HuffmanTable *dc_tab, HuffmanTable *ac_tab, bits_t *bits); - - -#endif - diff --git a/libswfdec/jpeg/jpeg.c b/libswfdec/jpeg/jpeg.c index 228a4d8..448db4b 100644 --- a/libswfdec/jpeg/jpeg.c +++ b/libswfdec/jpeg/jpeg.c @@ -1,338 +1,226 @@ -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <liboil/liboil.h> +#include <liboil/liboil-stdint.h> +#include <swfdec_debug.h> + #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <ctype.h> -#include <limits.h> -#include <liboil/liboil-stdint.h> -#include <liboil/liboil.h> -//#include <liboil/liboildebug.h> -#include <stdarg.h> -#define OIL_DEBUG(...) do {} while (0) #include "jpeg_internal.h" -#define MAX(a,b) ((a)>(b) ? (a) : (b)) +//#define MAX(a,b) ((a)>(b) ? (a) : (b)) -#define JPEG_MARKER_STUFFED 0x00 -#define JPEG_MARKER_TEM 0x01 -#define JPEG_MARKER_RES 0x02 - -#define JPEG_MARKER_SOF_0 0xc0 -#define JPEG_MARKER_SOF_1 0xc1 -#define JPEG_MARKER_SOF_2 0xc2 -#define JPEG_MARKER_SOF_3 0xc3 -#define JPEG_MARKER_DHT 0xc4 -#define JPEG_MARKER_SOF_5 0xc5 -#define JPEG_MARKER_SOF_6 0xc6 -#define JPEG_MARKER_SOF_7 0xc7 -#define JPEG_MARKER_JPG 0xc8 -#define JPEG_MARKER_SOF_9 0xc9 -#define JPEG_MARKER_SOF_10 0xca -#define JPEG_MARKER_SOF_11 0xcb -#define JPEG_MARKER_DAC 0xcc -#define JPEG_MARKER_SOF_13 0xcd -#define JPEG_MARKER_SOF_14 0xce -#define JPEG_MARKER_SOF_15 0xcf - -#define JPEG_MARKER_RST_0 0xd0 -#define JPEG_MARKER_RST_1 0xd1 -#define JPEG_MARKER_RST_2 0xd2 -#define JPEG_MARKER_RST_3 0xd3 -#define JPEG_MARKER_RST_4 0xd4 -#define JPEG_MARKER_RST_5 0xd5 -#define JPEG_MARKER_RST_6 0xd6 -#define JPEG_MARKER_RST_7 0xd7 -#define JPEG_MARKER_SOI 0xd8 -#define JPEG_MARKER_EOI 0xd9 -#define JPEG_MARKER_SOS 0xda -#define JPEG_MARKER_DQT 0xdb -#define JPEG_MARKER_DNL 0xdc -#define JPEG_MARKER_DRI 0xdd -#define JPEG_MARKER_DHP 0xde -#define JPEG_MARKER_EXP 0xdf -#define JPEG_MARKER_APP(x) (0xe0 + (x)) -#define JPEG_MARKER_JPG_(x) (0xf0 + (x)) -#define JPEG_MARKER_COM 0xfe +extern uint8_t jpeg_standard_tables[]; +extern int jpeg_standard_tables_size; -#define JPEG_MARKER_JFIF JPEG_MARKER_APP(0) +void jpeg_decoder_error(JpegDecoder *dec, char *fmt, ...); -struct jpeg_marker_struct -{ - unsigned int tag; - int (*func) (JpegDecoder * dec, bits_t * bits); - char *name; - unsigned int flags; -}; -static struct jpeg_marker_struct jpeg_markers[] = { - {0xc0, jpeg_decoder_sof_baseline_dct, - "baseline DCT"}, - {0xc4, jpeg_decoder_define_huffman_table, - "define Huffman table(s)"}, - {0xd8, jpeg_decoder_soi, - "start of image"}, - {0xd9, jpeg_decoder_eoi, - "end of image"}, - {0xda, jpeg_decoder_sos, - "start of scan", JPEG_ENTROPY_SEGMENT}, - {0xdb, jpeg_decoder_define_quant_table, - "define quantization table"}, - {0xe0, jpeg_decoder_application0, - "application segment 0"}, - - {0x00, NULL, "illegal"}, - {0x01, NULL, "TEM"}, - {0x02, NULL, "RES"}, - - {0xc1, NULL, "extended sequential DCT"}, - {0xc2, NULL, "progressive DCT"}, - {0xc3, NULL, "lossless (sequential)"}, - {0xc5, NULL, "differential sequential DCT"}, - {0xc6, NULL, "differential progressive DCT"}, - {0xc7, NULL, "differential lossless (sequential)"}, - {0xc8, NULL, "reserved"}, - {0xc9, NULL, "extended sequential DCT (arith)"}, - {0xca, NULL, "progressive DCT (arith)"}, - {0xcb, NULL, "lossless (sequential) (arith)"}, - {0xcc, NULL, "define arithmetic coding conditioning(s)"}, - {0xcd, NULL, "differential sequential DCT (arith)"}, - {0xce, NULL, "differential progressive DCT (arith)"}, - {0xcf, NULL, "differential lossless (sequential) (arith)"}, - - {0xd0, jpeg_decoder_restart, "restart0", JPEG_ENTROPY_SEGMENT}, - {0xd1, jpeg_decoder_restart, "restart1", JPEG_ENTROPY_SEGMENT}, - {0xd2, jpeg_decoder_restart, "restart2", JPEG_ENTROPY_SEGMENT}, - {0xd3, jpeg_decoder_restart, "restart3", JPEG_ENTROPY_SEGMENT}, - {0xd4, jpeg_decoder_restart, "restart4", JPEG_ENTROPY_SEGMENT}, - {0xd5, jpeg_decoder_restart, "restart5", JPEG_ENTROPY_SEGMENT}, - {0xd6, jpeg_decoder_restart, "restart6", JPEG_ENTROPY_SEGMENT}, - {0xd7, jpeg_decoder_restart, "restart7", JPEG_ENTROPY_SEGMENT}, - - {0xdc, NULL, "define number of lines"}, - {0xdd, jpeg_decoder_restart_interval, "define restart interval"}, - {0xde, NULL, "define hierarchical progression"}, - {0xdf, NULL, "expand reference component(s)"}, - - {0xe1, jpeg_decoder_application_misc, "application segment 1"}, - {0xe2, jpeg_decoder_application_misc, "application segment 2"}, - {0xe3, jpeg_decoder_application_misc, "application segment 3"}, - {0xe4, jpeg_decoder_application_misc, "application segment 4"}, - {0xe5, jpeg_decoder_application_misc, "application segment 5"}, - {0xe6, jpeg_decoder_application_misc, "application segment 6"}, - {0xe7, jpeg_decoder_application_misc, "application segment 7"}, - {0xe8, jpeg_decoder_application_misc, "application segment 8"}, - {0xe9, jpeg_decoder_application_misc, "application segment 9"}, - {0xea, jpeg_decoder_application_misc, "application segment a"}, - {0xeb, jpeg_decoder_application_misc, "application segment b"}, - {0xec, jpeg_decoder_application_misc, "application segment c"}, - {0xed, jpeg_decoder_application_misc, "application segment d"}, - {0xee, jpeg_decoder_application_misc, "application segment e"}, - {0xef, jpeg_decoder_application_misc, "application segment f"}, - - {0xf0, NULL, "JPEG extension 0"}, - {0xfe, jpeg_decoder_comment, "comment"}, - - {0x00, NULL, "illegal"}, -}; -static const int n_jpeg_markers - sizeof (jpeg_markers) / sizeof (jpeg_markers[0]); - -static unsigned char std_tables[] = { - 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, - - 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, - 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, - 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, - 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, - 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, - 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, - - 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, - - 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, - 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, - 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, - 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, - 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, - 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, - 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, - 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, -}; +void jpeg_decoder_define_huffman_tables (JpegDecoder * dec); +void jpeg_decoder_define_arithmetic_conditioning (JpegDecoder *dec); +void jpeg_decoder_define_quantization_tables (JpegDecoder *dec); +void jpeg_decoder_define_restart_interval (JpegDecoder *dec); +void jpeg_decoder_start_of_frame (JpegDecoder * dec, int marker); +void jpeg_decoder_start_of_scan (JpegDecoder * dec); /* misc helper function declarations */ -static void dumpbits (bits_t * bits); +static char *sprintbits (char *str, unsigned int bits, int n); -static void huffman_table_load_std_jpeg (JpegDecoder * dec); +static void jpeg_load_standard_huffman_tables (JpegDecoder * dec); +static void jpeg_decoder_verify_header (JpegDecoder *dec); +static void jpeg_decoder_init_decoder (JpegDecoder *dec); -int -jpeg_decoder_soi (JpegDecoder * dec, bits_t * bits) -{ - return 0; -} -int -jpeg_decoder_eoi (JpegDecoder * dec, bits_t * bits) -{ - return 0; -} -int -jpeg_decoder_sof_baseline_dct (JpegDecoder * dec, bits_t * bits) +static void +jpeg_decoder_verify_header (JpegDecoder *dec) { + int max_quant_table = 0; int i; - int length; - int image_size; - int rowstride; - int max_h_oversample = 0, max_v_oversample = 0; - OIL_DEBUG ("start of frame (baseline DCT)"); + if (dec->sof_type != JPEG_MARKER_SOF_0) { + SWFDEC_ERROR("only handle baseline DCT"); + dec->error = TRUE; + } - length = get_be_u16 (bits); - bits->end = bits->ptr + length - 2; + if (dec->width < 1) { + SWFDEC_ERROR("height can't be 0"); + dec->error = TRUE; + } - dec->depth = get_u8 (bits); - dec->height = get_be_u16 (bits); - dec->width = get_be_u16 (bits); - dec->n_components = get_u8 (bits); + switch (dec->sof_type) { + case JPEG_MARKER_SOF_0: + /* baseline DCT */ + max_quant_table = 3; + if (dec->depth != 8) { + SWFDEC_ERROR("depth must be 8 (%d)", dec->depth); + dec->error = TRUE; + } + break; + case JPEG_MARKER_SOF_1: + /* extended DCT */ + max_quant_table = 3; + if (dec->depth != 8 && dec->depth != 12) { + SWFDEC_ERROR("depth must be 8 or 12 (%d)", dec->depth); + dec->error = TRUE; + } + break; + case JPEG_MARKER_SOF_2: + /* progressive DCT */ + max_quant_table = 3; + if (dec->depth != 8 && dec->depth != 12) { + SWFDEC_ERROR("depth must be 8 or 12 (%d)", dec->depth); + dec->error = TRUE; + } + break; + case JPEG_MARKER_SOF_3: + /* lossless DCT */ + max_quant_table = 0; + if (dec->depth < 2 || dec->depth > 16) { + SWFDEC_ERROR("depth must be between 2 and 16 (%d)", dec->depth); + dec->error = TRUE; + } + break; + default: + break; + } - OIL_DEBUG ( - "frame_length=%d depth=%d height=%d width=%d n_components=%d", length, - dec->depth, dec->height, dec->width, dec->n_components); + if (dec->n_components < 0 || dec->n_components > 255) { + SWFDEC_ERROR("n_components must be in the range 0-255 (%d)", + dec->n_components); + dec->error = TRUE; + } + if (dec->sof_type == JPEG_MARKER_SOF_2 && dec->n_components > 4) { + SWFDEC_ERROR("n_components must be <= 4 for progressive DCT (%d)", + dec->n_components); + dec->error = TRUE; + } for (i = 0; i < dec->n_components; i++) { - dec->components[i].id = get_u8 (bits); - dec->components[i].h_oversample = getbits (bits, 4); - dec->components[i].v_oversample = getbits (bits, 4); - dec->components[i].quant_table = get_u8 (bits); + if (dec->components[i].id < 0 || dec->components[i].id > 255) { + SWFDEC_ERROR("component ID out of range"); + dec->error = TRUE; + break; + } + if (dec->components[i].h_sample < 1 || dec->components[i].h_sample > 4 || + dec->components[i].v_sample < 1 || dec->components[i].v_sample > 4) { + SWFDEC_ERROR("sample factor(s) for component %d out of range %d %d", + i, dec->components[i].h_sample, dec->components[i].v_sample); + dec->error = TRUE; + break; + } + if (dec->components[i].quant_table < 0 || + dec->components[i].quant_table > max_quant_table) { + SWFDEC_ERROR("quant table for component %d out of range (%d)", + i, dec->components[i].quant_table); + dec->error = TRUE; + break; + } + } +} + +static void +jpeg_decoder_init_decoder (JpegDecoder *dec) +{ + int max_h_sample = 0; + int max_v_sample = 0; + int i; + + /* decoder limitations */ + if (dec->n_components != 3) { + jpeg_decoder_error(dec, "wrong number of components %d", dec->n_components); + return; + } + if (dec->sof_type != JPEG_MARKER_SOF_0) { + jpeg_decoder_error(dec, "only handle baseline DCT"); + return; + } - OIL_DEBUG ( - "[%d] id=%d h_oversample=%d v_oversample=%d quant_table=%d", i, - dec->components[i].id, dec->components[i].h_oversample, - dec->components[i].v_oversample, dec->components[i].quant_table); - max_h_oversample = MAX (max_h_oversample, dec->components[i].h_oversample); - max_v_oversample = MAX (max_v_oversample, dec->components[i].v_oversample); + + + for (i=0; i < dec->n_components; i++) { + max_h_sample = MAX (max_h_sample, dec->components[i].h_sample); + max_v_sample = MAX (max_v_sample, dec->components[i].v_sample); } + dec->width_blocks - (dec->width + 8 * max_h_oversample - 1) / (8 * max_h_oversample); + (dec->width + 8 * max_h_sample - 1) / (8 * max_h_sample); dec->height_blocks - (dec->height + 8 * max_v_oversample - 1) / (8 * max_v_oversample); + (dec->height + 8 * max_v_sample - 1) / (8 * max_v_sample); for (i = 0; i < dec->n_components; i++) { - dec->components[i].h_subsample = max_h_oversample / - dec->components[i].h_oversample; - dec->components[i].v_subsample = max_v_oversample / - dec->components[i].v_oversample; + int rowstride; + int image_size; - rowstride = dec->width_blocks * 8 * max_h_oversample / + dec->components[i].h_subsample = max_h_sample / + dec->components[i].h_sample; + dec->components[i].v_subsample = max_v_sample / + dec->components[i].v_sample; + + rowstride = dec->width_blocks * 8 * max_h_sample / dec->components[i].h_subsample; image_size = rowstride * - (dec->height_blocks * 8 * max_v_oversample / + (dec->height_blocks * 8 * max_v_sample / dec->components[i].v_subsample); dec->components[i].rowstride = rowstride; dec->components[i].image = malloc (image_size); } - - if (bits->end != bits->ptr) - OIL_DEBUG ("endptr != bits"); - - return length; } -int -jpeg_decoder_define_quant_table (JpegDecoder * dec, bits_t * bits) + +void +generate_code_table (int *huffsize) { - int length; - int pq; - int tq; + int code; int i; - short *q; - - OIL_DEBUG ("define quantization table"); - - length = get_be_u16 (bits); - bits->end = bits->ptr + length - 2; - - while (bits->ptr < bits->end) { - pq = getbits (bits, 4); - tq = getbits (bits, 4); + int j; + int k; + char str[33]; - q = dec->quant_table[tq]; - if (pq) { - for (i = 0; i < 64; i++) { - q[i] = get_be_u16 (bits); - } - } else { - for (i = 0; i < 64; i++) { - q[i] = get_u8 (bits); - } - } + //int l; - OIL_DEBUG ("quant table index %d:", tq); - for (i = 0; i < 8; i++) { - OIL_DEBUG ("%3d %3d %3d %3d %3d %3d %3d %3d", - q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7]); - q += 8; + code = 0; + k = 0; + for (i = 0; i < 16; i++) { + for (j = 0; j < huffsize[i]; j++) { + SWFDEC_DEBUG ("huffcode[%d] = %s", k, + sprintbits (str, code >> (15 - i), i + 1)); + code++; + k++; } + code <<= 1; } - return length; } -HuffmanTable * -huffman_table_new_jpeg (bits_t * bits) +int +huffman_table_init_jpeg (HuffmanTable *table, JpegBits * bits) { int n_symbols; int huffsize[16]; int i, j, k; - HuffmanTable *table; unsigned int symbol; + int n = 0; - table = huffman_table_new (); + huffman_table_init (table); /* huffsize[i] is the number of symbols that have length * (i+1) bits. Maximum bit length is 16 bits, so there are * 16 entries. */ n_symbols = 0; for (i = 0; i < 16; i++) { - huffsize[i] = get_u8 (bits); + huffsize[i] = jpeg_bits_get_u8 (bits); + n++; n_symbols += huffsize[i]; } @@ -345,7 +233,8 @@ huffman_table_new_jpeg (bits_t * bits) k = 0; for (i = 0; i < 16; i++) { for (j = 0; j < huffsize[i]; j++) { - huffman_table_add (table, symbol, i + 1, get_u8 (bits)); + huffman_table_add (table, symbol, i + 1, jpeg_bits_get_u8 (bits)); + n++; symbol++; k++; } @@ -353,8 +242,9 @@ huffman_table_new_jpeg (bits_t * bits) * number of bits we think it is. This is only triggered * for bad huffsize[] arrays. */ if (symbol >= (1U << (i + 1))) { - OIL_DEBUG ("bad huffsize[] array"); - return NULL; + /* FIXME jpeg_decoder_error() */ + SWFDEC_DEBUG ("bad huffsize[] array"); + return -1; } symbol <<= 1; @@ -362,65 +252,7 @@ huffman_table_new_jpeg (bits_t * bits) huffman_table_dump (table); - return table; -} - -int -jpeg_decoder_define_huffman_table (JpegDecoder * dec, bits_t * bits) -{ - int length; - int tc; - int th; - HuffmanTable *hufftab; - - OIL_DEBUG ("define huffman table"); - - length = get_be_u16 (bits); - bits->end = bits->ptr + length - 2; - - while (bits->ptr < bits->end) { - tc = getbits (bits, 4); - th = getbits (bits, 4); - - OIL_DEBUG ("huff table index %d:", th); - OIL_DEBUG ("type %d (%s)", tc, tc ? "ac" : "dc"); - - hufftab = huffman_table_new_jpeg (bits); - if (tc) { - if (dec->ac_huff_table[th]) { - huffman_table_free (dec->ac_huff_table[th]); - } - dec->ac_huff_table[th] = hufftab; - } else { - if (dec->dc_huff_table[th]) { - huffman_table_free (dec->dc_huff_table[th]); - } - dec->dc_huff_table[th] = hufftab; - } - } - - return length; -} - -static void -dumpbits (bits_t * bits) -{ - int i; - int j; - unsigned char *p; - char s[40]; - - p = bits->ptr; - for (i = 0; i < 8; i++) { - sprintf (s, "%02x %02x %02x %02x %02x %02x %02x %02x ........", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - for (j = 0; j < 8; j++) { - s[j + 24] = (isprint (p[j])) ? p[j] : '.'; - } - OIL_DEBUG ("%s", s); - p += 8; - } - + return n; } int @@ -432,104 +264,19 @@ jpeg_decoder_find_component_by_id (JpegD if (dec->components[i].id == id) return i; } - OIL_DEBUG ("undefined component id %d", id); + SWFDEC_DEBUG ("undefined component id %d", id); return 0; } int -jpeg_decoder_sos (JpegDecoder * dec, bits_t * bits) -{ - int length; - int i; - - int n_components; - int spectral_start; - int spectral_end; - int approx_high; - int approx_low; - int n; - - OIL_DEBUG ("start of scan"); - - length = get_be_u16 (bits); - bits->end = bits->ptr + length - 2; - OIL_DEBUG ("length=%d", length); - - n_components = get_u8 (bits); - n = 0; - dec->scan_h_subsample = 0; - dec->scan_v_subsample = 0; - for (i = 0; i < n_components; i++) { - int component_id; - int dc_table; - int ac_table; - int x; - int y; - int index; - int h_subsample; - int v_subsample; - int quant_index; - - component_id = get_u8 (bits); - dc_table = getbits (bits, 4); - ac_table = getbits (bits, 4); - index = jpeg_decoder_find_component_by_id (dec, component_id); - - h_subsample = dec->components[index].h_oversample; - v_subsample = dec->components[index].v_oversample; - quant_index = dec->components[index].quant_table; - - for (y = 0; y < v_subsample; y++) { - for (x = 0; x < h_subsample; x++) { - dec->scan_list[n].component_index = index; - dec->scan_list[n].dc_table = dc_table; - dec->scan_list[n].ac_table = ac_table; - dec->scan_list[n].quant_table = quant_index; - dec->scan_list[n].x = x; - dec->scan_list[n].y = y; - dec->scan_list[n].offset - y * 8 * dec->components[index].rowstride + x * 8; - n++; - } - } - - dec->scan_h_subsample = MAX (dec->scan_h_subsample, h_subsample); - dec->scan_v_subsample = MAX (dec->scan_v_subsample, v_subsample); - - syncbits (bits); - - OIL_DEBUG ("component %d: index=%d dc_table=%d ac_table=%d n=%d", - component_id, index, dc_table, ac_table, n); - } - dec->scan_list_length = n; - - spectral_start = get_u8 (bits); - spectral_end = get_u8 (bits); - OIL_DEBUG ("spectral range [%d,%d]", spectral_start, spectral_end); - approx_high = getbits (bits, 4); - approx_low = getbits (bits, 4); - OIL_DEBUG ("approx range [%d,%d]", approx_low, approx_high); - syncbits (bits); - - dec->x = 0; - dec->y = 0; - dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128 * 8; - - if (bits->end != bits->ptr) - OIL_DEBUG ("endptr != bits"); - - return length; -} - -int -jpeg_decoder_application0 (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_application0 (JpegDecoder * dec, JpegBits * bits) { int length; - OIL_DEBUG ("app0"); + SWFDEC_DEBUG ("app0"); length = get_be_u16 (bits); - OIL_DEBUG ("length=%d", length); + SWFDEC_DEBUG ("length=%d", length); if (memcmp (bits->ptr, "JFIF", 4) == 0 && bits->ptr[4] == 0) { int version; @@ -539,7 +286,7 @@ jpeg_decoder_application0 (JpegDecoder * int x_thumbnail; int y_thumbnail; - OIL_DEBUG ("JFIF"); + SWFDEC_DEBUG ("JFIF"); bits->ptr += 5; version = get_be_u16 (bits); @@ -549,17 +296,17 @@ jpeg_decoder_application0 (JpegDecoder * x_thumbnail = get_u8 (bits); y_thumbnail = get_u8 (bits); - OIL_DEBUG ("version = %04x", version); - OIL_DEBUG ("units = %d", units); - OIL_DEBUG ("x_density = %d", x_density); - OIL_DEBUG ("y_density = %d", y_density); - OIL_DEBUG ("x_thumbnail = %d", x_thumbnail); - OIL_DEBUG ("y_thumbnail = %d", y_thumbnail); + SWFDEC_DEBUG ("version = %04x", version); + SWFDEC_DEBUG ("units = %d", units); + SWFDEC_DEBUG ("x_density = %d", x_density); + SWFDEC_DEBUG ("y_density = %d", y_density); + SWFDEC_DEBUG ("x_thumbnail = %d", x_thumbnail); + SWFDEC_DEBUG ("y_thumbnail = %d", y_thumbnail); } if (memcmp (bits->ptr, "JFXX", 4) == 0 && bits->ptr[4] == 0) { - OIL_DEBUG ("JFIF extension (not handled)"); + SWFDEC_DEBUG ("JFIF extension (not handled)"); bits->ptr += length - 2; } @@ -567,17 +314,17 @@ jpeg_decoder_application0 (JpegDecoder * } int -jpeg_decoder_application_misc (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_application_misc (JpegDecoder * dec, JpegBits * bits) { int length; - OIL_DEBUG ("appX"); + SWFDEC_DEBUG ("appX"); length = get_be_u16 (bits); - OIL_DEBUG ("length=%d", length); + SWFDEC_DEBUG ("length=%d", length); - OIL_DEBUG ("JPEG application tag X ignored"); - dumpbits (bits); + SWFDEC_DEBUG ("JPEG application tag X ignored"); + //dumpbits (bits); bits->ptr += length - 2; @@ -585,16 +332,16 @@ jpeg_decoder_application_misc (JpegDecod } int -jpeg_decoder_comment (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_comment (JpegDecoder * dec, JpegBits * bits) { int length; - OIL_DEBUG ("comment"); + SWFDEC_DEBUG ("comment"); length = get_be_u16 (bits); - OIL_DEBUG ("length=%d", length); + SWFDEC_DEBUG ("length=%d", length); - dumpbits (bits); + //dumpbits (bits); bits->ptr += length - 2; @@ -602,33 +349,34 @@ jpeg_decoder_comment (JpegDecoder * dec, } int -jpeg_decoder_restart_interval (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_restart_interval (JpegDecoder * dec, JpegBits * bits) { int length; - OIL_DEBUG ("comment"); + SWFDEC_DEBUG ("comment"); length = get_be_u16 (bits); - OIL_DEBUG ("length=%d", length); + SWFDEC_DEBUG ("length=%d", length); dec->restart_interval = get_be_u16 (bits); - OIL_DEBUG ("restart_interval=%d", dec->restart_interval); + SWFDEC_DEBUG ("restart_interval=%d", dec->restart_interval); return length; } int -jpeg_decoder_restart (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_restart (JpegDecoder * dec, JpegBits * bits) { - OIL_DEBUG ("restart"); + SWFDEC_DEBUG ("restart"); return 0; } void -jpeg_decoder_decode_entropy_segment (JpegDecoder * dec, bits_t * bits) +jpeg_decoder_decode_entropy_segment (JpegDecoder * dec) { - bits_t b2, *bits2 = &b2; + JpegBits * bits = &dec->bits; + JpegBits b2, *bits2 = &b2; short block[64]; short block2[64]; unsigned char *newptr; @@ -648,7 +396,7 @@ jpeg_decoder_decode_entropy_segment (Jpe } len++; } - OIL_DEBUG ("entropy length = %d", len); + SWFDEC_DEBUG ("entropy length = %d", len); /* we allocate extra space, since the getbits() code can * potentially read past the end of the buffer */ @@ -672,7 +420,7 @@ jpeg_decoder_decode_entropy_segment (Jpe x = dec->x; y = dec->y; n = dec->restart_interval; - if (n == 0) n = INT_MAX; + if (n == 0) n = (1<<26); /* max number of blocks */ while (n-- > 0) { for (i = 0; i < dec->scan_list_length; i++) { int dc_table_index; @@ -681,7 +429,7 @@ jpeg_decoder_decode_entropy_segment (Jpe unsigned char *ptr; int component_index; - OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", + SWFDEC_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", x, y, dec->scan_list[i].component_index, dec->scan_list[i].dc_table, dec->scan_list[i].ac_table); @@ -692,10 +440,10 @@ jpeg_decoder_decode_entropy_segment (Jpe quant_index = dec->scan_list[i].quant_table; ret = huffman_table_decode_macroblock (block, - dec->dc_huff_table[dc_table_index], - dec->ac_huff_table[ac_table_index], bits2); + &dec->dc_huff_table[dc_table_index], + &dec->ac_huff_table[ac_table_index], bits2); if (ret < 0) { - OIL_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", + SWFDEC_DEBUG ("%d,%d: component=%d dc_table=%d ac_table=%d", x, y, dec->scan_list[i].component_index, dec->scan_list[i].dc_table, dec->scan_list[i].ac_table); @@ -703,8 +451,8 @@ jpeg_decoder_decode_entropy_segment (Jpe break; } - OIL_DEBUG ("using quant table %d", quant_index); - oil_mult8x8_s16 (block2, block, dec->quant_table[quant_index], + SWFDEC_DEBUG ("using quant table %d", quant_index); + oil_mult8x8_s16 (block2, block, dec->quant_tables[quant_index].quantizer, sizeof (short) * 8, sizeof(short) * 8, sizeof (short) * 8); dec->dc[component_index] += block2[0]; block2[0] = dec->dc[component_index]; @@ -714,10 +462,10 @@ jpeg_decoder_decode_entropy_segment (Jpe oil_trans8x8_s16 (block, sizeof (short) * 8, block2, sizeof (short) * 8); ptr = dec->components[component_index].image + - x * dec->components[component_index].h_oversample + + x * dec->components[component_index].h_sample + dec->scan_list[i].offset + dec->components[component_index].rowstride * y * - dec->components[component_index].v_oversample; + dec->components[component_index].v_sample; oil_clipconv8x8_u8_s16 (ptr, dec->components[component_index].rowstride, @@ -749,7 +497,7 @@ jpeg_decoder_new (void) dec = malloc (sizeof(JpegDecoder)); memset (dec, 0, sizeof(JpegDecoder)); - huffman_table_load_std_jpeg (dec); + jpeg_load_standard_huffman_tables (dec); return dec; } @@ -759,12 +507,7 @@ jpeg_decoder_free (JpegDecoder * dec) { int i; - huffman_table_free (dec->dc_huff_table[0]); - huffman_table_free (dec->ac_huff_table[0]); - huffman_table_free (dec->dc_huff_table[1]); - huffman_table_free (dec->ac_huff_table[1]); - - for (i = 0; i < JPEG_N_COMPONENTS; i++) { + for (i = 0; i < JPEG_MAX_COMPONENTS; i++) { if (dec->components[i].image) free (dec->components[i].image); } @@ -775,26 +518,417 @@ jpeg_decoder_free (JpegDecoder * dec) free (dec); } +void +jpeg_decoder_error(JpegDecoder *dec, char *fmt, ...) +{ + va_list varargs; + + if (dec->error) return; + + dec->error_message = malloc(250); + va_start (varargs, fmt); + vsnprintf(dec->error_message, 250 - 1, fmt, varargs); + dec->error_message[250 - 1] = 0; + va_end (varargs); + + SWFDEC_ERROR("decoder error: %s", dec->error_message); + abort(); + dec->error = TRUE; +} + int -jpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len) +jpeg_decoder_get_marker (JpegDecoder *dec, int *marker) { - unsigned int offset; + int a,b; + JpegBits *bits = &dec->bits; - if (len == 0) - return 0; + if (jpeg_bits_available(bits) < 2) { + return FALSE; + } -#if 0 - { - static int index = 0; - FILE *file; - char s[100]; - - sprintf(s, "image-%d.jpg", index++); - file = fopen(s, "w"); - fwrite (data, len, 1, file); - fclose(file); + a = jpeg_bits_get_u8(bits); + if (a != 0xff) { + jpeg_decoder_error(dec, "expected marker, not 0x%02x", a); + return FALSE; } -#endif + + do { + b = jpeg_bits_get_u8 (bits); + } while (b == 0xff && jpeg_bits_error(bits)); + + *marker = b; + return TRUE; +} + +void +jpeg_decoder_skip (JpegDecoder *dec) +{ + int length; + + length = jpeg_bits_get_u16_be (&dec->bits); + jpeg_bits_skip (&dec->bits, length - 2); +} + +int +jpeg_decoder_decode (JpegDecoder *dec) +{ + JpegBits *bits; + int marker; + + dec->error = FALSE; + + bits = &dec->bits; + + /* Note: The spec is ambiguous as to whether fill bytes can come + * before the first marker. We'll assume yes. */ + if (!jpeg_decoder_get_marker (dec, &marker)) { + return FALSE; + } + if (marker != JPEG_MARKER_SOI) { + jpeg_decoder_error(dec, "not a JPEG image"); + return FALSE; + } + + /* Interpret markers up to the start of frame */ + while (!dec->error) { + if (!jpeg_decoder_get_marker (dec, &marker)) { + return FALSE; + } + + if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) { + jpeg_decoder_define_huffman_tables (dec); + } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) { + jpeg_decoder_define_arithmetic_conditioning (dec); + } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) { + jpeg_decoder_define_quantization_tables (dec); + } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) { + jpeg_decoder_define_restart_interval (dec); + } else if (JPEG_MARKER_IS_APP(marker)) { + /* FIXME decode app segment */ + jpeg_decoder_skip (dec); + } else if (marker == JPEG_MARKER_COMMENT) { + jpeg_decoder_skip (dec); + } else if (JPEG_MARKER_IS_START_OF_FRAME(marker)) { + break; + } else { + jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker); + return FALSE; + } + } + + jpeg_decoder_start_of_frame(dec, marker); + + jpeg_decoder_verify_header (dec); + if (dec->error) { + return FALSE; + } + + jpeg_decoder_init_decoder (dec); + if (dec->error) { + return FALSE; + } + + /* In this section, we loop over parse units until we reach the end + * of the image. */ + while (!dec->error) { + if (!jpeg_decoder_get_marker (dec, &marker)) { + return FALSE; + } + + if (marker == JPEG_MARKER_DEFINE_HUFFMAN_TABLES) { + jpeg_decoder_define_huffman_tables (dec); + } else if (marker == JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING) { + jpeg_decoder_define_arithmetic_conditioning (dec); + } else if (marker == JPEG_MARKER_DEFINE_QUANTIZATION_TABLES) { + jpeg_decoder_define_quantization_tables (dec); + } else if (marker == JPEG_MARKER_DEFINE_RESTART_INTERVAL) { + jpeg_decoder_define_restart_interval (dec); + } else if (JPEG_MARKER_IS_APP(marker)) { + jpeg_decoder_skip (dec); + } else if (marker == JPEG_MARKER_COMMENT) { + jpeg_decoder_skip (dec); + } else if (marker == JPEG_MARKER_SOS) { + jpeg_decoder_start_of_scan (dec); + jpeg_decoder_decode_entropy_segment (dec); + } else if (JPEG_MARKER_IS_RESET(marker)) { + jpeg_decoder_decode_entropy_segment (dec); + } else if (marker == JPEG_MARKER_EOI) { + break; + } else { + jpeg_decoder_error(dec, "unexpected marker 0x%02x", marker); + return FALSE; + } + } + + return TRUE; +} + +/* handle markers */ + +void +jpeg_decoder_define_huffman_tables (JpegDecoder * dec) +{ + JpegBits *bits = &dec->bits; + int length; + int tc; + int th; + int x; + HuffmanTable *hufftab; + + SWFDEC_DEBUG ("define huffman tables"); + + length = jpeg_bits_get_u16_be (bits); + if (length < 2) { + jpeg_decoder_error(dec, "length too short"); + return; + } + length -= 2; + + while (length > 0) { + x = jpeg_bits_get_u8 (bits); + length--; + + tc = x >> 4; + th = x & 0xf; + + SWFDEC_DEBUG ("huff table type %d (%s) index %d", tc, tc ? "ac" : "dc", th); + if (tc > 1 || th > 3) { + jpeg_decoder_error(dec, "huffman table type or index out of range"); + return; + } + + if (tc) { + hufftab = &dec->ac_huff_table[th]; + length -= huffman_table_init_jpeg (hufftab, bits); + } else { + hufftab = &dec->dc_huff_table[th]; + length -= huffman_table_init_jpeg (hufftab, bits); + } + } + if (length < 0) { + jpeg_decoder_error(dec, "huffman table overran available bytes"); + return; + } +} + +void +jpeg_decoder_define_quantization_tables (JpegDecoder *dec) +{ + JpegBits *bits = &dec->bits; + JpegQuantTable *table; + int length; + int pq; + int tq; + int i; + + SWFDEC_INFO ("define quantization table"); + + length = jpeg_bits_get_u16_be (bits); + if (length < 2) { + jpeg_decoder_error(dec, "length too short"); + return; + } + length -= 2; + + while (length > 0) { + int x; + + x = jpeg_bits_get_u8 (bits); + length--; + pq = x >> 4; + tq = x & 0xf; + + if (pq > 1) { + jpeg_decoder_error (dec, "bad pq value"); + return; + } + if (tq > 3) { + jpeg_decoder_error (dec, "bad tq value"); + return; + } + + table = &dec->quant_tables[tq]; + if (pq) { + for (i = 0; i < 64; i++) { + table->quantizer[i] = jpeg_bits_get_u16_be (bits); + length -= 2; + } + } else { + for (i = 0; i < 64; i++) { + table->quantizer[i] = jpeg_bits_get_u8 (bits); + length -= 1; + } + } + } + if (length < 0) { + jpeg_decoder_error(dec, "quantization table overran available bytes"); + return; + } +} + +void +jpeg_decoder_define_restart_interval (JpegDecoder *dec) +{ + JpegBits *bits = &dec->bits; + int length; + + length = jpeg_bits_get_u16_be (bits); + if (length != 4) { + jpeg_decoder_error(dec, "length supposed to be 4 (%d)", length); + return; + } + + /* FIXME this needs to be checked somewhere */ + dec->restart_interval = jpeg_bits_get_u16_be (bits); +} + +void +jpeg_decoder_define_arithmetic_conditioning (JpegDecoder *dec) +{ + /* we don't handle arithmetic coding, so skip it */ + jpeg_decoder_skip (dec); +} + +void +jpeg_decoder_start_of_frame (JpegDecoder * dec, int marker) +{ + JpegBits *bits = &dec->bits; + int i; + int length; + + SWFDEC_INFO ("start of frame"); + + dec->sof_type = marker; + + length = jpeg_bits_get_u16_be (bits); + + if (jpeg_bits_available(bits) < length) { + jpeg_decoder_error(dec, "not enough data for start_of_frame (%d < %d)", + length, jpeg_bits_available(bits)); + return; + } + + dec->depth = jpeg_bits_get_u8 (bits); + dec->height = jpeg_bits_get_u16_be (bits); + dec->width = jpeg_bits_get_u16_be (bits); + dec->n_components = jpeg_bits_get_u8 (bits); + + SWFDEC_DEBUG ( + "frame_length=%d depth=%d height=%d width=%d n_components=%d", length, + dec->depth, dec->height, dec->width, dec->n_components); + + if (dec->n_components * 3 + 8 != length) { + jpeg_decoder_error(dec, "inconsistent header"); + return; + } + + for (i = 0; i < dec->n_components; i++) { + dec->components[i].id = get_u8 (bits); + dec->components[i].h_sample = getbits (bits, 4); + dec->components[i].v_sample = getbits (bits, 4); + dec->components[i].quant_table = get_u8 (bits); + + SWFDEC_DEBUG ( + "[%d] id=%d h_sample=%d v_sample=%d quant_table=%d", i, + dec->components[i].id, dec->components[i].h_sample, + dec->components[i].v_sample, dec->components[i].quant_table); + } +} + +void +jpeg_decoder_start_of_scan (JpegDecoder * dec) +{ + JpegBits *bits = &dec->bits; + int length; + int i; + int spectral_start; + int spectral_end; + int approx_high; + int approx_low; + int n; + int tmp; + int n_components; + + SWFDEC_DEBUG ("start of scan"); + + length = jpeg_bits_get_u16_be (bits); + SWFDEC_DEBUG ("length=%d", length); + + n_components = jpeg_bits_get_u8 (bits); + n = 0; + dec->scan_h_subsample = 0; + dec->scan_v_subsample = 0; + for (i = 0; i < n_components; i++) { + int component_id; + int dc_table; + int ac_table; + int x; + int y; + int index; + int h_subsample; + int v_subsample; + int quant_index; + + component_id = jpeg_bits_get_u8 (bits); + tmp = jpeg_bits_get_u8 (bits); + dc_table = tmp >> 4; + ac_table = tmp & 0xf; + index = jpeg_decoder_find_component_by_id (dec, component_id); + + h_subsample = dec->components[index].h_sample; + v_subsample = dec->components[index].v_sample; + quant_index = dec->components[index].quant_table; + + for (y = 0; y < v_subsample; y++) { + for (x = 0; x < h_subsample; x++) { + dec->scan_list[n].component_index = index; + dec->scan_list[n].dc_table = dc_table; + dec->scan_list[n].ac_table = ac_table; + dec->scan_list[n].quant_table = quant_index; + dec->scan_list[n].x = x; + dec->scan_list[n].y = y; + dec->scan_list[n].offset + y * 8 * dec->components[index].rowstride + x * 8; + n++; + } + } + + dec->scan_h_subsample = MAX (dec->scan_h_subsample, h_subsample); + dec->scan_v_subsample = MAX (dec->scan_v_subsample, v_subsample); + + SWFDEC_DEBUG ("component %d: index=%d dc_table=%d ac_table=%d n=%d", + component_id, index, dc_table, ac_table, n); + } + dec->scan_list_length = n; + + spectral_start = jpeg_bits_get_u8 (bits); + spectral_end = jpeg_bits_get_u8 (bits); + SWFDEC_DEBUG ("spectral range [%d,%d]", spectral_start, spectral_end); + tmp = jpeg_bits_get_u8 (bits); + approx_high = tmp >> 4; + approx_low = tmp & 0xf; + SWFDEC_DEBUG ("approx range [%d,%d]", approx_low, approx_high); + + dec->x = 0; + dec->y = 0; + dec->dc[0] = dec->dc[1] = dec->dc[2] = dec->dc[3] = 128 * 8; +} + + + + + + + + + + + + +int +jpeg_decoder_addbits (JpegDecoder * dec, unsigned char *data, unsigned int len) +{ + unsigned int offset; offset = dec->bits.ptr - dec->data; @@ -821,7 +955,7 @@ jpeg_decoder_get_image_size (JpegDecoder int jpeg_decoder_get_component_ptr (JpegDecoder * dec, int id, - const unsigned char **image, int *rowstride) + unsigned char **image, int *rowstride) { int i; @@ -866,11 +1000,12 @@ jpeg_decoder_get_component_subsampling ( return 0; } +#if 0 int jpeg_decoder_parse (JpegDecoder * dec) { - bits_t *bits = &dec->bits; - bits_t b2; + JpegBits *bits = &dec->bits; + JpegBits b2; unsigned int x; unsigned int tag; int i; @@ -915,22 +1050,40 @@ jpeg_decoder_parse (JpegDecoder * dec) return 0; } +#endif /* misc helper functins */ +static char * +sprintbits (char *str, unsigned int bits, int n) +{ + int i; + int bit = 1 << (n - 1); + + for (i = 0; i < n; i++) { + str[i] = (bits & bit) ? '1' : '0'; + bit >>= 1; + } + str[i] = 0; + + return str; +} + static void -huffman_table_load_std_jpeg (JpegDecoder * dec) +jpeg_load_standard_huffman_tables (JpegDecoder * dec) { - bits_t b, *bits = &b; + JpegBits b, *bits = &b; - bits->ptr = std_tables; + bits->ptr = jpeg_standard_tables; bits->idx = 0; - bits->end = std_tables + sizeof (std_tables); + bits->end = jpeg_standard_tables + jpeg_standard_tables_size; - dec->dc_huff_table[0] = huffman_table_new_jpeg (bits); - dec->ac_huff_table[0] = huffman_table_new_jpeg (bits); - dec->dc_huff_table[1] = huffman_table_new_jpeg (bits); - dec->ac_huff_table[1] = huffman_table_new_jpeg (bits); + huffman_table_init_jpeg (&dec->dc_huff_table[0], bits); + huffman_table_init_jpeg (&dec->ac_huff_table[0], bits); + huffman_table_init_jpeg (&dec->dc_huff_table[1], bits); + huffman_table_init_jpeg (&dec->ac_huff_table[1], bits); } + + diff --git a/libswfdec/jpeg/jpeg.h b/libswfdec/jpeg/jpeg.h index f9fd194..49eaf6a 100644 --- a/libswfdec/jpeg/jpeg.h +++ b/libswfdec/jpeg/jpeg.h @@ -2,23 +2,75 @@ #ifndef _JPEG_DECODER_H_ #define _JPEG_DECODER_H_ +#include <stdint.h> + +#define JPEG_MARKER_STUFFED 0x00 +#define JPEG_MARKER_TEM 0x01 +#define JPEG_MARKER_RES 0x02 + +#define JPEG_MARKER_SOF_0 0xc0 +#define JPEG_MARKER_SOF_1 0xc1 +#define JPEG_MARKER_SOF_2 0xc2 +#define JPEG_MARKER_SOF_3 0xc3 +#define JPEG_MARKER_DEFINE_HUFFMAN_TABLES 0xc4 +#define JPEG_MARKER_SOF_5 0xc5 +#define JPEG_MARKER_SOF_6 0xc6 +#define JPEG_MARKER_SOF_7 0xc7 +#define JPEG_MARKER_JPG 0xc8 +#define JPEG_MARKER_SOF_9 0xc9 +#define JPEG_MARKER_SOF_10 0xca +#define JPEG_MARKER_SOF_11 0xcb +#define JPEG_MARKER_DEFINE_ARITHMETIC_CONDITIONING 0xcc +#define JPEG_MARKER_SOF_13 0xcd +#define JPEG_MARKER_SOF_14 0xce +#define JPEG_MARKER_SOF_15 0xcf + +#define JPEG_MARKER_RST_0 0xd0 +#define JPEG_MARKER_RST_1 0xd1 +#define JPEG_MARKER_RST_2 0xd2 +#define JPEG_MARKER_RST_3 0xd3 +#define JPEG_MARKER_RST_4 0xd4 +#define JPEG_MARKER_RST_5 0xd5 +#define JPEG_MARKER_RST_6 0xd6 +#define JPEG_MARKER_RST_7 0xd7 + +#define JPEG_MARKER_SOI 0xd8 +#define JPEG_MARKER_EOI 0xd9 +#define JPEG_MARKER_SOS 0xda +#define JPEG_MARKER_DEFINE_QUANTIZATION_TABLES 0xdb +#define JPEG_MARKER_DNL 0xdc +#define JPEG_MARKER_DEFINE_RESTART_INTERVAL 0xdd +#define JPEG_MARKER_DHP 0xde +#define JPEG_MARKER_EXP 0xdf +#define JPEG_MARKER_APP(x) (0xe0 + (x)) +#define JPEG_MARKER_JPG_(x) (0xf0 + (x)) +#define JPEG_MARKER_COMMENT 0xfe + +#define JPEG_MARKER_JFIF JPEG_MARKER_APP(0) + +#define JPEG_MARKER_IS_START_OF_FRAME(x) ((x)>=0xc0 && (x) <= 0xcf && (x)!=0xc4 && (x)!=0xc8 && (x)!=0xcc) +#define JPEG_MARKER_IS_APP(x) ((x)>=0xe0 && (x) <= 0xef) +#define JPEG_MARKER_IS_RESET(x) ((x)>=0xd0 && (x)<=0xd7) + + typedef struct _JpegDecoder JpegDecoder; JpegDecoder *jpeg_decoder_new(void); void jpeg_decoder_free(JpegDecoder *dec); int jpeg_decoder_addbits(JpegDecoder *dec, unsigned char *data, unsigned int len); -int jpeg_decoder_parse(JpegDecoder *dec); +int jpeg_decoder_decode (JpegDecoder *dec); int jpeg_decoder_get_image_size(JpegDecoder *dec, int *width, int *height); int jpeg_decoder_get_component_size(JpegDecoder *dec, int id, int *width, int *height); int jpeg_decoder_get_component_subsampling(JpegDecoder *dec, int id, int *h_subsample, int *v_subsample); int jpeg_decoder_get_component_ptr(JpegDecoder *dec, int id, - const unsigned char **image, int *rowstride); + unsigned char **image, int *rowstride); unsigned char *jpeg_decoder_get_argb_image (JpegDecoder *dec); - +int jpeg_decode_argb (uint8_t *data, int length, uint32_t **image, + int *width, int *height); #endif diff --git a/libswfdec/jpeg/jpeg_bits.c b/libswfdec/jpeg/jpeg_bits.c new file mode 100644 index 0000000..87700e9 --- /dev/null +++ b/libswfdec/jpeg/jpeg_bits.c @@ -0,0 +1,154 @@ + +#include <stdio.h> + +#include "jpeg_bits.h" + +/* FIXME */ +#define TRUE 1 +#define FALSE 0 + +int jpeg_bits_error (JpegBits *bits) +{ + return bits->error; +} + +int jpeg_bits_get_u8 (JpegBits *bits) +{ + if (bits->ptr < bits->end) { + return *bits->ptr++; + } + bits->error = TRUE; + return 0; +} + +void jpeg_bits_skip (JpegBits *bits, int n) +{ + bits->ptr += n; + if (bits->ptr > bits->end) { + bits->error = TRUE; + bits->ptr = bits->end; + } +} + +int jpeg_bits_get_u16_be (JpegBits *bits) +{ + int x; + + x = jpeg_bits_get_u8 (bits) << 8; + x |= jpeg_bits_get_u8 (bits); + + return x; +} + +int jpeg_bits_available (JpegBits *bits) +{ + return bits->end - bits->ptr; +} + +int bits_needbits(JpegBits *b, int n_bytes) +{ + if(b->ptr==NULL)return 1; + if(b->ptr + n_bytes > b->end)return 1; + + return 0; +} + +int getbit(JpegBits *b) +{ + int r; + + r = ((*b->ptr)>>(7-b->idx))&1; + + b->idx++; + if(b->idx>=8){ + b->ptr++; + b->idx = 0; + } + + return r; +} + +unsigned int getbits(JpegBits *b, int n) +{ + unsigned long r = 0; + int i; + + for(i=0;i<n;i++){ + r <<=1; + r |= getbit(b); + } + + return r; +} + +unsigned int peekbits(JpegBits *b, int n) +{ + JpegBits tmp = *b; + + return getbits(&tmp, n); +} + +int getsbits(JpegBits *b, int n) +{ + unsigned long r = 0; + int i; + + if(n==0)return 0; + r = -getbit(b); + for(i=1;i<n;i++){ + r <<=1; + r |= getbit(b); + } + + return r; +} + +unsigned int peek_u8(JpegBits *b) +{ + return *b->ptr; +} + +unsigned int get_u8(JpegBits *b) +{ + return *b->ptr++; +} + +unsigned int get_u16(JpegBits *b) +{ + unsigned int r; + + r = b->ptr[0] | (b->ptr[1]<<8); + b->ptr+=2; + + return r; +} + +unsigned int get_be_u16(JpegBits *b) +{ + unsigned int r; + + r = (b->ptr[0]<<8) | b->ptr[1]; + b->ptr+=2; + + return r; +} + +unsigned int get_u32(JpegBits *b) +{ + unsigned int r; + + r = b->ptr[0] | (b->ptr[1]<<8) | (b->ptr[2]<<16) | (b->ptr[3]<<24); + b->ptr+=4; + + return r; +} + +void syncbits(JpegBits *b) +{ + if(b->idx){ + b->ptr++; + b->idx=0; + } + +} + diff --git a/libswfdec/jpeg/jpeg_bits.h b/libswfdec/jpeg/jpeg_bits.h new file mode 100644 index 0000000..90cdcec --- /dev/null +++ b/libswfdec/jpeg/jpeg_bits.h @@ -0,0 +1,32 @@ + +#ifndef __BITS_H__ +#define __BITS_H__ + +typedef struct _JpegBits JpegBits; +struct _JpegBits { + unsigned char *ptr; + int idx; + unsigned char *end; + int error; +}; + +int jpeg_bits_error (JpegBits *bits); +int jpeg_bits_get_u8 (JpegBits *bits); +void jpeg_bits_skip (JpegBits *bits, int n); +int jpeg_bits_get_u16_be (JpegBits *bits); +int jpeg_bits_available (JpegBits *bits); + +int bits_needbits(JpegBits *b, int n_bytes); +int getbit(JpegBits *b); +unsigned int getbits(JpegBits *b, int n); +unsigned int peekbits(JpegBits *b, int n); +int getsbits(JpegBits *b, int n); +unsigned int peek_u8(JpegBits *b); +unsigned int get_u8(JpegBits *b); +unsigned int get_u16(JpegBits *b); +unsigned int get_be_u16(JpegBits *b); +unsigned int get_u32(JpegBits *b); +void syncbits(JpegBits *b); + +#endif + diff --git a/libswfdec/jpeg/jpeg_huffman.c b/libswfdec/jpeg/jpeg_huffman.c new file mode 100644 index 0000000..fffaeb0 --- /dev/null +++ b/libswfdec/jpeg/jpeg_huffman.c @@ -0,0 +1,171 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <swfdec_debug.h> +#include <liboil/liboil.h> + +#include <string.h> + +#include "jpeg_huffman.h" + +/* misc helper function definitions */ + +static char *sprintbits (char *str, unsigned int bits, int n); + + +//#define TRUE 1 +//#define FALSE 0 + +void +huffman_table_dump (HuffmanTable * table) +{ + unsigned int n_bits; + unsigned int code; + char str[33]; + int i; + HuffmanEntry *entry; + + SWFDEC_DEBUG ("dumping huffman table %p", table); + for (i = 0; i < table->len; i++) { + entry = table->entries + i; + n_bits = entry->n_bits; + code = entry->symbol >> (16 - n_bits); + sprintbits (str, code, n_bits); + SWFDEC_DEBUG ("%s --> %d", str, entry->value); + } +} + +void +huffman_table_init (HuffmanTable *table) +{ + memset (table, 0, sizeof(HuffmanTable)); +} + +void +huffman_table_add (HuffmanTable * table, uint32_t code, int n_bits, int value) +{ + HuffmanEntry *entry = table->entries + table->len; + + entry->value = value; + entry->symbol = code << (16 - n_bits); + entry->mask = 0xffff ^ (0xffff >> n_bits); + entry->n_bits = n_bits; + + table->len++; +} + +unsigned int +huffman_table_decode_jpeg (HuffmanTable * tab, JpegBits * bits) +{ + unsigned int code; + int i; + char str[33]; + HuffmanEntry *entry; + + code = peekbits (bits, 16); + for (i = 0; i < tab->len; i++) { + entry = tab->entries + i; + if ((code & entry->mask) == entry->symbol) { + code = getbits (bits, entry->n_bits); + sprintbits (str, code, entry->n_bits); + SWFDEC_DEBUG ("%s --> %d", str, entry->value); + return entry->value; + } + } + SWFDEC_ERROR ("huffman sync lost"); + + return -1; +} + +int +huffman_table_decode_macroblock (short *block, HuffmanTable * dc_tab, + HuffmanTable * ac_tab, JpegBits * bits) +{ + int r, s, x, rs; + int k; + char str[33]; + + memset (block, 0, sizeof (short) * 64); + + s = huffman_table_decode_jpeg (dc_tab, bits); + if (s < 0) + return -1; + x = getbits (bits, s); + if ((x >> (s - 1)) == 0) { + x -= (1 << s) - 1; + } + SWFDEC_DEBUG ("s=%d (block[0]=%d)", s, x); + block[0] = x; + + for (k = 1; k < 64; k++) { + rs = huffman_table_decode_jpeg (ac_tab, bits); + if (rs < 0) { + SWFDEC_DEBUG ("huffman error"); + return -1; + } + if (bits->ptr > bits->end) { + SWFDEC_DEBUG ("overrun"); + return -1; + } + s = rs & 0xf; + r = rs >> 4; + if (s == 0) { + if (r == 15) { + SWFDEC_DEBUG ("r=%d s=%d (skip 16)", r, s); + k += 15; + } else { + SWFDEC_DEBUG ("r=%d s=%d (eob)", r, s); + break; + } + } else { + k += r; + if (k >= 64) { + SWFDEC_ERROR ("macroblock overrun"); + return -1; + } + x = getbits (bits, s); + sprintbits (str, x, s); + if ((x >> (s - 1)) == 0) { + x -= (1 << s) - 1; + } + block[k] = x; + SWFDEC_DEBUG ("r=%d s=%d (%s -> block[%d]=%d)", r, s, str, k, x); + } + } + return 0; +} + +int +huffman_table_decode (HuffmanTable * dc_tab, HuffmanTable * ac_tab, + JpegBits * bits) +{ + int16_t zz[64]; + int ret; + + while (bits->ptr < bits->end) { + ret = huffman_table_decode_macroblock (zz, dc_tab, ac_tab, bits); + if (ret < 0) + return -1; + } + + return 0; +} + +/* misc helper functins */ + +static char * +sprintbits (char *str, unsigned int bits, int n) +{ + int i; + int bit = 1 << (n - 1); + + for (i = 0; i < n; i++) { + str[i] = (bits & bit) ? '1' : '0'; + bit >>= 1; + } + str[i] = 0; + + return str; +} diff --git a/libswfdec/jpeg/jpeg_huffman.h b/libswfdec/jpeg/jpeg_huffman.h new file mode 100644 index 0000000..9763e09 --- /dev/null +++ b/libswfdec/jpeg/jpeg_huffman.h @@ -0,0 +1,37 @@ + +#ifndef _HUFFMAN_H_ +#define _HUFFMAN_H_ + +#include <liboil/liboil-stdint.h> + +#include "jpeg_bits.h" + +typedef struct _HuffmanEntry HuffmanEntry; +typedef struct _HuffmanTable HuffmanTable; + +struct _HuffmanEntry { + unsigned int symbol; + unsigned int mask; + int n_bits; + unsigned char value; +}; + +struct _HuffmanTable { + int len; + HuffmanEntry entries[256]; +}; + + +void huffman_table_init(HuffmanTable *table); + +void huffman_table_dump(HuffmanTable *table); +void huffman_table_add(HuffmanTable *table, uint32_t code, int n_bits, + int value); +unsigned int huffman_table_decode_jpeg(HuffmanTable *tab, JpegBits *bits); +int huffman_table_decode_macroblock(short *block, HuffmanTable *dc_tab, + HuffmanTable *ac_tab, JpegBits *bits); +int huffman_table_decode(HuffmanTable *dc_tab, HuffmanTable *ac_tab, JpegBits *bits); + + +#endif + diff --git a/libswfdec/jpeg/jpeg_internal.h b/libswfdec/jpeg/jpeg_internal.h index 2ff43f2..3129374 100644 --- a/libswfdec/jpeg/jpeg_internal.h +++ b/libswfdec/jpeg/jpeg_internal.h @@ -3,26 +3,37 @@ #define _JPEG_INTERNAL_H_ #include "jpeg.h" -#include "huffman.h" -#include "bits.h" -#include "jpeg_debug.h" +#include "jpeg_huffman.h" +#include "jpeg_bits.h" +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif -//#define N_COMPONENTS 256 -#define JPEG_N_COMPONENTS 4 +#define JPEG_MAX_COMPONENTS 256 typedef struct _JpegScan JpegScan; +typedef struct _JpegQuantTable JpegQuantTable; -#define JPEG_ENTROPY_SEGMENT 0x0001 -#define JPEG_LENGTH 0x0002 +struct _JpegQuantTable { + int pq; + int16_t quantizer[64]; +}; struct _JpegDecoder { int width; int height; int depth; int n_components; - bits_t bits; + JpegBits bits; + int error; + char *error_message; + + int sof_type; int width_blocks; int height_blocks; @@ -34,18 +45,19 @@ struct _JpegDecoder { struct{ int id; - int h_oversample; - int v_oversample; + int h_sample; + int v_sample; + int quant_table; + int h_subsample; int v_subsample; - int quant_table; unsigned char *image; int rowstride; - } components[JPEG_N_COMPONENTS]; + } components[JPEG_MAX_COMPONENTS]; - short quant_table[4][64]; - HuffmanTable *dc_huff_table[4]; - HuffmanTable *ac_huff_table[4]; + JpegQuantTable quant_tables[4]; + HuffmanTable dc_huff_table[4]; + HuffmanTable ac_huff_table[4]; int scan_list_length; struct{ @@ -79,18 +91,18 @@ struct _JpegScan { /* jpeg.c */ -int jpeg_decoder_sof_baseline_dct(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_define_quant_table(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_define_huffman_table(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_sos(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_soi(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_eoi(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_application0(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_application_misc(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_comment(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_restart_interval(JpegDecoder *dec, bits_t *bits); -int jpeg_decoder_restart(JpegDecoder *dec, bits_t *bits); -void jpeg_decoder_decode_entropy_segment(JpegDecoder *dec, bits_t *bits); +int jpeg_decoder_sof_baseline_dct(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_define_quant_table(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_define_huffman_table(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_sos(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_soi(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_eoi(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_application0(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_application_misc(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_comment(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_restart_interval(JpegDecoder *dec, JpegBits *bits); +int jpeg_decoder_restart(JpegDecoder *dec, JpegBits *bits); +void jpeg_decoder_decode_entropy_segment(JpegDecoder *dec); #endif diff --git a/libswfdec/jpeg/jpeg_markers.h b/libswfdec/jpeg/jpeg_markers.h new file mode 100644 index 0000000..584cb23 --- /dev/null +++ b/libswfdec/jpeg/jpeg_markers.h @@ -0,0 +1,44 @@ + +#define JPEG_MARKER_STUFFED 0x00 +#define JPEG_MARKER_TEM 0x01 +#define JPEG_MARKER_RES 0x02 + +#define JPEG_MARKER_SOF_0 0xc0 +#define JPEG_MARKER_SOF_1 0xc1 +#define JPEG_MARKER_SOF_2 0xc2 +#define JPEG_MARKER_SOF_3 0xc3 +#define JPEG_MARKER_DHT 0xc4 +#define JPEG_MARKER_SOF_5 0xc5 +#define JPEG_MARKER_SOF_6 0xc6 +#define JPEG_MARKER_SOF_7 0xc7 +#define JPEG_MARKER_JPG 0xc8 +#define JPEG_MARKER_SOF_9 0xc9 +#define JPEG_MARKER_SOF_10 0xca +#define JPEG_MARKER_SOF_11 0xcb +#define JPEG_MARKER_DAC 0xcc +#define JPEG_MARKER_SOF_13 0xcd +#define JPEG_MARKER_SOF_14 0xce +#define JPEG_MARKER_SOF_15 0xcf + +#define JPEG_MARKER_RST_0 0xd0 +#define JPEG_MARKER_RST_1 0xd1 +#define JPEG_MARKER_RST_2 0xd2 +#define JPEG_MARKER_RST_3 0xd3 +#define JPEG_MARKER_RST_4 0xd4 +#define JPEG_MARKER_RST_5 0xd5 +#define JPEG_MARKER_RST_6 0xd6 +#define JPEG_MARKER_RST_7 0xd7 +#define JPEG_MARKER_SOI 0xd8 +#define JPEG_MARKER_EOI 0xd9 +#define JPEG_MARKER_SOS 0xda +#define JPEG_MARKER_DQT 0xdb +#define JPEG_MARKER_DNL 0xdc +#define JPEG_MARKER_DRI 0xdd +#define JPEG_MARKER_DHP 0xde +#define JPEG_MARKER_EXP 0xdf +#define JPEG_MARKER_APP(x) (0xe0 + (x)) +#define JPEG_MARKER_JPG_(x) (0xf0 + (x)) +#define JPEG_MARKER_COM 0xfe + +#define JPEG_MARKER_JFIF JPEG_MARKER_APP(0) + diff --git a/libswfdec/jpeg/jpeg_rgb_decoder.c b/libswfdec/jpeg/jpeg_rgb_decoder.c index 02af436..c3109de 100644 --- a/libswfdec/jpeg/jpeg_rgb_decoder.c +++ b/libswfdec/jpeg/jpeg_rgb_decoder.c @@ -8,18 +8,17 @@ #include <liboil/liboil.h> #include <liboil/liboildebug.h> -//#include <liboil/liboilcolorspace.h> +#define CLAMP(x,a,b) ((x)<(a) ? (a) : ((x)>(b) ? (b) : (x))) #define oil_argb(a,r,g,b) \ ((oil_clamp_255(a)<<24) | \ (oil_clamp_255(r)<<16) | \ (oil_clamp_255(g)<<8) | \ (oil_clamp_255(b)<<0)) -#define oil_clamp_255(x) oil_max(0,oil_min((x),255)) -#define oil_min(x,y) ((x)<(y)?(x):(y)) #define oil_max(x,y) ((x)>(y)?(x):(y)) +#define oil_min(x,y) ((x)<(y)?(x):(y)) +#define oil_clamp_255(x) oil_max(0,oil_min((x),255)) -#define CLAMP(x,a,b) ((x)<(a) ? (a) : ((x)>(b) ? (b) : (x))) static int16_t jfif_matrix[24] = { 0, 0, -8192, -8192, @@ -48,6 +47,25 @@ static void scanlinescale2_u8 (unsigned #endif +int jpeg_decode_argb (uint8_t *data, int length, uint32_t **image, + int *width, int *height) +{ + JpegDecoder *dec; + int ret; + + dec = jpeg_decoder_new(); + + jpeg_decoder_addbits (dec, data, length); + ret = jpeg_decoder_decode(dec); + + if (!ret) return FALSE; + + jpeg_decoder_get_image_size (dec, width, height); + *image = (uint32_t *)jpeg_decoder_get_argb_image (dec); + + return TRUE; +} + unsigned char * jpeg_decoder_get_argb_image (JpegDecoder *dec) { @@ -184,6 +202,7 @@ get_argb_422v (JpegDecoder *dec) int halfheight; int j; +OIL_ERROR("got here"); tmp = malloc (4 * dec->width * dec->height); tmp_u = malloc (dec->width); tmp_v = malloc (dec->width); diff --git a/libswfdec/jpeg/jpeg_rgb_decoder.h b/libswfdec/jpeg/jpeg_rgb_decoder.h new file mode 100644 index 0000000..08501ff --- /dev/null +++ b/libswfdec/jpeg/jpeg_rgb_decoder.h @@ -0,0 +1,18 @@ + +#ifndef _JPEG_RGB_DECODER_H_ +#define _JPEG_RGB_DECODER_H_ + +typedef struct jpeg_rgb_decoder_struct JpegRGBDecoder; + + +JpegRGBDecoder *jpeg_rgb_decoder_new(void); +void jpeg_rgb_decoder_free(JpegRGBDecoder *dec); +int jpeg_rgb_decoder_addbits(JpegRGBDecoder *dec, unsigned char *data, unsigned int len); +int jpeg_rgb_decoder_parse(JpegRGBDecoder *dec); +int jpeg_rgb_decoder_get_image(JpegRGBDecoder *dec, + unsigned char **image, int *rowstride, int *width, int *height); + + + +#endif + diff --git a/libswfdec/jpeg/jpeg_rgb_internal.h b/libswfdec/jpeg/jpeg_rgb_internal.h new file mode 100644 index 0000000..db8b80e --- /dev/null +++ b/libswfdec/jpeg/jpeg_rgb_internal.h @@ -0,0 +1,36 @@ + +#ifndef _JPEG_INTERNAL_H_ +#define _JPEG_INTERNAL_H_ + +#include "jpeg.h" +#include "jpeg_rgb_decoder.h" +#include "bits.h" + + +#define JPEG_DEBUG(n, format...) do{ \ + if((n)<=JPEG_DEBUG_LEVEL)jpeg_debug((n),format); \ +}while(0) +#define JPEG_DEBUG_LEVEL 4 + + +struct jpeg_rgb_decoder_struct { + JpegDecoder *dec; + + unsigned char *image; + int height, width; + + struct{ + unsigned char *image; + int rowstride; + int h_subsample; + int v_subsample; + int alloc; + }component[3]; +}; + +/* jpeg_rgb_decoder.c */ + + +#endif + + diff --git a/libswfdec/jpeg/jpeg_tables.c b/libswfdec/jpeg/jpeg_tables.c new file mode 100644 index 0000000..bd2d22a --- /dev/null +++ b/libswfdec/jpeg/jpeg_tables.c @@ -0,0 +1,54 @@ + +unsigned char jpeg_standard_tables[] = { + 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + + 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, + 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, + 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, + 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, + 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, + + 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, + + 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, + 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, + 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, + 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, + 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, +}; + +int jpeg_standard_tables_size = sizeof(jpeg_standard_tables); + diff --git a/libswfdec/jpeg/test.c b/libswfdec/jpeg/test.c deleted file mode 100644 index c5614ec..0000000 --- a/libswfdec/jpeg/test.c +++ /dev/null @@ -1,109 +0,0 @@ - -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#include "jpeg.h" - -/* getfile */ - -void *getfile (char *path, int *n_bytes); -static void dump_pgm (const unsigned char *ptr, int rowstride, int width, int height); - - -int -main (int argc, char *argv[]) -{ - unsigned char *data; - int len; - JpegDecoder *dec; - char *fn = "biglebowski.jpg"; - const unsigned char *ptr; - int rowstride; - int width; - int height; - - dec = jpeg_decoder_new (); - - if (argc > 1) - fn = argv[1]; - data = getfile (fn, &len); - - jpeg_decoder_addbits (dec, data, len); - jpeg_decoder_parse (dec); - - jpeg_decoder_get_component_ptr (dec, 1, &ptr, &rowstride); - jpeg_decoder_get_component_size (dec, 1, &width, &height); - - dump_pgm (ptr, rowstride, width, height); - jpeg_decoder_free (dec); - - return 0; -} - - - - - -/* getfile */ - -void * -getfile (char *path, int *n_bytes) -{ - int fd; - struct stat st; - void *ptr = NULL; - int ret; - - fd = open (path, O_RDONLY); - if (!fd) - return NULL; - - ret = fstat (fd, &st); - if (ret < 0) { - close (fd); - return NULL; - } - - ptr = malloc (st.st_size); - if (!ptr) { - close (fd); - return NULL; - } - - ret = read (fd, ptr, st.st_size); - if (ret != st.st_size) { - free (ptr); - close (fd); - return NULL; - } - - if (n_bytes) - *n_bytes = st.st_size; - - close (fd); - return ptr; -} - -static void -dump_pgm (const unsigned char *ptr, int rowstride, int width, int height) -{ - int x, y; - - printf ("P2\n"); - printf ("%d %d\n", width, height); - printf ("255\n"); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - printf ("%d ", ptr[x]); - if ((x & 15) == 15) { - printf ("\n"); - } - } - printf ("\n"); - ptr += rowstride; - } -} diff --git a/libswfdec/jpeg/test_rgb.c b/libswfdec/jpeg/test_rgb.c deleted file mode 100644 index c74c4de..0000000 --- a/libswfdec/jpeg/test_rgb.c +++ /dev/null @@ -1,129 +0,0 @@ - -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -#include <liboil/liboil.h> -//#include <liboil/liboilcolorspace.h> - -#define oil_argb_R(color) (((color)>>16)&0xff) -#define oil_argb_G(color) (((color)>>8)&0xff) -#define oil_argb_B(color) (((color)>>0)&0xff) - - - -#include "jpeg.h" - -/* getfile */ - -void *getfile (char *path, int *n_bytes); -static void dump_pnm (uint32_t *ptr, int rowstride, int width, int height); - -int -main (int argc, char *argv[]) -{ - unsigned char *data; - int len; - JpegDecoder *dec; - char *fn; - uint32_t *image; - int width; - int height; - - dec = jpeg_decoder_new (); - - if (argc < 2) { - printf("jpeg_rgb_test <file.jpg>\n"); - exit(1); - } - fn = argv[1]; - data = getfile (fn, &len); - - if (data == NULL) { - printf("cannot read file %s\n", fn); - exit(1); - } - - jpeg_decoder_addbits (dec, data, len); - jpeg_decoder_parse (dec); - - jpeg_decoder_get_image_size (dec, &width, &height); - - image = (uint32_t *)jpeg_decoder_get_argb_image (dec); - - dump_pnm (image, width*4, width, height); - - free (image); - - jpeg_decoder_free (dec); - free (data); - - return 0; -} - - - -/* getfile */ - -void * -getfile (char *path, int *n_bytes) -{ - int fd; - struct stat st; - void *ptr = NULL; - int ret; - - fd = open (path, O_RDONLY); - if (!fd) - return NULL; - - ret = fstat (fd, &st); - if (ret < 0) { - close (fd); - return NULL; - } - - ptr = malloc (st.st_size); - if (!ptr) { - close (fd); - return NULL; - } - - ret = read (fd, ptr, st.st_size); - if (ret != st.st_size) { - free (ptr); - close (fd); - return NULL; - } - - if (n_bytes) - *n_bytes = st.st_size; - - close (fd); - return ptr; -} - -static void -dump_pnm (uint32_t *ptr, int rowstride, int width, int height) -{ - int x, y; - - printf ("P3\n"); - printf ("%d %d\n", width, height); - printf ("255\n"); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - printf ("%d ", oil_argb_R(ptr[x])); - printf ("%d ", oil_argb_G(ptr[x])); - printf ("%d ", oil_argb_B(ptr[x])); - if ((x & 15) == 15) { - printf ("\n"); - } - } - printf ("\n"); - ptr += rowstride/4; - } -} diff --git a/libswfdec/swfdec_debug.h b/libswfdec/swfdec_debug.h index 60eec2a..565b2fa 100644 --- a/libswfdec/swfdec_debug.h +++ b/libswfdec/swfdec_debug.h @@ -22,6 +22,8 @@ #ifndef __SWFDEC_DEBUG_H__ #define __SWFDEC_DEBUG_H__ +#include <glib.h> + enum { SWFDEC_LEVEL_NONE = 0, SWFDEC_LEVEL_ERROR, diff --git a/libswfdec/swfdec_image.c b/libswfdec/swfdec_image.c index 6d15e27..3ca16b1 100644 --- a/libswfdec/swfdec_image.c +++ b/libswfdec/swfdec_image.c @@ -152,12 +152,13 @@ swfdec_image_jpeg_load (SwfdecImage *ima } jpeg_decoder_addbits (dec, image->raw_data->data, image->raw_data->length); - jpeg_decoder_parse (dec); + 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); 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; @@ -190,28 +191,15 @@ tag_func_define_bits_jpeg_2 (SwfdecSwfDe static void swfdec_image_jpeg2_load (SwfdecImage *image) { - JpegDecoder *dec; - - dec = jpeg_decoder_new (); + jpeg_decode_argb (image->raw_data->data, image->raw_data->length, + (void *)&image->data, &image->width, &image->height); - 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; - } - jpeg_decoder_addbits (dec, image->raw_data->data, - image->raw_data->length); - jpeg_decoder_parse (dec); - jpeg_decoder_get_image_size (dec, &image->width, &image->height); - if (image->width == 0 || image->height == 0) { - jpeg_decoder_free (dec); + if (image->data == NULL) { 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); @@ -240,7 +228,6 @@ tag_func_define_bits_jpeg_3 (SwfdecSwfDe static void swfdec_image_jpeg3_load (SwfdecImage *image) { - JpegDecoder *dec; SwfdecBits bits; SwfdecBuffer *buffer; int jpeg_length; @@ -252,26 +239,16 @@ swfdec_image_jpeg3_load (SwfdecImage *im if (buffer == NULL) return; - dec = jpeg_decoder_new (); - - if (buffer->data[0] != 0xff || buffer->data[1] != 0xd8) { - SWFDEC_ERROR("not jpeg %02x %02x", - buffer->data[0], buffer->data[1]); - jpeg_decoder_free (dec); - return; - } - jpeg_decoder_addbits (dec, buffer->data, buffer->length); + jpeg_decode_argb (buffer->data, buffer->length, + (void *)&image->data, &image->width, &image->height); swfdec_buffer_unref (buffer); - jpeg_decoder_parse (dec); - jpeg_decoder_get_image_size (dec, &image->width, &image->height); - if (image->width == 0 || image->height == 0) { - jpeg_decoder_free (dec); + + if (image->data == NULL) { 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); buffer = swfdec_bits_decompress (&bits, -1, image->width * image->height); if (buffer) { diff-tree 0e753f61522c8c732621630a05bec095a8cd01b3 (from parents) Merge: 468c231b9892101d792516da41d187eff2f943e8 ce83f3171f4400aa620464982ab266d567213be5 Author: Debian User <ds@gromit.(none)> Date: Tue Apr 17 10:43:55 2007 -0700 Merge branch 'master' of git+ssh://git.freedesktop.org/git/swfdec diff-tree 468c231b9892101d792516da41d187eff2f943e8 (from parents) Merge: b834f21d42bb9de27a3d7ae349403f112fd17a41 04113e5a83386f59140f248a817f7bf8d6728ddb Author: Debian User <ds@gromit.(none)> Date: Mon Apr 16 11:11:40 2007 -0700 Merge branch 'master' of git+ssh://git.freedesktop.org/git/swfdec diff-tree b834f21d42bb9de27a3d7ae349403f112fd17a41 (from parents) Merge: 798d47e5fe07d221d32575c7d34a27cb5c87a47f 26ee7f5d85a1d809daa20b2f67cf4cb99420ed66 Author: Debian User <ds@gromit.(none)> Date: Fri Apr 13 11:01:06 2007 -0700 Merge branch 'master' of git+ssh://git.freedesktop.org/git/swfdec diff-tree 798d47e5fe07d221d32575c7d34a27cb5c87a47f (from 25b8d26bdef82ba41b2e629398634545b7852ebd) Author: Debian User <ds@gromit.(none)> Date: Tue Apr 10 15:15:21 2007 -0700 Remove gtk_init(), since it fails if it can't find an X server diff --git a/doc/Makefile.am b/doc/Makefile.am index 4855ce8..558d819 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -25,7 +25,7 @@ DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sg DOC_SOURCE_DIR=../libswfdec # Extra options to pass to gtkdoc-scangobj. Not normally needed. -SCANGOBJ_OPTIONS=--type-init-func="swfdec_init(); gtk_init (NULL, NULL);" +SCANGOBJ_OPTIONS=--type-init-func="swfdec_init();" # Extra options to supply to gtkdoc-scan. # e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" diff-tree 25b8d26bdef82ba41b2e629398634545b7852ebd (from parents) Merge: b4f1f3a84d299933bbd9ade1aec8496eb1d960ec d2d5d5c377fd595bd8fef79d9773c9ed78410fc1 Author: Debian User <ds@gromit.(none)> Date: Tue Apr 10 15:21:54 2007 -0700 Merge branch 'master' of git+ssh://git.freedesktop.org/git/swfdec Conflicts: configure.ac diff-tree b4f1f3a84d299933bbd9ade1aec8496eb1d960ec (from bbf53a5c2060eadff2632674d2550a09719f41e1) Author: Debian User <ds@gromit.(none)> Date: Tue Apr 10 15:19:58 2007 -0700 Write better error messages for missing packages diff --git a/configure.ac b/configure.ac index 2159631..b72a0f7 100644 --- a/configure.ac +++ b/configure.ac @@ -61,10 +61,11 @@ AC_ARG_WITH(pkg-config-path, dnl Check for essential libraries first: dnl =================================== -GLIB_REQUIRES=2.0 -PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRES gobject-2.0 >= $GLIB_REQUIRES, HAVE_GLIB=yes, HAVE_GLIB=no) +GLIB_VER=2.0 +PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_VER gobject-2.0 >= $GLIB_VER, + HAVE_GLIB=yes, HAVE_GLIB=no) if test "$HAVE_GLIB" = "no"; then - AC_MSG_ERROR([cannot find GLIB-2.0, which is required for build]) + AC_MSG_ERROR([glib-2.0 >= $GLIB_VER and gobject-2.0 >= $GLIB_VER are required to build swfdec]) fi AC_SUBST(GLIB_LIBS) AC_SUBST(GLIB_CFLAGS) @@ -77,16 +78,17 @@ AC_SUBST(GLIB_MKENUMS) PKG_CHECK_MODULES(PANGO, pangocairo, HAVE_PANGO=yes, HAVE_PANGO=no) if test "$HAVE_PANGO" = "no"; then - AC_MSG_ERROR([cannot find pangocairo, which is required for build]) + AC_MSG_ERROR([pangocairo is required to build swfdec]) fi AC_SUBST(PANGO_LIBS) AC_SUBST(PANGO_CFLAGS) -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.8.0, HAVE_GTK=yes, HAVE_GTK=no) +GTK_VER=2.8.0 +PKG_CHECK_MODULES(GTK, gtk+-2.0 >= $GTK_VER, HAVE_GTK=yes, HAVE_GTK=no) AC_SUBST(GTK_LIBS) AC_SUBST(GTK_CFLAGS) if test "$HAVE_GTK" = "no"; then - AC_MSG_WARN([cannot find GTK+-2.0, player will be disabled]) + AC_MSG_WARN([gtk+-2.0 >= $GTK_VER not found, disabling build of player]) fi AM_CONDITIONAL(WITH_GTK,[test "$HAVE_GTK" != "no"]) @@ -125,18 +127,20 @@ AC_SUBST(AUDIO_LIBS) AC_SUBST(AUDIO_CFLAGS) AC_SUBST(AUDIO_TYPE) -PKG_CHECK_MODULES(LIBOIL, liboil-0.3 >= 0.3.1.1, HAVE_LIBOIL=yes, HAVE_LIBOIL=no) +LIBOIL_VER=0.3.1 +PKG_CHECK_MODULES(LIBOIL, liboil-0.3 >= $LIBOIL_VER, HAVE_LIBOIL=yes, HAVE_LIBOIL=no) AC_SUBST(LIBOIL_LIBS) AC_SUBST(LIBOIL_CFLAGS) if test "$HAVE_LIBOIL" = "no"; then - AC_MSG_ERROR([cannot find liboil-0.3, which is required for build]) + AC_MSG_ERROR([liboil-0.3 >= $LIBOIL_VER is required to build swfdec]) fi -PKG_CHECK_MODULES(CAIRO, cairo >= 1.2.0, HAVE_CAIRO=yes, HAVE_CAIRO=no) +CAIRO_VER=1.2.0 +PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VER, HAVE_CAIRO=yes, HAVE_CAIRO=no) AC_SUBST(CAIRO_LIBS) AC_SUBST(CAIRO_CFLAGS) if test "$HAVE_CAIRO" = "no"; then - AC_MSG_ERROR([cannot find cairo, which is required for build]) + AC_MSG_ERROR([cairo >= $CAIRO_VER is required to build swfdec]) fi AC_ARG_ENABLE(mad,
Possibly Parallel Threads
- libswfdec/jpeg libswfdec/swfdec_image.c
- libswfdec/jpeg
- 12 commits - configure.ac doc/Makefile.am doc/swfdec-sections.txt libswfdec/jpeg libswfdec/swfdec_as_array.c libswfdec/swfdec_as_object.c libswfdec/swfdec_as_strings.c libswfdec/swfdec_player.c libswfdec/swfdec_player.h libswfdec/swfdec_player_internal.h
- 6 commits - libswfdec-gtk/swfdec_gtk_widget.c libswfdec/jpeg libswfdec/swfdec_image.c
- 12 commits - configure.ac doc/swfdec-sections.txt libswfdec-gtk/swfdec_playback_alsa.c libswfdec/jpeg libswfdec/Makefile.am libswfdec/swfdec_amf.c libswfdec/swfdec_as_array.c libswfdec/swfdec_as_boolean.h libswfdec/swfdec_as_context.c