summaryrefslogtreecommitdiffstats
path: root/kernel/kls_ljpeg/ljpeg2ppm
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kls_ljpeg/ljpeg2ppm')
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Copyright79
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/Makefile.am5
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/huffd.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/io.h105
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/jpeg.h249
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c263
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.c125
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/mcu.h63
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.c189
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/predictor.h176
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/proto.h75
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/read.c665
-rw-r--r--kernel/kls_ljpeg/ljpeg2ppm/util.c297
13 files changed, 2956 insertions, 0 deletions
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Copyright b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
new file mode 100644
index 0000000..5fae625
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Copyright
@@ -0,0 +1,79 @@
+Copyright (c) 1993 Cornell University, Kongji Huang
+All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for research purposes, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE
+UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+
+Copyright (c) 1993 The Regents of the University of California, Brian
+C. Smith All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without written
+agreement is hereby granted, provided that the above copyright notice
+and the following two paragraphs appear in all copies of this
+software.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
+ENHANCEMENTS, OR MODIFICATIONS.
+
+---------------------------------------------------------------------------
+IJG Copyright
+
+The authors make NO WARRANTY or representation, either express or
+implied, with respect to this software, its quality, accuracy,
+merchantability, or fitness for a particular purpose. This software is
+provided "AS IS", and you, its user, assume the entire risk as to its
+quality and accuracy.
+
+This software is copyright (C) 1991, 1992, Thomas G. Lane. All Rights
+Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to
+these conditions: (1) If any part of the source code for this software
+is distributed, then this README file must be included, with this
+copyright and no-warranty notice unaltered; and any additions,
+deletions, or changes to the original files must be clearly indicated
+in accompanying documentation. (2) If only executable code is
+distributed, then the accompanying documentation must state that "this
+software is based in part on the work of the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user
+accepts full responsibility for any undesirable consequences; the
+authors accept NO LIABILITY for damages of any kind.
+
+Permission is NOT granted for the use of any IJG author's name or
+company name in advertising or publicity relating to this software or
+products derived from it. This software may be referred to only as
+"the Independent JPEG Group's software".
+
+We specifically permit and encourage the use of this software as the
+basis of commercial products, provided that all warranty or liability
+claims are assumed by the product vendor.
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
new file mode 100644
index 0000000..8d9632e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/Makefile.am
@@ -0,0 +1,5 @@
+#INCLUDES = -I../include
+
+bin_PROGRAMS = ksquirrel-libs-ljpeg2ppm
+
+ksquirrel_libs_ljpeg2ppm_SOURCES = huffd.c io.h jpeg.h ljpgtopnm.c mcu.c mcu.h predictor.c predictor.h proto.h read.c util.c
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/huffd.c b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
new file mode 100644
index 0000000..da5d2e9
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/huffd.c
@@ -0,0 +1,665 @@
+/*
+ * huffd.c --
+ *
+ * Code for JPEG lossless decoding. Large parts are grabbed from the IJG
+ * software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+#include "predictor.h"
+
+#define RST0 0xD0 /* RST0 marker code */
+
+static long getBuffer; /* current bit-extraction buffer */
+static int bitsLeft; /* # of unused bits in it */
+
+/*
+ * The following variables keep track of the input buffer
+ * for the JPEG data, which is read by ReadJpegData.
+ */
+Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+int numInputBytes; /* The total number of bytes in inputBuffer */
+int maxInputBytes; /* Size of inputBuffer */
+int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * Code for extracting the next N bits from the input stream.
+ * (N never exceeds 15 for JPEG data.)
+ * This needs to go as fast as possible!
+ *
+ * We read source bytes into getBuffer and dole out bits as needed.
+ * If getBuffer already contains enough bits, they are fetched in-line
+ * by the macros get_bits() and get_bit(). When there aren't enough bits,
+ * FillBitBuffer is called; it will attempt to fill getBuffer to the
+ * "high water mark", then extract the desired number of bits. The idea,
+ * of course, is to minimize the function-call overhead cost of entering
+ * FillBitBuffer.
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of getBuffer to be used. (On machines with wider words, an even larger
+ * buffer could be used.)
+ */
+
+#define BITS_PER_LONG (8*sizeof(long))
+#define MIN_GET_BITS (BITS_PER_LONG-7) /* max value for long getBuffer */
+
+/*
+ * bmask[n] is mask for n rightmost bits
+ */
+static int bmask[] = {0x0000,
+ 0x0001, 0x0003, 0x0007, 0x000F,
+ 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
+ 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FillBitBuffer --
+ *
+ * Load up the bit buffer with at least nbits
+ * Process any stuffed bytes at this time.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The bitwise global variables are updated.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+FillBitBuffer (nbits)
+ int nbits;
+{
+ int c, c2;
+
+ while (bitsLeft < MIN_GET_BITS) {
+ c = GetJpegChar ();
+
+ /*
+ * If it's 0xFF, check and discard stuffed zero byte
+ */
+ if (c == 0xFF) {
+ c2 = GetJpegChar ();
+
+ if (c2 != 0) {
+
+ /*
+ * Oops, it's actually a marker indicating end of
+ * compressed data. Better put it back for use later.
+ */
+ UnGetJpegChar (c2);
+ UnGetJpegChar (c);
+
+ /*
+ * There should be enough bits still left in the data
+ * segment; if so, just break out of the while loop.
+ */
+ if (bitsLeft >= nbits)
+ break;
+
+ /*
+ * Uh-oh. Corrupted data: stuff zeroes into the data
+ * stream, since this sometimes occurs when we are on the
+ * last show_bits(8) during decoding of the Huffman
+ * segment.
+ */
+ c = 0;
+ }
+ }
+ /*
+ * OK, load c into getBuffer
+ */
+ getBuffer = (getBuffer << 8) | c;
+ bitsLeft += 8;
+ }
+}
+
+/* Macros to make things go at some speed! */
+/* NB: parameter to get_bits should be simple variable, not expression */
+
+#define show_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = (getBuffer >> (bitsLeft-(nbits))) & bmask[nbits]; \
+}
+
+#define show_bits8(rv) { \
+ if (bitsLeft < 8) FillBitBuffer(8); \
+ rv = (getBuffer >> (bitsLeft-8)) & 0xff; \
+}
+
+#define flush_bits(nbits) { \
+ bitsLeft -= (nbits); \
+}
+
+#define get_bits(nbits,rv) { \
+ if (bitsLeft < nbits) FillBitBuffer(nbits); \
+ rv = ((getBuffer >> (bitsLeft -= (nbits)))) & bmask[nbits]; \
+}
+
+#define get_bit(rv) { \
+ if (!bitsLeft) FillBitBuffer(1); \
+ rv = (getBuffer >> (--bitsLeft)) & 1; \
+}
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+PmPutRow(RowBuf,numComp,numCol,Pt)
+ MCU *RowBuf;
+ int numCol,Pt;
+{
+ register int col,v;
+
+ /*
+ * Mulitply 2^Pt before output. Pt is the point
+ * transform parameter.
+ */
+ if (numComp==1) { /*pgm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ }
+ } else { /*ppm*/
+ for (col = 0; col < numCol; col++) {
+ v=RowBuf[col][0]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][1]<<Pt;
+ (void)putc(v,outFile);
+ v=RowBuf[col][2]<<Pt;
+ (void)putc(v,outFile);
+ }
+ }
+}
+#else
+/*
+ *--------------------------------------------------------------
+ *
+ * PmPutRow --
+ *
+ * Output one row of pixels stored in RowBuf.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * One row of pixels are write to file pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+#define PmPutRow(RowBuf,numComp,numCol,Pt) \
+{ register int col,v; \
+ if (numComp==1) { /*pgm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } else { /*ppm*/ \
+ for (col = 0; col < numCol; col++) { \
+ v=RowBuf[col][0]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][1]<<Pt; \
+ (void)putc(v,outFile); \
+ v=RowBuf[col][2]<<Pt; \
+ (void)putc(v,outFile); \
+ } \
+ } \
+}
+#endif
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecode --
+ *
+ * Taken from Figure F.16: extract next coded symbol from
+ * input stream. This should becode a macro.
+ *
+ * Results:
+ * Next coded symbol
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+#define HuffDecode(htbl,rv) \
+{ \
+ int l, code, temp; \
+ \
+ /* \
+ * If the huffman code is less than 8 bits, we can use the fast \
+ * table lookup to get its value. It's more than 8 bits about \
+ * 3-4% of the time. \
+ */ \
+ show_bits8(code); \
+ if (htbl->numbits[code]) { \
+ flush_bits(htbl->numbits[code]); \
+ rv=htbl->value[code]; \
+ } else { \
+ flush_bits(8); \
+ l = 8; \
+ while (code > htbl->maxcode[l]) { \
+ get_bit(temp); \
+ code = (code << 1) | temp; \
+ l++; \
+ } \
+ \
+ /* \
+ * With garbage input we may reach the sentinel value l = 17. \
+ */ \
+ \
+ if (l > 16) { \
+ fprintf (stderr, "Corrupt JPEG data: bad Huffman code"); \
+ rv = 0; /* fake a zero as the safest result */ \
+ } else { \
+ rv = htbl->huffval[htbl->valptr[l] + \
+ ((int)(code - htbl->mincode[l]))]; \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffExtend --
+ *
+ * Code and table for Figure F.12: extend sign bit
+ *
+ * Results:
+ * The extended value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static int extendTest[16] = /* entry n is 2**(n-1) */
+{0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
+
+static int extendOffset[16] = /* entry n is (-1 << n) + 1 */
+{0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
+ ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
+ ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
+ ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
+
+#define HuffExtend(x,s) { \
+ if ((x) < extendTest[s]) { \
+ (x) += extendOffset[s]; \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * HuffDecoderInit --
+ *
+ * Initialize for a Huffman-compressed scan.
+ * This is invoked after reading the SOS marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+HuffDecoderInit (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ short ci;
+ JpegComponentInfo *compptr;
+
+ /*
+ * Initialize static variables
+ */
+ bitsLeft = 0;
+
+ for (ci = 0; ci < dcPtr->compsInScan; ci++) {
+ compptr = dcPtr->curCompInfo[ci];
+ /*
+ * Make sure requested tables are present
+ */
+ if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
+ fprintf (stderr, "Error: Use of undefined Huffman table\n");
+ exit (1);
+ }
+
+ /*
+ * Compute derived values for Huffman tables.
+ * We may do this more than once for same table, but it's not a
+ * big deal
+ */
+ FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
+ }
+
+ /*
+ * Initialize restart stuff
+ */
+ dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessRestart --
+ *
+ * Check for a restart marker & resynchronize decoder.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * BitStream is parsed, bit buffer is reset, etc.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ProcessRestart (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+ short ci;
+
+ /*
+ * Throw away any unused bits remaining in bit buffer
+ */
+ nbytes = bitsLeft / 8;
+ bitsLeft = 0;
+
+ /*
+ * Scan for next JPEG marker
+ */
+ do {
+ do { /* skip any non-FF bytes */
+ nbytes++;
+ c = GetJpegChar ();
+ } while (c != 0xFF);
+ do { /* skip any duplicate FFs */
+ /*
+ * we don't increment nbytes here since extra FFs are legal
+ */
+ c = GetJpegChar ();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ if (c != (RST0 + dcPtr->nextRestartNum)) {
+
+ /*
+ * Uh-oh, the restart markers have been messed up too.
+ * Just bail out.
+ */
+ fprintf (stderr, "Error: Corrupt JPEG data. Exiting...\n");
+ exit(-1);
+ }
+
+ /*
+ * Update restart state
+ */
+ dcPtr->restartRowsToGo = dcPtr->restartInRows;
+ dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeFirstRow --
+ *
+ * Decode the first raster line of samples at the start of
+ * the scan and at the beginning of each restart interval.
+ * This includes modifying the component value so the real
+ * value, not the difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void DecodeFirstRow(dcPtr,curRowBuf)
+ DecompressInfo *dcPtr;
+ MCU *curRowBuf;
+{
+ register short curComp,ci;
+ register int s,col,compsInScan,numCOL;
+ register JpegComponentInfo *compptr;
+ int Pr,Pt,d;
+ HuffmanTable *dctbl;
+
+ Pr=dcPtr->dataPrecision;
+ Pt=dcPtr->Pt;
+ compsInScan=dcPtr->compsInScan;
+ numCOL=dcPtr->imageWidth;
+
+ /*
+ * the start of the scan or at the beginning of restart interval.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
+ }
+
+ /*
+ * the rest of the first row
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ /*
+ * Add the predictor to the difference.
+ */
+ curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
+ }
+ }
+
+ if (dcPtr->restartInRows) {
+ (dcPtr->restartRowsToGo)--;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecodeImage --
+ *
+ * Decode the input stream. This includes modifying
+ * the component value so the real value, not the
+ * difference is returned.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecodeImage(dcPtr)
+ DecompressInfo *dcPtr;
+{
+ register int s,d,col,row;
+ register short curComp, ci;
+ HuffmanTable *dctbl;
+ JpegComponentInfo *compptr;
+ int predictor;
+ int numCOL,numROW,compsInScan;
+ MCU *prevRowBuf,*curRowBuf;
+ int imagewidth,Pt,psv;
+
+ numCOL=imagewidth=dcPtr->imageWidth;
+ numROW=dcPtr->imageHeight;
+ compsInScan=dcPtr->compsInScan;
+ Pt=dcPtr->Pt;
+ psv=dcPtr->Ss;
+ prevRowBuf=mcuROW2;
+ curRowBuf=mcuROW1;
+
+ /*
+ * Decode the first row of image. Output the row and
+ * turn this row into a previous row for later predictor
+ * calculation.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+
+ for (row=1; row<numROW; row++) {
+
+ /*
+ * Account for restart interval, process restart marker if needed.
+ */
+ if (dcPtr->restartInRows) {
+ if (dcPtr->restartRowsToGo == 0) {
+ ProcessRestart (dcPtr);
+
+ /*
+ * Reset predictors at restart.
+ */
+ DecodeFirstRow(dcPtr,curRowBuf);
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ continue;
+ }
+ dcPtr->restartRowsToGo--;
+ }
+
+ /*
+ * The upper neighbors are predictors for the first column.
+ */
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+
+ curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
+ }
+
+ /*
+ * For the rest of the column on this row, predictor
+ * calculations are base on PSV.
+ */
+ for (col=1; col<numCOL; col++) {
+ for (curComp = 0; curComp < compsInScan; curComp++) {
+ ci = dcPtr->MCUmembership[curComp];
+ compptr = dcPtr->curCompInfo[ci];
+ dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
+
+ /*
+ * Section F.2.2.1: decode the difference
+ */
+ HuffDecode (dctbl,s);
+ if (s) {
+ get_bits(s,d);
+ HuffExtend(d,s);
+ } else {
+ d = 0;
+ }
+ QuickPredict(col,curComp,curRowBuf,prevRowBuf,
+ psv,&predictor);
+
+ curRowBuf[col][curComp]=d+predictor;
+ }
+ }
+ PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
+ swap(MCU *,prevRowBuf,curRowBuf);
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/io.h b/kernel/kls_ljpeg/ljpeg2ppm/io.h
new file mode 100644
index 0000000..65d9636
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/io.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _IO
+#define _IO
+
+/*
+ * Size of the input and output buffer
+ */
+#define JPEG_BUF_SIZE 4096
+
+/*
+ * The following variables keep track of the input and output
+ * buffer for the JPEG data.
+ */
+extern char outputBuffer[JPEG_BUF_SIZE]; /* output buffer */
+extern int numOutputBytes; /* bytes in the output buffer */
+extern Uchar inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
+extern int numInputBytes; /* bytes in inputBuffer */
+extern int maxInputBytes; /* Size of inputBuffer */
+extern int inputBufferOffset; /* Offset of current byte */
+
+/*
+ * the output file pointer.
+ */
+extern FILE *outFile;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * EmitByte --
+ *
+ * Write a single byte out to the output buffer, and
+ * flush if it's full.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The outp[ut buffer may get flushed.
+ *
+ *--------------------------------------------------------------
+ */
+#define EmitByte(val) { \
+ if (numOutputBytes >= JPEG_BUF_SIZE) { \
+ FlushBytes(); \
+ } \
+ outputBuffer[numOutputBytes++] = (char)(val); \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetJpegChar, UnGetJpegChar --
+ *
+ * Macros to get the next character from the input stream.
+ *
+ * Results:
+ * GetJpegChar returns the next character in the stream, or EOF
+ * UnGetJpegChar returns nothing.
+ *
+ * Side effects:
+ * A byte is consumed or put back into the inputBuffer.
+ *
+ *--------------------------------------------------------------
+ */
+#define GetJpegChar() \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ (numInputBytes = 2+ReadJpegData(inputBuffer+2,JPEG_BUF_SIZE-2), \
+ inputBufferOffset = 2, \
+ ((inputBufferOffset < numInputBytes)? \
+ inputBuffer[inputBufferOffset++]: \
+ EOF)))
+
+#define UnGetJpegChar(ch) (inputBuffer[--inputBufferOffset]=(ch))
+
+#endif /* _IO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
new file mode 100644
index 0000000..44a41cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/jpeg.h
@@ -0,0 +1,249 @@
+/*
+ * jpeg.h --
+ *
+ * Basic jpeg data structure definitions.
+ *
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _JPEG
+#define _JPEG
+
+typedef unsigned char Uchar;
+typedef unsigned short Ushort;
+typedef unsigned int Uint;
+
+/*
+ * The following structure stores basic information about one component.
+ */
+typedef struct JpegComponentInfo {
+ /*
+ * These values are fixed over the whole image.
+ * They are read from the SOF marker.
+ */
+ short componentId; /* identifier for this component (0..255) */
+ short componentIndex; /* its index in SOF or cPtr->compInfo[] */
+
+ /*
+ * Downsampling is not normally used in lossless JPEG, although
+ * it is permitted by the JPEG standard (DIS). We set all sampling
+ * factors to 1 in this program.
+ */
+ short hSampFactor; /* horizontal sampling factor */
+ short vSampFactor; /* vertical sampling factor */
+
+ /*
+ * Huffman table selector (0..3). The value may vary
+ * between scans. It is read from the SOS marker.
+ */
+ short dcTblNo;
+} JpegComponentInfo;
+
+
+/*
+ * One of the following structures is created for each huffman coding
+ * table. We use the same structure for encoding and decoding, so there
+ * may be some extra fields for encoding that aren't used in the decoding
+ * and vice-versa.
+ */
+typedef struct HuffmanTable {
+ /*
+ * These two fields directly represent the contents of a JPEG DHT
+ * marker
+ */
+ Uchar bits[17];
+ Uchar huffval[256];
+
+ /*
+ * 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.
+ */
+ int sentTable;
+
+ /*
+ * 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.
+ */
+ Ushort ehufco[256];
+ char ehufsi[256];
+
+ Ushort mincode[17];
+ int maxcode[18];
+ short valptr[17];
+ int numbits[256];
+ int value[256];
+} HuffmanTable;
+
+/*
+ * One of the following structures is used to pass around the
+ * compression information.
+ */
+typedef struct CompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * Pointers to Huffman coding tables, or NULL if not defined.
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * These fields are private data for the entropy encoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} CompressInfo;
+
+/*
+ * One of the following structures is used to pass around the
+ * decompression information.
+ */
+typedef struct DecompressInfo {
+ /*
+ * Image width, height, and image data precision (bits/sample)
+ * These fields are set by ReadFileHeader or ReadScanHeader
+ */
+ int imageWidth;
+ int imageHeight;
+ int dataPrecision;
+
+ /*
+ * compInfo[i] describes component that appears i'th in SOF
+ * numComponents is the # of color components in JPEG image.
+ */
+ JpegComponentInfo *compInfo;
+ short numComponents;
+
+ /*
+ * *curCompInfo[i] describes component that appears i'th in SOS.
+ * compsInScan is the # of color components in current scan.
+ */
+ JpegComponentInfo *curCompInfo[4];
+ short compsInScan;
+
+ /*
+ * MCUmembership[i] indexes the i'th component of MCU into the
+ * curCompInfo array.
+ */
+ short MCUmembership[10];
+
+ /*
+ * ptrs to Huffman coding tables, or NULL if not defined
+ */
+ HuffmanTable *dcHuffTblPtrs[4];
+
+ /*
+ * prediction seletion value (PSV) and point transform parameter (Pt)
+ */
+ int Ss;
+ int Pt;
+
+ /*
+ * In lossless JPEG, restart interval shall be an integer
+ * multiple of the number of MCU in a MCU row.
+ */
+ int restartInterval;/* MCUs per restart interval, 0 = no restart */
+ int restartInRows; /*if > 0, MCU rows per restart interval; 0 = no restart*/
+
+ /*
+ * these fields are private data for the entropy decoder
+ */
+ int restartRowsToGo; /* MCUs rows left in this restart interval */
+ short nextRestartNum; /* # of next RSTn marker (0..7) */
+} DecompressInfo;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * swap --
+ *
+ * Swap the contents stored in a and b.
+ * "type" is the variable type of a and b.
+ *
+ * Results:
+ * The values in a and b are swapped.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define swap(type,a,b) {type c; c=(a); (a)=(b); (b)=c;}
+
+#define MEMSET(s,c,n) memset((void *)(s),(int)(c),(int)(n))
+#define MEMCPY(s1,s2,n) memcpy((void *)(s1),(void *)(s2),(int)(n))
+
+/*
+ * Lossless JPEG specifies data precision to be from 2 to 16 bits/sample.
+ */
+#define MinPrecisionBits 2
+#define MaxPrecisionBits 16
+#define MinPrecisionValue 2
+#define MaxPrecisionValue 65535
+
+#endif /* _JPEG */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
new file mode 100644
index 0000000..c975892
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c
@@ -0,0 +1,263 @@
+/*
+ * ljpgtopnm.c --
+ *
+ * This is the main routine for the lossless JPEG decoder. Large
+ * parts are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+/*
+ * input and output file pointers
+ */
+FILE *inFile, *outFile;
+void FreeArray2D(char **);
+
+void WritePmHeader(DecompressInfo dcInfo);
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadJpegData --
+ *
+ * This is an interface routine to the JPEG library. The
+ * JPEG library calls this routine to "get more data"
+ *
+ * Results:
+ * Number of bytes actually returned.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadJpegData (buffer, numBytes)
+ char *buffer; /* Place to put new data */
+ int numBytes; /* Number of bytes to put */
+{
+ return fread(buffer, 1, numBytes, inFile);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * WritePmHeader --
+ *
+ * Output Portable Pixmap (PPM) or Portable
+ * Graymap (PGM) image header.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The PPM or PGM header is written to file
+ * pointed by outFile.
+ *
+ *--------------------------------------------------------------
+ */
+void
+WritePmHeader(dcInfo)
+DecompressInfo dcInfo;
+{
+ switch(dcInfo.numComponents) {
+ case 1: /* pgm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P5\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P5\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ case 3: /* ppm */
+ if (dcInfo.dataPrecision==8) {
+ fprintf(outFile,"P6\n%d %d\n255\n",
+ dcInfo.imageWidth,dcInfo.imageHeight);
+ } else {
+ fprintf(outFile,"P6\n%d %d\n%d\n",
+ dcInfo.imageWidth,dcInfo.imageHeight,
+ ((1<<dcInfo.dataPrecision)-1));
+ }
+ break;
+ default:
+ fprintf(stderr,"Error: Unsupported image format.\n");
+ exit(-1);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ArgParser --
+ *
+ * Command line parser.
+ *
+ * Results:
+ * Command line parameters and options are passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+ArgParser(argc,argv,verbose,linFile,loutFile)
+ int argc;
+ char **argv;
+ int *verbose;
+ FILE **linFile, **loutFile;
+{
+ int argn;
+ char *arg;
+ const char *usage="ppmtoljpeg [ -v -h ] [ inFile [outFile] ]";
+ int NumOfFile=0;
+
+ /*
+ * default values
+ */
+ *linFile=stdin;
+ *loutFile=stdout;
+ *verbose=0;
+
+ for (argn = 1; argn < argc; argn++) {
+ arg=argv[argn];
+ if (*arg != '-') { /* process a file name */
+ if (NumOfFile==0) {
+ if ((*linFile=fopen(arg,"r"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile==1) {
+ if ((*loutFile=fopen(arg,"w"))==NULL) {
+ fprintf(stderr,"Can't open %s\n",arg);
+ exit(-1);
+ }
+ }
+ if (NumOfFile>1) {
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ NumOfFile++;
+ }
+ else { /* precess a option */
+ arg++;
+ switch (*arg) {
+ case 'h':
+ /* help flag */
+ fprintf(stderr,"Decode a lossless JPEG image into ");
+ fprintf(stderr,"a PPM or PGM image.\n");
+ fprintf(stderr,"Usage:\n");
+ fprintf(stderr,"%s\n",usage);
+ fprintf(stderr,"Default input: stdin\n");
+ fprintf(stderr,"Default output: stdout\n");
+ fprintf(stderr,"-h help\n");
+ fprintf(stderr,"-v verbose\n");
+ exit(1);
+ break;
+ case 'v':
+ /* verbose flag */
+ *verbose=1;
+ break;
+ default:
+ fprintf(stderr,"%s\n",usage);
+ exit(-1);
+ }
+ }
+ }
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ DecompressInfo dcInfo;
+ int verbose;
+
+ /*
+ * Process command line parameters.
+ */
+ MEMSET(&dcInfo, 0, sizeof(dcInfo));
+ ArgParser(argc,argv,&verbose,&inFile,&outFile);
+
+ /*
+ * Read the JPEG File header, up to scan header, and initialize all
+ * the variables in the decompression information structure.
+ */
+ ReadFileHeader (&dcInfo);
+
+ /*
+ * Loop through each scan in image. ReadScanHeader returns
+ * 0 once it consumes and EOI marker.
+ */
+ if (!ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Empty JPEG file\n");
+ exit (1);
+ }
+
+ /*
+ * Output image parameter if verbose flag is on.
+ */
+ if (verbose) {
+ fprintf(stderr,"sample precision=%d\n",dcInfo.dataPrecision);
+ fprintf(stderr,"image height=%d\n",dcInfo.imageHeight);
+ fprintf(stderr,"image width=%d\n",dcInfo.imageWidth);
+ fprintf(stderr,"component=%d\n",dcInfo.numComponents);
+ }
+
+ /*
+ * Write PPM or PGM image header. Decode the image bits
+ * stream. Clean up everything when finished decoding.
+ */
+ WritePmHeader(dcInfo);
+ DecoderStructInit(&dcInfo);
+ HuffDecoderInit(&dcInfo);
+ DecodeImage(&dcInfo);
+ FreeArray2D(mcuROW1);
+ FreeArray2D(mcuROW2);
+
+ if (ReadScanHeader (&dcInfo)) {
+ fprintf (stderr, "Warning: multiple scans detected in JPEG file\n");
+ fprintf (stderr, " not currently supported\n");
+ fprintf (stderr, " ignoring extra scans\n");
+ }
+
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.c b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
new file mode 100644
index 0000000..bb1f0b3
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.c
@@ -0,0 +1,125 @@
+/*
+ * mcu.c --
+ *
+ * Support for MCU allocation, deallocation, and printing.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+MCU *mcuTable; /* the global mcu table that buffers the source image */
+MCU *mcuROW1, *mcuROW2; /* point to two rows of MCU in encoding & decoding */
+int numMCU; /* number of MCUs in mcuTable */
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU, InitMcuTable --
+ *
+ * InitMcuTable does a big malloc to get the amount of memory
+ * we'll need for storing MCU's, once we know the size of our
+ * input and output images.
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+InitMcuTable(lnumMCU,compsInScan)
+ int lnumMCU;
+ int compsInScan;
+{
+ int i, mcuSize;
+ char *buffer;
+
+ /*
+ * Compute size of on MCU (in bytes). Round up so it's on a
+ * boundary for any alignment. In this code, we assume this
+ * is a whole multiple of sizeof(double).
+ */
+ mcuSize = compsInScan * sizeof(ComponentType);
+ mcuSize = JroundUp(mcuSize,sizeof(double));
+
+ /*
+ * Allocate the MCU table, and a buffer which will contain all
+ * the data. Then carve up the buffer by hand. Note that
+ * mcuTable[0] points to the buffer, in case we want to free
+ * it up later.
+ */
+ mcuTable = (MCU *)malloc(lnumMCU * sizeof(MCU));
+ if (mcuTable==NULL)
+ fprintf(stderr,"Not enough memory for mcuTable\n");
+ buffer = (char *)malloc(lnumMCU * mcuSize);
+ if (buffer==NULL)
+ fprintf(stderr,"Not enough memory for buffer\n");
+ for (i=0; i<lnumMCU; i++) {
+ mcuTable[i] = (MCU)(buffer + i*mcuSize);
+ }
+}
+
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+/*
+ *--------------------------------------------------------------
+ *
+ * PrintMCU --
+ *
+ * Send an MCU in quasi-readable form to stdout.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+PrintMCU (compsInScan, mcu)
+ int compsInScan;
+ MCU mcu;
+{
+ ComponentType r;
+ int b;
+ static int callCount;
+
+ for (b=0; b<compsInScan; b++) {
+ callCount++;
+ r = mcu[b];
+ printf ("%d: %d ", callCount, r);
+ printf ("\n");
+ }
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/mcu.h b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
new file mode 100644
index 0000000..bb894e6
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/mcu.h
@@ -0,0 +1,63 @@
+/*
+ * mcu.h --
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _MCU
+#define _MCU
+
+/*
+ * An MCU (minimum coding unit) is an array of samples.
+ */
+typedef short ComponentType; /* the type of image components */
+typedef ComponentType *MCU; /* MCU - array of samples */
+
+extern MCU *mcuTable; /* the global mcu table that buffers the source image */
+extern int numMCU; /* number of MCUs in mcuTable */
+extern MCU *mcuROW1,*mcuROW2; /* pt to two rows of MCU in encoding & decoding */
+
+/*
+ *--------------------------------------------------------------
+ *
+ * MakeMCU --
+ *
+ * MakeMCU returns an MCU for input parsing.
+ *
+ * Results:
+ * A new MCU
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define MakeMCU(dcPtr) (mcuTable[numMCU++])
+
+#endif /* _MCU */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.c b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
new file mode 100644
index 0000000..36dedfd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.c
@@ -0,0 +1,189 @@
+/*
+ * predictor.c --
+ *
+ * Code for predictor calculation. Its macro version, predictor.h,
+ * is used in non-debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include "mcu.h"
+
+#ifdef DEBUG
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)
+ int row,col; /* position of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int Pr; /* data precision */
+ int Pt; /* point transformation */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ if (row==0) {
+
+ /*
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the
+ * predictors for rest of first row are left neighbors.
+ */
+ if (col==0) {
+ *predictor = (1<<(Pr-Pt-1));
+ }
+ else {
+ *predictor = curRowBuf[leftcol][curComp];
+ }
+ }
+ else {
+
+ /*
+ * The predictors of first column are upper neighbors.
+ * All other preditors are calculated according to psv.
+ */
+ upper=prevRowBuf[col][curComp];
+ if (col==0)
+ *predictor = upper;
+ else {
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor)
+ int col; /* column # of the pixel to be predicted */
+ int curComp; /* the pixel's component that is predicting */
+ MCU *curRowBuf,*prevRowBuf; /* current and previous row of image */
+ int psv; /* predictor selection value */
+ int *predictor; /* preditor value (output) */
+{
+ register int left,upper,diag,leftcol;
+
+ leftcol=col-1;
+ upper=prevRowBuf[col][curComp];
+ left=curRowBuf[leftcol][curComp];
+ diag=prevRowBuf[leftcol][curComp];
+
+ /*
+ * All predictor are calculated according to psv.
+ */
+ switch (psv) {
+ case 0:
+ *predictor = 0;
+ break;
+ case 1:
+ *predictor = left;
+ break;
+ case 2:
+ *predictor = upper;
+ break;
+ case 3:
+ *predictor = diag;
+ break;
+ case 4:
+ *predictor = left+upper-diag;
+ break;
+ case 5:
+ *predictor = left+((upper-diag)>>1);
+ break;
+ case 6:
+ *predictor = upper+((left-diag)>>1);
+ break;
+ case 7:
+ *predictor = (left+upper)>>1;
+ break;
+ default:
+ fprintf(stderr,"Warning: Undefined PSV\n");
+ *predictor = 0;
+ }
+}
+#endif /*DEBUG*/
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/predictor.h b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
new file mode 100644
index 0000000..a27b34e
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/predictor.h
@@ -0,0 +1,176 @@
+/*
+ * predictor.h --
+ *
+ * Code for predictor calculation. Its function version, predictor.c,
+ * is used in debugging compilation.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PREDICTOR
+#define _PREDICTOR
+
+#ifndef DEBUG
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Predict --
+ *
+ * Calculate the predictor for pixel[row][col][curComp],
+ * i.e. curRowBuf[col][curComp]. It handles the all special
+ * cases at image edges, such as first row and first column
+ * of a scan.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define Predict(row,col,curComp,curRowBuf,prevRowBuf,Pr,Pt,psv,predictor)\
+{ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ if (row==0) { \
+ \
+ /* \
+ * The predictor of first pixel is (1<<(Pr-Pt-1), and the \
+ * predictors for rest of first row are left neighbors. \
+ */ \
+ if (col==0) { \
+ *predictor = (1<<(Pr-Pt-1)); \
+ } \
+ else { \
+ *predictor = curRowBuf[leftcol][curComp]; \
+ } \
+ } \
+ else { \
+ \
+ /* \
+ * The predictors of first column are upper neighbors. \
+ * All other preditors are calculated according to psv. \
+ */ \
+ upper=prevRowBuf[col][curComp]; \
+ if (col==0) \
+ *predictor = upper; \
+ else { \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+ } \
+ } \
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * QuickPredict --
+ *
+ * Calculate the predictor for sample curRowBuf[col][curComp].
+ * It does not handle the special cases at image edges, such
+ * as first row and first column of a scan. We put the special
+ * case checkings outside so that the computations in main
+ * loop can be simpler. This has enhenced the performance
+ * significantly.
+ *
+ * Results:
+ * predictor is passed out.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+#define QuickPredict(col,curComp,curRowBuf,prevRowBuf,psv,predictor){ \
+ register int left,upper,diag,leftcol; \
+ \
+ leftcol=col-1; \
+ upper=prevRowBuf[col][curComp]; \
+ left=curRowBuf[leftcol][curComp]; \
+ diag=prevRowBuf[leftcol][curComp]; \
+ \
+ /* \
+ * All predictor are calculated according to psv. \
+ */ \
+ switch (psv) { \
+ case 0: \
+ *predictor = 0; \
+ break; \
+ case 1: \
+ *predictor = left; \
+ break; \
+ case 2: \
+ *predictor = upper; \
+ break; \
+ case 3: \
+ *predictor = diag; \
+ break; \
+ case 4: \
+ *predictor = left+upper-diag; \
+ break; \
+ case 5: \
+ *predictor = left+((upper-diag)>>1); \
+ break; \
+ case 6: \
+ *predictor = upper+((left-diag)>>1); \
+ break; \
+ case 7: \
+ *predictor = (left+upper)>>1; \
+ break; \
+ default: \
+ fprintf(stderr,"Warning: Undefined PSV\n"); \
+ *predictor = 0; \
+ } \
+}
+
+#endif /* DEBUG */
+#endif /* _PREDICTOR */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/proto.h b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
new file mode 100644
index 0000000..1188bae
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/proto.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _PROTO
+#define _PROTO
+
+#ifdef __STDC__
+# define P(s) s
+#else
+# define P(s) ()
+#endif
+
+
+/* huffc.c */
+void FlushBytes P((void ));
+void HuffEncoderInit P((CompressInfo *cPtr ));
+void HuffEncode P((CompressInfo *cPtr));
+void HuffEncoderTerm P((void ));
+
+/* huffd.c */
+void HuffDecoderInit P((DecompressInfo *dcPtr ));
+void DecodeImage P((DecompressInfo *dcPtr ));
+
+/* pnmtoljpg.c ljpgtopnm.c */
+int ReadJpegData P((char *buffer , int numBytes ));
+int WriteJpegData P((char *buffer , int numBytes));
+int main P((int argc , char **argv ));
+
+/* read.c */
+void ReadFileHeader P((DecompressInfo *dcPtr ));
+int ReadScanHeader P((DecompressInfo *dcPtr ));
+
+/* write.c */
+void WriteFileTrailer P((CompressInfo *cPtr ));
+void WriteScanHeader P((CompressInfo *cPtr ));
+void WriteFileHeader P((CompressInfo *cPtr ));
+
+/* util.c */
+int JroundUp P((int a , int b ));
+void DecoderStructInit P((DecompressInfo *dcPtr ));
+
+ /* mcu.c */
+void InitMcuTable P((int numMCU , int blocksInMCU ));
+void PrintMCU P((int blocksInMCU , MCU mcu ));
+
+#undef P
+
+#endif /* _PROTO */
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/read.c b/kernel/kls_ljpeg/ljpeg2ppm/read.c
new file mode 100644
index 0000000..e4855fd
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/read.c
@@ -0,0 +1,665 @@
+/*
+ * read.c --
+ *
+ * Code for reading and processing JPEG markers. Large parts are grabbed
+ * from the IJG software, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <string.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "io.h"
+#include "proto.h"
+
+/*
+ * Enumerate all the JPEG marker codes
+ */
+typedef enum {
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JpegMarker;
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Get2bytes --
+ *
+ * Get a 2-byte unsigned integer (e.g., a marker parameter length
+ * field)
+ *
+ * Results:
+ * Next two byte of input as an integer.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static Uint
+Get2bytes (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int a;
+
+ a = GetJpegChar();
+
+ return (a << 8) + GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * SkipVariable --
+ *
+ * Skip over an unknown or uninteresting variable-length marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed over marker.
+ *
+ *
+ *--------------------------------------------------------------
+ */
+static void
+SkipVariable (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length--) {
+ GetJpegChar();
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDht --
+ *
+ * Process a DHT marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * A huffman table is read.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDht (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ Uchar bits[17];
+ Uchar huffval[256];
+ int i, index, count;
+ HuffmanTable **htblptr;
+
+ length = Get2bytes (dcPtr) - 2;
+
+ while (length) {
+ index = GetJpegChar();
+
+ bits[0] = 0;
+ count = 0;
+ for (i = 1; i <= 16; i++) {
+ bits[i] = GetJpegChar();
+ count += bits[i];
+ }
+
+ if (count > 256) {
+ fprintf (stderr, "Bogus DHT counts");
+ exit (1);
+ }
+
+ for (i = 0; i < count; i++)
+ huffval[i] = GetJpegChar();
+
+ length -= 1 + 16 + count;
+
+ if (index & 0x10) { /* AC table definition */
+ fprintf(stderr,"Huffman table for lossless JPEG is not defined.\n");
+ } else { /* DC table definition */
+ htblptr = &dcPtr->dcHuffTblPtrs[index];
+ }
+
+ if (index < 0 || index >= 4) {
+ fprintf (stderr, "Bogus DHT index %d", index);
+ exit (1);
+ }
+
+ if (*htblptr == NULL) {
+ *htblptr = (HuffmanTable *) malloc (sizeof (HuffmanTable));
+ if (*htblptr==NULL) {
+ fprintf(stderr,"Can't malloc HuffmanTable\n");
+ exit(-1);
+ }
+ }
+
+ MEMCPY((*htblptr)->bits, bits, sizeof ((*htblptr)->bits));
+ MEMCPY((*htblptr)->huffval, huffval, sizeof ((*htblptr)->huffval));
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetDri --
+ *
+ * Process a DRI marker
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exits on error.
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetDri (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ if (Get2bytes (dcPtr) != 4) {
+ fprintf (stderr, "Bogus length in DRI");
+ exit (1);
+ }
+
+ dcPtr->restartInterval = (Ushort) Get2bytes (dcPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetApp0 --
+ *
+ * Process an APP0 marker.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Bitstream is parsed
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetApp0 (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+
+ length = Get2bytes (dcPtr) - 2;
+ while (length-- > 0) /* skip any remaining data */
+ (void)GetJpegChar();
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSof --
+ *
+ * Process a SOFn marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed
+ * Exits on error
+ * dcPtr structure is filled in
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSof (dcPtr, code)
+ DecompressInfo *dcPtr;
+ int code;
+{
+ int length;
+ short ci;
+ int c;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ dcPtr->dataPrecision = GetJpegChar();
+ dcPtr->imageHeight = Get2bytes (dcPtr);
+ dcPtr->imageWidth = Get2bytes (dcPtr);
+ dcPtr->numComponents = GetJpegChar();
+
+ /*
+ * We don't support files in which the image height is initially
+ * specified as 0 and is later redefined by DNL. As long as we
+ * have to check that, might as well have a general sanity check.
+ */
+ if ((dcPtr->imageHeight <= 0 ) ||
+ (dcPtr->imageWidth <= 0) ||
+ (dcPtr->numComponents <= 0)) {
+ fprintf (stderr, "Empty JPEG image (DNL not supported)");
+ exit(1);
+ }
+
+ if ((dcPtr->dataPrecision<MinPrecisionBits) ||
+ (dcPtr->dataPrecision>MaxPrecisionBits)) {
+ fprintf (stderr, "Unsupported JPEG data precision");
+ exit(1);
+ }
+
+ if (length != (dcPtr->numComponents * 3 + 8)) {
+ fprintf (stderr, "Bogus SOF length");
+ exit (1);
+ }
+
+ dcPtr->compInfo = (JpegComponentInfo *) malloc
+ (dcPtr->numComponents * sizeof (JpegComponentInfo));
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compptr = &dcPtr->compInfo[ci];
+ compptr->componentIndex = ci;
+ compptr->componentId = GetJpegChar();
+ c = GetJpegChar();
+ compptr->hSampFactor = (c >> 4) & 15;
+ compptr->vSampFactor = (c) & 15;
+ (void) GetJpegChar(); /* skip Tq */
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSos --
+ *
+ * Process a SOS marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSos (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int length;
+ int i, ci, n, c, cc;
+ JpegComponentInfo *compptr;
+
+ length = Get2bytes (dcPtr);
+
+ /*
+ * Get the number of image components.
+ */
+ n = GetJpegChar();
+ dcPtr->compsInScan = n;
+ length -= 3;
+
+ if (length != (n * 2 + 3) || n < 1 || n > 4) {
+ fprintf (stderr, "Bogus SOS length");
+ exit (1);
+ }
+
+
+ for (i = 0; i < n; i++) {
+ cc = GetJpegChar();
+ c = GetJpegChar();
+ length -= 2;
+
+ for (ci = 0; ci < dcPtr->numComponents; ci++)
+ if (cc == dcPtr->compInfo[ci].componentId) {
+ break;
+ }
+
+ if (ci >= dcPtr->numComponents) {
+ fprintf (stderr, "Invalid component number in SOS");
+ exit (1);
+ }
+
+ compptr = &dcPtr->compInfo[ci];
+ dcPtr->curCompInfo[i] = compptr;
+ compptr->dcTblNo = (c >> 4) & 15;
+ }
+
+ /*
+ * Get the PSV, skip Se, and get the point transform parameter.
+ */
+ dcPtr->Ss = GetJpegChar();
+ (void)GetJpegChar();
+ c = GetJpegChar();
+ dcPtr->Pt = c & 0x0F;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * GetSoi --
+ *
+ * Process an SOI marker
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ * Exits on error.
+ *
+ *--------------------------------------------------------------
+ */
+static void
+GetSoi (dcPtr)
+ DecompressInfo *dcPtr;
+{
+
+ /*
+ * Reset all parameters that are defined to be reset by SOI
+ */
+ dcPtr->restartInterval = 0;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * NextMarker --
+ *
+ * Find the next JPEG marker Note that the output might not
+ * be a valid marker code but it will never be 0 or FF
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static int
+NextMarker (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, nbytes;
+
+ nbytes = 0;
+ do {
+ /*
+ * skip any non-FF bytes
+ */
+ do {
+ nbytes++;
+ c = GetJpegChar();
+ } while (c != 0xFF);
+ /*
+ * skip any duplicate FFs without incrementing nbytes, since
+ * extra FFs are legal
+ */
+ do {
+ c = GetJpegChar();
+ } while (c == 0xFF);
+ } while (c == 0); /* repeat if it was a stuffed FF/00 */
+
+ return c;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ProcessTables --
+ *
+ * Scan and process JPEG markers that can appear in any order
+ * Return when an SOI, EOI, SOFn, or SOS is found
+ *
+ * Results:
+ * The marker found.
+ *
+ * Side effects:
+ * Bitstream is parsed.
+ *
+ *--------------------------------------------------------------
+ */
+static JpegMarker
+ProcessTables (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ while (1) {
+ c = NextMarker (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ case M_JPG:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ case M_SOI:
+ case M_EOI:
+ case M_SOS:
+ return ((JpegMarker)c);
+
+ case M_DHT:
+ GetDht (dcPtr);
+ break;
+
+ case M_DQT:
+ fprintf(stderr,"Not a lossless JPEG file.\n");
+ break;
+
+ case M_DRI:
+ GetDri (dcPtr);
+ break;
+
+ case M_APP0:
+ GetApp0 (dcPtr);
+ break;
+
+ case M_RST0: /* these are all parameterless */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ fprintf (stderr, "Warning: unexpected marker 0x%02x", c);
+ break;
+
+ default: /* must be DNL, DHP, EXP, APPn, JPGn, COM,
+ * or RESn */
+ SkipVariable (dcPtr);
+ break;
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadFileHeader --
+ *
+ * Initialize and read the file header (everything through
+ * the SOF marker).
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * Exit on error.
+ *
+ *--------------------------------------------------------------
+ */
+void
+ReadFileHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c, c2;
+
+ /*
+ * Demand an SOI marker at the start of the file --- otherwise it's
+ * probably not a JPEG file at all.
+ */
+ c = GetJpegChar();
+ c2 = GetJpegChar();
+ if ((c != 0xFF) || (c2 != M_SOI)) {
+ fprintf (stderr, "Not a JPEG file\n");
+ exit (1);
+ }
+
+ GetSoi (dcPtr); /* OK, process SOI */
+
+ /*
+ * Process markers until SOF
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF3:
+ GetSof (dcPtr, c);
+ break;
+
+ default:
+ fprintf (stderr, "Unsupported SOF marker type 0x%02x", c);
+ break;
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ReadScanHeader --
+ *
+ * Read the start of a scan (everything through the SOS marker).
+ *
+ * Results:
+ * 1 if find SOS, 0 if find EOI
+ *
+ * Side effects:
+ * Bitstream is parsed, may exit on errors.
+ *
+ *--------------------------------------------------------------
+ */
+int
+ReadScanHeader (dcPtr)
+ DecompressInfo *dcPtr;
+{
+ int c;
+
+ /*
+ * Process markers until SOS or EOI
+ */
+ c = ProcessTables (dcPtr);
+
+ switch (c) {
+ case M_SOS:
+ GetSos (dcPtr);
+ return 1;
+
+ case M_EOI:
+ return 0;
+
+ default:
+ fprintf (stderr, "Unexpected marker 0x%02x", c);
+ break;
+ }
+ return 0;
+}
diff --git a/kernel/kls_ljpeg/ljpeg2ppm/util.c b/kernel/kls_ljpeg/ljpeg2ppm/util.c
new file mode 100644
index 0000000..d5e99cb
--- /dev/null
+++ b/kernel/kls_ljpeg/ljpeg2ppm/util.c
@@ -0,0 +1,297 @@
+/*
+ * util.c --
+ *
+ * Various utility routines used in the jpeg encoder/decoder. Large parts
+ * are stolen from the IJG code, so:
+ *
+ * Copyright (C) 1991, 1992, Thomas G. Lane.
+ * Part of the Independent JPEG Group's software.
+ * See the file Copyright for more details.
+ *
+ * Copyright (c) 1993 Brian C. Smith, The Regents of the University
+ * of California
+ * All rights reserved.
+ *
+ * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
+ * Cornell University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include "jpeg.h"
+#include "mcu.h"
+#include "proto.h"
+
+void FreeArray2D(char **);
+void FixHuffTbl(HuffmanTable *);
+
+unsigned int bitMask[] = { 0xffffffff, 0x7fffffff, 0x3fffffff, 0x1fffffff,
+ 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff,
+ 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff,
+ 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff,
+ 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff,
+ 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff,
+ 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f,
+ 0x0000000f, 0x00000007, 0x00000003, 0x00000001};
+/*
+ *--------------------------------------------------------------
+ *
+ * JroundUp --
+ *
+ * Compute a rounded up to next multiple of b; a >= 0, b > 0
+ *
+ * Results:
+ * Rounded up value.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+int
+JroundUp (a, b)
+ int a, b;
+{
+ a += b - 1;
+ return a - (a % b);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * DecoderStructInit --
+ *
+ * Initalize the rest of the fields in the decompression
+ * structure.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+DecoderStructInit (dcPtr)
+ DecompressInfo *dcPtr;
+
+{
+ short ci,i;
+ JpegComponentInfo *compPtr;
+ char *buf1,*buf2;
+ int mcuSize;
+
+ /*
+ * Check sampling factor validity.
+ */
+ for (ci = 0; ci < dcPtr->numComponents; ci++) {
+ compPtr = &dcPtr->compInfo[ci];
+ if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
+ fprintf (stderr, "Error: Downsampling is not supported.\n");
+ exit(-1);
+ }
+ }
+
+ /*
+ * Prepare array describing MCU composition
+ */
+ if (dcPtr->compsInScan == 1) {
+ dcPtr->MCUmembership[0] = 0;
+ } else {
+ short lci;
+
+ if (dcPtr->compsInScan > 4) {
+ fprintf (stderr, "Too many components for interleaved scan");
+ exit (1);
+ }
+
+ for (lci = 0; lci < dcPtr->compsInScan; lci++) {
+ dcPtr->MCUmembership[lci] = lci;
+ }
+ }
+
+ /*
+ * Initialize mucROW1 and mcuROW2 which buffer two rows of
+ * pixels for predictor calculation.
+ */
+
+ if ((mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW1\n");
+ }
+ if ((mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
+ fprintf(stderr,"Not enough memory for mcuROW2\n");
+ }
+
+ mcuSize=dcPtr->compsInScan * sizeof(ComponentType);
+ if ((buf1 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf1\n");
+ }
+ if ((buf2 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
+ fprintf(stderr,"Not enough memory for buf2\n");
+ }
+
+ for (i=0;i<dcPtr->imageWidth;i++) {
+ mcuROW1[i]=(MCU)(buf1+i*mcuSize);
+ mcuROW2[i]=(MCU)(buf2+i*mcuSize);
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FixHuffTbl --
+ *
+ * Compute derived values for a Huffman table one the DHT marker
+ * has been processed. This generates both the encoding and
+ * decoding tables.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FixHuffTbl (htbl)
+ HuffmanTable *htbl;
+{
+ int p, i, l, lastp, si;
+ char huffsize[257];
+ Ushort huffcode[257];
+ Ushort code;
+ int size;
+ int value, ll, ul;
+
+ /*
+ * Figure C.1: make table of Huffman code length for each symbol
+ * Note that this is in code-length order.
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ for (i = 1; i <= (int)htbl->bits[l]; i++)
+ huffsize[p++] = (char)l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+
+ /*
+ * Figure C.2: generate the codes themselves
+ * Note that this is in code-length order.
+ */
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int)huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ /*
+ * Figure C.3: generate encoding tables
+ * These are code and size indexed by symbol value
+ * Set any codeless symbols to have code length 0; this allows
+ * EmitBits to detect any attempt to emit such symbols.
+ */
+ MEMSET(htbl->ehufsi, 0, sizeof(htbl->ehufsi));
+
+ for (p = 0; p < lastp; p++) {
+ htbl->ehufco[htbl->huffval[p]] = huffcode[p];
+ htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
+ }
+
+ /*
+ * Figure F.15: generate decoding tables
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (htbl->bits[l]) {
+ htbl->valptr[l] = p;
+ htbl->mincode[l] = huffcode[p];
+ p += htbl->bits[l];
+ htbl->maxcode[l] = huffcode[p - 1];
+ } else {
+ htbl->maxcode[l] = -1;
+ }
+ }
+
+ /*
+ * We put in this value to ensure HuffDecode terminates.
+ */
+ htbl->maxcode[17] = 0xFFFFFL;
+
+ /*
+ * Build the numbits, value lookup tables.
+ * These table allow us to gather 8 bits from the bits stream,
+ * and immediately lookup the size and value of the huffman codes.
+ * If size is zero, it means that more than 8 bits are in the huffman
+ * code (this happens about 3-4% of the time).
+ */
+ bzero (htbl->numbits, sizeof(htbl->numbits));
+ for (p=0; p<lastp; p++) {
+ size = huffsize[p];
+ if (size <= 8) {
+ value = htbl->huffval[p];
+ code = huffcode[p];
+ ll = code << (8-size);
+ if (size < 8) {
+ ul = ll | bitMask[24+size];
+ } else {
+ ul = ll;
+ }
+ for (i=ll; i<=ul; i++) {
+ htbl->numbits[i] = size;
+ htbl->value[i] = value;
+ }
+ }
+ }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FreeArray2D --
+ *
+ * Free the memory of a 2-D array pointed by arrayPtr.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The memory pointed by arrayPtr is freed.
+ *
+ *--------------------------------------------------------------
+ */
+void
+FreeArray2D(arrayPtr)
+ char **arrayPtr;
+{
+ free(arrayPtr[0]);
+ free(arrayPtr);
+}