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

« back to all changes in this revision

Viewing changes to extra/libkdcraw/libraw/RawSpeed/LJpegPlain.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 "LJpegPlain.h"
 
3
/*
 
4
RawSpeed - RAW file decoder.
 
5
 
 
6
Copyright (C) 2009 Klaus Post
 
7
 
 
8
This library is free software; you can redistribute it and/or
 
9
modify it under the terms of the GNU Lesser General Public
 
10
License as published by the Free Software Foundation; either
 
11
version 2 of the License, or (at your option) any later version.
 
12
 
 
13
This library is distributed in the hope that it will be useful,
 
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
16
Lesser General Public License for more details.
 
17
 
 
18
You should have received a copy of the GNU Lesser General Public
 
19
License along with this library; if not, write to the Free Software
 
20
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
21
 
 
22
http://www.klauspost.com
 
23
*/
 
24
 
 
25
namespace RawSpeed {
 
26
 
 
27
LJpegPlain::LJpegPlain(FileMap* file, RawImage img) :
 
28
    LJpegDecompressor(file, img) {
 
29
  offset = 0;
 
30
  slice_width = 0;
 
31
}
 
32
 
 
33
LJpegPlain::~LJpegPlain(void) {
 
34
  if (offset)
 
35
    delete[](offset);
 
36
  offset = 0;
 
37
  if (slice_width)
 
38
    delete[](slice_width);
 
39
  slice_width = 0;
 
40
}
 
41
 
 
42
void LJpegPlain::decodeScan() {
 
43
  // If image attempts to decode beyond the image bounds, strip it.
 
44
  if ((frame.w * frame.cps + offX * mRaw->getCpp()) > mRaw->dim.x * mRaw->getCpp())
 
45
    skipX = ((frame.w * frame.cps + offX * mRaw->getCpp()) - mRaw->dim.x * mRaw->getCpp()) / frame.cps;
 
46
  if (frame.h + offY > (uint32)mRaw->dim.y)
 
47
    skipY = frame.h + offY - mRaw->dim.y;
 
48
 
 
49
  _RPT1(0,"SlicesW:0x%x,\n",&slicesW);
 
50
  _RPT1(0,"Slices:%d\n",slicesW.size());
 
51
 
 
52
  if (slicesW.empty())
 
53
    slicesW.push_back(frame.w*frame.cps);
 
54
 
 
55
  if ( 0 == frame.h || 0 == frame.w)
 
56
    ThrowRDE("LJpegPlain::decodeScan: Image width or height set to zero");
 
57
 
 
58
  for (uint32 i = 0; i < frame.cps;  i++) {
 
59
    if (frame.compInfo[i].superH != 1 || frame.compInfo[i].superV != 1) {
 
60
      if (mRaw->isCFA)
 
61
        ThrowRDE("LJpegDecompressor::decodeScan: Cannot decode subsampled image to CFA data");
 
62
 
 
63
      if (mRaw->getCpp() != frame.cps)
 
64
        ThrowRDE("LJpegDecompressor::decodeScan: Subsampled component count does not match image.");
 
65
 
 
66
      if (pred == 1) {
 
67
        if (frame.compInfo[0].superH == 2 && frame.compInfo[0].superV == 2 &&
 
68
            frame.compInfo[1].superH == 1 && frame.compInfo[1].superV == 1 &&
 
69
            frame.compInfo[2].superH == 1 && frame.compInfo[2].superV == 1) {
 
70
          // Something like Cr2 sRaw1, use fast decoder
 
71
          decodeScanLeft4_2_0();
 
72
          return;
 
73
        } else if (frame.compInfo[0].superH == 2 && frame.compInfo[0].superV == 1 &&
 
74
                   frame.compInfo[1].superH == 1 && frame.compInfo[1].superV == 1 &&
 
75
                   frame.compInfo[2].superH == 1 && frame.compInfo[2].superV == 1) {
 
76
          // Something like Cr2 sRaw2, use fast decoder
 
77
          decodeScanLeft4_2_2();
 
78
          return;
 
79
        } else {
 
80
          ThrowRDE("LJpegDecompressor::decodeScan: Unsupported subsampling");
 
81
          decodeScanLeftGeneric();
 
82
          return;
 
83
        }
 
84
      } else {
 
85
        ThrowRDE("LJpegDecompressor::decodeScan: Unsupported prediction direction.");
 
86
      }
 
87
    }
 
88
  }
 
89
 
 
90
  if (pred == 1) {
 
91
    if (frame.cps == 2)
 
92
      decodeScanLeft2Comps();
 
93
    else if (frame.cps == 3)
 
94
      decodeScanLeft3Comps();
 
95
    else if (frame.cps == 4)
 
96
      decodeScanLeft4Comps();
 
97
    else
 
98
      ThrowRDE("LJpegDecompressor::decodeScan: Unsupported component direction count.");
 
99
    return;
 
100
  }
 
101
  ThrowRDE("LJpegDecompressor::decodeScan: Unsupported prediction direction.");
 
102
}
 
103
 
 
104
/**
 
105
*  CR2 Slice handling:
 
106
*  In the following code, canon slices are handled in-place, to avoid having to
 
107
*  copy the entire frame afterwards.
 
108
*  The "offset" array is created to easily map slice positions on to the output image.
 
109
*  The offset array size is the number of slices multiplied by height.
 
110
*  Each of these offsets are an offset into the destination image, and it also contains the
 
111
*  slice number (shifted up 28 bits), so it is possible to retrieve the width of each slice.
 
112
*  Every time "components" pixels has been processed the slice size is tested, and output offset
 
113
*  is adjusted if needed. This makes slice handling very "light", since it involves a single
 
114
*  counter, and a predictable branch.
 
115
*  For unsliced images, add one slice with the width of the image.
 
116
**/
 
117
 
 
118
void LJpegPlain::decodeScanLeftGeneric() {
 
119
  _ASSERTE(slicesW.size() < 16);  // We only have 4 bits for slice number.
 
120
  _ASSERTE(!(slicesW.size() > 1 && skipX)); // Check if this is a valid state
 
121
 
 
122
  uint32 comps = frame.cps;  // Components
 
123
  HuffmanTable *dctbl[4];   // Tables for up to 4 components
 
124
  ushort16 *predict;         // Prediction pointer
 
125
  /* Fast access to supersampling component settings
 
126
  * this is the number of components in a given block.
 
127
  */
 
128
  uint32 samplesH[4];
 
129
  uint32 samplesV[4];
 
130
 
 
131
  uchar8 *draw = mRaw->getData();
 
132
  uint32 maxSuperH = 1;
 
133
  uint32 maxSuperV = 1;
 
134
  uint32 samplesComp[4]; // How many samples per group does this component have
 
135
  uint32 pixGroup = 0;   // How many pixels per group.
 
136
 
 
137
  for (uint32 i = 0; i < comps; i++) {
 
138
    dctbl[i] = &huff[frame.compInfo[i].dcTblNo];
 
139
    samplesH[i] = frame.compInfo[i].superH;
 
140
    if (!isPowerOfTwo(samplesH[i]))
 
141
      ThrowRDE("LJpegPlain::decodeScanLeftGeneric: Horizontal sampling is not power of two.");
 
142
    maxSuperH = max(samplesH[i], maxSuperH);
 
143
    samplesV[i] = frame.compInfo[i].superV;
 
144
    if (!isPowerOfTwo(samplesV[i]))
 
145
      ThrowRDE("LJpegPlain::decodeScanLeftGeneric: Vertical sampling is not power of two.");
 
146
    maxSuperV = max(samplesV[i], maxSuperV);
 
147
    samplesComp[i] = samplesV[i] * samplesH[i];
 
148
    pixGroup += samplesComp[i];
 
149
  }
 
150
 
 
151
  mRaw->subsampling.x = maxSuperH;
 
152
  mRaw->subsampling.y = maxSuperV;
 
153
 
 
154
  //Prepare slices (for CR2)
 
155
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY) / maxSuperV;
 
156
  offset = new uint32[slices+1];
 
157
 
 
158
  uint32 t_y = 0;
 
159
  uint32 t_x = 0;
 
160
  uint32 t_s = 0;
 
161
  uint32 slice = 0;
 
162
  uint32 pitch_s = mRaw->pitch / 2;  // Pitch in shorts
 
163
  slice_width = new int[slices];
 
164
 
 
165
  // This is divided by comps, since comps pixels are processed at the time
 
166
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
167
    slice_width[i] = slicesW[i] / pixGroup / maxSuperH; // This is a guess, but works for sRaw1+2.
 
168
 
 
169
  for (slice = 0; slice < slices; slice++) {
 
170
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
171
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
172
    t_y += maxSuperV;
 
173
    if (t_y >= (frame.h - skipY)) {
 
174
      t_y = 0;
 
175
      t_x += slice_width[t_s++];
 
176
    }
 
177
  }
 
178
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
179
 
 
180
  if (skipX)
 
181
    ThrowRDE("LJpegPlain::decodeScanLeftGeneric: Cannot skip right border in subsampled mode");
 
182
 
 
183
  // Predictors for components
 
184
  int p[4];
 
185
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
186
 
 
187
  // Always points to next slice
 
188
  slice = 1;
 
189
  uint32 pixInSlice = slice_width[0];
 
190
 
 
191
  // Initialize predictors and decode one group.
 
192
  uint32 x = 0;
 
193
  predict = dest;
 
194
  for (uint32 i = 0; i < comps; i++) {
 
195
    for (uint32 y2 = 0; y2 < samplesV[i]; y2++) {
 
196
      for (uint32 x2 = 0; x2 < samplesH[i]; x2++) {
 
197
        // First pixel is not predicted, all other are.
 
198
        if (y2 == 0 && x2 == 0) {
 
199
          *dest = p[i] = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl[i]);
 
200
        } else {
 
201
          p[i] += HuffDecode(dctbl[i]);
 
202
          _ASSERTE(p[i] >= 0 && p[i] < 65536);
 
203
          dest[x2*comps+y2*pitch_s] = p[i];
 
204
        }
 
205
      }
 
206
    }
 
207
    // Set predictor for this component
 
208
    // Next component
 
209
    dest++;
 
210
  }
 
211
 
 
212
  // Increment destination to next group
 
213
  dest += (maxSuperH - 1) * comps;
 
214
  x = maxSuperH;
 
215
  pixInSlice -= maxSuperH;
 
216
 
 
217
  uint32 cw = (frame.w - skipX);
 
218
  for (uint32 y = 0;y < (frame.h - skipY);y += maxSuperV) {
 
219
    for (; x < cw ; x += maxSuperH) {
 
220
 
 
221
      if (0 == pixInSlice) { // Next slice
 
222
        if (slice > slices)
 
223
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
224
        uint32 o = offset[slice++];
 
225
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
226
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
227
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
228
        pixInSlice = slice_width[o>>28];
 
229
 
 
230
        // If new are at the start of a new line, also update predictors.
 
231
        if (x == 0)
 
232
          predict = dest;
 
233
      }
 
234
 
 
235
      for (uint32 i = 0; i < comps; i++) {
 
236
        for (uint32 y2 = 0; y2 < samplesV[i]; y2++) {
 
237
          for (uint32 x2 = 0; x2 < samplesH[i]; x2++) {
 
238
            p[i] += HuffDecode(dctbl[i]);
 
239
            _ASSERTE(p[i] >= 0 && p[i] < 65536);
 
240
            dest[x2*comps+y2*pitch_s] = p[i];
 
241
          }
 
242
        }
 
243
        dest++;
 
244
      }
 
245
      dest += (maxSuperH * comps) - comps;
 
246
      pixInSlice -= maxSuperH;
 
247
      // Check if we are still within the file.
 
248
      bits->checkPos();
 
249
    }
 
250
    // Update predictors
 
251
    for (uint32 i = 0; i < comps; i++) {
 
252
      p[i] = predict[i];
 
253
      // Ensure, that there is a slice shift at new line
 
254
      if (!(pixInSlice == 0 || maxSuperV == 1))
 
255
        ThrowRDE("LJpegPlain::decodeScanLeftGeneric: Slice not placed at new line");
 
256
    }
 
257
    predict = dest;
 
258
    x = 0;
 
259
  }
 
260
}
 
261
 
 
262
#define COMPS 3
 
263
/*************************************************************************/
 
264
/* These are often used compression schemes, heavily optimized to decode */
 
265
/* that specfic kind of images.                                          */
 
266
/*************************************************************************/
 
267
 
 
268
void LJpegPlain::decodeScanLeft4_2_0() {
 
269
  _ASSERTE(slicesW.size() < 16);  // We only have 4 bits for slice number.
 
270
  _ASSERTE(!(slicesW.size() > 1 && skipX)); // Check if this is a valid state
 
271
  _ASSERTE(frame.compInfo[0].superH == 2);   // Check if this is a valid state
 
272
  _ASSERTE(frame.compInfo[0].superV == 2);   // Check if this is a valid state
 
273
  _ASSERTE(frame.compInfo[1].superH == 1);   // Check if this is a valid state
 
274
  _ASSERTE(frame.compInfo[1].superV == 1);   // Check if this is a valid state
 
275
  _ASSERTE(frame.compInfo[2].superH == 1);   // Check if this is a valid state
 
276
  _ASSERTE(frame.compInfo[2].superV == 1);   // Check if this is a valid state
 
277
  _ASSERTE(frame.cps == COMPS);
 
278
  _ASSERTE(skipX == 0);
 
279
 
 
280
  HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
 
281
  HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
 
282
  HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
 
283
 
 
284
  ushort16 *predict;      // Prediction pointer
 
285
 
 
286
  mRaw->subsampling.x = 2;
 
287
  mRaw->subsampling.y = 2;
 
288
 
 
289
  uchar8 *draw = mRaw->getData();
 
290
 
 
291
  //Prepare slices (for CR2)
 
292
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY) / 2;
 
293
  offset = new uint32[slices+1];
 
294
 
 
295
  uint32 t_y = 0;
 
296
  uint32 t_x = 0;
 
297
  uint32 t_s = 0;
 
298
  uint32 slice = 0;
 
299
  uint32 pitch_s = mRaw->pitch / 2;  // Pitch in shorts
 
300
  slice_width = new int[slices];
 
301
 
 
302
  // This is divided by comps, since comps pixels are processed at the time
 
303
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
304
    slice_width[i] = slicesW[i] / COMPS;
 
305
 
 
306
  for (slice = 0; slice < slices; slice++) {
 
307
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
308
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
309
    t_y += 2;
 
310
    if (t_y >= (frame.h - skipY)) {
 
311
      t_y = 0;
 
312
      t_x += slice_width[t_s++];
 
313
    }
 
314
  }
 
315
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
316
 
 
317
  if (skipX)
 
318
    slice_width[slicesW.size()-1] -= skipX;
 
319
 
 
320
  // Predictors for components
 
321
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
322
 
 
323
  // Always points to next slice
 
324
  slice = 1;
 
325
  uint32 pixInSlice = slice_width[0];
 
326
 
 
327
  // Initialize predictors and decode one group.
 
328
  uint32 x = 0;
 
329
  int p1;
 
330
  int p2;
 
331
  int p3;
 
332
  // First pixel is not predicted, all other are.
 
333
  *dest = p1 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl1);
 
334
  p1 = dest[COMPS] = p1 + HuffDecode(dctbl1);
 
335
  p1 = dest[pitch_s] = p1 + HuffDecode(dctbl1);
 
336
  p1 = dest[COMPS+pitch_s] = p1 + HuffDecode(dctbl1);
 
337
  predict = dest;
 
338
 
 
339
  dest[1] = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
 
340
  dest[2] = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
 
341
 
 
342
  // Skip next
 
343
  dest += COMPS * 2;
 
344
 
 
345
  x = 2;
 
346
  pixInSlice -= 2;
 
347
 
 
348
  uint32 cw = (frame.w - skipX);
 
349
  for (uint32 y = 0;y < (frame.h - skipY);y += 2) {
 
350
    for (; x < cw ; x += 2) {
 
351
 
 
352
      if (0 == pixInSlice) { // Next slice
 
353
        if (slice > slices)
 
354
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
355
        uint32 o = offset[slice++];
 
356
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
357
        _ASSERTE((o&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
358
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
359
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
360
        pixInSlice = slice_width[o>>28];
 
361
 
 
362
        // If new are at the start of a new line, also update predictors.
 
363
        if (x == 0) {
 
364
          predict = dest;
 
365
        }
 
366
      }
 
367
      p1 += HuffDecode(dctbl1);
 
368
      *dest = p1;
 
369
      p1 += HuffDecode(dctbl1);
 
370
      dest[COMPS] = p1;
 
371
      p1 += HuffDecode(dctbl1);
 
372
      dest[pitch_s] = p1;
 
373
      p1 += HuffDecode(dctbl1);
 
374
      dest[pitch_s+COMPS] = p1;
 
375
 
 
376
      dest[1] = p2 = p2 + HuffDecode(dctbl2);
 
377
      dest[2] = p3 = p3 + HuffDecode(dctbl3);
 
378
 
 
379
      dest += COMPS * 2;
 
380
      pixInSlice -= 2;
 
381
      // Check if we are still within the file.
 
382
      bits->checkPos();
 
383
    }
 
384
 
 
385
    // Update predictors
 
386
    p1 = predict[0];
 
387
    p2 = predict[1];
 
388
    p3 = predict[2];
 
389
    _ASSERTE(pixInSlice == 0);  // Ensure, that there is a slice shift at new line
 
390
 
 
391
    x = 0;
 
392
  }
 
393
}
 
394
 
 
395
void LJpegPlain::decodeScanLeft4_2_2() {
 
396
  _ASSERTE(slicesW.size() < 16);  // We only have 4 bits for slice number.
 
397
  _ASSERTE(!(slicesW.size() > 1 && skipX)); // Check if this is a valid state
 
398
  _ASSERTE(frame.compInfo[0].superH == 2);   // Check if this is a valid state
 
399
  _ASSERTE(frame.compInfo[0].superV == 1);   // Check if this is a valid state
 
400
  _ASSERTE(frame.compInfo[1].superH == 1);   // Check if this is a valid state
 
401
  _ASSERTE(frame.compInfo[1].superV == 1);   // Check if this is a valid state
 
402
  _ASSERTE(frame.compInfo[2].superH == 1);   // Check if this is a valid state
 
403
  _ASSERTE(frame.compInfo[2].superV == 1);   // Check if this is a valid state
 
404
  _ASSERTE(frame.cps == COMPS);
 
405
  _ASSERTE(skipX == 0);
 
406
 
 
407
  HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
 
408
  HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
 
409
  HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
 
410
 
 
411
  mRaw->subsampling.x = 2;
 
412
  mRaw->subsampling.y = 1;
 
413
 
 
414
  ushort16 *predict;      // Prediction pointer
 
415
 
 
416
  uchar8 *draw = mRaw->getData();
 
417
 
 
418
  //Prepare slices (for CR2)
 
419
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
 
420
  offset = new uint32[slices+1];
 
421
 
 
422
  uint32 t_y = 0;
 
423
  uint32 t_x = 0;
 
424
  uint32 t_s = 0;
 
425
  uint32 slice = 0;
 
426
  slice_width = new int[slices];
 
427
 
 
428
  // This is divided by comps, since comps pixels are processed at the time
 
429
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
430
    slice_width[i] = slicesW[i] / 2;
 
431
 
 
432
  for (slice = 0; slice < slices; slice++) {
 
433
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
434
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
435
    t_y ++;
 
436
    if (t_y >= (frame.h - skipY)) {
 
437
      t_y = 0;
 
438
      t_x += slice_width[t_s++];
 
439
    }
 
440
  }
 
441
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
442
 
 
443
  if (skipX)
 
444
    slice_width[slicesW.size()-1] -= skipX;
 
445
 
 
446
  // Predictors for components
 
447
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
448
 
 
449
  // Always points to next slice
 
450
  slice = 1;
 
451
  uint32 pixInSlice = slice_width[0];
 
452
 
 
453
  // Initialize predictors and decode one group.
 
454
  uint32 x = 0;
 
455
  int p1;
 
456
  int p2;
 
457
  int p3;
 
458
  // First pixel is not predicted, all other are.
 
459
  *dest = p1 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl1);
 
460
  p1 = dest[COMPS] = p1 + HuffDecode(dctbl1);
 
461
  predict = dest;
 
462
 
 
463
  dest[1] = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
 
464
  dest[2] = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
 
465
 
 
466
  // Skip to next
 
467
  dest += COMPS * 2;
 
468
 
 
469
  x = 2;
 
470
  pixInSlice -= 2;
 
471
 
 
472
  uint32 cw = (frame.w - skipX);
 
473
  for (uint32 y = 0;y < (frame.h - skipY);y++) {
 
474
    for (; x < cw ; x += 2) {
 
475
 
 
476
      if (0 == pixInSlice) { // Next slice
 
477
        if (slice > slices)
 
478
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
479
        uint32 o = offset[slice++];
 
480
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
481
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
482
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
483
        pixInSlice = slice_width[o>>28];
 
484
 
 
485
        // If new are at the start of a new line, also update predictors.
 
486
        if (x == 0) {
 
487
          predict = dest;
 
488
        }
 
489
      }
 
490
      p1 += HuffDecode(dctbl1);
 
491
      *dest = p1;
 
492
      p1 += HuffDecode(dctbl1);
 
493
      dest[COMPS] = p1;
 
494
 
 
495
      dest[1] = p2 = p2 + HuffDecode(dctbl2);
 
496
      dest[2] = p3 = p3 + HuffDecode(dctbl3);
 
497
 
 
498
      dest += COMPS * 2;
 
499
      pixInSlice -= 2;
 
500
      // Check if we are still within the file.
 
501
      bits->checkPos();
 
502
    }
 
503
 
 
504
    // Update predictors
 
505
    p1 = predict[0];
 
506
    p2 = predict[1];
 
507
    p3 = predict[2];
 
508
    predict = dest;
 
509
    x = 0;
 
510
  }
 
511
}
 
512
 
 
513
#undef COMPS
 
514
#define COMPS 2
 
515
void LJpegPlain::decodeScanLeft2Comps() {
 
516
  _ASSERTE(slicesW.size() < 16);  // We only have 4 bits for slice number.
 
517
  _ASSERTE(!(slicesW.size() > 1 && skipX)); // Check if this is a valid state
 
518
 
 
519
  uchar8 *draw = mRaw->getData();
 
520
  // First line
 
521
  HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
 
522
  HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
 
523
 
 
524
  //Prepare slices (for CR2)
 
525
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
 
526
  offset = new uint32[slices+1];
 
527
 
 
528
  uint32 t_y = 0;
 
529
  uint32 t_x = 0;
 
530
  uint32 t_s = 0;
 
531
  uint32 slice = 0;
 
532
  uint32 cw = (frame.w - skipX);
 
533
  for (slice = 0; slice < slices; slice++) {
 
534
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
535
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
536
    t_y++;
 
537
    if (t_y == (frame.h - skipY)) {
 
538
      t_y = 0;
 
539
      t_x += slicesW[t_s++];
 
540
    }
 
541
  }
 
542
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
543
 
 
544
  slice_width = new int[slices];
 
545
 
 
546
  // This is divided by comps, since comps pixels are processed at the time
 
547
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
548
    slice_width[i] = slicesW[i] / COMPS;
 
549
 
 
550
  if (skipX)
 
551
    slice_width[slicesW.size()-1] -= skipX;
 
552
 
 
553
  // First pixels are obviously not predicted
 
554
  int p1;
 
555
  int p2;
 
556
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
557
  ushort16 *predict = dest;
 
558
  *dest++ = p1 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl1);
 
559
  *dest++ = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
 
560
 
 
561
  slice = 1;    // Always points to next slice
 
562
  uint32 pixInSlice = slice_width[0] - 1;  // Skip first pixel
 
563
 
 
564
  uint32 x = 1;                            // Skip first pixels on first line.
 
565
  for (uint32 y = 0;y < (frame.h - skipY);y++) {
 
566
    for (; x < cw ; x++) {
 
567
      int diff = HuffDecode(dctbl1);
 
568
      p1 += diff;
 
569
      *dest++ = (ushort16)p1;
 
570
  //    _ASSERTE(p1 >= 0 && p1 < 65536);
 
571
 
 
572
      diff = HuffDecode(dctbl2);
 
573
      p2 += diff;
 
574
      *dest++ = (ushort16)p2;
 
575
//      _ASSERTE(p2 >= 0 && p2 < 65536);
 
576
 
 
577
      if (0 == --pixInSlice) { // Next slice
 
578
        if (slice > slices)
 
579
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
580
        uint32 o = offset[slice++];
 
581
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
582
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
583
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
584
        pixInSlice = slice_width[o>>28];
 
585
      }
 
586
      bits->checkPos();
 
587
    }
 
588
 
 
589
    if (skipX) {
 
590
      for (uint32 i = 0; i < skipX; i++) {
 
591
        HuffDecode(dctbl1);
 
592
        HuffDecode(dctbl2);
 
593
      }
 
594
    }
 
595
 
 
596
    p1 = predict[0];  // Predictors for next row
 
597
    p2 = predict[1];
 
598
    predict = dest;  // Adjust destination for next prediction
 
599
    x = 0;
 
600
  }
 
601
}
 
602
 
 
603
#undef COMPS
 
604
#define COMPS 3
 
605
 
 
606
void LJpegPlain::decodeScanLeft3Comps() {
 
607
  uchar8 *draw = mRaw->getData();
 
608
  // First line
 
609
  HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
 
610
  HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
 
611
  HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
 
612
 
 
613
  //Prepare slices (for CR2)
 
614
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
 
615
  offset = new uint32[slices+1];
 
616
 
 
617
  uint32 t_y = 0;
 
618
  uint32 t_x = 0;
 
619
  uint32 t_s = 0;
 
620
  uint32 slice = 0;
 
621
  for (slice = 0; slice < slices; slice++) {
 
622
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
623
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
624
    t_y++;
 
625
    if (t_y == (frame.h - skipY)) {
 
626
      t_y = 0;
 
627
      t_x += slicesW[t_s++];
 
628
    }
 
629
  }
 
630
 
 
631
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
632
 
 
633
  slice_width = new int[slices];
 
634
 
 
635
  // This is divided by comps, since comps pixels are processed at the time
 
636
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
637
    slice_width[i] = slicesW[i] / COMPS;
 
638
 
 
639
  if (skipX)
 
640
    slice_width[slicesW.size()-1] -= skipX;
 
641
 
 
642
  // First pixels are obviously not predicted
 
643
  int p1;
 
644
  int p2;
 
645
  int p3;
 
646
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
647
  ushort16 *predict = dest;
 
648
  *dest++ = p1 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl1);
 
649
  *dest++ = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
 
650
  *dest++ = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
 
651
 
 
652
  slice = 1;
 
653
  uint32 pixInSlice = slice_width[0] - 1;
 
654
 
 
655
  uint32 cw = (frame.w - skipX);
 
656
  uint32 x = 1;                            // Skip first pixels on first line.
 
657
 
 
658
  for (uint32 y = 0;y < (frame.h - skipY);y++) {
 
659
    for (; x < cw ; x++) {
 
660
      p1 += HuffDecode(dctbl1);
 
661
      *dest++ = (ushort16)p1;
 
662
 
 
663
      p2 += HuffDecode(dctbl2);
 
664
      *dest++ = (ushort16)p2;
 
665
 
 
666
      p3 += HuffDecode(dctbl3);
 
667
      *dest++ = (ushort16)p3;
 
668
 
 
669
      if (0 == --pixInSlice) { // Next slice
 
670
        if (slice > slices)
 
671
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
672
        uint32 o = offset[slice++];
 
673
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
674
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
675
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
676
        _ASSERTE((o >> 28) < slicesW.size());
 
677
        pixInSlice = slice_width[o>>28];
 
678
      }
 
679
      bits->checkPos();
 
680
    }
 
681
 
 
682
    if (skipX) {
 
683
      for (uint32 i = 0; i < skipX; i++) {
 
684
        HuffDecode(dctbl1);
 
685
        HuffDecode(dctbl2);
 
686
        HuffDecode(dctbl3);
 
687
      }
 
688
    }
 
689
 
 
690
    p1 = predict[0];  // Predictors for next row
 
691
    p2 = predict[1];
 
692
    p3 = predict[2];  // Predictors for next row
 
693
    predict = dest;  // Adjust destination for next prediction
 
694
    x = 0;
 
695
  }
 
696
}
 
697
 
 
698
#undef COMPS
 
699
#define COMPS 4
 
700
 
 
701
void LJpegPlain::decodeScanLeft4Comps() {
 
702
  uchar8 *draw = mRaw->getData();
 
703
  // First line
 
704
  HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
 
705
  HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
 
706
  HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
 
707
  HuffmanTable *dctbl4 = &huff[frame.compInfo[3].dcTblNo];
 
708
 
 
709
  //Prepare slices (for CR2)
 
710
  uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
 
711
  offset = new uint32[slices+1];
 
712
 
 
713
  uint32 t_y = 0;
 
714
  uint32 t_x = 0;
 
715
  uint32 t_s = 0;
 
716
  uint32 slice = 0;
 
717
  for (slice = 0; slice < slices; slice++) {
 
718
    offset[slice] = ((t_x + offX) * mRaw->getBpp() + ((offY + t_y) * mRaw->pitch)) | (t_s << 28);
 
719
    _ASSERTE((offset[slice]&0x0fffffff) < mRaw->pitch*mRaw->dim.y);
 
720
    t_y++;
 
721
    if (t_y == (frame.h - skipY)) {
 
722
      t_y = 0;
 
723
      t_x += slicesW[t_s++];
 
724
    }
 
725
  }
 
726
  offset[slices] = offset[slices-1];        // Extra offset to avoid branch in loop.
 
727
 
 
728
  slice_width = new int[slices];
 
729
 
 
730
  // This is divided by comps, since comps pixels are processed at the time
 
731
  for (uint32 i = 0 ; i <  slicesW.size(); i++)
 
732
    slice_width[i] = slicesW[i] / COMPS;
 
733
 
 
734
  if (skipX)
 
735
    slice_width[slicesW.size()-1] -= skipX;
 
736
 
 
737
  // First pixels are obviously not predicted
 
738
  int p1;
 
739
  int p2;
 
740
  int p3;
 
741
  int p4;
 
742
  ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
 
743
  ushort16 *predict = dest;
 
744
  *dest++ = p1 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl1);
 
745
  *dest++ = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
 
746
  *dest++ = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
 
747
  *dest++ = p4 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl4);
 
748
 
 
749
  slice = 1;
 
750
  uint32 pixInSlice = slice_width[0] - 1;
 
751
 
 
752
  uint32 cw = (frame.w - skipX);
 
753
  uint32 x = 1;                            // Skip first pixels on first line.
 
754
 
 
755
  for (uint32 y = 0;y < (frame.h - skipY);y++) {
 
756
    for (; x < cw ; x++) {
 
757
      p1 += HuffDecode(dctbl1);
 
758
      *dest++ = (ushort16)p1;
 
759
 
 
760
      p2 += HuffDecode(dctbl2);
 
761
      *dest++ = (ushort16)p2;
 
762
 
 
763
      p3 += HuffDecode(dctbl3);
 
764
      *dest++ = (ushort16)p3;
 
765
 
 
766
      p4 += HuffDecode(dctbl4);
 
767
      *dest++ = (ushort16)p4;
 
768
 
 
769
      if (0 == --pixInSlice) { // Next slice
 
770
        if (slice > slices)
 
771
          ThrowRDE("LJpegPlain::decodeScanLeft: Ran out of slices");
 
772
        uint32 o = offset[slice++];
 
773
        dest = (ushort16*) & draw[o&0x0fffffff];  // Adjust destination for next pixel
 
774
        if((o&0x0fffffff) > mRaw->pitch*mRaw->dim.y)
 
775
          ThrowRDE("LJpegPlain::decodeScanLeft: Offset out of bounds");
 
776
        pixInSlice = slice_width[o>>28];
 
777
      }
 
778
      bits->checkPos();
 
779
    }
 
780
    if (skipX) {
 
781
      for (uint32 i = 0; i < skipX; i++) {
 
782
        HuffDecode(dctbl1);
 
783
        HuffDecode(dctbl2);
 
784
        HuffDecode(dctbl3);
 
785
        HuffDecode(dctbl4);
 
786
      }
 
787
    }
 
788
    p1 = predict[0];  // Predictors for next row
 
789
    p2 = predict[1];
 
790
    p3 = predict[2];  // Predictors for next row
 
791
    p4 = predict[3];
 
792
    predict = dest;  // Adjust destination for next prediction
 
793
    x = 0;
 
794
  }
 
795
}
 
796
 
 
797
} // namespace RawSpeed