summaryrefslogtreecommitdiff
path: root/gpr/source/lib/vc5_decoder/raw.c
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/lib/vc5_decoder/raw.c')
-rwxr-xr-xgpr/source/lib/vc5_decoder/raw.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/gpr/source/lib/vc5_decoder/raw.c b/gpr/source/lib/vc5_decoder/raw.c
new file mode 100755
index 0000000..7cbac6f
--- /dev/null
+++ b/gpr/source/lib/vc5_decoder/raw.c
@@ -0,0 +1,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;
+}