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),
98 LJpegDecompressor::~LJpegDecompressor()
115 void LJpegDecompressor::setSlices(
const std::vector<uint16_t> & slices)
117 uint16_t n = slices[0];
118 m_slices.resize(n + 1);
119 for(uint16_t i = 0; i < n; i++) {
120 m_slices[i] = slices[1];
122 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)
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 = (MCU)malloc(dcPtr->imageWidth * mcuSize)) == NULL) {
377 throw DecodingException(
"Not enough memory for buf1\n");
379 if ((m_buf2 = (MCU)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] = m_buf1 + i * dcPtr->compsInScan;
385 m_mcuROW2[i] = m_buf2 + i * dcPtr->compsInScan;
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 LOGWARN(
"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);
518 int32_t LJpegDecompressor::get_bits(uint16_t nbits)
520 if (m_bitsLeft < nbits)
521 fillBitBuffer(m_stream, nbits);
522 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
526 int32_t LJpegDecompressor::get_bit()
529 fillBitBuffer(m_stream, 1);
530 return (m_getBuffer >> (--m_bitsLeft)) & 1;
535 int32_t LJpegDecompressor::readBits(IO::Stream * s, uint16_t nbits)
537 if (m_bitsLeft < nbits) {
538 fillBitBuffer(s, nbits);
540 return ((m_getBuffer >> (m_bitsLeft -= (nbits)))) & bmask[nbits];
561 LJpegDecompressor::PmPutRow(MCU* RowBuf, int32_t numComp, int32_t numCol, int32_t Pt)
570 for (col = 0; col < numCol; col++) {
571 for (comp = 0; comp < numComp; comp++) {
572 v = RowBuf[col][comp]<<Pt;
595 LJpegDecompressor::HuffDecode(HuffmanTable *htbl)
606 code = show_bits8(m_stream);
607 if (htbl->numbits[code]) {
608 flush_bits(htbl->numbits[code]);
609 rv=htbl->value[code];
613 while (code > htbl->maxcode[l]) {
615 code = (code << 1) | temp;
627 rv = htbl->huffval[htbl->valptr[l] +
628 ((int)(code - htbl->mincode[l]))];
649 static const int32_t extendTest[16] =
650 {0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
651 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000};
655 #define EXTEND(n) (int32_t)(0xffffffff << n) + 1
656 static const int32_t extendOffset[16] =
658 0, EXTEND(1), EXTEND(2), EXTEND(3),
659 EXTEND(4), EXTEND(5), EXTEND(6), EXTEND(7),
660 EXTEND(8), EXTEND(9), EXTEND(10), EXTEND(11),
661 EXTEND(12), EXTEND(13), EXTEND(14), EXTEND(15)
665 void HuffExtend(int32_t & x, int32_t s) noexcept
669 if (s < 16 && x < extendTest[s]) {
670 (x) += extendOffset[s];
691 LJpegDecompressor::HuffDecoderInit (DecompressInfo *dcPtr)
695 JpegComponentInfo *compptr;
702 for (ci = 0; ci < dcPtr->compsInScan; ci++) {
703 compptr = dcPtr->curCompInfo[ci];
707 if (dcPtr->dcHuffTblPtrs[compptr->dcTblNo] == NULL) {
708 throw DecodingException(
"Error: Use of undefined Huffman table\n");
716 FixHuffTbl (dcPtr->dcHuffTblPtrs[compptr->dcTblNo]);
722 dcPtr->restartInRows = (dcPtr->restartInterval)/(dcPtr->imageWidth);
723 dcPtr->restartRowsToGo = dcPtr->restartInRows;
724 dcPtr->nextRestartNum = 0;
743 LJpegDecompressor::ProcessRestart (DecompressInfo *dcPtr)
751 nbytes = m_bitsLeft / 8;
760 c = m_stream->readByte();
766 c = m_stream->readByte();
770 if (c != (RST0 + dcPtr->nextRestartNum)) {
776 throw DecodingException(
"Error: Corrupt JPEG data. "
777 "Aborting decoding...\n");
783 dcPtr->restartRowsToGo = dcPtr->restartInRows;
784 dcPtr->nextRestartNum = (dcPtr->nextRestartNum + 1) & 7;
805 void LJpegDecompressor::DecodeFirstRow(DecompressInfo *dcPtr,
809 int32_t s,col,compsInScan,numCOL;
810 JpegComponentInfo *compptr;
814 Pr=dcPtr->dataPrecision;
816 compsInScan=dcPtr->compsInScan;
817 numCOL=dcPtr->imageWidth;
822 for (curComp = 0; curComp < compsInScan; curComp++) {
823 ci = dcPtr->MCUmembership[curComp];
824 compptr = dcPtr->curCompInfo[ci];
825 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
830 s = HuffDecode (dctbl);
841 curRowBuf[0][curComp]=d+(1<<(Pr-Pt-1));
847 for (col=1; col<numCOL; col++) {
848 for (curComp = 0; curComp < compsInScan; curComp++) {
849 ci = dcPtr->MCUmembership[curComp];
850 compptr = dcPtr->curCompInfo[ci];
851 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
856 s = HuffDecode (dctbl);
867 curRowBuf[col][curComp]=d+curRowBuf[col-1][curComp];
871 if (dcPtr->restartInRows) {
872 (dcPtr->restartRowsToGo)--;
894 LJpegDecompressor::DecodeImage(DecompressInfo *dcPtr)
899 JpegComponentInfo *compptr;
901 int32_t numCOL,numROW,compsInScan;
902 MCU *prevRowBuf,*curRowBuf;
905 numCOL = dcPtr->imageWidth;
906 numROW=dcPtr->imageHeight;
907 compsInScan=dcPtr->compsInScan;
910 prevRowBuf=m_mcuROW2;
918 DecodeFirstRow(dcPtr,curRowBuf);
919 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
920 std::swap(prevRowBuf,curRowBuf);
922 for (row=1; row<numROW; row++) {
927 if (dcPtr->restartInRows) {
928 if (dcPtr->restartRowsToGo == 0) {
929 ProcessRestart (dcPtr);
934 DecodeFirstRow(dcPtr,curRowBuf);
935 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
936 std::swap(prevRowBuf,curRowBuf);
939 dcPtr->restartRowsToGo--;
945 for (curComp = 0; curComp < compsInScan; curComp++) {
946 ci = dcPtr->MCUmembership[curComp];
947 compptr = dcPtr->curCompInfo[ci];
948 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
953 s = HuffDecode (dctbl);
961 curRowBuf[0][curComp]=d+prevRowBuf[0][curComp];
968 for (col=1; col<numCOL; col++) {
969 for (curComp = 0; curComp < compsInScan; curComp++) {
970 ci = dcPtr->MCUmembership[curComp];
971 compptr = dcPtr->curCompInfo[ci];
972 dctbl = dcPtr->dcHuffTblPtrs[compptr->dcTblNo];
977 s = HuffDecode (dctbl);
984 predictor = QuickPredict(col,curComp,curRowBuf,prevRowBuf,
987 curRowBuf[col][curComp]=d+predictor;
990 PmPutRow(curRowBuf,compsInScan,numCOL,Pt);
991 std::swap(prevRowBuf,curRowBuf);
1014 static inline uint16_t
1015 Get2bytes (IO::Stream * s)
1020 return (a << 8) | s->readByte();
1039 static inline void SkipVariable(IO::Stream * s)
1043 length = Get2bytes(s) - 2;
1045 s->seek(length, SEEK_CUR);
1065 LJpegDecompressor::GetDht (DecompressInfo *dcPtr)
1069 int32_t i, index, count;
1071 length = Get2bytes(m_stream) - 2;
1074 index = m_stream->readByte();
1076 if (index < 0 || index >= 4) {
1077 throw DecodingException(str(boost::format(
"Bogus DHT index %1%")
1081 HuffmanTable *& htblptr = dcPtr->dcHuffTblPtrs[index];
1082 if (htblptr == NULL) {
1083 htblptr = (HuffmanTable *) malloc(
sizeof (HuffmanTable));
1084 if (htblptr==NULL) {
1085 throw DecodingException(
"Can't malloc HuffmanTable");
1089 htblptr->bits[0] = 0;
1091 for (i = 1; i <= 16; i++) {
1092 htblptr->bits[i] = m_stream->readByte();
1093 count += htblptr->bits[i];
1097 throw DecodingException(
"Bogus DHT counts");
1100 for (i = 0; i < count; i++)
1101 htblptr->huffval[i] = m_stream->readByte();
1103 length -= 1 + 16 + count;
1124 LJpegDecompressor::GetDri(DecompressInfo *dcPtr)
1127 if (Get2bytes(m_stream) != 4) {
1128 throw DecodingException(
"Bogus length in DRI");
1131 dcPtr->restartInterval = Get2bytes(m_stream);
1149 static void GetApp0(IO::Stream *s)
1153 length = Get2bytes(s) - 2;
1154 s->seek(length, SEEK_CUR);
1175 LJpegDecompressor::GetSof(DecompressInfo *dcPtr)
1181 JpegComponentInfo *compptr;
1183 length = Get2bytes(m_stream);
1185 dcPtr->dataPrecision = m_stream->readByte();
1186 dcPtr->imageHeight = Get2bytes(m_stream);
1187 dcPtr->imageWidth = Get2bytes(m_stream);
1188 dcPtr->numComponents = m_stream->readByte();
1195 if ((dcPtr->imageHeight <= 0 ) ||
1196 (dcPtr->imageWidth <= 0) ||
1197 (dcPtr->numComponents <= 0)) {
1198 throw DecodingException(
"Empty JPEG image (DNL not supported)");
1201 if ((dcPtr->dataPrecision<MinPrecisionBits) ||
1202 (dcPtr->dataPrecision>MaxPrecisionBits)) {
1203 throw DecodingException(
"Unsupported JPEG data precision");
1206 if (length != (dcPtr->numComponents * 3 + 8)) {
1207 throw DecodingException(
"Bogus SOF length");
1210 dcPtr->compInfo = (JpegComponentInfo *) malloc
1211 (dcPtr->numComponents * sizeof (JpegComponentInfo));
1213 for (ci = 0; ci < dcPtr->numComponents; ci++) {
1214 compptr = &dcPtr->compInfo[ci];
1215 compptr->componentIndex = ci;
1216 compptr->componentId = m_stream->readByte();
1217 c = m_stream->readByte();
1218 compptr->hSampFactor = (int16_t)((c >> 4) & 15);
1219 compptr->vSampFactor = (int16_t)((c) & 15);
1220 (void) m_stream->readByte();
1241 LJpegDecompressor::GetSos (DecompressInfo *dcPtr)
1246 uint16_t n, ci, c, cc;
1247 JpegComponentInfo *compptr;
1249 length = Get2bytes (m_stream);
1254 n = m_stream->readByte();
1255 dcPtr->compsInScan = n;
1258 if (length != (n * 2 + 3) || n < 1 || n > 4) {
1259 throw DecodingException(
"Bogus SOS length");
1263 for (i = 0; i < n; i++) {
1264 cc = m_stream->readByte();
1265 c = m_stream->readByte();
1268 for (ci = 0; ci < dcPtr->numComponents; ci++)
1269 if (cc == dcPtr->compInfo[ci].componentId) {
1273 if (ci >= dcPtr->numComponents) {
1274 throw DecodingException(
"Invalid component number in SOS");
1277 compptr = &dcPtr->compInfo[ci];
1278 dcPtr->curCompInfo[i] = compptr;
1279 compptr->dcTblNo = (c >> 4) & 15;
1285 dcPtr->Ss = m_stream->readByte();
1286 (void)m_stream->readByte();
1287 c = m_stream->readByte();
1288 dcPtr->Pt = c & 0x0F;
1308 GetSoi (DecompressInfo *dcPtr)
1314 dcPtr->restartInterval = 0;
1334 NextMarker(IO::Stream *s)
1344 }
while (c != 0xFF);
1351 }
while (c == 0xFF);
1373 LJpegDecompressor::JpegMarker
1374 LJpegDecompressor::ProcessTables (DecompressInfo *dcPtr)
1379 c = NextMarker (m_stream);
1399 return ((JpegMarker)c);
1406 LOGWARN(
"Not a lossless JPEG file.\n");
1426 LOGWARN(
"Warning: unexpected marker 0x%x", c);
1431 SkipVariable (m_stream);
1454 LJpegDecompressor::ReadFileHeader (DecompressInfo *dcPtr)
1463 c = m_stream->readByte();
1464 c2 = m_stream->readByte();
1465 if ((c != 0xFF) || (c2 != M_SOI)) {
1466 throw DecodingException(str(boost::format(
"Not a JPEG file. "
1467 "marker is %1% %2%\n")
1476 c = ProcessTables (dcPtr);
1486 LOGWARN(
"Unsupported SOF marker type 0x%x\n", c);
1507 LJpegDecompressor::ReadScanHeader (DecompressInfo *dcPtr)
1514 c = ProcessTables (dcPtr);
1525 LOGWARN(
"Unexpected marker 0x%x\n", c);
1532 RawDataPtr LJpegDecompressor::decompress()
1536 ReadFileHeader(&dcInfo);
1537 ReadScanHeader (&dcInfo);
1539 m_output = RawDataPtr(
new RawData);
1541 uint32_t bpc = dcInfo.dataPrecision;
1543 m_output->setBpc(bpc);
1544 m_output->setWhiteLevel((1 << bpc) - 1);
1546 m_output->allocData(dcInfo.imageWidth
1548 * dcInfo.imageHeight
1549 * dcInfo.numComponents);
1551 LOGDBG1(
"dc width = %d dc height = %d\n", dcInfo.imageWidth,
1552 dcInfo.imageHeight);
1556 uint32_t width = dcInfo.imageWidth * dcInfo.numComponents;
1557 m_output->setDimensions(width, dcInfo.imageHeight);
1558 m_output->setSlices(m_slices);
1559 DecoderStructInit(&dcInfo);
1560 HuffDecoderInit(&dcInfo);
1561 DecodeImage(&dcInfo);
1566 LOGERR(
"Decompression error\n");
1568 return std::move(m_output);
Represent camera raw data.
Global namespace for libopenraw.