summaryrefslogtreecommitdiff
path: root/gpr/source/lib/gpr_sdk
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2023-06-15 15:58:59 -0500
committerluxagraf <sng@luxagraf.net>2023-06-15 15:58:59 -0500
commitab987e10f154f5536bb8fd936ae0966e909fa969 (patch)
tree9de5076f38b71ececb1bc94f8d9d19170898d603 /gpr/source/lib/gpr_sdk
added all my scriptssynced/master
Diffstat (limited to 'gpr/source/lib/gpr_sdk')
-rw-r--r--gpr/source/lib/gpr_sdk/CMakeLists.txt44
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr.cpp1849
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_exif_info.cpp105
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_image_writer.cpp129
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_image_writer.h87
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_profile_info.cpp57
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_read_image.cpp129
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_read_image.h64
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_tuning_info.cpp84
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_utils.cpp73
-rwxr-xr-xgpr/source/lib/gpr_sdk/private/gpr_utils.h40
-rwxr-xr-xgpr/source/lib/gpr_sdk/public/gpr.h169
-rwxr-xr-xgpr/source/lib/gpr_sdk/public/gpr_exif_info.h352
-rwxr-xr-xgpr/source/lib/gpr_sdk/public/gpr_profile_info.h60
-rwxr-xr-xgpr/source/lib/gpr_sdk/public/gpr_tuning_info.h149
15 files changed, 3391 insertions, 0 deletions
diff --git a/gpr/source/lib/gpr_sdk/CMakeLists.txt b/gpr/source/lib/gpr_sdk/CMakeLists.txt
new file mode 100644
index 0000000..9ce99c4
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/CMakeLists.txt
@@ -0,0 +1,44 @@
+# library
+set( LIB_NAME gpr_sdk )
+
+# get source files
+file( GLOB SRC_FILES "private/*.cpp" "public/*.cpp" )
+
+# get include files
+file( GLOB INC_FILES "private/*.h" "public/*.h" )
+
+# add include files from other folders
+include_directories( "./public" )
+include_directories( "../common/private" )
+include_directories( "../common/public" )
+include_directories( "../dng_sdk" )
+include_directories( "../vc5_common" )
+
+if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
+ include_directories( "../vc5_decoder" )
+ add_definitions("-DGPR_READING=1")
+else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
+ add_definitions("-DGPR_READING=0")
+endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_decoder")
+
+if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
+ include_directories( "../vc5_encoder" )
+ add_definitions("-DGPR_WRITING=1")
+else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
+ add_definitions("-DGPR_WRITING=0")
+endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/vc5_encoder")
+
+if(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
+ include_directories( "../tiny_jpeg" )
+ add_definitions("-DGPR_JPEG_AVAILABLE=1")
+else(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
+ add_definitions("-DGPR_JPEG_AVAILABLE=0")
+endif(EXISTS "${CMAKE_SOURCE_DIR}/source/lib/tiny_jpeg")
+
+# library
+add_library( ${LIB_NAME} STATIC ${SRC_FILES} ${INC_FILES} )
+
+target_link_libraries( ${LIB_NAME} )
+
+# set the folder where to place the projects
+set_target_properties( ${LIB_NAME} PROPERTIES FOLDER lib )
diff --git a/gpr/source/lib/gpr_sdk/private/gpr.cpp b/gpr/source/lib/gpr_sdk/private/gpr.cpp
new file mode 100755
index 0000000..516c0f5
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr.cpp
@@ -0,0 +1,1849 @@
+/*! @file gpr.c
+ *
+ * @brief Implementation of top level functions that implement GPR-SDK API
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.h"
+
+#include "dng_camera_profile.h"
+#include "dng_color_space.h"
+#include "dng_date_time.h"
+#include "dng_exceptions.h"
+#include "dng_file_stream.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_ifd.h"
+#include "dng_image_writer.h"
+#include "dng_info.h"
+#include "dng_linearization_info.h"
+#include "dng_mosaic_info.h"
+#include "dng_negative.h"
+#include "dng_preview.h"
+#include "dng_render.h"
+#include "dng_simple_image.h"
+#include "dng_tag_codes.h"
+#include "dng_tag_types.h"
+#include "dng_tag_values.h"
+#include "dng_xmp.h"
+#include "dng_xmp_sdk.h"
+#include "dng_memory_stream.h"
+#include "dng_bottlenecks.h"
+
+#include "dng_misc_opcodes.h"
+#include "dng_gain_map.h"
+#include "dng_lens_correction.h"
+
+#include "gpr_utils.h"
+
+#include "macros.h"
+#include "gpr_buffer.h"
+#include "gpr_buffer_auto.h"
+
+#if GPR_READING
+#include "vc5_decoder.h"
+#endif
+
+#if GPR_WRITING
+#include "gpr_image_writer.h"
+#endif
+
+#if GPR_READING
+#include "gpr_read_image.h"
+#endif
+
+#if GPR_JPEG_AVAILABLE
+#include "jpeg.h"
+#endif
+
+extern bool gDNGShowTimers;
+
+#define PRINT_MATRIX 0
+
+// Include logging file (for reporting timing)
+#include "log.h"
+
+void find_rational(float number, float error_tolerance, int* numerator, int* denominator_pow2)
+{
+ int _num;
+ int _den_pow2;
+
+ _den_pow2 = 1;
+
+ while(1)
+ {
+ _num = number * (1 << _den_pow2);
+
+ float error = number - (float)_num / (float)((1 << _den_pow2));
+
+ if( error < error_tolerance )
+ break;
+
+ _den_pow2++;
+ }
+
+ *numerator = _num;
+ *denominator_pow2 = _den_pow2;
+}
+
+static void unpack_pixel_format( const gpr_buffer_auto* input_buffer, const gpr_parameters* convert_params, gpr_buffer_auto* output_buffer )
+{
+ size_t buffer_size = convert_params->input_height * convert_params->input_width * 2;
+ output_buffer->allocate( buffer_size );
+
+ unsigned char* src = input_buffer->to_uchar();
+ uint16_t* dst = output_buffer->to_uint16_t();
+
+ int src_stride = convert_params->input_pitch;
+ int dst_stride = convert_params->input_width;
+
+ for (unsigned int row = 0; row < convert_params->input_height; row++ )
+ {
+ for (unsigned int col = 0; col < (convert_params->input_width / 2); col++ )
+ {
+ unsigned char byte_0 = *(src + col * 3 + 0);
+ unsigned char byte_1 = *(src + col * 3 + 1);
+ unsigned char byte_2 = *(src + col * 3 + 2);
+
+ uint16_t pix1 = (byte_2 << 4) + ((byte_1 & 0xf0) >> 4);
+ uint16_t pix2 = (byte_0) + ((byte_1 & 0x0f) << 8);
+
+ *(dst + col * 2 + 0) = pix2;
+ *(dst + col * 2 + 1) = pix1;
+ }
+
+ src += src_stride;
+ dst += dst_stride;
+ }
+}
+
+#if GPR_WRITING
+static void set_vc5_encoder_parameters( vc5_encoder_parameters& vc5_encoder_params, const gpr_parameters* convert_params )
+{
+ vc5_encoder_params.input_width = convert_params->input_width;
+ vc5_encoder_params.input_height = convert_params->input_height;
+ vc5_encoder_params.input_pitch = convert_params->input_pitch;
+
+ switch ( convert_params->tuning_info.pixel_format )
+ {
+ case PIXEL_FORMAT_RGGB_12:
+ vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_12;
+ break;
+
+ case PIXEL_FORMAT_RGGB_12P:
+ vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_12P;
+ break;
+
+ case PIXEL_FORMAT_RGGB_14:
+ vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_RGGB_14;
+ break;
+
+ case PIXEL_FORMAT_GBRG_12:
+ vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_GBRG_12;
+ break;
+
+ case PIXEL_FORMAT_GBRG_12P:
+ vc5_encoder_params.pixel_format = VC5_ENCODER_PIXEL_FORMAT_GBRG_12P;
+ break;
+
+ default:
+ break;
+ }
+
+ if( convert_params->fast_encoding )
+ vc5_encoder_params.quality_setting = VC5_ENCODER_QUALITY_SETTING_MEDIUM;
+ else
+ vc5_encoder_params.quality_setting = VC5_ENCODER_QUALITY_SETTING_FS1;
+}
+#endif
+
+void gpr_parameters_set_defaults(gpr_parameters* x)
+{
+ memset(x, 0, sizeof(gpr_parameters));
+
+ gpr_exif_info_set_defaults(&x->exif_info);
+ gpr_profile_info_set_defaults(&x->profile_info);
+ gpr_tuning_info_set_defaults(&x->tuning_info);
+
+ x->enable_preview = true;
+
+ x->compute_md5sum = false;
+
+ x->fast_encoding = false;
+}
+
+void gpr_parameters_construct_copy(const gpr_parameters* y, gpr_parameters* x, gpr_malloc mem_alloc)
+{
+ gpr_parameters_set_defaults(x);
+
+ *x = *y;
+
+ if( y->gpmf_payload.size > 0 && y->gpmf_payload.buffer != NULL )
+ {
+ x->gpmf_payload.buffer = mem_alloc( y->gpmf_payload.size );
+ memcpy( x->gpmf_payload.buffer, y->gpmf_payload.buffer, y->gpmf_payload.size );
+ }
+
+ if( y->tuning_info.gain_map.size > 0 )
+ {
+ for ( int i = 0; i < 4; i++)
+ {
+ if( y->tuning_info.gain_map.buffers[i] != 0 )
+ {
+ x->tuning_info.gain_map.buffers[i] = (char*)mem_alloc( y->tuning_info.gain_map.size );
+ memcpy( x->tuning_info.gain_map.buffers[i], y->tuning_info.gain_map.buffers[i], y->tuning_info.gain_map.size );
+ }
+ }
+ }
+}
+
+void gpr_parameters_destroy(gpr_parameters* x, gpr_free mem_free)
+{
+ if( x->gpmf_payload.buffer && x->gpmf_payload.size > 0 )
+ {
+ mem_free( x->gpmf_payload.buffer );
+ }
+
+ if( x->tuning_info.gain_map.size > 0 )
+ {
+ for ( int i = 0; i < 4; i++)
+ {
+ if( x->tuning_info.gain_map.buffers[i] )
+ mem_free( x->tuning_info.gain_map.buffers[i] );
+ }
+ }
+}
+
+
+static dng_srational convert_to_dng_srational(gpr_signed_rational x)
+{
+ return dng_srational(x.numerator, x.denominator);
+}
+
+static dng_urational convert_to_dng_urational(gpr_unsigned_rational x)
+{
+ return dng_urational(x.numerator, x.denominator);
+}
+
+static gpr_unsigned_rational convert_to_unsigned_rational(dng_urational x)
+{
+ gpr_unsigned_rational a;
+ a.numerator = x.n;
+ a.denominator = x.d;
+
+ return a;
+}
+
+static gpr_signed_rational convert_to_signed_rational(dng_srational x)
+{
+ gpr_signed_rational a;
+ a.numerator = x.n;
+ a.denominator = x.d;
+
+ return a;
+}
+
+static dng_date_time convert_to_dng_date_time( const gpr_date_and_time& x )
+{
+ return dng_date_time (x.year, x.month, x.day, x.hour, x.minute, x.second );
+}
+
+static gpr_date_and_time convert_to_dng_date_and_time( const dng_date_time& x )
+{
+ gpr_date_and_time a;
+
+ a.year = x.fYear;
+ a.month = x.fMonth;
+ a.day = x.fDay;
+ a.hour = x.fHour;
+ a.minute = x.fMinute;
+ a.second = x.fSecond;
+
+ return a;
+}
+
+static void convert_dng_exif_info_to_dng_exif( dng_exif* dst_exif, const gpr_exif_info* src_exif )
+{
+ dst_exif->fModel.Set_ASCII( src_exif->camera_model );
+ dst_exif->fMake.Set_ASCII( src_exif->camera_make );
+ dst_exif->fCameraSerialNumber.Set_ASCII( src_exif->camera_serial );
+ dst_exif->fImageDescription.Set_ASCII( src_exif->image_description );
+
+ dst_exif->fApertureValue = convert_to_dng_urational( src_exif->aperture );
+ dst_exif->fMaxApertureValue = convert_to_dng_urational( src_exif->aperture );
+ dst_exif->fFNumber = convert_to_dng_urational( src_exif->f_stop_number );
+ dst_exif->fExposureTime = convert_to_dng_urational( src_exif->exposure_time );
+ dst_exif->fFocalLength = convert_to_dng_urational( src_exif->focal_length );
+ dst_exif->fDigitalZoomRatio = convert_to_dng_urational( src_exif->digital_zoom );
+ dst_exif->fExposureBiasValue = convert_to_dng_srational( src_exif->exposure_bias );
+
+ const int32_t focal_plane = 72;
+ dst_exif->fFocalPlaneXResolution = dng_urational(focal_plane, 1);
+ dst_exif->fFocalPlaneYResolution = dng_urational(focal_plane, 1);
+
+ dst_exif->fMeteringMode = src_exif->metering_mode;
+ dst_exif->fFocalLengthIn35mmFilm = src_exif->focal_length_in_35mm_film;
+ dst_exif->fExposureProgram = src_exif->exposure_program;
+ dst_exif->fLightSource = src_exif->light_source;
+ dst_exif->fFlash = src_exif->flash;
+ dst_exif->fSensingMethod = src_exif->sensing_method;
+ dst_exif->fFileSource = src_exif->file_source;
+ dst_exif->fSceneType = src_exif->scene_type;
+ dst_exif->fWhiteBalance = src_exif->white_balance;
+ dst_exif->fExposureMode = src_exif->exposure_mode;
+ dst_exif->fSceneCaptureType = src_exif->scene_capture_type;
+ dst_exif->fGainControl = src_exif->gain_control;
+ dst_exif->fContrast = src_exif->contrast;
+ dst_exif->fSaturation = src_exif->saturation;
+ dst_exif->fSharpness = src_exif->sharpness;
+
+ dst_exif->fISOSpeedRatings[0] = src_exif->iso_speed_rating;
+
+ dst_exif->fComponentsConfiguration = 0x04050600; //?? - since we're raw?
+
+ dst_exif->fDateTimeOriginal.SetDateTime( convert_to_dng_date_time( src_exif->date_time_original ) );
+ dst_exif->fDateTimeDigitized.SetDateTime( convert_to_dng_date_time( src_exif->date_time_digitized ) );
+
+ dst_exif->fSoftware.Set(src_exif->software_version);
+
+ dst_exif->fUserComment.Set(src_exif->user_comment);
+
+ const gpr_gps_info& src_gps_info = src_exif->gps_info;
+
+ if( src_gps_info.gps_info_valid )
+ {
+ dst_exif->fGPSVersionID = src_gps_info.version_id;
+
+ dst_exif->fGPSLatitudeRef.Set( src_gps_info.latitude_ref );
+
+ dst_exif->fGPSLatitude[0] = convert_to_dng_urational( src_gps_info.latitude[0] );
+ dst_exif->fGPSLatitude[1] = convert_to_dng_urational( src_gps_info.latitude[1] );
+ dst_exif->fGPSLatitude[2] = convert_to_dng_urational( src_gps_info.latitude[2] );
+
+ dst_exif->fGPSLongitudeRef.Set( src_gps_info.longitude_ref );
+
+ dst_exif->fGPSLongitude[0] = convert_to_dng_urational( src_gps_info.longitude[0] );
+ dst_exif->fGPSLongitude[1] = convert_to_dng_urational( src_gps_info.longitude[1] );
+ dst_exif->fGPSLongitude[2] = convert_to_dng_urational( src_gps_info.longitude[2] );
+
+ dst_exif->fGPSAltitudeRef = src_gps_info.altitude_ref;
+
+ dst_exif->fGPSAltitude = convert_to_dng_urational( src_gps_info.altitude );
+
+ dst_exif->fGPSTimeStamp[0] = convert_to_dng_urational( src_gps_info.time_stamp[0] );
+ dst_exif->fGPSTimeStamp[1] = convert_to_dng_urational( src_gps_info.time_stamp[1] );
+ dst_exif->fGPSTimeStamp[2] = convert_to_dng_urational( src_gps_info.time_stamp[2] );
+
+ dst_exif->fGPSSatellites.Set( src_gps_info.satellites );
+
+ dst_exif->fGPSStatus.Set( src_gps_info.status );
+
+ dst_exif->fGPSMeasureMode.Set( src_gps_info.measure_mode );
+
+ dst_exif->fGPSDOP = convert_to_dng_urational( src_gps_info.dop );
+
+ dst_exif->fGPSSpeedRef.Set( src_gps_info.speed_ref );
+
+ dst_exif->fGPSSpeed = convert_to_dng_urational( src_gps_info.speed );
+
+ dst_exif->fGPSTrackRef.Set( src_gps_info.track_ref );
+
+ dst_exif->fGPSTrack = convert_to_dng_urational( src_gps_info.track );
+
+ dst_exif->fGPSImgDirectionRef.Set( src_gps_info.img_direction_ref );
+
+ dst_exif->fGPSImgDirection = convert_to_dng_urational( src_gps_info.img_direction );
+
+ dst_exif->fGPSMapDatum.Set( src_gps_info.map_datum );
+
+ dst_exif->fGPSDestLatitudeRef.Set( src_gps_info.dest_latitude_ref );
+
+ dst_exif->fGPSDestLatitude[0] = convert_to_dng_urational( src_gps_info.dest_latitude[0] );
+ dst_exif->fGPSDestLatitude[1] = convert_to_dng_urational( src_gps_info.dest_latitude[1] );
+ dst_exif->fGPSDestLatitude[2] = convert_to_dng_urational( src_gps_info.dest_latitude[2] );
+
+ dst_exif->fGPSDestLongitudeRef.Set( src_gps_info.dest_longitude_ref );
+
+ dst_exif->fGPSDestLongitude[0] = convert_to_dng_urational( src_gps_info.dest_longitude[0] );
+ dst_exif->fGPSDestLongitude[1] = convert_to_dng_urational( src_gps_info.dest_longitude[1] );
+ dst_exif->fGPSDestLongitude[2] = convert_to_dng_urational( src_gps_info.dest_longitude[2] );
+
+ dst_exif->fGPSDestBearingRef.Set( src_gps_info.dest_bearing_ref );
+
+ dst_exif->fGPSDestBearing = convert_to_dng_urational( src_gps_info.dest_bearing );
+
+ dst_exif->fGPSDestDistanceRef.Set( src_gps_info.dest_distance_ref );
+
+ dst_exif->fGPSDestDistance = convert_to_dng_urational( src_gps_info.dest_distance );
+
+ dst_exif->fGPSProcessingMethod.Set( src_gps_info.processing_method );
+
+ dst_exif->fGPSAreaInformation.Set( src_gps_info.area_information );
+
+ dst_exif->fGPSDateStamp.Set( src_gps_info.date_stamp );
+
+ dst_exif->fGPSDifferential = src_gps_info.differential;
+ }
+}
+
+static void convert_dng_exif_to_dng_exif_info( gpr_exif_info* dst_exif, const dng_exif* src_exif )
+{
+ assert(src_exif->fModel.Length() < sizeof(dst_exif->camera_model));
+ strcpy( dst_exif->camera_model, src_exif->fModel.Get() );
+
+ assert(src_exif->fMake.Length() < sizeof(dst_exif->camera_make));
+ strcpy( dst_exif->camera_make, src_exif->fMake.Get() );
+
+ assert(src_exif->fCameraSerialNumber.Length() < sizeof(dst_exif->camera_serial));
+ strcpy( dst_exif->camera_serial, src_exif->fCameraSerialNumber.Get() );
+
+ assert(src_exif->fImageDescription.Length() < sizeof(dst_exif->image_description));
+ strcpy( dst_exif->image_description, src_exif->fImageDescription.Get() );
+
+ dst_exif->aperture = convert_to_unsigned_rational( src_exif->fMaxApertureValue );
+ dst_exif->f_stop_number = convert_to_unsigned_rational( src_exif->fFNumber );
+ dst_exif->exposure_time = convert_to_unsigned_rational( src_exif->fExposureTime );
+ dst_exif->focal_length = convert_to_unsigned_rational( src_exif->fFocalLength );
+ dst_exif->digital_zoom = convert_to_unsigned_rational( src_exif->fDigitalZoomRatio );
+ dst_exif->exposure_bias = convert_to_signed_rational( src_exif->fExposureBiasValue );
+
+ dst_exif->metering_mode = (gpr_metering_mode)src_exif->fMeteringMode;
+ dst_exif->focal_length_in_35mm_film = src_exif->fFocalLengthIn35mmFilm;
+ dst_exif->exposure_program = (gpr_exposure_program)src_exif->fExposureProgram;
+ dst_exif->light_source = (gpr_light_source)src_exif->fLightSource;
+ dst_exif->flash = (gpr_flash)src_exif->fFlash;
+ dst_exif->sensing_method = (gpr_sensing_method)src_exif->fSensingMethod;
+ dst_exif->file_source = (gpr_file_source)src_exif->fFileSource;
+ dst_exif->scene_type = (gpr_scene_type)src_exif->fSceneType;
+ dst_exif->white_balance = (gpr_white_balance)src_exif->fWhiteBalance;
+ dst_exif->exposure_mode = (gpr_exposure_mode)src_exif->fExposureMode;
+ dst_exif->scene_capture_type = (gpr_scene_capture_type)src_exif->fSceneCaptureType;
+ dst_exif->gain_control = (gpr_gain_control)src_exif->fGainControl;
+ dst_exif->contrast = (gpr_contrast)src_exif->fContrast;
+ dst_exif->saturation = src_exif->fSaturation;
+ dst_exif->sharpness = (gpr_sharpness)src_exif->fSharpness;
+
+ dst_exif->iso_speed_rating = src_exif->fISOSpeedRatings[0];
+
+ dst_exif->date_time_original = convert_to_dng_date_and_time( src_exif->fDateTimeOriginal.DateTime() );
+ dst_exif->date_time_digitized = convert_to_dng_date_and_time( src_exif->fDateTimeOriginal.DateTime() );
+
+ assert(src_exif->fSoftware.Length() < sizeof(dst_exif->software_version));
+ memcpy( dst_exif->software_version, src_exif->fSoftware.Get(), src_exif->fSoftware.Length() );
+
+ assert(src_exif->fUserComment.Length() < sizeof(dst_exif->user_comment));
+ memcpy( dst_exif->user_comment, src_exif->fUserComment.Get(), src_exif->fUserComment.Length() );
+
+ // GPS Info
+ gpr_gps_info& dst_gps_info = dst_exif->gps_info;
+
+ dst_gps_info.version_id = src_exif->fGPSVersionID;
+
+ dst_gps_info.gps_info_valid = dst_gps_info.version_id > 0;
+
+ strcpy( dst_gps_info.latitude_ref, src_exif->fGPSLatitudeRef.Get() );
+
+ dst_gps_info.latitude[0] = convert_to_unsigned_rational( src_exif->fGPSLatitude[0] );
+ dst_gps_info.latitude[1] = convert_to_unsigned_rational( src_exif->fGPSLatitude[1] );
+ dst_gps_info.latitude[2] = convert_to_unsigned_rational( src_exif->fGPSLatitude[2] );
+
+ strcpy( dst_gps_info.longitude_ref, src_exif->fGPSLongitudeRef.Get() );
+
+ dst_gps_info.longitude[0] = convert_to_unsigned_rational( src_exif->fGPSLongitude[0] );
+ dst_gps_info.longitude[1] = convert_to_unsigned_rational( src_exif->fGPSLongitude[1] );
+ dst_gps_info.longitude[2] = convert_to_unsigned_rational( src_exif->fGPSLongitude[2] );
+
+ dst_gps_info.altitude_ref = src_exif->fGPSAltitudeRef;
+
+ dst_gps_info.altitude = convert_to_unsigned_rational( src_exif->fGPSAltitude );
+
+ dst_gps_info.time_stamp[0] = convert_to_unsigned_rational( src_exif->fGPSTimeStamp[0] );
+ dst_gps_info.time_stamp[1] = convert_to_unsigned_rational( src_exif->fGPSTimeStamp[1] );
+ dst_gps_info.time_stamp[2] = convert_to_unsigned_rational( src_exif->fGPSTimeStamp[2] );
+
+ strcpy( dst_gps_info.satellites, src_exif->fGPSSatellites.Get() );
+
+ strcpy( dst_gps_info.status, src_exif->fGPSStatus.Get() );
+
+ strcpy( dst_gps_info.measure_mode, src_exif->fGPSMeasureMode.Get() );
+
+ dst_gps_info.dop = convert_to_unsigned_rational( src_exif->fGPSDOP );
+
+ strcpy( dst_gps_info.speed_ref, src_exif->fGPSSpeedRef.Get() );
+
+ dst_gps_info.speed = convert_to_unsigned_rational( src_exif->fGPSSpeed );
+
+ strcpy( dst_gps_info.track_ref, src_exif->fGPSTrackRef.Get() );
+
+ dst_gps_info.track = convert_to_unsigned_rational( src_exif->fGPSTrack );
+
+ strcpy( dst_gps_info.img_direction_ref, src_exif->fGPSImgDirectionRef.Get() );
+
+ dst_gps_info.img_direction = convert_to_unsigned_rational( src_exif->fGPSImgDirection );
+
+ strcpy( dst_gps_info.map_datum, src_exif->fGPSMapDatum.Get() );
+
+ strcpy( dst_gps_info.dest_latitude_ref, src_exif->fGPSDestLatitudeRef.Get() );
+
+ dst_gps_info.dest_latitude[0] = convert_to_unsigned_rational( src_exif->fGPSDestLatitude[0] );
+ dst_gps_info.dest_latitude[1] = convert_to_unsigned_rational( src_exif->fGPSDestLatitude[1] );
+ dst_gps_info.dest_latitude[2] = convert_to_unsigned_rational( src_exif->fGPSDestLatitude[2] );
+
+ strcpy( dst_gps_info.dest_longitude_ref, src_exif->fGPSDestLongitudeRef.Get() );
+
+ dst_gps_info.dest_longitude[0] = convert_to_unsigned_rational( src_exif->fGPSDestLongitude[0] );
+ dst_gps_info.dest_longitude[1] = convert_to_unsigned_rational( src_exif->fGPSDestLongitude[1] );
+ dst_gps_info.dest_longitude[2] = convert_to_unsigned_rational( src_exif->fGPSDestLongitude[2] );
+
+ strcpy( dst_gps_info.dest_bearing_ref, src_exif->fGPSDestBearingRef.Get() );
+
+ dst_gps_info.dest_bearing = convert_to_unsigned_rational( src_exif->fGPSDestBearing );
+
+ strcpy( dst_gps_info.dest_distance_ref, src_exif->fGPSDestDistanceRef.Get() );
+
+ dst_gps_info.dest_distance = convert_to_unsigned_rational( src_exif->fGPSDestDistance );
+
+ strcpy( dst_gps_info.processing_method, src_exif->fGPSProcessingMethod.Get() );
+
+ strcpy( dst_gps_info.area_information, src_exif->fGPSAreaInformation.Get() );
+
+ strcpy( dst_gps_info.date_stamp, src_exif->fGPSDateStamp.Get() );
+
+ dst_gps_info.differential = src_exif->fGPSDifferential;
+}
+
+
+#define MAX_BUF_SIZE 16000
+
+static char _warp_rect_buffer [256];
+
+static bool read_dng(const gpr_allocator* allocator,
+ dng_stream* dng_read_stream,
+ gpr_buffer_auto* raw_image_buffer,
+ gpr_buffer_auto* vc5_image_buffer,
+ gpr_parameters* convert_params = NULL,
+ bool* is_vc5_format = NULL )
+{
+ dng_host host;
+
+ gpr_buffer_auto vc5_image_obj( allocator->Alloc, allocator->Free );
+
+ static uint32 gPreferredSize = 0;
+ static uint32 gMinimumSize = 0;
+ static uint32 gMaximumSize = 0;
+
+ static dng_string gDumpDNG;
+
+ host.SetPreferredSize (gPreferredSize);
+ host.SetMinimumSize (gMinimumSize );
+ host.SetMaximumSize (gMaximumSize );
+
+ host.ValidateSizes ();
+
+ host.SetSaveDNGVersion (dngVersion_SaveDefault);
+
+ host.SetSaveLinearDNG (false);
+
+ host.SetKeepOriginalFile (false);
+
+ AutoPtr<dng_negative> negative;
+
+ if( raw_image_buffer != NULL && vc5_image_buffer == NULL )
+ {
+ vc5_image_buffer = &vc5_image_obj;
+ }
+
+ {
+ dng_info info;
+
+ info.Parse (host, *dng_read_stream);
+
+ info.PostParse (host);
+
+ if (!info.IsValidDNG ())
+ {
+ return false;
+ }
+
+ dng_memory_block* gpmf_payload = host.GetGPMFPayload().Get();
+
+ if( gpmf_payload && gpmf_payload->LogicalSize() > 0 )
+ {
+ if( convert_params != NULL && convert_params->gpmf_payload.buffer == NULL && convert_params->gpmf_payload.size == 0 )
+ {
+ convert_params->gpmf_payload.size = gpmf_payload->LogicalSize();
+ convert_params->gpmf_payload.buffer = allocator->Alloc( convert_params->gpmf_payload.size );
+
+ memcpy( convert_params->gpmf_payload.buffer, gpmf_payload->Buffer(), convert_params->gpmf_payload.size );
+ }
+ }
+
+ negative.Reset (host.Make_dng_negative ());
+
+ negative->Parse (host, *dng_read_stream, info);
+
+ negative->PostParse (host, *dng_read_stream, info);
+
+#if GPR_READING
+ if( negative->IsVc5Image( info ) )
+ {
+ gpr_read_image reader( vc5_image_buffer );
+
+ if( vc5_image_buffer == NULL )
+ {
+ reader.SetReadVC5(false);
+ }
+
+ if( raw_image_buffer == NULL )
+ {
+ reader.SetDecodeVC5(false);
+ }
+
+ negative->ReadVc5Image(host, *dng_read_stream, info, reader);
+
+ dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get ();
+
+ if (rawIFD.fOpcodeList2Count)
+ {
+ negative->OpcodeList2().Parse (host, *dng_read_stream, rawIFD.fOpcodeList2Count, rawIFD.fOpcodeList2Offset);
+ }
+
+ if (rawIFD.fOpcodeList3Count)
+ {
+ negative->OpcodeList3().Parse (host, *dng_read_stream, rawIFD.fOpcodeList3Count, rawIFD.fOpcodeList3Offset);
+ }
+
+ if( is_vc5_format )
+ *is_vc5_format = true;
+ }
+ else
+#endif
+ {
+ negative->ReadStage1Image (host, *dng_read_stream, info);
+
+ if( is_vc5_format )
+ *is_vc5_format = false;
+ }
+
+ const dng_image& raw_image = negative->RawImage();
+
+ if( convert_params )
+ {
+ dng_rect bounds = raw_image.Bounds();
+ int i,j;
+
+ convert_params->input_width = bounds.W();
+ convert_params->input_height = bounds.H();
+ convert_params->input_pitch = convert_params->input_width * 2;
+
+ // Copy ColorMatrix1, ColorMatrix2
+ {
+ const dng_camera_profile &profile_info = negative->ProfileByIndex( 0 );
+ const dng_matrix &m1 = profile_info.ColorMatrix1();
+ const dng_matrix &m2 = profile_info.ColorMatrix2();
+
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ {
+ convert_params->profile_info.color_matrix_1[i][j] = m1[i][j];
+ convert_params->profile_info.color_matrix_2[i][j] = m2[i][j];
+ }
+ }
+
+ convert_params->profile_info.compute_color_matrix = false;
+ convert_params->profile_info.matrix_weighting = 1.0;
+
+ memset( convert_params->profile_info.wb1, 0, sizeof(convert_params->profile_info.wb1) );
+ memset( convert_params->profile_info.wb2, 0, sizeof(convert_params->profile_info.wb2) );
+
+ memset( convert_params->profile_info.cam_to_srgb_1, 0, sizeof(convert_params->profile_info.cam_to_srgb_1) );
+ memset( convert_params->profile_info.cam_to_srgb_2, 0, sizeof(convert_params->profile_info.cam_to_srgb_2) );
+ }
+
+ // Set Exif Info
+ convert_dng_exif_to_dng_exif_info( &convert_params->exif_info, negative->GetExif() );
+
+ // Set Tuning Info
+ {
+ gpr_tuning_info& tuning_info = convert_params->tuning_info;
+
+ tuning_info.orientation = (GPR_ORIENTATION)negative->BaseOrientation().GetAdobe();
+
+ if( negative->HasCameraNeutral() )
+ {
+ const dng_vector& camNeutral = negative->CameraNeutral();
+
+ tuning_info.wb_gains.r_gain = 1 / camNeutral[0];
+ tuning_info.wb_gains.g_gain = 1 / camNeutral[1];
+ tuning_info.wb_gains.b_gain = 1 / camNeutral[2];
+ }
+
+ const dng_linearization_info& linearization_info = *negative->GetLinearizationInfo();
+
+ {
+ gpr_static_black_level& static_black_level = tuning_info.static_black_level;
+
+ static_black_level.r_black = linearization_info.fBlackLevel[0][0][0];
+ static_black_level.g_r_black = linearization_info.fBlackLevel[0][1][0];
+ static_black_level.g_b_black = linearization_info.fBlackLevel[1][0][0];
+ static_black_level.b_black = linearization_info.fBlackLevel[1][1][0];
+ }
+
+ {
+ gpr_saturation_level& dgain_saturation_level = tuning_info.dgain_saturation_level;
+
+ dgain_saturation_level.level_red = linearization_info.fWhiteLevel[0];
+ dgain_saturation_level.level_green_even = dgain_saturation_level.level_red;
+ dgain_saturation_level.level_green_odd = dgain_saturation_level.level_red;
+ dgain_saturation_level.level_blue = dgain_saturation_level.level_red;
+ }
+
+ {
+ dng_ifd &rawIFD = *info.fIFD [info.fMainIndex].Get ();
+
+ gpr_saturation_level& dgain_saturation_level = tuning_info.dgain_saturation_level;
+
+ bool rggb_raw = (rawIFD.fCFAPattern[0][0] == 0) && (rawIFD.fCFAPattern[0][1] == 1) && (rawIFD.fCFAPattern[1][0] == 1) && (rawIFD.fCFAPattern[1][1] == 2);
+
+ if( rggb_raw )
+ {
+ if( dgain_saturation_level.level_red == 4095 &&
+ dgain_saturation_level.level_green_even == 4095 &&
+ dgain_saturation_level.level_green_odd == 4095 &&
+ dgain_saturation_level.level_blue == 4095 )
+ {
+ tuning_info.pixel_format = PIXEL_FORMAT_RGGB_12;
+ }
+ else if(dgain_saturation_level.level_red == 16383 &&
+ dgain_saturation_level.level_green_even == 16383 &&
+ dgain_saturation_level.level_green_odd == 16383 &&
+ dgain_saturation_level.level_blue == 16383 )
+ {
+ tuning_info.pixel_format = PIXEL_FORMAT_RGGB_14;
+ }
+ else
+ {
+ assert(0);
+ return false;
+ }
+ }
+ else
+ {
+ if( dgain_saturation_level.level_red == 4095 &&
+ dgain_saturation_level.level_green_even == 4095 &&
+ dgain_saturation_level.level_green_odd == 4095 &&
+ dgain_saturation_level.level_blue == 4095 )
+ {
+ tuning_info.pixel_format = PIXEL_FORMAT_GBRG_12;
+ }
+ else
+ {
+ assert(0);
+ return false;
+ }
+
+
+ }
+ }
+
+ // Noise profile
+ if ( negative->HasNoiseProfile() )
+ {
+ dng_noise_profile noise_profile = negative->NoiseProfile();
+
+ dng_noise_function noise_function = noise_profile.NoiseFunction (0);
+
+ tuning_info.noise_scale = noise_function.Scale();
+ tuning_info.noise_offset = noise_function.Offset();
+ //LogPrint( "Noise profile s = %f, o = %f ", tuning_info.noise_scale, tuning_info.noise_offset );
+ }
+
+ // GainMap
+ dng_opcode_list &opcodelist2 = negative->OpcodeList2 ();
+ uint32_t count = opcodelist2.Count ();
+ // Note: this code will have to get smarter if we ever have anything other than four GainMap tags in OpcodeList2
+ if ( count == 4 && tuning_info.gain_map.size == 0 )
+ {
+ char gainmap_buffer [4][MAX_BUF_SIZE];
+
+ for ( int i = 0; i < 4; i++ )
+ {
+ // Get GainMap Opcode
+ dng_opcode &opcode = opcodelist2.Entry( i );
+
+ // generate stream data
+ dng_stream stream ( gainmap_buffer[i], MAX_BUF_SIZE );
+ stream.Put_uint32 ( 0x01040000 ); // version
+ stream.Put_uint32 ( 0x3 ); // flags
+ opcode.PutData( stream );
+
+ // Point to buffer
+ if( i == 0 )
+ tuning_info.gain_map.size = stream.Position();
+
+ assert( tuning_info.gain_map.buffers[i] == NULL );
+
+ tuning_info.gain_map.buffers[i] = (char*)allocator->Alloc( tuning_info.gain_map.size );
+ memcpy( tuning_info.gain_map.buffers[i], gainmap_buffer[i], tuning_info.gain_map.size );
+ }
+ }
+ else
+ {
+ tuning_info.gain_map.size = 0;
+ }
+
+ // WarpRectilinear
+ dng_opcode_list &opcodelist3 = negative->OpcodeList3 ();
+ count = opcodelist3.Count ();
+ // Note: this code will have to get smarter if we ever have anything other than one WarpRectilinear tag in OpcodeList3
+ if ( count == 1 )
+ {
+ // Get WarpRectilinear Opcode
+ dng_opcode &opcode = opcodelist3.Entry( 0 );
+
+ dng_stream stream ( _warp_rect_buffer, 256 );
+ opcode.PutData( stream );
+
+ // Ugly way to get the parameters, but I couldn't figure how else to get access to the data
+ double red_coefficient = * (double *) &_warp_rect_buffer[8];
+ double blue_coefficient = * (double *) &_warp_rect_buffer[8 + 2*6*8];
+ //LogPrint( "WarpRectilinear red = %f, blue = %f ", red_coefficient, blue_coefficient );
+
+ tuning_info.warp_red_coefficient = red_coefficient;
+ tuning_info.warp_blue_coefficient = blue_coefficient;
+ }
+ else
+ {
+ tuning_info.warp_red_coefficient = 0;
+ tuning_info.warp_blue_coefficient = 0;
+ }
+ }
+ }
+
+ if( raw_image_buffer )
+ {
+ CopyRawImageToBuffer( raw_image, *raw_image_buffer );
+ }
+ }
+
+ return true;
+}
+
+
+void reduction(double a[][6], int size, int pivot, int col)
+{
+ int i, j;
+ double factor;
+ factor = a[pivot][col];
+
+ for (i = 0; i < 2 * size; i++) {
+ a[pivot][i] /= factor;
+ }
+
+ for (i = 0; i < size; i++) {
+ if (i != pivot) {
+ factor = a[i][col];
+ for (j = 0; j < 2 * size; j++) {
+ a[i][j] = a[i][j] - a[pivot][j] * factor;
+ }
+ }
+ }
+}
+
+void calc_color_matrix( double in_matrix[3][3], double wb[3], double weight, double out_matrix[3][3] )
+{
+ double temp1[3][3];
+ double temp2[3][3];
+
+ int i,j,k;
+
+#if PRINT_MATRIX
+ LogPrint("\nOriginal Matrix");
+ for (i = 0; i < 3; i++)
+ LogPrint("%8.5f %8.5f %8.5f", in_matrix[i][0], in_matrix[i][1], in_matrix[i][2] );
+#endif
+
+ // Interpolate with identity matrix by weight w
+ double w = weight;
+ double z = 1.0 - weight;
+
+ for (i = 0; i < 3; i++ )
+ {
+ for (j = 0; j < 3; j++ )
+ temp1[i][j] = in_matrix[i][j] * w;
+
+ temp1[i][i] += z;
+ }
+
+#if PRINT_MATRIX
+ LogPrint("\nInterpolated Matrix");
+ for (i = 0; i < 3; i++)
+ LogPrint("%8.5f %8.5f %8.5f", temp1[i][0], temp1[i][1], temp1[i][2] );
+#endif
+
+ // Multiply matrix by sRGB_to_XYZd50 (from http://www.brucelindbloom.com)
+ double sRGB_to_XYZd50[3][3] = {{0.4361, 0.3851, 0.1431}, {0.2225, 0.7169, 0.0606}, {0.0139, 0.0971, 0.7142}};
+
+ double sum;
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ {
+ sum = 0;
+ for (k = 0; k < 3; k++)
+ sum = sum + sRGB_to_XYZd50[i][k] * temp1[k][j];
+
+ temp2[i][j] = sum;
+ }
+
+#if PRINT_MATRIX
+ LogPrint("\ntimes sRGB_to_XYZd50");
+ for (i = 0; i < 3; i++)
+ LogPrint("%8.5f %8.5f %8.5f", temp2[i][0], temp2[i][1], temp2[i][2] );
+#endif
+
+ // Set up diagonal matrix with white balance gains
+ double wb_diag[3][3];
+ for (i = 0; i < 3; i++)
+ {
+ for (j = 0; j < 3; j++)
+ wb_diag[i][j] = 0.0;
+
+ wb_diag[i][i] = wb[i];
+ }
+
+ // Multiply by white balance gains
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ {
+ sum = 0;
+ for (k = 0; k < 3; k++)
+ sum = sum + temp2[i][k] * wb_diag[k][j];
+
+ temp1[i][j] = sum;
+ }
+
+#if PRINT_MATRIX
+ LogPrint("\ntimes wb");
+ for (i = 0; i < 3; i++)
+ LogPrint("%8.5f %8.5f %8.5f", temp1[i][0], temp1[i][1], temp1[i][2] );
+#endif
+
+ // Invert the resulting matrix
+ double matrix[3][6];
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 6; j++)
+ if (j == i + 3)
+ matrix[i][j] = 1;
+ else
+ matrix[i][j] = 0;
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ matrix[i][j] = temp1[i][j];
+
+ for (i = 0; i < 3; i++)
+ reduction(matrix, 3, i, i);
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ out_matrix[i][j] = matrix[i][j+3];
+
+#if PRINT_MATRIX
+ LogPrint("\nInverse Matrix");
+ for (i = 0; i < 3; i++) {
+ LogPrint("%8.5f %8.5f %8.5f", out_matrix[i][0], out_matrix[i][1], out_matrix[i][2] );
+ }
+#endif
+
+}
+
+typedef struct
+{
+ unsigned char* orig_dst; /* Address to the memory location that this buffer points to */
+
+ unsigned char* next_dst;
+
+} jpg_write_context;
+
+void write_jpg_thumbnail(void* context, void* data, int size)
+{
+ jpg_write_context* _context = (jpg_write_context*)context;
+
+ memcpy( _context->next_dst, data, size );
+
+ _context->next_dst = (unsigned char*)_context->next_dst + size;
+}
+
+static void write_dng(const gpr_allocator* allocator,
+ dng_stream* dng_write_stream,
+ const gpr_buffer_auto* raw_image_buffer,
+ bool compress_raw_to_vc5,
+ gpr_buffer_auto* vc5_image_buffer,
+ const gpr_parameters* convert_params )
+{
+ gpr_profile_info* profile_info = (gpr_profile_info *) &convert_params->profile_info;
+ const gpr_exif_info* exif_info = &convert_params->exif_info;
+
+ const bool vc5_dng = compress_raw_to_vc5 || vc5_image_buffer;
+
+ int i,j;
+
+ int activeWidth = convert_params->input_width;
+ int activeHeight = convert_params->input_height;
+
+ int outputWidth = activeWidth;
+ int outputHeight = activeHeight;
+
+ gDNGShowTimers = false;
+
+ dng_memory_allocator memalloc(gDefaultDNGMemoryAllocator);
+
+ dng_rect rect(outputHeight, outputWidth);
+ dng_host host(&memalloc);
+
+ host.SetSaveDNGVersion(dngVersion_SaveDefault);
+ host.SetSaveLinearDNG(false);
+ host.SetKeepOriginalFile(true);
+
+ AutoPtr<dng_image> image(new dng_simple_image(rect, 1, ttShort, memalloc));
+
+ gpr_buffer_auto raw_allocated_buffer( allocator->Alloc, allocator->Free );
+
+ if( raw_image_buffer == NULL && vc5_image_buffer )
+ {
+#if GPR_READING
+ vc5_decoder_parameters vc5_decoder_params;
+
+ vc5_decoder_parameters_set_default(&vc5_decoder_params);
+
+ vc5_decoder_params.mem_alloc = allocator->Alloc;
+ vc5_decoder_params.mem_free = allocator->Free;
+
+ switch(convert_params->tuning_info.pixel_format)
+ {
+ case PIXEL_FORMAT_RGGB_12:
+ vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_RGGB_12;
+ break;
+
+ case PIXEL_FORMAT_RGGB_14:
+ vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_RGGB_14;
+ break;
+
+ case PIXEL_FORMAT_GBRG_12:
+ vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_GBRG_12;
+ break;
+
+ default:
+ assert(0);
+ return;
+ };
+
+ gpr_buffer vc5_image = { vc5_image_buffer->get_buffer(), vc5_image_buffer->get_size() };
+ gpr_buffer raw_image = { raw_allocated_buffer.get_buffer(), raw_allocated_buffer.get_size() };
+
+ if( vc5_decoder_process( &vc5_decoder_params, &vc5_image, &raw_image, NULL ) != CODEC_ERROR_OKAY )
+ {
+ assert(0);
+ }
+
+ raw_allocated_buffer.set( raw_image.buffer, raw_image.size, true );
+
+ raw_image_buffer = &raw_allocated_buffer;
+#else
+ return; // Since vc5 decoder is not enabled, we cannot decode this vc5 bitstream to create raw image
+#endif // GPR_READING
+ }
+
+ unsigned int input_pitch = convert_params->input_pitch;
+
+ if( ( convert_params->tuning_info.pixel_format == PIXEL_FORMAT_GBRG_12P ||
+ convert_params->tuning_info.pixel_format == PIXEL_FORMAT_RGGB_12P ) &&
+ vc5_dng == false )
+ {
+ unpack_pixel_format( raw_image_buffer, convert_params, &raw_allocated_buffer );
+
+ raw_image_buffer = &raw_allocated_buffer;
+
+ input_pitch = convert_params->input_width * 2;
+ }
+
+ if( vc5_dng == false )
+ {
+ CopyBufferToRawImage( *raw_image_buffer, input_pitch / sizeof(short), *(image.Get()) );
+ }
+
+ AutoPtr<dng_negative> negative(host.Make_dng_negative());
+
+ negative->SetOriginalBestQualityFinalSize( dng_point(outputHeight, outputWidth) );
+
+ negative->SetOriginalDefaultFinalSize( dng_point(outputHeight, outputWidth) );
+
+ { // Set Tuning Info
+ const gpr_tuning_info* tuning_info = &convert_params->tuning_info;
+
+ const gpr_static_black_level static_black_level = tuning_info->static_black_level;
+
+ switch( convert_params->tuning_info.pixel_format )
+ {
+ case PIXEL_FORMAT_RGGB_12:
+ case PIXEL_FORMAT_RGGB_12P:
+ case PIXEL_FORMAT_RGGB_14:
+ negative->SetQuadBlacks(static_black_level.r_black,
+ static_black_level.g_r_black,
+ static_black_level.g_b_black,
+ static_black_level.b_black,
+ -1 );
+ break;
+ case PIXEL_FORMAT_GBRG_12:
+ case PIXEL_FORMAT_GBRG_12P:
+ negative->SetQuadBlacks(static_black_level.g_b_black,
+ static_black_level.b_black,
+ static_black_level.r_black,
+ static_black_level.g_r_black,
+ -1 );
+ break;
+
+ default:
+ assert(0);
+ }
+
+ const gpr_saturation_level dgain_saturation_level = tuning_info->dgain_saturation_level;
+
+ if( dgain_saturation_level.level_red == dgain_saturation_level.level_green_even &&
+ dgain_saturation_level.level_red == dgain_saturation_level.level_green_odd &&
+ dgain_saturation_level.level_red == dgain_saturation_level.level_blue )
+ {
+ negative->SetWhiteLevel( dgain_saturation_level.level_red, -1 );
+ }
+ else
+ {
+ negative->SetWhiteLevel( dgain_saturation_level.level_red, 0 );
+ negative->SetWhiteLevel( dgain_saturation_level.level_green_even, 1 );
+ negative->SetWhiteLevel( dgain_saturation_level.level_green_odd, 2 );
+ negative->SetWhiteLevel( dgain_saturation_level.level_blue, 3 );
+ }
+
+ negative->SetBaseOrientation((dng_orientation::AdobeToDNG(tuning_info->orientation)));
+
+ dng_vector camNeutral(3);
+
+ camNeutral[0] = 1.0 / tuning_info->wb_gains.r_gain;
+ camNeutral[1] = 1.0 / tuning_info->wb_gains.g_gain;
+ camNeutral[2] = 1.0 / tuning_info->wb_gains.b_gain;
+
+ negative->SetCameraNeutral(camNeutral);
+
+
+ // Add noise profile
+ if ( tuning_info->noise_scale > 0 )
+ {
+ std::vector<dng_noise_function> noiseFunctions;
+ noiseFunctions.push_back( dng_noise_function ( tuning_info->noise_scale, tuning_info->noise_offset ) );
+ negative->SetNoiseProfile( dng_noise_profile ( noiseFunctions ) );
+ }
+
+ size_t gain_map_size = tuning_info->gain_map.size;
+
+ // GainMap - aka vignette or shading correction (one for each CFA channel)(applied before demosaicking (OpcodeList2))
+ if ( gain_map_size > 0 && tuning_info->gain_map.buffers[0] != 0 && tuning_info->gain_map.buffers[1] != 0 && tuning_info->gain_map.buffers[2] != 0 && tuning_info->gain_map.buffers[3] != 0 )
+ {
+ dng_opcode_list &opcodelist2 = negative->OpcodeList2 ();
+
+ dng_stream gain_map_stream0 (tuning_info->gain_map.buffers[0], gain_map_size);
+ AutoPtr<dng_opcode> gain_map_opcode0 ( new dng_opcode_GainMap ( host, gain_map_stream0 ));
+ opcodelist2.Append( gain_map_opcode0 );
+
+ dng_stream gain_map_stream1 (tuning_info->gain_map.buffers[1], gain_map_size);
+ AutoPtr<dng_opcode> gain_map_opcode1 ( new dng_opcode_GainMap ( host, gain_map_stream1 ));
+ opcodelist2.Append( gain_map_opcode1 );
+
+ dng_stream gain_map_stream2 (tuning_info->gain_map.buffers[2], gain_map_size);
+ AutoPtr<dng_opcode> gain_map_opcode2 ( new dng_opcode_GainMap ( host, gain_map_stream2 ));
+ opcodelist2.Append( gain_map_opcode2 );
+
+ dng_stream gain_map_stream3 (tuning_info->gain_map.buffers[3], gain_map_size);
+ AutoPtr<dng_opcode> gain_map_opcode3 ( new dng_opcode_GainMap ( host, gain_map_stream3 ));
+ opcodelist2.Append( gain_map_opcode3 );
+ }
+
+ // WarpRectilinear - aka chromatic aberration correction (applied after demosaicking (OpcodeList3))
+ if ( tuning_info->warp_red_coefficient > 0 && tuning_info->warp_blue_coefficient > 0 )
+ {
+ dng_opcode_list &opcodelist3 = negative->OpcodeList3 ();
+
+ dng_warp_params_rectilinear chromatic_aberration;
+
+ chromatic_aberration.fPlanes = 3;
+ chromatic_aberration.fCenter = dng_point_real64( 0.5, 0.5 );
+ chromatic_aberration.fRadParams[0][0] = tuning_info->warp_red_coefficient;
+ chromatic_aberration.fRadParams[1][0] = 1.0;
+ chromatic_aberration.fRadParams[2][0] = tuning_info->warp_blue_coefficient;
+
+ AutoPtr<dng_opcode> warp_opcode ( new dng_opcode_WarpRectilinear ( chromatic_aberration, 0x03 ));
+
+ opcodelist3.Append( warp_opcode );
+ }
+ }
+
+ //GP!! NEED outputWidth, activeWidth, outputHeight, activeHeight here
+ negative->SetDefaultScale(dng_urational(outputWidth, activeWidth), dng_urational(outputHeight, activeHeight));
+
+ uint32 crop_size_val = 0;
+ dng_point crop_origin( 0, 0 );
+ dng_point crop_size( activeHeight - 2 * crop_size_val, activeWidth - 2 * crop_size_val );
+
+ negative->SetDefaultCropOrigin( crop_origin.h, crop_origin.v );
+ negative->SetDefaultCropSize( crop_size.h, crop_size.v );
+
+ negative->SetOriginalDefaultCropSize( dng_urational(crop_size.h, 1), dng_urational(crop_size.v, 1) );
+
+ {
+ dng_rect activeArea = dng_rect(activeHeight, activeWidth);
+
+ negative->SetActiveArea(activeArea);
+ }
+
+ char camera_make_and_model[256];
+
+ gpr_exif_info_get_camera_make_and_model(exif_info, camera_make_and_model);
+
+ negative->SetModelName( camera_make_and_model );
+
+ negative->SetLocalName( camera_make_and_model );
+
+ //GP!! "Raw file?"
+ negative->SetOriginalRawFileName("RAW FILE");
+ //GP!! Either 1 or 3
+ negative->SetColorChannels(3);
+
+ //!! Need correct CFA sequence here!!
+ ColorKeyCode colorCodes[4] = { colorKeyRed, colorKeyGreen, colorKeyBlue, colorKeyGreen };
+ // ColorKeyCode colorCodes[4] = { colorKeyGreen, colorKeyRed, colorKeyGreen, colorKeyBlue };
+
+ negative->SetColorKeys(colorCodes[0], colorCodes[1], colorCodes[2], colorCodes[3]);
+
+ // Set Bayer Pattern
+ if( convert_params->tuning_info.pixel_format == PIXEL_FORMAT_RGGB_12 || convert_params->tuning_info.pixel_format == PIXEL_FORMAT_RGGB_12P || convert_params->tuning_info.pixel_format == PIXEL_FORMAT_RGGB_14 )
+ {
+ negative->SetBayerMosaic(1);
+ }
+ else if( convert_params->tuning_info.pixel_format == PIXEL_FORMAT_GBRG_12 || convert_params->tuning_info.pixel_format == PIXEL_FORMAT_GBRG_12P )
+ {
+ negative->SetBayerMosaic(3);
+ }
+ else
+ {
+ assert(0);
+ return;
+ }
+
+ negative->SetBaselineExposure(0);
+ negative->SetBaselineNoise(1.0);
+ negative->SetBaselineSharpness(1.0);
+
+ negative->SetAntiAliasStrength(dng_urational(100, 100));
+ negative->SetLinearResponseLimit(1.0);
+ negative->SetShadowScale( dng_urational(1, 1) );
+ negative->SetAnalogBalance(dng_vector_3(1.0, 1.0, 1.0));
+
+ AutoPtr<dng_camera_profile> prof(new dng_camera_profile);
+ prof->SetName( camera_make_and_model );
+
+ dng_matrix_3by3 mColor1;
+ dng_matrix_3by3 mColor2;
+
+ if ( profile_info->compute_color_matrix )
+ {
+ double matrix_weighting = profile_info->matrix_weighting;
+
+ double out_matrix[3][3];
+
+ if ( matrix_weighting < 0.0 || matrix_weighting > 1.0 )
+ matrix_weighting = 1.0;
+
+ calc_color_matrix( profile_info->cam_to_srgb_1, profile_info->wb1, matrix_weighting, out_matrix );
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ mColor1[i][j] = out_matrix[i][j];
+
+ calc_color_matrix( profile_info->cam_to_srgb_2, profile_info->wb2, matrix_weighting, out_matrix );
+
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ mColor2[i][j] = out_matrix[i][j];
+ }
+ else
+ {
+ for (i = 0; i < 3; i++)
+ for (j = 0; j < 3; j++)
+ {
+ mColor1[i][j] = profile_info->color_matrix_1[i][j];
+ mColor2[i][j] = profile_info->color_matrix_2[i][j];
+ }
+ }
+
+#if PRINT_MATRIX
+ LogPrint("CM1:");
+ for (i = 0; i < 3; i++)
+ LogPrint(" %8.5f %8.5f %8.5f", mColor1[i][0], mColor1[i][1], mColor1[i][2] );
+ LogPrint("CM2:");
+ for (i = 0; i < 3; i++)
+ LogPrint(" %8.5f %8.5f %8.5f", mColor2[i][0], mColor2[i][1], mColor2[i][2] );
+#endif
+
+ prof->SetColorMatrix1((dng_matrix) mColor1);
+ prof->SetColorMatrix2((dng_matrix) mColor2);
+
+ prof->SetCalibrationIlluminant1(profile_info->illuminant1);
+ prof->SetCalibrationIlluminant2(profile_info->illuminant2);
+
+ negative->AddProfile(prof);
+
+ dng_exif* const exif = negative->GetExif();
+ exif->fModel.Set( exif_info->camera_model );
+ exif->fMake.Set( exif_info->camera_make );
+
+ convert_dng_exif_info_to_dng_exif(exif, exif_info );
+
+ {
+ dng_date_time_info date_time_original;
+ date_time_original.SetDateTime( convert_to_dng_date_time( exif_info->date_time_original ) );
+
+ negative->UpdateDateTime(date_time_original);
+ }
+
+ if( convert_params->gpmf_payload.buffer != NULL && convert_params->gpmf_payload.size > 0 )
+ { // Set GPMF Data
+ dng_string gopro_tag;
+ gopro_tag.Append("GoPro\n");
+
+ AutoPtr<dng_memory_block> gpmf_buffer;
+
+ gpmf_buffer.Reset (host.Allocate(gopro_tag.Length() + convert_params->gpmf_payload.size) );
+
+ unsigned char* gpmf_buffer_ptr = (unsigned char*)gpmf_buffer.Get()->Buffer();
+
+ memcpy( gpmf_buffer_ptr + 0, gopro_tag.Get(), gopro_tag.Length() );
+ memcpy( gpmf_buffer_ptr + gopro_tag.Length(), convert_params->gpmf_payload.buffer, convert_params->gpmf_payload.size );
+
+ negative->SetPrivateData(gpmf_buffer);
+ }
+
+ negative->SetStage1Image(image);
+
+ dng_preview_list* preview_list = NULL;
+
+ dng_image_writer* writer = NULL;
+
+#if GPR_WRITING
+ if( vc5_dng )
+ {
+ gpr_image_writer* gpr_writer = new gpr_image_writer(raw_image_buffer, convert_params->input_width, convert_params->input_height, convert_params->input_pitch, vc5_image_buffer );
+ set_vc5_encoder_parameters( gpr_writer->GetVc5EncoderParams(), convert_params );
+
+ gpr_writer->EncodeVc5Image();
+
+ if( convert_params->enable_preview )
+ {
+ const gpr_preview_image& preview_image = convert_params->preview_image;
+
+ if( preview_image.jpg_preview.size > 0 && preview_image.jpg_preview.buffer != NULL )
+ {
+ preview_list = new dng_preview_list;
+
+ AutoPtr<dng_jpeg_preview> jpeg_preview;
+ jpeg_preview.Reset(new dng_jpeg_preview);
+ jpeg_preview->fPhotometricInterpretation = piYCbCr;
+
+ jpeg_preview->fInfo.fIsPrimary = true;
+
+ jpeg_preview->fPreviewSize.v = preview_image.preview_height;
+ jpeg_preview->fPreviewSize.h = preview_image.preview_width;
+ jpeg_preview->fCompressedData.Reset(host.Allocate( preview_image.jpg_preview.size ));
+ memcpy( jpeg_preview->fCompressedData->Buffer_char(), preview_image.jpg_preview.buffer, preview_image.jpg_preview.size );
+
+ AutoPtr<dng_preview> pp( dynamic_cast<dng_preview*>(jpeg_preview.Release()) );
+
+ preview_list->Append(pp);
+ }
+#if GPR_JPEG_AVAILABLE
+ else
+ {
+ preview_list = new dng_preview_list;
+
+ AutoPtr<dng_jpeg_preview> jpeg_preview;
+ jpeg_preview.Reset(new dng_jpeg_preview);
+ jpeg_preview->fPhotometricInterpretation = piYCbCr;
+
+ jpeg_preview->fInfo.fIsPrimary = true;
+
+ const gpr_rgb_buffer& rgb_buffer = gpr_writer->get_rgb_thumbnail();
+
+ gpr_buffer_auto buffer( allocator->Alloc, allocator->Free );
+
+ buffer.allocate(1024*1024);
+
+ jpg_write_context context;
+ context.orig_dst = buffer.to_uchar();
+ context.next_dst = context.orig_dst;
+
+ tje_encode_with_func(write_jpg_thumbnail, (void*)&context, 2, rgb_buffer.width, rgb_buffer.height, 3, (const unsigned char*)rgb_buffer.buffer );
+
+ size_t size = context.next_dst - context.orig_dst;
+ jpeg_preview->fPreviewSize.v = rgb_buffer.height;
+ jpeg_preview->fPreviewSize.h = rgb_buffer.width;
+ jpeg_preview->fCompressedData.Reset(host.Allocate( size ));
+ memcpy( jpeg_preview->fCompressedData->Buffer_char(), buffer.get_buffer(), size );
+
+ AutoPtr<dng_preview> pp( dynamic_cast<dng_preview*>(jpeg_preview.Release()) );
+
+ preview_list->Append(pp);
+ }
+#endif
+ }
+
+ writer = gpr_writer;
+ }
+ else
+#endif
+ {
+ writer = new dng_image_writer;
+ }
+
+ writer->SetComputeMd5Sum( convert_params->compute_md5sum );
+
+ assert(writer);
+ writer->WriteDNG(host, *dng_write_stream, *negative.Get(), preview_list, dngVersion_Current, vc5_dng == false );
+
+ delete writer;
+
+ if( preview_list )
+ delete preview_list;
+}
+
+extern dng_memory_allocator gDefaultDNGMemoryAllocator;
+
+bool write_dngstream_to_buffer( dng_stream* stream, gpr_buffer* output_buffer, gpr_malloc mem_alloc, gpr_free mem_free )
+{
+ size_t buffer_size = stream->Length();
+ void* buffer = mem_alloc(buffer_size);
+
+ stream->SetReadPosition(0);
+ stream->Get(buffer, buffer_size);
+
+ output_buffer->buffer = buffer;
+ output_buffer->size = buffer_size;
+
+ return true;
+}
+
+bool gpr_parse_metadata(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_parameters* parameters)
+{
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, NULL, NULL, parameters ) == false )
+ {
+ assert(0); return false;
+ }
+
+ return true;
+}
+
+bool gpr_convert_raw_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_raw_buffer,
+ gpr_buffer* out_dng_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+ raw_buffer.set( (char*)inp_raw_buffer->buffer, inp_raw_buffer->size );
+
+ dng_memory_stream out_dng_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_dng_stream, &raw_buffer, false, NULL, parameters );
+
+ write_dngstream_to_buffer( &out_dng_stream, out_dng_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_dng_to_raw(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_raw_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, &raw_buffer, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ out_raw_buffer->buffer = allocator->Alloc( raw_buffer.get_size() );
+ out_raw_buffer->size = raw_buffer.get_size();
+
+ memcpy(out_raw_buffer->buffer, raw_buffer.get_buffer(), raw_buffer.get_size() );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+//!< dng to raw conversion
+bool gpr_convert_dng_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_dng_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, &raw_buffer, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ dng_memory_stream out_dng_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_dng_stream, &raw_buffer, false, NULL, parameters );
+
+ write_dngstream_to_buffer( &out_dng_stream, out_dng_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_vc5_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_vc5_buffer,
+ gpr_buffer* out_gpr_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+ vc5_buffer.set( (char*)inp_vc5_buffer->buffer, inp_vc5_buffer->size );
+
+ dng_memory_stream out_gpr_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_gpr_stream, NULL, false, &vc5_buffer, parameters );
+
+ write_dngstream_to_buffer( &out_gpr_stream, out_gpr_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_gpr_to_vc5(const gpr_allocator* allocator,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_vc5_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_gpr_stream( gDefaultDNGMemoryAllocator );
+ inp_gpr_stream.Put( inp_gpr_buffer->buffer, inp_gpr_buffer->size );
+ inp_gpr_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_gpr_stream, NULL, &vc5_buffer ) == false )
+ {
+ assert(0); return false;
+ }
+
+ if( vc5_buffer.is_valid() == false )
+ {
+ return false;
+ }
+
+ out_vc5_buffer->buffer = allocator->Alloc( vc5_buffer.get_size() );
+ out_vc5_buffer->size = vc5_buffer.get_size();
+ memcpy(out_vc5_buffer->buffer, vc5_buffer.get_buffer(), vc5_buffer.get_size() );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+#if GPR_WRITING
+
+bool gpr_convert_raw_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_raw_buffer,
+ gpr_buffer* out_gpr_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+
+ raw_buffer.set(inp_raw_buffer->buffer, inp_raw_buffer->size);
+
+ dng_memory_stream out_gpr_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_gpr_stream, &raw_buffer, true, NULL, parameters );
+
+ write_dngstream_to_buffer( &out_gpr_stream, out_gpr_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_dng_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_gpr_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, &raw_buffer, NULL, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ dng_memory_stream out_gpr_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_gpr_stream, &raw_buffer, true, NULL, parameters );
+
+ write_dngstream_to_buffer( &out_gpr_stream, out_gpr_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_dng_to_vc5(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_vc5_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, &raw_buffer, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ out_vc5_buffer->buffer = allocator->Alloc( vc5_buffer.get_size() );
+ out_vc5_buffer->size = vc5_buffer.get_size();
+
+ memcpy(out_vc5_buffer->buffer, vc5_buffer.get_buffer(), vc5_buffer.get_size() );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+#endif // GPR_WRITING
+
+#if GPR_READING
+
+bool gpr_convert_gpr_to_rgb(const gpr_allocator* allocator,
+ GPR_RGB_RESOLUTION rgb_resolution,
+ int rgb_bits,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_rgb_buffer* out_rgb_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_parameters params;
+
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_gpr_stream( gDefaultDNGMemoryAllocator );
+ inp_gpr_stream.Put( inp_gpr_buffer->buffer, inp_gpr_buffer->size );
+ inp_gpr_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_gpr_stream, NULL, &vc5_buffer, &params ) == false )
+ {
+ assert(0); return false;
+ }
+
+ if( vc5_buffer.is_valid() == false )
+ {
+ return false;
+ }
+
+ vc5_decoder_parameters vc5_decoder_params;
+
+ vc5_decoder_parameters_set_default(&vc5_decoder_params);
+
+ vc5_decoder_params.mem_alloc = allocator->Alloc;
+ vc5_decoder_params.mem_free = allocator->Free;
+ vc5_decoder_params.pixel_format = VC5_DECODER_PIXEL_FORMAT_DEFAULT;
+
+ vc5_decoder_params.rgb_bits = rgb_bits;
+
+ gpr_rgb_gain& rgb_gain = vc5_decoder_params.rgb_gain;
+
+ find_rational( params.tuning_info.wb_gains.r_gain, 0.125, &rgb_gain.r_gain_num, &rgb_gain.r_gain_pow2_den );
+ find_rational( params.tuning_info.wb_gains.g_gain, 0.125, &rgb_gain.g_gain_num, &rgb_gain.g_gain_pow2_den );
+ find_rational( params.tuning_info.wb_gains.b_gain, 0.125, &rgb_gain.b_gain_num, &rgb_gain.b_gain_pow2_den );
+
+ vc5_decoder_params.rgb_resolution = rgb_resolution;
+
+ if( vc5_decoder_process( &vc5_decoder_params, &vc5_buffer.get_gpr_buffer(), NULL, out_rgb_buffer ) != CODEC_ERROR_OKAY )
+ {
+ assert(0);
+ }
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_gpr_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_dng_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_gpr_stream( gDefaultDNGMemoryAllocator );
+ inp_gpr_stream.Put( inp_gpr_buffer->buffer, inp_gpr_buffer->size );
+ inp_gpr_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_gpr_stream, &raw_buffer, &vc5_buffer, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ dng_memory_stream out_dng_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_dng_stream, &raw_buffer, false, NULL, parameters );
+
+ write_dngstream_to_buffer( &out_dng_stream, out_dng_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_vc5_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_vc5_buffer,
+ gpr_buffer* out_dng_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto vc5_buffer( allocator->Alloc, allocator->Free );
+
+ vc5_buffer.set(inp_vc5_buffer->buffer, inp_vc5_buffer->size);
+
+ dng_memory_stream out_dng_stream( gDefaultDNGMemoryAllocator );
+
+ write_dng( allocator, &out_dng_stream, NULL, false, &vc5_buffer, parameters );
+
+ write_dngstream_to_buffer( &out_dng_stream, out_dng_buffer, allocator->Alloc, allocator->Free );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+bool gpr_convert_gpr_to_raw(const gpr_allocator* allocator,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_raw_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+
+ dng_memory_stream inp_gpr_stream( gDefaultDNGMemoryAllocator );
+ inp_gpr_stream.Put( inp_gpr_buffer->buffer, inp_gpr_buffer->size );
+ inp_gpr_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_gpr_stream, &raw_buffer, NULL ) == false )
+ {
+ assert(0); return false;
+ }
+
+ out_raw_buffer->buffer = allocator->Alloc( raw_buffer.get_size() );
+ out_raw_buffer->size = raw_buffer.get_size();
+
+ memcpy(out_raw_buffer->buffer, raw_buffer.get_buffer(), raw_buffer.get_size() );
+
+ TIMESTAMP("[END]", 1)
+
+ return true;
+}
+
+#endif // GPR_READING
+
+bool gpr_check_vc5( const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer)
+{
+ TIMESTAMP("[BEG]", 1)
+
+ gpr_buffer_auto raw_buffer(allocator->Alloc, allocator->Free);
+ gpr_buffer_auto vc5_buffer(allocator->Alloc, allocator->Free);
+ bool is_vc5_format = false;
+
+ {
+ dng_memory_stream inp_dng_stream( gDefaultDNGMemoryAllocator );
+ inp_dng_stream.Put( inp_dng_buffer->buffer, inp_dng_buffer->size );
+ inp_dng_stream.SetReadPosition(0);
+
+ if( read_dng( allocator, &inp_dng_stream, &raw_buffer, &vc5_buffer, NULL, &is_vc5_format ) == false )
+ {
+ assert(0); return -1;
+ }
+ }
+
+ TIMESTAMP("[END]", 1)
+
+ return is_vc5_format;
+}
+
+
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_exif_info.cpp b/gpr/source/lib/gpr_sdk/private/gpr_exif_info.cpp
new file mode 100755
index 0000000..4b1e9bc
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_exif_info.cpp
@@ -0,0 +1,105 @@
+
+#include "gpr_platform.h"
+#include "gpr_exif_info.h"
+#include "stdc_includes.h"
+
+static gpr_signed_rational signed_rational_construct(int32_t numerator, int32_t denominator)
+{
+ gpr_signed_rational a;
+ a.numerator = numerator;
+ a.denominator = denominator;
+ return a;
+}
+
+static gpr_unsigned_rational unsigned_rational_construct(int32_t numerator, int32_t denominator)
+{
+ gpr_unsigned_rational a;
+ a.numerator = numerator;
+ a.denominator = denominator;
+ return a;
+}
+
+gpr_date_and_time construct_dng_date_and_time (uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second)
+{
+ gpr_date_and_time x;
+ x.year = year;
+ x.month = month;
+ x.day = day;
+ x.hour = hour;
+ x.minute = minute;
+ x.second = second;
+
+ return x;
+}
+
+void gpr_exif_info_set_defaults( gpr_exif_info* x )
+{
+ x->exposure_time = unsigned_rational_construct(1, 60);
+
+ x->exposure_bias = signed_rational_construct( 0, 1 );
+
+ double d_aperture = 2.8;
+
+ x->f_stop_number = unsigned_rational_construct( (unsigned int)(d_aperture * 1000), 1000 );
+
+ // Convert aperture to APEX
+ double aperture_apex = log(d_aperture) / log(sqrt(2.0));
+
+ x->aperture = unsigned_rational_construct( (unsigned int)(aperture_apex * 1000), 1000 );
+
+ x->focal_length = unsigned_rational_construct(3, 1);
+
+ x->digital_zoom = unsigned_rational_construct(1, 1);
+
+ x->metering_mode = gpr_metering_mode_center_weighted_average;
+
+ x->focal_length_in_35mm_film = 15;
+
+ x->exposure_program = gpr_exposure_program_normal;
+
+ x->light_source = gpr_light_source_auto;
+
+ x->flash = gpr_flash_not_supported;
+
+ x->sensing_method = gpr_sensing_method_chip_color_area;
+
+ x->file_source = gpr_file_source_digital_still;
+
+ x->scene_type = gpr_scene_type_directly_photographed;
+
+ x->white_balance = gpr_white_balance_auto;
+
+ x->exposure_mode = gpr_exposure_mode_auto;
+
+ x->scene_capture_type = gpr_scene_capture_type_standard;
+
+ x->gain_control = gpr_gain_control_normal;
+
+ x->contrast = gpr_contrast_normal;
+
+ x->saturation = gpr_saturation_normal;
+
+ x->sharpness = gpr_sharpness_hard;
+
+ x->iso_speed_rating = 232;
+
+ x->date_time_original = construct_dng_date_and_time (2016, 03, 25, 15, 55, 23 );
+
+ x->date_time_digitized = x->date_time_original;
+
+ strcpy( x->camera_make, "GoPro" );
+
+ strcpy( x->camera_model, "HERO6 Black" );
+
+ sprintf( x->software_version, "%d.%d.%d", GPR_VERSION_MAJOR, GPR_VERSION_MINOR, GPR_VERSION_REVISION );
+
+ strcpy( x->user_comment, "" );
+}
+
+void gpr_exif_info_get_camera_make_and_model( const gpr_exif_info* x, char camera_make_and_model[256] )
+{
+ strcpy(camera_make_and_model, x->camera_make );
+ strcpy(camera_make_and_model + strlen(camera_make_and_model), " " );
+ strcpy(camera_make_and_model + strlen(camera_make_and_model), x->camera_model );
+}
+
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_image_writer.cpp b/gpr/source/lib/gpr_sdk/private/gpr_image_writer.cpp
new file mode 100755
index 0000000..891f66d
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_image_writer.cpp
@@ -0,0 +1,129 @@
+
+#include "gpr_image_writer.h"
+
+#include "dng_camera_profile.h"
+#include "dng_color_space.h"
+#include "dng_date_time.h"
+#include "dng_exceptions.h"
+#include "dng_file_stream.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_ifd.h"
+#include "dng_image_writer.h"
+#include "dng_info.h"
+#include "dng_linearization_info.h"
+#include "dng_mosaic_info.h"
+#include "dng_negative.h"
+#include "dng_preview.h"
+#include "dng_render.h"
+#include "dng_simple_image.h"
+#include "dng_tag_codes.h"
+#include "dng_tag_types.h"
+#include "dng_tag_values.h"
+#include "dng_xmp.h"
+#include "dng_xmp_sdk.h"
+#include "dng_memory_stream.h"
+#include "dng_bottlenecks.h"
+
+#if GPR_WRITING
+#include "vc5_encoder.h"
+#endif
+
+#include "gpr_utils.h"
+
+#if GPR_WRITING
+
+gpr_image_writer::gpr_image_writer(const gpr_buffer_auto* raw_buffer,
+ unsigned int raw_buffer_width,
+ unsigned int raw_buffer_height,
+ size_t raw_buffer_pitch,
+ gpr_buffer_auto* vc5_buffer
+ ) : _vc5_buffer_obj( raw_buffer->get_malloc(), raw_buffer->get_free() ),
+ _vc5_buffer(vc5_buffer),
+ _raw_buffer(raw_buffer)
+{
+ if( _vc5_buffer == NULL )
+ {
+ _vc5_buffer = &_vc5_buffer_obj;
+ }
+
+ _rgb_thumbnail.buffer = NULL;
+ _rgb_thumbnail.size = 0;
+
+ vc5_encoder_parameters_set_default(&vc5_encoder_params);
+}
+
+gpr_image_writer::~gpr_image_writer()
+{
+ if( _rgb_thumbnail.buffer )
+ {
+ assert( _rgb_thumbnail.size > 0 );
+
+ _raw_buffer->get_free()(_rgb_thumbnail.buffer);
+ _rgb_thumbnail.buffer = NULL;
+ _rgb_thumbnail.size = 0;
+ }
+}
+
+
+void gpr_image_writer::EncodeVc5Image()
+{
+ if( _vc5_buffer->is_valid() == false )
+ {
+
+ gpr_buffer raw_image = { _raw_buffer->get_buffer(), _raw_buffer->get_size() };
+ gpr_buffer vc5_image = { _vc5_buffer->get_buffer(), _vc5_buffer->get_size() };
+
+ if( vc5_encoder_process( &vc5_encoder_params, &raw_image, &vc5_image, &_rgb_thumbnail ) != CODEC_ERROR_OKAY )
+ {
+ assert(0);
+ }
+
+ _vc5_buffer->set( vc5_image.buffer, vc5_image.size, true );
+ }
+}
+
+void gpr_image_writer::WriteImage (dng_host &host,
+ const dng_ifd &ifd,
+ dng_basic_tag_set &basic,
+ dng_stream &stream,
+ const dng_image &image,
+ uint32 fakeChannels)
+{
+ dng_image_writer::WriteImage ( host, ifd, basic, stream, image, fakeChannels);
+}
+
+uint32 gpr_image_writer::CompressedBufferSize (const dng_ifd &ifd, uint32 uncompressedSize)
+{
+ if( ifd.fCompression == ccVc5 )
+ {
+ return _vc5_buffer->get_size();
+ }
+ else
+ {
+ return dng_image_writer::CompressedBufferSize( ifd, uncompressedSize );
+ }
+}
+
+void gpr_image_writer::WriteTile (dng_host &host,
+ const dng_ifd &ifd,
+ dng_stream &stream,
+ const dng_image &image,
+ const dng_rect &tileArea,
+ uint32 fakeChannels,
+ AutoPtr<dng_memory_block> &compressedBuffer,
+ AutoPtr<dng_memory_block> &uncompressedBuffer,
+ AutoPtr<dng_memory_block> &subTileBlockBuffer,
+ AutoPtr<dng_memory_block> &tempBuffer)
+{
+ if( ifd.fCompression == ccVc5 )
+ {
+ stream.Put( _vc5_buffer->get_buffer(), _vc5_buffer->get_size() );
+ }
+ else
+ {
+ return dng_image_writer::WriteTile( host, ifd, stream, image, tileArea, fakeChannels, compressedBuffer, uncompressedBuffer, subTileBlockBuffer, tempBuffer );
+ }
+}
+
+#endif // GPR_WRITING
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_image_writer.h b/gpr/source/lib/gpr_sdk/private/gpr_image_writer.h
new file mode 100755
index 0000000..bb07c60
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_image_writer.h
@@ -0,0 +1,87 @@
+/*! @file gpr_image_writer.h
+ *
+ * @brief Declaration of gpr_image_writer class
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_IMAGE_WRITER
+#define GPR_IMAGE_WRITER
+
+#include "dng_image_writer.h"
+#include "gpr_buffer_auto.h"
+
+#if GPR_WRITING
+
+#include "vc5_encoder.h"
+
+class gpr_image_writer : public dng_image_writer
+{
+private:
+
+ gpr_buffer_auto _vc5_buffer_obj;
+
+ gpr_rgb_buffer _rgb_thumbnail;
+
+ gpr_buffer_auto* _vc5_buffer;
+ const gpr_buffer_auto* _raw_buffer;
+
+ vc5_encoder_parameters vc5_encoder_params;
+
+public:
+
+ void EncodeVc5Image();
+
+ const gpr_rgb_buffer& get_rgb_thumbnail() { return _rgb_thumbnail; }
+
+ vc5_encoder_parameters& GetVc5EncoderParams() { return vc5_encoder_params; }
+
+ gpr_image_writer(const gpr_buffer_auto* raw_buffer,
+ unsigned int raw_buffer_width,
+ unsigned int raw_buffer_height,
+ size_t raw_buffer_pitch,
+ gpr_buffer_auto* vc5_buffer = NULL );
+
+ ~gpr_image_writer();
+
+ void WriteImage (dng_host &host,
+ const dng_ifd &ifd,
+ dng_basic_tag_set &basic,
+ dng_stream &stream,
+ const dng_image &image,
+ uint32 fakeChannels);
+
+ uint32 CompressedBufferSize (const dng_ifd &ifd, uint32 uncompressedSize);
+
+ uint32 GetDefaultCompression() { return ccVc5; }
+
+ void WriteTile (dng_host &host,
+ const dng_ifd &ifd,
+ dng_stream &stream,
+ const dng_image &image,
+ const dng_rect &tileArea,
+ uint32 fakeChannels,
+ AutoPtr<dng_memory_block> &compressedBuffer,
+ AutoPtr<dng_memory_block> &uncompressedBuffer,
+ AutoPtr<dng_memory_block> &subTileBlockBuffer,
+ AutoPtr<dng_memory_block> &tempBuffer);
+
+};
+
+#endif // GPR_WRITING
+
+#endif // GPR_IMAGE_WRITER
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_profile_info.cpp b/gpr/source/lib/gpr_sdk/private/gpr_profile_info.cpp
new file mode 100755
index 0000000..93ad542
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_profile_info.cpp
@@ -0,0 +1,57 @@
+
+#include "gpr_profile_info.h"
+#include "stdc_includes.h"
+
+void gpr_profile_info_set_defaults(gpr_profile_info* x)
+{
+ x->compute_color_matrix = true;
+
+ x->matrix_weighting = 1.0;
+
+ x->illuminant1 = 3; // tungsten
+ x->illuminant2 = 23; // d50
+
+ x->wb1[0] = 1.339600;
+ x->wb1[1] = 1.00000;
+ x->wb1[2] = 2.780029;
+
+ x->wb2[0] = 1.9036;
+ x->wb2[1] = 1.00000;
+ x->wb2[2] = 1.7483;
+
+ {
+ const double cam_to_srgb[] = { 1.2963, -0.2025, -0.0939, -0.4789, 1.5728, -0.0939, -0.1007, -0.7605, 1.8612 };
+
+ x->cam_to_srgb_1[0][0] = cam_to_srgb[0];
+ x->cam_to_srgb_1[0][1] = cam_to_srgb[1];
+ x->cam_to_srgb_1[0][2] = cam_to_srgb[2];
+
+ x->cam_to_srgb_1[1][0] = cam_to_srgb[3];
+ x->cam_to_srgb_1[1][1] = cam_to_srgb[4];
+ x->cam_to_srgb_1[1][2] = cam_to_srgb[5];
+
+ x->cam_to_srgb_1[2][0] = cam_to_srgb[6];
+ x->cam_to_srgb_1[2][1] = cam_to_srgb[7];
+ x->cam_to_srgb_1[2][2] = cam_to_srgb[8];
+ }
+
+ {
+ const double cam_to_srgb[] = { 1.5580, -0.3019, -0.2561, -0.3023, 1.6328, -0.3305, -0.0365, -0.5127, 1.5492 };
+
+ x->cam_to_srgb_2[0][0] = cam_to_srgb[0];
+ x->cam_to_srgb_2[0][1] = cam_to_srgb[1];
+ x->cam_to_srgb_2[0][2] = cam_to_srgb[2];
+
+ x->cam_to_srgb_2[1][0] = cam_to_srgb[3];
+ x->cam_to_srgb_2[1][1] = cam_to_srgb[4];
+ x->cam_to_srgb_2[1][2] = cam_to_srgb[5];
+
+ x->cam_to_srgb_2[2][0] = cam_to_srgb[6];
+ x->cam_to_srgb_2[2][1] = cam_to_srgb[7];
+ x->cam_to_srgb_2[2][2] = cam_to_srgb[8];
+ }
+
+ memset( x->color_matrix_1, 0, sizeof(x->color_matrix_1) );
+ memset( x->color_matrix_2, 0, sizeof(x->color_matrix_2) );
+}
+
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_read_image.cpp b/gpr/source/lib/gpr_sdk/private/gpr_read_image.cpp
new file mode 100755
index 0000000..84c2fe9
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_read_image.cpp
@@ -0,0 +1,129 @@
+
+#include "gpr_read_image.h"
+
+#include "dng_camera_profile.h"
+#include "dng_color_space.h"
+#include "dng_date_time.h"
+#include "dng_exceptions.h"
+#include "dng_file_stream.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_ifd.h"
+#include "dng_image_writer.h"
+#include "dng_info.h"
+#include "dng_linearization_info.h"
+#include "dng_mosaic_info.h"
+#include "dng_negative.h"
+#include "dng_preview.h"
+#include "dng_render.h"
+#include "dng_simple_image.h"
+#include "dng_tag_codes.h"
+#include "dng_tag_types.h"
+#include "dng_tag_values.h"
+#include "dng_xmp.h"
+#include "dng_xmp_sdk.h"
+#include "dng_memory_stream.h"
+#include "dng_bottlenecks.h"
+
+#include "gpr_utils.h"
+
+#if GPR_READING
+
+#include "vc5_decoder.h"
+
+static bool DecodeVC5(dng_image &image, gpr_buffer_auto& vc5_buffer, VC5_DECODER_PIXEL_FORMAT pixel_format )
+{
+ gpr_buffer_auto raw_buffer( malloc, free );
+
+ vc5_decoder_parameters vc5_decoder_params;
+
+ vc5_decoder_parameters_set_default(&vc5_decoder_params);
+
+ vc5_decoder_params.mem_alloc = raw_buffer.get_malloc();
+ vc5_decoder_params.mem_free = raw_buffer.get_free();
+ vc5_decoder_params.pixel_format = pixel_format;
+
+ gpr_buffer vc5_image = { vc5_buffer.get_buffer(), vc5_buffer.get_size() };
+ gpr_buffer raw_image = { raw_buffer.get_buffer(), raw_buffer.get_size() };
+
+ if( vc5_decoder_process( &vc5_decoder_params, &vc5_image, &raw_image, NULL ) != CODEC_ERROR_OKAY )
+ {
+ assert(0);
+ return false;
+ }
+
+ raw_buffer.set( raw_image.buffer, raw_image.size, true );
+
+ dng_point size = image.Bounds().Size();
+
+ CopyBufferToRawImage( raw_buffer, size.h, image );
+
+ return true;
+}
+
+gpr_read_image::gpr_read_image( gpr_buffer_auto* vc5_buffer ) : _vc5_buffer(vc5_buffer)
+{
+ fReadVC5 = true;
+ fDecodeVC5 = true;
+}
+
+void gpr_read_image::ReadTile (dng_host &host,
+ const dng_ifd &ifd,
+ dng_stream &stream,
+ dng_image &image,
+ const dng_rect &tileArea,
+ uint32 plane,
+ uint32 planes,
+ uint32 tileByteCount,
+ AutoPtr<dng_memory_block> &compressedBuffer,
+ AutoPtr<dng_memory_block> &uncompressedBuffer,
+ AutoPtr<dng_memory_block> &subTileBlockBuffer)
+{
+
+ if( ifd.fCompression == ccVc5 )
+ {
+ if( GetReadVC5() && _vc5_buffer != NULL )
+ {
+ _vc5_buffer->allocate( tileByteCount );
+
+ stream.Get(_vc5_buffer->get_buffer(), _vc5_buffer->get_size() );
+
+ if( GetDecodeVC5() == true )
+ {
+ bool rggb_raw = (ifd.fCFAPattern[0][0] == 0) && (ifd.fCFAPattern[0][1] == 1) && (ifd.fCFAPattern[1][0] == 1) && (ifd.fCFAPattern[1][1] == 2);
+
+ VC5_DECODER_PIXEL_FORMAT pixel_format;
+
+ if( rggb_raw )
+ {
+ pixel_format = VC5_DECODER_PIXEL_FORMAT_RGGB_14;
+ }
+ else
+ {
+ pixel_format = VC5_DECODER_PIXEL_FORMAT_GBRG_12;
+ }
+
+ if( DecodeVC5( image, *_vc5_buffer, pixel_format ) )
+ {
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ dng_read_image::ReadTile (host,
+ ifd,
+ stream,
+ image,
+ tileArea,
+ plane,
+ planes,
+ tileByteCount,
+ compressedBuffer,
+ uncompressedBuffer,
+ subTileBlockBuffer);
+ }
+}
+
+#endif
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_read_image.h b/gpr/source/lib/gpr_sdk/private/gpr_read_image.h
new file mode 100755
index 0000000..c8aa534
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_read_image.h
@@ -0,0 +1,64 @@
+/*! @file gpr_read_image.h
+ *
+ * @brief Declaration of gpr_read_image class
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_READ_IMAGE
+#define GPR_READ_IMAGE
+
+#include "dng_read_image.h"
+#include "gpr_buffer_auto.h"
+
+#if GPR_READING
+
+class gpr_read_image : public dng_read_image
+{
+private:
+ gpr_buffer_auto* _vc5_buffer;
+
+ bool fReadVC5;
+
+ bool fDecodeVC5;
+
+public:
+
+ gpr_read_image( gpr_buffer_auto* vc5_buffer = NULL );
+
+ void SetReadVC5(bool read_vc5) { fReadVC5 = read_vc5; }
+ bool GetReadVC5() { return fReadVC5; }
+
+ void SetDecodeVC5(bool decode_vc5) { fDecodeVC5 = decode_vc5; }
+ bool GetDecodeVC5() { return fDecodeVC5; }
+
+ void ReadTile (dng_host &host,
+ const dng_ifd &ifd,
+ dng_stream &stream,
+ dng_image &image,
+ const dng_rect &tileArea,
+ uint32 plane,
+ uint32 planes,
+ uint32 tileByteCount,
+ AutoPtr<dng_memory_block> &compressedBuffer,
+ AutoPtr<dng_memory_block> &uncompressedBuffer,
+ AutoPtr<dng_memory_block> &subTileBlockBuffer);
+};
+
+#endif // GPR_READING
+
+#endif // GPR_READ_IMAGE
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_tuning_info.cpp b/gpr/source/lib/gpr_sdk/private/gpr_tuning_info.cpp
new file mode 100755
index 0000000..45ff9f7
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_tuning_info.cpp
@@ -0,0 +1,84 @@
+
+#include "gpr_buffer_auto.h"
+
+#include "gpr_tuning_info.h"
+
+static void _static_black_level_set_defaults(gpr_static_black_level* x)
+{
+ const int black = 0;
+
+ x->r_black = black;
+ x->g_r_black = black;
+ x->g_b_black = black;
+ x->b_black = black;
+}
+
+static void _ae_info_set_defaults(gpr_auto_exposure_info* x)
+{
+ x->iso_value = 228;
+ x->shutter_time = 34952;
+}
+
+static void _dgain_saturation_level_set_defaults(gpr_saturation_level* x)
+{
+ const int32_t saturation_level = 16383;
+
+ x->level_red = saturation_level;
+ x->level_green_even = saturation_level;
+ x->level_green_odd = saturation_level;
+ x->level_blue = saturation_level;
+}
+
+static void _wb_gains_set_defaults(gpr_white_balance_gains* x)
+{
+ x->r_gain = (float_t)6273.0 / 4096.0;
+ x->g_gain = (float_t)4096.0 / 4096.0;
+ x->b_gain = (float_t)8371.0 / 4096.0;
+}
+
+static void _gain_map_set_defaults( gpr_tuning_info* tuning_info )
+{
+ tuning_info->gain_map.size = 0;
+
+ tuning_info->gain_map.buffers[0] = NULL;
+ tuning_info->gain_map.buffers[1] = NULL;
+ tuning_info->gain_map.buffers[2] = NULL;
+ tuning_info->gain_map.buffers[3] = NULL;
+}
+
+int32_t gpr_tuning_info_get_dgain_saturation_level(const gpr_tuning_info* x, GPR_RAW_CHANNEL channel)
+{
+ switch(channel)
+ {
+ case RAW_CHANNEL_RED:
+ return x->dgain_saturation_level.level_red;
+ case RAW_CHANNEL_GREEN_EVEN:
+ return x->dgain_saturation_level.level_green_even;
+ case RAW_CHANNEL_GREEN_ODD:
+ return x->dgain_saturation_level.level_green_odd;
+ case RAW_CHANNEL_BLUE:
+ return x->dgain_saturation_level.level_blue;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+void gpr_tuning_info_set_defaults( gpr_tuning_info* x )
+{
+ x->orientation = ORIENTATION_DEFAULT;
+
+ _static_black_level_set_defaults(&x->static_black_level);
+
+ _dgain_saturation_level_set_defaults(&x->dgain_saturation_level);
+
+ _wb_gains_set_defaults(&x->wb_gains);
+
+ _ae_info_set_defaults(&x->ae_info);
+
+ _gain_map_set_defaults( x );
+
+ x->pixel_format = PIXEL_FORMAT_RGGB_14;
+}
+
+
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_utils.cpp b/gpr/source/lib/gpr_sdk/private/gpr_utils.cpp
new file mode 100755
index 0000000..7672fde
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_utils.cpp
@@ -0,0 +1,73 @@
+
+#include "gpr_utils.h"
+
+#include "dng_camera_profile.h"
+#include "dng_color_space.h"
+#include "dng_date_time.h"
+#include "dng_exceptions.h"
+#include "dng_file_stream.h"
+#include "dng_globals.h"
+#include "dng_host.h"
+#include "dng_ifd.h"
+#include "dng_image_writer.h"
+#include "dng_info.h"
+#include "dng_linearization_info.h"
+#include "dng_mosaic_info.h"
+#include "dng_negative.h"
+#include "dng_preview.h"
+#include "dng_render.h"
+#include "dng_simple_image.h"
+#include "dng_tag_codes.h"
+#include "dng_tag_types.h"
+#include "dng_tag_values.h"
+#include "dng_xmp.h"
+#include "dng_xmp_sdk.h"
+#include "dng_memory_stream.h"
+#include "dng_bottlenecks.h"
+
+#include "gpr_platform.h"
+#include "gpr_buffer_auto.h"
+
+void CopyRawImageToBuffer( const dng_image& raw_image, gpr_buffer_auto& buffer )
+{
+ dng_point size = raw_image.Bounds().Size();
+
+ const int raw_image_size = size.h * size.v * 2;
+
+ buffer.allocate( raw_image_size );
+
+ dng_pixel_buffer pixel_buffer;
+
+ pixel_buffer.fArea = dng_rect(size.v, size.h);
+ pixel_buffer.fPlane = 0;
+ pixel_buffer.fPlanes = 1;
+ pixel_buffer.fRowStep = size.h;
+ pixel_buffer.fColStep = pixel_buffer.fPlanes;
+ pixel_buffer.fPlaneStep = 1;
+ pixel_buffer.fPixelType = ttShort;
+ pixel_buffer.fPixelSize = TagTypeSize(ttShort);
+
+ pixel_buffer.fData = buffer.get_buffer();
+
+ raw_image.Get(pixel_buffer);
+}
+
+void CopyBufferToRawImage( const gpr_buffer_auto& buffer, size_t stride, dng_image& raw_image )
+{
+ dng_pixel_buffer pixel_buffer;
+
+ dng_point size = raw_image.Bounds().Size();
+
+ pixel_buffer.fArea = dng_rect(size.v, size.h);
+ pixel_buffer.fPlane = 0;
+ pixel_buffer.fPlanes = 1;
+ pixel_buffer.fRowStep = stride;
+ pixel_buffer.fColStep = pixel_buffer.fPlanes;
+ pixel_buffer.fPlaneStep = 1;
+ pixel_buffer.fPixelType = ttShort;
+ pixel_buffer.fPixelSize = TagTypeSize(ttShort);
+
+ pixel_buffer.fData = buffer.get_buffer();
+
+ raw_image.Put(pixel_buffer);
+}
diff --git a/gpr/source/lib/gpr_sdk/private/gpr_utils.h b/gpr/source/lib/gpr_sdk/private/gpr_utils.h
new file mode 100755
index 0000000..45e30f3
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/private/gpr_utils.h
@@ -0,0 +1,40 @@
+/*! @file gpr_utils.h
+ *
+ * @brief Declaration of general gpr functions that belong in gpr library
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_UTILS_H
+#define GPR_UTILS_H
+
+#include "gpr_buffer_auto.h"
+#include "dng_image.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ void CopyRawImageToBuffer( const dng_image& raw_image, gpr_buffer_auto& buffer );
+
+ void CopyBufferToRawImage( const gpr_buffer_auto& buffer, size_t buffer_stride, dng_image& raw_image );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GPR_UTILS_H
diff --git a/gpr/source/lib/gpr_sdk/public/gpr.h b/gpr/source/lib/gpr_sdk/public/gpr.h
new file mode 100755
index 0000000..666e727
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/public/gpr.h
@@ -0,0 +1,169 @@
+/*! @file gpr.h
+ *
+ * @brief Declaration of the GPR-SDK objects and functions
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_H
+#define GPR_H
+
+#include "gpr_platform.h"
+#include "gpr_exif_info.h"
+#include "gpr_profile_info.h"
+#include "gpr_tuning_info.h"
+#include "gpr_allocator.h"
+#include "gpr_buffer.h"
+#include "gpr_rgb_buffer.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ typedef struct
+ {
+ gpr_buffer jpg_preview; /* Address to the memory location that this buffer points to */
+
+ unsigned int preview_width; /* Width of input source in pixels (only applies to raw input) */
+
+ unsigned int preview_height; /* Height of input source in pixels (only applies to raw input) */
+
+ } gpr_preview_image;
+
+ typedef struct
+ {
+ unsigned int input_width; /* Width of input source in pixels (only applies to raw input) */
+
+ unsigned int input_height; /* Height of input source in pixels (only applies to raw input) */
+
+ unsigned int input_pitch; /* Pitch of input source in pixels (only applies to raw input) */
+
+ bool fast_encoding;
+
+ bool compute_md5sum;
+
+ gpr_buffer gpmf_payload; /* GPMF payload of image file */
+
+ gpr_preview_image preview_image; /* Preview JPG image */
+
+ bool enable_preview;
+
+ gpr_exif_info exif_info; /* Exif info object */
+
+ gpr_profile_info profile_info; /* Camera color profile info object */
+
+ gpr_tuning_info tuning_info; /* Camera tuning info object */
+
+ } gpr_parameters;
+
+ void gpr_parameters_set_defaults(gpr_parameters* x);
+
+ void gpr_parameters_construct_copy(const gpr_parameters* y, gpr_parameters* x);
+
+ void gpr_parameters_destroy(gpr_parameters* x, gpr_free mem_free);
+
+ //!< Parse Metadata of DNG File and return in gpr_parameters struct
+ bool gpr_parse_metadata(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_parameters* parameters);
+
+ //!< CHECK IF DNG IS VC5 COMPRESSED
+ bool gpr_check_vc5( gpr_buffer* inp_dng_buffer, gpr_malloc mem_alloc, gpr_free mem_free );
+
+ //!< CONVERSION FUNCTIONS
+
+ //!< raw to dng conversion
+ bool gpr_convert_raw_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_raw_buffer,
+ gpr_buffer* out_dng_buffer);
+
+ //!< dng to raw conversion
+ bool gpr_convert_dng_to_raw(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_raw_buffer);
+
+ //!< dng to raw conversion
+ bool gpr_convert_dng_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_dng_buffer);
+
+ //!< vc5 to gpr conversion
+ bool gpr_convert_vc5_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_vc5_buffer,
+ gpr_buffer* out_gpr_buffer);
+
+ //!< gpr to vc5 conversion
+ bool gpr_convert_gpr_to_vc5(const gpr_allocator* allocator,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_vc5_buffer);
+
+#if GPR_WRITING
+
+ //!< raw to gpr conversion
+ bool gpr_convert_raw_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_raw_buffer,
+ gpr_buffer* out_gpr_buffer);
+
+ //!< dng to gpr conversion
+ bool gpr_convert_dng_to_gpr(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_gpr_buffer);
+
+ //!< dng to vc5 conversion
+ bool gpr_convert_dng_to_vc5(const gpr_allocator* allocator,
+ gpr_buffer* inp_dng_buffer,
+ gpr_buffer* out_vc5_buffer);
+#endif // GPR_WRITING
+
+
+#if GPR_READING
+
+ //!< gpr to rgb conversion
+ bool gpr_convert_gpr_to_rgb(const gpr_allocator* allocator,
+ GPR_RGB_RESOLUTION rgb_resolution,
+ int rgb_bits,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_rgb_buffer* out_rgb_buffer);
+
+ //!< gpr to dng conversion
+ bool gpr_convert_gpr_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_dng_buffer);
+
+ //!< vc5 to dng conversion
+ bool gpr_convert_vc5_to_dng(const gpr_allocator* allocator,
+ const gpr_parameters* parameters,
+ gpr_buffer* inp_vc5_buffer,
+ gpr_buffer* out_dng_buffer);
+
+ //!< gpr to raw conversion
+ bool gpr_convert_gpr_to_raw(const gpr_allocator* allocator,
+ gpr_buffer* inp_gpr_buffer,
+ gpr_buffer* out_raw_buffer);
+#endif
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // GPR_H
diff --git a/gpr/source/lib/gpr_sdk/public/gpr_exif_info.h b/gpr/source/lib/gpr_sdk/public/gpr_exif_info.h
new file mode 100755
index 0000000..2917b25
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/public/gpr_exif_info.h
@@ -0,0 +1,352 @@
+/*! @file gpr_exif_info.h
+ *
+ * @brief Declaration of gpr_exif_info object and associated functions
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_EXIF_INFO
+#define GPR_EXIF_INFO
+
+#define CAMERA_MAKE_SIZE 32
+#define CAMERA_MODEL_SIZE 32
+#define CAMERA_SERIAL_SIZE 32
+#define SOFTWARE_VERSION_SIZE 32
+#define USER_COMMENT_SIZE 64
+#define SATELLITES_USED_SIZE 32
+#define SURVEY_DATA_SIZE 32
+#define PROCESSING_METHOD_SIZE 32
+#define AREA_INFORMATION_SIZE 32
+#define IMAGE_DESCRIPTION_SIZE 32
+
+#include "gpr_platform.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ typedef enum
+ {
+ gpr_sensing_method_chip_color_area = 2,
+
+ } gpr_sensing_method;
+
+ typedef enum
+ {
+ gpr_file_source_digital_still = 3,
+
+ } gpr_file_source;
+
+ typedef enum
+ {
+ gpr_scene_type_directly_photographed = 1,
+
+ } gpr_scene_type;
+
+ typedef enum
+ {
+ gpr_white_balance_auto = 0,
+
+ gpr_white_balance_manual = 1,
+
+ } gpr_white_balance;
+
+ typedef enum
+ {
+ gpr_exposure_mode_auto = 0,
+
+ gpr_exposure_mode_manual = 1,
+
+ gpr_exposure_mode_auto_bracket = 2,
+
+ } gpr_exposure_mode;
+
+ typedef enum
+ {
+ gpr_scene_capture_type_standard = 0,
+
+ gpr_scene_capture_type_landscape = 1,
+
+ gpr_scene_capture_type_portrait = 2,
+
+ gpr_scene_capture_type_night = 3,
+
+ } gpr_scene_capture_type;
+
+ typedef enum
+ {
+ gpr_contrast_normal = 0,
+
+ } gpr_contrast;
+
+ typedef enum
+ {
+ gpr_gain_control_normal = 0,
+
+ } gpr_gain_control;
+
+ typedef enum
+ {
+ gpr_saturation_normal = 0,
+
+ } gpr_saturation;
+
+ typedef enum
+ {
+ gpr_sharpness_normal = 0,
+
+ gpr_sharpness_soft = 1,
+
+ gpr_sharpness_hard = 2,
+
+ } gpr_sharpness;
+
+ typedef enum
+ {
+ gpr_flash_not_used = 0,
+
+ gpr_flash_used = 1,
+
+ gpr_flash_not_supported = 32,
+
+ } gpr_flash;
+
+ typedef enum
+ {
+ gpr_exposure_program_manual_control = 1,
+
+ gpr_exposure_program_normal = 2,
+
+ gpr_exposure_program_aperture_priority = 3,
+
+ gpr_exposure_program_shutter_priority = 4,
+
+ gpr_exposure_program_creative = 5,
+
+ gpr_exposure_program_action = 6,
+
+ gpr_exposure_program_portrait_mode = 7,
+
+ gpr_exposure_program_landscape_mode = 8,
+
+ } gpr_exposure_program;
+
+ typedef enum
+ {
+ gpr_metering_mode_average = 1,
+
+ gpr_metering_mode_center_weighted_average = 2,
+
+ gpr_metering_mode_spot = 3,
+
+ gpr_metering_mode_multi_spot = 4,
+
+ gpr_metering_mode_multi_segment = 5,
+
+ } gpr_metering_mode;
+
+ typedef enum
+ {
+ gpr_light_source_auto = 0,
+
+ gpr_light_source_daylight = 1,
+
+ gpr_light_source_fuorescent = 2,
+
+ gpr_light_source_tungsten = 3,
+
+ } gpr_light_source; // See this link for more info: http://www.awaresystems.be/imaging/tiff/tifftags/privateifd/exif/lightsource.html
+
+ /*****************************************************************************/
+
+ typedef struct
+ {
+ int32_t numerator; // Numerator
+
+ int32_t denominator; // Denominator
+
+ } gpr_signed_rational;
+
+ typedef struct
+ {
+ uint32_t numerator; // Numerator
+
+ uint32_t denominator; // Denominator
+
+ } gpr_unsigned_rational;
+
+ typedef struct
+ {
+ uint32_t year;
+
+ uint32_t month;
+
+ uint32_t day;
+
+ uint32_t hour;
+
+ uint32_t minute;
+
+ uint32_t second;
+
+ } gpr_date_and_time;
+
+ typedef struct
+ {
+ bool gps_info_valid;
+
+ uint32_t version_id;
+
+ char latitude_ref[2];
+
+ gpr_unsigned_rational latitude[3];
+
+ char longitude_ref[2];
+
+ gpr_unsigned_rational longitude[3];
+
+ uint8_t altitude_ref;
+
+ gpr_unsigned_rational altitude;
+
+ gpr_unsigned_rational time_stamp[3];
+
+ char satellites[SATELLITES_USED_SIZE];
+
+ char status[2];
+
+ char measure_mode[2];
+
+ gpr_unsigned_rational dop;
+
+ char speed_ref[2];
+
+ gpr_unsigned_rational speed;
+
+ char track_ref[2];
+
+ gpr_unsigned_rational track;
+
+ char img_direction_ref[2];
+
+ gpr_unsigned_rational img_direction;
+
+ char map_datum[SURVEY_DATA_SIZE];
+
+ char dest_latitude_ref[2];
+
+ gpr_unsigned_rational dest_latitude[3];
+
+ char dest_longitude_ref[2];
+
+ gpr_unsigned_rational dest_longitude[3];
+
+ char dest_bearing_ref[2];
+
+ gpr_unsigned_rational dest_bearing;
+
+ char dest_distance_ref[2];
+
+ gpr_unsigned_rational dest_distance;
+
+ char processing_method[PROCESSING_METHOD_SIZE];
+
+ char area_information[AREA_INFORMATION_SIZE];
+
+ char date_stamp[11];
+
+ unsigned short differential;
+
+ } gpr_gps_info;
+
+ typedef struct
+ {
+ char camera_make[CAMERA_MAKE_SIZE];
+
+ char camera_model[CAMERA_MODEL_SIZE];
+
+ char camera_serial[CAMERA_SERIAL_SIZE];
+
+ char software_version[SOFTWARE_VERSION_SIZE];
+
+ char user_comment[USER_COMMENT_SIZE];
+
+ char image_description[IMAGE_DESCRIPTION_SIZE];
+
+ gpr_unsigned_rational exposure_time; /* exposure time (as fraction) */
+
+ gpr_unsigned_rational f_stop_number; /* f-stop number (as fraction) */
+
+ gpr_unsigned_rational aperture; /* aperture */
+
+ gpr_exposure_program exposure_program;
+
+ uint16_t iso_speed_rating;
+
+ gpr_date_and_time date_time_original;
+
+ gpr_date_and_time date_time_digitized;
+
+ gpr_signed_rational exposure_bias;
+
+ gpr_metering_mode metering_mode;
+
+ gpr_light_source light_source;
+
+ gpr_flash flash;
+
+ gpr_unsigned_rational focal_length;
+
+ gpr_sharpness sharpness;
+
+ uint16_t saturation;
+
+ gpr_gain_control gain_control;
+
+ gpr_contrast contrast;
+
+ gpr_scene_capture_type scene_capture_type;
+
+ gpr_exposure_mode exposure_mode;
+
+ uint16_t focal_length_in_35mm_film;
+
+ gpr_unsigned_rational digital_zoom;
+
+ gpr_white_balance white_balance;
+
+ gpr_scene_type scene_type;
+
+ gpr_file_source file_source;
+
+ gpr_sensing_method sensing_method;
+
+ gpr_gps_info gps_info;
+
+ } gpr_exif_info;
+
+ void gpr_exif_info_set_defaults( gpr_exif_info* x );
+
+ void gpr_exif_info_get_camera_make_and_model( const gpr_exif_info* x, char camera_make_and_model[256] );
+
+ gpr_date_and_time construct_gpr_date_and_time (uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // GPR_EXIF_INFO
diff --git a/gpr/source/lib/gpr_sdk/public/gpr_profile_info.h b/gpr/source/lib/gpr_sdk/public/gpr_profile_info.h
new file mode 100755
index 0000000..5fc37b3
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/public/gpr_profile_info.h
@@ -0,0 +1,60 @@
+/*! @file gpr_profile_info.h
+ *
+ * @brief Declaration of gpr_profile_info object and associated functions
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_PROFILE_INFO_H
+#define GPR_PROFILE_INFO_H
+
+#include "gpr_platform.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ typedef double Matrix[3][3];
+
+ typedef struct
+ {
+
+ bool compute_color_matrix;
+
+ double matrix_weighting;
+
+ double wb1[3];
+ double wb2[3];
+
+ Matrix cam_to_srgb_1;
+ Matrix cam_to_srgb_2;
+
+ Matrix color_matrix_1;
+ Matrix color_matrix_2;
+
+ uint16_t illuminant1;
+ uint16_t illuminant2;
+
+ } gpr_profile_info;
+
+ void gpr_profile_info_set_defaults(gpr_profile_info* x);
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // GPR_PROFILE_INFO_H
diff --git a/gpr/source/lib/gpr_sdk/public/gpr_tuning_info.h b/gpr/source/lib/gpr_sdk/public/gpr_tuning_info.h
new file mode 100755
index 0000000..677d68d
--- /dev/null
+++ b/gpr/source/lib/gpr_sdk/public/gpr_tuning_info.h
@@ -0,0 +1,149 @@
+/*! @file gpr_tuning_info.h
+ *
+ * @brief Declaration of gpr_tuning_info object and associated functions
+ *
+ * GPR API can be invoked by simply including this header file.
+ * This file includes all other header files that are needed.
+ *
+ * (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.
+ */
+
+#ifndef GPR_TUNING_INFO_H
+#define GPR_TUNING_INFO_H
+
+#include "gpr_platform.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+ typedef enum
+ {
+ RAW_CHANNEL_RED = 0,
+
+ RAW_CHANNEL_GREEN_EVEN = 1,
+
+ RAW_CHANNEL_GREEN_ODD = 2,
+
+ RAW_CHANNEL_BLUE = 3,
+
+ } GPR_RAW_CHANNEL;
+
+ typedef enum
+ {
+ PIXEL_FORMAT_RGGB_12 = 0, // RGGB 12bit pixels packed into 16bits
+
+ PIXEL_FORMAT_RGGB_12P = 1, // RGGB 12bit pixels packed into 12bits
+
+ PIXEL_FORMAT_RGGB_14 = 2, // RGGB 14bit pixels packed into 16bits
+
+ PIXEL_FORMAT_GBRG_12 = 3, // GBRG 12bit pixels packed into 16bits
+
+ PIXEL_FORMAT_GBRG_12P = 4, // GBRG 12bit pixels packed into 12bits
+
+ } GPR_PIXEL_FORMAT;
+
+ typedef enum
+ {
+ ORIENTATION_NORMAL = 0,
+
+ ORIENTATION_MIRROR = 4,
+
+ ORIENTATION_DEFAULT = ORIENTATION_MIRROR,
+
+ } GPR_ORIENTATION;
+
+ typedef struct
+ {
+ int32_t r_black;
+
+ int32_t g_r_black;
+
+ int32_t g_b_black;
+
+ int32_t b_black;
+
+ } gpr_static_black_level;
+
+ typedef struct
+ {
+ uint16_t iso_value;
+
+ uint32_t shutter_time;
+
+ } gpr_auto_exposure_info;
+
+ typedef struct
+ {
+ int32_t level_red;
+
+ int32_t level_green_even;
+
+ int32_t level_green_odd;
+
+ int32_t level_blue;
+
+ } gpr_saturation_level;
+
+ typedef struct
+ {
+ float_t r_gain;
+
+ float_t g_gain;
+
+ float_t b_gain;
+
+ } gpr_white_balance_gains;
+
+ typedef struct
+ {
+ char *buffers[4];
+
+ uint32_t size;
+
+ } gpr_gain_map;
+
+ typedef struct
+ {
+ GPR_ORIENTATION orientation;
+
+ gpr_static_black_level static_black_level;
+
+ gpr_saturation_level dgain_saturation_level;
+
+ gpr_white_balance_gains wb_gains;
+
+ gpr_auto_exposure_info ae_info;
+
+ double noise_scale;
+ double noise_offset;
+
+ double warp_red_coefficient;
+ double warp_blue_coefficient;
+
+ gpr_gain_map gain_map;
+
+ GPR_PIXEL_FORMAT pixel_format;
+
+ } gpr_tuning_info;
+
+ int32_t gpr_tuning_info_get_dgain_saturation_level(const gpr_tuning_info* x, GPR_RAW_CHANNEL channel);
+
+ void gpr_tuning_info_set_defaults( gpr_tuning_info* x );
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // GPR_TUNING_INFO_H