57 #include <boost/scoped_ptr.hpp>
58 #include <boost/scoped_array.hpp>
59 #include <boost/format.hpp>
61 #include <libopenraw++/rawdata.h>
62 #include "io/memstream.h"
64 #include "rawcontainer.h"
65 #include "jfifcontainer.h"
66 #include "ljpegdecompressor.h"
67 #include "ljpegdecompressor_priv.h"
71 using namespace Debug;
76 static void SkipVariable(IO::Stream *s);
77 static uint16_t Get2bytes (IO::Stream * s);
78 static int32_t NextMarker(IO::Stream * );
79 static void GetSoi(DecompressInfo *dcPtr);
80 static void GetApp0(IO::Stream *);
82 LJpegDecompressor::LJpegDecompressor(IO::Stream *stream,
83 RawContainer *container)
84 : Decompressor(stream, container),
86 m_mcuROW1(NULL), m_mcuROW2(NULL),
87 m_buf1(NULL), m_buf2(NULL),
95 LJpegDecompressor::~LJpegDecompressor()
114 uint16_t n = slices[0];
115 m_slices.resize(n + 1);
116 for(uint16_t i = 0; i < n; i++) {
117 m_slices[i] = slices[1];
119 m_slices[n] = slices[2];
125 static uint32_t bitMask[] = { 0xffffffff, 0x7fffffff,
126 0x3fffffff, 0x1fffffff,
127 0x0fffffff, 0x07ffffff,
128 0x03ffffff, 0x01ffffff,
129 0x00ffffff, 0x007fffff,
130 0x003fffff, 0x001fffff,
131 0x000fffff, 0x0007ffff,
132 0x0003ffff, 0x0001ffff,
133 0x0000ffff, 0x00007fff,
134 0x00003fff, 0x00001fff,
135 0x00000fff, 0x000007ff,
136 0x000003ff, 0x000001ff,
137 0x000000ff, 0x0000007f,
138 0x0000003f, 0x0000001f,
139 0x0000000f, 0x00000007,
140 0x00000003, 0x00000001};
142 void FixHuffTbl (HuffmanTable *htbl);
163 FixHuffTbl (HuffmanTable *htbl)
165 int32_t p, i, l, lastp, si;
167 uint16_t huffcode[257];
170 int32_t value, ll, ul;
177 for (l = 1; l <= 16; l++) {
178 for (i = 1; i <= (int)htbl->bits[l]; i++)
179 huffsize[p++] = (char)l;
192 while (huffsize[p]) {
193 while (((
int)huffsize[p]) == si) {
194 huffcode[p++] = code;
207 memset(htbl->ehufsi, 0,
sizeof(htbl->ehufsi));
209 for (p = 0; p < lastp; p++) {
210 htbl->ehufco[htbl->huffval[p]] = huffcode[p];
211 htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
218 for (l = 1; l <= 16; l++) {
221 htbl->mincode[l] = huffcode[p];
223 htbl->maxcode[l] = huffcode[p - 1];
225 htbl->maxcode[l] = -1;
232 htbl->maxcode[17] = 0xFFFFFL;
241 bzero (htbl->numbits,
sizeof(htbl->numbits));
242 for (p=0; p<lastp; p++) {
245 value = htbl->huffval[p];
247 ll = code << (8-size);
249 ul = ll | bitMask[24+size];
253 for (i=ll; i<=ul; i++) {
254 htbl->numbits[i] = size;
255 htbl->value[i] = value;
270 uint8_t inputBuffer[JPEG_BUF_SIZE];
273 int inputBufferOffset;
294 #define BITS_PER_LONG (8*sizeof(int32_t))
295 #define MIN_GET_BITS (BITS_PER_LONG-7)
300 static int32_t bmask[] = {0x0000,
301 0x0001, 0x0003, 0x0007, 0x000F,
302 0x001F, 0x003F, 0x007F, 0x00FF,
303 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
304 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
310 #define MinPrecisionBits 2
311 #define MaxPrecisionBits 16
331 LJpegDecompressor::DecoderStructInit (DecompressInfo *dcPtr)
332 throw(DecodingException)
335 JpegComponentInfo *compPtr;
341 for (ci = 0; ci < dcPtr->numComponents; ci++) {
342 compPtr = &dcPtr->compInfo[ci];
343 if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
344 throw DecodingException(
"Error: Downsampling is not supported.\n");
351 if (dcPtr->compsInScan == 1) {
352 dcPtr->MCUmembership[0] = 0;
354 if (dcPtr->compsInScan > 4) {
355 throw DecodingException(
"Too many components for interleaved scan");
358 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
359 dcPtr->MCUmembership[ci] = ci;
368 if ((m_mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*
sizeof(MCU)))==NULL) {
369 throw DecodingException(
"Not enough memory for mcuROW1\n");
371 if ((m_mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*
sizeof(MCU)))==NULL) {
372 throw DecodingException(
"Not enough memory for mcuROW2\n");
375 mcuSize=dcPtr->compsInScan *
sizeof(ComponentType);
376 if ((m_buf1 = (
char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
377 throw DecodingException(
"Not enough memory for buf1\n");
379 if ((m_buf2 = (
char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
380 throw DecodingException(
"Not enough memory for buf2\n");
383 for (i=0;i<dcPtr->imageWidth;i++) {
384 m_mcuROW1[i]=(MCU)(m_buf1+i*mcuSize);
385 m_mcuROW2[i]=(MCU)(m_buf2+i*mcuSize);
407 LJpegDecompressor::fillBitBuffer (IO::Stream * s,uint16_t nbits)
411 while (m_bitsLeft < MIN_GET_BITS) {
426 s->seek(-2, SEEK_CUR);
432 if (m_bitsLeft >= nbits)
447 m_getBuffer = (m_getBuffer << 8) | c;
454 inline int32_t LJpegDecompressor::QuickPredict(int32_t col, int16_t curComp,
459 int32_t left,upper,diag,leftcol;
463 upper=prevRowBuf[col][curComp];
464 left=curRowBuf[leftcol][curComp];
465 diag=prevRowBuf[leftcol][curComp];
484 predictor = left+upper-diag;
487 predictor = left+((upper-diag)>>1);
490 predictor = upper+((left-diag)>>1);
493 predictor = (left+upper)>>1;
496 Trace(WARNING) <<
"Warning: Undefined PSV\n";
503 int32_t LJpegDecompressor::show_bits8(IO::Stream * s)
505 if (m_bitsLeft < 8) {
508 return (m_getBuffer >> (m_bitsLeft-8)) & 0xff;
512 void LJpegDecompressor::flush_bits(uint16_t nbits)
514 m_bitsLeft -= (nbits);
519 int32_t LJpegDecompressor::get_bits(uint16_t nbits)
521 if (m_bitsLeft < nbits)
522 fillBitBuffer(m_stream, nbits);
523 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
527 int32_t LJpegDecompressor::get_bit()
530 fillBitBuffer(m_stream, 1);
531 return (m_getBuffer >> (--m_bitsLeft)) & 1;
536 int32_t LJpegDecompressor::readBits(IO::Stream * s, uint16_t nbits)
538 if (m_bitsLeft < nbits) {
539 fillBitBuffer(s, nbits);
541 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
562 LJpegDecompressor::PmPutRow(MCU* RowBuf, int32_t numComp, int32_t numCol, int32_t Pt)
571 for (col = 0; col < numCol; col++) {
572 for (comp = 0; comp < numComp; comp++) {
573 v = RowBuf[col][comp]<<Pt;
597 LJpegDecompressor::HuffDecode(HuffmanTable *htbl)
608 code = show_bits8(m_stream);
609 if (htbl->numbits[code]) {
610 flush_bits(htbl->numbits[code]);
611 rv=htbl->value[code];
615 while (code > htbl->maxcode[l]) {
617 code = (code << 1) | temp;
629 rv = htbl->huffval[htbl->valptr[l] +
630 ((int)(code - htbl->mincode[l]))];
651 static int32_t extendTest[16] =
652 {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
653 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
655 static int32_t extendOffset[16] =
656 {0, ((-1) << 1) + 1, ((-1) << 2) + 1, ((-1) << 3) + 1, ((-1) << 4) + 1,
657 ((-1) << 5) + 1, ((-1) << 6) + 1, ((-1) << 7) + 1, ((-1) << 8) + 1,
658 ((-1) << 9) + 1, ((-1) << 10) + 1, ((-1) << 11) + 1, ((-1) << 12) + 1,
659 ((-1) << 13) + 1, ((-1) << 14) + 1, ((-1) << 15) + 1};
663 void HuffExtend(int32_t & x, int32_t s)
665 if ((x) < extendTest[s]) {
666 (x) += extendOffset[s];
687 LJpegDecompressor::HuffDecoderInit (DecompressInfo *dcPtr)
688 throw(DecodingException)
691 JpegComponentInfo *compptr;
698 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
699 compptr = dcPtr->curCompInfo[ci];
703 if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
704 throw DecodingException(
"Error: Use of undefined Huffman table\n");
712 FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
718 dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
719 dcPtr->restartRowsToGo = dcPtr->restartInRows;
720 dcPtr->nextRestartNum = 0;
739 LJpegDecompressor::ProcessRestart (DecompressInfo *dcPtr)
740 throw(DecodingException)
747 nbytes = m_bitsLeft / 8;
756 c = m_stream->readByte();
762 c = m_stream->readByte();
766 if (c != (RST0 + dcPtr->nextRestartNum)) {
772 throw DecodingException(
"Error: Corrupt JPEG data. "
773 "Aborting decoding...\n");
779 dcPtr->restartRowsToGo = dcPtr->restartInRows;
780 dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
801 void LJpegDecompressor::DecodeFirstRow(DecompressInfo *dcPtr,
805 int32_t s,col,compsInScan,numCOL;
806 JpegComponentInfo *compptr;
810 Pr=dcPtr->dataPrecision;
812 compsInScan=dcPtr->compsInScan;
813 numCOL=dcPtr->imageWidth;
818 for (curComp = 0; curComp < compsInScan; curComp++) {
819 ci = dcPtr->MCUmembership[curComp];
820 compptr = dcPtr->curCompInfo[ci];
821 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
826 s = HuffDecode (dctbl);
837 curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
843 for (col=1; col<numCOL; col++) {
844 for (curComp = 0; curComp < compsInScan; curComp++) {
845 ci = dcPtr->MCUmembership[curComp];
846 compptr = dcPtr->curCompInfo[ci];
847 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
852 s = HuffDecode (dctbl);
863 curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
867 if (dcPtr->restartInRows) {
868 (dcPtr->restartRowsToGo)--;
890 LJpegDecompressor::DecodeImage(DecompressInfo *dcPtr)
895 JpegComponentInfo *compptr;
897 int32_t numCOL,numROW,compsInScan;
898 MCU *prevRowBuf,*curRowBuf;
899 int32_t imagewidth,Pt,psv;
901 numCOL=imagewidth=dcPtr->imageWidth;
902 numROW=dcPtr->imageHeight;
903 compsInScan=dcPtr->compsInScan;
906 prevRowBuf=m_mcuROW2;
914 DecodeFirstRow(dcPtr,curRowBuf);
915 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
916 std::swap(prevRowBuf,curRowBuf);
918 for (row=1; row<numROW; row++) {
923 if (dcPtr->restartInRows) {
924 if (dcPtr->restartRowsToGo == 0) {
925 ProcessRestart (dcPtr);
930 DecodeFirstRow(dcPtr,curRowBuf);
931 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
932 std::swap(prevRowBuf,curRowBuf);
935 dcPtr->restartRowsToGo--;
941 for (curComp = 0; curComp < compsInScan; curComp++) {
942 ci = dcPtr->MCUmembership[curComp];
943 compptr = dcPtr->curCompInfo[ci];
944 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
949 s = HuffDecode (dctbl);
957 curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
964 for (col=1; col<numCOL; col++) {
965 for (curComp = 0; curComp < compsInScan; curComp++) {
966 ci = dcPtr->MCUmembership[curComp];
967 compptr = dcPtr->curCompInfo[ci];
968 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
973 s = HuffDecode (dctbl);
980 predictor = QuickPredict(col,curComp,curRowBuf,prevRowBuf,
983 curRowBuf[col][curComp]=d+predictor;
986 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
987 std::swap(prevRowBuf,curRowBuf);
1010 static inline uint16_t
1011 Get2bytes (IO::Stream * s)
1016 return (a << 8) | s->readByte();
1035 static inline void SkipVariable(IO::Stream * s)
1039 length = Get2bytes(s) - 2;
1041 s->seek(length, SEEK_CUR);
1061 LJpegDecompressor::GetDht (DecompressInfo *dcPtr)
1062 throw(DecodingException)
1065 int32_t i, index, count;
1067 length = Get2bytes(m_stream) - 2;
1070 index = m_stream->readByte();
1072 if (index < 0 || index >= 4) {
1073 throw DecodingException(str(boost::format(
"Bogus DHT index %1%")
1077 HuffmanTable *& htblptr = dcPtr->dcHuffTblPtrs[index];
1078 if (htblptr == NULL) {
1079 htblptr = (HuffmanTable *) malloc(
sizeof (HuffmanTable));
1080 if (htblptr==NULL) {
1081 throw DecodingException(
"Can't malloc HuffmanTable");
1085 htblptr->bits[0] = 0;
1087 for (i = 1; i <= 16; i++) {
1088 htblptr->bits[i] = m_stream->readByte();
1089 count += htblptr->bits[i];
1093 throw DecodingException(
"Bogus DHT counts");
1096 for (i = 0; i < count; i++)
1097 htblptr->huffval[i] = m_stream->readByte();
1099 length -= 1 + 16 + count;
1120 LJpegDecompressor::GetDri(DecompressInfo *dcPtr)
1121 throw(DecodingException)
1123 if (Get2bytes(m_stream) != 4) {
1124 throw DecodingException(
"Bogus length in DRI");
1127 dcPtr->restartInterval = Get2bytes(m_stream);
1145 static void GetApp0(IO::Stream *s)
1149 length = Get2bytes(s) - 2;
1150 s->seek(length, SEEK_CUR);
1171 LJpegDecompressor::GetSof(DecompressInfo *dcPtr)
throw(DecodingException)
1176 JpegComponentInfo *compptr;
1178 length = Get2bytes(m_stream);
1180 dcPtr->dataPrecision = m_stream->readByte();
1181 dcPtr->imageHeight = Get2bytes(m_stream);
1182 dcPtr->imageWidth = Get2bytes(m_stream);
1183 dcPtr->numComponents = m_stream->readByte();
1190 if ((dcPtr->imageHeight <= 0 ) ||
1191 (dcPtr->imageWidth <= 0) ||
1192 (dcPtr->numComponents <= 0)) {
1193 throw DecodingException(
"Empty JPEG image (DNL not supported)");
1196 if ((dcPtr->dataPrecision<MinPrecisionBits) ||
1197 (dcPtr->dataPrecision>MaxPrecisionBits)) {
1198 throw DecodingException(
"Unsupported JPEG data precision");
1201 if (length != (dcPtr->numComponents * 3 + 8)) {
1202 throw DecodingException(
"Bogus SOF length");
1205 dcPtr->compInfo = (JpegComponentInfo *) malloc
1206 (dcPtr->numComponents * sizeof (JpegComponentInfo));
1208 for (ci = 0; ci < dcPtr->numComponents; ci++) {
1209 compptr = &dcPtr->compInfo[ci];
1210 compptr->componentIndex = ci;
1211 compptr->componentId = m_stream->readByte();
1212 c = m_stream->readByte();
1213 compptr->hSampFactor = (int16_t)((c >> 4) & 15);
1214 compptr->vSampFactor = (int16_t)((c) & 15);
1215 (void) m_stream->readByte();
1236 LJpegDecompressor::GetSos (DecompressInfo *dcPtr)
1237 throw(DecodingException)
1241 uint16_t n, ci, c, cc;
1242 JpegComponentInfo *compptr;
1244 length = Get2bytes (m_stream);
1249 n = m_stream->readByte();
1250 dcPtr->compsInScan = n;
1253 if (length != (n * 2 + 3) || n < 1 || n > 4) {
1254 throw DecodingException(
"Bogus SOS length");
1258 for (i = 0; i < n; i++) {
1259 cc = m_stream->readByte();
1260 c = m_stream->readByte();
1263 for (ci = 0; ci < dcPtr->numComponents; ci++)
1264 if (cc == dcPtr->compInfo[ci].componentId) {
1268 if (ci >= dcPtr->numComponents) {
1269 throw DecodingException(
"Invalid component number in SOS");
1272 compptr = &dcPtr->compInfo[ci];
1273 dcPtr->curCompInfo[i] = compptr;
1274 compptr->dcTblNo = (c >> 4) & 15;
1280 dcPtr->Ss = m_stream->readByte();
1281 (void)m_stream->readByte();
1282 c = m_stream->readByte();
1283 dcPtr->Pt = c & 0x0F;
1303 GetSoi (DecompressInfo *dcPtr)
1309 dcPtr->restartInterval = 0;
1329 NextMarker(IO::Stream *s)
1339 }
while (c != 0xFF);
1346 }
while (c == 0xFF);
1368 LJpegDecompressor::JpegMarker
1369 LJpegDecompressor::ProcessTables (DecompressInfo *dcPtr)
1374 c = NextMarker (m_stream);
1394 return ((JpegMarker)c);
1401 Trace(WARNING) <<
"Not a lossless JPEG file.\n";
1421 Trace(WARNING) << str(boost::format(
"Warning: unexpected "
1422 "marker 0x%1%") % c);
1427 SkipVariable (m_stream);
1450 LJpegDecompressor::ReadFileHeader (DecompressInfo *dcPtr)
1451 throw(DecodingException)
1459 c = m_stream->readByte();
1460 c2 = m_stream->readByte();
1461 if ((c != 0xFF) || (c2 != M_SOI)) {
1462 throw DecodingException(str(boost::format(
"Not a JPEG file. "
1463 "marker is %1% %2%\n")
1472 c = ProcessTables (dcPtr);
1482 Trace(WARNING) << str(boost::format(
"Unsupported SOF marker "
1483 "type 0x%1%\n") % c);
1504 LJpegDecompressor::ReadScanHeader (DecompressInfo *dcPtr)
1511 c = ProcessTables (dcPtr);
1522 Trace(WARNING) << str(boost::format(
"Unexpected marker "
1534 ReadFileHeader(&dcInfo);
1535 ReadScanHeader (&dcInfo);
1543 uint32_t bpc = dcInfo.dataPrecision;
1546 bitmap->setMax((1 << bpc) - 1);
1548 bitmap->allocData(dcInfo.imageWidth
1550 * dcInfo.imageHeight
1551 * dcInfo.numComponents);
1553 Trace(DEBUG1) <<
"dc width = " << dcInfo.imageWidth
1554 <<
" dc height = " << dcInfo.imageHeight
1560 uint32_t width = dcInfo.imageWidth * dcInfo.numComponents;
1562 bitmap->setSlices(m_slices);
1563 DecoderStructInit(&dcInfo);
1564 HuffDecoderInit(&dcInfo);
1565 DecodeImage(&dcInfo);
1570 Trace(ERROR) <<
"Decompression error\n";
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
virtual void setDimensions(uint32_t x, uint32_t y)
RawData & append(uint16_t c)
void setBpc(uint32_t _bpc)
void setSlices(const std::vector< uint16_t > &slices)
void setDataType(DataType _type)
virtual RawData * decompress(RawData *in=NULL)