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 
32 namespace OpenRaw {
33 
34 namespace Internals {
35 
37 static const uint8_t RED = OR_PATTERN_COLOUR_RED;
38 static const uint8_t GREEN = OR_PATTERN_COLOUR_GREEN;
39 static const uint8_t BLUE = OR_PATTERN_COLOUR_BLUE;
40 
41 static const uint8_t RGGB_PATTERN[] = { RED, GREEN, GREEN, BLUE };
42 static const uint8_t GBRG_PATTERN[] = { GREEN, BLUE, RED, GREEN };
43 static const uint8_t BGGR_PATTERN[] = { BLUE, GREEN, GREEN, RED };
44 static const uint8_t GRBG_PATTERN[] = { GREEN, RED, BLUE, GREEN };
45 
47  : public CfaPattern
48 {
49 public:
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 
76 const CfaPattern*
77 CfaPattern::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 {
101 public:
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 
117 CfaPattern::CfaPattern()
118  : d(new CfaPattern::Private)
119 {
120 }
121 
122 CfaPattern::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 
130 CfaPattern::~CfaPattern()
131 {
132  delete d;
133 }
134 
135 void 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 
153 void
154 CfaPattern::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 
164 const uint8_t*
165 CfaPattern::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 
176 void 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 */
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
static const CfaPattern * twoByTwoPattern(::or_cfa_pattern)
Definition: cfapattern.cpp:77
void setPatternPattern(const uint8_t *pattern, uint16_t count)
Definition: cfapattern.cpp:154
::or_cfa_pattern patternType() const
Definition: cfapattern.cpp:186
bool is2by2Rgb() const
Definition: cfapattern.cpp:147
void setSize(uint16_t x, uint16_t y)
Definition: cfapattern.cpp:135