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 #ifndef IMG_UTILS_DNG_UTILS_H
18 #define IMG_UTILS_DNG_UTILS_H
19 
20 #include <img_utils/ByteArrayOutput.h>
21 #include <img_utils/EndianUtils.h>
22 
23 #include <utils/Errors.h>
24 #include <utils/Log.h>
25 #include <utils/RefBase.h>
26 
27 #include <cutils/compiler.h>
28 #include <stdint.h>
29 
30 namespace android {
31 namespace img_utils {
32 
33 #define NELEMS(x) ((int) (sizeof(x) / sizeof((x)[0])))
34 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
35 
36 /**
37  * Utility class for building values for the OpcodeList tags specified
38  * in the Adobe DNG 1.4 spec.
39  */
40 class ANDROID_API OpcodeListBuilder : public LightRefBase<OpcodeListBuilder> {
41     public:
42         // Note that the Adobe DNG 1.4 spec for Bayer phase (defined for the
43         // FixBadPixelsConstant and FixBadPixelsList opcodes) is incorrect. It's
44         // inconsistent with the DNG SDK (cf. dng_negative::SetBayerMosaic and
45         // dng_opcode_FixBadPixelsList::IsGreen), and Adobe confirms that the
46         // spec should be updated to match the SDK.
47         enum CfaLayout {
48             CFA_GRBG = 0,
49             CFA_RGGB,
50             CFA_BGGR,
51             CFA_GBRG,
52         };
53 
54         OpcodeListBuilder();
55         virtual ~OpcodeListBuilder();
56 
57         /**
58          * Get the total size of this opcode list in bytes.
59          */
60         virtual size_t getSize() const;
61 
62         /**
63          * Get the number of opcodes defined in this list.
64          */
65         virtual uint32_t getCount() const;
66 
67         /**
68          * Write the opcode list into the given buffer.  This buffer
69          * must be able to hold at least as many elements as returned
70          * by calling the getSize() method.
71          *
72          * Returns OK on success, or a negative error code.
73          */
74         virtual status_t buildOpList(/*out*/ uint8_t* buf) const;
75 
76         /**
77          * Add GainMap opcode(s) for the given metadata parameters.  The given
78          * CFA layout must match the layout of the shading map passed into the
79          * lensShadingMap parameter.
80          *
81          * Returns OK on success, or a negative error code.
82          */
83         virtual status_t addGainMapsForMetadata(uint32_t lsmWidth,
84                                                 uint32_t lsmHeight,
85                                                 uint32_t activeAreaTop,
86                                                 uint32_t activeAreaLeft,
87                                                 uint32_t activeAreaBottom,
88                                                 uint32_t activeAreaRight,
89                                                 CfaLayout cfa,
90                                                 const float* lensShadingMap);
91 
92 
93         /**
94          * Add a GainMap opcode with the given fields.  The mapGains array
95          * must have mapPointsV * mapPointsH * mapPlanes elements.
96          *
97          * Returns OK on success, or a negative error code.
98          */
99         virtual status_t addGainMap(uint32_t top,
100                                     uint32_t left,
101                                     uint32_t bottom,
102                                     uint32_t right,
103                                     uint32_t plane,
104                                     uint32_t planes,
105                                     uint32_t rowPitch,
106                                     uint32_t colPitch,
107                                     uint32_t mapPointsV,
108                                     uint32_t mapPointsH,
109                                     double mapSpacingV,
110                                     double mapSpacingH,
111                                     double mapOriginV,
112                                     double mapOriginH,
113                                     uint32_t mapPlanes,
114                                     const float* mapGains);
115 
116         /**
117          * Add WarpRectilinear opcode for the given metadata parameters.
118          *
119          * Returns OK on success, or a negative error code.
120          */
121         virtual status_t addWarpRectilinearForMetadata(const float* kCoeffs,
122                                                        uint32_t activeArrayWidth,
123                                                        uint32_t activeArrayHeight,
124                                                        float opticalCenterX,
125                                                        float opticalCenterY);
126 
127         /**
128          * Add a WarpRectilinear opcode.
129          *
130          * numPlanes - Number of planes included in this opcode.
131          * opticalCenterX, opticalCenterY - Normalized x,y coordinates of the sensor optical
132          *          center relative to the top,left pixel of the produced images (e.g. [0.5, 0.5]
133          *          gives a sensor optical center in the image center.
134          * kCoeffs - A list of coefficients for the polynomial equation representing the distortion
135          *          correction.  For each plane, 6 coefficients must be included:
136          *          {k_r0, k_r1, k_r2, k_r3, k_t0, k_t1}.  See the DNG 1.4 specification for an
137          *          outline of the polynomial used here.
138          *
139          * Returns OK on success, or a negative error code.
140          */
141         virtual status_t addWarpRectilinear(uint32_t numPlanes,
142                                             double opticalCenterX,
143                                             double opticalCenterY,
144                                             const double* kCoeffs);
145 
146 
147         /**
148          * Add FixBadPixelsList opcode for the given metadata parameters.
149          *
150          * Returns OK on success, or a negative error code.
151          */
152         virtual status_t addBadPixelListForMetadata(const uint32_t* hotPixels,
153                                                     uint32_t xyPairCount,
154                                                     uint32_t colorFilterArrangement);
155 
156         /**
157          * Add FixBadPixelsList opcode.
158          *
159          * bayerPhase - 0=top-left of image is red, 1=top-left of image is green pixel in red row,
160          *              2=top-left of image is green pixel in blue row, 3=top-left of image is
161          *              blue.
162          * badPointCount - number of (x,y) pairs of bad pixels are given in badPointRowColPairs.
163          * badRectCount - number of (top, left, bottom, right) tuples are given in
164          *              badRectTopLeftBottomRightTuples
165          *
166          * Returns OK on success, or a negative error code.
167          */
168         virtual status_t addBadPixelList(uint32_t bayerPhase,
169                                          uint32_t badPointCount,
170                                          uint32_t badRectCount,
171                                          const uint32_t* badPointRowColPairs,
172                                          const uint32_t* badRectTopLeftBottomRightTuples);
173 
174         // TODO: Add other Opcode methods
175     protected:
176         static const uint32_t FLAG_OPTIONAL = 0x1u;
177         static const uint32_t FLAG_OPTIONAL_FOR_PREVIEW = 0x2u;
178 
179         // Opcode IDs
180         enum {
181             WARP_RECTILINEAR_ID = 1,
182             FIX_BAD_PIXELS_LIST = 5,
183             GAIN_MAP_ID = 9,
184         };
185 
186         // LSM mosaic indices
187         enum {
188             LSM_R_IND = 0,
189             LSM_GE_IND = 1,
190             LSM_GO_IND = 2,
191             LSM_B_IND = 3,
192         };
193 
194         uint32_t mCount;
195         ByteArrayOutput mOpList;
196         EndianOutput mEndianOut;
197 
198         status_t addOpcodePreamble(uint32_t opcodeId);
199 
200 };
201 
202 } /*namespace img_utils*/
203 } /*namespace android*/
204 
205 #endif /*IMG_UTILS_DNG_UTILS_H*/
206