diff options
Diffstat (limited to 'kernel/kls_ljpeg/ljpeg2ppm')
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/Copyright | 79 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/Makefile.am | 5 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/huffd.c | 665 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/io.h | 105 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/jpeg.h | 249 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/ljpgtopnm.c | 263 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/mcu.c | 125 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/mcu.h | 63 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/predictor.c | 189 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/predictor.h | 176 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/proto.h | 75 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/read.c | 665 | ||||
-rw-r--r-- | kernel/kls_ljpeg/ljpeg2ppm/util.c | 297 |
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); +} |