[Swfdec] 8 commits - configure.ac doc/Makefile.am libswfdec/jpeg libswfdec/swfdec_debug.h libswfdec/swfdec_image.c

David Schleef ds at kemper.freedesktop.org
Tue Apr 17 12:18:03 PDT 2007


 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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,


More information about the Swfdec mailing list