kopia lustrzana https://github.com/gopro/gpr
546 wiersze
16 KiB
C++
Executable File
546 wiersze
16 KiB
C++
Executable File
/*! @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;
|
|
}
|