1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/*! @file raw.c
*
* @brief Definition of routines for packing a row of pixels into a RAW image.
*
* (C) Copyright 2018 GoPro Inc (http://gopro.com/).
*
* Licensed under either:
* - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0
* - MIT license, http://opensource.org/licenses/MIT
* at your option.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "headers.h"
/*!
@brief Pack the component arrays into an output image
The inverse component transform for Bayer images (VC-5 Part 3)
is applied to the component arrays before combining the values
into a packed image.
*/
CODEC_ERROR PackComponentsToRAW(const UNPACKED_IMAGE *image,
PIXEL *output_buffer, size_t output_pitch,
DIMENSION width, DIMENSION height,
ENABLED_PARTS enabled_parts, uint16_t output_bit_depth, PIXEL_FORMAT output_format )
{
// Define pointers to the rows for each input component
COMPONENT_VALUE *GS_input_buffer;
COMPONENT_VALUE *RG_input_buffer;
COMPONENT_VALUE *BG_input_buffer;
COMPONENT_VALUE *GD_input_buffer;
// Define pointers to the rows for each output component
uint16_t *output_row1_ptr;
uint16_t *output_row2_ptr;
//size_t input_quarter_pitch;
size_t output_half_pitch;
int row;
GS_input_buffer = image->component_array_list[0].data;
RG_input_buffer = image->component_array_list[1].data;
BG_input_buffer = image->component_array_list[2].data;
GD_input_buffer = image->component_array_list[3].data;
// Compute the distance between the half rows in the Bayer grid
output_half_pitch = output_pitch / 2;
for (row = 0; row < height; row++)
{
COMPONENT_VALUE *GS_input_row_ptr = (COMPONENT_VALUE *)((uintptr_t)GS_input_buffer + row * image->component_array_list[0].pitch);
COMPONENT_VALUE *RG_input_row_ptr = (COMPONENT_VALUE *)((uintptr_t)RG_input_buffer + row * image->component_array_list[1].pitch);
COMPONENT_VALUE *BG_input_row_ptr = (COMPONENT_VALUE *)((uintptr_t)BG_input_buffer + row * image->component_array_list[2].pitch);
COMPONENT_VALUE *GD_input_row_ptr = (COMPONENT_VALUE *)((uintptr_t)GD_input_buffer + row * image->component_array_list[3].pitch);
uint8_t *output_row_ptr = (uint8_t *)output_buffer + row * output_pitch;
const int32_t midpoint = 2048;
int column;
output_row1_ptr = (uint16_t *)output_row_ptr;
output_row2_ptr = (uint16_t *)(output_row_ptr + output_half_pitch);
// Pack the rows of Bayer components into the BYR4 pattern
for (column = 0; column < width; column++)
{
int32_t GS, RG, BG, GD;
int32_t R, G1, G2, B;
GS = GS_input_row_ptr[column];
RG = RG_input_row_ptr[column];
BG = BG_input_row_ptr[column];
GD = GD_input_row_ptr[column];
// Convert unsigned values to signed values
GD -= midpoint;
RG -= midpoint;
BG -= midpoint;
R = (RG << 1) + GS;
B = (BG << 1) + GS;
G1 = GS + GD;
G2 = GS - GD;
R = clamp_uint(R, 12);
G1 = clamp_uint(G1, 12);
G2 = clamp_uint(G2, 12);
B = clamp_uint(B, 12);
// Apply inverse protune log curve
R = DecoderLogCurve[R];
B = DecoderLogCurve[B];
G1 = DecoderLogCurve[G1];
G2 = DecoderLogCurve[G2];
R >>= (16 - output_bit_depth);
B >>= (16 - output_bit_depth);
G1 >>= (16 - output_bit_depth);
G2 >>= (16 - output_bit_depth);
switch (output_format)
{
case PIXEL_FORMAT_RAW_RGGB_12:
case PIXEL_FORMAT_RAW_RGGB_14:
output_row1_ptr[2 * column + 0] = (uint16_t)R;
output_row1_ptr[2 * column + 1] = (uint16_t)G1;
output_row2_ptr[2 * column + 0] = (uint16_t)G2;
output_row2_ptr[2 * column + 1] = (uint16_t)B;
break;
case PIXEL_FORMAT_RAW_GBRG_12:
case PIXEL_FORMAT_RAW_GBRG_14:
output_row1_ptr[2 * column + 0] = (uint16_t)G1;
output_row1_ptr[2 * column + 1] = (uint16_t)B;
output_row2_ptr[2 * column + 0] = (uint16_t)R;
output_row2_ptr[2 * column + 1] = (uint16_t)G2;
break;
default:
assert(0);
break;
}
}
}
return CODEC_ERROR_OKAY;
}
|