2
#include "LJpegDecompressor.h"
3
#include "ByteStreamSwap.h"
6
RawSpeed - RAW file decoder.
8
Copyright (C) 2009 Klaus Post
10
This library is free software; you can redistribute it and/or
11
modify it under the terms of the GNU Lesser General Public
12
License as published by the Free Software Foundation; either
13
version 2 of the License, or (at your option) any later version.
15
This library is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
Lesser General Public License for more details.
20
You should have received a copy of the GNU Lesser General Public
21
License along with this library; if not, write to the Free Software
22
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
http://www.klauspost.com
28
* Huffman table generation:
29
* LJpegDecompressor::HuffDecode,
30
* LJpegDecompressor::createHuffmanTable
31
* and used data structures are originally grabbed from the IJG software,
32
* and adapted by Hubert Figuiere.
34
* Copyright (C) 1991, 1992, Thomas G. Lane.
35
* Part of the Independent JPEG Group's software.
36
* See the file Copyright for more details.
38
* Copyright (c) 1993 Brian C. Smith, The Regents of the University
40
* All rights reserved.
42
* Copyright (c) 1994 Kongji Huang and Brian C. Smith.
44
* All rights reserved.
46
* Permission to use, copy, modify, and distribute this software and its
47
* documentation for any purpose, without fee, and without written agreement is
48
* hereby granted, provided that the above copyright notice and the following
49
* two paragraphs appear in all copies of this software.
51
* IN NO EVENT SHALL CORNELL UNIVERSITY BE LIABLE TO ANY PARTY FOR
52
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
53
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF CORNELL
54
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56
* CORNELL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
57
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
58
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
59
* ON AN "AS IS" BASIS, AND CORNELL UNIVERSITY HAS NO OBLIGATION TO
60
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
65
const uint32 bitMask[] = { 0xffffffff, 0x7fffffff,
66
0x3fffffff, 0x1fffffff,
67
0x0fffffff, 0x07ffffff,
68
0x03ffffff, 0x01ffffff,
69
0x00ffffff, 0x007fffff,
70
0x003fffff, 0x001fffff,
71
0x000fffff, 0x0007ffff,
72
0x0003ffff, 0x0001ffff,
73
0x0000ffff, 0x00007fff,
74
0x00003fff, 0x00001fff,
75
0x00000fff, 0x000007ff,
76
0x000003ff, 0x000001ff,
77
0x000000ff, 0x0000007f,
78
0x0000003f, 0x0000001f,
79
0x0000000f, 0x00000007,
80
0x00000003, 0x00000001
83
LJpegDecompressor::LJpegDecompressor(FileMap* file, RawImage img):
84
mFile(file), mRaw(img) {
87
for (int i = 0; i < 4; i++) {
88
huff[i].initialized = false;
91
mDNGCompatible = false;
96
LJpegDecompressor::~LJpegDecompressor(void) {
100
for (int i = 0; i < 4; i++) {
101
if (huff[i].bigTable)
102
_aligned_free(huff[i].bigTable);
107
void LJpegDecompressor::getSOF(SOFInfo* sof, uint32 offset, uint32 size) {
108
if (!mFile->isValid(offset + size - 1))
109
ThrowRDE("LJpegDecompressor::getSOF: Start offset plus size is longer than file. Truncated file.");
111
Endianness host_endian = getHostEndianness();
112
// JPEG is big endian
113
if (host_endian == big)
114
input = new ByteStream(mFile->getData(offset), size);
116
input = new ByteStreamSwap(mFile->getData(offset), size);
118
if (getNextMarker(false) != M_SOI)
119
ThrowRDE("LJpegDecompressor::getSOF: Image did not start with SOI. Probably not an LJPEG");
122
JpegMarker m = getNextMarker(true);
128
ThrowRDE("LJpegDecompressor: Could not locate Start of Frame.");
132
} catch (IOException) {
133
ThrowRDE("LJpegDecompressor: IO exception, read outside file. Corrupt File.");
137
void LJpegDecompressor::startDecoder(uint32 offset, uint32 size, uint32 offsetX, uint32 offsetY) {
138
if (!mFile->isValid(offset + size - 1))
139
ThrowRDE("LJpegDecompressor::startDecoder: Start offset plus size is longer than file. Truncated file.");
140
if ((int)offsetX >= mRaw->dim.x)
141
ThrowRDE("LJpegDecompressor::startDecoder: X offset outside of image");
142
if ((int)offsetY >= mRaw->dim.y)
143
ThrowRDE("LJpegDecompressor::startDecoder: Y offset outside of image");
148
Endianness host_endian = getHostEndianness();
149
// JPEG is big endian
150
if (host_endian == big)
151
input = new ByteStream(mFile->getData(offset), size);
153
input = new ByteStreamSwap(mFile->getData(offset), size);
155
if (getNextMarker(false) != M_SOI)
156
ThrowRDE("LJpegDecompressor::startDecoder: Image did not start with SOI. Probably not an LJPEG");
157
// _RPT0(0,"Found SOI marker\n");
159
bool moreImage = true;
161
JpegMarker m = getNextMarker(true);
165
// _RPT0(0,"Found SOS marker\n");
169
// _RPT0(0,"Found EOI marker\n");
174
// _RPT0(0,"Found DHT marker\n");
179
ThrowRDE("LJpegDecompressor: Not a valid RAW file.");
183
// _RPT0(0,"Found DRI marker\n");
187
// _RPT0(0,"Found APP0 marker\n");
191
// _RPT0(0,"Found SOF 3 marker:\n");
195
default: // Just let it skip to next marker
196
_RPT1(0, "Found marker:0x%x. Skipping\n", (int)m);
201
} catch (IOException) {
206
void LJpegDecompressor::parseSOF(SOFInfo* sof) {
207
uint32 headerLength = input->getShort();
208
sof->prec = input->getByte();
209
sof->h = input->getShort();
210
sof->w = input->getShort();
212
sof->cps = input->getByte();
215
ThrowRDE("LJpegDecompressor: More than 16 bits per channel is not supported.");
217
if (sof->cps > 4 || sof->cps < 2)
218
ThrowRDE("LJpegDecompressor: Only from 2 to 4 components are supported.");
220
if (headerLength != 8 + sof->cps*3)
221
ThrowRDE("LJpegDecompressor: Header size mismatch.");
223
for (uint32 i = 0; i < sof->cps; i++) {
224
sof->compInfo[i].componentId = input->getByte();
225
uint32 subs = input->getByte();
226
frame.compInfo[i].superV = subs & 0xf;
227
frame.compInfo[i].superH = subs >> 4;
228
uint32 Tq = input->getByte();
230
ThrowRDE("LJpegDecompressor: Quantized components not supported.");
232
sof->initialized = true;
235
void LJpegDecompressor::parseSOS() {
236
if (!frame.initialized)
237
ThrowRDE("LJpegDecompressor::parseSOS: Frame not yet initialized (SOF Marker not parsed)");
239
uint32 headerLength = input->getShort();
240
uint32 soscps = input->getByte();
241
if (frame.cps != soscps)
242
ThrowRDE("LJpegDecompressor::parseSOS: Component number mismatch.");
244
for (uint32 i = 0;i < frame.cps;i++) {
245
uint32 cs = input->getByte();
247
uint32 count = 0; // Find the correct component
248
while (frame.compInfo[count].componentId != cs) {
249
if (count >= frame.cps)
250
ThrowRDE("LJpegDecompressor::parseSOS: Invalid Component Selector");
254
uint32 b = input->getByte();
257
ThrowRDE("LJpegDecompressor::parseSOS: Invalid Huffman table selection");
258
if (!huff[td].initialized)
259
ThrowRDE("LJpegDecompressor::parseSOS: Invalid Huffman table selection, not defined.");
261
frame.compInfo[count].dcTblNo = td;
265
pred = input->getByte();
267
ThrowRDE("LJpegDecompressor::parseSOS: Invalid predictor mode.");
269
input->skipBytes(1); // Se + Ah Not used in LJPEG
270
uint32 b = input->getByte();
271
Pt = b & 0xf; // Point Transform
273
uint32 cheadersize = 3 + frame.cps * 2 + 3;
274
_ASSERTE(cheadersize == headerLength);
276
bits = new BitPumpJPEG(input);
283
input->skipBytes(bits->getOffset());
287
void LJpegDecompressor::parseDHT() {
288
uint32 headerLength = input->getShort() - 2; // Subtract myself
290
while (headerLength) {
291
uint32 b = input->getByte();
293
uint32 Tc = (b >> 4);
295
ThrowRDE("LJpegDecompressor::parseDHT: Unsupported Table class.");
299
ThrowRDE("LJpegDecompressor::parseDHT: Invalid huffman table destination id.");
302
HuffmanTable* t = &huff[Th];
305
ThrowRDE("LJpegDecompressor::parseDHT: Duplicate table definition");
307
for (uint32 i = 0; i < 16 ;i++) {
308
t->bits[i+1] = input->getByte();
312
memset(t->huffval, 0, sizeof(t->huffval));
314
ThrowRDE("LJpegDecompressor::parseDHT: Invalid DHT table.");
316
if (headerLength < 1 + 16 + acc)
317
ThrowRDE("LJpegDecompressor::parseDHT: Invalid DHT table length.");
319
for (uint32 i = 0 ; i < acc; i++) {
320
t->huffval[i] = input->getByte();
322
createHuffmanTable(t);
323
headerLength -= 1 + 16 + acc;
328
JpegMarker LJpegDecompressor::getNextMarker(bool allowskip) {
331
uchar8 id = input->getByte();
333
ThrowRDE("LJpegDecompressor::getNextMarker: (Noskip) Expected marker not found. Propably corrupt file.");
335
JpegMarker mark = (JpegMarker)input->getByte();
337
if (M_FILL == mark || M_STUFF == mark)
338
ThrowRDE("LJpegDecompressor::getNextMarker: (Noskip) Expected marker, but found stuffed 00 or ff.");
342
input->skipToMarker();
343
uchar8 id = input->getByte();
344
_ASSERTE(0xff == id);
345
JpegMarker mark = (JpegMarker)input->getByte();
349
void LJpegDecompressor::createHuffmanTable(HuffmanTable *htbl) {
350
int p, i, l, lastp, si;
352
ushort16 huffcode[257];
358
* Figure C.1: make table of Huffman code length for each symbol
359
* Note that this is in code-length order.
362
for (l = 1; l <= 16; l++) {
363
for (i = 1; i <= (int)htbl->bits[l]; i++) {
364
huffsize[p++] = (char)l;
366
ThrowRDE("LJpegDecompressor::createHuffmanTable: Code length too long. Corrupt data.");
374
* Figure C.2: generate the codes themselves
375
* Note that this is in code-length order.
380
while (huffsize[p]) {
381
while (((int)huffsize[p]) == si) {
382
huffcode[p++] = code;
388
ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
393
* Figure F.15: generate decoding tables
395
htbl->mincode[0] = 0;
396
htbl->maxcode[0] = 0;
398
for (l = 1; l <= 16; l++) {
401
htbl->mincode[l] = huffcode[p];
403
htbl->maxcode[l] = huffcode[p - 1];
405
htbl->valptr[l] = 0xff; // This check must be present to avoid crash on junk
406
htbl->maxcode[l] = -1;
409
ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
413
* We put in this value to ensure HuffDecode terminates.
415
htbl->maxcode[17] = 0xFFFFFL;
418
* Build the numbits, value lookup tables.
419
* These table allow us to gather 8 bits from the bits stream,
420
* and immediately lookup the size and value of the huffman codes.
421
* If size is zero, it means that more than 8 bits are in the huffman
422
* code (this happens about 3-4% of the time).
424
memset(htbl->numbits, 0, sizeof(htbl->numbits));
425
for (p = 0; p < lastp; p++) {
428
value = htbl->huffval[p];
430
ll = code << (8 - size);
432
ul = ll | bitMask[24+size];
436
if (ul > 256 || ll > ul)
437
ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
438
for (i = ll; i <= ul; i++) {
439
htbl->numbits[i] = size | (value << 4);
444
createBigTable(htbl);
445
htbl->initialized = true;
448
/************************************
451
* This is expanding the concept of fast lookups
453
* A complete table for 14 arbitrary bits will be
454
* created that enables fast lookup of number of bits used,
455
* and final delta result.
456
* Hit rate is about 90-99% for typical LJPEGS, usually about 98%
458
************************************/
460
void LJpegDecompressor::createBigTable(HuffmanTable *htbl) {
461
const uint32 bits = 14; // HuffDecode functions must be changed, if this is modified.
462
const uint32 size = 1 << bits;
467
htbl->bigTable = (int*)_aligned_malloc(size * sizeof(int), 16);
468
for (uint32 i = 0; i < size; i++) {
469
ushort16 input = i << 2; // Calculate input value
470
int code = input >> 8; // Get 8 bits
471
uint32 val = htbl->numbits[code];
477
while (code > htbl->maxcode[l]) {
478
temp = input >> (15 - l) & 1;
479
code = (code << 1) | temp;
484
* With garbage input we may reach the sentinel value l = 17.
487
if (l > frame.prec || htbl->valptr[l] == 0xff) {
488
htbl->bigTable[i] = 0xff;
491
rv = htbl->huffval[htbl->valptr[l] +
492
((int)(code - htbl->mincode[l]))];
499
htbl->bigTable[i] = (-32768 << 8) | (16 + l);
501
htbl->bigTable[i] = (-32768 << 8) | l;
506
htbl->bigTable[i] = 0xff;
511
int x = input >> (16 - l - rv) & ((1 << rv) - 1);
512
if ((x & (1 << (rv - 1))) == 0)
514
htbl->bigTable[i] = (x << 8) | (l + rv);
516
htbl->bigTable[i] = l;
523
*--------------------------------------------------------------
527
* Taken from Figure F.16: extract next coded symbol from
528
* input stream. This should becode a macro.
534
* Bitstream is parsed.
536
*--------------------------------------------------------------
538
int LJpegDecompressor::HuffDecode(HuffmanTable *htbl) {
544
* First attempt to do complete decode, by using the first 14 bits
548
code = bits->peekBitsNoFill(14);
549
if (htbl->bigTable) {
550
val = htbl->bigTable[code];
551
if ((val&0xff) != 0xff) {
552
bits->skipBitsNoFill(val&0xff);
557
* If the huffman code is less than 8 bits, we can use the fast
558
* table lookup to get its value. It's more than 8 bits about
563
val = htbl->numbits[code];
566
bits->skipBitsNoFill(l);
569
bits->skipBitsNoFill(8);
571
while (code > htbl->maxcode[l]) {
572
temp = bits->getBitNoFill();
573
code = (code << 1) | temp;
578
* With garbage input we may reach the sentinel value l = 17.
581
if (l > frame.prec || htbl->valptr[l] == 0xff) {
582
ThrowIOE("Corrupt JPEG data: bad Huffman code:%u", l);
584
rv = htbl->huffval[htbl->valptr[l] +
585
((int)(code - htbl->mincode[l]))];
591
bits->skipBitsNoFill(16);
595
// Ensure we have enough bits
597
if (rv > 16) // There is no values above 16 bits.
598
ThrowIOE("Corrupt JPEG data: Too many bits requested.");
604
* Section F.2.2.1: decode the difference and
605
* Figure F.12: extend sign bit
609
int x = bits->getBitsNoFill(rv);
610
if ((x & (1 << (rv - 1))) == 0)
617
} // namespace RawSpeed