• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <img_utils/DngUtils.h>
18 
19 namespace android {
20 namespace img_utils {
21 
OpcodeListBuilder()22 OpcodeListBuilder::OpcodeListBuilder() : mCount(0), mOpList(), mEndianOut(&mOpList, BIG) {
23     if(mEndianOut.open() != OK) {
24         ALOGE("%s: Open failed.", __FUNCTION__);
25     }
26 }
27 
~OpcodeListBuilder()28 OpcodeListBuilder::~OpcodeListBuilder() {
29     if(mEndianOut.close() != OK) {
30         ALOGE("%s: Close failed.", __FUNCTION__);
31     }
32 }
33 
getSize() const34 size_t OpcodeListBuilder::getSize() const {
35     return mOpList.getSize() + sizeof(mCount);
36 }
37 
getCount() const38 uint32_t OpcodeListBuilder::getCount() const {
39     return mCount;
40 }
41 
buildOpList(uint8_t * buf) const42 status_t OpcodeListBuilder::buildOpList(uint8_t* buf) const {
43     uint32_t count = convertToBigEndian(mCount);
44     memcpy(buf, &count, sizeof(count));
45     memcpy(buf + sizeof(count), mOpList.getArray(), mOpList.getSize());
46     return OK;
47 }
48 
addGainMapsForMetadata(uint32_t lsmWidth,uint32_t lsmHeight,uint32_t activeAreaTop,uint32_t activeAreaLeft,uint32_t activeAreaBottom,uint32_t activeAreaRight,CfaLayout cfa,const float * lensShadingMap)49 status_t OpcodeListBuilder::addGainMapsForMetadata(uint32_t lsmWidth,
50                                                    uint32_t lsmHeight,
51                                                    uint32_t activeAreaTop,
52                                                    uint32_t activeAreaLeft,
53                                                    uint32_t activeAreaBottom,
54                                                    uint32_t activeAreaRight,
55                                                    CfaLayout cfa,
56                                                    const float* lensShadingMap) {
57     uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
58     uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
59     double spacingV = 1.0 / lsmHeight;
60     double spacingH = 1.0 / lsmWidth;
61 
62     float redMap[lsmWidth * lsmHeight];
63     float greenEvenMap[lsmWidth * lsmHeight];
64     float greenOddMap[lsmWidth * lsmHeight];
65     float blueMap[lsmWidth * lsmHeight];
66 
67     size_t lsmMapSize = lsmWidth * lsmHeight * 4;
68 
69     // Split lens shading map channels into separate arrays
70     size_t j = 0;
71     for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
72         redMap[j] = lensShadingMap[i + LSM_R_IND];
73         greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
74         greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
75         blueMap[j] = lensShadingMap[i + LSM_B_IND];
76     }
77 
78     uint32_t redTop = 0;
79     uint32_t redLeft = 0;
80     uint32_t greenEvenTop = 0;
81     uint32_t greenEvenLeft = 1;
82     uint32_t greenOddTop = 1;
83     uint32_t greenOddLeft = 0;
84     uint32_t blueTop = 1;
85     uint32_t blueLeft = 1;
86 
87     switch(cfa) {
88         case CFA_RGGB:
89             redTop = 0;
90             redLeft = 0;
91             greenEvenTop = 0;
92             greenEvenLeft = 1;
93             greenOddTop = 1;
94             greenOddLeft = 0;
95             blueTop = 1;
96             blueLeft = 1;
97             break;
98         case CFA_GRBG:
99             redTop = 0;
100             redLeft = 1;
101             greenEvenTop = 0;
102             greenEvenLeft = 0;
103             greenOddTop = 1;
104             greenOddLeft = 1;
105             blueTop = 1;
106             blueLeft = 0;
107             break;
108         case CFA_GBRG:
109             redTop = 1;
110             redLeft = 0;
111             greenEvenTop = 0;
112             greenEvenLeft = 0;
113             greenOddTop = 1;
114             greenOddLeft = 1;
115             blueTop = 0;
116             blueLeft = 1;
117             break;
118         case CFA_BGGR:
119             redTop = 1;
120             redLeft = 1;
121             greenEvenTop = 0;
122             greenEvenLeft = 1;
123             greenOddTop = 1;
124             greenOddLeft = 0;
125             blueTop = 0;
126             blueLeft = 0;
127             break;
128         default:
129             ALOGE("%s: Unknown CFA layout %d", __FUNCTION__, cfa);
130             return BAD_VALUE;
131     }
132 
133     status_t err = addGainMap(/*top*/redTop,
134                               /*left*/redLeft,
135                               /*bottom*/activeAreaHeight - 1,
136                               /*right*/activeAreaWidth - 1,
137                               /*plane*/0,
138                               /*planes*/1,
139                               /*rowPitch*/2,
140                               /*colPitch*/2,
141                               /*mapPointsV*/lsmHeight,
142                               /*mapPointsH*/lsmWidth,
143                               /*mapSpacingV*/spacingV,
144                               /*mapSpacingH*/spacingH,
145                               /*mapOriginV*/0,
146                               /*mapOriginH*/0,
147                               /*mapPlanes*/1,
148                               /*mapGains*/redMap);
149     if (err != OK) return err;
150 
151     err = addGainMap(/*top*/greenEvenTop,
152                      /*left*/greenEvenLeft,
153                      /*bottom*/activeAreaHeight - 1,
154                      /*right*/activeAreaWidth - 1,
155                      /*plane*/0,
156                      /*planes*/1,
157                      /*rowPitch*/2,
158                      /*colPitch*/2,
159                      /*mapPointsV*/lsmHeight,
160                      /*mapPointsH*/lsmWidth,
161                      /*mapSpacingV*/spacingV,
162                      /*mapSpacingH*/spacingH,
163                      /*mapOriginV*/0,
164                      /*mapOriginH*/0,
165                      /*mapPlanes*/1,
166                      /*mapGains*/greenEvenMap);
167     if (err != OK) return err;
168 
169     err = addGainMap(/*top*/greenOddTop,
170                      /*left*/greenOddLeft,
171                      /*bottom*/activeAreaHeight - 1,
172                      /*right*/activeAreaWidth - 1,
173                      /*plane*/0,
174                      /*planes*/1,
175                      /*rowPitch*/2,
176                      /*colPitch*/2,
177                      /*mapPointsV*/lsmHeight,
178                      /*mapPointsH*/lsmWidth,
179                      /*mapSpacingV*/spacingV,
180                      /*mapSpacingH*/spacingH,
181                      /*mapOriginV*/0,
182                      /*mapOriginH*/0,
183                      /*mapPlanes*/1,
184                      /*mapGains*/greenOddMap);
185     if (err != OK) return err;
186 
187     err = addGainMap(/*top*/blueTop,
188                      /*left*/blueLeft,
189                      /*bottom*/activeAreaHeight - 1,
190                      /*right*/activeAreaWidth - 1,
191                      /*plane*/0,
192                      /*planes*/1,
193                      /*rowPitch*/2,
194                      /*colPitch*/2,
195                      /*mapPointsV*/lsmHeight,
196                      /*mapPointsH*/lsmWidth,
197                      /*mapSpacingV*/spacingV,
198                      /*mapSpacingH*/spacingH,
199                      /*mapOriginV*/0,
200                      /*mapOriginH*/0,
201                      /*mapPlanes*/1,
202                      /*mapGains*/blueMap);
203     return err;
204 }
205 
addGainMap(uint32_t top,uint32_t left,uint32_t bottom,uint32_t right,uint32_t plane,uint32_t planes,uint32_t rowPitch,uint32_t colPitch,uint32_t mapPointsV,uint32_t mapPointsH,double mapSpacingV,double mapSpacingH,double mapOriginV,double mapOriginH,uint32_t mapPlanes,const float * mapGains)206 status_t OpcodeListBuilder::addGainMap(uint32_t top,
207                                        uint32_t left,
208                                        uint32_t bottom,
209                                        uint32_t right,
210                                        uint32_t plane,
211                                        uint32_t planes,
212                                        uint32_t rowPitch,
213                                        uint32_t colPitch,
214                                        uint32_t mapPointsV,
215                                        uint32_t mapPointsH,
216                                        double mapSpacingV,
217                                        double mapSpacingH,
218                                        double mapOriginV,
219                                        double mapOriginH,
220                                        uint32_t mapPlanes,
221                                        const float* mapGains) {
222 
223     uint32_t opcodeId = GAIN_MAP_ID;
224 
225     status_t err = mEndianOut.write(&opcodeId, 0, 1);
226     if (err != OK) return err;
227 
228     uint8_t version[] = {1, 3, 0, 0};
229     err = mEndianOut.write(version, 0, NELEMS(version));
230     if (err != OK) return err;
231 
232     // Do not include optional flag for preview, as this can have a large effect on the output.
233     uint32_t flags = FLAG_OPTIONAL;
234 
235     err = mEndianOut.write(&flags, 0, 1);
236     if (err != OK) return err;
237 
238     const uint32_t NUMBER_INT_ARGS = 11;
239     const uint32_t NUMBER_DOUBLE_ARGS = 4;
240 
241     uint32_t totalSize = NUMBER_INT_ARGS * sizeof(uint32_t) + NUMBER_DOUBLE_ARGS * sizeof(double) +
242             mapPointsV * mapPointsH * mapPlanes * sizeof(float);
243 
244     err = mEndianOut.write(&totalSize, 0, 1);
245     if (err != OK) return err;
246 
247     // Batch writes as much as possible
248     uint32_t settings1[] = { top,
249                             left,
250                             bottom,
251                             right,
252                             plane,
253                             planes,
254                             rowPitch,
255                             colPitch,
256                             mapPointsV,
257                             mapPointsH };
258 
259     err = mEndianOut.write(settings1, 0, NELEMS(settings1));
260     if (err != OK) return err;
261 
262     double settings2[] = { mapSpacingV,
263                           mapSpacingH,
264                           mapOriginV,
265                           mapOriginH };
266 
267     err = mEndianOut.write(settings2, 0, NELEMS(settings2));
268     if (err != OK) return err;
269 
270     err = mEndianOut.write(&mapPlanes, 0, 1);
271     if (err != OK) return err;
272 
273     err = mEndianOut.write(mapGains, 0, mapPointsV * mapPointsH * mapPlanes);
274     if (err != OK) return err;
275 
276     mCount++;
277 
278     return OK;
279 }
280 
281 } /*namespace img_utils*/
282 } /*namespace android*/
283