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
40namespace OpenRaw {
41
42static const int MAX_MATRIX_SIZE = 12;
43
45public:
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();
84private:
85 Private(const Private &);
86 Private & operator=(const Private &);
87};
88
89
90RawData *
91RawData::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
110RawData::RawData()
111 : BitmapData(),
112 d(new RawData::Private(this))
113{
114
115}
116
117
118RawData::~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
180uint16_t RawData::blackLevel() const
181{
182 return d->blackLevel;
183}
184
185uint16_t RawData::whiteLevel() const
186{
187 return d->whiteLevel;
188}
189
190void RawData::setBlackLevel(uint16_t m)
191{
192 d->blackLevel = m;
193}
194
195void RawData::setWhiteLevel(uint16_t m)
196{
197 d->whiteLevel = m;
198}
199
200void RawData::setPhotometricInterpretation(ExifPhotometricInterpretation pi)
201{
202 d->photometricInterpretation = pi;
203}
204
205ExifPhotometricInterpretation RawData::getPhotometricInterpretation() const
206{
207 return d->photometricInterpretation;
208}
209
210
211const double* RawData::getColourMatrix1(uint32_t & matrixSize) const
212{
213 matrixSize = d->colourMatrixCount;
214 return d->colourMatrix;
215}
216
217void 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
228const double* RawData::getColourMatrix2(uint32_t & matrixSize) const
229{
230 matrixSize = d->colourMatrix2Count;
231 return d->colourMatrix2;
232}
233
234void 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
246{
247 BitmapData::swap(with);
248 std::swap(this->d, with.d);
249}
250
251void * 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
260void 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
271void 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
282void RawData::setCfaPatternType(or_cfa_pattern t)
283{
284 d->cfa_pattern = CfaPattern::twoByTwoPattern(t);
285}
286
288{
289 return d->cfa_pattern;
290}
291
292void RawData::setCfaPattern(const CfaPattern* pattern)
293{
294 d->cfa_pattern = pattern;
295}
296
297void RawData::setCompression(uint32_t t)
298{
299 d->compression = t;
300}
301
302uint32_t RawData::compression() const
303{
304 return d->compression;
305}
306
307#if 0
308RawData &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
333void 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
349void 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
363void 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
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
void swap(BitmapData &with)
Definition: bitmapdata.cpp:90
size_t size() const
Definition: bitmapdata.cpp:129
virtual void setDimensions(uint32_t x, uint32_t y)
Definition: bitmapdata.cpp:169
DataType dataType() const
Definition: bitmapdata.cpp:95
static const CfaPattern * twoByTwoPattern(::or_cfa_pattern)
Definition: cfapattern.cpp:77
::or_cfa_pattern patternType() const
Definition: cfapattern.cpp:186
double colourMatrix[MAX_MATRIX_SIZE]
Definition: rawdata.cpp:60
void swap(RawData &with)
Definition: rawdata.cpp:245
const double * getColourMatrix1(uint32_t &size) const
Definition: rawdata.cpp:211
RawData & append(uint16_t c)
Definition: rawdata.cpp:318
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Definition: rawdata.cpp:125
const CfaPattern * cfaPattern() const
Definition: rawdata.cpp:287
const double * getColourMatrix2(uint32_t &size) const
Definition: rawdata.cpp:228
virtual void setDimensions(uint32_t x, uint32_t y) override
Definition: rawdata.cpp:260
::or_error getRawData(RawData &rawdata, uint32_t options)
Definition: rawfile.cpp:451
static RawFile * newRawFile(const char *_filename, Type _typeHint=OR_RAWFILE_TYPE_UNKNOWN)
Definition: rawfile.cpp:167
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30