summaryrefslogtreecommitdiff
path: root/gpr/source/app/gpr_tools/gpr_parse_utils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gpr/source/app/gpr_tools/gpr_parse_utils.cpp')
-rwxr-xr-xgpr/source/app/gpr_tools/gpr_parse_utils.cpp545
1 files changed, 545 insertions, 0 deletions
diff --git a/gpr/source/app/gpr_tools/gpr_parse_utils.cpp b/gpr/source/app/gpr_tools/gpr_parse_utils.cpp
new file mode 100755
index 0000000..c31ca7d
--- /dev/null
+++ b/gpr/source/app/gpr_tools/gpr_parse_utils.cpp
@@ -0,0 +1,545 @@
+/*! @file gpr_parse_utils.cpp
+ *
+ * @brief Parsing utilities for gpr_tools
+ *
+ * (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 "gpr_parse_utils.h"
+#include "stdcpp_utils.h"
+
+#include "cJSON.h"
+
+#include "dng_stream.h"
+#include "dng_misc_opcodes.h"
+#include "dng_gain_map.h"
+
+#define MAX_BUF_SIZE 16000
+
+void parse_gps_info( cJSON* pGpsInfo, gpr_gps_info& exif_info )
+{
+ exif_info.gps_info_valid = false;
+}
+
+void parse_exif_info( cJSON* pExifInfo, gpr_exif_info& exif_info )
+{
+ cJSON* pJSON = pExifInfo->child;
+
+ strcpy( exif_info.camera_make, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ strcpy( exif_info.camera_model, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ strcpy( exif_info.camera_serial, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ strcpy( exif_info.software_version, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ strcpy( exif_info.user_comment, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ strcpy( exif_info.image_description, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ exif_info.exposure_time.numerator = pJSON->child->valueint;
+ exif_info.exposure_time.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.f_stop_number.numerator = pJSON->child->valueint;
+ exif_info.f_stop_number.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.aperture.numerator = pJSON->child->valueint;
+ exif_info.aperture.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.exposure_program = (gpr_exposure_program)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.iso_speed_rating = pJSON->valueint;
+ pJSON = pJSON->next;
+
+// strcpy( exif_info.date_time_original, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+// strcpy( exif_info.date_time_digitized, pJSON->valuestring );
+ pJSON = pJSON->next;
+
+ exif_info.exposure_bias.numerator = pJSON->child->valueint;
+ exif_info.exposure_bias.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.light_source = (gpr_light_source)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.flash = (gpr_flash)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.focal_length.numerator = pJSON->child->valueint;
+ exif_info.focal_length.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.sharpness = (gpr_sharpness)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.saturation = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.gain_control = (gpr_gain_control)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.contrast = (gpr_contrast)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.scene_capture_type = (gpr_scene_capture_type)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.exposure_mode = (gpr_exposure_mode)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.focal_length_in_35mm_film = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.digital_zoom.numerator = pJSON->child->valueint;
+ exif_info.digital_zoom.denominator = pJSON->child->next->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.white_balance = (gpr_white_balance)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.scene_type = (gpr_scene_type)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.file_source = (gpr_file_source)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ exif_info.sensing_method = (gpr_sensing_method)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ parse_gps_info( pJSON, exif_info.gps_info );
+}
+
+void parse_profile_info( cJSON* pProfileInfo, gpr_profile_info& profile_info )
+{
+ cJSON* pJSON = pProfileInfo->child;
+
+ profile_info.compute_color_matrix = pJSON->valueint > 0 ? true : false;
+ pJSON = pJSON->next;
+
+ profile_info.matrix_weighting = pJSON->valuedouble;
+ pJSON = pJSON->next;
+
+
+ {
+ cJSON* child = pJSON->child;
+
+ profile_info.wb1[0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.wb1[1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.wb1[2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ profile_info.wb2[0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.wb2[1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.wb2[2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ profile_info.cam_to_srgb_1[0][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[0][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[0][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[1][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[1][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[1][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[2][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[2][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_1[2][2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ profile_info.cam_to_srgb_2[0][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[0][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[0][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[1][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[1][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[1][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[2][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[2][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.cam_to_srgb_2[2][2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ profile_info.color_matrix_1[0][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[0][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[0][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[1][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[1][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[1][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[2][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[2][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_1[2][2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ profile_info.color_matrix_2[0][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[0][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[0][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[1][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[1][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[1][2] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[2][0] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[2][1] = child->valuedouble;
+ child = child->next;
+
+ profile_info.color_matrix_2[2][2] = child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ profile_info.illuminant1 = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ profile_info.illuminant2 = pJSON->valueint;
+}
+
+void parse_tuning_info( cJSON* pTuningInfo, gpr_tuning_info& tuning_info )
+{
+ cJSON* pJSON = pTuningInfo->child;
+
+ tuning_info.orientation = (GPR_ORIENTATION)pJSON->valueint;
+ pJSON = pJSON->next;
+
+ {
+ cJSON* child = pJSON->child;
+ tuning_info.static_black_level.r_black = child->valueint;
+ child = child->next;
+
+ tuning_info.static_black_level.g_r_black = child->valueint;
+ child = child->next;
+
+ tuning_info.static_black_level.g_b_black = child->valueint;
+ child = child->next;
+
+ tuning_info.static_black_level.b_black = child->valueint;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ tuning_info.dgain_saturation_level.level_red = child->valueint;
+ child = child->next;
+
+ tuning_info.dgain_saturation_level.level_green_even = child->valueint;
+ child = child->next;
+
+ tuning_info.dgain_saturation_level.level_green_odd = child->valueint;
+ child = child->next;
+
+ tuning_info.dgain_saturation_level.level_blue = child->valueint;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ tuning_info.wb_gains.r_gain = (float_t)child->valuedouble;
+ child = child->next;
+
+ tuning_info.wb_gains.g_gain = (float_t)child->valuedouble;
+ child = child->next;
+
+ tuning_info.wb_gains.b_gain = (float_t)child->valuedouble;
+
+ pJSON = pJSON->next;
+ }
+
+ {
+ cJSON* child = pJSON->child;
+ tuning_info.ae_info.iso_value = child->valueint;
+ child = child->next;
+
+ tuning_info.ae_info.shutter_time = child->valueint;
+
+ pJSON = pJSON->next;
+ }
+
+ tuning_info.noise_scale = pJSON->valuedouble;
+ pJSON = pJSON->next;
+
+ tuning_info.noise_offset = pJSON->valuedouble;
+ pJSON = pJSON->next;
+
+ tuning_info.warp_red_coefficient = pJSON->valuedouble;
+ pJSON = pJSON->next;
+
+ tuning_info.warp_blue_coefficient = pJSON->valuedouble;
+ pJSON = pJSON->next;
+
+ if( pJSON->child )
+ {
+ cJSON* size = pJSON->child;
+ int buffer_size = size->valueint;
+
+ tuning_info.gain_map.size = buffer_size;
+
+ cJSON* channel = size->next;
+
+ int channel_index = 0;
+ while( channel && channel_index < 4 && buffer_size > 0 )
+ {
+ cJSON* child = channel->child;
+
+ int version = child->valueint;
+ child = child->next;
+
+ int flags = child->valueint;
+ child = child->next;
+
+ int bytes = child->valueint;
+ child = child->next;
+
+ char gain_map_buffer[MAX_BUF_SIZE];
+
+ tuning_info.gain_map.buffers[channel_index] = (char*)malloc( buffer_size );
+
+ dng_stream gain_map_stream ( gain_map_buffer, buffer_size );
+
+ gain_map_stream.Put_uint32( version );
+ gain_map_stream.Put_uint32( flags );
+ gain_map_stream.Put_uint32( bytes );
+
+ {
+ cJSON* _child = child->child;
+ dng_rect rect;
+ rect.t = _child->valueint;
+ _child = _child->next;
+
+ rect.l = _child->valueint;
+ _child = _child->next;
+
+ rect.b = _child->valueint;
+ _child = _child->next;
+
+ rect.r = _child->valueint;
+
+ dng_area_spec area_spec(rect, 0, 1, 2, 2);
+ area_spec.PutData (gain_map_stream);
+
+ child = child->next;
+ }
+
+
+ dng_point points;
+
+ {
+ cJSON* _child = child->child;
+
+ points.h = _child->valueint;
+ _child = _child->next;
+
+ points.v = _child->valueint;
+
+ child = child->next;
+ }
+
+ dng_point_real64 spacing;
+
+ {
+ cJSON* _child = child->child;
+
+ spacing.h = _child->valuedouble;
+ _child = _child->next;
+
+ spacing.v = _child->valuedouble;
+
+ child = child->next;
+ }
+
+ dng_point_real64 origin;
+
+ {
+ cJSON* _child = child->child;
+
+ origin.h = _child->valuedouble;
+ _child = _child->next;
+
+ origin.v = _child->valuedouble;
+
+ child = child->next;
+ }
+
+ dng_gain_map gain_map( gDefaultDNGMemoryAllocator, points, spacing, origin, 1 );
+
+ cJSON* _child = child->child;
+ for (int row = 0; row < points.v; row++)
+ {
+ for (int col = 0; col < points.h; col++)
+ {
+ gain_map.Entry (row, col, 0) = (float_t)_child->valuedouble;
+ _child = _child->next;
+ }
+ }
+
+ gain_map.PutStream( gain_map_stream );
+
+ memcpy( tuning_info.gain_map.buffers[channel_index], gain_map_buffer, buffer_size );
+
+ channel = channel->next;
+
+ channel_index++;
+ }
+ }
+
+ pJSON = pJSON->next;
+
+ tuning_info.pixel_format = (GPR_PIXEL_FORMAT)pJSON->valueint;
+}
+
+int gpr_parameters_parse( gpr_parameters* parameters, const char* input_file_path )
+{
+ gpr_buffer buffer;
+
+ if( read_from_file( &buffer, input_file_path, malloc, free) )
+ {
+ return -2;
+ }
+
+ const char* return_parse_end;
+
+ cJSON* pRoot = cJSON_ParseWithOpts( (const char*)buffer.buffer, &return_parse_end, 0 );
+
+ if( pRoot == NULL )
+ {
+ printf( "Error parsing %s \n", input_file_path );
+ printf( "Error: %s", return_parse_end );
+ return -1;
+ }
+
+ cJSON* pJSON = pRoot->child;
+
+ parameters->input_width = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ parameters->input_height = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ parameters->input_pitch = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ parameters->fast_encoding = pJSON->valueint > 0 ? true : false;
+ pJSON = pJSON->next;
+
+ parameters->gpmf_payload.size = pJSON->valueint;
+ pJSON = pJSON->next;
+
+ parse_exif_info( pJSON, parameters->exif_info );
+ pJSON = pJSON->next;
+
+ parse_profile_info( pJSON, parameters->profile_info );
+ pJSON = pJSON->next;
+
+ parse_tuning_info( pJSON, parameters->tuning_info );
+
+ free( buffer.buffer );
+
+ return 0;
+}