1e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk/*
2e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Copyright 2014 The Android Open Source Project
3e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
4e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * you may not use this file except in compliance with the License.
6e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * You may obtain a copy of the License at
7e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
8e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk *
10e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * Unless required by applicable law or agreed to in writing, software
11e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * See the License for the specific language governing permissions and
14e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk * limitations under the License.
15e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk */
16e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
17e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk#include <img_utils/DngUtils.h>
18e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
190f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk#include <inttypes.h>
200f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
2145a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala#include <vector>
220f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk#include <math.h>
230f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
24e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace android {
25e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunknamespace img_utils {
26e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
273fe1435e28dc6959e410740feea89ca1bf4f4fc1Ruben BrunkOpcodeListBuilder::OpcodeListBuilder() : mCount(0), mOpList(), mEndianOut(&mOpList, BIG) {
28e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if(mEndianOut.open() != OK) {
29e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: Open failed.", __FUNCTION__);
30e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
31e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
32e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
33e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben BrunkOpcodeListBuilder::~OpcodeListBuilder() {
34e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if(mEndianOut.close() != OK) {
35e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        ALOGE("%s: Close failed.", __FUNCTION__);
36e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
37e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
38e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
39e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunksize_t OpcodeListBuilder::getSize() const {
40e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mOpList.getSize() + sizeof(mCount);
41e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
42e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
43e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkuint32_t OpcodeListBuilder::getCount() const {
44e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return mCount;
45e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
46e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
47e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t OpcodeListBuilder::buildOpList(uint8_t* buf) const {
48e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t count = convertToBigEndian(mCount);
49e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    memcpy(buf, &count, sizeof(count));
50e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    memcpy(buf + sizeof(count), mOpList.getArray(), mOpList.getSize());
51e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return OK;
52e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
53e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
54e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t OpcodeListBuilder::addGainMapsForMetadata(uint32_t lsmWidth,
55e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   uint32_t lsmHeight,
56e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   uint32_t activeAreaTop,
57e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   uint32_t activeAreaLeft,
58e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   uint32_t activeAreaBottom,
59e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   uint32_t activeAreaRight,
60e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   CfaLayout cfa,
61e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                                   const float* lensShadingMap) {
62e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t activeAreaWidth = activeAreaRight - activeAreaLeft;
63e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t activeAreaHeight = activeAreaBottom - activeAreaTop;
64e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    double spacingV = 1.0 / lsmHeight;
65e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    double spacingH = 1.0 / lsmWidth;
66e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
6745a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    std::vector<float> redMapVector(lsmWidth * lsmHeight);
6845a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    float *redMap = redMapVector.data();
6945a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala
7045a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    std::vector<float> greenEvenMapVector(lsmWidth * lsmHeight);
7145a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    float *greenEvenMap = greenEvenMapVector.data();
7245a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala
7345a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    std::vector<float> greenOddMapVector(lsmWidth * lsmHeight);
7445a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    float *greenOddMap = greenOddMapVector.data();
7545a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala
7645a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    std::vector<float> blueMapVector(lsmWidth * lsmHeight);
7745a599d79a1a1b74b959d98eccfbec9c6a5aa237Eino-Ville Talvala    float *blueMap = blueMapVector.data();
78e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
79e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    size_t lsmMapSize = lsmWidth * lsmHeight * 4;
80e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
81e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    // Split lens shading map channels into separate arrays
82e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    size_t j = 0;
83e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    for (size_t i = 0; i < lsmMapSize; i += 4, ++j) {
84e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        redMap[j] = lensShadingMap[i + LSM_R_IND];
85e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        greenEvenMap[j] = lensShadingMap[i + LSM_GE_IND];
86e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        greenOddMap[j] = lensShadingMap[i + LSM_GO_IND];
87e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        blueMap[j] = lensShadingMap[i + LSM_B_IND];
88e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
89e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
90e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t redTop = 0;
91e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t redLeft = 0;
92e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t greenEvenTop = 0;
93e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t greenEvenLeft = 1;
94e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t greenOddTop = 1;
95e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t greenOddLeft = 0;
96e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t blueTop = 1;
97e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t blueLeft = 1;
98e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
99e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    switch(cfa) {
100e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case CFA_RGGB:
101e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redTop = 0;
102e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redLeft = 0;
103e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenTop = 0;
104e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenLeft = 1;
105e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddTop = 1;
106e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddLeft = 0;
107e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueTop = 1;
108e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueLeft = 1;
109e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            break;
110e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case CFA_GRBG:
111e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redTop = 0;
112e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redLeft = 1;
113e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenTop = 0;
114e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenLeft = 0;
115e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddTop = 1;
116e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddLeft = 1;
117e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueTop = 1;
118e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueLeft = 0;
119e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            break;
120e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case CFA_GBRG:
121e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redTop = 1;
122e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redLeft = 0;
123e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenTop = 0;
124e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenLeft = 0;
125e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddTop = 1;
126e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddLeft = 1;
127e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueTop = 0;
128e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueLeft = 1;
129e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            break;
130e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        case CFA_BGGR:
131e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redTop = 1;
132e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            redLeft = 1;
133e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenTop = 0;
134e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenEvenLeft = 1;
135e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddTop = 1;
136e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            greenOddLeft = 0;
137e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueTop = 0;
138e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            blueLeft = 0;
139e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            break;
140e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk        default:
141e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            ALOGE("%s: Unknown CFA layout %d", __FUNCTION__, cfa);
142e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            return BAD_VALUE;
143e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    }
144e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
145e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    status_t err = addGainMap(/*top*/redTop,
146e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*left*/redLeft,
147e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*bottom*/activeAreaHeight - 1,
148e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*right*/activeAreaWidth - 1,
149e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*plane*/0,
150e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*planes*/1,
151e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*rowPitch*/2,
152e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*colPitch*/2,
153e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapPointsV*/lsmHeight,
154e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapPointsH*/lsmWidth,
155e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapSpacingV*/spacingV,
156e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapSpacingH*/spacingH,
157e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapOriginV*/0,
158e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapOriginH*/0,
159e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapPlanes*/1,
160e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                              /*mapGains*/redMap);
161e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
162e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
163e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = addGainMap(/*top*/greenEvenTop,
164e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*left*/greenEvenLeft,
165e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*bottom*/activeAreaHeight - 1,
166e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*right*/activeAreaWidth - 1,
167e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*plane*/0,
168e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*planes*/1,
169e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*rowPitch*/2,
170e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*colPitch*/2,
171e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsV*/lsmHeight,
172e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsH*/lsmWidth,
173e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingV*/spacingV,
174e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingH*/spacingH,
175e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginV*/0,
176e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginH*/0,
177e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPlanes*/1,
178e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapGains*/greenEvenMap);
179e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
180e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
181e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = addGainMap(/*top*/greenOddTop,
182e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*left*/greenOddLeft,
183e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*bottom*/activeAreaHeight - 1,
184e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*right*/activeAreaWidth - 1,
185e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*plane*/0,
186e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*planes*/1,
187e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*rowPitch*/2,
188e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*colPitch*/2,
189e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsV*/lsmHeight,
190e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsH*/lsmWidth,
191e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingV*/spacingV,
192e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingH*/spacingH,
193e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginV*/0,
194e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginH*/0,
195e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPlanes*/1,
196e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapGains*/greenOddMap);
197e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
198e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
199e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = addGainMap(/*top*/blueTop,
200e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*left*/blueLeft,
201e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*bottom*/activeAreaHeight - 1,
202e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*right*/activeAreaWidth - 1,
203e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*plane*/0,
204e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*planes*/1,
205e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*rowPitch*/2,
206e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*colPitch*/2,
207e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsV*/lsmHeight,
208e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPointsH*/lsmWidth,
209e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingV*/spacingV,
210e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapSpacingH*/spacingH,
211e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginV*/0,
212e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapOriginH*/0,
213e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapPlanes*/1,
214e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                     /*mapGains*/blueMap);
215e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return err;
216e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
217e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
218e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunkstatus_t OpcodeListBuilder::addGainMap(uint32_t top,
219e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t left,
220e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t bottom,
221e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t right,
222e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t plane,
223e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t planes,
224e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t rowPitch,
225e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t colPitch,
226e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t mapPointsV,
227e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t mapPointsH,
228e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       double mapSpacingV,
229e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       double mapSpacingH,
230e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       double mapOriginV,
231e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       double mapOriginH,
232e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       uint32_t mapPlanes,
233e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                                       const float* mapGains) {
234e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
235bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    status_t err = addOpcodePreamble(GAIN_MAP_ID);
236e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
237e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
2380f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    // Allow this opcode to be skipped if not supported
239482e0235f84ec483c57bab4cb16b5918d0821630Ruben Brunk    uint32_t flags = FLAG_OPTIONAL;
240482e0235f84ec483c57bab4cb16b5918d0821630Ruben Brunk
241e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(&flags, 0, 1);
242e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
243e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
244e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    const uint32_t NUMBER_INT_ARGS = 11;
245e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    const uint32_t NUMBER_DOUBLE_ARGS = 4;
246e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
247e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t totalSize = NUMBER_INT_ARGS * sizeof(uint32_t) + NUMBER_DOUBLE_ARGS * sizeof(double) +
248e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk            mapPointsV * mapPointsH * mapPlanes * sizeof(float);
249e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
250e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(&totalSize, 0, 1);
251e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
252e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
253e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    // Batch writes as much as possible
254e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    uint32_t settings1[] = { top,
255e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            left,
256e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            bottom,
257e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            right,
258e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            plane,
259e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            planes,
260e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            rowPitch,
261e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            colPitch,
262e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            mapPointsV,
263e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                            mapPointsH };
264e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
265e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(settings1, 0, NELEMS(settings1));
266e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
267e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
268e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    double settings2[] = { mapSpacingV,
269e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                          mapSpacingH,
270e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                          mapOriginV,
271e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk                          mapOriginH };
272e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
273e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(settings2, 0, NELEMS(settings2));
274e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
275e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
276e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(&mapPlanes, 0, 1);
277e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
278e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
279e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    err = mEndianOut.write(mapGains, 0, mapPointsV * mapPointsH * mapPlanes);
280e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    if (err != OK) return err;
281e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
282e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    mCount++;
283e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
284e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk    return OK;
285e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk}
286e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk
2870f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunkstatus_t OpcodeListBuilder::addWarpRectilinearForMetadata(const float* kCoeffs,
2880f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                                          uint32_t activeArrayWidth,
2890f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                                          uint32_t activeArrayHeight,
2900f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                                          float opticalCenterX,
2910f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                                          float opticalCenterY) {
2920f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (activeArrayWidth <= 1 || activeArrayHeight <= 1) {
2930f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk        ALOGE("%s: Cannot add opcode for active array with dimensions w=%" PRIu32 ", h=%" PRIu32,
2940f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                __FUNCTION__, activeArrayWidth, activeArrayHeight);
2950f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk        return BAD_VALUE;
2960f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    }
2970f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
2980f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    double normalizedOCX = opticalCenterX / static_cast<double>(activeArrayWidth - 1);
2990f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    double normalizedOCY = opticalCenterY / static_cast<double>(activeArrayHeight - 1);
3000f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3010f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    normalizedOCX = CLAMP(normalizedOCX, 0, 1);
3020f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    normalizedOCY = CLAMP(normalizedOCY, 0, 1);
3030f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3040f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    // Conversion factors from Camera2 K factors to DNG spec. K factors:
3050f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //
3060f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      Note: these are necessary because our unit system assumes a
3070f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      normalized max radius of sqrt(2), whereas the DNG spec's
3080f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      WarpRectilinear opcode assumes a normalized max radius of 1.
3090f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      Thus, each K coefficient must include the domain scaling
3100f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      factor (the DNG domain is scaled by sqrt(2) to emulate the
3110f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    //      domain used by the Camera2 specification).
3120f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3130f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_0 = sqrt(2);
3140f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_1 = 2 * sqrt(2);
3150f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_2 = 4 * sqrt(2);
3160f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_3 = 8 * sqrt(2);
3170f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_4 = 2;
3180f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double c_5 = 2;
3190f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3200f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const double coeffs[] = { c_0 * kCoeffs[0],
3210f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              c_1 * kCoeffs[1],
3220f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              c_2 * kCoeffs[2],
3230f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              c_3 * kCoeffs[3],
3240f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              c_4 * kCoeffs[4],
3250f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              c_5 * kCoeffs[5] };
3260f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3270f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3280f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    return addWarpRectilinear(/*numPlanes*/1,
3290f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              /*opticalCenterX*/normalizedOCX,
3300f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              /*opticalCenterY*/normalizedOCY,
3310f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                              coeffs);
3320f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk}
3330f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3340f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunkstatus_t OpcodeListBuilder::addWarpRectilinear(uint32_t numPlanes,
3350f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                               double opticalCenterX,
3360f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                               double opticalCenterY,
3370f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk                                               const double* kCoeffs) {
3380f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
339bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    status_t err = addOpcodePreamble(WARP_RECTILINEAR_ID);
3400f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3410f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3420f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    // Allow this opcode to be skipped if not supported
3430f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    uint32_t flags = FLAG_OPTIONAL;
3440f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3450f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(&flags, 0, 1);
3460f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3470f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3480f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const uint32_t NUMBER_CENTER_ARGS = 2;
3490f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    const uint32_t NUMBER_COEFFS = numPlanes * 6;
3500f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    uint32_t totalSize = (NUMBER_CENTER_ARGS + NUMBER_COEFFS) * sizeof(double) + sizeof(uint32_t);
3510f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3520f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(&totalSize, 0, 1);
3530f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3540f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3550f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(&numPlanes, 0, 1);
3560f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3570f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3580f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(kCoeffs, 0, NUMBER_COEFFS);
3590f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3600f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3610f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(&opticalCenterX, 0, 1);
3620f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3630f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3640f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    err = mEndianOut.write(&opticalCenterY, 0, 1);
3650f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    if (err != OK) return err;
3660f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3670f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    mCount++;
3680f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
3690f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk    return OK;
3700f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk}
3710f212b73e47ef0e1fa39aa250ebabedb9d81a361Ruben Brunk
372bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunkstatus_t OpcodeListBuilder::addBadPixelListForMetadata(const uint32_t* hotPixels,
373bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                                       uint32_t xyPairCount,
374bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                                       uint32_t colorFilterArrangement) {
375bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (colorFilterArrangement > 3) {
376bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        ALOGE("%s:  Unknown color filter arrangement %" PRIu32, __FUNCTION__,
377bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                colorFilterArrangement);
378bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        return BAD_VALUE;
379bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    }
380bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
381bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    return addBadPixelList(colorFilterArrangement, xyPairCount, 0, hotPixels, nullptr);
382bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk}
383bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
384bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunkstatus_t OpcodeListBuilder::addBadPixelList(uint32_t bayerPhase,
385bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                            uint32_t badPointCount,
386bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                            uint32_t badRectCount,
387bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                            const uint32_t* badPointRowColPairs,
388bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk                                            const uint32_t* badRectTopLeftBottomRightTuples) {
389bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
390bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    status_t err = addOpcodePreamble(FIX_BAD_PIXELS_LIST);
391bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
392bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
393bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    // Allow this opcode to be skipped if not supported
394bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    uint32_t flags = FLAG_OPTIONAL;
395bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
396bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(&flags, 0, 1);
397bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
398bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
399bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    const uint32_t NUM_NON_VARLEN_FIELDS = 3;
400bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    const uint32_t SIZE_OF_POINT = 2;
401bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    const uint32_t SIZE_OF_RECT = 4;
402bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
403bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    uint32_t totalSize =  (NUM_NON_VARLEN_FIELDS  + badPointCount * SIZE_OF_POINT +
404bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk            badRectCount * SIZE_OF_RECT) * sizeof(uint32_t);
405bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(&totalSize, 0, 1);
406bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
407bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
408bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(&bayerPhase, 0, 1);
409bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
410bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
411bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(&badPointCount, 0, 1);
412bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
413bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
414bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(&badRectCount, 0, 1);
415bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
416bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
417bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (badPointCount > 0) {
418bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        err = mEndianOut.write(badPointRowColPairs, 0, SIZE_OF_POINT * badPointCount);
419bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        if (err != OK) return err;
420bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    }
421bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
422bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (badRectCount > 0) {
423bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        err = mEndianOut.write(badRectTopLeftBottomRightTuples, 0, SIZE_OF_RECT * badRectCount);
424bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk        if (err != OK) return err;
425bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    }
426bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
427bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    mCount++;
428bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    return OK;
429bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk}
430bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
431bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunkstatus_t OpcodeListBuilder::addOpcodePreamble(uint32_t opcodeId) {
432bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    status_t err = mEndianOut.write(&opcodeId, 0, 1);
433bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
434bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
435bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    uint8_t version[] = {1, 3, 0, 0};
436bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    err = mEndianOut.write(version, 0, NELEMS(version));
437bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    if (err != OK) return err;
438bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk    return OK;
439bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk}
440bdd368796e7773f0fefb9e238dd16c9242180db5Ruben Brunk
441e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace img_utils*/
442e507721000647a7d8afe44c63ef7fd04ef8971b1Ruben Brunk} /*namespace android*/
443