ljpegdecompressor.cpp

00001 /*
00002  * libopenraw - ljpegdecompressor.cpp
00003  *
00004  * Copyright (C) 2007 Hubert Figuiere
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
00019  */
00020 /*
00021  * Code for JPEG lossless decoding.  Large parts are grabbed from the IJG
00022  * software, so:
00023  *
00024  * Copyright (C) 1991, 1992, Thomas G. Lane.
00025  * Part of the Independent JPEG Group's software.
00026  * See the file Copyright for more details.
00027  *
00028  * Copyright (c) 1993 Brian C. Smith, The Regents of the University
00029  * of California
00030  * All rights reserved.
00031  * 
00032  * Copyright (c) 1994 Kongji Huang and Brian C. Smith.
00033  * Cornell University
00034  * All rights reserved.
00035  * 
00036  * Permission to use, copy, modify, and distribute this software and its
00037  * documentation for any purpose, without fee, and without written agreement is
00038  * hereby granted, provided that the above copyright notice and the following
00039  * two paragraphs appear in all copies of this software.
00040  * 
00041  * IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
00042  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00043  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
00044  * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00045  * 
00046  * CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00047  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00048  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00049  * ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
00050  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
00051  */
00052 
00053 
00054 #include <boost/scoped_ptr.hpp>
00055 #include <boost/scoped_array.hpp>
00056 #include <boost/format.hpp>
00057 
00058 #include <libopenraw++/rawdata.h>
00059 #include "io/memstream.h"
00060 #include "debug.h"
00061 #include "rawcontainer.h"
00062 #include "jfifcontainer.h"
00063 #include "ljpegdecompressor.h"
00064 #include "ljpegdecompressor_priv.h"
00065 #include "debug.h"
00066 
00067 namespace OpenRaw {
00068 
00069     using namespace Debug;
00070 
00071     namespace Internals {
00072 
00073 
00074         static void SkipVariable(IO::Stream *s);
00075         static uint16_t Get2bytes (IO::Stream * s);
00076         static int32_t  NextMarker(IO::Stream * );
00077         static void GetSoi(DecompressInfo *dcPtr);
00078         static void GetApp0(IO::Stream *);
00079 
00080         LJpegDecompressor::LJpegDecompressor(IO::Stream *stream,
00081                                                                                  RawContainer *container)
00082             : Decompressor(stream, container),
00083                 m_slices(),
00084                 m_mcuROW1(NULL), m_mcuROW2(NULL),
00085                 m_buf1(NULL), m_buf2(NULL),
00086                 m_bitsLeft(0),
00087                 m_getBuffer(0),
00088                 m_output(0)
00089         {
00090         }
00091 
00092 
00093         LJpegDecompressor::~LJpegDecompressor()
00094         {
00095             if(m_mcuROW1) {
00096                 free(m_mcuROW1);
00097             }
00098             if(m_mcuROW2) {
00099                 free(m_mcuROW2);
00100             }
00101             if(m_buf1) {
00102                 free(m_buf1);
00103             }
00104             if(m_buf2) {
00105                 free(m_buf2);
00106             }
00107         }
00108         
00109 
00110         void LJpegDecompressor::setSlices(const std::vector<uint16_t> & slices, 
00111                                                                             std::vector<uint16_t>::size_type idx)
00112         {
00113             m_slices.resize(slices.size() - idx);
00114             std::copy(slices.begin() + idx, slices.end(), m_slices.begin());
00115         }
00116         
00117 
00118 
00119         
00120         static uint32_t bitMask[] = {  0xffffffff, 0x7fffffff, 
00121                                                                              0x3fffffff, 0x1fffffff,
00122                                                                              0x0fffffff, 0x07ffffff, 
00123                                                                              0x03ffffff, 0x01ffffff,
00124                                                                              0x00ffffff, 0x007fffff, 
00125                                                                              0x003fffff, 0x001fffff,
00126                                                                              0x000fffff, 0x0007ffff, 
00127                                                                              0x0003ffff, 0x0001ffff,
00128                                                                              0x0000ffff, 0x00007fff, 
00129                                                                              0x00003fff, 0x00001fff,
00130                                                                              0x00000fff, 0x000007ff, 
00131                                                                              0x000003ff, 0x000001ff,
00132                                                                              0x000000ff, 0x0000007f, 
00133                                                                              0x0000003f, 0x0000001f,
00134                                                                              0x0000000f, 0x00000007, 
00135                                                                              0x00000003, 0x00000001};
00136 
00137 
00138 /*
00139  *--------------------------------------------------------------
00140  *
00141  * FixHuffTbl --
00142  *
00143  *      Compute derived values for a Huffman table one the DHT marker
00144  *      has been processed.  This generates both the encoding and
00145  *      decoding tables.
00146  *
00147  * Results:
00148  *      None.
00149  *
00150  * Side effects:
00151  *      None.
00152  *
00153  *--------------------------------------------------------------
00154  */
00155         void
00156         FixHuffTbl (HuffmanTable *htbl)
00157         {
00158             int32_t p, i, l, lastp, si;
00159             char huffsize[257];
00160             uint16_t huffcode[257];
00161             uint16_t code;
00162             int32_t size;
00163             int32_t value, ll, ul;
00164             
00165             /*
00166              * Figure C.1: make table of Huffman code length for each symbol
00167              * Note that this is in code-length order.
00168              */
00169             p = 0;
00170             for (l = 1; l <= 16; l++) {
00171         for (i = 1; i <= (int)htbl->bits[l]; i++)
00172                     huffsize[p++] = (char)l;
00173             }
00174             huffsize[p] = 0;
00175             lastp = p;
00176             
00177             
00178             /*
00179              * Figure C.2: generate the codes themselves
00180              * Note that this is in code-length order.
00181              */
00182             code = 0;
00183             si = huffsize[0];
00184             p = 0;
00185             while (huffsize[p]) {
00186         while (((int)huffsize[p]) == si) {
00187                     huffcode[p++] = code;
00188                     code++;
00189         }
00190         code <<= 1;
00191         si++;
00192             }
00193             
00194             /*
00195              * Figure C.3: generate encoding tables
00196              * These are code and size indexed by symbol value
00197              * Set any codeless symbols to have code length 0; this allows
00198              * EmitBits to detect any attempt to emit such symbols.
00199              */
00200             memset(htbl->ehufsi, 0, sizeof(htbl->ehufsi));
00201             
00202             for (p = 0; p < lastp; p++) {
00203         htbl->ehufco[htbl->huffval[p]] = huffcode[p];
00204         htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
00205             }
00206             
00207             /*
00208              * Figure F.15: generate decoding tables
00209              */
00210             p = 0;
00211             for (l = 1; l <= 16; l++) {
00212         if (htbl->bits[l]) {
00213                     htbl->valptr[l] = p;
00214                     htbl->mincode[l] = huffcode[p];
00215                     p += htbl->bits[l];
00216                     htbl->maxcode[l] = huffcode[p - 1];
00217         } else {
00218                     htbl->maxcode[l] = -1;
00219         }
00220             }
00221             
00222             /*
00223              * We put in this value to ensure HuffDecode terminates.
00224              */
00225             htbl->maxcode[17] = 0xFFFFFL;
00226             
00227             /*
00228              * Build the numbits, value lookup tables.
00229              * These table allow us to gather 8 bits from the bits stream,
00230              * and immediately lookup the size and value of the huffman codes.
00231              * If size is zero, it means that more than 8 bits are in the huffman
00232              * code (this happens about 3-4% of the time).
00233              */
00234             bzero (htbl->numbits, sizeof(htbl->numbits));
00235             for (p=0; p<lastp; p++) {
00236         size = huffsize[p];
00237         if (size <= 8) {
00238                     value = htbl->huffval[p];
00239                     code = huffcode[p];
00240                     ll = code << (8-size);
00241                     if (size < 8) {
00242                         ul = ll | bitMask[24+size];
00243                     } else {
00244                         ul = ll;
00245                     }
00246                     for (i=ll; i<=ul; i++) {
00247                         htbl->numbits[i] = size;
00248                         htbl->value[i] = value;
00249                     }
00250         }
00251             }
00252         }
00253 
00254 
00255 #define RST0    0xD0    /* RST0 marker code */
00256 
00257 
00258 #if 0
00259 /*
00260  * The following variables keep track of the input buffer
00261  * for the JPEG data, which is read by ReadJpegData.
00262  */
00263         uint8_t inputBuffer[JPEG_BUF_SIZE]; /* Input buffer for JPEG data */
00264         int numInputBytes;      /* The total number of bytes in inputBuffer */
00265         int maxInputBytes;      /* Size of inputBuffer */
00266         int inputBufferOffset;      /* Offset of current byte */
00267 #endif
00268 
00269 
00270 /*
00271  * Code for extracting the next N bits from the input stream.
00272  * (N never exceeds 15 for JPEG data.)
00273  * This needs to go as fast as possible!
00274  *
00275  * We read source bytes into getBuffer and dole out bits as needed.
00276  * If getBuffer already contains enough bits, they are fetched in-line
00277  * by the macros get_bits() and get_bit().  When there aren't enough bits,
00278  * fillBitBuffer is called; it will attempt to fill getBuffer to the
00279  * "high water mark", then extract the desired number of bits.  The idea,
00280  * of course, is to minimize the function-call overhead cost of entering
00281  * fillBitBuffer.
00282  * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
00283  * of getBuffer to be used.  (On machines with wider words, an even larger
00284  * buffer could be used.)  
00285  */
00286 
00287 #define BITS_PER_LONG   (8*sizeof(int32_t))
00288 #define MIN_GET_BITS  (BITS_PER_LONG-7)    /* max value for long getBuffer */
00289         
00290 /*
00291  * bmask[n] is mask for n rightmost bits
00292  */
00293         static int32_t bmask[] = {0x0000,
00294                                                     0x0001, 0x0003, 0x0007, 0x000F,
00295                                                     0x001F, 0x003F, 0x007F, 0x00FF,
00296                                                     0x01FF, 0x03FF, 0x07FF, 0x0FFF,
00297                                                     0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
00298         
00299 
00300 /*
00301  * Lossless JPEG specifies data precision to be from 2 to 16 bits/sample.
00302  */ 
00303 #define MinPrecisionBits 2
00304 #define MaxPrecisionBits 16
00305 
00306 
00307 /*
00308  *--------------------------------------------------------------
00309  *
00310  * DecoderStructInit --
00311  *
00312  *  Initalize the rest of the fields in the decompression
00313  *  structure.
00314  *
00315  * Results:
00316  *  None.
00317  *
00318  * Side effects:
00319  *  None.
00320  *
00321  *--------------------------------------------------------------
00322  */
00323         void
00324         LJpegDecompressor::DecoderStructInit (DecompressInfo *dcPtr)
00325             throw(DecodingException)
00326         {
00327             int16_t ci,i;
00328             JpegComponentInfo *compPtr;
00329             int32_t mcuSize;
00330 
00331             /*
00332              * Check sampling factor validity.
00333              */
00334             for (ci = 0; ci < dcPtr->numComponents; ci++) {
00335                 compPtr = &dcPtr->compInfo[ci];
00336                 if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
00337                     throw DecodingException("Error: Downsampling is not supported.\n");
00338                 }
00339             }
00340 
00341             /*
00342              * Prepare array describing MCU composition
00343              */
00344             if (dcPtr->compsInScan == 1) {
00345                 dcPtr->MCUmembership[0] = 0;
00346             } else {
00347                 if (dcPtr->compsInScan > 4) {
00348                     throw DecodingException("Too many components for interleaved scan");
00349                 }
00350 
00351                 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
00352                     dcPtr->MCUmembership[ci] = ci;
00353                 }
00354             }
00355 
00356             /*
00357              * Initialize mucROW1 and mcuROW2 which buffer two rows of
00358              * pixels for predictor calculation.
00359              */
00360 
00361             if ((m_mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
00362                 throw DecodingException("Not enough memory for mcuROW1\n");
00363             }
00364             if ((m_mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
00365                 throw DecodingException("Not enough memory for mcuROW2\n");
00366             }
00367 
00368             mcuSize=dcPtr->compsInScan * sizeof(ComponentType);
00369             if ((m_buf1 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
00370                 throw DecodingException("Not enough memory for buf1\n");
00371             }
00372             if ((m_buf2 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
00373                 throw DecodingException("Not enough memory for buf2\n");
00374             }
00375 
00376             for (i=0;i<dcPtr->imageWidth;i++) {
00377         m_mcuROW1[i]=(MCU)(m_buf1+i*mcuSize);
00378         m_mcuROW2[i]=(MCU)(m_buf2+i*mcuSize);
00379             }
00380         }
00381 
00382 
00383 /*
00384  *--------------------------------------------------------------
00385  *
00386  * fillBitBuffer --
00387  *
00388  *  Load up the bit buffer with at least nbits
00389  *  Process any stuffed bytes at this time.
00390  *
00391  * Results:
00392  *  None
00393  *
00394  * Side effects:
00395  *  The bitwise global variables are updated.
00396  *
00397  *--------------------------------------------------------------
00398  */
00399         void
00400         LJpegDecompressor::fillBitBuffer (IO::Stream * s,uint16_t nbits)
00401         {
00402             uint8_t c, c2;
00403             
00404             while (m_bitsLeft < MIN_GET_BITS) {
00405                 c = s->readByte();
00406                 
00407                 /*
00408                  * If it's 0xFF, check and discard stuffed zero byte
00409                  */
00410                 if (c == 0xFF) {
00411                     c2 = s->readByte();
00412                     
00413                     if (c2 != 0) {
00414                         
00415                         /*
00416                          * Oops, it's actually a marker indicating end of
00417                          * compressed data.  Better put it back for use later.
00418                          */
00419                         s->seek(-2, SEEK_CUR);
00420                         
00421                         /*
00422                          * There should be enough bits still left in the data
00423                          * segment; if so, just break out of the while loop.
00424                          */
00425                         if (m_bitsLeft >= nbits)
00426                             break;
00427                         
00428                         /*
00429                          * Uh-oh.  Corrupted data: stuff zeroes into the data
00430                          * stream, since this sometimes occurs when we are on the
00431                          * last show_bits(8) during decoding of the Huffman
00432                          * segment.
00433                          */
00434                         c = 0;
00435                     }
00436                 }
00437                 /*
00438                  * OK, load c into getBuffer
00439                  */
00440                 m_getBuffer = (m_getBuffer << 8) | c;
00441                 m_bitsLeft += 8;
00442             }
00443         }
00444 
00445 
00446 
00447         inline int32_t LJpegDecompressor::QuickPredict(int32_t col, int16_t curComp,
00448                                                                                                      MCU *curRowBuf, 
00449                                                                                                      MCU *prevRowBuf,
00450                                                                                                      int32_t psv)
00451         {
00452             int32_t left,upper,diag,leftcol;
00453             int32_t predictor;
00454 
00455             leftcol=col-1;
00456             upper=prevRowBuf[col][curComp];
00457             left=curRowBuf[leftcol][curComp];
00458             diag=prevRowBuf[leftcol][curComp];
00459     
00460             /*
00461              * All predictor are calculated according to psv.
00462              */
00463             switch (psv) {
00464             case 0:
00465                 predictor = 0;
00466                 break;
00467             case 1:
00468                 predictor = left;
00469                 break;
00470             case 2:
00471                 predictor = upper;
00472                 break;
00473             case 3:
00474                 predictor = diag;
00475                 break;
00476             case 4:
00477                 predictor = left+upper-diag;
00478                 break;
00479             case 5:
00480                 predictor = left+((upper-diag)>>1);
00481                 break;
00482             case 6:
00483                 predictor = upper+((left-diag)>>1);
00484                 break;
00485             case 7:
00486                 predictor = (left+upper)>>1;
00487                 break;
00488             default:
00489                 Trace(WARNING) << "Warning: Undefined PSV\n";
00490                 predictor = 0;
00491             }
00492             return predictor;
00493         }
00494 
00495         inline
00496         int32_t LJpegDecompressor::show_bits8(IO::Stream * s) 
00497         {
00498             if (m_bitsLeft < 8) {
00499                 fillBitBuffer(s, 8);
00500             }
00501             return (m_getBuffer >> (m_bitsLeft-8)) & 0xff;  
00502         }
00503         
00504         inline
00505         void LJpegDecompressor::flush_bits(uint16_t nbits) 
00506         {
00507             m_bitsLeft -= (nbits);
00508         }
00509         
00510         
00511         inline
00512         int32_t LJpegDecompressor::get_bits(uint16_t nbits) 
00513         {
00514             if (m_bitsLeft < nbits) 
00515                 fillBitBuffer(m_stream, nbits);
00516             return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
00517         }
00518         
00519         inline
00520         int32_t LJpegDecompressor::get_bit() 
00521         {
00522             if (!m_bitsLeft) 
00523                 fillBitBuffer(m_stream, 1);
00524             return (m_getBuffer >> (--m_bitsLeft)) & 1;
00525         }
00526 
00527 
00528         inline 
00529         int32_t LJpegDecompressor::readBits(IO::Stream * s, uint16_t nbits)
00530         {
00531             if (m_bitsLeft < nbits) {
00532                 fillBitBuffer(s, nbits);
00533             }
00534             return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
00535         }
00536 
00537 
00538 
00539 /*
00540  *--------------------------------------------------------------
00541  *
00542  * PmPutRow --
00543  *
00544  *      Output one row of pixels stored in RowBuf.
00545  *
00546  * Results:
00547  *      None
00548  *
00549  * Side effects:
00550  *      One row of pixels are write to file pointed by outFile.
00551  *
00552  *--------------------------------------------------------------
00553  */
00554         inline void 
00555         LJpegDecompressor::PmPutRow(MCU* RowBuf, int32_t numComp, int32_t numCol, int32_t Pt)
00556         { 
00557             // TODO this might be wrong in 8 bits...
00558             // original code was using putc which *i think* was a problem for
00559             // 16bpp
00560             int32_t col;
00561             uint16_t v;
00562                             
00563             if (numComp==1) { /*pgm*/               
00564                 for (col = 0; col < numCol; col++) {    
00565                     v=RowBuf[col][0]<<Pt;
00566                     m_output->append(v);
00567                 }
00568             } else if (numComp==2) { /*pgm*/                
00569                 for (col = 0; col < numCol; col++) {    
00570                     v=RowBuf[col][0]<<Pt;
00571                     m_output->append(v);
00572                     v=RowBuf[col][1]<<Pt;
00573                     m_output->append(v);
00574                 }
00575             } else { /*ppm*/
00576                 for (col = 0; col < numCol; col++) {
00577                     v=RowBuf[col][0]<<Pt;
00578                     m_output->append(v);
00579                     v=RowBuf[col][1]<<Pt;
00580                     m_output->append(v);
00581                     v=RowBuf[col][2]<<Pt;
00582                     m_output->append(v);
00583                 }
00584             }
00585 //          m_output->nextRow();
00586         }
00587 
00588 /*
00589  *--------------------------------------------------------------
00590  *
00591  * HuffDecode --
00592  *
00593  *  Taken from Figure F.16: extract next coded symbol from
00594  *  input stream.  This should becode a macro.
00595  *
00596  * Results:
00597  *  Next coded symbol
00598  *
00599  * Side effects:
00600  *  Bitstream is parsed.
00601  *
00602  *--------------------------------------------------------------
00603  */
00604         inline int32_t 
00605         LJpegDecompressor::HuffDecode(HuffmanTable *htbl)
00606         {
00607             int32_t rv;
00608             int32_t l, temp;
00609             int32_t code;
00610     
00611             /*
00612              * If the huffman code is less than 8 bits, we can use the fast
00613              * table lookup to get its value.  It's more than 8 bits about
00614              * 3-4% of the time.
00615              */
00616             code = show_bits8(m_stream);
00617             if (htbl->numbits[code]) {
00618                 flush_bits(htbl->numbits[code]);
00619                 rv=htbl->value[code];
00620             }  else {
00621                 flush_bits(8);
00622                 l = 8;
00623                 while (code > htbl->maxcode[l]) {
00624                     temp = get_bit();
00625                     code = (code << 1) | temp;
00626                     l++;
00627                 }
00628         
00629                 /*
00630                  * With garbage input we may reach the sentinel value l = 17.
00631                  */
00632         
00633                 if (l > 16) {
00634                     //Trace(WARNING) << "Corrupt JPEG data: bad Huffman code " << l << "\n";
00635                     rv = 0;     /* fake a zero as the safest result */
00636                 } else {
00637                     rv = htbl->huffval[htbl->valptr[l] +
00638                                                          ((int)(code - htbl->mincode[l]))];
00639                 }
00640             }
00641             return rv;
00642         }
00643 
00644 /*
00645  *--------------------------------------------------------------
00646  *
00647  * HuffExtend --
00648  *
00649  *  Code and table for Figure F.12: extend sign bit
00650  *
00651  * Results:
00652  *  The extended value.
00653  *
00654  * Side effects:
00655  *  None.
00656  *
00657  *--------------------------------------------------------------
00658  */
00659         static int32_t extendTest[16] = /* entry n is 2**(n-1) */
00660         {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
00661          0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
00662 
00663         static int32_t extendOffset[16] =   /* entry n is (-1 << n) + 1 */
00664         {0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
00665          ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
00666          ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
00667          ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
00668 
00669         
00670         inline
00671         void HuffExtend(int32_t & x, int32_t s) 
00672         {
00673             if ((x) < extendTest[s]) {
00674                 (x) += extendOffset[s];
00675             }
00676         }
00677 
00678 /*
00679  *--------------------------------------------------------------
00680  *
00681  * HuffDecoderInit --
00682  *
00683  *  Initialize for a Huffman-compressed scan.
00684  *  This is invoked after reading the SOS marker.
00685  *
00686  * Results:
00687  *  None
00688  *
00689  * Side effects:
00690  *  None.
00691  *
00692  *--------------------------------------------------------------
00693  */
00694         void
00695         LJpegDecompressor::HuffDecoderInit (DecompressInfo *dcPtr)
00696             throw(DecodingException)
00697         {
00698             int16_t ci;
00699             JpegComponentInfo *compptr;
00700 
00701             /*
00702              * Initialize static variables
00703              */
00704             m_bitsLeft = 0;
00705 
00706             for (ci = 0; ci < dcPtr->compsInScan; ci++) {
00707                 compptr = dcPtr->curCompInfo[ci];
00708                 /*
00709                  * Make sure requested tables are present
00710                  */
00711                 if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) { 
00712                     throw DecodingException("Error: Use of undefined Huffman table\n");
00713                 }
00714 
00715                 /*
00716                  * Compute derived values for Huffman tables.
00717                  * We may do this more than once for same table, but it's not a
00718                  * big deal
00719                  */
00720                 FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
00721             }
00722 
00723             /*
00724              * Initialize restart stuff
00725              */
00726             dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
00727             dcPtr->restartRowsToGo = dcPtr->restartInRows;
00728             dcPtr->nextRestartNum = 0;
00729         }
00730 
00731 /*
00732  *--------------------------------------------------------------
00733  *
00734  * ProcessRestart --
00735  *
00736  *  Check for a restart marker & resynchronize decoder.
00737  *
00738  * Results:
00739  *  None.
00740  *
00741  * Side effects:
00742  *  BitStream is parsed, bit buffer is reset, etc.
00743  *
00744  *--------------------------------------------------------------
00745  */
00746         void
00747         LJpegDecompressor::ProcessRestart (DecompressInfo *dcPtr)
00748             throw(DecodingException)
00749         {
00750             int32_t c, nbytes;
00751 
00752             /*
00753              * Throw away any unused bits remaining in bit buffer
00754              */
00755             nbytes = m_bitsLeft / 8;
00756             m_bitsLeft = 0;
00757 
00758             /*
00759              * Scan for next JPEG marker
00760              */
00761             do {
00762                 do {            /* skip any non-FF bytes */
00763                     nbytes++;
00764                     c = m_stream->readByte();
00765                 } while (c != 0xFF);
00766                 do {            /* skip any duplicate FFs */
00767                     /*
00768                      * we don't increment nbytes here since extra FFs are legal
00769                      */
00770                     c = m_stream->readByte();
00771                 } while (c == 0xFF);
00772             } while (c == 0);       /* repeat if it was a stuffed FF/00 */
00773 
00774             if (c != (RST0 + dcPtr->nextRestartNum)) {
00775 
00776                 /*
00777                  * Uh-oh, the restart markers have been messed up too.
00778                  * Just bail out.
00779                  */
00780                 throw DecodingException("Error: Corrupt JPEG data. "
00781                                                                 "Aborting decoding...\n");
00782             }
00783 
00784             /*
00785              * Update restart state
00786              */
00787             dcPtr->restartRowsToGo = dcPtr->restartInRows;
00788             dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
00789         }
00790 
00791 /*
00792  *--------------------------------------------------------------
00793  *
00794  * DecodeFirstRow --
00795  *
00796  *  Decode the first raster line of samples at the start of 
00797  *      the scan and at the beginning of each restart interval.
00798  *  This includes modifying the component value so the real
00799  *      value, not the difference is returned.
00800  *
00801  * Results:
00802  *  None.
00803  *
00804  * Side effects:
00805  *  Bitstream is parsed.
00806  *
00807  *--------------------------------------------------------------
00808  */
00809         void LJpegDecompressor::DecodeFirstRow(DecompressInfo *dcPtr,
00810                                                                                      MCU *curRowBuf)
00811         {
00812             uint16_t curComp,ci;
00813             int32_t s,col,compsInScan,numCOL;
00814             JpegComponentInfo *compptr;
00815             int32_t Pr,Pt,d;
00816             HuffmanTable *dctbl;
00817 
00818             Pr=dcPtr->dataPrecision;
00819             Pt=dcPtr->Pt;
00820             compsInScan=dcPtr->compsInScan;
00821             numCOL=dcPtr->imageWidth;
00822 
00823             /*
00824              * the start of the scan or at the beginning of restart interval.
00825              */
00826             for (curComp = 0; curComp < compsInScan; curComp++) {
00827         ci = dcPtr->MCUmembership[curComp];
00828         compptr = dcPtr->curCompInfo[ci];
00829         dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00830 
00831         /*
00832          * Section F.2.2.1: decode the difference
00833          */
00834         s = HuffDecode (dctbl);
00835         if (s) {
00836                     d = get_bits(s);
00837                     HuffExtend(d,s);
00838                 } else {
00839                     d = 0;
00840         }
00841 
00842         /* 
00843          * Add the predictor to the difference.
00844          */
00845         curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
00846             }
00847 
00848             /*
00849              * the rest of the first row
00850              */
00851             for (col=1; col<numCOL; col++) {
00852         for (curComp = 0; curComp < compsInScan; curComp++) {
00853                     ci = dcPtr->MCUmembership[curComp];
00854                     compptr = dcPtr->curCompInfo[ci];
00855                     dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00856 
00857                     /*
00858                      * Section F.2.2.1: decode the difference
00859                      */
00860                     s = HuffDecode (dctbl);
00861                     if (s) {
00862                         d = get_bits(s);
00863                         HuffExtend(d,s);
00864                     } else {
00865                         d = 0;
00866                     }
00867 
00868                     /* 
00869                      * Add the predictor to the difference.
00870                      */
00871                     curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
00872         }
00873             }
00874 
00875             if (dcPtr->restartInRows) {
00876                 (dcPtr->restartRowsToGo)--;
00877             }
00878         }
00879 
00880 /*
00881  *--------------------------------------------------------------
00882  *
00883  * DecodeImage --
00884  *
00885  *      Decode the input stream. This includes modifying
00886  *      the component value so the real value, not the
00887  *      difference is returned.
00888  *
00889  * Results:
00890  *      None.
00891  *
00892  * Side effects:
00893  *      Bitstream is parsed.
00894  *
00895  *--------------------------------------------------------------
00896  */
00897         void
00898         LJpegDecompressor::DecodeImage(DecompressInfo *dcPtr)
00899         {
00900             int32_t s,d,col,row;
00901             int16_t curComp, ci;
00902             HuffmanTable *dctbl;
00903             JpegComponentInfo *compptr;
00904             int32_t predictor;
00905             int32_t numCOL,numROW,compsInScan;
00906             MCU *prevRowBuf,*curRowBuf;
00907             int32_t imagewidth,Pt,psv;
00908 
00909             numCOL=imagewidth=dcPtr->imageWidth;
00910             numROW=dcPtr->imageHeight;
00911             compsInScan=dcPtr->compsInScan;
00912             Pt=dcPtr->Pt;
00913             psv=dcPtr->Ss;
00914             prevRowBuf=m_mcuROW2;
00915             curRowBuf=m_mcuROW1;
00916 
00917             /*
00918              * Decode the first row of image. Output the row and
00919              * turn this row into a previous row for later predictor
00920              * calculation.
00921              */  
00922             DecodeFirstRow(dcPtr,curRowBuf);
00923             PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
00924             std::swap(prevRowBuf,curRowBuf);
00925 
00926             for (row=1; row<numROW; row++) {
00927 
00928         /*
00929          * Account for restart interval, process restart marker if needed.
00930          */
00931         if (dcPtr->restartInRows) {
00932                     if (dcPtr->restartRowsToGo == 0) {
00933                         ProcessRestart (dcPtr);
00934             
00935                         /*
00936                          * Reset predictors at restart.
00937                          */
00938                         DecodeFirstRow(dcPtr,curRowBuf);
00939                         PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
00940                         std::swap(prevRowBuf,curRowBuf);
00941                         continue;
00942                     }
00943                     dcPtr->restartRowsToGo--;
00944         }
00945 
00946         /*
00947          * The upper neighbors are predictors for the first column.
00948          */
00949         for (curComp = 0; curComp < compsInScan; curComp++) {
00950                     ci = dcPtr->MCUmembership[curComp];
00951                     compptr = dcPtr->curCompInfo[ci];
00952                     dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00953 
00954                     /*
00955                      * Section F.2.2.1: decode the difference
00956                      */
00957                     s = HuffDecode (dctbl);
00958                     if (s) {
00959                         d = get_bits(s);
00960                         HuffExtend(d,s);
00961                     } else {
00962                         d = 0;
00963                     }
00964 
00965                     curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
00966         }
00967 
00968         /*
00969          * For the rest of the column on this row, predictor
00970          * calculations are base on PSV. 
00971          */
00972         for (col=1; col<numCOL; col++) {
00973                     for (curComp = 0; curComp < compsInScan; curComp++) {
00974                         ci = dcPtr->MCUmembership[curComp];
00975                         compptr = dcPtr->curCompInfo[ci];
00976                         dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00977 
00978                         /*
00979                          * Section F.2.2.1: decode the difference
00980                          */
00981                         s = HuffDecode (dctbl);
00982                         if (s) {
00983                             d = get_bits(s);
00984                             HuffExtend(d,s);
00985                         } else {
00986                             d = 0;
00987                         }
00988                         predictor = QuickPredict(col,curComp,curRowBuf,prevRowBuf,
00989                                                                          psv);
00990 
00991                         curRowBuf[col][curComp]=d+predictor;
00992                     }
00993         }
00994                 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
00995                 std::swap(prevRowBuf,curRowBuf);
00996             }
00997         }
00998 
00999 
01000 
01001 
01002 /*
01003  *--------------------------------------------------------------
01004  *
01005  * Get2bytes --
01006  *
01007  *  Get a 2-byte unsigned integer (e.g., a marker parameter length
01008  *  field)
01009  *
01010  * Results:
01011  *  Next two byte of input as an integer.
01012  *
01013  * Side effects:
01014  *  Bitstream is parsed.
01015  *
01016  *--------------------------------------------------------------
01017  */
01018         static inline uint16_t
01019         Get2bytes (IO::Stream * s)
01020         {
01021             uint16_t a;
01022 
01023             a = s->readByte();
01024             return (a << 8) | s->readByte();
01025         }
01026 
01027 /*
01028  *--------------------------------------------------------------
01029  *
01030  * SkipVariable --
01031  *
01032  *  Skip over an unknown or uninteresting variable-length marker
01033  *
01034  * Results:
01035  *  None.
01036  *
01037  * Side effects:
01038  *  Bitstream is parsed over marker.
01039  *
01040  *
01041  *--------------------------------------------------------------
01042  */
01043         static inline void SkipVariable(IO::Stream * s)
01044         {
01045             int32_t length;
01046 
01047             length = Get2bytes(s) - 2;
01048 
01049             s->seek(length, SEEK_CUR);
01050         }
01051 
01052 /*
01053  *--------------------------------------------------------------
01054  *
01055  * GetDht --
01056  *
01057  *  Process a DHT marker
01058  *
01059  * Results:
01060  *  None
01061  *
01062  * Side effects:
01063  *  A huffman table is read.
01064  *  Exits on error.
01065  *
01066  *--------------------------------------------------------------
01067  */
01068         void
01069         LJpegDecompressor::GetDht (DecompressInfo *dcPtr)
01070             throw(DecodingException)
01071         {
01072             int32_t length;
01073             int32_t i, index, count;
01074 
01075             length = Get2bytes(m_stream) - 2;
01076 
01077             while (length) {
01078                 index = m_stream->readByte();
01079 
01080                 if (index < 0 || index >= 4) {
01081                     throw DecodingException(str(boost::format("Bogus DHT index %1%")
01082                                                                                                         % index));
01083                 }
01084 
01085                 HuffmanTable *& htblptr = dcPtr->dcHuffTblPtrs[index];
01086                 if (htblptr == NULL) {
01087                     htblptr = (HuffmanTable *) malloc(sizeof (HuffmanTable));
01088                     if (htblptr==NULL) {
01089                         throw DecodingException("Can't malloc HuffmanTable");
01090                     }
01091                 }
01092 
01093                 htblptr->bits[0] = 0;
01094                 count = 0;
01095                 for (i = 1; i <= 16; i++) {
01096                     htblptr->bits[i] = m_stream->readByte();
01097                     count += htblptr->bits[i];
01098                 }
01099 
01100                 if (count > 256) {
01101                     throw DecodingException("Bogus DHT counts");
01102                 }
01103 
01104                 for (i = 0; i < count; i++)
01105                     htblptr->huffval[i] = m_stream->readByte();
01106 
01107                 length -= 1 + 16 + count;
01108             }
01109         }
01110 
01111 /*
01112  *--------------------------------------------------------------
01113  *
01114  * GetDri --
01115  *
01116  *  Process a DRI marker
01117  *
01118  * Results:
01119  *  None
01120  *
01121  * Side effects:
01122  *  Exits on error.
01123  *  Bitstream is parsed.
01124  *
01125  *--------------------------------------------------------------
01126  */
01127         void
01128         LJpegDecompressor::GetDri(DecompressInfo *dcPtr)
01129             throw(DecodingException)
01130         {
01131             if (Get2bytes(m_stream) != 4) {
01132                 throw DecodingException("Bogus length in DRI");
01133             }
01134 
01135             dcPtr->restartInterval = Get2bytes(m_stream);
01136         }
01137 
01138 /*
01139  *--------------------------------------------------------------
01140  *
01141  * GetApp0 --
01142  *
01143  *  Process an APP0 marker.
01144  *
01145  * Results:
01146  *  None
01147  *
01148  * Side effects:
01149  *  Bitstream is parsed
01150  *
01151  *--------------------------------------------------------------
01152  */
01153         static void GetApp0(IO::Stream *s)
01154         {
01155             int32_t length;
01156 
01157             length = Get2bytes(s) - 2;
01158             s->seek(length, SEEK_CUR);
01159         }
01160 
01161 /*
01162  *--------------------------------------------------------------
01163  *
01164  * GetSof --
01165  *
01166  *  Process a SOFn marker
01167  *
01168  * Results:
01169  *  None.
01170  *
01171  * Side effects:
01172  *  Bitstream is parsed
01173  *  Exits on error
01174  *  dcPtr structure is filled in
01175  *
01176  *--------------------------------------------------------------
01177  */
01178         void
01179         LJpegDecompressor::GetSof(DecompressInfo *dcPtr) throw(DecodingException)
01180         {
01181             int32_t length;
01182             int16_t ci;
01183             int32_t c;
01184             JpegComponentInfo *compptr;
01185 
01186             length = Get2bytes(m_stream);
01187 
01188             dcPtr->dataPrecision = m_stream->readByte();
01189             dcPtr->imageHeight = Get2bytes(m_stream);
01190             dcPtr->imageWidth = Get2bytes(m_stream);
01191             dcPtr->numComponents = m_stream->readByte();
01192 
01193             /*
01194              * We don't support files in which the image height is initially
01195              * specified as 0 and is later redefined by DNL.  As long as we
01196              * have to check that, might as well have a general sanity check.
01197              */
01198             if ((dcPtr->imageHeight <= 0 ) ||
01199                     (dcPtr->imageWidth <= 0) || 
01200                     (dcPtr->numComponents <= 0)) {
01201                 throw DecodingException("Empty JPEG image (DNL not supported)");
01202             }
01203 
01204             if ((dcPtr->dataPrecision<MinPrecisionBits) ||
01205                     (dcPtr->dataPrecision>MaxPrecisionBits)) {
01206                 throw DecodingException("Unsupported JPEG data precision");
01207             }
01208 
01209             if (length != (dcPtr->numComponents * 3 + 8)) {
01210                 throw DecodingException("Bogus SOF length");
01211             }
01212 
01213             dcPtr->compInfo = (JpegComponentInfo *) malloc
01214                 (dcPtr->numComponents * sizeof (JpegComponentInfo));
01215 
01216             for (ci = 0; ci < dcPtr->numComponents; ci++) {
01217                 compptr = &dcPtr->compInfo[ci];
01218                 compptr->componentIndex = ci;
01219                 compptr->componentId = m_stream->readByte();
01220                 c = m_stream->readByte();
01221                 compptr->hSampFactor = (int16_t)((c >> 4) & 15);
01222                 compptr->vSampFactor = (int16_t)((c) & 15);
01223         (void) m_stream->readByte();   /* skip Tq */
01224             }
01225         }
01226 
01227 /*
01228  *--------------------------------------------------------------
01229  *
01230  * GetSos --
01231  *
01232  *  Process a SOS marker
01233  *
01234  * Results:
01235  *  None.
01236  *
01237  * Side effects:
01238  *  Bitstream is parsed.
01239  *  Exits on error.
01240  *
01241  *--------------------------------------------------------------
01242  */
01243         void
01244         LJpegDecompressor::GetSos (DecompressInfo *dcPtr)
01245             throw(DecodingException)
01246         {
01247             int32_t length;
01248             int32_t i;
01249             uint16_t n, ci, c, cc;
01250             JpegComponentInfo *compptr;
01251 
01252             length = Get2bytes (m_stream);
01253 
01254             /* 
01255              * Get the number of image components.
01256              */
01257             n = m_stream->readByte();
01258             dcPtr->compsInScan = n;
01259             length -= 3;
01260 
01261             if (length != (n * 2 + 3) || n < 1 || n > 4) {
01262                 throw DecodingException("Bogus SOS length");
01263             }
01264 
01265 
01266             for (i = 0; i < n; i++) {
01267                 cc = m_stream->readByte();
01268                 c = m_stream->readByte();
01269                 length -= 2;
01270 
01271                 for (ci = 0; ci < dcPtr->numComponents; ci++)
01272                     if (cc == dcPtr->compInfo[ci].componentId) {
01273                         break;
01274                     }
01275 
01276                 if (ci >= dcPtr->numComponents) {
01277                     throw DecodingException("Invalid component number in SOS");
01278                 }
01279 
01280                 compptr = &dcPtr->compInfo[ci];
01281                 dcPtr->curCompInfo[i] = compptr;
01282                 compptr->dcTblNo = (c >> 4) & 15;
01283             }
01284 
01285             /*
01286              * Get the PSV, skip Se, and get the point transform parameter.
01287              */
01288             dcPtr->Ss = m_stream->readByte(); 
01289             (void)m_stream->readByte();
01290             c = m_stream->readByte(); 
01291             dcPtr->Pt = c & 0x0F;
01292         }
01293 
01294 /*
01295  *--------------------------------------------------------------
01296  *
01297  * GetSoi --
01298  *
01299  *  Process an SOI marker
01300  *
01301  * Results:
01302  *  None.
01303  *
01304  * Side effects:
01305  *  Bitstream is parsed.
01306  *  Exits on error.
01307  *
01308  *--------------------------------------------------------------
01309  */
01310         static inline void
01311         GetSoi (DecompressInfo *dcPtr)
01312         {
01313 
01314             /*
01315              * Reset all parameters that are defined to be reset by SOI
01316              */
01317             dcPtr->restartInterval = 0;
01318         }
01319 
01320 /*
01321  *--------------------------------------------------------------
01322  *
01323  * NextMarker --
01324  *
01325  *      Find the next JPEG marker Note that the output might not
01326  *  be a valid marker code but it will never be 0 or FF
01327  *
01328  * Results:
01329  *  The marker found.
01330  *
01331  * Side effects:
01332  *  Bitstream is parsed.
01333  *
01334  *--------------------------------------------------------------
01335  */
01336         static int32_t
01337         NextMarker(IO::Stream *s)
01338         {
01339             int32_t c;
01340 
01341             do {
01342                 /*
01343                  * skip any non-FF bytes
01344                  */
01345                 do {
01346                     c = s->readByte();
01347                 } while (c != 0xFF);
01348                 /*
01349                  * skip any duplicate FFs without incrementing nbytes, since
01350                  * extra FFs are legal
01351                  */
01352                 do {
01353                     c = s->readByte();
01354                 } while (c == 0xFF);
01355             } while (c == 0);       /* repeat if it was a stuffed FF/00 */
01356 
01357             return c;
01358         }
01359 
01360 /*
01361  *--------------------------------------------------------------
01362  *
01363  * ProcessTables --
01364  *
01365  *  Scan and process JPEG markers that can appear in any order
01366  *  Return when an SOI, EOI, SOFn, or SOS is found
01367  *
01368  * Results:
01369  *  The marker found.
01370  *
01371  * Side effects:
01372  *  Bitstream is parsed.
01373  *
01374  *--------------------------------------------------------------
01375  */
01376         LJpegDecompressor::JpegMarker
01377         LJpegDecompressor::ProcessTables (DecompressInfo *dcPtr)
01378         {
01379             int c;
01380 
01381             while (1) {
01382                 c = NextMarker (m_stream);
01383 
01384                 switch (c) {
01385                 case M_SOF0:
01386                 case M_SOF1:
01387                 case M_SOF2:
01388                 case M_SOF3:
01389                 case M_SOF5:
01390                 case M_SOF6:
01391                 case M_SOF7:
01392                 case M_JPG:
01393                 case M_SOF9:
01394                 case M_SOF10:
01395                 case M_SOF11:
01396                 case M_SOF13:
01397                 case M_SOF14:
01398                 case M_SOF15:
01399                 case M_SOI:
01400                 case M_EOI:
01401                 case M_SOS:
01402                     return ((JpegMarker)c);
01403 
01404                 case M_DHT:
01405                     GetDht (dcPtr);
01406                     break;
01407 
01408                 case M_DQT:
01409                     Trace(WARNING) << "Not a lossless JPEG file.\n";
01410                     break;
01411 
01412                 case M_DRI:
01413                     GetDri (dcPtr);
01414                     break;
01415 
01416                 case M_APP0:
01417                     GetApp0(m_stream);
01418                     break;
01419 
01420                 case M_RST0:        /* these are all parameterless */
01421                 case M_RST1:
01422                 case M_RST2:
01423                 case M_RST3:
01424                 case M_RST4:
01425                 case M_RST5:
01426                 case M_RST6:
01427                 case M_RST7:
01428                 case M_TEM:
01429                     Trace(WARNING) << str(boost::format("Warning: unexpected "
01430                                                                                             "marker 0x%1%") % c);
01431                     break;
01432 
01433                 default:        /* must be DNL, DHP, EXP, APPn, JPGn, COM,
01434                                          * or RESn */
01435                     SkipVariable (m_stream);
01436                     break;
01437                 }
01438             }
01439         }
01440 
01441 /*
01442  *--------------------------------------------------------------
01443  *
01444  * ReadFileHeader --
01445  *
01446  *  Initialize and read the file header (everything through
01447  *  the SOF marker).
01448  *
01449  * Results:
01450  *  None
01451  *
01452  * Side effects:
01453  *  Exit on error.
01454  *
01455  *--------------------------------------------------------------
01456  */
01457         void
01458         LJpegDecompressor::ReadFileHeader (DecompressInfo *dcPtr)
01459             throw(DecodingException)
01460         {
01461             int c, c2;
01462             
01463             /*
01464              * Demand an SOI marker at the start of the file --- otherwise it's
01465              * probably not a JPEG file at all.
01466              */
01467             c = m_stream->readByte();
01468             c2 = m_stream->readByte();
01469             if ((c != 0xFF) || (c2 != M_SOI)) {
01470                 throw DecodingException(str(boost::format("Not a JPEG file. "
01471                                                                                                     "marker is %1% %2%\n")
01472                                                                         % c % c2));
01473             }
01474             
01475             GetSoi (dcPtr);     /* OK, process SOI */
01476             
01477             /*
01478              * Process markers until SOF
01479              */
01480             c = ProcessTables (dcPtr);
01481             
01482             switch (c) {
01483             case M_SOF0:
01484             case M_SOF1:
01485             case M_SOF3:
01486                 GetSof(dcPtr);
01487                 break;
01488                 
01489             default:
01490                 Trace(WARNING) << str(boost::format("Unsupported SOF marker "
01491                                                                                         "type 0x%1%\n") % c);
01492                 break;
01493             }
01494         }
01495             
01496 /*
01497  *--------------------------------------------------------------
01498  *
01499  * ReadScanHeader --
01500  *
01501  *  Read the start of a scan (everything through the SOS marker).
01502  *
01503  * Results:
01504  *  1 if find SOS, 0 if find EOI
01505  *
01506  * Side effects:
01507  *  Bitstream is parsed, may exit on errors.
01508  *
01509  *--------------------------------------------------------------
01510  */
01511         int32_t
01512         LJpegDecompressor::ReadScanHeader (DecompressInfo *dcPtr)
01513         {
01514             int c;
01515 
01516             /*
01517              * Process markers until SOS or EOI
01518              */
01519             c = ProcessTables (dcPtr);
01520 
01521             switch (c) {
01522             case M_SOS:
01523                 GetSos (dcPtr);
01524                 return 1;
01525 
01526             case M_EOI:
01527                 return 0;
01528 
01529             default:
01530                 Trace(WARNING) << str(boost::format("Unexpected marker "
01531                                                                                         "0x%1%\n") % c);
01532                 break;
01533             }
01534             return 0;
01535         }
01536 
01537 
01538         RawData *LJpegDecompressor::decompress(RawData *bitmap)
01539         {
01540             DecompressInfo dcInfo;
01541             try {
01542                 ReadFileHeader(&dcInfo); 
01543                 ReadScanHeader (&dcInfo);
01544 
01545                 if(bitmap == NULL)
01546                 {
01547                     bitmap = new RawData();
01548                 }
01549                 m_output = bitmap;
01550                 bitmap->setDataType(OR_DATA_TYPE_CFA);
01551                 // bpc is a multiple of 8
01552                 uint32_t bpc = dcInfo.dataPrecision;
01553                 if(bpc % 8) {
01554                     bpc = ((bpc / 8) + 1) * 8;
01555                 }
01556                 bitmap->setBpc(bpc);
01557                 /*uint16_t *dataPtr = (uint16_t*)*/
01558                 bitmap->allocData(dcInfo.imageWidth
01559                                                     * sizeof(uint16_t) 
01560                                                     * dcInfo.imageHeight
01561                                                     * dcInfo.numComponents);
01562                 
01563                 Trace(DEBUG1) << "dc width = " << dcInfo.imageWidth
01564                                             << " dc height = " << dcInfo.imageHeight
01565                                             << "\n";
01566                 /* currently if the CFA is not sliced, it's this is half what it is */ 
01567                 uint32_t width = (isSliced() ? dcInfo.imageWidth * m_slices.size()
01568                                                     : dcInfo.imageWidth * dcInfo.numComponents);
01569                 bitmap->setDimensions(width, 
01570                                                             dcInfo.imageHeight);
01571                 bitmap->setSlices(m_slices);
01572                 DecoderStructInit(&dcInfo);
01573                 HuffDecoderInit(&dcInfo);
01574                 DecodeImage(&dcInfo);
01575                 // TODO handle the error properly
01576             }
01577             catch(...)
01578             {
01579                 Trace(ERROR) << "Decompression error\n";
01580             }
01581             m_output = NULL;
01582             return bitmap;
01583         }
01584 
01585     }
01586 }

Generated on Sat Nov 7 19:23:18 2009 for libopenraw by  doxygen 1.5.8