123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #include "dcp.h"
- #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)
- {
- // Check config/%model,%sensor.dcp in the current working directory
- sprintf(conffile, "config/%s,%s.dcp", model, sensor);
- if (access(conffile, F_OK) != -1) {
- printf("Found calibration file at %s\n", conffile);
- return true;
- }
- // Check user overridden /etc/megapixels/config/%model,%sensor.dcp
- sprintf(conffile,
- "%s/megapixels/config/%s,%s.dcp",
- "/etc",
- model,
- sensor);
- if (access(conffile, F_OK) != -1) {
- printf("Found calibration file at %s\n", conffile);
- return true;
- }
- // Check packaged /usr/share/megapixels/config/%model,%sensor.ini
- sprintf(conffile, "%s/megapixels/config/%s,%s.dcp", "/usr/share", model, sensor);
- if (access(conffile, F_OK) != -1) {
- printf("Found calibration file at %s\n", conffile);
- return true;
- }
- printf("No calibration found for %s,%s\n", model, sensor);
- return false;
- }
- bool
- find_calibration(char *conffile, const char *sensor)
- {
- char model[512];
- FILE *fp;
- if (access("/proc/device-tree/compatible", F_OK) == -1) {
- return false;
- }
- fp = fopen("/proc/device-tree/compatible", "r");
- char *modelptr = model;
- while (1) {
- int c = fgetc(fp);
- if (c == EOF) {
- *(modelptr) = '\0';
- return find_calibration_by_model(conffile, model, sensor);
- }
- *(modelptr++) = (char)c;
- if (c == 0) {
- bool res =
- find_calibration_by_model(conffile, model, sensor);
- if (res) {
- return true;
- }
- modelptr = model;
- }
- }
- }
|