39#include <libraw/libraw.h>
42typedef struct model_map
44 const gchar *exif_make;
46 const gchar *clean_make;
47 const gchar *clean_model;
48 const gchar *clean_alias;
53const model_map_t modelMap[] = {
56 .exif_model =
"Canon EOS R",
57 .clean_make =
"Canon",
58 .clean_model =
"EOS R",
59 .clean_alias =
"EOS R"
63 .exif_model =
"Canon EOS RP",
64 .clean_make =
"Canon",
65 .clean_model =
"EOS RP",
66 .clean_alias =
"EOS RP"
70 .exif_model =
"Canon EOS R5",
71 .clean_make =
"Canon",
72 .clean_model =
"EOS R5",
73 .clean_alias =
"EOS R5"
77 .exif_model =
"Canon EOS R6",
78 .clean_make =
"Canon",
79 .clean_model =
"EOS R6",
80 .clean_alias =
"EOS R6"
84 .exif_model =
"Canon EOS R3",
85 .clean_make =
"Canon",
86 .clean_model =
"EOS R3",
87 .clean_alias =
"EOS R3"
91 .exif_model =
"Canon EOS R7",
92 .clean_make =
"Canon",
93 .clean_model =
"EOS R7",
94 .clean_alias =
"EOS R7"
98 .exif_model =
"Canon EOS R10",
99 .clean_make =
"Canon",
100 .clean_model =
"EOS R10",
101 .clean_alias =
"EOS R10"
104 .exif_make =
"Canon",
105 .exif_model =
"Canon EOS M50",
106 .clean_make =
"Canon",
107 .clean_model =
"EOS M50",
108 .clean_alias =
"EOS M50"
111 .exif_make =
"Canon",
112 .exif_model =
"Canon EOS KISS M",
113 .clean_make =
"Canon",
114 .clean_model =
"EOS M50",
115 .clean_alias =
"EOS KISS M"
118 .exif_make =
"Canon",
119 .exif_model =
"Canon EOS M50m2",
120 .clean_make =
"Canon",
121 .clean_model =
"EOS M50 Mark II",
122 .clean_alias =
"EOS M50 Mark II"
125 .exif_make =
"Canon",
126 .exif_model =
"Canon EOS KISS M2",
127 .clean_make =
"Canon",
128 .clean_model =
"EOS M50 Mark II",
129 .clean_alias =
"EOS KISS M2"
132 .exif_make =
"Canon",
133 .exif_model =
"Canon EOS M6 Mark II",
134 .clean_make =
"Canon",
135 .clean_model =
"EOS M6 Mark II",
136 .clean_alias =
"EOS M6 Mark II"
139 .exif_make =
"Canon",
140 .exif_model =
"Canon EOS M200",
141 .clean_make =
"Canon",
142 .clean_model =
"EOS M200",
143 .clean_alias =
"EOS M200"
146 .exif_make =
"Canon",
147 .exif_model =
"Canon EOS 250D",
148 .clean_make =
"Canon",
149 .clean_model =
"EOS 250D",
150 .clean_alias =
"EOS 250D"
153 .exif_make =
"Canon",
154 .exif_model =
"Canon EOS Kiss X10",
155 .clean_make =
"Canon",
156 .clean_model =
"EOS 250D",
157 .clean_alias =
"EOS Kiss X10"
160 .exif_make =
"Canon",
161 .exif_model =
"Canon EOS Rebel SL3",
162 .clean_make =
"Canon",
163 .clean_model =
"EOS 250D",
164 .clean_alias =
"EOS Rebel SL3"
167 .exif_make =
"Canon",
168 .exif_model =
"Canon EOS 200D II",
169 .clean_make =
"Canon",
170 .clean_model =
"EOS 250D",
171 .clean_alias =
"EOS 200D Mark II"
174 .exif_make =
"Canon",
175 .exif_model =
"Canon EOS 850D",
176 .clean_make =
"Canon",
177 .clean_model =
"EOS 850D",
178 .clean_alias =
"EOS 850D"
181 .exif_make =
"Canon",
182 .exif_model =
"Canon EOS Kiss X10i",
183 .clean_make =
"Canon",
184 .clean_model =
"EOS 850D",
185 .clean_alias =
"EOS Kiss X10i"
188 .exif_make =
"Canon",
189 .exif_model =
"Canon EOS Rebel T8i",
190 .clean_make =
"Canon",
191 .clean_model =
"EOS 850D",
192 .clean_alias =
"EOS Rebel T8i"
195 .exif_make =
"Canon",
196 .exif_model =
"Canon EOS 90D",
197 .clean_make =
"Canon",
198 .clean_model =
"EOS 90D",
199 .clean_alias =
"EOS 90D"
202 .exif_make =
"Canon",
203 .exif_model =
"Canon EOS-1D X Mark III",
204 .clean_make =
"Canon",
205 .clean_model =
"EOS-1D X Mark III",
206 .clean_alias =
"EOS-1D X Mark III"
209 .exif_make =
"Canon",
210 .exif_model =
"Canon PowerShot G7 X Mark III",
211 .clean_make =
"Canon",
212 .clean_model =
"PowerShot G7 X Mark III",
213 .clean_alias =
"PowerShot G7 X Mark III"
216 .exif_make =
"Canon",
217 .exif_model =
"Canon PowerShot G5 X Mark II",
218 .clean_make =
"Canon",
219 .clean_model =
"PowerShot G5 X Mark II",
220 .clean_alias =
"PowerShot G5 X Mark II"
225 char *mk,
int mk_len,
char *md,
int md_len,
226 char *al,
int al_len)
228 for(
int i = 0;
i <
sizeof(modelMap) /
sizeof(modelMap[0]); ++
i)
230 if(!g_strcmp0(
maker, modelMap[
i].exif_make) && !g_strcmp0(
model, modelMap[
i].exif_model))
233 g_strlcpy(mk, modelMap[
i].clean_make, mk_len);
234 g_strlcpy(md, modelMap[
i].clean_model, md_len);
235 g_strlcpy(al, modelMap[
i].clean_alias, al_len);
246 int libraw_err = LIBRAW_SUCCESS;
249 libraw_data_t *raw = libraw_init(0);
252#if defined(_WIN32) && (defined(UNICODE) || defined(_UNICODE))
253 wchar_t *wfilename = g_utf8_to_utf16(filename, -1, NULL, NULL, NULL);
254 libraw_err = libraw_open_wfile(raw, wfilename);
257 libraw_err = libraw_open_file(raw, filename);
259 if(libraw_err != LIBRAW_SUCCESS)
goto error;
261 libraw_err = libraw_unpack(raw);
262 if(libraw_err != LIBRAW_SUCCESS)
goto error;
268 if(raw->rawdata.color.cam_mul[0] == 0.0f || isnan(raw->rawdata.color.cam_mul[0]) ||
IS_NULL_PTR(raw->rawdata.raw_image))
270 fprintf(stderr,
"[libraw_open] detected unsupported image `%s'\n", img->
filename);
275 img->
raw_white_point = raw->rawdata.color.linear_max[0] ? raw->rawdata.color.linear_max[0] :raw->rawdata.color.maximum;
279 for(
size_t c = 0;
c < 4; ++
c)
283 for(
size_t c = 0;
c < 4; ++
c)
284 img->
wb_coeffs[c] = raw->rawdata.color.cam_mul[c];
287 for(
int k = 0;
k < 4;
k++)
288 for(
int i = 0;
i < 3;
i++)
292 img->
width = raw->rawdata.sizes.raw_width;
293 img->
height = raw->rawdata.sizes.raw_height;
296 libraw_raw_inset_crop_t *ric = &raw->rawdata.sizes.raw_inset_crops[0];
299 img->
crop_width = raw->rawdata.sizes.raw_width - ric->cwidth - ric->cleft;
300 img->
crop_height = raw->rawdata.sizes.raw_height - ric->cheight - ric->ctop;
304 libraw_err = libraw_dcraw_process(raw);
305 if(libraw_err != LIBRAW_SUCCESS)
goto error;
311 img->
dsc.
bpp =
sizeof(uint16_t);
320 img->
flags &= ~DT_IMAGE_4BAYER;
325 img->
flags &= ~DT_IMAGE_LDR;
326 img->
flags &= ~DT_IMAGE_HDR;
332 img->
flags &= ~DT_IMAGE_RAW;
333 img->
flags &= ~DT_IMAGE_HDR;
349 fprintf(stderr,
"[libraw_open] could not alloc full buffer for image `%s'\n", img->
filename);
354 const size_t bufSize_mipmap = (size_t)img->
width * img->
height *
sizeof(uint16_t);
355 const size_t bufSize_libraw = (size_t)raw->rawdata.sizes.raw_pitch * raw->rawdata.sizes.raw_height;
356 if(bufSize_mipmap == bufSize_libraw)
358 memcpy(buf, raw->rawdata.raw_image, bufSize_mipmap);
363 raw->rawdata.sizes.raw_width, raw->rawdata.sizes.raw_height,
364 raw->rawdata.sizes.raw_width, raw->rawdata.sizes.raw_height,
371 if(libraw_err != LIBRAW_SUCCESS)
372 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))
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
int dt_exif_read(dt_image_t *img, const char *path)
@ 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
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