2
#include "LJpegPlain.h"
4
RawSpeed - RAW file decoder.
6
Copyright (C) 2009 Klaus Post
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.
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.
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
22
http://www.klauspost.com
27
LJpegPlain::LJpegPlain(FileMap* file, RawImage img) :
28
LJpegDecompressor(file, img) {
33
LJpegPlain::~LJpegPlain(void) {
38
delete[](slice_width);
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;
49
_RPT1(0,"SlicesW:0x%x,\n",&slicesW);
50
_RPT1(0,"Slices:%d\n",slicesW.size());
53
slicesW.push_back(frame.w*frame.cps);
55
if ( 0 == frame.h || 0 == frame.w)
56
ThrowRDE("LJpegPlain::decodeScan: Image width or height set to zero");
58
for (uint32 i = 0; i < frame.cps; i++) {
59
if (frame.compInfo[i].superH != 1 || frame.compInfo[i].superV != 1) {
61
ThrowRDE("LJpegDecompressor::decodeScan: Cannot decode subsampled image to CFA data");
63
if (mRaw->getCpp() != frame.cps)
64
ThrowRDE("LJpegDecompressor::decodeScan: Subsampled component count does not match image.");
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();
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();
80
ThrowRDE("LJpegDecompressor::decodeScan: Unsupported subsampling");
81
decodeScanLeftGeneric();
85
ThrowRDE("LJpegDecompressor::decodeScan: Unsupported prediction direction.");
92
decodeScanLeft2Comps();
93
else if (frame.cps == 3)
94
decodeScanLeft3Comps();
95
else if (frame.cps == 4)
96
decodeScanLeft4Comps();
98
ThrowRDE("LJpegDecompressor::decodeScan: Unsupported component direction count.");
101
ThrowRDE("LJpegDecompressor::decodeScan: Unsupported prediction direction.");
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.
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
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.
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.
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];
151
mRaw->subsampling.x = maxSuperH;
152
mRaw->subsampling.y = maxSuperV;
154
//Prepare slices (for CR2)
155
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY) / maxSuperV;
156
offset = new uint32[slices+1];
162
uint32 pitch_s = mRaw->pitch / 2; // Pitch in shorts
163
slice_width = new int[slices];
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.
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);
173
if (t_y >= (frame.h - skipY)) {
175
t_x += slice_width[t_s++];
178
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
181
ThrowRDE("LJpegPlain::decodeScanLeftGeneric: Cannot skip right border in subsampled mode");
183
// Predictors for components
185
ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
187
// Always points to next slice
189
uint32 pixInSlice = slice_width[0];
191
// Initialize predictors and decode one group.
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]);
201
p[i] += HuffDecode(dctbl[i]);
202
_ASSERTE(p[i] >= 0 && p[i] < 65536);
203
dest[x2*comps+y2*pitch_s] = p[i];
207
// Set predictor for this component
212
// Increment destination to next group
213
dest += (maxSuperH - 1) * comps;
215
pixInSlice -= maxSuperH;
217
uint32 cw = (frame.w - skipX);
218
for (uint32 y = 0;y < (frame.h - skipY);y += maxSuperV) {
219
for (; x < cw ; x += maxSuperH) {
221
if (0 == pixInSlice) { // Next slice
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];
230
// If new are at the start of a new line, also update predictors.
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];
245
dest += (maxSuperH * comps) - comps;
246
pixInSlice -= maxSuperH;
247
// Check if we are still within the file.
251
for (uint32 i = 0; i < comps; 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");
263
/*************************************************************************/
264
/* These are often used compression schemes, heavily optimized to decode */
265
/* that specfic kind of images. */
266
/*************************************************************************/
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);
280
HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
281
HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
282
HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
284
ushort16 *predict; // Prediction pointer
286
mRaw->subsampling.x = 2;
287
mRaw->subsampling.y = 2;
289
uchar8 *draw = mRaw->getData();
291
//Prepare slices (for CR2)
292
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY) / 2;
293
offset = new uint32[slices+1];
299
uint32 pitch_s = mRaw->pitch / 2; // Pitch in shorts
300
slice_width = new int[slices];
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;
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);
310
if (t_y >= (frame.h - skipY)) {
312
t_x += slice_width[t_s++];
315
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
318
slice_width[slicesW.size()-1] -= skipX;
320
// Predictors for components
321
ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
323
// Always points to next slice
325
uint32 pixInSlice = slice_width[0];
327
// Initialize predictors and decode one group.
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);
339
dest[1] = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
340
dest[2] = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
348
uint32 cw = (frame.w - skipX);
349
for (uint32 y = 0;y < (frame.h - skipY);y += 2) {
350
for (; x < cw ; x += 2) {
352
if (0 == pixInSlice) { // Next slice
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];
362
// If new are at the start of a new line, also update predictors.
367
p1 += HuffDecode(dctbl1);
369
p1 += HuffDecode(dctbl1);
371
p1 += HuffDecode(dctbl1);
373
p1 += HuffDecode(dctbl1);
374
dest[pitch_s+COMPS] = p1;
376
dest[1] = p2 = p2 + HuffDecode(dctbl2);
377
dest[2] = p3 = p3 + HuffDecode(dctbl3);
381
// Check if we are still within the file.
389
_ASSERTE(pixInSlice == 0); // Ensure, that there is a slice shift at new line
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);
407
HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
408
HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
409
HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
411
mRaw->subsampling.x = 2;
412
mRaw->subsampling.y = 1;
414
ushort16 *predict; // Prediction pointer
416
uchar8 *draw = mRaw->getData();
418
//Prepare slices (for CR2)
419
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
420
offset = new uint32[slices+1];
426
slice_width = new int[slices];
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;
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);
436
if (t_y >= (frame.h - skipY)) {
438
t_x += slice_width[t_s++];
441
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
444
slice_width[slicesW.size()-1] -= skipX;
446
// Predictors for components
447
ushort16 *dest = (ushort16*) & draw[offset[0] & 0x0fffffff];
449
// Always points to next slice
451
uint32 pixInSlice = slice_width[0];
453
// Initialize predictors and decode one group.
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);
463
dest[1] = p2 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl2);
464
dest[2] = p3 = (1 << (frame.prec - Pt - 1)) + HuffDecode(dctbl3);
472
uint32 cw = (frame.w - skipX);
473
for (uint32 y = 0;y < (frame.h - skipY);y++) {
474
for (; x < cw ; x += 2) {
476
if (0 == pixInSlice) { // Next slice
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];
485
// If new are at the start of a new line, also update predictors.
490
p1 += HuffDecode(dctbl1);
492
p1 += HuffDecode(dctbl1);
495
dest[1] = p2 = p2 + HuffDecode(dctbl2);
496
dest[2] = p3 = p3 + HuffDecode(dctbl3);
500
// Check if we are still within the file.
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
519
uchar8 *draw = mRaw->getData();
521
HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
522
HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
524
//Prepare slices (for CR2)
525
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
526
offset = new uint32[slices+1];
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);
537
if (t_y == (frame.h - skipY)) {
539
t_x += slicesW[t_s++];
542
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
544
slice_width = new int[slices];
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;
551
slice_width[slicesW.size()-1] -= skipX;
553
// First pixels are obviously not predicted
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);
561
slice = 1; // Always points to next slice
562
uint32 pixInSlice = slice_width[0] - 1; // Skip first pixel
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);
569
*dest++ = (ushort16)p1;
570
// _ASSERTE(p1 >= 0 && p1 < 65536);
572
diff = HuffDecode(dctbl2);
574
*dest++ = (ushort16)p2;
575
// _ASSERTE(p2 >= 0 && p2 < 65536);
577
if (0 == --pixInSlice) { // Next slice
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];
590
for (uint32 i = 0; i < skipX; i++) {
596
p1 = predict[0]; // Predictors for next row
598
predict = dest; // Adjust destination for next prediction
606
void LJpegPlain::decodeScanLeft3Comps() {
607
uchar8 *draw = mRaw->getData();
609
HuffmanTable *dctbl1 = &huff[frame.compInfo[0].dcTblNo];
610
HuffmanTable *dctbl2 = &huff[frame.compInfo[1].dcTblNo];
611
HuffmanTable *dctbl3 = &huff[frame.compInfo[2].dcTblNo];
613
//Prepare slices (for CR2)
614
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
615
offset = new uint32[slices+1];
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);
625
if (t_y == (frame.h - skipY)) {
627
t_x += slicesW[t_s++];
631
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
633
slice_width = new int[slices];
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;
640
slice_width[slicesW.size()-1] -= skipX;
642
// First pixels are obviously not predicted
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);
653
uint32 pixInSlice = slice_width[0] - 1;
655
uint32 cw = (frame.w - skipX);
656
uint32 x = 1; // Skip first pixels on first line.
658
for (uint32 y = 0;y < (frame.h - skipY);y++) {
659
for (; x < cw ; x++) {
660
p1 += HuffDecode(dctbl1);
661
*dest++ = (ushort16)p1;
663
p2 += HuffDecode(dctbl2);
664
*dest++ = (ushort16)p2;
666
p3 += HuffDecode(dctbl3);
667
*dest++ = (ushort16)p3;
669
if (0 == --pixInSlice) { // Next slice
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];
683
for (uint32 i = 0; i < skipX; i++) {
690
p1 = predict[0]; // Predictors for next row
692
p3 = predict[2]; // Predictors for next row
693
predict = dest; // Adjust destination for next prediction
701
void LJpegPlain::decodeScanLeft4Comps() {
702
uchar8 *draw = mRaw->getData();
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];
709
//Prepare slices (for CR2)
710
uint32 slices = (uint32)slicesW.size() * (frame.h - skipY);
711
offset = new uint32[slices+1];
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);
721
if (t_y == (frame.h - skipY)) {
723
t_x += slicesW[t_s++];
726
offset[slices] = offset[slices-1]; // Extra offset to avoid branch in loop.
728
slice_width = new int[slices];
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;
735
slice_width[slicesW.size()-1] -= skipX;
737
// First pixels are obviously not predicted
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);
750
uint32 pixInSlice = slice_width[0] - 1;
752
uint32 cw = (frame.w - skipX);
753
uint32 x = 1; // Skip first pixels on first line.
755
for (uint32 y = 0;y < (frame.h - skipY);y++) {
756
for (; x < cw ; x++) {
757
p1 += HuffDecode(dctbl1);
758
*dest++ = (ushort16)p1;
760
p2 += HuffDecode(dctbl2);
761
*dest++ = (ushort16)p2;
763
p3 += HuffDecode(dctbl3);
764
*dest++ = (ushort16)p3;
766
p4 += HuffDecode(dctbl4);
767
*dest++ = (ushort16)p4;
769
if (0 == --pixInSlice) { // Next slice
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];
781
for (uint32 i = 0; i < skipX; i++) {
788
p1 = predict[0]; // Predictors for next row
790
p3 = predict[2]; // Predictors for next row
792
predict = dest; // Adjust destination for next prediction
797
} // namespace RawSpeed