61 #include <boost/format.hpp> 63 #include <libopenraw/consts.h> 64 #include <libopenraw/debug.h> 66 #include "rawdata.hpp" 67 #include "exception.hpp" 68 #include "io/stream.hpp" 70 #include "ljpegdecompressor.hpp" 71 #include "ljpegdecompressor_priv.hpp" 75 using namespace Debug;
80 static void SkipVariable(IO::Stream *s);
81 static uint16_t Get2bytes (IO::Stream * s);
82 static int32_t NextMarker(IO::Stream * );
83 static void GetSoi(DecompressInfo *dcPtr);
84 static void GetApp0(IO::Stream *);
86 LJpegDecompressor::LJpegDecompressor(IO::Stream *stream,
87 RawContainer *container)
88 : Decompressor(stream, container),
90 m_mcuROW1(NULL), m_mcuROW2(NULL),
91 m_buf1(NULL), m_buf2(NULL),
99 LJpegDecompressor::~LJpegDecompressor()
118 uint16_t n = slices[0];
119 m_slices.resize(n + 1);
120 for(uint16_t i = 0; i < n; i++) {
121 m_slices[i] = slices[1];
123 m_slices[n] = slices[2];
129 static uint32_t bitMask[] = { 0xffffffff, 0x7fffffff,
130 0x3fffffff, 0x1fffffff,
131 0x0fffffff, 0x07ffffff,
132 0x03ffffff, 0x01ffffff,
133 0x00ffffff, 0x007fffff,
134 0x003fffff, 0x001fffff,
135 0x000fffff, 0x0007ffff,
136 0x0003ffff, 0x0001ffff,
137 0x0000ffff, 0x00007fff,
138 0x00003fff, 0x00001fff,
139 0x00000fff, 0x000007ff,
140 0x000003ff, 0x000001ff,
141 0x000000ff, 0x0000007f,
142 0x0000003f, 0x0000001f,
143 0x0000000f, 0x00000007,
144 0x00000003, 0x00000001};
169 int32_t p, i, l, lastp, si;
171 uint16_t huffcode[257];
174 int32_t value, ll, ul;
181 for (l = 1; l <= 16; l++) {
182 for (i = 1; i <= (int)htbl->bits[l]; i++)
183 huffsize[p++] = (char)l;
196 while (huffsize[p]) {
197 while (((
int)huffsize[p]) == si) {
198 huffcode[p++] = code;
211 memset(htbl->ehufsi, 0,
sizeof(htbl->ehufsi));
213 for (p = 0; p < lastp; p++) {
214 htbl->ehufco[htbl->huffval[p]] = huffcode[p];
215 htbl->ehufsi[htbl->huffval[p]] = huffsize[p];
222 for (l = 1; l <= 16; l++) {
225 htbl->mincode[l] = huffcode[p];
227 htbl->maxcode[l] = huffcode[p - 1];
229 htbl->maxcode[l] = -1;
236 htbl->maxcode[17] = 0xFFFFFL;
245 bzero (htbl->numbits,
sizeof(htbl->numbits));
246 for (p=0; p<lastp; p++) {
249 value = htbl->huffval[p];
251 ll = code << (8-size);
253 ul = ll | bitMask[24+size];
257 for (i=ll; i<=ul; i++) {
258 htbl->numbits[i] = size;
259 htbl->value[i] = value;
274 uint8_t inputBuffer[JPEG_BUF_SIZE];
277 int inputBufferOffset;
298 #define BITS_PER_LONG (8*sizeof(int32_t)) 299 #define MIN_GET_BITS (BITS_PER_LONG-7) 304 static int32_t bmask[] = {0x0000,
305 0x0001, 0x0003, 0x0007, 0x000F,
306 0x001F, 0x003F, 0x007F, 0x00FF,
307 0x01FF, 0x03FF, 0x07FF, 0x0FFF,
308 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
314 #define MinPrecisionBits 2 315 #define MaxPrecisionBits 16 345 for (ci = 0; ci < dcPtr->numComponents; ci++) {
346 compPtr = &dcPtr->compInfo[ci];
347 if ((compPtr->hSampFactor != 1) || (compPtr->vSampFactor != 1)) {
355 if (dcPtr->compsInScan == 1) {
356 dcPtr->MCUmembership[0] = 0;
358 if (dcPtr->compsInScan > 4) {
362 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
363 dcPtr->MCUmembership[ci] = ci;
372 if ((m_mcuROW1 = (MCU *)malloc(dcPtr->imageWidth*
sizeof(MCU)))==NULL) {
375 if ((m_mcuROW2 = (MCU *)malloc(dcPtr->imageWidth*
sizeof(MCU)))==NULL) {
379 mcuSize=dcPtr->compsInScan *
sizeof(ComponentType);
380 if ((m_buf1 = (
char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
383 if ((m_buf2 = (
char *)malloc(dcPtr->imageWidth*mcuSize))==NULL) {
387 for (i=0;i<dcPtr->imageWidth;i++) {
388 m_mcuROW1[i]=(MCU)(m_buf1+i*mcuSize);
389 m_mcuROW2[i]=(MCU)(m_buf2+i*mcuSize);
411 LJpegDecompressor::fillBitBuffer (
IO::Stream * s,uint16_t nbits)
415 while (m_bitsLeft < MIN_GET_BITS) {
430 s->
seek(-2, SEEK_CUR);
436 if (m_bitsLeft >= nbits)
451 m_getBuffer = (m_getBuffer << 8) | c;
458 inline int32_t LJpegDecompressor::QuickPredict(int32_t col, int16_t curComp,
463 int32_t left,upper,diag,leftcol;
467 upper=prevRowBuf[col][curComp];
468 left=curRowBuf[leftcol][curComp];
469 diag=prevRowBuf[leftcol][curComp];
488 predictor = left+upper-diag;
491 predictor = left+((upper-diag)>>1);
494 predictor = upper+((left-diag)>>1);
497 predictor = (left+upper)>>1;
500 Trace(WARNING) <<
"Warning: Undefined PSV\n";
507 int32_t LJpegDecompressor::show_bits8(
IO::Stream * s)
509 if (m_bitsLeft < 8) {
512 return (m_getBuffer >> (m_bitsLeft-8)) & 0xff;
516 void LJpegDecompressor::flush_bits(uint16_t nbits)
518 m_bitsLeft -= (nbits);
523 int32_t LJpegDecompressor::get_bits(uint16_t nbits)
525 if (m_bitsLeft < nbits)
526 fillBitBuffer(m_stream, nbits);
527 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
531 int32_t LJpegDecompressor::get_bit()
534 fillBitBuffer(m_stream, 1);
535 return (m_getBuffer >> (--m_bitsLeft)) & 1;
540 int32_t LJpegDecompressor::readBits(
IO::Stream * s, uint16_t nbits)
542 if (m_bitsLeft < nbits) {
543 fillBitBuffer(s, nbits);
545 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
566 LJpegDecompressor::PmPutRow(MCU* RowBuf, int32_t numComp, int32_t numCol, int32_t Pt)
575 for (col = 0; col < numCol; col++) {
576 for (comp = 0; comp < numComp; comp++) {
577 v = RowBuf[col][comp]<<Pt;
612 code = show_bits8(m_stream);
613 if (htbl->numbits[code]) {
614 flush_bits(htbl->numbits[code]);
615 rv=htbl->value[code];
619 while (code > htbl->maxcode[l]) {
621 code = (code << 1) | temp;
633 rv = htbl->huffval[htbl->valptr[l] +
634 ((int)(code - htbl->mincode[l]))];
655 static const int32_t extendTest[16] =
656 {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
657 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
661 #define EXTEND(n) (int32_t)(0xffffffff << n) + 1 662 static const int32_t extendOffset[16] =
664 0, EXTEND(1), EXTEND(2), EXTEND(3),
665 EXTEND(4), EXTEND(5), EXTEND(6), EXTEND(7),
666 EXTEND(8), EXTEND(9), EXTEND(10), EXTEND(11),
667 EXTEND(12), EXTEND(13), EXTEND(14), EXTEND(15)
671 void HuffExtend(int32_t & x, int32_t s) noexcept
673 if ((x) < extendTest[s]) {
674 (x) += extendOffset[s];
706 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
707 compptr = dcPtr->curCompInfo[ci];
711 if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
720 FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
726 dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
727 dcPtr->restartRowsToGo = dcPtr->restartInRows;
728 dcPtr->nextRestartNum = 0;
755 nbytes = m_bitsLeft / 8;
764 c = m_stream->readByte();
770 c = m_stream->readByte();
774 if (c != (RST0 + dcPtr->nextRestartNum)) {
781 "Aborting decoding...\n");
787 dcPtr->restartRowsToGo = dcPtr->restartInRows;
788 dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
813 int32_t s,col,compsInScan,numCOL;
818 Pr=dcPtr->dataPrecision;
820 compsInScan=dcPtr->compsInScan;
821 numCOL=dcPtr->imageWidth;
826 for (curComp = 0; curComp < compsInScan; curComp++) {
827 ci = dcPtr->MCUmembership[curComp];
828 compptr = dcPtr->curCompInfo[ci];
829 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
834 s = HuffDecode (dctbl);
845 curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
851 for (col=1; col<numCOL; col++) {
852 for (curComp = 0; curComp < compsInScan; curComp++) {
853 ci = dcPtr->MCUmembership[curComp];
854 compptr = dcPtr->curCompInfo[ci];
855 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
860 s = HuffDecode (dctbl);
871 curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
875 if (dcPtr->restartInRows) {
876 (dcPtr->restartRowsToGo)--;
905 int32_t numCOL,numROW,compsInScan;
906 MCU *prevRowBuf,*curRowBuf;
907 int32_t imagewidth,Pt,psv;
909 numCOL=imagewidth=dcPtr->imageWidth;
910 numROW=dcPtr->imageHeight;
911 compsInScan=dcPtr->compsInScan;
914 prevRowBuf=m_mcuROW2;
922 DecodeFirstRow(dcPtr,curRowBuf);
923 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
924 std::swap(prevRowBuf,curRowBuf);
926 for (row=1; row<numROW; row++) {
931 if (dcPtr->restartInRows) {
932 if (dcPtr->restartRowsToGo == 0) {
933 ProcessRestart (dcPtr);
938 DecodeFirstRow(dcPtr,curRowBuf);
939 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
940 std::swap(prevRowBuf,curRowBuf);
943 dcPtr->restartRowsToGo--;
949 for (curComp = 0; curComp < compsInScan; curComp++) {
950 ci = dcPtr->MCUmembership[curComp];
951 compptr = dcPtr->curCompInfo[ci];
952 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
957 s = HuffDecode (dctbl);
965 curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
972 for (col=1; col<numCOL; col++) {
973 for (curComp = 0; curComp < compsInScan; curComp++) {
974 ci = dcPtr->MCUmembership[curComp];
975 compptr = dcPtr->curCompInfo[ci];
976 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
981 s = HuffDecode (dctbl);
988 predictor = QuickPredict(col,curComp,curRowBuf,prevRowBuf,
991 curRowBuf[col][curComp]=d+predictor;
994 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
995 std::swap(prevRowBuf,curRowBuf);
1018 static inline uint16_t
1024 return (a << 8) | s->readByte();
1043 static inline void SkipVariable(
IO::Stream * s)
1047 length = Get2bytes(s) - 2;
1049 s->
seek(length, SEEK_CUR);
1073 int32_t i, index, count;
1075 length = Get2bytes(m_stream) - 2;
1078 index = m_stream->readByte();
1080 if (index < 0 || index >= 4) {
1086 if (htblptr == NULL) {
1088 if (htblptr==NULL) {
1093 htblptr->bits[0] = 0;
1095 for (i = 1; i <= 16; i++) {
1096 htblptr->bits[i] = m_stream->readByte();
1097 count += htblptr->bits[i];
1104 for (i = 0; i < count; i++)
1105 htblptr->huffval[i] = m_stream->readByte();
1107 length -= 1 + 16 + count;
1131 if (Get2bytes(m_stream) != 4) {
1135 dcPtr->restartInterval = Get2bytes(m_stream);
1157 length = Get2bytes(s) - 2;
1158 s->
seek(length, SEEK_CUR);
1187 length = Get2bytes(m_stream);
1189 dcPtr->dataPrecision = m_stream->readByte();
1190 dcPtr->imageHeight = Get2bytes(m_stream);
1191 dcPtr->imageWidth = Get2bytes(m_stream);
1192 dcPtr->numComponents = m_stream->readByte();
1199 if ((dcPtr->imageHeight <= 0 ) ||
1200 (dcPtr->imageWidth <= 0) ||
1201 (dcPtr->numComponents <= 0)) {
1205 if ((dcPtr->dataPrecision<MinPrecisionBits) ||
1206 (dcPtr->dataPrecision>MaxPrecisionBits)) {
1210 if (length != (dcPtr->numComponents * 3 + 8)) {
1217 for (ci = 0; ci < dcPtr->numComponents; ci++) {
1218 compptr = &dcPtr->compInfo[ci];
1219 compptr->componentIndex = ci;
1220 compptr->componentId = m_stream->readByte();
1221 c = m_stream->readByte();
1222 compptr->hSampFactor = (int16_t)((c >> 4) & 15);
1223 compptr->vSampFactor = (int16_t)((c) & 15);
1224 (void) m_stream->readByte();
1250 uint16_t n, ci, c, cc;
1253 length = Get2bytes (m_stream);
1258 n = m_stream->readByte();
1259 dcPtr->compsInScan = n;
1262 if (length != (n * 2 + 3) || n < 1 || n > 4) {
1267 for (i = 0; i < n; i++) {
1268 cc = m_stream->readByte();
1269 c = m_stream->readByte();
1272 for (ci = 0; ci < dcPtr->numComponents; ci++)
1273 if (cc == dcPtr->compInfo[ci].componentId) {
1277 if (ci >= dcPtr->numComponents) {
1281 compptr = &dcPtr->compInfo[ci];
1282 dcPtr->curCompInfo[i] = compptr;
1283 compptr->dcTblNo = (c >> 4) & 15;
1289 dcPtr->Ss = m_stream->readByte();
1290 (void)m_stream->readByte();
1291 c = m_stream->readByte();
1292 dcPtr->Pt = c & 0x0F;
1318 dcPtr->restartInterval = 0;
1348 }
while (c != 0xFF);
1355 }
while (c == 0xFF);
1377 LJpegDecompressor::JpegMarker
1383 c = NextMarker (m_stream);
1403 return ((JpegMarker)c);
1410 LOGWARN(
"Not a lossless JPEG file.\n");
1430 LOGWARN(
"Warning: unexpected marker 0x%x", c);
1435 SkipVariable (m_stream);
1467 c = m_stream->readByte();
1468 c2 = m_stream->readByte();
1469 if ((c != 0xFF) || (c2 != M_SOI)) {
1471 "marker is %1% %2%\n")
1480 c = ProcessTables (dcPtr);
1490 LOGWARN(
"Unsupported SOF marker type 0x%x\n", c);
1518 c = ProcessTables (dcPtr);
1529 Trace(WARNING) << str(boost::format(
"Unexpected marker " 1541 ReadFileHeader(&dcInfo);
1542 ReadScanHeader (&dcInfo);
1550 uint32_t bpc = dcInfo.dataPrecision;
1553 bitmap->setWhiteLevel((1 << bpc) - 1);
1555 bitmap->allocData(dcInfo.imageWidth
1557 * dcInfo.imageHeight
1558 * dcInfo.numComponents);
1560 Trace(DEBUG1) <<
"dc width = " << dcInfo.imageWidth
1561 <<
" dc height = " << dcInfo.imageHeight
1567 uint32_t width = dcInfo.imageWidth * dcInfo.numComponents;
1569 bitmap->setSlices(m_slices);
1570 DecoderStructInit(&dcInfo);
1571 HuffDecoderInit(&dcInfo);
1572 DecodeImage(&dcInfo);
1577 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 RawData * decompress(RawData *in=NULL) override
void setBpc(uint32_t _bpc)
virtual int seek(off_t offset, int whence)=0
void setSlices(const std::vector< uint16_t > &slices)
void setDataType(DataType _type)
base virtual class for IO
virtual void setDimensions(uint32_t x, uint32_t y) override