1 /*
2 * This file is part of RawTherapee.
3 *
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
5 *
6 * RawTherapee is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * RawTherapee 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #include <algorithm>
20
21 #include "bayerhelper.h"
22 #include "librtprocess.h"
23 #include "StopWatch.h"
24 #include "xtranshelper.h"
25
26 using namespace librtprocess;
27
bayerborder_demosaic(int winw,int winh,int lborders,const float * const * rawData,float ** red,float ** green,float ** blue,const unsigned cfarray[2][2])28 rpError bayerborder_demosaic(int winw, int winh, int lborders, const float * const *rawData, float **red, float **green, float **blue, const unsigned cfarray[2][2])
29 {
30 BENCHFUN
31 if (!validateBayerCfa(3, cfarray)) {
32 return RP_WRONG_CFA;
33 }
34
35 int bord = lborders;
36 int width = winw;
37 int height = winh;
38
39 for (int i = 0; i < height; i++) {
40
41 float sum[6];
42
43 for (int j = 0; j < bord; j++) { //first few columns
44 for (int c = 0; c < 6; c++) {
45 sum[c] = 0;
46 }
47
48 for (int i1 = i - 1; i1 < i + 2; i1++)
49 for (int j1 = j - 1; j1 < j + 2; j1++) {
50 if ((i1 > -1) && (i1 < height) && (j1 > -1)) {
51 int c = fc(cfarray, i1, j1);
52 sum[c] += rawData[i1][j1];
53 sum[c + 3]++;
54 }
55 }
56
57 int c = fc(cfarray, i, j);
58
59 if (c == 1) {
60 red[i][j] = sum[0] / sum[3];
61 green[i][j] = rawData[i][j];
62 blue[i][j] = sum[2] / sum[5];
63 } else {
64 green[i][j] = sum[1] / sum[4];
65
66 if (c == 0) {
67 red[i][j] = rawData[i][j];
68 blue[i][j] = sum[2] / sum[5];
69 } else {
70 red[i][j] = sum[0] / sum[3];
71 blue[i][j] = rawData[i][j];
72 }
73 }
74 }//j
75
76 for (int j = width - bord; j < width; j++) { //last few columns
77 for (int c = 0; c < 6; c++) {
78 sum[c] = 0;
79 }
80
81 for (int i1 = i - 1; i1 < i + 2; i1++)
82 for (int j1 = j - 1; j1 < j + 2; j1++) {
83 if ((i1 > -1) && (i1 < height ) && (j1 < width)) {
84 int c = fc(cfarray, i1, j1);
85 sum[c] += rawData[i1][j1];
86 sum[c + 3]++;
87 }
88 }
89
90 int c = fc(cfarray, i, j);
91
92 if (c == 1) {
93 red[i][j] = sum[0] / sum[3];
94 green[i][j] = rawData[i][j];
95 blue[i][j] = sum[2] / sum[5];
96 } else {
97 green[i][j] = sum[1] / sum[4];
98
99 if (c == 0) {
100 red[i][j] = rawData[i][j];
101 blue[i][j] = sum[2] / sum[5];
102 } else {
103 red[i][j] = sum[0] / sum[3];
104 blue[i][j] = rawData[i][j];
105 }
106 }
107 }//j
108 }//i
109
110 for (int i = 0; i < bord; i++) {
111
112 float sum[6];
113
114 for (int j = bord; j < width - bord; j++) { //first few rows
115 for (int c = 0; c < 6; c++) {
116 sum[c] = 0;
117 }
118
119 for (int i1 = i - 1; i1 < i + 2; i1++)
120 for (int j1 = j - 1; j1 < j + 2; j1++) {
121 if ((i1 > -1) && (i1 < height) && (j1 > -1)) {
122 int c = fc(cfarray, i1, j1);
123 sum[c] += rawData[i1][j1];
124 sum[c + 3]++;
125 }
126 }
127
128 int c = fc(cfarray, i, j);
129
130 if (c == 1) {
131 red[i][j] = sum[0] / sum[3];
132 green[i][j] = rawData[i][j];
133 blue[i][j] = sum[2] / sum[5];
134 } else {
135 green[i][j] = sum[1] / sum[4];
136
137 if (c == 0) {
138 red[i][j] = rawData[i][j];
139 blue[i][j] = sum[2] / sum[5];
140 } else {
141 red[i][j] = sum[0] / sum[3];
142 blue[i][j] = rawData[i][j];
143 }
144 }
145 }//j
146 }
147
148 for (int i = height - bord; i < height; i++) {
149
150 float sum[6];
151
152 for (int j = bord; j < width - bord; j++) { //last few rows
153 for (int c = 0; c < 6; c++) {
154 sum[c] = 0;
155 }
156
157 for (int i1 = i - 1; i1 < i + 2; i1++)
158 for (int j1 = j - 1; j1 < j + 2; j1++) {
159 if ((i1 > -1) && (i1 < height) && (j1 < width)) {
160 int c = fc(cfarray, i1, j1);
161 sum[c] += rawData[i1][j1];
162 sum[c + 3]++;
163 }
164 }
165
166 int c = fc(cfarray, i, j);
167
168 if (c == 1) {
169 red[i][j] = sum[0] / sum[3];
170 green[i][j] = rawData[i][j];
171 blue[i][j] = sum[2] / sum[5];
172 } else {
173 green[i][j] = sum[1] / sum[4];
174
175 if (c == 0) {
176 red[i][j] = rawData[i][j];
177 blue[i][j] = sum[2] / sum[5];
178 } else {
179 red[i][j] = sum[0] / sum[3];
180 blue[i][j] = rawData[i][j];
181 }
182 }
183 }//j
184 }
185
186 return RP_NO_ERROR;
187 }
188
xtransborder_demosaic(int winw,int winh,int border,const float * const * rawData,float ** red,float ** green,float ** blue,const unsigned xtrans[6][6])189 void xtransborder_demosaic(int winw, int winh, int border, const float * const *rawData, float **red, float **green, float **blue, const unsigned xtrans[6][6])
190 {
191 BENCHFUN
192 const int height = winh, width = winw;
193
194 const float weight[3][3] = {
195 {0.25f, 0.5f, 0.25f},
196 {0.5f, 0.f, 0.5f},
197 {0.25f, 0.5f, 0.25f}
198 };
199
200 for (int row = 0; row < height; row++) {
201 for (int col = 0; col < width; col++) {
202 if (col == border && row >= border && row < height - border) {
203 col = width - border;
204 }
205
206 float sum[6] = {0.f};
207
208 for (int y = std::max(0, row - 1), v = row == 0 ? 0 : -1; y <= std::min(row + 1, height - 1); y++, v++)
209 for (int x = std::max(0, col - 1), h = col == 0 ? 0 : -1; x <= std::min(col + 1, width - 1); x++, h++) {
210 int f = fc(xtrans, y, x);
211 sum[f] += rawData[y][x] * weight[v + 1][h + 1];
212 sum[f + 3] += weight[v + 1][h + 1];
213 }
214
215 switch(fc(xtrans, row, col)) {
216 case 0:
217 red[row][col] = rawData[row][col];
218 green[row][col] = (sum[1] / sum[4]);
219 blue[row][col] = (sum[2] / sum[5]);
220 break;
221
222 case 1:
223 if(sum[3] == 0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area
224 red[row][col] = green[row][col] = blue[row][col] = rawData[row][col];
225 } else {
226 red[row][col] = (sum[0] / sum[3]);
227 green[row][col] = rawData[row][col];
228 blue[row][col] = (sum[2] / sum[5]);
229 }
230
231 break;
232
233 case 2:
234 red[row][col] = (sum[0] / sum[3]);
235 green[row][col] = (sum[1] / sum[4]);
236 blue[row][col] = rawData[row][col];
237 }
238 }
239 }
240 }
241