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

« back to all changes in this revision

Viewing changes to extra/libkdcraw/libraw/RawSpeed/Cr2Decoder.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 "Cr2Decoder.h"
 
3
#include "TiffParserHeaderless.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
namespace RawSpeed {
 
28
 
 
29
Cr2Decoder::Cr2Decoder(TiffIFD *rootIFD, FileMap* file) :
 
30
    RawDecoder(file), mRootIFD(rootIFD) {
 
31
  decoderVersion = 2;
 
32
}
 
33
 
 
34
Cr2Decoder::~Cr2Decoder(void) {
 
35
  if (mRootIFD)
 
36
    delete mRootIFD;
 
37
  mRootIFD = NULL;
 
38
}
 
39
 
 
40
RawImage Cr2Decoder::decodeRawInternal() {
 
41
 
 
42
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0xc5d8);
 
43
 
 
44
  if (data.empty())
 
45
    ThrowRDE("CR2 Decoder: No image data found");
 
46
 
 
47
 
 
48
  TiffIFD* raw = data[0];
 
49
  mRaw = RawImage::create();
 
50
  mRaw->isCFA = true;
 
51
  vector<Cr2Slice> slices;
 
52
  int completeH = 0;
 
53
 
 
54
  try {
 
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++) {
 
59
      Cr2Slice slice;
 
60
      slice.offset = offsets[0].getInt();
 
61
      slice.count = counts[0].getInt();
 
62
      SOFInfo sof;
 
63
      LJpegPlain l(mFile, mRaw);
 
64
      l.getSOF(&sof, slice.offset, slice.count);
 
65
      slice.w = sof.w * sof.cps;
 
66
      slice.h = sof.h;
 
67
      if (!slices.empty())
 
68
        if (slices[0].w != slice.w)
 
69
          ThrowRDE("CR2 Decoder: Slice width does not match.");
 
70
 
 
71
      if (mFile->isValid(slice.offset + slice.count)) // Only decode if size is valid
 
72
        slices.push_back(slice);
 
73
      completeH += slice.h;
 
74
    }
 
75
  } catch (TiffParserException) {
 
76
    ThrowRDE("CR2 Decoder: Unsupported format.");
 
77
  }
 
78
 
 
79
  if (slices.empty()) {
 
80
    ThrowRDE("CR2 Decoder: No Slices found.");
 
81
  }
 
82
 
 
83
  mRaw->dim = iPoint2D(slices[0].w, completeH);
 
84
 
 
85
  if (raw->hasEntry((TiffTag)0xc6c5)) {
 
86
    ushort16 ss = raw->getEntry((TiffTag)0xc6c5)->getInt();
 
87
    // sRaw
 
88
    if (ss == 4) {
 
89
      mRaw->dim.x /= 3;
 
90
      mRaw->setCpp(3);
 
91
      mRaw->isCFA = false;
 
92
    }
 
93
  }
 
94
 
 
95
  mRaw->createData();
 
96
 
 
97
  vector<int> s_width;
 
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]);
 
102
    }
 
103
    s_width.push_back(ss[2]);
 
104
  } else {
 
105
    s_width.push_back(slices[0].w);
 
106
  }
 
107
  uint32 offY = 0;
 
108
 
 
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];
 
114
    try {
 
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) {
 
120
      if (i == 0)
 
121
        throw;
 
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());
 
127
    }
 
128
    offY += slice.w;
 
129
  }
 
130
 
 
131
  if (mRaw->subsampling.x > 1 || mRaw->subsampling.y > 1)
 
132
    sRawInterpolate();
 
133
 
 
134
  return mRaw;
 
135
}
 
136
 
 
137
void Cr2Decoder::checkSupportInternal(CameraMetaData *meta) {
 
138
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
 
139
  if (data.empty())
 
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);
 
146
 
 
147
  if (data.empty())
 
148
    ThrowRDE("CR2 Decoder: No image data found");
 
149
 
 
150
  TiffIFD* raw = data[0];
 
151
 
 
152
  if (raw->hasEntry((TiffTag)0xc6c5)) {
 
153
    ushort16 ss = raw->getEntry((TiffTag)0xc6c5)->getInt();
 
154
    if (ss == 4) {
 
155
      this->checkCameraSupported(meta, make, model, "sRaw1");
 
156
      return;
 
157
    }
 
158
  }
 
159
  this->checkCameraSupported(meta, make, model, "");
 
160
}
 
161
 
 
162
void Cr2Decoder::decodeMetaDataInternal(CameraMetaData *meta) {
 
163
  int iso = 0;
 
164
  mRaw->cfa.setCFA(CFA_RED, CFA_GREEN, CFA_GREEN2, CFA_BLUE);
 
165
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag(MODEL);
 
166
 
 
167
  if (data.empty())
 
168
    ThrowRDE("CR2 Meta Decoder: Model name not found");
 
169
 
 
170
  string make = data[0]->getEntry(MAKE)->getString();
 
171
  string model = data[0]->getEntry(MODEL)->getString();
 
172
  string mode = "";
 
173
 
 
174
  if (mRaw->subsampling.y == 2 && mRaw->subsampling.x == 2)
 
175
    mode = "sRaw1";
 
176
 
 
177
  if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2)
 
178
    mode = "sRaw2";
 
179
 
 
180
  if (mRootIFD->hasEntryRecursive(ISOSPEEDRATINGS))
 
181
    iso = mRootIFD->getEntryRecursive(ISOSPEEDRATINGS)->getInt();
 
182
 
 
183
  setMetaData(meta, make, model, mode, iso);
 
184
 
 
185
}
 
186
 
 
187
int Cr2Decoder::getHue() {
 
188
  if (hints.find("old_sraw_hue") != hints.end())
 
189
    return (mRaw->subsampling.y * mRaw->subsampling.x);
 
190
 
 
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;
 
194
 
 
195
  return (mRaw->subsampling.y * mRaw->subsampling.x);
 
196
    
 
197
}
 
198
 
 
199
// Interpolate and convert sRaw data.
 
200
void Cr2Decoder::sRawInterpolate() {
 
201
  vector<TiffIFD*> data = mRootIFD->getIFDsWithTag((TiffTag)0x4001);
 
202
  if (data.empty())
 
203
    ThrowRDE("CR2 sRaw: Unable to locate WB info.");
 
204
 
 
205
  const ushort16 *wb_data = data[0]->getEntry((TiffTag)0x4001)->getShortArray();
 
206
 
 
207
  // Offset to sRaw coefficients used to reconstruct uncorrected RGB data.
 
208
  wb_data = &wb_data[4+(126+22)/2];
 
209
 
 
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];
 
213
 
 
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));
 
217
  }
 
218
 
 
219
  /* Determine sRaw coefficients */
 
220
  bool isOldSraw = hints.find("sraw_40d") != hints.end();
 
221
  bool isNewSraw = hints.find("sraw_new") != hints.end();
 
222
 
 
223
  if (mRaw->subsampling.y == 1 && mRaw->subsampling.x == 2) {
 
224
    if (isOldSraw)
 
225
      interpolate_422_old(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
 
226
    else if (isNewSraw)
 
227
      interpolate_422_new(mRaw->dim.x / 2, mRaw->dim.y , 0, mRaw->dim.y);
 
228
    else
 
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) {
 
231
    if (isNewSraw)
 
232
      interpolate_420_new(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
 
233
    else
 
234
      interpolate_420(mRaw->dim.x / 2, mRaw->dim.y / 2 , 0 , mRaw->dim.y / 2);
 
235
  } else
 
236
    ThrowRDE("CR2 Decoder: Unknown subsampling");
 
237
}
 
238
 
 
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;
 
243
 
 
244
#define STORE_RGB(X,A,B,C) X[A] = clampbits(r,16); X[B] = clampbits(g,16); X[C] = clampbits(b,16);
 
245
 
 
246
/* sRaw interpolators - ugly as sin, but does the job in reasonably speed */
 
247
 
 
248
// Note: Thread safe.
 
249
 
 
250
void Cr2Decoder::interpolate_422(int w, int h, int start_h , int end_h) {
 
251
  // Last pixel should not be interpolated
 
252
  w--;
 
253
 
 
254
  // Current line
 
255
  ushort16* c_line;
 
256
  const int hue = -getHue() + 16384;
 
257
  for (int y = start_h; y < end_h; y++) {
 
258
    c_line = (ushort16*)mRaw->getData(0, y);
 
259
    int r, g, b;
 
260
    int off = 0;
 
261
    for (int x = 0; x < w; x++) {
 
262
      int Y = c_line[off];
 
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);
 
267
      off += 3;
 
268
 
 
269
      Y = c_line[off];
 
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);
 
274
      off += 3;
 
275
    }
 
276
    // Last two pixels
 
277
    int Y = c_line[off];
 
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);
 
282
 
 
283
    Y = c_line[off+3];
 
284
    YUV_TO_RGB(Y, Cb, Cr);
 
285
    STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
286
  }
 
287
}
 
288
 
 
289
 
 
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
 
293
  w--;
 
294
 
 
295
  bool atLastLine = FALSE;
 
296
 
 
297
  if (end_h == h) {
 
298
    end_h--;
 
299
    atLastLine = TRUE;
 
300
  }
 
301
 
 
302
  // Current line
 
303
  ushort16* c_line;
 
304
  // Next line
 
305
  ushort16* n_line;
 
306
  // Next line again
 
307
  ushort16* nn_line;
 
308
 
 
309
  int off;
 
310
  int r, g, b;
 
311
  const int hue = -getHue() + 16384;
 
312
 
 
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);
 
317
    off = 0;
 
318
    for (int x = 0; x < w; x++) {
 
319
      int Y = c_line[off];
 
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);
 
324
 
 
325
      Y = c_line[off+3];
 
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);
 
330
 
 
331
      // Next line
 
332
      Y = n_line[off];
 
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);
 
337
 
 
338
      Y = n_line[off+3];
 
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);
 
343
      off += 6;
 
344
    }
 
345
    int Y = c_line[off];
 
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);
 
350
 
 
351
    Y = c_line[off+3];
 
352
    YUV_TO_RGB(Y, Cb, Cr);
 
353
    STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
354
 
 
355
    // Next line
 
356
    Y = n_line[off];
 
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);
 
361
 
 
362
    Y = n_line[off+3];
 
363
    YUV_TO_RGB(Y, Cb, Cr);
 
364
    STORE_RGB(n_line, off + 3, off + 4, off + 5);
 
365
  }
 
366
 
 
367
  if (atLastLine) {
 
368
    c_line = (ushort16*)mRaw->getData(0, end_h * 2);
 
369
    n_line = (ushort16*)mRaw->getData(0, end_h * 2 + 1);
 
370
    off = 0;
 
371
 
 
372
    // Last line
 
373
    for (int x = 0; x < w; x++) {
 
374
      int Y = c_line[off];
 
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);
 
379
 
 
380
      Y = c_line[off+3];
 
381
      YUV_TO_RGB(Y, Cb, Cr);
 
382
      STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
383
 
 
384
      // Next line
 
385
      Y = n_line[off];
 
386
      YUV_TO_RGB(Y, Cb, Cr);
 
387
      STORE_RGB(n_line, off, off + 1, off + 2);
 
388
 
 
389
      Y = n_line[off+3];
 
390
      YUV_TO_RGB(Y, Cb, Cr);
 
391
      STORE_RGB(n_line, off + 3, off + 4, off + 5);
 
392
      off += 6;
 
393
    }
 
394
  }
 
395
}
 
396
 
 
397
#undef YUV_TO_RGB
 
398
 
 
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;
 
403
 
 
404
 
 
405
// Note: Thread safe.
 
406
 
 
407
void Cr2Decoder::interpolate_422_old(int w, int h, int start_h , int end_h) {
 
408
  // Last pixel should not be interpolated
 
409
  w--;
 
410
 
 
411
  // Current line
 
412
  ushort16* c_line;
 
413
  const int hue = -getHue() + 16384;
 
414
 
 
415
  for (int y = start_h; y < end_h; y++) {
 
416
    c_line = (ushort16*)mRaw->getData(0, y);
 
417
    int r, g, b;
 
418
    int off = 0;
 
419
    for (int x = 0; x < w; x++) {
 
420
      int Y = c_line[off];
 
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);
 
425
      off += 3;
 
426
 
 
427
      Y = c_line[off];
 
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);
 
432
      off += 3;
 
433
    }
 
434
    // Last two pixels
 
435
    int Y = c_line[off];
 
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);
 
440
 
 
441
    Y = c_line[off+3];
 
442
    YUV_TO_RGB(Y, Cb, Cr);
 
443
    STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
444
  }
 
445
}
 
446
 
 
447
/* Algorithm found in EOS 5d Mk III */
 
448
 
 
449
#undef YUV_TO_RGB
 
450
 
 
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;
 
455
 
 
456
void Cr2Decoder::interpolate_422_new(int w, int h, int start_h , int end_h) {
 
457
  // Last pixel should not be interpolated
 
458
  w--;
 
459
 
 
460
  // Current line
 
461
  ushort16* c_line;
 
462
  const int hue = -getHue() + 16384;
 
463
 
 
464
  for (int y = start_h; y < end_h; y++) {
 
465
    c_line = (ushort16*)mRaw->getData(0, y);
 
466
    int r, g, b;
 
467
    int off = 0;
 
468
    for (int x = 0; x < w; x++) {
 
469
      int Y = c_line[off];
 
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);
 
474
      off += 3;
 
475
 
 
476
      Y = c_line[off];
 
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);
 
481
      off += 3;
 
482
    }
 
483
    // Last two pixels
 
484
    int Y = c_line[off];
 
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);
 
489
 
 
490
    Y = c_line[off+3];
 
491
    YUV_TO_RGB(Y, Cb, Cr);
 
492
    STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
493
  }
 
494
}
 
495
 
 
496
 
 
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
 
500
  w--;
 
501
 
 
502
  bool atLastLine = FALSE;
 
503
 
 
504
  if (end_h == h) {
 
505
    end_h--;
 
506
    atLastLine = TRUE;
 
507
  }
 
508
 
 
509
  // Current line
 
510
  ushort16* c_line;
 
511
  // Next line
 
512
  ushort16* n_line;
 
513
  // Next line again
 
514
  ushort16* nn_line;
 
515
  const int hue = -getHue() + 16384;
 
516
 
 
517
  int off;
 
518
  int r, g, b;
 
519
 
 
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);
 
524
    off = 0;
 
525
    for (int x = 0; x < w; x++) {
 
526
      int Y = c_line[off];
 
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);
 
531
 
 
532
      Y = c_line[off+3];
 
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);
 
537
 
 
538
      // Next line
 
539
      Y = n_line[off];
 
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);
 
544
 
 
545
      Y = n_line[off+3];
 
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);
 
550
      off += 6;
 
551
    }
 
552
    int Y = c_line[off];
 
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);
 
557
 
 
558
    Y = c_line[off+3];
 
559
    YUV_TO_RGB(Y, Cb, Cr);
 
560
    STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
561
 
 
562
    // Next line
 
563
    Y = n_line[off];
 
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);
 
568
 
 
569
    Y = n_line[off+3];
 
570
    YUV_TO_RGB(Y, Cb, Cr);
 
571
    STORE_RGB(n_line, off + 3, off + 4, off + 5);
 
572
  }
 
573
 
 
574
  if (atLastLine) {
 
575
    c_line = (ushort16*)mRaw->getData(0, end_h * 2);
 
576
    n_line = (ushort16*)mRaw->getData(0, end_h * 2 + 1);
 
577
    off = 0;
 
578
 
 
579
    // Last line
 
580
    for (int x = 0; x < w; x++) {
 
581
      int Y = c_line[off];
 
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);
 
586
 
 
587
      Y = c_line[off+3];
 
588
      YUV_TO_RGB(Y, Cb, Cr);
 
589
      STORE_RGB(c_line, off + 3, off + 4, off + 5);
 
590
 
 
591
      // Next line
 
592
      Y = n_line[off];
 
593
      YUV_TO_RGB(Y, Cb, Cr);
 
594
      STORE_RGB(n_line, off, off + 1, off + 2);
 
595
 
 
596
      Y = n_line[off+3];
 
597
      YUV_TO_RGB(Y, Cb, Cr);
 
598
      STORE_RGB(n_line, off + 3, off + 4, off + 5);
 
599
      off += 6;
 
600
    }
 
601
  }
 
602
}
 
603
 
 
604
} // namespace RawSpeed