Some of the accompanying sources were based upon software from the
Independent JPEG Group, specifically from releases 3, 4 and 5. In accordance
with the terms of redistribution of that source code, see below the diffs
from the appropriate release to the earliest revision of each relevant
source code file in CVS, and see also the matching README file that you
should have received alongside this one. CVS may be used to derive the diffs
to other revisions.

BJGA, 2007-10-18


diff -U 3 -H -b -B -d -p -r -N -- jpeg-3/jconfig.h cvs/h/jconfig
--- jpeg-3/jconfig.h	1992-03-08 03:26:04.000000000 +0000
+++ cvs/h/jconfig	1996-11-05 09:45:08.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jconfig.h
  *
@@ -5,27 +22,7 @@
  * This file is part of the Independent JPEG Group's software.
  * For conditions of distribution and use, see the accompanying README file.
  *
- * This file contains preprocessor declarations that help customize
- * the JPEG software for a particular application, machine, or compiler.
- * Edit these declarations as needed (or add -D flags to the Makefile).
- */
-
-
-/*
- * These symbols indicate the properties of your machine or compiler.
- * The conditional definitions given may do the right thing already,
- * but you'd best look them over closely, especially if your compiler
- * does not handle full ANSI C.  An ANSI-compliant C compiler should
- * provide all the necessary features; __STDC__ is supposed to be
- * predefined by such compilers.
- */
-
-/*
- * HAVE_STDC is tested below to see whether ANSI features are available.
- * We avoid testing __STDC__ directly for arcane reasons of portability.
- * (On some compilers, __STDC__ is only defined if a switch is given,
- * but the switch also disables machine-specific features we need to get at.
- * In that case, -DHAVE_STDC in the Makefile is a convenient solution.)
+ * Seriously updated for use deep within RISC OS.
  */
 
 #ifdef __STDC__			/* if compiler claims to be ANSI, believe it */
@@ -52,153 +48,18 @@
 #define HAVE_UNSIGNED_SHORT
 #endif
 
-/* Define this if an ordinary "char" type is unsigned.
- * If you're not sure, leaving it undefined will work at some cost in speed.
- * If you defined HAVE_UNSIGNED_CHAR then it doesn't matter very much.
- */
-
-/* #define CHAR_IS_UNSIGNED */
-
-/* Define this if your compiler implements ">>" on signed values as a logical
- * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
- * which is the normal and rational definition.
- */
-
-/* #define RIGHT_SHIFT_IS_UNSIGNED */
-
-/* Define "void" as "char" if your compiler doesn't know about type void.
- * NOTE: be sure to define void such that "void *" represents the most general
- * pointer type, e.g., that returned by malloc().
- */
-
-/* #define void char */
-
-/* Define const as empty if your compiler doesn't know the "const" keyword. */
-/* (Even if it does, defining const as empty won't break anything.) */
-
-#ifndef HAVE_STDC		/* ANSI C and C++ compilers should know it. */
-#ifndef __cplusplus
-#define const
-#endif
-#endif
-
-/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
- * unless you are using a large-data memory model or 80386 flat-memory mode.
- * On less brain-damaged CPUs this symbol must not be defined.
- * (Defining this symbol causes large data structures to be referenced through
- * "far" pointers and to be allocated with a special version of malloc.)
- */
-
-#ifdef MSDOS
-#define NEED_FAR_POINTERS
-#endif
-
-
-/* The next three symbols only affect the system-dependent user interface
- * modules (jcmain.c, jdmain.c).  You can ignore these if you are supplying
- * your own user interface code.
- */
-
-/* Define this if you want to name both input and output files on the command
- * line, rather than using stdout and optionally stdin.  You MUST do this if
- * your system can't cope with binary I/O to stdin/stdout.  See comments at
- * head of jcmain.c or jdmain.c.
- */
-
-#ifdef MSDOS			/* two-file style is needed for PCs */
-#define TWO_FILE_COMMANDLINE
-#endif
-#ifdef THINK_C			/* needed for Macintosh too */
-#define TWO_FILE_COMMANDLINE
-#endif
-
-/* Define this if your system needs explicit cleanup of temporary files.
- * This is crucial under MS-DOS, where the temporary "files" may be areas
- * of extended memory; on most other systems it's not as important.
- */
-
-#ifdef MSDOS
-#define NEED_SIGNAL_CATCHER
-#endif
-
-/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
- * This is necessary on systems that distinguish text files from binary files,
- * and is harmless on most systems that don't.  If you have one of the rare
- * systems that complains about the "b" spec, define this symbol.
- */
-
-/* #define DONT_USE_B_MODE */
-
-
-/* If you're getting bored, that's the end of the symbols you HAVE to
- * worry about.  Go fix the makefile and compile.
- */
-
-
-/* On a few systems, type boolean and/or macros FALSE, TRUE may appear
- * in standard header files.  Or you may have conflicts with application-
- * specific header files that you want to include together with these files.
- * In that case you need only comment out these definitions.
- */
-
 typedef int boolean;
+#ifndef BOOL
+  #define BOOL int
+#endif
 #undef FALSE			/* in case these macros already exist */
 #undef TRUE
 #define FALSE	0		/* values of boolean */
 #define TRUE	1
 
-/* This defines the size of the I/O buffers for entropy compression
- * and decompression; you could reduce it if memory is tight.
- */
-
-#define JPEG_BUF_SIZE	4096 /* bytes */
-
-
-
 /* These symbols determine the JPEG functionality supported. */
 
-/*
- * These defines indicate whether to include various optional functions.
- * Undefining some of these symbols will produce a smaller but less capable
- * program file.  Note that you can leave certain source files out of the
- * compilation/linking process if you've #undef'd the corresponding symbols.
- * (You may HAVE to do that if your compiler doesn't like null source files.)
- */
-
-/* Arithmetic coding is unsupported for legal reasons.  Complaints to IBM. */
-#undef  ARITH_CODING_SUPPORTED	/* Arithmetic coding back end? */
-#define MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
-#define ENTROPY_OPT_SUPPORTED	/* Optimization of entropy coding parms? */
-#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing during decoding? */
-#define QUANT_1PASS_SUPPORTED	/* 1-pass color quantization? */
-#define QUANT_2PASS_SUPPORTED	/* 2-pass color quantization? */
-/* these defines indicate which JPEG file formats are allowed */
 #define JFIF_SUPPORTED		/* JFIF or "raw JPEG" files */
-#undef  JTIFF_SUPPORTED		/* JPEG-in-TIFF (not yet implemented) */
-/* these defines indicate which image (non-JPEG) file formats are allowed */
-#define GIF_SUPPORTED		/* GIF image file format */
-/* #define RLE_SUPPORTED */	/* RLE image file format (by default, no) */
-#define PPM_SUPPORTED		/* PPM/PGM image file format */
-#define TARGA_SUPPORTED		/* Targa image file format */
-#undef  TIFF_SUPPORTED		/* TIFF image file format (not yet impl.) */
-
-/* more capability options later, no doubt */
-
-
-/*
- * Define exactly one of these three symbols to indicate whether you want
- * 8-bit, 12-bit, or 16-bit sample (pixel component) values.  8-bit is the
- * default and is nearly always the right thing to use.  You can use 12-bit if
- * you need to support image formats with more than 8 bits of resolution in a
- * color value.  16-bit should only be used for the lossless JPEG mode (not
- * currently supported).  Note that 12- and 16-bit values take up twice as
- * much memory as 8-bit!
- * Note: if you select 12- or 16-bit precision, it is dangerous to turn off
- * ENTROPY_OPT_SUPPORTED.  The standard Huffman tables are only good for 8-bit
- * precision, so jchuff.c normally uses entropy optimization to compute
- * usable tables for higher precision.  If you don't want to do optimization,
- * you'll have to supply different default Huffman tables.
- */
 
 #define EIGHT_BIT_SAMPLES
 #undef  TWELVE_BIT_SAMPLES
@@ -295,8 +154,11 @@ typedef unsigned int JSAMPLE;
  * more will cost you a BIG hit of memory, less will give wrong answers.
  */
 
+#ifdef RISCOS
+typedef int JCOEF;
+#else
 typedef short JCOEF;
-
+#endif
 
 /* The remaining typedefs are used for various table entries and so forth.
  * They must be at least as wide as specified; but making them too big
@@ -334,6 +196,11 @@ typedef short INT16;
 /* INT32 must hold signed 32-bit values; if your machine happens */
 /* to have 64-bit longs, you might want to change this. */
 
-#ifndef XMD_H			/* X11/xmd.h correctly defines INT32 */
-typedef long INT32;
+#ifdef RISCOS
+typedef int INT32;
+typedef unsigned int UINT32;
+#else
+  #ifndef XMD_H                 /* X11/xmd.h correctly defines INT32 */
+  typedef long INT32;
+  #endif
 #endif
diff -U 3 -H -b -B -d -p -r -N -- jpeg-4/jdcolor.c cvs/c/jdcolor
--- jpeg-4/jdcolor.c	1992-08-23 20:59:39.000000000 +0100
+++ cvs/c/jdcolor	1996-11-05 09:45:02.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jdcolor.c
  *
diff -U 3 -H -b -B -d -p -r -N -- jpeg-3/jdhuff.c cvs/c/jdhuff
--- jpeg-3/jdhuff.c	1992-03-07 00:58:45.000000000 +0000
+++ cvs/c/jdhuff	1996-11-05 09:45:02.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jdhuff.c
  *
@@ -8,21 +25,31 @@
  * This file contains Huffman entropy decoding routines.
  * These routines are invoked via the methods entropy_decode
  * and entropy_decoder_init/term.
+
+ * Not only hacked for use deep within RISC OS, but bits of release 4 transplanted in too.
  */
+#undef FILE_
+#define FILE_ (10000)
 
 #include "jinclude.h"
 
 
 /* Static variables to avoid passing 'round extra parameters */
 
+#if 0
 static decompress_info_ptr dcinfo;
 
 static INT32 get_buffer;	/* current bit-extraction buffer */
 static int bits_left;		/* # of unused bits in it */
+#endif
+/* These have been moved to the cinfo structure, so that there are no
+static variables. */
 
+LOCAL int
+huff_DECODE_buildshortcut (decompress_info_ptr cinfo, HUFF_TBL * htbl); /* forward reference */
 
 LOCAL void
-fix_huff_tbl (HUFF_TBL * htbl)
+fix_huff_tbl (decompress_info_ptr cinfo, HUFF_TBL * htbl)
 /* Compute derived values for a Huffman table */
 {
   int p, i, l, si;
@@ -64,74 +91,122 @@ fix_huff_tbl (HUFF_TBL * htbl)
   for (l = 1; l <= 16; l++) {
     if (htbl->bits[l]) {
       htbl->valptr[l] = p;	/* huffval[] index of 1st sym of code len l */
-      htbl->mincode[l] = huffcode[p]; /* minimum code of length l */
+      htbl->valptr[l] -= huffcode[p]; /* subtract value in old 'mincode' table, for speed later */
+      /* htbl->mincode[l] = huffcode[p]; */ /* minimum code of length l */
       p += htbl->bits[l];
       htbl->maxcode[l] = huffcode[p-1];	/* maximum code of length l */
     } else {
       htbl->maxcode[l] = -1;
     }
   }
-  htbl->maxcode[17] = 0xFFFFFL;	/* ensures huff_DECODE terminates */
-}
+  htbl->maxcode[17] = 0xFFFFF /*0xFFFFFL*/; /* ensures huff_DECODE terminates */
 
+  /* Now we build the shortcut table. Using the above, reading a huffman code
+  proceeds by reading bits one at a time, and looking up the result in a table
+  to see if it is big enough yet. The shortcut table reads the next 8 bits
+  of input, and uses this to index a table that says what to do. This table
+  is constructed by trying all 256 possibles. */
+  {
+    int i; /* index into shortcut table */
+    int h; /* the code you read */
+
+    for (i = 0; i < 256; i++) /* for each element of shortcut table */
+    {
+      cinfo->bits_left = 32;
+      cinfo->get_buffer = i << 24; /* fake the input bits */
+      h = huff_DECODE_buildshortcut(cinfo, htbl); /* the C-coded decoding doesn't use the shortcut table - we haven't built it yet! */
+      if (cinfo->bits_left < 24) /* code longer than 8 bits */
+        htbl->shortcut[i] = -1;
+      else
+      {
+        assert(h >= 0, ERROR_FATAL);
+        htbl->shortcut[i] = ((32 - cinfo->bits_left) << 24) | h; /* remember size and value */
+      }
+    }
+    cinfo->bits_left = 0;
+    cinfo->get_buffer = 0;
+  }
+}
 
 /* Extract the next N bits from the input stream (N <= 15) */
 
 LOCAL int
-get_bits (int nbits)
+get_bits (decompress_info_ptr cinfo, int nbits)
 {
   int result;
   
-  while (nbits > bits_left) {
-    int c = JGETC(dcinfo);
+  while (nbits > cinfo->bits_left) {
+    int c = JGETC(cinfo);
     
-    get_buffer <<= 8;
-    get_buffer |= c;
-    bits_left += 8;
+    cinfo->get_buffer <<= 8;
+    cinfo->get_buffer |= c;
+    cinfo->bits_left += 8;
     /* If it's 0xFF, check and discard stuffed zero byte */
     if (c == 0xff) {
-      c = JGETC(dcinfo);  /* Byte stuffing */
+      c = JGETC(cinfo);  /* Byte stuffing */
       if (c != 0)
-	ERREXIT1(dcinfo->emethods,
+        ERREXIT1(cinfo->emethods,
 		 "Unexpected marker 0x%02x in compressed data", c);
     }
   }
   
-  bits_left -= nbits;
-  result = ((int) (get_buffer >> bits_left)) & ((1 << nbits) - 1);
+  cinfo->bits_left -= nbits;
+  result = ((int) (cinfo->get_buffer >> cinfo->bits_left)) & ((1 << nbits) - 1);
   return result;
 }
 
 /* Macro to make things go at some speed! */
 
-#define get_bit()	(bits_left ? \
-			 ((int) (get_buffer >> (--bits_left))) & 1 : \
-			 get_bits(1))
-
+#define get_bit(cinfo)       (cinfo->bits_left ? \
+                             ((int) (cinfo->get_buffer >> (--cinfo->bits_left))) & 1 : \
+                             get_bits(cinfo, 1))
 
 /* Figure F.16: extract next coded symbol from input stream */
   
+/* Altered version of huff_DECODE for use in constructing the shortcut table */
 LOCAL int
-huff_DECODE (HUFF_TBL * htbl)
+huff_DECODE_buildshortcut (decompress_info_ptr cinfo, HUFF_TBL * htbl)
 {
   int l, p;
   INT32 code;
   
-  code = get_bit();
+  code = get_bit(cinfo);
+  l = 1;
+  while (code > htbl->maxcode[l] && l <= 8) {
+    code = (code << 1) + get_bit(cinfo);
+    l++;
+  }
+  if (l > 8) return -1;
+  p = (int) (htbl->valptr[l] + (code /* - htbl->mincode[l] */));
+  return (int) htbl->huffval[p];
+}
+
+#ifndef ASMHUFF
+
+LOCAL int
+huff_DECODE (decompress_info_ptr cinfo, HUFF_TBL * htbl)
+{
+  int l, p;
+  INT32 code;
+
+  code = get_bit(cinfo);
   l = 1;
   while (code > htbl->maxcode[l]) {
-    code = (code << 1) + get_bit();
+    code = (code << 1) + get_bit(cinfo);
     l++;
   }
 
   /* With garbage input we may reach the sentinel value l = 17. */
 
   if (l > 16) {
-    ERREXIT(dcinfo->emethods, "Corrupted data in JPEG file");
+    ERREXIT(cinfo->emethods, "Corrupted data in JPEG file");
   }
 
-  p = (int) (htbl->valptr[l] + (code - htbl->mincode[l]));
-  
+  p = (int) (htbl->valptr[l] + (code /* - htbl->mincode[l] */));
+/*
+  tracef("Decoded huffman value=%i next_byte=0x%x bits_left=%i get_buf=0x%x.\n"
+  _ htbl->huffval[p] _ (int)cinfo->next_input_byte _ cinfo->bits_left _ cinfo->get_buffer);
+*/
   return (int) htbl->huffval[p];
 }
 
@@ -146,10 +220,59 @@ huff_DECODE (HUFF_TBL * htbl)
 
 
 /* Decode a single block's worth of coefficients */
-/* Note that only the difference is returned for the DC coefficient */
+
+/* ZAG[i] is the natural-order position of the i'th element of zigzag order.
+ * If the incoming data is corrupted, huff_decode_mcu could attempt to
+ * reference values beyond the end of the array.  To avoid a wild store,
+ * we put some extra zeroes after the real entries.
+ */
+
+#if 0
+
+static const short ZAG[DCTSIZE2+16] = {
+  0,  1,  8, 16,  9,  2,  3, 10,
+ 17, 24, 32, 25, 18, 11,  4,  5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13,  6,  7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+  0,  0,  0,  0,  0,  0,  0,  0, /* extra entries in case k>63 below */
+  0,  0,  0,  0,  0,  0,  0,  0
+};
+
+/* 2-digit ones in decimal: */
+#define ZAG (\
+"\x00\x01\x08\x16\x09\x02\x03\x10" \
+"\x17\x24\x32\x25\x18\x11\x04\x05" \
+"\x12\x19\x26\x33\x40\x48\x41\x34" \
+"\x27\x20\x13\x06\x07\x14\x21\x28" \
+"\x35\x42\x49\x56\x57\x50\x43\x36" \
+"\x29\x22\x15\x23\x30\x37\x44\x51" \
+"\x58\x59\x52\x45\x38\x31\x39\x46" \
+"\x53\x60\x61\x54\x47\x55\x62\x63" \
+"\x00\x00\x00\x00\x00\x00\x00\x00" \
+"\x00\x00\x00\x00\x00\x00\x00\x00")
+
+#else
+
+#define ZAG (\
+"\x00\x01\x08\x10\x09\x02\x03\x0a" \
+"\x11\x18\x20\x19\x12\x0b\x04\x05" \
+"\x0c\x13\x1a\x21\x28\x30\x29\x22" \
+"\x1b\x14\x0d\x06\x07\x0e\x15\x1c" \
+"\x23\x2a\x31\x38\x39\x32\x2b\x24" \
+"\x1d\x16\x0f\x17\x1e\x25\x2c\x33" \
+"\x3a\x3b\x34\x2d\x26\x1f\x27\x2e" \
+"\x35\x3c\x3d\x36\x2f\x37\x3e\x3f" \
+"\x00\x00\x00\x00\x00\x00\x00\x00" \
+"\x00\x00\x00\x00\x00\x00\x00\x00")
+
+#endif
 
 LOCAL void
-decode_one_block (JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl)
+decode_one_block (decompress_info_ptr cinfo, JBLOCK block, HUFF_TBL *dctbl, HUFF_TBL *actbl, QUANT_TBL_PTR quanttbl, int *last_dc_val)
 {
   int s, k, r, n;
 
@@ -159,25 +282,31 @@ decode_one_block (JBLOCK block, HUFF_TBL
   
   /* Section F.2.2.1: decode the DC coefficient difference */
 
-  s = huff_DECODE(dctbl);
+  s = huff_DECODE(cinfo, dctbl);
   if (s) {
-    r = get_bits(s);
+    r = get_bits(cinfo, s);
     s = huff_EXTEND(r, s);
   }
-  block[0] = s;
+  /* Convert DC difference to actual value, update last_dc_val */
+  s += *last_dc_val;
+  *last_dc_val = (JCOEF) s;
+  /* Descale and output the DC coefficient (assumes ZAG[0] = 0) */
+  block[0] = (JCOEF) (((JCOEF) s) * quanttbl[0]);
 
   /* Section F.2.2.2: decode the AC coefficients */
   
   for (k = 1; k < DCTSIZE2; k++) {
-    r = huff_DECODE(actbl);
+    r = huff_DECODE(cinfo, actbl);
     
     s = r & 15;
     n = r >> 4;
     
     if (s) {
       k += n;
-      r = get_bits(s);
-      block[k] = huff_EXTEND(r, s);
+      r = get_bits(cinfo, s);
+      s = huff_EXTEND(r, s);
+      /* Descale coefficient and output in natural (dezigzagged) order */
+      block[ZAG[k]] = (JCOEF) (((JCOEF) s) * quanttbl[k]);
     } else {
       if (n != 15)
 	break;
@@ -186,140 +315,81 @@ decode_one_block (JBLOCK block, HUFF_TBL
   }
 }
 
-
-/*
- * Initialize for a Huffman-compressed scan.
- * This is invoked after reading the SOS marker.
- */
-
-METHODDEF void
-huff_decoder_init (decompress_info_ptr cinfo)
-{
-  short ci;
-  jpeg_component_info * compptr;
-
-  /* Initialize static variables */
-  dcinfo = cinfo;
-  bits_left = 0;
-
-  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
-    compptr = cinfo->cur_comp_info[ci];
-    /* Make sure requested tables are present */
-    if (cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no] == NULL ||
-	cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no] == NULL)
-      ERREXIT(cinfo->emethods, "Use of undefined Huffman table");
-    /* Compute derived values for Huffman tables */
-    /* We may do this more than once for same table, but it's not a big deal */
-    fix_huff_tbl(cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no]);
-    fix_huff_tbl(cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
-    /* Initialize DC predictions to 0 */
-    cinfo->last_dc_val[ci] = 0;
-  }
-
-  /* Initialize restart stuff */
-  cinfo->restarts_to_go = cinfo->restart_interval;
-  cinfo->next_restart_num = 0;
-}
-
-
-/*
- * Check for a restart marker & resynchronize decoder.
- */
-
 LOCAL void
-process_restart (decompress_info_ptr cinfo)
+skip_one_block (decompress_info_ptr cinfo, HUFF_TBL *dctbl, HUFF_TBL *actbl, int *last_dc_val)
+/* Like decode_one_block in its effect on *last_dc_val and the source of the input stream,
+but no block of coefficients need be produced. */
 {
-  int c, nbytes;
-  short ci;
+  int s, k, r, n;
 
-  /* Throw away any partial unread byte */
-  bits_left = 0;
+  /* Section F.2.2.1: decode the DC coefficient difference */
 
-  /* Scan for next JPEG marker */
-  nbytes = 0;
-  do {
-    do {			/* skip any non-FF bytes */
-      nbytes++;
-      c = JGETC(cinfo);
-    } while (c != 0xFF);
-    do {			/* skip any duplicate FFs */
-      nbytes++;
-      c = JGETC(cinfo);
-    } while (c == 0xFF);
-  } while (c == 0);		/* repeat if it was a stuffed FF/00 */
+  s = huff_DECODE(cinfo, dctbl);
+  if (s) {
+    r = get_bits(cinfo, s);
+    s = huff_EXTEND(r, s);
+  }
+  /* Convert DC difference to actual value, update last_dc_val */
+  s += *last_dc_val;
+  *last_dc_val = (JCOEF) s;
 
-  if (c != (RST0 + cinfo->next_restart_num))
-    ERREXIT2(cinfo->emethods, "Found 0x%02x marker instead of RST%d",
-	     c, cinfo->next_restart_num);
+  /* Section F.2.2.2: decode the AC coefficients */
 
-  if (nbytes != 2)
-    TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before RST%d",
-	     nbytes-2, cinfo->next_restart_num);
-  else
-    TRACEMS1(cinfo->emethods, 2, "RST%d", cinfo->next_restart_num);
+  for (k = 1; k < DCTSIZE2; k++) {
+    r = huff_DECODE(cinfo, actbl);
 
-  /* Re-initialize DC predictions to 0 */
-  for (ci = 0; ci < cinfo->comps_in_scan; ci++)
-    cinfo->last_dc_val[ci] = 0;
+    s = r & 15;
+    n = r >> 4;
 
-  /* Update restart state */
-  cinfo->restarts_to_go = cinfo->restart_interval;
-  cinfo->next_restart_num++;
-  cinfo->next_restart_num &= 7;
+    if (s) {
+      k += n;
+      r = get_bits(cinfo, s);
+    } else {
+      if (n != 15)
+        break;
+      k += 15;
+    }
+  }
 }
 
-
-/*
- * Decode and return one MCU's worth of Huffman-compressed coefficients.
- */
-
-METHODDEF void
-huff_decode (decompress_info_ptr cinfo, JBLOCK *MCU_data)
+LOCAL void
+huff_decode_blocks(decompress_info_ptr cinfo, JBLOCK block,
+                   HUFF_TBL *dctbl, HUFF_TBL *actbl, QUANT_TBL_PTR quanttbl,
+                   int *last_dc_val, int nblocks)
 {
-  short blkn, ci;
-  jpeg_component_info * compptr;
-
-  /* Account for restart interval, process restart marker if needed */
-  if (cinfo->restart_interval) {
-    if (cinfo->restarts_to_go == 0)
-      process_restart(cinfo);
-    cinfo->restarts_to_go--;
+  while (nblocks > 0)
+  {
+    decode_one_block(cinfo,block,dctbl,actbl,quanttbl,last_dc_val);
+    nblocks--;
   }
+}
 
-  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
-    ci = cinfo->MCU_membership[blkn];
-    compptr = cinfo->cur_comp_info[ci];
-    decode_one_block(MCU_data[blkn],
-		     cinfo->dc_huff_tbl_ptrs[compptr->dc_tbl_no],
-		     cinfo->ac_huff_tbl_ptrs[compptr->ac_tbl_no]);
-    /* Convert DC difference to actual value, update last_dc_val */
-    MCU_data[blkn][0] += cinfo->last_dc_val[ci];
-    cinfo->last_dc_val[ci] = MCU_data[blkn][0];
+extern void
+huff_skip_blocks (decompress_info_ptr cinfo, JBLOCK block,
+                  HUFF_TBL *dctbl, HUFF_TBL *actbl,
+                  QUANT_TBL_PTR quanttbl, int *last_dc_val, int nblocks)
+{
+  block=block; /* unused */
+  quanttbl=quanttbl; /* unused */
+  while (nblocks > 0)
+  {
+    skip_one_block(cinfo,dctbl,actbl,last_dc_val);
+    nblocks--;
   }
 }
 
+#endif
 
 /*
- * Finish up at the end of a Huffman-compressed scan.
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after reading the SOS marker.
  */
 
 METHODDEF void
-huff_decoder_term (decompress_info_ptr cinfo)
+huff_decoder_init (decompress_info_ptr cinfo)
 {
-  /* No work needed */
-}
-
-
-/*
- * The method selection routine for Huffman entropy decoding.
- */
+  /* Initialize static variables */
+/*  dcinfo = cinfo; */
+  cinfo->bits_left = 0;
 
-GLOBAL void
-jseldhuffman (decompress_info_ptr cinfo)
-{
-  if (! cinfo->arith_code) {
-    cinfo->methods->entropy_decoder_init = huff_decoder_init;
-    cinfo->methods->entropy_decode = huff_decode;
-    cinfo->methods->entropy_decoder_term = huff_decoder_term;
-  }
 }
diff -U 3 -H -b -B -d -p -r -N -- jpeg-3/jinclude.h cvs/h/jinclude
--- jpeg-3/jinclude.h	1992-03-08 03:01:21.000000000 +0000
+++ cvs/h/jinclude	1996-11-05 09:45:08.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jinclude.h
  *
@@ -12,6 +29,10 @@
  * system include files.
  */
 
+/* RISCOS thing - only allow this file to be included once */
+#ifndef jinclude__
+#define jinclude__
+
 
 /*
  * Normally the __STDC__ macro can be taken as indicating that the system
@@ -27,16 +48,6 @@
 #endif
 
 /*
- * <stdio.h> is included to get the FILE typedef and NULL macro.
- * Note that the core portable-JPEG files do not actually do any I/O
- * using the stdio library; only the user interface, error handler,
- * and file reading/writing modules invoke any stdio functions.
- * (Well, we did cheat a bit in jmemmgr.c, but only if MEM_STATS is defined.)
- */
-
-#include <stdio.h>
-
-/*
  * We need the size_t typedef, which defines the parameter type of malloc().
  * In an ANSI-conforming implementation this is provided by <stdio.h>,
  * but on non-ANSI systems it's more likely to be in <sys/types.h>.
@@ -62,17 +73,6 @@
 #define SIZEOF(object)	((size_t) sizeof(object))
 
 /*
- * fread() and fwrite() are always invoked through these macros.
- * On some systems you may need to twiddle the argument casts.
- * CAUTION: argument order is different from underlying functions!
- */
-
-#define JFREAD(file,buf,sizeofbuf)  \
-  ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
-#define JFWRITE(file,buf,sizeofbuf)  \
-  ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
-
-/*
  * We need the memcpy() and strcmp() functions, plus memory zeroing.
  * ANSI and System V implementations declare these in <string.h>.
  * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
@@ -81,17 +81,17 @@
  */
 
 #ifdef INCLUDES_ARE_ANSI
-#include <string.h>
-#define MEMZERO(voidptr,size)	memset((voidptr), 0, (size))
+  #include <string.h>
+  #define MEMZERO(voidptr,size)   memset((voidptr), 0, (size))
 #else /* not ANSI */
-#ifdef BSD
-#include <strings.h>
-#define MEMZERO(voidptr,size)	bzero((voidptr), (size))
-#define memcpy(dest,src,size)	bcopy((src), (dest), (size))
-#else /* not BSD, assume Sys V or compatible */
-#include <string.h>
-#define MEMZERO(voidptr,size)	memset((voidptr), 0, (size))
-#endif /* BSD */
+  #ifdef BSD
+    #include <strings.h>
+    #define MEMZERO(voidptr,size)   bzero((voidptr), (size))
+    #define memcpy(dest,src,size)   bcopy((src), (dest), (size))
+  #else /* not BSD, assume Sys V or compatible */
+    #include <string.h>
+    #define MEMZERO(voidptr,size)   memset((voidptr), 0, (size))
+  #endif /* BSD */
 #endif /* ANSI */
 
 
@@ -100,3 +100,29 @@
 #include "jconfig.h"
 
 #include "jpegdata.h"
+
+/* Assembler coded stuff */
+#ifdef ASMHUFF
+extern void
+asm_huff_decode_blocks(decompress_info_ptr cinfo, JBLOCK block,
+                   HUFF_TBL *dctbl, HUFF_TBL *actbl, QUANT_TBL_PTR quanttbl,
+                   int *last_dc_val, int nblocks);
+
+extern void
+asm_huff_skip_blocks(decompress_info_ptr cinfo, JBLOCK block,
+                 HUFF_TBL *dctbl, HUFF_TBL *actbl, QUANT_TBL_PTR quanttbl,
+                 int *last_dc_val, int nblocks);
+
+extern void panic_exit(int i);
+#endif
+
+extern void asm_j_rev_dct(decompress_info_ptr cinfo, JBLOCK block, int count);
+extern void asm_mono_convert_block(JBLOCK jblock, int *outptr, int outoffset);
+extern void asm_colour_convert_block(JBLOCK jblock, int *outptr, int outoffset);
+extern void asm_colour_convert_block_16(JBLOCK jblock, short int *outptr, int outoffset);
+extern void asm_colour_convert_block_8(JBLOCK jblock, char *outptr, int outoffset);
+extern void asm_diffuse_line_to_8bpp(int *line, int linelength, char *output, char *table32k);
+extern void asm_diffuse_to_8bpp(int *line, int linelength, char *output, char *table32k, int nlines, int linestep, int *palette_data);
+extern char *asm_get_table32k(void);
+
+#endif
diff -U 3 -H -b -B -d -p -r -N -- jpeg-3/jpegdata.h cvs/h/jpegdata
--- jpeg-3/jpegdata.h	1992-03-02 18:16:52.000000000 +0000
+++ cvs/h/jpegdata	1996-11-05 09:45:08.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jpegdata.h
  *
@@ -6,96 +23,20 @@
  * For conditions of distribution and use, see the accompanying README file.
  *
  * This file defines shared data structures for the various JPEG modules.
- */
-
-
-/*
- * You might need to change some of the following declarations if you are
- * using the JPEG software within a surrounding application program
- * or porting it to an unusual system.
- */
-
-
-/* If the source or destination of image data is not to be stdio streams,
- * these types may need work.  You can replace them with some kind of
- * pointer or indicator that is useful to you, or just ignore 'em.
- * Note that the user interface and the various jrdxxx/jwrxxx modules
- * will also need work for non-stdio input/output.
- */
-
-typedef FILE * JFILEREF;	/* source or dest of JPEG-compressed data */
-
-typedef FILE * IFILEREF;	/* source or dest of non-JPEG image data */
-
-
-/* These defines are used in all function definitions and extern declarations.
- * You could modify them if you need to change function linkage conventions,
- * as is shown below for use with C++.  Another application would be to make
- * all functions global for use with code profilers that require it.
- * NOTE: the C++ test does the right thing if you are reading this include
- * file in a C++ application to link to JPEG code that's been compiled with a
- * regular C compiler.  I'm not sure it works if you try to compile the JPEG
- * code with C++.
+ *
+ * Seriously updated for use deep in RISCOS.
  */
 
 #define METHODDEF static	/* a function called through method pointers */
 #define LOCAL	  static	/* a function used only in its module */
-#define GLOBAL			/* a function referenced thru EXTERNs */
-#ifdef __cplusplus
-#define EXTERN	  extern "C"	/* a reference to a GLOBAL function */
-#else
-#define EXTERN	  extern	/* a reference to a GLOBAL function */
-#endif
-
-
-/* Here is the pseudo-keyword for declaring pointers that must be "far"
- * on 80x86 machines.  Most of the specialized coding for 80x86 is handled
- * by just saying "FAR *" where such a pointer is needed.  In a few places
- * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
- */
-
-#ifdef NEED_FAR_POINTERS
-#define FAR  far
-#else
+#define GLOBAL    static
+#define EXTERN    static
 #define FAR
-#endif
-
-
-
-/* The remaining declarations are not system-dependent, we hope. */
-
-
-/*
- * NOTE: if you have an ancient, strict-K&R C compiler, it may choke on the
- * similarly-named fields in compress_info_struct and decompress_info_struct.
- * If this happens, you can get around it by rearranging the two structs so
- * that the similarly-named fields appear first and in the same order in
- * each struct.  Since such compilers are now pretty rare, we haven't done
- * this in the portable code, preferring to maintain a logical ordering.
- */
-
-
-
-/* This macro is used to declare a "method", that is, a function pointer. */
-/* We want to supply prototype parameters if the compiler can cope. */
-/* Note that the arglist parameter must be parenthesized! */
 
-#ifdef PROTO
 #define METHOD(type,methodname,arglist)  type (*methodname) arglist
-#else
-#define METHOD(type,methodname,arglist)  type (*methodname) ()
-#endif
-
-/* Forward references to lists of method pointers */
-typedef struct external_methods_struct * external_methods_ptr;
-typedef struct compress_methods_struct * compress_methods_ptr;
-typedef struct decompress_methods_struct * decompress_methods_ptr;
-
 
 /* Data structures for images containing either samples or coefficients. */
 /* Note that the topmost (leftmost) index is always color component. */
-/* On 80x86 machines, the image arrays are too big for near pointers, */
-/* but the pointer arrays can fit in near memory. */
 
 typedef JSAMPLE FAR *JSAMPROW;	/* ptr to one image row of pixel samples. */
 typedef JSAMPROW *JSAMPARRAY;	/* ptr to some rows (a 2-D sample array) */
@@ -123,9 +62,35 @@ typedef JCOEF FAR *JCOEFPTR;	/* useful i
 typedef JCOEF DCTELEM;
 typedef DCTELEM DCTBLOCK[DCTSIZE2];
 
+/* -------------------- Statistics on JPEG files ------------------------- */
 
-/* Types for JPEG compression parameters and working tables. */
+#ifdef STATS
+typedef struct
+{
+  int n_jblocks;                  /* JBLOCKs analysed */
+  int n_nonzero_coeff[DCTSIZE2];  /* no of JBLOCKs with this many nonzero coeffs,
+                                     given absolute DC value (not just delta). */
+
+  int n_lines_thismany_nonzero_coeffs_pass1[DCTSIZE]; /* just ac coeffs */
+  int n_lines_thismany_nonzero_coeffs_pass2[DCTSIZE];
+
+  int n_pass1_ac_zero;
+  int n_pass1_ac_dc_zero;
+  int n_pass1_ac_nonzero;
+
+  int n_pass1_even_zero; /* no of rows in pass 1 with even coeffs zero */
+  int n_pass1_odd_zero;
+  int n_pass1_odd_nonzero;
+
+  int higher_coeff_all_zero[DCTSIZE]; /* higher coeffs than this are all zero, in pass 1 */
+
+} stats_struct;
+#define IFSTATS(a) a
+#else
+#define IFSTATS(a)
+#endif
 
+/* ----------- Types for JPEG compression parameters and working tables. ---------- */
 
 typedef enum {			/* defines known color spaces */
 	CS_UNKNOWN,		/* error/unspecified */
@@ -141,24 +106,24 @@ typedef struct {		/* Basic info about on
   /* These values are fixed over the whole image */
   /* For compression, they must be supplied by the user interface; */
   /* for decompression, they are read from the SOF marker. */
-	short component_id;	/* identifier for this component (0..255) */
-	short component_index;	/* its index in SOF or cinfo->comp_info[] */
-	short h_samp_factor;	/* horizontal sampling factor (1..4) */
-	short v_samp_factor;	/* vertical sampling factor (1..4) */
-	short quant_tbl_no;	/* quantization table selector (0..3) */
+        int /*short*/ component_id;     /* identifier for this component (0..255) */
+        int /*short*/ component_index;  /* its index in SOF or cinfo->comp_info[] */
+        int /*short*/ h_samp_factor;    /* horizontal sampling factor (1..4) */
+        int /*short*/ v_samp_factor;    /* vertical sampling factor (1..4) */
+        int /*short*/ quant_tbl_no;     /* quantization table selector (0..3) */
   /* These values may vary between scans */
   /* For compression, they must be supplied by the user interface; */
   /* for decompression, they are read from the SOS marker. */
-	short dc_tbl_no;	/* DC entropy table selector (0..3) */
-	short ac_tbl_no;	/* AC entropy table selector (0..3) */
+        int /*short*/ dc_tbl_no;        /* DC entropy table selector (0..3) */
+        int /*short*/ ac_tbl_no;        /* AC entropy table selector (0..3) */
   /* These values are computed during compression or decompression startup */
 	long true_comp_width;	/* component's image width in samples */
 	long true_comp_height;	/* component's image height in samples */
 	/* the above are the logical dimensions of the subsampled image */
   /* These values are computed before starting a scan of the component */
-	short MCU_width;	/* number of blocks per MCU, horizontally */
-	short MCU_height;	/* number of blocks per MCU, vertically */
-	short MCU_blocks;	/* MCU_width * MCU_height */
+        int /*short*/ MCU_width;        /* number of blocks per MCU, horizontally */
+        int /*short*/ MCU_height;       /* number of blocks per MCU, vertically */
+        int /*short*/ MCU_blocks;       /* MCU_width * MCU_height */
 	long subsampled_width;	/* image width in samples, after expansion */
 	long subsampled_height;	/* image height in samples, after expansion */
 	/* the above are the true_comp_xxx values rounded up to multiples of */
@@ -175,11 +140,7 @@ typedef struct {		/* Basic info about on
  * quantization values is a significant chunk of the runtime).
  * Note: the values in a QUANT_TBL are always given in zigzag order.
  */
-#ifdef EIGHT_BIT_SAMPLES
-typedef INT16 QUANT_VAL;	/* element of a quantization table */
-#else
-typedef UINT16 QUANT_VAL;	/* element of a quantization table */
-#endif
+typedef int QUANT_VAL;
 typedef QUANT_VAL QUANT_TBL[DCTSIZE2];	/* A quantization table */
 typedef QUANT_VAL * QUANT_TBL_PTR;	/* pointer to same */
 
@@ -189,22 +151,24 @@ typedef struct {		/* A Huffman coding ta
 	UINT8 bits[17];		/* bits[k] = # of symbols with codes of */
 				/* length k bits; bits[0] is unused */
 	UINT8 huffval[256];	/* The symbols, in order of incr code length */
-  /* This field is used only during compression.  It's initialized FALSE when
-   * the table is created, and set TRUE when it's been output to the file.
-   */
-	boolean sent_table;	/* TRUE when table has been output */
+
   /* The remaining fields are computed from the above to allow more efficient
    * coding and decoding.  These fields should be considered private to the
    * Huffman compression & decompression modules.
    */
-	/* encoding tables: */
-	UINT16 ehufco[256];	/* code for each symbol */
-	char ehufsi[256];	/* length of code for each symbol */
 	/* decoding tables: (element [0] of each array is unused) */
-	UINT16 mincode[17];	/* smallest code of length k */
+#if 0
+        UINT32 /*UINT16*/ mincode[17];     /* smallest code of length k */
+#endif
 	INT32 maxcode[18];	/* largest code of length k (-1 if none) */
 	/* (maxcode[17] is a sentinel to ensure huff_DECODE terminates) */
-	short valptr[17];	/* huffval[] index of 1st symbol of length k */
+        int /*short*/ valptr[17];       /* huffval[] index of 1st symbol of length k */
+                                        /* with value of mincode[k] from above subtracted */
+
+        int shortcut[256]; /* shortcuts the actual reading of huffman values - indexed
+                              by the next 8 bits in the bit stream an entry tells you
+                              how long the next entry is. This allows you to read
+                              the vast majority of huffman codes at a single step. */
 } HUFF_TBL;
 
 
@@ -215,169 +179,70 @@ typedef struct {		/* A Huffman coding ta
 #define MAX_SAMP_FACTOR     4	/* JPEG limit on sampling factors */
 #define MAX_BLOCKS_IN_MCU   10	/* JPEG limit on # of blocks in an MCU */
 
+/* ----------- Remember a precise position in the huffman stream. ------------------ */
+typedef struct
+{
+  int bit_pointer;   /* (next_input_byte-input_buffer)*32 + bits_left */
+  int get_buffer;
+  short int last_dc_val0; /* NB NOT dequantised */
+  short int last_dc_val1;
+  short int last_dc_val2;
+  short int last_dc_val3; /* in case we ever do CMYK */
+  short int restarts_to_go;
+  short int next_restart_num;
+} huff_pointer;
 
-/* Working data for compression */
-
-struct compress_info_struct {
-/*
- * All of these fields shall be established by the user interface before
- * calling jpeg_compress, or by the input_init or c_ui_method_selection
- * methods.
- * Most parameters can be set to reasonable defaults by j_c_defaults.
- * Note that the UI must supply the storage for the main methods struct,
- * though it sets only a few of the methods there.
- */
-	compress_methods_ptr methods; /* Points to list of methods to use */
-
-	external_methods_ptr emethods; /* Points to list of methods to use */
-
-	IFILEREF input_file;	/* tells input routines where to read image */
-	JFILEREF output_file;	/* tells output routines where to write JPEG */
-
-	long image_width;	/* input image width */
-	long image_height;	/* input image height */
-	short input_components;	/* # of color components in input image */
-
-	short data_precision;	/* bits of precision in image data */
-
-	COLOR_SPACE in_color_space; /* colorspace of input file */
-	COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
-
-	double input_gamma;	/* image gamma of input file */
-
-	boolean write_JFIF_header; /* should a JFIF marker be written? */
-	/* These three values are not used by the JPEG code, only copied */
-	/* into the JFIF APP0 marker.  density_unit can be 0 for unknown, */
-	/* 1 for dots/inch, or 2 for dots/cm.  Note that the pixel aspect */
-	/* ratio is defined by X_density/Y_density even when density_unit=0. */
-	UINT8 density_unit;	/* JFIF code for pixel size units */
-	UINT16 X_density;	/* Horizontal pixel density */
-	UINT16 Y_density;	/* Vertical pixel density */
-
-	short num_components;	/* # of color components in JPEG image */
-	jpeg_component_info * comp_info;
-	/* comp_info[i] describes component that appears i'th in SOF */
-
-	QUANT_TBL_PTR quant_tbl_ptrs[NUM_QUANT_TBLS];
-	/* ptrs to coefficient quantization tables, or NULL if not defined */
-
-	HUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
-	HUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
-	/* ptrs to Huffman coding tables, or NULL if not defined */
-
-	UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arithmetic-coding tables */
-	UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arithmetic-coding tables */
-	UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arithmetic-coding tables */
-
-	boolean arith_code;	/* TRUE=arithmetic coding, FALSE=Huffman */
-	boolean interleave;	/* TRUE=interleaved output, FALSE=not */
-	boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
-	boolean CCIR601_sampling; /* TRUE=first samples are cosited */
-
-	UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
-
-/*
- * These fields are computed during jpeg_compress startup
- */
-	short max_h_samp_factor; /* largest h_samp_factor */
-	short max_v_samp_factor; /* largest v_samp_factor */
-
-/*
- * These fields may be useful for progress monitoring
- */
-
-	int total_passes;	/* number of passes expected */
-	int completed_passes;	/* number of passes completed so far */
-
-/*
- * These fields are valid during any one scan
- */
-	short comps_in_scan;	/* # of JPEG components output this time */
-	jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
-	/* *cur_comp_info[i] describes component that appears i'th in SOS */
-
-	long MCUs_per_row;	/* # of MCUs across the image */
-	long MCU_rows_in_scan;	/* # of MCU rows in the image */
-
-	short blocks_in_MCU;	/* # of DCT blocks per MCU */
-	short MCU_membership[MAX_BLOCKS_IN_MCU];
-	/* MCU_membership[i] is index in cur_comp_info of component owning */
-	/* i'th block in an MCU */
-
-	/* these fields are private data for the entropy encoder */
-	JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
-	JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
-	UINT16 restarts_to_go;	/* MDUs left in this restart interval */
-	short next_restart_num;	/* # of next RSTn marker (0..7) */
-};
-
-typedef struct compress_info_struct * compress_info_ptr;
-
+/* ------------- Error codes for various forms of unacceptable JPEG file ------------- */
+#define E_PRE_NOT_8         1            /* Data precision not 8 */
+#define E_RESTART           2            /* Restart interval not 0 */
+#define E_MULTI_SCAN        3            /* Multi-scan file */
+#define E_TOO_HIGH          4            /* Image too high, max is %i pixels */
+#define E_BAD_SAMPLE        5            /* Bad sample factor */
+#define E_HEIGHT            6            /* Height is %i, not as specified */
+#define E_WIDTH             7            /* Width is %i, not as specified */
+#define E_COLOUR            8            /* Bad colour space (%i), not grey or YUV */
+#define E_COMPONENTS        9            /* Bad number (%i) of components, only 1 or 3 allowed */
+#define E_TOO_WIDE          10           /* Image too wide, max is %i pixels */
 
-/* Working data for decompression */
+/* ------------- Working data for decompression ---------------------------------- */
 
 struct decompress_info_struct {
-/*
- * These fields shall be established by the user interface before
- * calling jpeg_decompress.
- * Most parameters can be set to reasonable defaults by j_d_defaults.
- * Note that the UI must supply the storage for the main methods struct,
- * though it sets only a few of the methods there.
- */
-	decompress_methods_ptr methods; /* Points to list of methods to use */
-
-	external_methods_ptr emethods; /* Points to list of methods to use */
 
-	JFILEREF input_file;	/* tells input routines where to read JPEG */
-	IFILEREF output_file;	/* tells output routines where to write image */
-
-	/* these can be set at d_ui_method_selection time: */
+        int error_code;         /* Returned err code, 0 if no error */
+        int error_argument1;    /* Supplementary error data */
+        int error_argument2;    /* Supplementary error data */
 
-	COLOR_SPACE out_color_space; /* colorspace of output */
+        char *workspace_UNUSED;        /* For band buffer and things. (no, implicitly at end of this space now) */
+        int workspace_size;     /* number of bytes */
+/* up to here appears in sources.SprExtend */
 
-	double output_gamma;	/* image gamma wanted in output */
+        int /*long*/ image_width;       /* overall image width */
+        int /*long*/ image_height;      /* overall image height */
+        COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
+/* up to here is replicated somewhat in CFSI-JPEG's interface */
 
-	boolean quantize_colors; /* T if output is a colormapped format */
-	/* the following are ignored if not quantize_colors: */
-	boolean two_pass_quantize;	/* use two-pass color quantization? */
-	boolean use_dithering;		/* want color dithering? */
-	int desired_number_of_colors;	/* max number of colors to use */
+        char *table32k; /* the 16bpp->8bpp 32K lookup table, if you need it. */
+        BOOL table32k_unavailable; /* Set if we ever failed to get table32k.
+                                   This means we're probably on an old OS, so the
+                                   table will never be available. */
 
-	boolean do_block_smoothing; /* T = apply cross-block smoothing */
-	boolean do_pixel_smoothing; /* T = apply post-subsampling smoothing */
+        int *band_buffer; /* Large buffer into which the colour data goes. */
+                          /* We construct one strip, 8 or 16 pixels high, across the image. */
+        int band_buffer_size; /* Must be a multiple of 16 */
 
-/*
- * These fields are used for efficient buffering of data between read_jpeg_data
- * and the entropy decoding object.  By using a shared buffer, we avoid copying
- * data and eliminate the need for an "unget" operation at the end of a scan.
- * The actual source of the data is known only to read_jpeg_data; see the
- * JGETC macro, below.
- * Note: the user interface is expected to allocate the input_buffer and
- * initialize bytes_in_buffer to 0.  Also, for JFIF/raw-JPEG input, the UI
- * actually supplies the read_jpeg_data method.  This is all handled by
- * j_d_defaults in a typical implementation.
- */
 	char * input_buffer;	/* start of buffer (private to input code) */
 	char * next_input_byte;	/* => next byte to read from buffer */
-	int bytes_in_buffer;	/* # of bytes remaining in buffer */
-
-/*
- * These fields are set by read_file_header or read_scan_header
- */
-	long image_width;	/* overall image width */
-	long image_height;	/* overall image height */
-
-	short data_precision;	/* bits of precision in image data */
+        char * buffer_end;      /* pointer to end of buffer */
 
-	COLOR_SPACE jpeg_color_space; /* colorspace of JPEG file */
+        int data_precision;   /* bits of precision in image data */
 
         /* These three values are not used by the JPEG code, merely copied */
 	/* from the JFIF APP0 marker (if any). */
-	UINT8 density_unit;	/* JFIF code for pixel size units */
-	UINT16 X_density;	/* Horizontal pixel density */
-	UINT16 Y_density;	/* Vertical pixel density */
+        UINT32 /*UINT8*/ density_unit;     /* JFIF code for pixel size units */
+        UINT32 /*UINT16*/ X_density;       /* Horizontal pixel density */
+        UINT32 /*UINT16*/ Y_density;       /* Vertical pixel density */
 
-	short num_components;	/* # of color components in JPEG image */
+        int /*short*/ num_components;   /* # of color components in JPEG image */
 	jpeg_component_info * comp_info;
 	/* comp_info[i] describes component that appears i'th in SOF */
 
@@ -395,462 +260,113 @@ struct decompress_info_struct {
 	boolean arith_code;	/* TRUE=arithmetic coding, FALSE=Huffman */
 	boolean CCIR601_sampling; /* TRUE=first samples are cosited */
 
-	UINT16 restart_interval;/* MDUs per restart interval, or 0 for no restart */
-
-/*
- * These fields are computed during jpeg_decompress startup
- */
-	short max_h_samp_factor; /* largest h_samp_factor */
-	short max_v_samp_factor; /* largest v_samp_factor */
-
-	short color_out_comps;	/* # of color components output by color_convert */
-				/* (need not match num_components) */
-	short final_out_comps;	/* # of color components sent to put_pixel_rows */
-	/* (1 when quantizing colors, else same as color_out_comps) */
-
-/*
- * When quantizing colors, the color quantizer leaves a pointer to the output
- * colormap in these fields.  The colormap is valid from the time put_color_map
- * is called (must be before any put_pixel_rows calls) until shutdown (more
- * specifically, until free_all is called to release memory).
- */
-	int actual_number_of_colors; /* actual number of entries */
-	JSAMPARRAY colormap;	/* NULL if not valid */
-	/* map has color_out_comps rows * actual_number_of_colors columns */
-
-/*
- * These fields may be useful for progress monitoring
- */
-
-	int total_passes;	/* number of passes expected */
-	int completed_passes;	/* number of passes completed so far */
+        UINT32 /*UINT16*/ restart_interval;/* MDUs per restart interval, or 0 for no restart */
+        int restarts_to_go;
+        int next_restart_num;
 
 /*
  * These fields are valid during any one scan
  */
-	short comps_in_scan;	/* # of JPEG components input this time */
+        int /*short*/ comps_in_scan;    /* # of JPEG components input this time */
 	jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
 	/* *cur_comp_info[i] describes component that appears i'th in SOS */
 
 	long MCUs_per_row;	/* # of MCUs across the image */
 	long MCU_rows_in_scan;	/* # of MCU rows in the image */
 
-	short blocks_in_MCU;	/* # of DCT blocks per MCU */
-	short MCU_membership[MAX_BLOCKS_IN_MCU];
-	/* MCU_membership[i] is index in cur_comp_info of component owning */
-	/* i'th block in an MCU */
-
 	/* these fields are private data for the entropy encoder */
-	JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp */
-	JCOEF last_dc_diff[MAX_COMPS_IN_SCAN]; /* last DC diff for each comp */
-	UINT16 restarts_to_go;	/* MDUs left in this restart interval */
-	short next_restart_num;	/* # of next RSTn marker (0..7) */
-};
-
-typedef struct decompress_info_struct * decompress_info_ptr;
-
-
-/* Macros for reading data from the decompression input buffer */
-
-#ifdef CHAR_IS_UNSIGNED
-#define JGETC(cinfo)	( --(cinfo)->bytes_in_buffer < 0 ? \
-			 (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
-			 (int) (*(cinfo)->next_input_byte++) )
-#else
-#define JGETC(cinfo)	( --(cinfo)->bytes_in_buffer < 0 ? \
-			 (*(cinfo)->methods->read_jpeg_data) (cinfo) : \
-			 (int) (*(cinfo)->next_input_byte++) & 0xFF )
-#endif
-
-#define JUNGETC(ch,cinfo)  ((cinfo)->bytes_in_buffer++, \
-			    *(--((cinfo)->next_input_byte)) = (ch))
-
-#define MIN_UNGET	4	/* may always do at least 4 JUNGETCs */
-
-
-/* A virtual image has a control block whose contents are private to the
- * memory manager module (and may differ between managers).  The rest of the
- * code only refers to virtual images by these pointer types, and never
- * dereferences the pointer.
- */
-
-typedef struct big_sarray_control * big_sarray_ptr;
-typedef struct big_barray_control * big_barray_ptr;
-
-/* Although a real ANSI C compiler can deal perfectly well with pointers to
- * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
- * and pseudo-ANSI compilers get confused.  To keep one of these bozos happy,
- * add -DINCOMPLETE_TYPES_BROKEN to CFLAGS in your Makefile.  Then we will
- * pseudo-define the structs as containing a single "dummy" field.
- * The memory managers #define AM_MEMORY_MANAGER before including this file,
- * so that they can make their own definitions of the structs.
- */
-
-#ifdef INCOMPLETE_TYPES_BROKEN
-#ifndef AM_MEMORY_MANAGER
-struct big_sarray_control { long dummy; };
-struct big_barray_control { long dummy; };
-#endif
-#endif
-
-
-/* Method types that need typedefs */
-
-typedef METHOD(void, MCU_output_method_ptr, (compress_info_ptr cinfo,
-					     JBLOCK *MCU_data));
-typedef METHOD(void, MCU_output_caller_ptr, (compress_info_ptr cinfo,
-					     MCU_output_method_ptr output_method));
-typedef METHOD(void, subsample_ptr, (compress_info_ptr cinfo,
-				     int which_component,
-				     long input_cols, int input_rows,
-				     long output_cols, int output_rows,
-				     JSAMPARRAY above,
-				     JSAMPARRAY input_data,
-				     JSAMPARRAY below,
-				     JSAMPARRAY output_data));
-typedef METHOD(void, unsubsample_ptr, (decompress_info_ptr cinfo,
-				       int which_component,
-				       long input_cols, int input_rows,
-				       long output_cols, int output_rows,
-				       JSAMPARRAY above,
-				       JSAMPARRAY input_data,
-				       JSAMPARRAY below,
-				       JSAMPARRAY output_data));
-typedef METHOD(void, quantize_method_ptr, (decompress_info_ptr cinfo,
-					   int num_rows,
-					   JSAMPIMAGE input_data,
-					   JSAMPARRAY output_workspace));
-typedef METHOD(void, quantize_caller_ptr, (decompress_info_ptr cinfo,
-					   quantize_method_ptr quantize_method));
+        JCOEF last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each comp - NOT dequantized yet */
 
+        int current_huff_pointer; /* Currently loaded band, or -1 if none. */
+        int xmin;
+        int xmax;                 /* Min and max x pixels required: clip as early
+                                  as possible. */
+        int options;
 
-/* These structs contain function pointers for the various JPEG methods. */
+        /* Statics moved in from the huffman decoding */
+        int get_buffer;
+        int bits_left;
 
-/* Routines to be provided by the surrounding application, rather than the
- * portable JPEG code proper.  These are the same for compression and
- * decompression.
- */
+        /* Random check words to look for the same sprite over again */
+        int check1;
+        int check2;
+        int check3;
 
-struct external_methods_struct {
-	/* User interface: error exit and trace message routines */
-	/* NOTE: the string msgtext parameters will eventually be replaced */
-	/* by an enumerated-type code so that non-English error messages */
-	/* can be substituted easily.  This will not be done until all the */
-	/* code is in place, so that we know what messages are needed. */
-	METHOD(void, error_exit, (const char *msgtext));
-	METHOD(void, trace_message, (const char *msgtext));
+        IFSTATS(stats_struct stats;)       /* Gathering statistics */
 
-	/* Working data for error/trace facility */
-	/* See macros below for the usage of these variables */
-	int trace_level;	/* level of detail of tracing messages */
-	/* Use level 0 for unsuppressable messages (nonfatal errors) */
-	/* Use levels 1, 2, 3 for successively more detailed trace options */
+        JBLOCK jblocks[7]; /* YYYYUV blocks, and one spare at the front */
 
-	int message_parm[8];	/* store numeric parms for messages here */
+#define HPOINTERS 200 /* max picture depth 16*this for colour, 8*this for mono, in pixels */
+        huff_pointer *huff_pointers;
+                      /* An array of information every 16 pixel lines, which
+                      allows us to start decoding the file at that point. This
+                      allows reasonably quick random access to anywhere in the file. */
 
-	/* Memory management */
-	/* NB: alloc routines never return NULL. They exit to */
-	/* error_exit if not successful. */
-	METHOD(void *, alloc_small, (size_t sizeofobject));
-	METHOD(void, free_small, (void *ptr));
-	METHOD(void FAR *, alloc_medium, (size_t sizeofobject));
-	METHOD(void, free_medium, (void FAR *ptr));
-	METHOD(JSAMPARRAY, alloc_small_sarray, (long samplesperrow,
-						long numrows));
-	METHOD(void, free_small_sarray, (JSAMPARRAY ptr));
-	METHOD(JBLOCKARRAY, alloc_small_barray, (long blocksperrow,
-						 long numrows));
-	METHOD(void, free_small_barray, (JBLOCKARRAY ptr));
-	METHOD(big_sarray_ptr, request_big_sarray, (long samplesperrow,
-						    long numrows,
-						    long unitheight));
-	METHOD(big_barray_ptr, request_big_barray, (long blocksperrow,
-						    long numrows,
-						    long unitheight));
-	METHOD(void, alloc_big_arrays, (long extra_small_samples,
-					long extra_small_blocks,
-					long extra_medium_space));
-	METHOD(JSAMPARRAY, access_big_sarray, (big_sarray_ptr ptr,
-					       long start_row,
-					       boolean writable));
-	METHOD(JBLOCKARRAY, access_big_barray, (big_barray_ptr ptr,
-						long start_row,
-						boolean writable));
-	METHOD(void, free_big_sarray, (big_sarray_ptr ptr));
-	METHOD(void, free_big_barray, (big_barray_ptr ptr));
-	METHOD(void, free_all, (void));
+        /* Space always needed, and pointed at by some of the pointers above. */
 
-	long max_memory_to_use;	/* maximum amount of memory to use */
+        jpeg_component_info s_cur_comp_info[MAX_COMPS_IN_SCAN];
+        QUANT_TBL s_quant_tbl[NUM_QUANT_TBLS];
+        HUFF_TBL s_dc_huff_tbl[NUM_HUFF_TBLS];
+        HUFF_TBL s_ac_huff_tbl[NUM_HUFF_TBLS];
 };
 
-/* Macros to simplify using the error and trace message stuff */
-/* The first parameter is generally cinfo->emethods */
-
-#define ERREXIT(emeth,msg)		((*(emeth)->error_exit) (msg))
-#define ERREXIT1(emeth,msg,p1)		((emeth)->message_parm[0] = (p1), \
-					 (*(emeth)->error_exit) (msg))
-#define ERREXIT2(emeth,msg,p1,p2)	((emeth)->message_parm[0] = (p1), \
-					 (emeth)->message_parm[1] = (p2), \
-					 (*(emeth)->error_exit) (msg))
-#define ERREXIT3(emeth,msg,p1,p2,p3)	((emeth)->message_parm[0] = (p1), \
-					 (emeth)->message_parm[1] = (p2), \
-					 (emeth)->message_parm[2] = (p3), \
-					 (*(emeth)->error_exit) (msg))
-#define ERREXIT4(emeth,msg,p1,p2,p3,p4) ((emeth)->message_parm[0] = (p1), \
-					 (emeth)->message_parm[1] = (p2), \
-					 (emeth)->message_parm[2] = (p3), \
-					 (emeth)->message_parm[3] = (p4), \
-					 (*(emeth)->error_exit) (msg))
-
-#define MAKESTMT(stuff)		do { stuff } while (0)
-
-#define TRACEMS(emeth,lvl,msg)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		(*(emeth)->trace_message) (msg); } )
-#define TRACEMS1(emeth,lvl,msg,p1)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		(emeth)->message_parm[0] = (p1); \
-		(*(emeth)->trace_message) (msg); } )
-#define TRACEMS2(emeth,lvl,msg,p1,p2)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		(emeth)->message_parm[0] = (p1); \
-		(emeth)->message_parm[1] = (p2); \
-		(*(emeth)->trace_message) (msg); } )
-#define TRACEMS3(emeth,lvl,msg,p1,p2,p3)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		int * _mp = (emeth)->message_parm; \
-		*_mp++ = (p1); *_mp++ = (p2); *_mp = (p3); \
-		(*(emeth)->trace_message) (msg); } )
-#define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		int * _mp = (emeth)->message_parm; \
-		*_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp = (p4); \
-		(*(emeth)->trace_message) (msg); } )
-#define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8)    \
-  MAKESTMT( if ((emeth)->trace_level >= (lvl)) { \
-		int * _mp = (emeth)->message_parm; \
-		*_mp++ = (p1); *_mp++ = (p2); *_mp++ = (p3); *_mp++ = (p4); \
-		*_mp++ = (p5); *_mp++ = (p6); *_mp++ = (p7); *_mp = (p8); \
-		(*(emeth)->trace_message) (msg); } )
-
-
-/* Methods used during JPEG compression. */
+typedef struct decompress_info_struct * decompress_info_ptr;
 
-struct compress_methods_struct {
-	/* Hook for user interface to get control after input_init */
-	METHOD(void, c_ui_method_selection, (compress_info_ptr cinfo));
-	/* Hook for user interface to do progress monitoring */
-	METHOD(void, progress_monitor, (compress_info_ptr cinfo,
-					long loopcounter, long looplimit));
-	/* Input image reading & conversion to standard form */
-	METHOD(void, input_init, (compress_info_ptr cinfo));
-	METHOD(void, get_input_row, (compress_info_ptr cinfo,
-				     JSAMPARRAY pixel_row));
-	METHOD(void, input_term, (compress_info_ptr cinfo));
-	/* Color space and gamma conversion */
-	METHOD(void, colorin_init, (compress_info_ptr cinfo));
-	METHOD(void, get_sample_rows, (compress_info_ptr cinfo,
-				       int rows_to_read,
-				       JSAMPIMAGE image_data));
-	METHOD(void, colorin_term, (compress_info_ptr cinfo));
-	/* Expand picture data at edges */
-	METHOD(void, edge_expand, (compress_info_ptr cinfo,
-				   long input_cols, int input_rows,
-				   long output_cols, int output_rows,
-				   JSAMPIMAGE image_data));
-	/* Subsample pixel values of a single component */
-	/* There can be a different subsample method for each component */
-	METHOD(void, subsample_init, (compress_info_ptr cinfo));
-	subsample_ptr subsample[MAX_COMPS_IN_SCAN];
-	METHOD(void, subsample_term, (compress_info_ptr cinfo));
-	/* Extract samples in MCU order, process & hand off to output_method */
-	/* The input is always exactly N MCU rows worth of data */
-	METHOD(void, extract_init, (compress_info_ptr cinfo));
-	METHOD(void, extract_MCUs, (compress_info_ptr cinfo,
-				    JSAMPIMAGE image_data,
-				    int num_mcu_rows,
-				    MCU_output_method_ptr output_method));
-	METHOD(void, extract_term, (compress_info_ptr cinfo));
-	/* Entropy encoding parameter optimization */
-	METHOD(void, entropy_optimize, (compress_info_ptr cinfo,
-					MCU_output_caller_ptr source_method));
-	/* Entropy encoding */
-	METHOD(void, entropy_encoder_init, (compress_info_ptr cinfo));
-	METHOD(void, entropy_encode, (compress_info_ptr cinfo,
-				      JBLOCK *MCU_data));
-	METHOD(void, entropy_encoder_term, (compress_info_ptr cinfo));
-	/* JPEG file header construction */
-	METHOD(void, write_file_header, (compress_info_ptr cinfo));
-	METHOD(void, write_scan_header, (compress_info_ptr cinfo));
-	METHOD(void, write_jpeg_data, (compress_info_ptr cinfo,
-				       char *dataptr,
-				       int datacount));
-	METHOD(void, write_scan_trailer, (compress_info_ptr cinfo));
-	METHOD(void, write_file_trailer, (compress_info_ptr cinfo));
-	/* Pipeline control */
-	METHOD(void, c_pipeline_controller, (compress_info_ptr cinfo));
-	METHOD(void, entropy_output, (compress_info_ptr cinfo,
-				      char *dataptr,
-				      int datacount));
-	/* Overall control */
-	METHOD(void, c_per_scan_method_selection, (compress_info_ptr cinfo));
-};
 
-/* Methods used during JPEG decompression. */
+/* Macros for reading data from the decompression input buffer */
 
-struct decompress_methods_struct {
-	/* Hook for user interface to get control after reading file header */
-	METHOD(void, d_ui_method_selection, (decompress_info_ptr cinfo));
-	/* Hook for user interface to do progress monitoring */
-	METHOD(void, progress_monitor, (decompress_info_ptr cinfo,
-					long loopcounter, long looplimit));
-	/* JPEG file scanning */
-	METHOD(void, read_file_header, (decompress_info_ptr cinfo));
-	METHOD(boolean, read_scan_header, (decompress_info_ptr cinfo));
-	METHOD(int, read_jpeg_data, (decompress_info_ptr cinfo));
-	METHOD(void, read_scan_trailer, (decompress_info_ptr cinfo));
-	METHOD(void, read_file_trailer, (decompress_info_ptr cinfo));
-	/* Entropy decoding */
-	METHOD(void, entropy_decoder_init, (decompress_info_ptr cinfo));
-	METHOD(void, entropy_decode, (decompress_info_ptr cinfo,
-				      JBLOCK *MCU_data));
-	METHOD(void, entropy_decoder_term, (decompress_info_ptr cinfo));
-	/* MCU disassembly: fetch MCUs from entropy_decode, build coef array */
-	/* The reverse_DCT step is in the same module for symmetry reasons */
-	METHOD(void, disassemble_init, (decompress_info_ptr cinfo));
-	METHOD(void, disassemble_MCU, (decompress_info_ptr cinfo,
-				       JBLOCKIMAGE image_data));
-	METHOD(void, reverse_DCT, (decompress_info_ptr cinfo,
-				   JBLOCKIMAGE coeff_data,
-				   JSAMPIMAGE output_data, int start_row));
-	METHOD(void, disassemble_term, (decompress_info_ptr cinfo));
-	/* Cross-block smoothing */
-	METHOD(void, smooth_coefficients, (decompress_info_ptr cinfo,
-					   jpeg_component_info *compptr,
-					   JBLOCKROW above,
-					   JBLOCKROW currow,
-					   JBLOCKROW below,
-					   JBLOCKROW output));
-	/* Un-subsample pixel values of a single component */
-	/* There can be a different unsubsample method for each component */
-	METHOD(void, unsubsample_init, (decompress_info_ptr cinfo));
-	unsubsample_ptr unsubsample[MAX_COMPS_IN_SCAN];
-	METHOD(void, unsubsample_term, (decompress_info_ptr cinfo));
-	/* Color space and gamma conversion */
-	METHOD(void, colorout_init, (decompress_info_ptr cinfo));
-	METHOD(void, color_convert, (decompress_info_ptr cinfo,
-				     int num_rows, long num_cols,
-				     JSAMPIMAGE input_data,
-				     JSAMPIMAGE output_data));
-	METHOD(void, colorout_term, (decompress_info_ptr cinfo));
-	/* Color quantization */
-	METHOD(void, color_quant_init, (decompress_info_ptr cinfo));
-	METHOD(void, color_quantize, (decompress_info_ptr cinfo,
-				      int num_rows,
-				      JSAMPIMAGE input_data,
-				      JSAMPARRAY output_data));
-	METHOD(void, color_quant_prescan, (decompress_info_ptr cinfo,
-					   int num_rows,
-					   JSAMPIMAGE image_data,
-					   JSAMPARRAY workspace));
-	METHOD(void, color_quant_doit, (decompress_info_ptr cinfo,
-					quantize_caller_ptr source_method));
-	METHOD(void, color_quant_term, (decompress_info_ptr cinfo));
-	/* Output image writing */
-	METHOD(void, output_init, (decompress_info_ptr cinfo));
-	METHOD(void, put_color_map, (decompress_info_ptr cinfo,
-				     int num_colors, JSAMPARRAY colormap));
-	METHOD(void, put_pixel_rows, (decompress_info_ptr cinfo,
-				      int num_rows,
-				      JSAMPIMAGE pixel_data));
-	METHOD(void, output_term, (decompress_info_ptr cinfo));
-	/* Pipeline control */
-	METHOD(void, d_pipeline_controller, (decompress_info_ptr cinfo));
-	/* Overall control */
-	METHOD(void, d_per_scan_method_selection, (decompress_info_ptr cinfo));
-};
+/* The buffer contains the entire file */
+#define JGETC(cinfo) (int) ((cinfo)->next_input_byte >= (cinfo)->buffer_end ? 255 : *(cinfo)->next_input_byte++)
 
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is generally cinfo->emethods, left undisturbed in
+   c.jrdjfif but not used here. */
 
-/* External declarations for routines that aren't called via method ptrs. */
-/* Note: use "j" as first char of names to minimize namespace pollution. */
-/* The PP macro hides prototype parameters from compilers that can't cope. */
+/* The variable FILE_ is used to identify source files, smaller than __FILE__ (a bit!) for
+non-debugging code. */
+#define EXIT exit(FILE_+__LINE__);
 
-#ifdef PROTO
-#define PP(arglist)	arglist
+#ifdef DEBUG
+  #ifdef EMBED
+    #define TRACEMS(emeth,lvl,msg) {sprintf(0, msg); newline();}
+    #define TRACEMS1(emeth,lvl,msg,p1) {sprintf(0, msg,p1); newline();}
+    #define TRACEMS2(emeth,lvl,msg,p1,p2) {sprintf(0, msg,p1,p2); newline();}
+    #define TRACEMS3(emeth,lvl,msg,p1,p2,p3) {sprintf(0, msg,p1,p2,p3); newline();}
+    #define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4) {sprintf(0, msg,p1,p2,p3,p4); newline();}
+    #define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8) {sprintf(0, msg,p1,p2,p3,p4,p5,p6,p7,p8); newline();}
+  #else
+    #define TRACEMS(emeth,lvl,msg) {if (verbose) {printf(msg); printf("\n");}}
+    #define TRACEMS1(emeth,lvl,msg,p1) {if (verbose) {printf(msg,p1); printf("\n");}}
+    #define TRACEMS2(emeth,lvl,msg,p1,p2) {if (verbose) {printf(msg,p1,p2); printf("\n");}}
+    #define TRACEMS3(emeth,lvl,msg,p1,p2,p3) {if (verbose) {printf(msg,p1,p2,p3); printf("\n");}}
+    #define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4) {if (verbose) {printf(msg,p1,p2,p3,p4); printf("\n");}}
+    #define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8) {if (verbose) {printf(msg,p1,p2,p3,p4,p5,p6,p7,p8); printf("\n");}}
+  #endif
 #else
-#define PP(arglist)	()
+  #define TRACEMS(emeth,lvl,msg)
+  #define TRACEMS1(emeth,lvl,msg,p1)
+  #define TRACEMS2(emeth,lvl,msg,p1,p2)
+  #define TRACEMS3(emeth,lvl,msg,p1,p2,p3)
+  #define TRACEMS4(emeth,lvl,msg,p1,p2,p3,p4)
+  #define TRACEMS8(emeth,lvl,msg,p1,p2,p3,p4,p5,p6,p7,p8)
 #endif
 
+#define DUMPVAL(x) tracef(#x "=0x%x " _ (int)(x));
+#define DUMPVALN(x) tracef(#x "=0x%x\n" _ (int)(x));
 
-/* main entry for compression */
-EXTERN void jpeg_compress PP((compress_info_ptr cinfo));
-
-/* default parameter setup for compression */
-EXTERN void j_c_defaults PP((compress_info_ptr cinfo, int quality,
-			     boolean force_baseline));
-EXTERN void j_monochrome_default PP((compress_info_ptr cinfo));
-EXTERN void j_set_quality PP((compress_info_ptr cinfo, int quality,
-			      boolean force_baseline));
-
-/* main entry for decompression */
-EXTERN void jpeg_decompress PP((decompress_info_ptr cinfo));
-
-/* default parameter setup for decompression */
-EXTERN void j_d_defaults PP((decompress_info_ptr cinfo,
-			     boolean standard_buffering));
-
-/* forward DCT */
-EXTERN void j_fwd_dct PP((DCTBLOCK data));
-/* inverse DCT */
-EXTERN void j_rev_dct PP((DCTBLOCK data));
-
-/* utility routines in jutils.c */
-EXTERN long jround_up PP((long a, long b));
-EXTERN void jcopy_sample_rows PP((JSAMPARRAY input_array, int source_row,
-				  JSAMPARRAY output_array, int dest_row,
-				  int num_rows, long num_cols));
-EXTERN void jcopy_block_row PP((JBLOCKROW input_row, JBLOCKROW output_row,
-				long num_blocks));
-EXTERN void jzero_far PP((void FAR * target, size_t bytestozero));
-
-/* method selection routines for compression modules */
-EXTERN void jselcpipeline PP((compress_info_ptr cinfo)); /* jcpipe.c */
-EXTERN void jselchuffman PP((compress_info_ptr cinfo)); /* jchuff.c */
-EXTERN void jselcarithmetic PP((compress_info_ptr cinfo)); /* jcarith.c */
-EXTERN void jselexpand PP((compress_info_ptr cinfo)); /* jcexpand.c */
-EXTERN void jselsubsample PP((compress_info_ptr cinfo)); /* jcsample.c */
-EXTERN void jselcmcu PP((compress_info_ptr cinfo)); /* jcmcu.c */
-EXTERN void jselccolor PP((compress_info_ptr cinfo));	/* jccolor.c */
-/* The user interface should call one of these to select input format: */
-EXTERN void jselrgif PP((compress_info_ptr cinfo)); /* jrdgif.c */
-EXTERN void jselrppm PP((compress_info_ptr cinfo)); /* jrdppm.c */
-EXTERN void jselrrle PP((compress_info_ptr cinfo)); /* jrdrle.c */
-EXTERN void jselrtarga PP((compress_info_ptr cinfo)); /* jrdtarga.c */
-/* and one of these to select output header format: */
-EXTERN void jselwjfif PP((compress_info_ptr cinfo)); /* jwrjfif.c */
-
-/* method selection routines for decompression modules */
-EXTERN void jseldpipeline PP((decompress_info_ptr cinfo)); /* jdpipe.c */
-EXTERN void jseldhuffman PP((decompress_info_ptr cinfo)); /* jdhuff.c */
-EXTERN void jseldarithmetic PP((decompress_info_ptr cinfo)); /* jdarith.c */
-EXTERN void jseldmcu PP((decompress_info_ptr cinfo)); /* jdmcu.c */
-EXTERN void jselbsmooth PP((decompress_info_ptr cinfo)); /* jbsmooth.c */
-EXTERN void jselunsubsample PP((decompress_info_ptr cinfo)); /* jdsample.c */
-EXTERN void jseldcolor PP((decompress_info_ptr cinfo));	/* jdcolor.c */
-EXTERN void jsel1quantize PP((decompress_info_ptr cinfo)); /* jquant1.c */
-EXTERN void jsel2quantize PP((decompress_info_ptr cinfo)); /* jquant2.c */
-/* The user interface should call one of these to select input format: */
-EXTERN void jselrjfif PP((decompress_info_ptr cinfo)); /* jrdjfif.c */
-/* and one of these to select output image format: */
-EXTERN void jselwgif PP((decompress_info_ptr cinfo)); /* jwrgif.c */
-EXTERN void jselwppm PP((decompress_info_ptr cinfo)); /* jwrppm.c */
-EXTERN void jselwrle PP((decompress_info_ptr cinfo)); /* jwrrle.c */
-EXTERN void jselwtarga PP((decompress_info_ptr cinfo)); /* jwrtarga.c */
-
-/* method selection routines for system-dependent modules */
-EXTERN void jselerror PP((external_methods_ptr emethods)); /* jerror.c */
-EXTERN void jselmemmgr PP((external_methods_ptr emethods)); /* jmemmgr.c */
-
+#ifdef EMBED
+  #define ERREXIT(emeth,msg) {tracef("Error:"); tracef(msg); newline(); EXIT}
+  #define ERREXIT1(emeth,msg,p1) {tracef("Error:"); tracef(msg _ p1); newline(); EXIT}
+  #define ERREXIT2(emeth,msg,p1,p2) {tracef("Error:"); tracef(msg _ p1 _ p2); newline(); EXIT}
+  #define ERREXIT3(emeth,msg,p1,p2,p3) {tracef("Error:"); tracef(msg _ p1 _ p2 _ p3); newline(); EXIT}
+  #define ERREXIT4(emeth,msg,p1,p2,p3,p4) {tracef("Error:"); tracef(msg _ p1 _ p2 _ p3 _ p4); newline(); EXIT}
+#else
+  #define ERREXIT(emeth,msg) {printf("Error:"); printf(msg); printf("\n"); exit(1);}
+  #define ERREXIT1(emeth,msg,p1) {printf("Error:"); printf(msg,p1); printf("\n"); exit(1);}
+  #define ERREXIT2(emeth,msg,p1,p2) {printf("Error:"); printf(msg,p1,p2); printf("\n"); exit(1);}
+  #define ERREXIT3(emeth,msg,p1,p2,p3) {printf("Error:"); printf(msg,p1,p2,p3); printf("\n"); exit(1);}
+  #define ERREXIT4(emeth,msg,p1,p2,p3,p4) {printf("Error:"); printf(msg,p1,p2,p3,p4); printf("\n"); exit(1);}
+#endif
 
 /* We assume that right shift corresponds to signed division by 2 with
  * rounding towards minus infinity.  This is correct for typical "arithmetic
diff -U 3 -H -b -B -d -p -r -N -- jpeg-5/jpeglib.h cvs/h/jpeglib
--- jpeg-5/jpeglib.h	1994-08-25 15:20:36.000000000 +0100
+++ cvs/h/jpeglib	1996-11-05 09:45:08.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jpeglib.h
  *
@@ -738,7 +755,6 @@ typedef JMETHOD(boolean, jpeg_marker_par
 #define jpeg_stdio_src		jStdSrc
 #define jpeg_set_defaults	jSetDefaults
 #define jpeg_set_colorspace	jSetColorspace
-#define jpeg_default_colorspace	jDefColorspace
 #define jpeg_set_quality	jSetQuality
 #define jpeg_set_linear_quality	jSetLQuality
 #define jpeg_add_quant_table	jAddQuantTable
@@ -787,7 +803,6 @@ EXTERN void jpeg_set_defaults JPP((j_com
 /* Compression parameter setup aids */
 EXTERN void jpeg_set_colorspace JPP((j_compress_ptr cinfo,
 				     J_COLOR_SPACE colorspace));
-EXTERN void jpeg_default_colorspace JPP((j_compress_ptr cinfo));
 EXTERN void jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
 				  boolean force_baseline));
 EXTERN void jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
diff -U 3 -H -b -B -d -p -r -N -- jpeg-3/jrdjfif.c cvs/c/jrdjfif
--- jpeg-3/jrdjfif.c	1992-01-17 23:28:05.000000000 +0000
+++ cvs/c/jrdjfif	1996-11-05 09:45:03.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jrdjfif.c
  *
@@ -24,6 +41,8 @@
  * These routines are invoked via the methods read_file_header,
  * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
  */
+#undef FILE_
+#define FILE_ (20000)
 
 #include "jinclude.h"
 
@@ -85,37 +104,6 @@ typedef enum {			/* JPEG marker codes */
 
 
 /*
- * Reload the input buffer after it's been emptied, and return the next byte.
- * This is exported for direct use by the entropy decoder.
- * See the JGETC macro for calling conditions.
- *
- * For this header control module, read_jpeg_data is supplied by the
- * user interface.  However, header formats that require random access
- * to the input file would need to supply their own code.  This code is
- * left here to indicate what is required.
- */
-
-#if 0				/* not needed in this module */
-
-METHODDEF int
-read_jpeg_data (decompress_info_ptr cinfo)
-{
-  cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
-
-  cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
-					cinfo->next_input_byte,
-					JPEG_BUF_SIZE);
-  
-  if (cinfo->bytes_in_buffer <= 0)
-    ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
-
-  return JGETC(cinfo);
-}
-
-#endif
-
-
-/*
  * Routines to parse JPEG markers & save away the useful info.
  */
 
@@ -196,8 +184,10 @@ get_dht (decompress_info_ptr cinfo)
     if (index < 0 || index >= NUM_HUFF_TBLS)
       ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
 
+#if 0
     if (*htblptr == NULL)
-      *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
+      *htblptr = (HUFF_TBL *) malloc (SIZEOF(HUFF_TBL));
+#endif
   
     memcpy((void *) (*htblptr)->bits, (void *) bits,
 	   SIZEOF((*htblptr)->bits));
@@ -262,9 +252,11 @@ get_dqt (decompress_info_ptr cinfo)
     if (n >= NUM_QUANT_TBLS)
       ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
       
+#if 0
     if (cinfo->quant_tbl_ptrs[n] == NULL)
       cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
-	(*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
+        malloc (SIZEOF(QUANT_TBL));
+#endif
     quant_ptr = cinfo->quant_tbl_ptrs[n];
 
     for (i = 0; i < DCTSIZE2; i++) {
@@ -394,8 +386,14 @@ get_sof (decompress_info_ptr cinfo, int 
   if (length != (cinfo->num_components * 3 + 8))
     ERREXIT(cinfo->emethods, "Bogus SOF length");
 
-  cinfo->comp_info = (jpeg_component_info *) (*cinfo->emethods->alloc_small)
+#if RISCOS
+  if (cinfo->num_components > 3)
+    ERREXIT(cinfo->emethods, "Too many colour components");
+  /* cinfo->comp_info set up already */
+#else
+  cinfo->comp_info = (jpeg_component_info *) malloc
 			(cinfo->num_components * SIZEOF(jpeg_component_info));
+#endif
   
   for (ci = 0; ci < cinfo->num_components; ci++) {
     compptr = &cinfo->comp_info[ci];
@@ -693,6 +691,7 @@ read_scan_header (decompress_info_ptr ci
 }
 
 
+#if 0
 /*
  * Finish up after a compressed scan (series of read_jpeg_data calls);
  * prepare for another read_scan_header call.
@@ -703,8 +702,9 @@ read_scan_trailer (decompress_info_ptr c
 {
   /* no work needed */
 }
+#endif
 
-
+#if 0
 /*
  * Finish up at the end of the file.
  */
@@ -714,8 +714,10 @@ read_file_trailer (decompress_info_ptr c
 {
   /* no work needed */
 }
+#endif
 
 
+#ifndef RISCOS
 /*
  * The method selection routine for standard JPEG header reading.
  * Note that this must be called by the user interface before calling
@@ -737,4 +739,5 @@ jselrjfif (decompress_info_ptr cinfo)
   cinfo->methods->read_file_trailer = read_file_trailer;
 }
 
+#endif
 #endif /* JFIF_SUPPORTED */
diff -U 3 -H -b -B -d -p -r -N -- jpeg-4/jrevdct.c cvs/c/jrevdct4
--- jpeg-4/jrevdct.c	1992-11-11 02:27:59.000000000 +0000
+++ cvs/c/jrevdct4	1996-11-05 09:45:03.000000000 +0000
@@ -1,3 +1,20 @@
+/* This source code in this file is licensed to You by Castle Technology
+ * Limited ("Castle") and its licensors on contractual terms and conditions
+ * ("Licence") which entitle you freely to modify and/or to distribute this
+ * source code subject to Your compliance with the terms of the Licence.
+ * 
+ * This source code has been made available to You without any warranties
+ * whatsoever. Consequently, Your use, modification and distribution of this
+ * source code is entirely at Your own risk and neither Castle, its licensors
+ * nor any other person who has contributed to this source code shall be
+ * liable to You for any loss or damage which You may suffer as a result of
+ * Your use, modification or distribution of this source code.
+ * 
+ * Full details of Your rights and obligations are set out in the Licence.
+ * You should have received a copy of the Licence with this source code file.
+ * If You have not received a copy, the text of the Licence is available
+ * online at www.castle-technology.co.uk/riscosbaselicence.htm
+ */
 /*
  * jrevdct.c
  *
@@ -17,6 +34,10 @@
  * multiplication; this allows a very simple and accurate implementation in
  * scaled fixed-point arithmetic, with a minimal number of shifts.
  */
+#undef FILE_
+#define FILE_ (30000)
+/* This version has been updated to include gathering of statistics,
+for tuning other implementations. */
 
 #include "jinclude.h"
 
@@ -66,8 +87,10 @@
  */
 
 #ifdef EIGHT_BIT_SAMPLES
-#define CONST_BITS  13
-#define PASS1_BITS  2
+/* #define CONST_BITS  13 */
+/* #define PASS1_BITS  2 */
+#define CONST_BITS 8
+#define PASS1_BITS  8
 #else
 #define CONST_BITS  13
 #define PASS1_BITS  1		/* lose a little precision to avoid overflow */
@@ -122,7 +145,14 @@
  * the fudge factor is correct for either sign of X.
  */
 
-#define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+/* special case for if we're trying to reduce precision and speed things ups */
+#if PASS1_BITS == CONST_BITS
+  #define DESCALE1(x,n)  (x)
+  #define DESCALE(x,n) (x)
+#else
+  #define DESCALE(x,n)  RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+  #define DESCALE1 DESCALE
+#endif
 
 /* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
  * For 8-bit samples with the recommended scaling, all the variable
@@ -135,26 +165,60 @@
  * NB: for 12-bit samples, a full 32-bit multiplication will be needed.
  */
 
-#ifdef EIGHT_BIT_SAMPLES
-#ifdef SHORTxSHORT_32		/* may work if 'int' is 32 bits */
-#define MULTIPLY(var,const)  (((INT16) (var)) * ((INT16) (const)))
-#endif
-#ifdef SHORTxLCONST_32		/* known to work with Microsoft C 6.0 */
-#define MULTIPLY(var,const)  (((INT16) (var)) * ((INT32) (const)))
-#endif
+#ifndef RISCOS
+  #ifdef EIGHT_BIT_SAMPLES
+  #ifdef SHORTxSHORT_32           /* may work if 'int' is 32 bits */
+  #define MULTIPLY(var,const)  (((INT16) (var)) * ((INT16) (const)))
+  #endif
+  #ifdef SHORTxLCONST_32          /* known to work with Microsoft C 6.0 */
+  #define MULTIPLY(var,const)  (((INT16) (var)) * ((INT32) (const)))
+  #endif
+  #endif
 #endif
 
 #ifndef MULTIPLY		/* default definition */
 #define MULTIPLY(var,const)  ((var) * (const))
 #endif
 
+#ifdef STATS
+static int how_many(int a, int b, int c, int d, int e, int f, int g, int h)
+/* How many of these 8 numbers are nonzero? */
+{
+  int i = 0;
+  if (a) i++;
+  if (b) i++;
+  if (c) i++;
+  if (d) i++;
+  if (e) i++;
+  if (f) i++;
+  if (g) i++;
+  if (h) i++;
+  return i;
+}
+
+static int how_many_row(DCTELEM *p, int size)
+{
+  return how_many(   p[0]     , p[1*size], p[2*size], p[3*size],
+                     p[4*size], p[5*size], p[6*size], p[7*size]);
+}
+
+#endif
 
 /*
  * Perform the inverse DCT on one block of coefficients.
  */
 
 GLOBAL void
-j_rev_dct (DCTBLOCK data)
+j_rev_dct (decompress_info_ptr cinfo, DCTBLOCK data, int count)
+/*
+ * NB in order to make the assembler equivalent more efficient, this routine
+ * now places its output at data-1, in row order. This is done as an
+ * entirely separate final pass.
+ *
+ * The output values are also unscaled, so you need to add 0x40000 and
+ * shift right by 19.
+ *
+ */
 {
   INT32 tmp0, tmp1, tmp2, tmp3;
   INT32 tmp10, tmp11, tmp12, tmp13;
@@ -163,6 +227,10 @@ j_rev_dct (DCTBLOCK data)
   int rowctr;
   SHIFT_TEMPS
 
+  for (; count > 0; count--, data = (DCTELEM*)data + DCTSIZE2) {
+
+  IFSTATS(cinfo->stats.n_jblocks++;)
+
   /* Pass 1: process rows. */
   /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
   /* furthermore, we scale the results by 2**PASS1_BITS. */
@@ -178,11 +246,17 @@ j_rev_dct (DCTBLOCK data)
      * row DCT calculations can be simplified this way.
      */
 
+      #ifdef STATS
+        cinfo->stats.n_lines_thismany_nonzero_coeffs_pass1[how_many_row(dataptr, 1)]++;
+      #endif
+
     if ((dataptr[1] | dataptr[2] | dataptr[3] | dataptr[4] |
 	 dataptr[5] | dataptr[6] | dataptr[7]) == 0) {
       /* AC terms all zero */
-      DCTELEM dcval = (DCTELEM) (dataptr[0] << PASS1_BITS);
+        DCTELEM dcval;
       
+        if (0 != (dcval = (DCTELEM) (dataptr[0] << PASS1_BITS)))
+        {
       dataptr[0] = dcval;
       dataptr[1] = dcval;
       dataptr[2] = dcval;
@@ -191,11 +265,33 @@ j_rev_dct (DCTBLOCK data)
       dataptr[5] = dcval;
       dataptr[6] = dcval;
       dataptr[7] = dcval;
+        }
+
+        #ifdef STATS
+          cinfo->stats.n_pass1_ac_zero++;
+          if (dcval == 0) cinfo->stats.n_pass1_ac_dc_zero++;
+        #endif
       
       dataptr += DCTSIZE;	/* advance pointer to next row */
       continue;
     }
 
+      #ifdef STATS
+        cinfo->stats.n_pass1_ac_nonzero++;
+        if (0 == how_many(0,0,0,0,dataptr[0],dataptr[2],dataptr[4],dataptr[6])) cinfo->stats.n_pass1_even_zero++;
+        if (0 == how_many(0,0,0,0,dataptr[1],dataptr[3],dataptr[5],dataptr[7])) cinfo->stats.n_pass1_odd_zero++;
+        else cinfo->stats.n_pass1_odd_nonzero++;
+
+        /* Look for cases where all the high frequency coeffs are zero */
+        {
+          int i;
+          for (i = DCTSIZE-1; i >= 0; i--) if (dataptr[i] != 0) break;
+          cinfo->stats.higher_coeff_all_zero[i]++;
+        }
+      #endif
+
+      /* printf("n "); */
+
     /* Even part: reverse the even part of the forward DCT. */
     /* The rotator is sqrt(2)*c(-6). */
 
@@ -248,14 +344,14 @@ j_rev_dct (DCTBLOCK data)
 
     /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
 
-    dataptr[0] = (DCTELEM) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[7] = (DCTELEM) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
-    dataptr[1] = (DCTELEM) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[6] = (DCTELEM) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
-    dataptr[2] = (DCTELEM) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[5] = (DCTELEM) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
-    dataptr[3] = (DCTELEM) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
-    dataptr[4] = (DCTELEM) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+      dataptr[0] = (DCTELEM) DESCALE1(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+      dataptr[7] = (DCTELEM) DESCALE1(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+      dataptr[1] = (DCTELEM) DESCALE1(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+      dataptr[6] = (DCTELEM) DESCALE1(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+      dataptr[2] = (DCTELEM) DESCALE1(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+      dataptr[5] = (DCTELEM) DESCALE1(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+      dataptr[3] = (DCTELEM) DESCALE1(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+      dataptr[4] = (DCTELEM) DESCALE1(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
 
     dataptr += DCTSIZE;		/* advance pointer to next row */
   }
@@ -274,7 +370,10 @@ j_rev_dct (DCTBLOCK data)
      * may be commented out.
      */
 
-#ifndef NO_ZERO_COLUMN_TEST
+      IFSTATS(cinfo->stats.n_lines_thismany_nonzero_coeffs_pass2[how_many_row(dataptr, DCTSIZE)]++;)
+
+  /* #ifndef NO_ZERO_COLUMN_TEST */
+  #if 0
     if ((dataptr[DCTSIZE*1] | dataptr[DCTSIZE*2] | dataptr[DCTSIZE*3] |
 	 dataptr[DCTSIZE*4] | dataptr[DCTSIZE*5] | dataptr[DCTSIZE*6] |
 	 dataptr[DCTSIZE*7]) == 0) {
@@ -290,10 +389,12 @@ j_rev_dct (DCTBLOCK data)
       dataptr[DCTSIZE*6] = dcval;
       dataptr[DCTSIZE*7] = dcval;
       
+        /* printf("z2 "); */
+        
       dataptr++;		/* advance pointer to next column */
       continue;
     }
-#endif
+  #endif
 
     /* Even part: reverse the even part of the forward DCT. */
     /* The rotator is sqrt(2)*c(-6). */
@@ -366,4 +467,19 @@ j_rev_dct (DCTBLOCK data)
     
     dataptr++;			/* advance pointer to next column */
   }
+
+    /* Final pass to place output in an order compatible with the
+    assembler equivalent. */
+    dataptr = data;
+    {
+      int *inptr = dataptr;
+      int *outptr = inptr - 64;
+      int col;
+      int row;
+
+      for (row = 0; row < 8; row++)
+        for (col = 0; col < 8; col++)
+          outptr[row + 8 * col] = inptr[row * 8 + col];
+    }
+  }
 }