00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 #include <stdlib.h>
00055 #include <string.h>
00056
00057 #include <boost/scoped_ptr.hpp>
00058 #include <boost/scoped_array.hpp>
00059 #include <boost/format.hpp>
00060
00061 #include <libopenraw++/rawdata.h>
00062 #include "io/memstream.h"
00063 #include "debug.h"
00064 #include "rawcontainer.h"
00065 #include "jfifcontainer.h"
00066 #include "ljpegdecompressor.h"
00067 #include "ljpegdecompressor_priv.h"
00068 #include "debug.h"
00069
00070 namespace OpenRaw {
00071
00072 using namespace Debug;
00073
00074 namespace Internals {
00075
00076
00077 static void SkipVariable(IO::Stream *s);
00078 static uint16_t Get2bytes (IO::Stream * s);
00079 static int32_t NextMarker(IO::Stream * );
00080 static void GetSoi(DecompressInfo *dcPtr);
00081 static void GetApp0(IO::Stream *);
00082
00083 LJpegDecompressor::LJpegDecompressor(IO::Stream *stream,
00084 RawContainer *container)
00085 : Decompressor(stream, container),
00086 m_slices(),
00087 m_mcuROW1(NULL), m_mcuROW2(NULL),
00088 m_buf1(NULL), m_buf2(NULL),
00089 m_bitsLeft(0),
00090 m_getBuffer(0),
00091 m_output(0)
00092 {
00093 }
00094
00095
00096 LJpegDecompressor::~LJpegDecompressor()
00097 {
00098 if(m_mcuROW1) {
00099 free(m_mcuROW1);
00100 }
00101 if(m_mcuROW2) {
00102 free(m_mcuROW2);
00103 }
00104 if(m_buf1) {
00105 free(m_buf1);
00106 }
00107 if(m_buf2) {
00108 free(m_buf2);
00109 }
00110 }
00111
00112
00113 void LJpegDecompressor::setSlices(const std::vector<uint16_t> & slices)
00114 {
00115 uint16_t n = slices[0];
00116 m_slices.resize(n + 1);
00117 for(uint16_t i = 0; i < n; i++) {
00118 m_slices[i] = slices[1];
00119 }
00120 m_slices[n] = slices[2];
00121 }
00122
00123
00124
00125
00126 static uint32_t bitMask[] = { 0xffffffff, 0x7fffffff,
00127 0x3fffffff, 0x1fffffff,
00128 0x0fffffff, 0x07ffffff,
00129 0x03ffffff, 0x01ffffff,
00130 0x00ffffff, 0x007fffff,
00131 0x003fffff, 0x001fffff,
00132 0x000fffff, 0x0007ffff,
00133 0x0003ffff, 0x0001ffff,
00134 0x0000ffff, 0x00007fff,
00135 0x00003fff, 0x00001fff,
00136 0x00000fff, 0x000007ff,
00137 0x000003ff, 0x000001ff,
00138 0x000000ff, 0x0000007f,
00139 0x0000003f, 0x0000001f,
00140 0x0000000f, 0x00000007,
00141 0x00000003, 0x00000001};
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 void
00162 FixHuffTbl (HuffmanTable *htbl)
00163 {
00164 int32_t p, i, l, lastp, si;
00165 char huffsize[257];
00166 uint16_t huffcode[257];
00167 uint16_t code;
00168 int32_t size;
00169 int32_t value, ll, ul;
00170
00171
00172
00173
00174
00175 p = 0;
00176 for (l = 1; l <= 16; l++) {
00177 for (i = 1; i <= (int)htbl->bits[l]; i++)
00178 huffsize[p++] = (char)l;
00179 }
00180 huffsize[p] = 0;
00181 lastp = p;
00182
00183
00184
00185
00186
00187
00188 code = 0;
00189 si = huffsize[0];
00190 p = 0;
00191 while (huffsize[p]) {
00192 while (((int)huffsize[p]) == si) {
00193 huffcode[p++] = code;
00194 code++;
00195 }
00196 code <<= 1;
00197 si++;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 memset(htbl->ehufsi, 0, sizeof(htbl->ehufsi));
00207
00208 for (p = 0; p < lastp; p++) {
00209 htbl->ehufco[htbl->huffval[p]] = huffcode[p];
00210 htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
00211 }
00212
00213
00214
00215
00216 p = 0;
00217 for (l = 1; l <= 16; l++) {
00218 if (htbl->bits[l]) {
00219 htbl->valptr[l] = p;
00220 htbl->mincode[l] = huffcode[p];
00221 p += htbl->bits[l];
00222 htbl->maxcode[l] = huffcode[p - 1];
00223 } else {
00224 htbl->maxcode[l] = -1;
00225 }
00226 }
00227
00228
00229
00230
00231 htbl->maxcode[17] = 0xFFFFFL;
00232
00233
00234
00235
00236
00237
00238
00239
00240 bzero (htbl->numbits, sizeof(htbl->numbits));
00241 for (p=0; p<lastp; p++) {
00242 size = huffsize[p];
00243 if (size <= 8) {
00244 value = htbl->huffval[p];
00245 code = huffcode[p];
00246 ll = code << (8-size);
00247 if (size < 8) {
00248 ul = ll | bitMask[24+size];
00249 } else {
00250 ul = ll;
00251 }
00252 for (i=ll; i<=ul; i++) {
00253 htbl->numbits[i] = size;
00254 htbl->value[i] = value;
00255 }
00256 }
00257 }
00258 }
00259
00260
00261 #define RST0 0xD0
00262
00263
00264 #if 0
00265
00266
00267
00268
00269 uint8_t inputBuffer[JPEG_BUF_SIZE];
00270 int numInputBytes;
00271 int maxInputBytes;
00272 int inputBufferOffset;
00273 #endif
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 #define BITS_PER_LONG (8*sizeof(int32_t))
00294 #define MIN_GET_BITS (BITS_PER_LONG-7)
00295
00296
00297
00298
00299 static int32_t bmask[] = {0x0000,
00300 0x0001, 0x0003, 0x0007, 0x000F,
00301 0x001F, 0x003F, 0x007F, 0x00FF,
00302 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
00303 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
00304
00305
00306
00307
00308
00309 #define MinPrecisionBits 2
00310 #define MaxPrecisionBits 16
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void
00330 LJpegDecompressor::DecoderStructInit (DecompressInfo *dcPtr)
00331 throw(DecodingException)
00332 {
00333 int16_t ci,i;
00334 JpegComponentInfo *compPtr;
00335 int32_t mcuSize;
00336
00337
00338
00339
00340 for (ci = 0; ci < dcPtr->numComponents; ci++) {
00341 compPtr = &dcPtr->compInfo[ci];
00342 if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
00343 throw DecodingException("Error: Downsampling is not supported.\n");
00344 }
00345 }
00346
00347
00348
00349
00350 if (dcPtr->compsInScan == 1) {
00351 dcPtr->MCUmembership[0] = 0;
00352 } else {
00353 if (dcPtr->compsInScan > 4) {
00354 throw DecodingException("Too many components for interleaved scan");
00355 }
00356
00357 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
00358 dcPtr->MCUmembership[ci] = ci;
00359 }
00360 }
00361
00362
00363
00364
00365
00366
00367 if ((m_mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
00368 throw DecodingException("Not enough memory for mcuROW1\n");
00369 }
00370 if ((m_mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*sizeof(MCU)))==NULL) {
00371 throw DecodingException("Not enough memory for mcuROW2\n");
00372 }
00373
00374 mcuSize=dcPtr->compsInScan * sizeof(ComponentType);
00375 if ((m_buf1 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
00376 throw DecodingException("Not enough memory for buf1\n");
00377 }
00378 if ((m_buf2 = (char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
00379 throw DecodingException("Not enough memory for buf2\n");
00380 }
00381
00382 for (i=0;i<dcPtr->imageWidth;i++) {
00383 m_mcuROW1[i]=(MCU)(m_buf1+i*mcuSize);
00384 m_mcuROW2[i]=(MCU)(m_buf2+i*mcuSize);
00385 }
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405 void
00406 LJpegDecompressor::fillBitBuffer (IO::Stream * s,uint16_t nbits)
00407 {
00408 uint8_t c, c2;
00409
00410 while (m_bitsLeft < MIN_GET_BITS) {
00411 c = s->readByte();
00412
00413
00414
00415
00416 if (c == 0xFF) {
00417 c2 = s->readByte();
00418
00419 if (c2 != 0) {
00420
00421
00422
00423
00424
00425 s->seek(-2, SEEK_CUR);
00426
00427
00428
00429
00430
00431 if (m_bitsLeft >= nbits)
00432 break;
00433
00434
00435
00436
00437
00438
00439
00440 c = 0;
00441 }
00442 }
00443
00444
00445
00446 m_getBuffer = (m_getBuffer << 8) | c;
00447 m_bitsLeft += 8;
00448 }
00449 }
00450
00451
00452
00453 inline int32_t LJpegDecompressor::QuickPredict(int32_t col, int16_t curComp,
00454 MCU *curRowBuf,
00455 MCU *prevRowBuf,
00456 int32_t psv)
00457 {
00458 int32_t left,upper,diag,leftcol;
00459 int32_t predictor;
00460
00461 leftcol=col-1;
00462 upper=prevRowBuf[col][curComp];
00463 left=curRowBuf[leftcol][curComp];
00464 diag=prevRowBuf[leftcol][curComp];
00465
00466
00467
00468
00469 switch (psv) {
00470 case 0:
00471 predictor = 0;
00472 break;
00473 case 1:
00474 predictor = left;
00475 break;
00476 case 2:
00477 predictor = upper;
00478 break;
00479 case 3:
00480 predictor = diag;
00481 break;
00482 case 4:
00483 predictor = left+upper-diag;
00484 break;
00485 case 5:
00486 predictor = left+((upper-diag)>>1);
00487 break;
00488 case 6:
00489 predictor = upper+((left-diag)>>1);
00490 break;
00491 case 7:
00492 predictor = (left+upper)>>1;
00493 break;
00494 default:
00495 Trace(WARNING) << "Warning: Undefined PSV\n";
00496 predictor = 0;
00497 }
00498 return predictor;
00499 }
00500
00501 inline
00502 int32_t LJpegDecompressor::show_bits8(IO::Stream * s)
00503 {
00504 if (m_bitsLeft < 8) {
00505 fillBitBuffer(s, 8);
00506 }
00507 return (m_getBuffer >> (m_bitsLeft-8)) & 0xff;
00508 }
00509
00510 inline
00511 void LJpegDecompressor::flush_bits(uint16_t nbits)
00512 {
00513 m_bitsLeft -= (nbits);
00514 }
00515
00516
00517 inline
00518 int32_t LJpegDecompressor::get_bits(uint16_t nbits)
00519 {
00520 if (m_bitsLeft < nbits)
00521 fillBitBuffer(m_stream, nbits);
00522 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
00523 }
00524
00525 inline
00526 int32_t LJpegDecompressor::get_bit()
00527 {
00528 if (!m_bitsLeft)
00529 fillBitBuffer(m_stream, 1);
00530 return (m_getBuffer >> (--m_bitsLeft)) & 1;
00531 }
00532
00533
00534 inline
00535 int32_t LJpegDecompressor::readBits(IO::Stream * s, uint16_t nbits)
00536 {
00537 if (m_bitsLeft < nbits) {
00538 fillBitBuffer(s, nbits);
00539 }
00540 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 inline void
00561 LJpegDecompressor::PmPutRow(MCU* RowBuf, int32_t numComp, int32_t numCol, int32_t Pt)
00562 {
00563
00564
00565
00566 int32_t col;
00567 uint16_t v;
00568
00569 if (numComp==1) {
00570 for (col = 0; col < numCol; col++) {
00571 v=RowBuf[col][0]<<Pt;
00572 m_output->append(v);
00573 }
00574 } else if (numComp==2) {
00575 for (col = 0; col < numCol; col++) {
00576 v=RowBuf[col][0]<<Pt;
00577 m_output->append(v);
00578 v=RowBuf[col][1]<<Pt;
00579 m_output->append(v);
00580 }
00581 } else {
00582 for (col = 0; col < numCol; col++) {
00583 v=RowBuf[col][0]<<Pt;
00584 m_output->append(v);
00585 v=RowBuf[col][1]<<Pt;
00586 m_output->append(v);
00587 v=RowBuf[col][2]<<Pt;
00588 m_output->append(v);
00589 }
00590 }
00591
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 inline int32_t
00611 LJpegDecompressor::HuffDecode(HuffmanTable *htbl)
00612 {
00613 int32_t rv;
00614 int32_t l, temp;
00615 int32_t code;
00616
00617
00618
00619
00620
00621
00622 code = show_bits8(m_stream);
00623 if (htbl->numbits[code]) {
00624 flush_bits(htbl->numbits[code]);
00625 rv=htbl->value[code];
00626 } else {
00627 flush_bits(8);
00628 l = 8;
00629 while (code > htbl->maxcode[l]) {
00630 temp = get_bit();
00631 code = (code << 1) | temp;
00632 l++;
00633 }
00634
00635
00636
00637
00638
00639 if (l > 16) {
00640
00641 rv = 0;
00642 } else {
00643 rv = htbl->huffval[htbl->valptr[l] +
00644 ((int)(code - htbl->mincode[l]))];
00645 }
00646 }
00647 return rv;
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 static int32_t extendTest[16] =
00666 {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
00667 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
00668
00669 static int32_t extendOffset[16] =
00670 {0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
00671 ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
00672 ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
00673 ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
00674
00675
00676 inline
00677 void HuffExtend(int32_t & x, int32_t s)
00678 {
00679 if ((x) < extendTest[s]) {
00680 (x) += extendOffset[s];
00681 }
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 void
00701 LJpegDecompressor::HuffDecoderInit (DecompressInfo *dcPtr)
00702 throw(DecodingException)
00703 {
00704 int16_t ci;
00705 JpegComponentInfo *compptr;
00706
00707
00708
00709
00710 m_bitsLeft = 0;
00711
00712 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
00713 compptr = dcPtr->curCompInfo[ci];
00714
00715
00716
00717 if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
00718 throw DecodingException("Error: Use of undefined Huffman table\n");
00719 }
00720
00721
00722
00723
00724
00725
00726 FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
00727 }
00728
00729
00730
00731
00732 dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
00733 dcPtr->restartRowsToGo = dcPtr->restartInRows;
00734 dcPtr->nextRestartNum = 0;
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752 void
00753 LJpegDecompressor::ProcessRestart (DecompressInfo *dcPtr)
00754 throw(DecodingException)
00755 {
00756 int32_t c, nbytes;
00757
00758
00759
00760
00761 nbytes = m_bitsLeft / 8;
00762 m_bitsLeft = 0;
00763
00764
00765
00766
00767 do {
00768 do {
00769 nbytes++;
00770 c = m_stream->readByte();
00771 } while (c != 0xFF);
00772 do {
00773
00774
00775
00776 c = m_stream->readByte();
00777 } while (c == 0xFF);
00778 } while (c == 0);
00779
00780 if (c != (RST0 + dcPtr->nextRestartNum)) {
00781
00782
00783
00784
00785
00786 throw DecodingException("Error: Corrupt JPEG data. "
00787 "Aborting decoding...\n");
00788 }
00789
00790
00791
00792
00793 dcPtr->restartRowsToGo = dcPtr->restartInRows;
00794 dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 void LJpegDecompressor::DecodeFirstRow(DecompressInfo *dcPtr,
00816 MCU *curRowBuf)
00817 {
00818 uint16_t curComp,ci;
00819 int32_t s,col,compsInScan,numCOL;
00820 JpegComponentInfo *compptr;
00821 int32_t Pr,Pt,d;
00822 HuffmanTable *dctbl;
00823
00824 Pr=dcPtr->dataPrecision;
00825 Pt=dcPtr->Pt;
00826 compsInScan=dcPtr->compsInScan;
00827 numCOL=dcPtr->imageWidth;
00828
00829
00830
00831
00832 for (curComp = 0; curComp < compsInScan; curComp++) {
00833 ci = dcPtr->MCUmembership[curComp];
00834 compptr = dcPtr->curCompInfo[ci];
00835 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00836
00837
00838
00839
00840 s = HuffDecode (dctbl);
00841 if (s) {
00842 d = get_bits(s);
00843 HuffExtend(d,s);
00844 } else {
00845 d = 0;
00846 }
00847
00848
00849
00850
00851 curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
00852 }
00853
00854
00855
00856
00857 for (col=1; col<numCOL; col++) {
00858 for (curComp = 0; curComp < compsInScan; curComp++) {
00859 ci = dcPtr->MCUmembership[curComp];
00860 compptr = dcPtr->curCompInfo[ci];
00861 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00862
00863
00864
00865
00866 s = HuffDecode (dctbl);
00867 if (s) {
00868 d = get_bits(s);
00869 HuffExtend(d,s);
00870 } else {
00871 d = 0;
00872 }
00873
00874
00875
00876
00877 curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
00878 }
00879 }
00880
00881 if (dcPtr->restartInRows) {
00882 (dcPtr->restartRowsToGo)--;
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 void
00904 LJpegDecompressor::DecodeImage(DecompressInfo *dcPtr)
00905 {
00906 int32_t s,d,col,row;
00907 int16_t curComp, ci;
00908 HuffmanTable *dctbl;
00909 JpegComponentInfo *compptr;
00910 int32_t predictor;
00911 int32_t numCOL,numROW,compsInScan;
00912 MCU *prevRowBuf,*curRowBuf;
00913 int32_t imagewidth,Pt,psv;
00914
00915 numCOL=imagewidth=dcPtr->imageWidth;
00916 numROW=dcPtr->imageHeight;
00917 compsInScan=dcPtr->compsInScan;
00918 Pt=dcPtr->Pt;
00919 psv=dcPtr->Ss;
00920 prevRowBuf=m_mcuROW2;
00921 curRowBuf=m_mcuROW1;
00922
00923
00924
00925
00926
00927
00928 DecodeFirstRow(dcPtr,curRowBuf);
00929 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
00930 std::swap(prevRowBuf,curRowBuf);
00931
00932 for (row=1; row<numROW; row++) {
00933
00934
00935
00936
00937 if (dcPtr->restartInRows) {
00938 if (dcPtr->restartRowsToGo == 0) {
00939 ProcessRestart (dcPtr);
00940
00941
00942
00943
00944 DecodeFirstRow(dcPtr,curRowBuf);
00945 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
00946 std::swap(prevRowBuf,curRowBuf);
00947 continue;
00948 }
00949 dcPtr->restartRowsToGo--;
00950 }
00951
00952
00953
00954
00955 for (curComp = 0; curComp < compsInScan; curComp++) {
00956 ci = dcPtr->MCUmembership[curComp];
00957 compptr = dcPtr->curCompInfo[ci];
00958 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00959
00960
00961
00962
00963 s = HuffDecode (dctbl);
00964 if (s) {
00965 d = get_bits(s);
00966 HuffExtend(d,s);
00967 } else {
00968 d = 0;
00969 }
00970
00971 curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
00972 }
00973
00974
00975
00976
00977
00978 for (col=1; col<numCOL; col++) {
00979 for (curComp = 0; curComp < compsInScan; curComp++) {
00980 ci = dcPtr->MCUmembership[curComp];
00981 compptr = dcPtr->curCompInfo[ci];
00982 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
00983
00984
00985
00986
00987 s = HuffDecode (dctbl);
00988 if (s) {
00989 d = get_bits(s);
00990 HuffExtend(d,s);
00991 } else {
00992 d = 0;
00993 }
00994 predictor = QuickPredict(col,curComp,curRowBuf,prevRowBuf,
00995 psv);
00996
00997 curRowBuf[col][curComp]=d+predictor;
00998 }
00999 }
01000 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
01001 std::swap(prevRowBuf,curRowBuf);
01002 }
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024 static inline uint16_t
01025 Get2bytes (IO::Stream * s)
01026 {
01027 uint16_t a;
01028
01029 a = s->readByte();
01030 return (a << 8) | s->readByte();
01031 }
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 static inline void SkipVariable(IO::Stream * s)
01050 {
01051 int32_t length;
01052
01053 length = Get2bytes(s) - 2;
01054
01055 s->seek(length, SEEK_CUR);
01056 }
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 void
01075 LJpegDecompressor::GetDht (DecompressInfo *dcPtr)
01076 throw(DecodingException)
01077 {
01078 int32_t length;
01079 int32_t i, index, count;
01080
01081 length = Get2bytes(m_stream) - 2;
01082
01083 while (length) {
01084 index = m_stream->readByte();
01085
01086 if (index < 0 || index >= 4) {
01087 throw DecodingException(str(boost::format("Bogus DHT index %1%")
01088 % index));
01089 }
01090
01091 HuffmanTable *& htblptr = dcPtr->dcHuffTblPtrs[index];
01092 if (htblptr == NULL) {
01093 htblptr = (HuffmanTable *) malloc(sizeof (HuffmanTable));
01094 if (htblptr==NULL) {
01095 throw DecodingException("Can't malloc HuffmanTable");
01096 }
01097 }
01098
01099 htblptr->bits[0] = 0;
01100 count = 0;
01101 for (i = 1; i <= 16; i++) {
01102 htblptr->bits[i] = m_stream->readByte();
01103 count += htblptr->bits[i];
01104 }
01105
01106 if (count > 256) {
01107 throw DecodingException("Bogus DHT counts");
01108 }
01109
01110 for (i = 0; i < count; i++)
01111 htblptr->huffval[i] = m_stream->readByte();
01112
01113 length -= 1 + 16 + count;
01114 }
01115 }
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 void
01134 LJpegDecompressor::GetDri(DecompressInfo *dcPtr)
01135 throw(DecodingException)
01136 {
01137 if (Get2bytes(m_stream) != 4) {
01138 throw DecodingException("Bogus length in DRI");
01139 }
01140
01141 dcPtr->restartInterval = Get2bytes(m_stream);
01142 }
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 static void GetApp0(IO::Stream *s)
01160 {
01161 int32_t length;
01162
01163 length = Get2bytes(s) - 2;
01164 s->seek(length, SEEK_CUR);
01165 }
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184 void
01185 LJpegDecompressor::GetSof(DecompressInfo *dcPtr) throw(DecodingException)
01186 {
01187 int32_t length;
01188 int16_t ci;
01189 int32_t c;
01190 JpegComponentInfo *compptr;
01191
01192 length = Get2bytes(m_stream);
01193
01194 dcPtr->dataPrecision = m_stream->readByte();
01195 dcPtr->imageHeight = Get2bytes(m_stream);
01196 dcPtr->imageWidth = Get2bytes(m_stream);
01197 dcPtr->numComponents = m_stream->readByte();
01198
01199
01200
01201
01202
01203
01204 if ((dcPtr->imageHeight <= 0 ) ||
01205 (dcPtr->imageWidth <= 0) ||
01206 (dcPtr->numComponents <= 0)) {
01207 throw DecodingException("Empty JPEG image (DNL not supported)");
01208 }
01209
01210 if ((dcPtr->dataPrecision<MinPrecisionBits) ||
01211 (dcPtr->dataPrecision>MaxPrecisionBits)) {
01212 throw DecodingException("Unsupported JPEG data precision");
01213 }
01214
01215 if (length != (dcPtr->numComponents * 3 + 8)) {
01216 throw DecodingException("Bogus SOF length");
01217 }
01218
01219 dcPtr->compInfo = (JpegComponentInfo *) malloc
01220 (dcPtr->numComponents * sizeof (JpegComponentInfo));
01221
01222 for (ci = 0; ci < dcPtr->numComponents; ci++) {
01223 compptr = &dcPtr->compInfo[ci];
01224 compptr->componentIndex = ci;
01225 compptr->componentId = m_stream->readByte();
01226 c = m_stream->readByte();
01227 compptr->hSampFactor = (int16_t)((c >> 4) & 15);
01228 compptr->vSampFactor = (int16_t)((c) & 15);
01229 (void) m_stream->readByte();
01230 }
01231 }
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249 void
01250 LJpegDecompressor::GetSos (DecompressInfo *dcPtr)
01251 throw(DecodingException)
01252 {
01253 int32_t length;
01254 int32_t i;
01255 uint16_t n, ci, c, cc;
01256 JpegComponentInfo *compptr;
01257
01258 length = Get2bytes (m_stream);
01259
01260
01261
01262
01263 n = m_stream->readByte();
01264 dcPtr->compsInScan = n;
01265 length -= 3;
01266
01267 if (length != (n * 2 + 3) || n < 1 || n > 4) {
01268 throw DecodingException("Bogus SOS length");
01269 }
01270
01271
01272 for (i = 0; i < n; i++) {
01273 cc = m_stream->readByte();
01274 c = m_stream->readByte();
01275 length -= 2;
01276
01277 for (ci = 0; ci < dcPtr->numComponents; ci++)
01278 if (cc == dcPtr->compInfo[ci].componentId) {
01279 break;
01280 }
01281
01282 if (ci >= dcPtr->numComponents) {
01283 throw DecodingException("Invalid component number in SOS");
01284 }
01285
01286 compptr = &dcPtr->compInfo[ci];
01287 dcPtr->curCompInfo[i] = compptr;
01288 compptr->dcTblNo = (c >> 4) & 15;
01289 }
01290
01291
01292
01293
01294 dcPtr->Ss = m_stream->readByte();
01295 (void)m_stream->readByte();
01296 c = m_stream->readByte();
01297 dcPtr->Pt = c & 0x0F;
01298 }
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316 static inline void
01317 GetSoi (DecompressInfo *dcPtr)
01318 {
01319
01320
01321
01322
01323 dcPtr->restartInterval = 0;
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342 static int32_t
01343 NextMarker(IO::Stream *s)
01344 {
01345 int32_t c;
01346
01347 do {
01348
01349
01350
01351 do {
01352 c = s->readByte();
01353 } while (c != 0xFF);
01354
01355
01356
01357
01358 do {
01359 c = s->readByte();
01360 } while (c == 0xFF);
01361 } while (c == 0);
01362
01363 return c;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382 LJpegDecompressor::JpegMarker
01383 LJpegDecompressor::ProcessTables (DecompressInfo *dcPtr)
01384 {
01385 int c;
01386
01387 while (1) {
01388 c = NextMarker (m_stream);
01389
01390 switch (c) {
01391 case M_SOF0:
01392 case M_SOF1:
01393 case M_SOF2:
01394 case M_SOF3:
01395 case M_SOF5:
01396 case M_SOF6:
01397 case M_SOF7:
01398 case M_JPG:
01399 case M_SOF9:
01400 case M_SOF10:
01401 case M_SOF11:
01402 case M_SOF13:
01403 case M_SOF14:
01404 case M_SOF15:
01405 case M_SOI:
01406 case M_EOI:
01407 case M_SOS:
01408 return ((JpegMarker)c);
01409
01410 case M_DHT:
01411 GetDht (dcPtr);
01412 break;
01413
01414 case M_DQT:
01415 Trace(WARNING) << "Not a lossless JPEG file.\n";
01416 break;
01417
01418 case M_DRI:
01419 GetDri (dcPtr);
01420 break;
01421
01422 case M_APP0:
01423 GetApp0(m_stream);
01424 break;
01425
01426 case M_RST0:
01427 case M_RST1:
01428 case M_RST2:
01429 case M_RST3:
01430 case M_RST4:
01431 case M_RST5:
01432 case M_RST6:
01433 case M_RST7:
01434 case M_TEM:
01435 Trace(WARNING) << str(boost::format("Warning: unexpected "
01436 "marker 0x%1%") % c);
01437 break;
01438
01439 default:
01440
01441 SkipVariable (m_stream);
01442 break;
01443 }
01444 }
01445 }
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463 void
01464 LJpegDecompressor::ReadFileHeader (DecompressInfo *dcPtr)
01465 throw(DecodingException)
01466 {
01467 int c, c2;
01468
01469
01470
01471
01472
01473 c = m_stream->readByte();
01474 c2 = m_stream->readByte();
01475 if ((c != 0xFF) || (c2 != M_SOI)) {
01476 throw DecodingException(str(boost::format("Not a JPEG file. "
01477 "marker is %1% %2%\n")
01478 % c % c2));
01479 }
01480
01481 GetSoi (dcPtr);
01482
01483
01484
01485
01486 c = ProcessTables (dcPtr);
01487
01488 switch (c) {
01489 case M_SOF0:
01490 case M_SOF1:
01491 case M_SOF3:
01492 GetSof(dcPtr);
01493 break;
01494
01495 default:
01496 Trace(WARNING) << str(boost::format("Unsupported SOF marker "
01497 "type 0x%1%\n") % c);
01498 break;
01499 }
01500 }
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517 int32_t
01518 LJpegDecompressor::ReadScanHeader (DecompressInfo *dcPtr)
01519 {
01520 int c;
01521
01522
01523
01524
01525 c = ProcessTables (dcPtr);
01526
01527 switch (c) {
01528 case M_SOS:
01529 GetSos (dcPtr);
01530 return 1;
01531
01532 case M_EOI:
01533 return 0;
01534
01535 default:
01536 Trace(WARNING) << str(boost::format("Unexpected marker "
01537 "0x%1%\n") % c);
01538 break;
01539 }
01540 return 0;
01541 }
01542
01543
01544 RawData *LJpegDecompressor::decompress(RawData *bitmap)
01545 {
01546 DecompressInfo dcInfo;
01547 try {
01548 ReadFileHeader(&dcInfo);
01549 ReadScanHeader (&dcInfo);
01550
01551 if(bitmap == NULL)
01552 {
01553 bitmap = new RawData();
01554 }
01555 m_output = bitmap;
01556 bitmap->setDataType(OR_DATA_TYPE_CFA);
01557 uint32_t bpc = dcInfo.dataPrecision;
01558
01559 bitmap->setBpc(bpc);
01560 bitmap->setMax((1 << bpc) - 1);
01561
01562 bitmap->allocData(dcInfo.imageWidth
01563 * sizeof(uint16_t)
01564 * dcInfo.imageHeight
01565 * dcInfo.numComponents);
01566
01567 Trace(DEBUG1) << "dc width = " << dcInfo.imageWidth
01568 << " dc height = " << dcInfo.imageHeight
01569 << "\n";
01570
01571
01572
01573
01574 uint32_t width = dcInfo.imageWidth * dcInfo.numComponents;
01575 bitmap->setDimensions(width,
01576 dcInfo.imageHeight);
01577 bitmap->setSlices(m_slices);
01578 DecoderStructInit(&dcInfo);
01579 HuffDecoderInit(&dcInfo);
01580 DecodeImage(&dcInfo);
01581
01582 }
01583 catch(...)
01584 {
01585 Trace(ERROR) << "Decompression error\n";
01586 }
01587 m_output = NULL;
01588 return bitmap;
01589 }
01590
01591 }
01592 }
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602