~ubuntu-branches/ubuntu/trusty/digikam/trusty

« back to all changes in this revision

Viewing changes to extra/libkdcraw/libraw/RawSpeed/LJpegDecompressor.cpp

  • Committer: Package Import Robot
  • Author(s): Rohan Garg
  • Date: 2012-11-26 18:24:20 UTC
  • mfrom: (1.9.1) (3.1.23 experimental)
  • Revision ID: package-import@ubuntu.com-20121126182420-qoy6z0nx4ai0wzcl
Tags: 4:3.0.0~beta3-0ubuntu1
* New upstream release
  - Add build-deps :  libhupnp-dev, libqtgstreamer-dev, libmagickcore-dev
* Merge from debian, remaining changes:
  - Make sure libqt4-opengl-dev, libgl1-mesa-dev and libglu1-mesa-dev only
    install on i386,amd64 and powerpc
  - Depend on libtiff-dev instead of libtiff4-dev
  - Drop digikam breaks/replaces kipi-plugins-common since we're past the
    LTS release now
  - digikam to recommend mplayerthumbs | ffmpegthumbs. We currently only
    have latter in the archives, even though former is also supposed to
    be part of kdemultimedia. (LP: #890059)
  - kipi-plugins to recommend www-browser rather than konqueror directly
    since 2.8 no direct usage of konqueror is present in the flickr
    plugin anymore (LP: #1011211)
  - Keep kubuntu_mysqld_executable_name.diff
  - Don't install libkipi translations
  - Keep deps on libcv-dev, libcvaux-dev
  - Keep split packaging of libraries
  - Replace icons from KDE 3 time in debian/xpm.d/*.xpm with the new
    versions (LP: #658047)
* Update debian/not-installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "StdAfx.h"
 
2
#include "LJpegDecompressor.h"
 
3
#include "ByteStreamSwap.h"
 
4
 
 
5
/*
 
6
    RawSpeed - RAW file decoder.
 
7
 
 
8
    Copyright (C) 2009 Klaus Post
 
9
 
 
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.
 
14
 
 
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.
 
19
 
 
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
 
23
 
 
24
    http://www.klauspost.com
 
25
*/
 
26
 
 
27
/*
 
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.
 
33
*
 
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.
 
37
*
 
38
* Copyright (c) 1993 Brian C. Smith, The Regents of the University
 
39
* of California
 
40
* All rights reserved.
 
41
*
 
42
* Copyright (c) 1994 Kongji Huang and Brian C. Smith.
 
43
* Cornell University
 
44
* All rights reserved.
 
45
*
 
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.
 
50
*
 
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.
 
55
*
 
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.
 
61
*/
 
62
 
 
63
namespace RawSpeed {
 
64
 
 
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
 
81
                        };
 
82
 
 
83
LJpegDecompressor::LJpegDecompressor(FileMap* file, RawImage img):
 
84
    mFile(file), mRaw(img) {
 
85
  input = 0;
 
86
  skipX = skipY = 0;
 
87
  for (int i = 0; i < 4; i++) {
 
88
    huff[i].initialized = false;
 
89
    huff[i].bigTable = 0;
 
90
  }
 
91
  mDNGCompatible = false;
 
92
  slicesW.clear();
 
93
  mUseBigtable = false;
 
94
}
 
95
 
 
96
LJpegDecompressor::~LJpegDecompressor(void) {
 
97
  if (input)
 
98
    delete input;
 
99
  input = 0;
 
100
  for (int i = 0; i < 4; i++) {
 
101
    if (huff[i].bigTable)
 
102
      _aligned_free(huff[i].bigTable);
 
103
  }
 
104
 
 
105
}
 
106
 
 
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.");
 
110
  try {
 
111
    Endianness host_endian = getHostEndianness();
 
112
    // JPEG is big endian
 
113
    if (host_endian == big)
 
114
      input = new ByteStream(mFile->getData(offset), size);
 
115
    else 
 
116
      input = new ByteStreamSwap(mFile->getData(offset), size);
 
117
 
 
118
    if (getNextMarker(false) != M_SOI)
 
119
      ThrowRDE("LJpegDecompressor::getSOF: Image did not start with SOI. Probably not an LJPEG");
 
120
 
 
121
    while (true) {
 
122
      JpegMarker m = getNextMarker(true);
 
123
      if (M_SOF3 == m) {
 
124
        parseSOF(sof);
 
125
        return;
 
126
      }
 
127
      if (M_EOI == m) {
 
128
        ThrowRDE("LJpegDecompressor: Could not locate Start of Frame.");
 
129
        return;
 
130
      }
 
131
    }
 
132
  } catch (IOException) {
 
133
    ThrowRDE("LJpegDecompressor: IO exception, read outside file. Corrupt File.");
 
134
  }
 
135
}
 
136
 
 
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");
 
144
  offX = offsetX;
 
145
  offY = offsetY;
 
146
 
 
147
  try {
 
148
    Endianness host_endian = getHostEndianness();
 
149
    // JPEG is big endian
 
150
    if (host_endian == big)
 
151
      input = new ByteStream(mFile->getData(offset), size);
 
152
    else 
 
153
      input = new ByteStreamSwap(mFile->getData(offset), size);
 
154
 
 
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");
 
158
 
 
159
    bool moreImage = true;
 
160
    while (moreImage) {
 
161
      JpegMarker m = getNextMarker(true);
 
162
 
 
163
      switch (m) {
 
164
        case M_SOS:
 
165
//          _RPT0(0,"Found SOS marker\n");
 
166
          parseSOS();
 
167
          break;
 
168
        case M_EOI:
 
169
//          _RPT0(0,"Found EOI marker\n");
 
170
          moreImage = false;
 
171
          break;
 
172
 
 
173
        case M_DHT:
 
174
//          _RPT0(0,"Found DHT marker\n");
 
175
          parseDHT();
 
176
          break;
 
177
 
 
178
        case M_DQT:
 
179
          ThrowRDE("LJpegDecompressor: Not a valid RAW file.");
 
180
          break;
 
181
 
 
182
        case M_DRI:
 
183
//          _RPT0(0,"Found DRI marker\n");
 
184
          break;
 
185
 
 
186
        case M_APP0:
 
187
//          _RPT0(0,"Found APP0 marker\n");
 
188
          break;
 
189
 
 
190
        case M_SOF3:
 
191
//          _RPT0(0,"Found SOF 3 marker:\n");
 
192
          parseSOF(&frame);
 
193
          break;
 
194
 
 
195
        default:  // Just let it skip to next marker
 
196
          _RPT1(0, "Found marker:0x%x. Skipping\n", (int)m);
 
197
          break;
 
198
      }
 
199
    }
 
200
 
 
201
  } catch (IOException) {
 
202
    throw;
 
203
  }
 
204
}
 
205
 
 
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();
 
211
 
 
212
  sof->cps = input->getByte();
 
213
 
 
214
  if (sof->prec > 16)
 
215
    ThrowRDE("LJpegDecompressor: More than 16 bits per channel is not supported.");
 
216
 
 
217
  if (sof->cps > 4 || sof->cps < 2)
 
218
    ThrowRDE("LJpegDecompressor: Only from 2 to 4 components are supported.");
 
219
 
 
220
  if (headerLength != 8 + sof->cps*3)
 
221
    ThrowRDE("LJpegDecompressor: Header size mismatch.");
 
222
 
 
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();
 
229
    if (Tq != 0)
 
230
      ThrowRDE("LJpegDecompressor: Quantized components not supported.");
 
231
  }
 
232
  sof->initialized = true;
 
233
}
 
234
 
 
235
void LJpegDecompressor::parseSOS() {
 
236
  if (!frame.initialized)
 
237
    ThrowRDE("LJpegDecompressor::parseSOS: Frame not yet initialized (SOF Marker not parsed)");
 
238
 
 
239
  uint32 headerLength = input->getShort();
 
240
  uint32 soscps = input->getByte();
 
241
  if (frame.cps != soscps)
 
242
    ThrowRDE("LJpegDecompressor::parseSOS: Component number mismatch.");
 
243
 
 
244
  for (uint32 i = 0;i < frame.cps;i++) {
 
245
    uint32 cs = input->getByte();
 
246
 
 
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");
 
251
      count++;
 
252
    }
 
253
 
 
254
    uint32 b = input->getByte();
 
255
    uint32 td = b >> 4;
 
256
    if (td > 3)
 
257
      ThrowRDE("LJpegDecompressor::parseSOS: Invalid Huffman table selection");
 
258
    if (!huff[td].initialized)
 
259
      ThrowRDE("LJpegDecompressor::parseSOS: Invalid Huffman table selection, not defined.");
 
260
 
 
261
    if (count > 3)
 
262
      ThrowRDE("LJpegDecompressor::parseSOS: Component count out of range");
 
263
 
 
264
    frame.compInfo[count].dcTblNo = td;
 
265
  }
 
266
 
 
267
  // Get predictor
 
268
  pred = input->getByte();
 
269
  if (pred > 7)
 
270
    ThrowRDE("LJpegDecompressor::parseSOS: Invalid predictor mode.");
 
271
 
 
272
  input->skipBytes(1);                    // Se + Ah Not used in LJPEG
 
273
  uint32 b = input->getByte();
 
274
  Pt = b & 0xf;        // Point Transform
 
275
 
 
276
  uint32 cheadersize = 3 + frame.cps * 2 + 3;
 
277
  _ASSERTE(cheadersize == headerLength);
 
278
 
 
279
  bits = new BitPumpJPEG(input);
 
280
  try {
 
281
    decodeScan();
 
282
  } catch (...) {
 
283
    delete bits;
 
284
    throw;
 
285
  }
 
286
  input->skipBytes(bits->getOffset());
 
287
  delete bits;
 
288
}
 
289
 
 
290
void LJpegDecompressor::parseDHT() {
 
291
  uint32 headerLength = input->getShort() - 2; // Subtract myself
 
292
 
 
293
  while (headerLength)  {
 
294
    uint32 b = input->getByte();
 
295
 
 
296
    uint32 Tc = (b >> 4);
 
297
    if (Tc != 0)
 
298
      ThrowRDE("LJpegDecompressor::parseDHT: Unsupported Table class.");
 
299
 
 
300
    uint32 Th = b & 0xf;
 
301
    if (Th > 3)
 
302
      ThrowRDE("LJpegDecompressor::parseDHT: Invalid huffman table destination id.");
 
303
 
 
304
    uint32 acc = 0;
 
305
    HuffmanTable* t = &huff[Th];
 
306
 
 
307
    if (t->initialized)
 
308
      ThrowRDE("LJpegDecompressor::parseDHT: Duplicate table definition");
 
309
 
 
310
    for (uint32 i = 0; i < 16 ;i++) {
 
311
      t->bits[i+1] = input->getByte();
 
312
      acc += t->bits[i+1];
 
313
    }
 
314
    t->bits[0] = 0;
 
315
    memset(t->huffval, 0, sizeof(t->huffval));
 
316
    if (acc > 256)
 
317
      ThrowRDE("LJpegDecompressor::parseDHT: Invalid DHT table.");
 
318
 
 
319
    if (headerLength < 1 + 16 + acc)
 
320
      ThrowRDE("LJpegDecompressor::parseDHT: Invalid DHT table length.");
 
321
 
 
322
    for (uint32 i = 0 ; i < acc; i++) {
 
323
      t->huffval[i] = input->getByte();
 
324
    }
 
325
    createHuffmanTable(t);
 
326
    headerLength -= 1 + 16 + acc;
 
327
  }
 
328
}
 
329
 
 
330
 
 
331
JpegMarker LJpegDecompressor::getNextMarker(bool allowskip) {
 
332
 
 
333
  if (!allowskip) {
 
334
    uchar8 id = input->getByte();
 
335
    if (id != 0xff)
 
336
      ThrowRDE("LJpegDecompressor::getNextMarker: (Noskip) Expected marker not found. Propably corrupt file.");
 
337
 
 
338
    JpegMarker mark = (JpegMarker)input->getByte();
 
339
 
 
340
    if (M_FILL == mark || M_STUFF == mark)
 
341
      ThrowRDE("LJpegDecompressor::getNextMarker: (Noskip) Expected marker, but found stuffed 00 or ff.");
 
342
 
 
343
    return mark;
 
344
  }
 
345
  input->skipToMarker();
 
346
  uchar8 id = input->getByte();
 
347
  _ASSERTE(0xff == id);
 
348
  JpegMarker mark = (JpegMarker)input->getByte();
 
349
  return mark;
 
350
}
 
351
 
 
352
void LJpegDecompressor::createHuffmanTable(HuffmanTable *htbl) {
 
353
  int p, i, l, lastp, si;
 
354
  char huffsize[257];
 
355
  ushort16 huffcode[257];
 
356
  ushort16 code;
 
357
  int size;
 
358
  int value, ll, ul;
 
359
 
 
360
  /*
 
361
  * Figure C.1: make table of Huffman code length for each symbol
 
362
  * Note that this is in code-length order.
 
363
  */
 
364
  p = 0;
 
365
  for (l = 1; l <= 16; l++) {
 
366
    for (i = 1; i <= (int)htbl->bits[l]; i++) {
 
367
      huffsize[p++] = (char)l;
 
368
      if (p > 256)
 
369
        ThrowRDE("LJpegDecompressor::createHuffmanTable: Code length too long. Corrupt data.");
 
370
    }
 
371
  }
 
372
  huffsize[p] = 0;
 
373
  lastp = p;
 
374
 
 
375
 
 
376
  /*
 
377
  * Figure C.2: generate the codes themselves
 
378
  * Note that this is in code-length order.
 
379
  */
 
380
  code = 0;
 
381
  si = huffsize[0];
 
382
  p = 0;
 
383
  while (huffsize[p]) {
 
384
    while (((int)huffsize[p]) == si) {
 
385
      huffcode[p++] = code;
 
386
      code++;
 
387
    }
 
388
    code <<= 1;
 
389
    si++;
 
390
    if (p > 256)
 
391
      ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
 
392
  }
 
393
 
 
394
 
 
395
  /*
 
396
  * Figure F.15: generate decoding tables
 
397
  */
 
398
  htbl->mincode[0] = 0;
 
399
  htbl->maxcode[0] = 0;
 
400
  p = 0;
 
401
  for (l = 1; l <= 16; l++) {
 
402
    if (htbl->bits[l]) {
 
403
      htbl->valptr[l] = p;
 
404
      htbl->mincode[l] = huffcode[p];
 
405
      p += htbl->bits[l];
 
406
      htbl->maxcode[l] = huffcode[p - 1];
 
407
    } else {
 
408
      htbl->valptr[l] = 0xff;   // This check must be present to avoid crash on junk
 
409
      htbl->maxcode[l] = -1;
 
410
    }
 
411
    if (p > 256)
 
412
      ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
 
413
  }
 
414
 
 
415
  /*
 
416
  * We put in this value to ensure HuffDecode terminates.
 
417
  */
 
418
  htbl->maxcode[17] = 0xFFFFFL;
 
419
 
 
420
  /*
 
421
  * Build the numbits, value lookup tables.
 
422
  * These table allow us to gather 8 bits from the bits stream,
 
423
  * and immediately lookup the size and value of the huffman codes.
 
424
  * If size is zero, it means that more than 8 bits are in the huffman
 
425
  * code (this happens about 3-4% of the time).
 
426
  */
 
427
  memset(htbl->numbits, 0, sizeof(htbl->numbits));
 
428
  for (p = 0; p < lastp; p++) {
 
429
    size = huffsize[p];
 
430
    if (size <= 8) {
 
431
      value = htbl->huffval[p];
 
432
      code = huffcode[p];
 
433
      ll = code << (8 - size);
 
434
      if (size < 8) {
 
435
        ul = ll | bitMask[24+size];
 
436
      } else {
 
437
        ul = ll;
 
438
      }
 
439
      if (ul > 256 || ll > ul)
 
440
        ThrowRDE("createHuffmanTable: Code length too long. Corrupt data.");
 
441
      for (i = ll; i <= ul; i++) {
 
442
        htbl->numbits[i] = size | (value << 4);
 
443
      }
 
444
    }
 
445
  }
 
446
  if (mUseBigtable)
 
447
    createBigTable(htbl);
 
448
  htbl->initialized = true;
 
449
}
 
450
 
 
451
/************************************
 
452
 * Bitable creation
 
453
 *
 
454
 * This is expanding the concept of fast lookups
 
455
 *
 
456
 * A complete table for 14 arbitrary bits will be
 
457
 * created that enables fast lookup of number of bits used,
 
458
 * and final delta result.
 
459
 * Hit rate is about 90-99% for typical LJPEGS, usually about 98%
 
460
 *
 
461
 ************************************/
 
462
 
 
463
void LJpegDecompressor::createBigTable(HuffmanTable *htbl) {
 
464
  const uint32 bits = 14;      // HuffDecode functions must be changed, if this is modified.
 
465
  const uint32 size = 1 << bits;
 
466
  int rv = 0;
 
467
  int temp;
 
468
  uint32 l;
 
469
 
 
470
  htbl->bigTable = (int*)_aligned_malloc(size * sizeof(int), 16);
 
471
  if (!htbl->bigTable)
 
472
        ThrowRDE("Out of memory, failed to allocate %d bytes", size*sizeof(int));
 
473
  for (uint32 i = 0; i < size; i++) {
 
474
    ushort16 input = i << 2; // Calculate input value
 
475
    int code = input >> 8;   // Get 8 bits
 
476
    uint32 val = htbl->numbits[code];
 
477
    l = val & 15;
 
478
    if (l) {
 
479
      rv = val >> 4;
 
480
    }  else {
 
481
      l = 8;
 
482
      while (code > htbl->maxcode[l]) {
 
483
        temp = input >> (15 - l) & 1;
 
484
        code = (code << 1) | temp;
 
485
        l++;
 
486
      }
 
487
 
 
488
      /*
 
489
      * With garbage input we may reach the sentinel value l = 17.
 
490
      */
 
491
 
 
492
      if (l > frame.prec || htbl->valptr[l] == 0xff) {
 
493
        htbl->bigTable[i] = 0xff;
 
494
        continue;
 
495
      } else {
 
496
        rv = htbl->huffval[htbl->valptr[l] +
 
497
                           ((int)(code - htbl->mincode[l]))];
 
498
      }
 
499
    }
 
500
 
 
501
 
 
502
    if (rv == 16) {
 
503
      if (mDNGCompatible)
 
504
        htbl->bigTable[i] = (-32768 << 8) | (16 + l);
 
505
      else
 
506
        htbl->bigTable[i] = (-32768 << 8) | l;
 
507
      continue;
 
508
    }
 
509
 
 
510
    if (rv + l > bits) {
 
511
      htbl->bigTable[i] = 0xff;
 
512
      continue;
 
513
    }
 
514
 
 
515
    if (rv) {
 
516
      int x = input >> (16 - l - rv) & ((1 << rv) - 1);
 
517
      if ((x & (1 << (rv - 1))) == 0)
 
518
        x -= (1 << rv) - 1;
 
519
      htbl->bigTable[i] = (x << 8) | (l + rv);
 
520
    } else {
 
521
      htbl->bigTable[i] = l;
 
522
    }
 
523
  }
 
524
}
 
525
 
 
526
 
 
527
/*
 
528
*--------------------------------------------------------------
 
529
*
 
530
* HuffDecode --
 
531
*
 
532
* Taken from Figure F.16: extract next coded symbol from
 
533
* input stream.  This should becode a macro.
 
534
*
 
535
* Results:
 
536
* Next coded symbol
 
537
*
 
538
* Side effects:
 
539
* Bitstream is parsed.
 
540
*
 
541
*--------------------------------------------------------------
 
542
*/
 
543
int LJpegDecompressor::HuffDecode(HuffmanTable *htbl) {
 
544
  int rv;
 
545
  int temp;
 
546
  int code, val;
 
547
  uint32 l;
 
548
  /**
 
549
   * First attempt to do complete decode, by using the first 14 bits
 
550
   */
 
551
 
 
552
  bits->fill();
 
553
  code = bits->peekBitsNoFill(14);
 
554
  if (htbl->bigTable) {
 
555
    val = htbl->bigTable[code];
 
556
    if ((val&0xff) !=  0xff) {
 
557
      bits->skipBitsNoFill(val&0xff);
 
558
      return val >> 8;
 
559
    }
 
560
  }
 
561
  /*
 
562
  * If the huffman code is less than 8 bits, we can use the fast
 
563
  * table lookup to get its value.  It's more than 8 bits about
 
564
  * 3-4% of the time.
 
565
  */
 
566
  rv = 0;
 
567
  code = code>>6;
 
568
  val = htbl->numbits[code];
 
569
  l = val & 15;
 
570
  if (l) {
 
571
    bits->skipBitsNoFill(l);
 
572
    rv = val >> 4;
 
573
  }  else {
 
574
    bits->skipBitsNoFill(8);
 
575
    l = 8;
 
576
    while (code > htbl->maxcode[l]) {
 
577
      temp = bits->getBitNoFill();
 
578
      code = (code << 1) | temp;
 
579
      l++;
 
580
    }
 
581
 
 
582
    /*
 
583
    * With garbage input we may reach the sentinel value l = 17.
 
584
    */
 
585
 
 
586
    if (l > frame.prec || htbl->valptr[l] == 0xff) {
 
587
      ThrowRDE("Corrupt JPEG data: bad Huffman code:%u", l);
 
588
    } else {
 
589
      rv = htbl->huffval[htbl->valptr[l] +
 
590
                         ((int)(code - htbl->mincode[l]))];
 
591
    }
 
592
  }
 
593
 
 
594
  if (rv == 16) {
 
595
    if (mDNGCompatible)
 
596
      bits->skipBitsNoFill(16);
 
597
    return -32768;
 
598
  }
 
599
 
 
600
  // Ensure we have enough bits
 
601
  if ((rv + l) > 24) {
 
602
    if (rv > 16) // There is no values above 16 bits.
 
603
      ThrowRDE("Corrupt JPEG data: Too many bits requested.");
 
604
    else
 
605
      bits->fill();
 
606
  }
 
607
 
 
608
  /*
 
609
  * Section F.2.2.1: decode the difference and
 
610
  * Figure F.12: extend sign bit
 
611
  */
 
612
 
 
613
  if (rv) {
 
614
    int x = bits->getBitsNoFill(rv);
 
615
    if ((x & (1 << (rv - 1))) == 0)
 
616
      x -= (1 << rv) - 1;
 
617
    return x;
 
618
  }
 
619
  return 0;
 
620
}
 
621
 
 
622
} // namespace RawSpeed