libopenraw
cfapattern.cpp
1/*
2 * libopenraw - cfapattern.cpp
3 *
4 * Copyright (C) 2012 Hubert Figuière
5 *
6 * This library is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation, either version 3 of
9 * the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21#include <stdint.h>
22#include <stddef.h>
23
24#include <array>
25
26#include <boost/static_assert.hpp>
27
28#include <libopenraw/consts.h>
29
30#include "cfapattern.hpp"
31
32namespace OpenRaw {
33
34namespace Internals {
35
37static const uint8_t RED = OR_PATTERN_COLOUR_RED;
38static const uint8_t GREEN = OR_PATTERN_COLOUR_GREEN;
39static const uint8_t BLUE = OR_PATTERN_COLOUR_BLUE;
40
41static const uint8_t RGGB_PATTERN[] = { RED, GREEN, GREEN, BLUE };
42static const uint8_t GBRG_PATTERN[] = { GREEN, BLUE, RED, GREEN };
43static const uint8_t BGGR_PATTERN[] = { BLUE, GREEN, GREEN, RED };
44static const uint8_t GRBG_PATTERN[] = { GREEN, RED, BLUE, GREEN };
45
46class Cfa2x2RgbPattern
47 : public CfaPattern
48{
49public:
50 Cfa2x2RgbPattern(::or_cfa_pattern pattern)
51 : CfaPattern(pattern, 2, 2)
52 {
53 switch(pattern) {
54 case OR_CFA_PATTERN_RGGB:
55 setPatternPattern(RGGB_PATTERN, 4);
56 break;
57 case OR_CFA_PATTERN_GBRG:
58 setPatternPattern(GBRG_PATTERN, 4);
59 break;
60 case OR_CFA_PATTERN_BGGR:
61 setPatternPattern(BGGR_PATTERN, 4);
62 break;
63 case OR_CFA_PATTERN_GRBG:
64 setPatternPattern(GRBG_PATTERN, 4);
65 break;
66
67 default:
68 break;
69 }
70 }
71
72};
73
74}
75
76const CfaPattern*
77CfaPattern::twoByTwoPattern(::or_cfa_pattern pattern)
78{
79 static std::array<CfaPattern*, _OR_CFA_PATTERN_INVALID> s_patterns
80 = { { NULL, NULL, NULL, NULL, NULL, NULL } };
81 // this should be updated if we change the enum
82 BOOST_STATIC_ASSERT(_OR_CFA_PATTERN_INVALID == 6);
83
84 if((pattern == OR_CFA_PATTERN_NON_RGB22) ||
85 (pattern >= _OR_CFA_PATTERN_INVALID)) {
86 return NULL;
87 }
88
89 CfaPattern* pat = s_patterns[pattern];
90 if(!pat) {
91 pat = new Internals::Cfa2x2RgbPattern(pattern);
92 s_patterns[pattern] = pat;
93 }
94
95 return pat;
96}
97
98
100{
101public:
102 friend class Internals::Cfa2x2RgbPattern;
103
104 Private()
105 : x(0), y(0), n_colours(0)
106 , pattern_type(OR_CFA_PATTERN_NONE)
107 , pattern(NULL)
108 {}
109
110 uint16_t x;
111 uint16_t y;
112 uint16_t n_colours;
113 ::or_cfa_pattern pattern_type;
114 const uint8_t* pattern;
115};
116
117CfaPattern::CfaPattern()
118 : d(new CfaPattern::Private)
119{
120}
121
122CfaPattern::CfaPattern(::or_cfa_pattern pattern,
123 uint16_t width, uint16_t height)
124 : d(new CfaPattern::Private)
125{
126 setSize(width, height);
127 setPatternType(pattern);
128}
129
130CfaPattern::~CfaPattern()
131{
132 delete d;
133}
134
135void CfaPattern::setSize(uint16_t x, uint16_t y)
136{
137 d->x = x;
138 d->y = y;
139 if(x != 2 || y != 2) {
140 d->pattern_type = OR_CFA_PATTERN_NON_RGB22;
141 }
142 else if(!is2by2Rgb()) {
143 d->pattern_type = OR_CFA_PATTERN_NONE;
144 }
145}
146
148{
149 return (d->pattern_type != OR_CFA_PATTERN_NONE)
150 && (d->pattern_type != OR_CFA_PATTERN_NON_RGB22);
151}
152
153void
154CfaPattern::setPatternPattern(const uint8_t* pattern, uint16_t count)
155{
156 if(count != d->x * d->y) {
157 d->pattern = NULL;
158 // TODO deal with the error
159 return;
160 }
161 d->pattern = pattern;
162}
163
164const uint8_t*
165CfaPattern::patternPattern(uint16_t& count) const
166{
167 if(d->pattern) {
168 count = d->x * d->y;
169 return d->pattern;
170 }
171
172 count = 0;
173 return NULL;
174}
175
176void CfaPattern::setPatternType(::or_cfa_pattern pattern)
177{
178 d->pattern_type = pattern;
179 if(is2by2Rgb()) {
180 setSize(2, 2);
181 d->n_colours = 3;
182 }
183}
184
185::or_cfa_pattern
187{
188 return d->pattern_type;
189}
190
191}
192/*
193 Local Variables:
194 mode:c++
195 c-file-style:"stroustrup"
196 c-file-offsets:((innamespace . 0))
197 tab-width:2
198 c-basic-offset:2
199 indent-tabs-mode:nil
200 fill-column:80
201 End:
202*/
void setPatternPattern(const uint8_t *pattern, uint16_t count)
bool is2by2Rgb() const
static const CfaPattern * twoByTwoPattern(::or_cfa_pattern)
::or_cfa_pattern patternType() const
void setSize(uint16_t x, uint16_t y)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30