Write more metadata using libdng
This commit is contained in:
146
src/dcp.c
146
src/dcp.c
@@ -2,154 +2,8 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned int
|
||||
get_int32(const unsigned char *buffer, size_t offset)
|
||||
{
|
||||
return (buffer[offset + 3] << 24) | (buffer[offset + 2] << 16) |
|
||||
(buffer[offset + 1] << 8) | (buffer[offset]);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
get_int16(const unsigned char *buffer, size_t offset)
|
||||
{
|
||||
return (buffer[offset + 1] << 8) | (buffer[offset]);
|
||||
}
|
||||
|
||||
float
|
||||
get_float(unsigned char *buffer, size_t offset)
|
||||
{
|
||||
float f;
|
||||
unsigned char b[] = { buffer[offset + 0],
|
||||
buffer[offset + 1],
|
||||
buffer[offset + 2],
|
||||
buffer[offset + 3] };
|
||||
memcpy(&f, &b, sizeof(f));
|
||||
return f;
|
||||
}
|
||||
|
||||
float
|
||||
get_srational(unsigned char *buffer, size_t offset)
|
||||
{
|
||||
int a = (int)get_int32(buffer, offset);
|
||||
int b = (int)get_int32(buffer, offset + 4);
|
||||
return (float)a / (float)b;
|
||||
}
|
||||
|
||||
struct MPCameraCalibration
|
||||
parse_calibration_file(const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
size_t size;
|
||||
unsigned char *buffer;
|
||||
|
||||
struct MPCameraCalibration result = { 0 };
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
buffer = malloc(sizeof(char) * size);
|
||||
size_t ret = fread(buffer, 1, size, fp);
|
||||
if (ret != size) {
|
||||
return result;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
if (buffer[0] != 'I' || buffer[1] != 'I') {
|
||||
fprintf(stderr, "Magic for DCP file incorrect\n");
|
||||
return result;
|
||||
}
|
||||
if (buffer[2] != 0x52 || buffer[3] != 0x43) {
|
||||
fprintf(stderr, "Invalid DCP version\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int ifd0 = get_int32(buffer, 4);
|
||||
unsigned int tag_count = get_int16(buffer, ifd0);
|
||||
|
||||
for (int i = 0; i < tag_count; i++) {
|
||||
int tag_offset = ifd0 + 2 + (i * 12);
|
||||
unsigned int tag = get_int16(buffer, tag_offset + 0);
|
||||
unsigned int type = get_int16(buffer, tag_offset + 2);
|
||||
unsigned int count = get_int32(buffer, tag_offset + 4);
|
||||
unsigned int offset = get_int32(buffer, tag_offset + 8);
|
||||
|
||||
switch (tag) {
|
||||
case DCPTAG_COLOR_MATRIX_1:
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float point =
|
||||
get_srational(buffer, offset + (j * 8));
|
||||
result.color_matrix_1[j] = point;
|
||||
}
|
||||
break;
|
||||
case DCPTAG_COLOR_MATRIX_2:
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float point =
|
||||
get_srational(buffer, offset + (j * 8));
|
||||
result.color_matrix_2[j] = point;
|
||||
}
|
||||
break;
|
||||
case DCPTAG_FORWARD_MATRIX_1:
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float point =
|
||||
get_srational(buffer, offset + (j * 8));
|
||||
result.forward_matrix_1[j] = point;
|
||||
}
|
||||
break;
|
||||
case DCPTAG_FORWARD_MATRIX_2:
|
||||
for (int j = 0; j < 9; j++) {
|
||||
float point =
|
||||
get_srational(buffer, offset + (j * 8));
|
||||
result.forward_matrix_2[j] = point;
|
||||
}
|
||||
break;
|
||||
case DCPTAG_CALIBRATION_ILLUMINANT_1:
|
||||
result.illuminant_1 = offset;
|
||||
break;
|
||||
case DCPTAG_CALIBRATION_ILLUMINANT_2:
|
||||
result.illuminant_2 = offset;
|
||||
break;
|
||||
case DCPTAG_PROFILE_TONE_CURVE:
|
||||
result.tone_curve = malloc(count * sizeof(float));
|
||||
result.tone_curve_length = count;
|
||||
for (int j = 0; j < count; j++) {
|
||||
result.tone_curve[j] =
|
||||
get_float(buffer, offset + (j * 4));
|
||||
}
|
||||
break;
|
||||
case DCPTAG_PROFILE_HUE_SAT_MAP_DIMS:
|
||||
result.hue_sat_map_dims[0] = get_int32(buffer, offset);
|
||||
result.hue_sat_map_dims[1] = get_int32(buffer, offset + 4);
|
||||
result.hue_sat_map_dims[2] = get_int32(buffer, offset + 8);
|
||||
break;
|
||||
case DCPTAG_PROFILE_HUE_SAT_MAP_DATA_1:
|
||||
result.hue_sat_map_data_1 = malloc(count * sizeof(float));
|
||||
for (int j = 0; j < count; j++) {
|
||||
result.hue_sat_map_data_1[j] =
|
||||
get_float(buffer, offset + (j * 4));
|
||||
}
|
||||
break;
|
||||
case DCPTAG_PROFILE_HUE_SAT_MAP_DATA_2:
|
||||
result.hue_sat_map_data_2 = malloc(count * sizeof(float));
|
||||
for (int j = 0; j < count; j++) {
|
||||
result.hue_sat_map_data_2[j] =
|
||||
get_float(buffer, offset + (j * 4));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
find_calibration_by_model(char *conffile, char *model, const char *sensor)
|
||||
{
|
||||
|
Reference in New Issue
Block a user