2
#include "Cr2Decoder.h"
3
#include "TiffParserHeaderless.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
29
Cr2Decoder::Cr2Decoder(TiffIFD *rootIFD, FileMap* file) :
30
RawDecoder(file), mRootIFD(rootIFD) {
34
Cr2Decoder::~Cr2Decoder(void) {
40
RawImage Cr2Decoder::decodeRawInternal() {
42
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0xc5d8);
45
ThrowRDE("CR2 Decoder: No image data found");
48
TiffIFD* raw = data[0];
49
mRaw = RawImage::create();
51
vector<Cr2Slice> slices;
55
TiffEntry *offsets = raw->getEntry(STRIPOFFSETS);
56
TiffEntry *counts = raw->getEntry(STRIPBYTECOUNTS);
57
// Iterate through all slices
58
for (uint32 s = 0; s < offsets->count; s++) {
60
slice.offset = offsets[0].getInt();
61
slice.count = counts[0].getInt();
63
LJpegPlain l(mFile, mRaw);
64
l.getSOF(&sof, slice.offset, slice.count);
65
slice.w = sof.w * sof.cps;
68
if (slices[0].w != slice.w)
69
ThrowRDE("CR2 Decoder: Slice width does not match.");
71
if (mFile->isValid(slice.offset + slice.count)) // Only decode if size is valid
72
slices.push_back(slice);
75
} catch (TiffParserException) {
76
ThrowRDE("CR2 Decoder: Unsupported format.");
80
ThrowRDE("CR2 Decoder: No Slices found.");
83
mRaw->dim = iPoint2D(slices[0].w, completeH);
85
if (raw->hasEntry((TiffTag)0xc6c5)) {
86
ushort16 ss = raw->getEntry((TiffTag)0xc6c5)->getInt();
98
if (raw->hasEntry(CANONCR2SLICE)) {
99
const ushort16 *ss = raw->getEntry(CANONCR2SLICE)->getShortArray();
100
for (int i = 0; i < ss[0]; i++) {
101
s_width.push_back(ss[1]);
103
s_width.push_back(ss[2]);
105
s_width.push_back(slices[0].w);
109
if (s_width.size() > 15)
110
ThrowRDE("CR2 Decoder: No more than 15 slices supported");
111
_RPT1(0,"Org slices:%d\n", s_width.size());
112
for (uint32 i = 0; i < slices.size(); i++) {
113
Cr2Slice slice = slices[i];
115
LJpegPlain l(mFile, mRaw);
116
l.addSlices(s_width);
117
l.mUseBigtable = true;
118
l.startDecoder(slice.offset, slice.count, 0, offY);
119
} catch (RawDecoderException &e) {
122
// These may just be single slice error - store the error and move on
123
mRaw->setError(e.what());
124
} catch (IOException &e) {
125
// Let's try to ignore this - it might be truncated data, so something might be useful.
126
mRaw->setError(e.what());
131
if (mRaw->subsampling.x > 1 || mRaw->subsampling.y > 1)
137
void Cr2Decoder::checkSupportInternal(CameraMetaData *meta) {
138
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
140
ThrowRDE("CR2 Support check: Model name found");
141
if (!data[0]->hasEntry(MAKE))
142
ThrowRDE("CR2 Support: Make name not found");
143
string make = data[0]->getEntry(MAKE)->getString();
144
string model = data[0]->getEntry(MODEL)->getString();
145
data = mRootIFD->getIFDsWithTag((TiffTag)0xc5d8);
148
ThrowRDE("CR2 Decoder: No image data found");
150
TiffIFD* raw = data[0];
152
if (raw->hasEntry((TiffTag)0xc6c5)) {
153
ushort16 ss = raw->getEntry((TiffTag)0xc6c5)->getInt();
155
this->checkCameraSupported(meta, make, model, "sRaw1");
159
this->checkCameraSupported(meta, make, model, "");
162
void Cr2Decoder::decodeMetaDataInternal(CameraMetaData *meta) {
164
mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
165
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
168
ThrowRDE("CR2 Meta Decoder: Model name not found");
170
string make = data[0]->getEntry(MAKE)->getString();
171
string model = data[0]->getEntry(MODEL)->getString();
174
if (mRaw->subsampling.y == 2 && mRaw->subsampling.x == 2)
177
if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2)
180
if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
181
iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();
183
setMetaData(meta, make, model, mode, iso);
187
int Cr2Decoder::getHue() {
188
if (hints.find("old_sraw_hue") != hints.end())
189
return (mRaw->subsampling.y * mRaw->subsampling.x);
191
uint32 model_id = mRootIFD->getEntryRecursive((TiffTag)0x10)->getInt();
192
if (model_id >= 0x80000281 || model_id == 0x80000218 || (hints.find("force_new_sraw_hue") != hints.end()))
193
return ((mRaw->subsampling.y * mRaw->subsampling.x) - 1) >> 1;
195
return (mRaw->subsampling.y * mRaw->subsampling.x);
199
// Interpolate and convert sRaw data.
200
void Cr2Decoder::sRawInterpolate() {
201
vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0x4001);
203
ThrowRDE("CR2 sRaw: Unable to locate WB info.");
205
const ushort16 *wb_data = data[0]->getEntry((TiffTag)0x4001)->getShortArray();
207
// Offset to sRaw coefficients used to reconstruct uncorrected RGB data.
208
wb_data = &wb_data[4+(126+22)/2];
210
sraw_coeffs[0] = wb_data[0];
211
sraw_coeffs[1] = (wb_data[1] + wb_data[2] + 1) >> 1;
212
sraw_coeffs[2] = wb_data[3];
214
if (hints.find("invert_sraw_wb") != hints.end()) {
215
sraw_coeffs[0] = (int)(1024.0f/((float)sraw_coeffs[0]/1024.0f));
216
sraw_coeffs[2] = (int)(1024.0f/((float)sraw_coeffs[2]/1024.0f));
219
/* Determine sRaw coefficients */
220
bool isOldSraw = hints.find("sraw_40d") != hints.end();
221
bool isNewSraw = hints.find("sraw_new") != hints.end();
223
if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2) {
225
interpolate_422_old(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
227
interpolate_422_new(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
229
interpolate_422(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
230
} else if (mRaw->subsampling.y == 2 && mRaw->subsampling.x == 2) {
232
interpolate_420_new(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
234
interpolate_420(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
236
ThrowRDE("CR2 Decoder: Unknown subsampling");
239
#define YUV_TO_RGB(Y, Cb, Cr) r = sraw_coeffs[0] * ((int)Y + (( 50*(int)Cb + 22929*(int)Cr) >> 12));\
240
g = sraw_coeffs[1] * ((int)Y + ((-5640*(int)Cb - 11751*(int)Cr) >> 12));\
241
b = sraw_coeffs[2] * ((int)Y + ((29040*(int)Cb - 101*(int)Cr) >> 12));\
242
r >>= 8; g >>=8; b >>=8;
244
#define STORE_RGB(X,A,B,C) X[A] = clampbits(r,16); X[B] = clampbits(g,16); X[C] = clampbits(b,16);
246
/* sRaw interpolators - ugly as sin, but does the job in reasonably speed */
248
// Note: Thread safe.
250
void Cr2Decoder::interpolate_422(int w, int h, int start_h , int end_h) {
251
// Last pixel should not be interpolated
256
const int hue = -getHue() + 16384;
257
for (int y = start_h; y < end_h; y++) {
258
c_line = (ushort16*)mRaw->getData(0, y);
261
for (int x = 0; x < w; x++) {
263
int Cb = c_line[off+1] - hue;
264
int Cr = c_line[off+2] - hue;
265
YUV_TO_RGB(Y, Cb, Cr);
266
STORE_RGB(c_line, off, off + 1, off + 2);
270
int Cb2 = (Cb + c_line[off+1+3] - hue) >> 1;
271
int Cr2 = (Cr + c_line[off+2+3] - hue) >> 1;
272
YUV_TO_RGB(Y, Cb2, Cr2);
273
STORE_RGB(c_line, off, off + 1, off + 2);
278
int Cb = c_line[off+1] - hue;
279
int Cr = c_line[off+2] - hue;
280
YUV_TO_RGB(Y, Cb, Cr);
281
STORE_RGB(c_line, off, off + 1, off + 2);
284
YUV_TO_RGB(Y, Cb, Cr);
285
STORE_RGB(c_line, off + 3, off + 4, off + 5);
290
// Note: Not thread safe, since it writes inplace.
291
void Cr2Decoder::interpolate_420(int w, int h, int start_h , int end_h) {
292
// Last pixel should not be interpolated
295
bool atLastLine = FALSE;
311
const int hue = -getHue() + 16384;
313
for (int y = start_h; y < end_h; y++) {
314
c_line = (ushort16*)mRaw->getData(0, y * 2);
315
n_line = (ushort16*)mRaw->getData(0, y * 2 + 1);
316
nn_line = (ushort16*)mRaw->getData(0, y * 2 + 2);
318
for (int x = 0; x < w; x++) {
320
int Cb = c_line[off+1] - hue;
321
int Cr = c_line[off+2] - hue;
322
YUV_TO_RGB(Y, Cb, Cr);
323
STORE_RGB(c_line, off, off + 1, off + 2);
326
int Cb2 = (Cb + c_line[off+1+6] - hue) >> 1;
327
int Cr2 = (Cr + c_line[off+2+6] - hue) >> 1;
328
YUV_TO_RGB(Y, Cb2, Cr2);
329
STORE_RGB(c_line, off + 3, off + 4, off + 5);
333
int Cb3 = (Cb + nn_line[off+1] - hue) >> 1;
334
int Cr3 = (Cr + nn_line[off+2] - hue) >> 1;
335
YUV_TO_RGB(Y, Cb3, Cr3);
336
STORE_RGB(n_line, off, off + 1, off + 2);
339
Cb = (Cb + Cb2 + Cb3 + nn_line[off+1+6] - hue) >> 2; //Left + Above + Right +Below
340
Cr = (Cr + Cr2 + Cr3 + nn_line[off+2+6] - hue) >> 2;
341
YUV_TO_RGB(Y, Cb, Cr);
342
STORE_RGB(n_line, off + 3, off + 4, off + 5);
346
int Cb = c_line[off+1] - hue;
347
int Cr = c_line[off+2] - hue;
348
YUV_TO_RGB(Y, Cb, Cr);
349
STORE_RGB(c_line, off, off + 1, off + 2);
352
YUV_TO_RGB(Y, Cb, Cr);
353
STORE_RGB(c_line, off + 3, off + 4, off + 5);
357
Cb = (Cb + nn_line[off+1] - hue) >> 1;
358
Cr = (Cr + nn_line[off+2] - hue) >> 1;
359
YUV_TO_RGB(Y, Cb, Cr);
360
STORE_RGB(n_line, off, off + 1, off + 2);
363
YUV_TO_RGB(Y, Cb, Cr);
364
STORE_RGB(n_line, off + 3, off + 4, off + 5);
368
c_line = (ushort16*)mRaw->getData(0, end_h * 2);
369
n_line = (ushort16*)mRaw->getData(0, end_h * 2 + 1);
373
for (int x = 0; x < w; x++) {
375
int Cb = c_line[off+1] - hue;
376
int Cr = c_line[off+2] - hue;
377
YUV_TO_RGB(Y, Cb, Cr);
378
STORE_RGB(c_line, off, off + 1, off + 2);
381
YUV_TO_RGB(Y, Cb, Cr);
382
STORE_RGB(c_line, off + 3, off + 4, off + 5);
386
YUV_TO_RGB(Y, Cb, Cr);
387
STORE_RGB(n_line, off, off + 1, off + 2);
390
YUV_TO_RGB(Y, Cb, Cr);
391
STORE_RGB(n_line, off + 3, off + 4, off + 5);
399
#define YUV_TO_RGB(Y, Cb, Cr) r = sraw_coeffs[0] * (Y + Cr -512 );\
400
g = sraw_coeffs[1] * (Y + ((-778*Cb - (Cr << 11)) >> 12) - 512);\
401
b = sraw_coeffs[2] * (Y + (Cb - 512));\
402
r >>= 8; g >>=8; b >>=8;
405
// Note: Thread safe.
407
void Cr2Decoder::interpolate_422_old(int w, int h, int start_h , int end_h) {
408
// Last pixel should not be interpolated
413
const int hue = -getHue() + 16384;
415
for (int y = start_h; y < end_h; y++) {
416
c_line = (ushort16*)mRaw->getData(0, y);
419
for (int x = 0; x < w; x++) {
421
int Cb = c_line[off+1] - hue;
422
int Cr = c_line[off+2] - hue;
423
YUV_TO_RGB(Y, Cb, Cr);
424
STORE_RGB(c_line, off, off + 1, off + 2);
428
int Cb2 = (Cb + c_line[off+1+3] - hue) >> 1;
429
int Cr2 = (Cr + c_line[off+2+3] - hue) >> 1;
430
YUV_TO_RGB(Y, Cb2, Cr2);
431
STORE_RGB(c_line, off, off + 1, off + 2);
436
int Cb = c_line[off+1] - 16384;
437
int Cr = c_line[off+2] - 16384;
438
YUV_TO_RGB(Y, Cb, Cr);
439
STORE_RGB(c_line, off, off + 1, off + 2);
442
YUV_TO_RGB(Y, Cb, Cr);
443
STORE_RGB(c_line, off + 3, off + 4, off + 5);
447
/* Algorithm found in EOS 5d Mk III */
451
#define YUV_TO_RGB(Y, Cb, Cr) r = sraw_coeffs[0] * (Y + Cr);\
452
g = sraw_coeffs[1] * (Y + ((-778*Cb - (Cr << 11)) >> 12) );\
453
b = sraw_coeffs[2] * (Y + Cb);\
454
r >>= 8; g >>=8; b >>=8;
456
void Cr2Decoder::interpolate_422_new(int w, int h, int start_h , int end_h) {
457
// Last pixel should not be interpolated
462
const int hue = -getHue() + 16384;
464
for (int y = start_h; y < end_h; y++) {
465
c_line = (ushort16*)mRaw->getData(0, y);
468
for (int x = 0; x < w; x++) {
470
int Cb = c_line[off+1] - hue;
471
int Cr = c_line[off+2] - hue;
472
YUV_TO_RGB(Y, Cb, Cr);
473
STORE_RGB(c_line, off, off + 1, off + 2);
477
int Cb2 = (Cb + c_line[off+1+3] - hue) >> 1;
478
int Cr2 = (Cr + c_line[off+2+3] - hue) >> 1;
479
YUV_TO_RGB(Y, Cb2, Cr2);
480
STORE_RGB(c_line, off, off + 1, off + 2);
485
int Cb = c_line[off+1] - 16384;
486
int Cr = c_line[off+2] - 16384;
487
YUV_TO_RGB(Y, Cb, Cr);
488
STORE_RGB(c_line, off, off + 1, off + 2);
491
YUV_TO_RGB(Y, Cb, Cr);
492
STORE_RGB(c_line, off + 3, off + 4, off + 5);
497
// Note: Not thread safe, since it writes inplace.
498
void Cr2Decoder::interpolate_420_new(int w, int h, int start_h , int end_h) {
499
// Last pixel should not be interpolated
502
bool atLastLine = FALSE;
515
const int hue = -getHue() + 16384;
520
for (int y = start_h; y < end_h; y++) {
521
c_line = (ushort16*)mRaw->getData(0, y * 2);
522
n_line = (ushort16*)mRaw->getData(0, y * 2 + 1);
523
nn_line = (ushort16*)mRaw->getData(0, y * 2 + 2);
525
for (int x = 0; x < w; x++) {
527
int Cb = c_line[off+1] - hue;
528
int Cr = c_line[off+2] - hue;
529
YUV_TO_RGB(Y, Cb, Cr);
530
STORE_RGB(c_line, off, off + 1, off + 2);
533
int Cb2 = (Cb + c_line[off+1+6] - hue) >> 1;
534
int Cr2 = (Cr + c_line[off+2+6] - hue) >> 1;
535
YUV_TO_RGB(Y, Cb2, Cr2);
536
STORE_RGB(c_line, off + 3, off + 4, off + 5);
540
int Cb3 = (Cb + nn_line[off+1] - hue) >> 1;
541
int Cr3 = (Cr + nn_line[off+2] - hue) >> 1;
542
YUV_TO_RGB(Y, Cb3, Cr3);
543
STORE_RGB(n_line, off, off + 1, off + 2);
546
Cb = (Cb + Cb2 + Cb3 + nn_line[off+1+6] - hue) >> 2; //Left + Above + Right +Below
547
Cr = (Cr + Cr2 + Cr3 + nn_line[off+2+6] - hue) >> 2;
548
YUV_TO_RGB(Y, Cb, Cr);
549
STORE_RGB(n_line, off + 3, off + 4, off + 5);
553
int Cb = c_line[off+1] - hue;
554
int Cr = c_line[off+2] - hue;
555
YUV_TO_RGB(Y, Cb, Cr);
556
STORE_RGB(c_line, off, off + 1, off + 2);
559
YUV_TO_RGB(Y, Cb, Cr);
560
STORE_RGB(c_line, off + 3, off + 4, off + 5);
564
Cb = (Cb + nn_line[off+1] - hue) >> 1;
565
Cr = (Cr + nn_line[off+2] - hue) >> 1;
566
YUV_TO_RGB(Y, Cb, Cr);
567
STORE_RGB(n_line, off, off + 1, off + 2);
570
YUV_TO_RGB(Y, Cb, Cr);
571
STORE_RGB(n_line, off + 3, off + 4, off + 5);
575
c_line = (ushort16*)mRaw->getData(0, end_h * 2);
576
n_line = (ushort16*)mRaw->getData(0, end_h * 2 + 1);
580
for (int x = 0; x < w; x++) {
582
int Cb = c_line[off+1] - hue;
583
int Cr = c_line[off+2] - hue;
584
YUV_TO_RGB(Y, Cb, Cr);
585
STORE_RGB(c_line, off, off + 1, off + 2);
588
YUV_TO_RGB(Y, Cb, Cr);
589
STORE_RGB(c_line, off + 3, off + 4, off + 5);
593
YUV_TO_RGB(Y, Cb, Cr);
594
STORE_RGB(n_line, off, off + 1, off + 2);
597
YUV_TO_RGB(Y, Cb, Cr);
598
STORE_RGB(n_line, off + 3, off + 4, off + 5);
604
} // namespace RawSpeed