37#include <libraw/libraw.h>
40typedef struct model_map
42 const gchar *exif_make;
44 const gchar *clean_make;
45 const gchar *clean_model;
46 const gchar *clean_alias;
51const model_map_t modelMap[] = {
54 .exif_model =
"Canon EOS R",
55 .clean_make =
"Canon",
56 .clean_model =
"EOS R",
57 .clean_alias =
"EOS R"
61 .exif_model =
"Canon EOS RP",
62 .clean_make =
"Canon",
63 .clean_model =
"EOS RP",
64 .clean_alias =
"EOS RP"
68 .exif_model =
"Canon EOS R5",
69 .clean_make =
"Canon",
70 .clean_model =
"EOS R5",
71 .clean_alias =
"EOS R5"
75 .exif_model =
"Canon EOS R6",
76 .clean_make =
"Canon",
77 .clean_model =
"EOS R6",
78 .clean_alias =
"EOS R6"
82 .exif_model =
"Canon EOS R3",
83 .clean_make =
"Canon",
84 .clean_model =
"EOS R3",
85 .clean_alias =
"EOS R3"
89 .exif_model =
"Canon EOS R7",
90 .clean_make =
"Canon",
91 .clean_model =
"EOS R7",
92 .clean_alias =
"EOS R7"
96 .exif_model =
"Canon EOS R10",
97 .clean_make =
"Canon",
98 .clean_model =
"EOS R10",
99 .clean_alias =
"EOS R10"
102 .exif_make =
"Canon",
103 .exif_model =
"Canon EOS M50",
104 .clean_make =
"Canon",
105 .clean_model =
"EOS M50",
106 .clean_alias =
"EOS M50"
109 .exif_make =
"Canon",
110 .exif_model =
"Canon EOS KISS M",
111 .clean_make =
"Canon",
112 .clean_model =
"EOS M50",
113 .clean_alias =
"EOS KISS M"
116 .exif_make =
"Canon",
117 .exif_model =
"Canon EOS M50m2",
118 .clean_make =
"Canon",
119 .clean_model =
"EOS M50 Mark II",
120 .clean_alias =
"EOS M50 Mark II"
123 .exif_make =
"Canon",
124 .exif_model =
"Canon EOS KISS M2",
125 .clean_make =
"Canon",
126 .clean_model =
"EOS M50 Mark II",
127 .clean_alias =
"EOS KISS M2"
130 .exif_make =
"Canon",
131 .exif_model =
"Canon EOS M6 Mark II",
132 .clean_make =
"Canon",
133 .clean_model =
"EOS M6 Mark II",
134 .clean_alias =
"EOS M6 Mark II"
137 .exif_make =
"Canon",
138 .exif_model =
"Canon EOS M200",
139 .clean_make =
"Canon",
140 .clean_model =
"EOS M200",
141 .clean_alias =
"EOS M200"
144 .exif_make =
"Canon",
145 .exif_model =
"Canon EOS 250D",
146 .clean_make =
"Canon",
147 .clean_model =
"EOS 250D",
148 .clean_alias =
"EOS 250D"
151 .exif_make =
"Canon",
152 .exif_model =
"Canon EOS Kiss X10",
153 .clean_make =
"Canon",
154 .clean_model =
"EOS 250D",
155 .clean_alias =
"EOS Kiss X10"
158 .exif_make =
"Canon",
159 .exif_model =
"Canon EOS Rebel SL3",
160 .clean_make =
"Canon",
161 .clean_model =
"EOS 250D",
162 .clean_alias =
"EOS Rebel SL3"
165 .exif_make =
"Canon",
166 .exif_model =
"Canon EOS 200D II",
167 .clean_make =
"Canon",
168 .clean_model =
"EOS 250D",
169 .clean_alias =
"EOS 200D Mark II"
172 .exif_make =
"Canon",
173 .exif_model =
"Canon EOS 850D",
174 .clean_make =
"Canon",
175 .clean_model =
"EOS 850D",
176 .clean_alias =
"EOS 850D"
179 .exif_make =
"Canon",
180 .exif_model =
"Canon EOS Kiss X10i",
181 .clean_make =
"Canon",
182 .clean_model =
"EOS 850D",
183 .clean_alias =
"EOS Kiss X10i"
186 .exif_make =
"Canon",
187 .exif_model =
"Canon EOS Rebel T8i",
188 .clean_make =
"Canon",
189 .clean_model =
"EOS 850D",
190 .clean_alias =
"EOS Rebel T8i"
193 .exif_make =
"Canon",
194 .exif_model =
"Canon EOS 90D",
195 .clean_make =
"Canon",
196 .clean_model =
"EOS 90D",
197 .clean_alias =
"EOS 90D"
200 .exif_make =
"Canon",
201 .exif_model =
"Canon EOS-1D X Mark III",
202 .clean_make =
"Canon",
203 .clean_model =
"EOS-1D X Mark III",
204 .clean_alias =
"EOS-1D X Mark III"
207 .exif_make =
"Canon",
208 .exif_model =
"Canon PowerShot G7 X Mark III",
209 .clean_make =
"Canon",
210 .clean_model =
"PowerShot G7 X Mark III",
211 .clean_alias =
"PowerShot G7 X Mark III"
214 .exif_make =
"Canon",
215 .exif_model =
"Canon PowerShot G5 X Mark II",
216 .clean_make =
"Canon",
217 .clean_model =
"PowerShot G5 X Mark II",
218 .clean_alias =
"PowerShot G5 X Mark II"
223 char *mk,
int mk_len,
char *md,
int md_len,
224 char *al,
int al_len)
226 for(
int i = 0;
i <
sizeof(modelMap) /
sizeof(modelMap[0]); ++
i)
228 if(!g_strcmp0(
maker, modelMap[
i].exif_make) && !g_strcmp0(
model, modelMap[
i].exif_model))
231 g_strlcpy(mk, modelMap[
i].clean_make, mk_len);
232 g_strlcpy(md, modelMap[
i].clean_model, md_len);
233 g_strlcpy(al, modelMap[
i].clean_alias, al_len);
244 int libraw_err = LIBRAW_SUCCESS;
247 libraw_data_t *raw = libraw_init(0);
250#if defined(_WIN32) && (defined(UNICODE) || defined(_UNICODE))
251 wchar_t *wfilename = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
252 libraw_err = libraw_open_wfile(raw, wfilename);
255 libraw_err = libraw_open_file(raw, filename);
257 if(libraw_err != LIBRAW_SUCCESS)
goto error;
259 libraw_err = libraw_unpack(raw);
260 if(libraw_err != LIBRAW_SUCCESS)
goto error;
266 if(raw->rawdata.color.cam_mul[0] == 0.0f || isnan(raw->rawdata.color.cam_mul[0]) ||
IS_NULL_PTR(raw->rawdata.raw_image))
268 fprintf(stderr,
"[libraw_open] detected unsupported image `%s'\n", img->
filename);
273 img->
raw_white_point = raw->rawdata.color.linear_max[0] ? raw->rawdata.color.linear_max[0] :raw->rawdata.color.maximum;
277 for(
size_t c = 0;
c < 4; ++
c)
281 for(
size_t c = 0;
c < 4; ++
c)
282 img->
wb_coeffs[c] = raw->rawdata.color.cam_mul[c];
285 for(
int k = 0;
k < 4;
k++)
286 for(
int i = 0;
i < 3;
i++)
290 img->
width = raw->rawdata.sizes.raw_width;
291 img->
height = raw->rawdata.sizes.raw_height;
294 libraw_raw_inset_crop_t *ric = &raw->rawdata.sizes.raw_inset_crops[0];
297 img->
crop_width = raw->rawdata.sizes.raw_width - ric->cwidth - ric->cleft;
298 img->
crop_height = raw->rawdata.sizes.raw_height - ric->cheight - ric->ctop;
302 libraw_err = libraw_dcraw_process(raw);
303 if(libraw_err != LIBRAW_SUCCESS)
goto error;
316 img->
dsc.
bpp =
sizeof(uint16_t);
325 img->
flags &= ~DT_IMAGE_4BAYER;
330 img->
flags &= ~DT_IMAGE_LDR;
331 img->
flags &= ~DT_IMAGE_HDR;
337 img->
flags &= ~DT_IMAGE_RAW;
338 img->
flags &= ~DT_IMAGE_HDR;
354 fprintf(stderr,
"[libraw_open] could not alloc full buffer for image `%s'\n", img->
filename);
359 const size_t bufSize_mipmap = (size_t)img->
width * img->
height *
sizeof(uint16_t);
360 const size_t bufSize_libraw = (size_t)raw->rawdata.sizes.raw_pitch * raw->rawdata.sizes.raw_height;
361 if(bufSize_mipmap == bufSize_libraw)
363 memcpy(buf, raw->rawdata.raw_image, bufSize_mipmap);
368 raw->rawdata.sizes.raw_width, raw->rawdata.sizes.raw_height,
369 raw->rawdata.sizes.raw_width, raw->rawdata.sizes.raw_height,
376 if(libraw_err != LIBRAW_SUCCESS)
377 fprintf(stderr,
"[libraw_open] `%s': %s\n", img->
filename, libraw_strerror(libraw_err));
static void error(char *msg)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
int dt_exif_read(dt_image_t *img, const char *path)
What a photograph says about itself: the EXIF, IPTC and XMP tags a camera and a cataloguer write,...
@ DT_IMAGEIO_FILE_CORRUPTED
__DT_CLONE_TARGETS__ void dt_imageio_flip_buffers(char *out, const char *in, const size_t bpp, const int wd, const int ht, const int fwd, const int fht, const int stride, const dt_image_orientation_t orientation)
#define FILTERS_ARE_4BAYER(filters)
dt_imageio_retval_t dt_imageio_open_libraw(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *buf)
gboolean dt_libraw_lookup_makermodel(const char *maker, const char *model, char *mk, int mk_len, char *md, int md_len, char *al, int al_len)
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
float adobe_XYZ_to_CAM[4][3]
char filename[DT_MAX_FILENAME_LEN]
uint16_t raw_black_level_separate[4]
dt_aligned_pixel_t wb_coeffs
dt_iop_buffer_type_t datatype