libopenraw
rawdata.cpp
1 /*
2  * libopenraw - rawdata.cpp
3  *
4  * Copyright (C) 2007-2016 Hubert Figuiere
5  * Copyright (C) 2008 Novell, Inc.
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <stddef.h>
23 #include <string.h>
24 #include <algorithm>
25 #include <cassert>
26 #include <cstdint>
27 #include <vector>
28 
29 #include <libopenraw/consts.h>
30 #include <libopenraw/debug.h>
31 
32 #include "bitmapdata.hpp"
33 #include "rawdata.hpp"
34 #include "cfapattern.hpp"
35 #include "rawfile.hpp"
36 #include "render/bimedian_demosaic.hpp"
37 #include "render/grayscale.hpp"
38 #include "trace.hpp"
39 
40 namespace OpenRaw {
41 
42 static const int MAX_MATRIX_SIZE = 12;
43 
45 public:
46  RawData *self;
47  uint16_t blackLevel, whiteLevel;
48  ExifPhotometricInterpretation photometricInterpretation;
49  const CfaPattern* cfa_pattern; // IMMUTABLE
50  uint32_t compression;
51  uint8_t *pos;
52  size_t offset;
53  size_t row_offset;
54  uint8_t slice;
55  uint32_t sliceWidth;
56  uint32_t sliceOffset;
58  std::vector<uint16_t> slices;
60  double colourMatrix[MAX_MATRIX_SIZE];
61  uint32_t colourMatrixCount;
62  double colourMatrix2[MAX_MATRIX_SIZE];
63  uint32_t colourMatrix2Count;
64 
65  Private(RawData *_self)
66  : self(_self),
67  blackLevel(0), whiteLevel(0),
68  photometricInterpretation(EV_PI_CFA),
69  cfa_pattern(CfaPattern::twoByTwoPattern(OR_CFA_PATTERN_NONE)),
70  compression(0),
71  pos(NULL), offset(0),
72  row_offset(0),
73  slice(0), sliceWidth(0),
74  sliceOffset(0), slices(),
75  colourMatrixCount(0),
76  colourMatrix2Count(0)
77  {
78  memset(colourMatrix, 0, sizeof(colourMatrix));
79  memset(colourMatrix2, 0, sizeof(colourMatrix2));
80  }
81  void advance(size_t s);
82  void nextSlice();
83  void nextRow();
84 private:
85  Private(const Private &);
86  Private & operator=(const Private &);
87 };
88 
89 
90 RawData *
91 RawData::getAndExtractRawData(const char* filename, uint32_t options,
92  or_error & err)
93 {
94  err = OR_ERROR_NONE;
95  RawData *rawdata = NULL;
96 
97  RawFile *file = RawFile::newRawFile(filename);
98  if (file) {
99  rawdata = new RawData();
100  err = file->getRawData(*rawdata, options);
101  delete file;
102  }
103  else {
104  err = OR_ERROR_CANT_OPEN; // file error
105  }
106  return rawdata;
107 }
108 
109 
110 RawData::RawData()
111  : BitmapData(),
112  d(new RawData::Private(this))
113 {
114 
115 }
116 
117 
118 RawData::~RawData()
119 {
120  delete d;
121 }
122 
123 // rendering
124 
125 ::or_error RawData::getRenderedImage(BitmapData & bitmapdata, uint32_t /*options*/)
126 {
127  uint32_t _x, _y, out_x, out_y;
128  uint16_t *src;
129 
130  if(dataType() != OR_DATA_TYPE_RAW) {
131  LOGDBG1("wrong data type\n");
132  return OR_ERROR_INVALID_FORMAT;
133  }
134  if(d->photometricInterpretation != EV_PI_CFA &&
135  d->photometricInterpretation != EV_PI_LINEAR_RAW) {
136  LOGDBG1("only CFA or LinearRaw are supported.\n");
137  return OR_ERROR_INVALID_FORMAT;
138  }
139 
140  or_cfa_pattern pattern;
141  pattern = cfaPattern()->patternType();
142  _x = width();
143  _y = height();
144 
145  /*
146  rawdata.linearize();
147  rawdata.subtractBlack();
148  rawdata.rescale();
149  rawdata.clip();
150  */
151  src = (uint16_t*)data();
152 
153  or_error err = OR_ERROR_NONE;
154 
155  if (d->photometricInterpretation == EV_PI_CFA) {
156  /* figure out how the demosaic can be plugged for a different
157  * algorithm */
158  bitmapdata.setDataType(OR_DATA_TYPE_PIXMAP_8RGB);
159  uint8_t *dst = (uint8_t *)bitmapdata.allocData(sizeof(uint8_t) * 3 * _x * _y);
160  err = bimedian_demosaic(src, _x, _y, pattern, dst, out_x, out_y);
161  bitmapdata.setDimensions(out_x, out_y);
162 
163  // correct colour using the colour matrices
164  // TODO
165  }
166  else {
167  bitmapdata.setDataType(OR_DATA_TYPE_PIXMAP_16RGB);
168  uint16_t *dst = (uint16_t *)bitmapdata.allocData(sizeof(uint16_t)
169  * 3 * _x * _y);
170 
171  err = grayscale_to_rgb(src, _x, _y, dst);
172  bitmapdata.setDimensions(_x, _y);
173  }
174 
175  return err;
176 }
177 
178 // other
179 
180 uint16_t RawData::blackLevel() const
181 {
182  return d->blackLevel;
183 }
184 
185 uint16_t RawData::whiteLevel() const
186 {
187  return d->whiteLevel;
188 }
189 
190 void RawData::setBlackLevel(uint16_t m)
191 {
192  d->blackLevel = m;
193 }
194 
195 void RawData::setWhiteLevel(uint16_t m)
196 {
197  d->whiteLevel = m;
198 }
199 
200 void RawData::setPhotometricInterpretation(ExifPhotometricInterpretation pi)
201 {
202  d->photometricInterpretation = pi;
203 }
204 
205 ExifPhotometricInterpretation RawData::getPhotometricInterpretation() const
206 {
207  return d->photometricInterpretation;
208 }
209 
210 
211 const double* RawData::getColourMatrix1(uint32_t & matrixSize) const
212 {
213  matrixSize = d->colourMatrixCount;
214  return d->colourMatrix;
215 }
216 
217 void RawData::setColourMatrix1(const double* matrix, uint32_t matrixSize)
218 {
219  if(matrixSize > MAX_MATRIX_SIZE) {
220  matrixSize = MAX_MATRIX_SIZE;
221  }
222  for(uint32_t i = 0; i < matrixSize; i++) {
223  d->colourMatrix[i] = matrix[i];
224  }
225  d->colourMatrixCount = matrixSize;
226 }
227 
228 const double* RawData::getColourMatrix2(uint32_t & matrixSize) const
229 {
230  matrixSize = d->colourMatrix2Count;
231  return d->colourMatrix2;
232 }
233 
234 void RawData::setColourMatrix2(const double* matrix, uint32_t matrixSize)
235 {
236  if(matrixSize > MAX_MATRIX_SIZE) {
237  matrixSize = MAX_MATRIX_SIZE;
238  }
239  for(uint32_t i = 0; i < matrixSize; i++) {
240  d->colourMatrix2[i] = matrix[i];
241  }
242  d->colourMatrix2Count = matrixSize;
243 }
244 
245 void RawData::swap(RawData & with)
246 {
247  BitmapData::swap(with);
248  std::swap(this->d, with.d);
249 }
250 
251 void * RawData::allocData(const size_t s)
252 {
253  void * p = BitmapData::allocData(s);
254  d->pos = (uint8_t*)p;
255  d->offset = 0;
256  return p;
257 }
258 
259 
260 void RawData::setDimensions(uint32_t _x, uint32_t _y)
261 {
263  if(d->slices.size()) {
264  d->sliceWidth = d->slices[0];
265  }
266  else {
267  d->sliceWidth = _x;
268  }
269 }
270 
271 void RawData::setSlices(const std::vector<uint16_t> & slices)
272 {
273  d->slices = slices;
274  if(slices.size()) {
275  d->sliceWidth = slices[0];
276  }
277  else {
278  d->sliceWidth = width();
279  }
280 }
281 
282 void RawData::setCfaPatternType(or_cfa_pattern t)
283 {
284  d->cfa_pattern = CfaPattern::twoByTwoPattern(t);
285 }
286 
288 {
289  return d->cfa_pattern;
290 }
291 
292 void RawData::setCfaPattern(const CfaPattern* pattern)
293 {
294  d->cfa_pattern = pattern;
295 }
296 
297 void RawData::setCompression(uint32_t t)
298 {
299  d->compression = t;
300 }
301 
302 uint32_t RawData::compression() const
303 {
304  return d->compression;
305 }
306 
307 #if 0
308 RawData &RawData::append(uint8_t c)
309 {
310  assert(d->pos);
311  assert(d->offset < d->data_size);
312  *(d->pos) = c;
313  advance(sizeof(c));
314  return *this;
315 }
316 #endif
317 
319 {
320  assert(d->pos);
321  assert(d->offset < size());
322  *(d->pos) = c & 0xff;
323  *(d->pos + 1) = (c >> 8) & 0xff;
324  d->advance(sizeof(c));
325  return *this;
326 }
327 
329 {
330  d->nextRow();
331 }
332 
333 void RawData::Private::nextRow()
334 {
335  uint32_t w = self->width() * 2;
336  uint32_t row = offset / w;
337  row++;
338  if(row == self->height())
339  {
340  // on the last
341  nextSlice();
342  row = 0;
343  }
344  offset = row * w + sliceOffset * 2;
345  pos = (uint8_t*)(self->data()) + offset;
346  row_offset = offset;
347 }
348 
349 void RawData::Private::nextSlice()
350 {
351  if(slices.size() > slice) {
352  sliceOffset += slices[slice];
353  slice++;
354  }
355  if(slices.size() > slice) {
356  sliceWidth = slices[slice];
357  }
358  else {
359  sliceWidth = 0;
360  }
361 }
362 
363 void RawData::Private::advance(size_t s)
364 {
365  if(offset + s - row_offset >= sliceWidth * 2) {
366  nextRow();
367  }
368  else {
369  pos += s;
370  offset += s;
371  }
372 }
373 
374 }
375 /*
376  Local Variables:
377  mode:c++
378  c-file-style:"stroustrup"
379  c-file-offsets:((innamespace . 0))
380  indent-tabs-mode:nil
381  fill-column:80
382  End:
383 */
384 
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
Definition: arwfile.cpp:30
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Definition: rawdata.cpp:125
double colourMatrix[MAX_MATRIX_SIZE]
Definition: rawdata.cpp:60
const double * getColourMatrix2(uint32_t &size) const
Definition: rawdata.cpp:228
::or_error getRawData(RawData &rawdata, uint32_t options)
Definition: rawfile.cpp:448
RawData & append(uint16_t c)
Definition: rawdata.cpp:318
size_t size() const
Definition: bitmapdata.cpp:129
void swap(RawData &with)
Definition: rawdata.cpp:245
virtual void setDimensions(uint32_t x, uint32_t y)
Definition: bitmapdata.cpp:169
static const CfaPattern * twoByTwoPattern(::or_cfa_pattern)
Definition: cfapattern.cpp:77
void swap(BitmapData &with)
Definition: bitmapdata.cpp:90
::or_cfa_pattern patternType() const
Definition: cfapattern.cpp:186
const CfaPattern * cfaPattern() const
Definition: rawdata.cpp:287
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
DataType dataType() const
Definition: bitmapdata.cpp:95
virtual void setDimensions(uint32_t x, uint32_t y) override
Definition: rawdata.cpp:260
static RawFile * newRawFile(const char *_filename, Type _typeHint=OR_RAWFILE_TYPE_UNKNOWN)
Definition: rawfile.cpp:164
const double * getColourMatrix1(uint32_t &size) const
Definition: rawdata.cpp:211