diff options
Diffstat (limited to 'gpr/source/app/gpr_tools/main_c.c')
-rwxr-xr-x | gpr/source/app/gpr_tools/main_c.c | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/gpr/source/app/gpr_tools/main_c.c b/gpr/source/app/gpr_tools/main_c.c new file mode 100755 index 0000000..0583b01 --- /dev/null +++ b/gpr/source/app/gpr_tools/main_c.c @@ -0,0 +1,346 @@ +/*! @file main_c.c + * + * @brief Implement C conversion routines used by 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 <stdio.h> +#include <string.h> +#include <stdbool.h> + +#include "gpr.h" + +#if defined __GNUC__ +#define stricmp strcasecmp +#else +#endif // if defined __GNUC__ + +#include "main_c.h" +#include "gpr_parse_utils.h" +#include "gpr_print_utils.h" + +#if GPR_JPEG_AVAILABLE +#include "jpeg.h" +#endif + +#define MAX_FILE_PATH 256 + +typedef enum +{ + FILE_TYPE_UNKNOWN = -1, + + FILE_TYPE_RAW, + FILE_TYPE_GPR, + FILE_TYPE_DNG, + FILE_TYPE_PPM, + FILE_TYPE_JPG, + + FILE_TYPE_COUNT, + +} FILE_TYPE; + +static FILE_TYPE GetFileType( const char* file_path ) +{ + const char *extension = NULL; + + if (file_path == NULL) { + return FILE_TYPE_UNKNOWN; + } + + // Get the pathname extension + extension = strrchr(file_path, '.'); + if (extension == NULL) + { + return FILE_TYPE_UNKNOWN; + } + + if (stricmp(extension, ".raw") == 0 || stricmp(extension, ".RAW") == 0) + { + return FILE_TYPE_RAW; + } + + if (stricmp(extension, ".gpr") == 0 || stricmp(extension, ".GPR") == 0) + { + return FILE_TYPE_GPR; + } + + if (stricmp(extension, ".dng") == 0 || stricmp(extension, ".DNG") == 0 ) + { + return FILE_TYPE_DNG; + } + + if (stricmp(extension, ".ppm") == 0 || stricmp(extension, ".PPM") == 0) + { + return FILE_TYPE_PPM; + } + + if (stricmp(extension, ".jpg") == 0 || stricmp(extension, ".JPG") == 0) + { + return FILE_TYPE_JPG; + } + + return FILE_TYPE_UNKNOWN; +} + +int dng_convert_main(const char* input_file_path, unsigned int input_width, unsigned int input_height, size_t input_pitch, size_t input_skip_rows, const char* input_pixel_format, + const char* output_file_path, const char* metadata_file_path, const char* gpmf_file_path, const char* rgb_file_resolution, int rgb_file_bits, + const char* jpg_preview_file_path, int jpg_preview_file_width, int jpg_preview_file_height ) +{ + bool success; + bool write_buffer_to_file = true; + + FILE_TYPE input_file_type = GetFileType( input_file_path ); + FILE_TYPE output_file_type = GetFileType( output_file_path ); + + if( input_file_type == FILE_TYPE_UNKNOWN ) + { + printf( "Unsupported input file type" ); + return -1; + } + + if( output_file_type == FILE_TYPE_UNKNOWN ) + { + printf( "Unsupported output file type" ); + return -1; + } + + gpr_allocator allocator; + allocator.Alloc = malloc; + allocator.Free = free; + + gpr_parameters params; + gpr_parameters_set_defaults(¶ms); + + gpr_buffer input_buffer = { NULL, 0 }; + + if( read_from_file( &input_buffer, input_file_path, allocator.Alloc, allocator.Free ) != 0 ) + { + return -1; + } + + if( metadata_file_path && strcmp(metadata_file_path, "") ) + { + if( gpr_parameters_parse( ¶ms, metadata_file_path ) != 0 ) + return -1; + } + else if( input_file_type == FILE_TYPE_GPR || input_file_type == FILE_TYPE_DNG ) + { + gpr_parse_metadata( &allocator, &input_buffer, ¶ms ); + } + else + { + params.input_width = input_width; + params.input_height = input_height; + params.input_pitch = input_pitch; + + int32_t saturation_level = params.tuning_info.dgain_saturation_level.level_red; + + if( output_file_type == FILE_TYPE_GPR ) + saturation_level = (1 << 14) - 1; + else if( output_file_type == FILE_TYPE_DNG ) + saturation_level = (1 << 12) - 1; + + if( strcmp(input_pixel_format, "rggb12") == 0 ) + { + params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_12; + + if( input_pitch == -1 ) + input_pitch = input_width * 2; + } + if( strcmp(input_pixel_format, "rggb12p") == 0 ) + { + params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_12P; + + if( input_pitch == -1 ) + input_pitch = (input_width * 3 / 4) * 2; + } + else if( strcmp(input_pixel_format, "rggb14") == 0 ) + { + params.tuning_info.pixel_format = PIXEL_FORMAT_RGGB_14; + + saturation_level = (1 << 14) - 1; + + if( input_pitch == -1 ) + input_pitch = input_width * 2; + } + else if( strcmp(input_pixel_format, "gbrg12") == 0 ) + { + params.tuning_info.pixel_format = PIXEL_FORMAT_GBRG_12; + + if( input_pitch == -1 ) + input_pitch = input_width * 2; + } + else if( strcmp(input_pixel_format, "gbrg12p") == 0 ) + { + params.tuning_info.pixel_format = PIXEL_FORMAT_GBRG_12P; + + if( input_pitch == -1 ) + input_pitch = (input_width * 3 / 4) * 2; + } + + params.tuning_info.dgain_saturation_level.level_red = saturation_level; + params.tuning_info.dgain_saturation_level.level_green_even = saturation_level; + params.tuning_info.dgain_saturation_level.level_green_odd = saturation_level; + params.tuning_info.dgain_saturation_level.level_blue = saturation_level; + } + + if( gpmf_file_path != NULL && strcmp(gpmf_file_path, "") ) + { + read_from_file( ¶ms.gpmf_payload, gpmf_file_path, allocator.Alloc, allocator.Free ); + } + + gpr_buffer output_buffer = { NULL, 0 }; + + if( input_skip_rows > 0 ) + { + input_buffer.buffer = (unsigned char*)(input_buffer.buffer) + (input_skip_rows * input_pitch); + } + + gpr_buffer preview = { NULL, 0 }; + + if( strcmp(jpg_preview_file_path, "") != 0 ) + { + if( read_from_file( &preview, jpg_preview_file_path, allocator.Alloc, allocator.Free) == 0 ) + { + params.preview_image.jpg_preview = preview; + params.preview_image.preview_width = jpg_preview_file_width; + params.preview_image.preview_height = jpg_preview_file_height; + } + } + + if( input_file_type == FILE_TYPE_RAW && output_file_type == FILE_TYPE_DNG ) + { + success = gpr_convert_raw_to_dng( &allocator, ¶ms, &input_buffer, &output_buffer ); + } + else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_RAW ) + { + success = gpr_convert_dng_to_raw( &allocator, &input_buffer, &output_buffer ); + } + else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_DNG ) + { + success = gpr_convert_dng_to_dng( &allocator, ¶ms, &input_buffer, &output_buffer ); + } +#if GPR_WRITING + else if( input_file_type == FILE_TYPE_DNG && output_file_type == FILE_TYPE_GPR ) + { + success = gpr_convert_dng_to_gpr( &allocator, ¶ms, &input_buffer, &output_buffer ); + } + else if( input_file_type == FILE_TYPE_RAW && output_file_type == FILE_TYPE_GPR ) + { + success = gpr_convert_raw_to_gpr( &allocator, ¶ms, &input_buffer, &output_buffer ); + } +#endif +#if GPR_READING + else if( input_file_type == FILE_TYPE_GPR && ( output_file_type == FILE_TYPE_PPM || output_file_type == FILE_TYPE_JPG ) ) + { + gpr_rgb_buffer rgb_buffer = { NULL, 0, 0, 0 }; + + GPR_RGB_RESOLUTION rgb_resolution = GPR_RGB_RESOLUTION_DEFAULT; + + if( strcmp(rgb_file_resolution, "1:1") == 0 ) + rgb_resolution = GPR_RGB_RESOLUTION_FULL; + else if( strcmp(rgb_file_resolution, "2:1") == 0 ) + rgb_resolution = GPR_RGB_RESOLUTION_HALF; + else if( strcmp(rgb_file_resolution, "4:1") == 0 ) + rgb_resolution = GPR_RGB_RESOLUTION_QUARTER; + else if( strcmp(rgb_file_resolution, "8:1") == 0 ) + rgb_resolution = GPR_RGB_RESOLUTION_EIGHTH; + else if( strcmp(rgb_file_resolution, "16:1") == 0 ) + rgb_resolution = GPR_RGB_RESOLUTION_SIXTEENTH; + + if( output_file_type == FILE_TYPE_JPG && rgb_file_bits == 16 ) + { + printf( "Asked to output 16-bits RGB, but that is only possible in PPM format.\n"); + rgb_file_bits = 8; + } + + success = gpr_convert_gpr_to_rgb( &allocator, rgb_resolution, rgb_file_bits, &input_buffer, &rgb_buffer ); + + if( output_file_type == FILE_TYPE_PPM ) + { +#define PPM_HEADER_SIZE 100 + char header_text[PPM_HEADER_SIZE]; + + if( rgb_file_bits == 8 ) + { + // 8 bits + sprintf( header_text, "P6\n%ld %ld\n255\n", rgb_buffer.width, rgb_buffer.height ); + } + else + { + // 16 bits + sprintf( header_text, "P6\n%ld %ld\n65535\n", rgb_buffer.width, rgb_buffer.height ); + } + + output_buffer.size = rgb_buffer.size + strlen( header_text ); + output_buffer.buffer = allocator.Alloc( output_buffer.size ); + char* buffer_c = (char*)output_buffer.buffer; + + memcpy( buffer_c, header_text, strlen( header_text ) ); + memcpy( buffer_c + strlen( header_text ), rgb_buffer.buffer, rgb_buffer.size ); +#undef PPM_HEADER_SIZE + } + else if( output_file_type == FILE_TYPE_JPG ) + { + write_buffer_to_file = false; +#if GPR_JPEG_AVAILABLE + tje_encode_to_file( output_file_path, rgb_buffer.width, rgb_buffer.height, 3, rgb_buffer.buffer ); +#else + printf("JPG writing capability is disabled. You could still write to a PPM file"); +#endif + } + + allocator.Free( rgb_buffer.buffer ); + } + else if( input_file_type == FILE_TYPE_GPR && output_file_type == FILE_TYPE_DNG ) + { + success = gpr_convert_gpr_to_dng( &allocator, ¶ms, &input_buffer, &output_buffer ); + } + else if( input_file_type == FILE_TYPE_GPR && output_file_type == FILE_TYPE_RAW ) + { + success = gpr_convert_gpr_to_raw( &allocator, &input_buffer, &output_buffer ); + } +#endif + else + { + printf( "Unsupported conversion from %s to %s \n", input_file_path, output_file_path ); + return -1; + } + + if( success == 0 ) + { + printf("Conversion failed \n"); + return -1; + } + else if( write_buffer_to_file ) + { + write_to_file( &output_buffer, output_file_path ); + } + + if( input_skip_rows > 0 ) + { + input_buffer.buffer = (unsigned char*)(input_buffer.buffer) - (input_skip_rows * input_pitch); + } + + if( preview.buffer ) + { + allocator.Free( preview.buffer ); + } + + gpr_parameters_destroy(¶ms, allocator.Free); + + return 0; +} + |