1 /* -*- C++ -*-
2  * File: libraw_c_api.cpp
3  * Copyright 2008-2021 LibRaw LLC (info@libraw.org)
4  * Created: Sat Mar  8 , 2008
5  *
6  * LibRaw C interface
7 
8 
9 LibRaw is free software; you can redistribute it and/or modify
10 it under the terms of the one of two licenses as you choose:
11 
12 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
13    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
14 
15 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
16    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
17 
18  */
19 
20 #include <math.h>
21 #include <errno.h>
22 #include "libraw/libraw.h"
23 
24 #ifdef __cplusplus
25 #include <new>
26 extern "C"
27 {
28 #endif
29 
libraw_init(unsigned int flags)30   libraw_data_t *libraw_init(unsigned int flags)
31   {
32     LibRaw *ret;
33     try
34     {
35       ret = new LibRaw(flags);
36     }
37     catch (const std::bad_alloc& )
38     {
39       return NULL;
40     }
41     return &(ret->imgdata);
42   }
43 
libraw_capabilities()44   unsigned libraw_capabilities() { return LibRaw::capabilities(); }
libraw_version()45   const char *libraw_version() { return LibRaw::version(); }
libraw_strprogress(enum LibRaw_progress p)46   const char *libraw_strprogress(enum LibRaw_progress p)
47   {
48     return LibRaw::strprogress(p);
49   }
libraw_versionNumber()50   int libraw_versionNumber() { return LibRaw::versionNumber(); }
libraw_cameraList()51   const char **libraw_cameraList() { return LibRaw::cameraList(); }
libraw_cameraCount()52   int libraw_cameraCount() { return LibRaw::cameraCount(); }
libraw_unpack_function_name(libraw_data_t * lr)53   const char *libraw_unpack_function_name(libraw_data_t *lr)
54   {
55     if (!lr)
56       return "NULL parameter passed";
57     LibRaw *ip = (LibRaw *)lr->parent_class;
58     return ip->unpack_function_name();
59   }
60 
libraw_subtract_black(libraw_data_t * lr)61   void libraw_subtract_black(libraw_data_t *lr)
62   {
63     if (!lr)
64       return;
65     LibRaw *ip = (LibRaw *)lr->parent_class;
66     ip->subtract_black();
67   }
68 
libraw_open_file(libraw_data_t * lr,const char * file)69   int libraw_open_file(libraw_data_t *lr, const char *file)
70   {
71     if (!lr)
72       return EINVAL;
73     LibRaw *ip = (LibRaw *)lr->parent_class;
74     return ip->open_file(file);
75   }
76 
libraw_get_iparams(libraw_data_t * lr)77   libraw_iparams_t *libraw_get_iparams(libraw_data_t *lr)
78   {
79     if (!lr)
80       return NULL;
81     return &(lr->idata);
82   }
83 
libraw_get_lensinfo(libraw_data_t * lr)84   libraw_lensinfo_t *libraw_get_lensinfo(libraw_data_t *lr)
85   {
86     if (!lr)
87       return NULL;
88     return &(lr->lens);
89   }
90 
libraw_get_imgother(libraw_data_t * lr)91   libraw_imgother_t *libraw_get_imgother(libraw_data_t *lr)
92   {
93     if (!lr)
94       return NULL;
95     return &(lr->other);
96   }
97 
98 #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM
libraw_open_file_ex(libraw_data_t * lr,const char * file,INT64 sz)99   int libraw_open_file_ex(libraw_data_t *lr, const char *file, INT64 sz)
100   {
101     if (!lr)
102       return EINVAL;
103     LibRaw *ip = (LibRaw *)lr->parent_class;
104     return ip->open_file(file, sz);
105   }
106 #endif
107 
108 #if defined(_WIN32) && !defined(__MINGW32__) && defined(_MSC_VER) &&           \
109     (_MSC_VER > 1310)
libraw_open_wfile(libraw_data_t * lr,const wchar_t * file)110   int libraw_open_wfile(libraw_data_t *lr, const wchar_t *file)
111   {
112     if (!lr)
113       return EINVAL;
114     LibRaw *ip = (LibRaw *)lr->parent_class;
115     return ip->open_file(file);
116   }
117 
118 #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM
libraw_open_wfile_ex(libraw_data_t * lr,const wchar_t * file,INT64 sz)119   int libraw_open_wfile_ex(libraw_data_t *lr, const wchar_t *file, INT64 sz)
120   {
121     if (!lr)
122       return EINVAL;
123     LibRaw *ip = (LibRaw *)lr->parent_class;
124     return ip->open_file(file, sz);
125   }
126 #endif
127 #endif
libraw_open_buffer(libraw_data_t * lr,const void * buffer,size_t size)128   int libraw_open_buffer(libraw_data_t *lr, const void *buffer, size_t size)
129   {
130     if (!lr)
131       return EINVAL;
132     LibRaw *ip = (LibRaw *)lr->parent_class;
133     return ip->open_buffer(buffer, size);
134   }
libraw_open_bayer(libraw_data_t * lr,unsigned char * data,unsigned datalen,ushort _raw_width,ushort _raw_height,ushort _left_margin,ushort _top_margin,ushort _right_margin,ushort _bottom_margin,unsigned char procflags,unsigned char bayer_pattern,unsigned unused_bits,unsigned otherflags,unsigned black_level)135   int libraw_open_bayer(libraw_data_t *lr, unsigned char *data,
136                         unsigned datalen, ushort _raw_width, ushort _raw_height,
137                         ushort _left_margin, ushort _top_margin,
138                         ushort _right_margin, ushort _bottom_margin,
139                         unsigned char procflags, unsigned char bayer_pattern,
140                         unsigned unused_bits, unsigned otherflags,
141                         unsigned black_level)
142   {
143     if (!lr)
144       return EINVAL;
145     LibRaw *ip = (LibRaw *)lr->parent_class;
146     return ip->open_bayer(data, datalen, _raw_width, _raw_height, _left_margin,
147                           _top_margin, _right_margin, _bottom_margin, procflags,
148                           bayer_pattern, unused_bits, otherflags, black_level);
149   }
libraw_unpack(libraw_data_t * lr)150   int libraw_unpack(libraw_data_t *lr)
151   {
152     if (!lr)
153       return EINVAL;
154     LibRaw *ip = (LibRaw *)lr->parent_class;
155     return ip->unpack();
156   }
libraw_unpack_thumb(libraw_data_t * lr)157   int libraw_unpack_thumb(libraw_data_t *lr)
158   {
159     if (!lr)
160       return EINVAL;
161     LibRaw *ip = (LibRaw *)lr->parent_class;
162     return ip->unpack_thumb();
163   }
libraw_recycle_datastream(libraw_data_t * lr)164   void libraw_recycle_datastream(libraw_data_t *lr)
165   {
166     if (!lr)
167       return;
168     LibRaw *ip = (LibRaw *)lr->parent_class;
169     ip->recycle_datastream();
170   }
libraw_recycle(libraw_data_t * lr)171   void libraw_recycle(libraw_data_t *lr)
172   {
173     if (!lr)
174       return;
175     LibRaw *ip = (LibRaw *)lr->parent_class;
176     ip->recycle();
177   }
libraw_close(libraw_data_t * lr)178   void libraw_close(libraw_data_t *lr)
179   {
180     if (!lr)
181       return;
182     LibRaw *ip = (LibRaw *)lr->parent_class;
183     delete ip;
184   }
185 
libraw_set_exifparser_handler(libraw_data_t * lr,exif_parser_callback cb,void * data)186   void libraw_set_exifparser_handler(libraw_data_t *lr, exif_parser_callback cb,
187                                      void *data)
188   {
189     if (!lr)
190       return;
191     LibRaw *ip = (LibRaw *)lr->parent_class;
192     ip->set_exifparser_handler(cb, data);
193   }
194 
libraw_set_memerror_handler(libraw_data_t * lr,memory_callback cb,void * data)195   void libraw_set_memerror_handler(libraw_data_t *lr, memory_callback cb,
196                                    void *data)
197   {
198     if (!lr)
199       return;
200     LibRaw *ip = (LibRaw *)lr->parent_class;
201     ip->set_memerror_handler(cb, data);
202   }
libraw_set_dataerror_handler(libraw_data_t * lr,data_callback func,void * data)203   void libraw_set_dataerror_handler(libraw_data_t *lr, data_callback func,
204                                     void *data)
205   {
206     if (!lr)
207       return;
208     LibRaw *ip = (LibRaw *)lr->parent_class;
209     ip->set_dataerror_handler(func, data);
210   }
libraw_set_progress_handler(libraw_data_t * lr,progress_callback cb,void * data)211   void libraw_set_progress_handler(libraw_data_t *lr, progress_callback cb,
212                                    void *data)
213   {
214     if (!lr)
215       return;
216     LibRaw *ip = (LibRaw *)lr->parent_class;
217     ip->set_progress_handler(cb, data);
218   }
219 
220   // DCRAW
libraw_adjust_sizes_info_only(libraw_data_t * lr)221   int libraw_adjust_sizes_info_only(libraw_data_t *lr)
222   {
223     if (!lr)
224       return EINVAL;
225     LibRaw *ip = (LibRaw *)lr->parent_class;
226     return ip->adjust_sizes_info_only();
227   }
libraw_dcraw_ppm_tiff_writer(libraw_data_t * lr,const char * filename)228   int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename)
229   {
230     if (!lr)
231       return EINVAL;
232     LibRaw *ip = (LibRaw *)lr->parent_class;
233     return ip->dcraw_ppm_tiff_writer(filename);
234   }
libraw_dcraw_thumb_writer(libraw_data_t * lr,const char * fname)235   int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname)
236   {
237     if (!lr)
238       return EINVAL;
239     LibRaw *ip = (LibRaw *)lr->parent_class;
240     return ip->dcraw_thumb_writer(fname);
241   }
libraw_dcraw_process(libraw_data_t * lr)242   int libraw_dcraw_process(libraw_data_t *lr)
243   {
244     if (!lr)
245       return EINVAL;
246     LibRaw *ip = (LibRaw *)lr->parent_class;
247     return ip->dcraw_process();
248   }
libraw_dcraw_make_mem_image(libraw_data_t * lr,int * errc)249   libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t *lr,
250                                                         int *errc)
251   {
252     if (!lr)
253     {
254       if (errc)
255         *errc = EINVAL;
256       return NULL;
257     }
258     LibRaw *ip = (LibRaw *)lr->parent_class;
259     return ip->dcraw_make_mem_image(errc);
260   }
libraw_dcraw_make_mem_thumb(libraw_data_t * lr,int * errc)261   libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t *lr,
262                                                         int *errc)
263   {
264     if (!lr)
265     {
266       if (errc)
267         *errc = EINVAL;
268       return NULL;
269     }
270     LibRaw *ip = (LibRaw *)lr->parent_class;
271     return ip->dcraw_make_mem_thumb(errc);
272   }
273 
libraw_dcraw_clear_mem(libraw_processed_image_t * p)274   void libraw_dcraw_clear_mem(libraw_processed_image_t *p)
275   {
276     LibRaw::dcraw_clear_mem(p);
277   }
278 
libraw_raw2image(libraw_data_t * lr)279   int libraw_raw2image(libraw_data_t *lr)
280   {
281     if (!lr)
282       return EINVAL;
283     LibRaw *ip = (LibRaw *)lr->parent_class;
284     return ip->raw2image();
285   }
libraw_free_image(libraw_data_t * lr)286   void libraw_free_image(libraw_data_t *lr)
287   {
288     if (!lr)
289       return;
290     LibRaw *ip = (LibRaw *)lr->parent_class;
291     ip->free_image();
292   }
libraw_get_decoder_info(libraw_data_t * lr,libraw_decoder_info_t * d)293   int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d)
294   {
295     if (!lr || !d)
296       return EINVAL;
297     LibRaw *ip = (LibRaw *)lr->parent_class;
298     return ip->get_decoder_info(d);
299   }
libraw_COLOR(libraw_data_t * lr,int row,int col)300   int libraw_COLOR(libraw_data_t *lr, int row, int col)
301   {
302     if (!lr)
303       return EINVAL;
304     LibRaw *ip = (LibRaw *)lr->parent_class;
305     return ip->COLOR(row, col);
306   }
307 
308   /* getters/setters used by 3DLut Creator */
libraw_set_demosaic(libraw_data_t * lr,int value)309   DllDef void libraw_set_demosaic(libraw_data_t *lr, int value)
310   {
311     if (!lr)
312       return;
313     LibRaw *ip = (LibRaw *)lr->parent_class;
314     ip->imgdata.params.user_qual = value;
315   }
316 
libraw_set_output_color(libraw_data_t * lr,int value)317   DllDef void libraw_set_output_color(libraw_data_t *lr, int value)
318   {
319     if (!lr)
320       return;
321     LibRaw *ip = (LibRaw *)lr->parent_class;
322     ip->imgdata.params.output_color = value;
323   }
324 
libraw_set_output_bps(libraw_data_t * lr,int value)325   DllDef void libraw_set_output_bps(libraw_data_t *lr, int value)
326   {
327     if (!lr)
328       return;
329     LibRaw *ip = (LibRaw *)lr->parent_class;
330     ip->imgdata.params.output_bps = value;
331   }
332 
libraw_set_output_tif(libraw_data_t * lr,int value)333   	DllDef void libraw_set_output_tif(libraw_data_t *lr, int value)
334   {
335     if (!lr)
336       return;
337     LibRaw *ip = (LibRaw *)lr->parent_class;
338     ip->imgdata.params.output_tiff = value;
339   }
340 
341 #define MIN(a, b) ((a) < (b) ? (a) : (b))
342 #define MAX(a, b) ((a) > (b) ? (a) : (b))
343 #define LIM(x, min, max) MAX(min, MIN(x, max))
344 
libraw_set_user_mul(libraw_data_t * lr,int index,float val)345   DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val)
346   {
347     if (!lr)
348       return;
349     LibRaw *ip = (LibRaw *)lr->parent_class;
350     ip->imgdata.params.user_mul[LIM(index, 0, 3)] = val;
351   }
352 
libraw_set_gamma(libraw_data_t * lr,int index,float value)353   DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value)
354   {
355     if (!lr)
356       return;
357     LibRaw *ip = (LibRaw *)lr->parent_class;
358     ip->imgdata.params.gamm[LIM(index, 0, 5)] = value;
359   }
360 
libraw_set_no_auto_bright(libraw_data_t * lr,int value)361   DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value)
362   {
363     if (!lr)
364       return;
365     LibRaw *ip = (LibRaw *)lr->parent_class;
366     ip->imgdata.params.no_auto_bright = value;
367   }
368 
libraw_set_bright(libraw_data_t * lr,float value)369   DllDef void libraw_set_bright(libraw_data_t *lr, float value)
370   {
371     if (!lr)
372       return;
373     LibRaw *ip = (LibRaw *)lr->parent_class;
374     ip->imgdata.params.bright = value;
375   }
376 
libraw_set_highlight(libraw_data_t * lr,int value)377   DllDef void libraw_set_highlight(libraw_data_t *lr, int value)
378   {
379     if (!lr)
380       return;
381     LibRaw *ip = (LibRaw *)lr->parent_class;
382     ip->imgdata.params.highlight = value;
383   }
384 
libraw_set_fbdd_noiserd(libraw_data_t * lr,int value)385   DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value)
386   {
387     if (!lr)
388       return;
389     LibRaw *ip = (LibRaw *)lr->parent_class;
390     ip->imgdata.params.fbdd_noiserd = value;
391   }
392 
libraw_get_raw_height(libraw_data_t * lr)393   DllDef int libraw_get_raw_height(libraw_data_t *lr)
394   {
395     if (!lr)
396       return EINVAL;
397     return lr->sizes.raw_height;
398   }
399 
libraw_get_raw_width(libraw_data_t * lr)400   DllDef int libraw_get_raw_width(libraw_data_t *lr)
401   {
402     if (!lr)
403       return EINVAL;
404     return lr->sizes.raw_width;
405   }
406 
libraw_get_iheight(libraw_data_t * lr)407   DllDef int libraw_get_iheight(libraw_data_t *lr)
408   {
409     if (!lr)
410       return EINVAL;
411     return lr->sizes.iheight;
412   }
413 
libraw_get_iwidth(libraw_data_t * lr)414   DllDef int libraw_get_iwidth(libraw_data_t *lr)
415   {
416     if (!lr)
417       return EINVAL;
418     return lr->sizes.iwidth;
419   }
420 
libraw_get_cam_mul(libraw_data_t * lr,int index)421   DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index)
422   {
423     if (!lr)
424       return EINVAL;
425     return lr->color.cam_mul[LIM(index, 0, 3)];
426   }
427 
libraw_get_pre_mul(libraw_data_t * lr,int index)428   DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index)
429   {
430     if (!lr)
431       return EINVAL;
432     return lr->color.pre_mul[LIM(index, 0, 3)];
433   }
434 
libraw_get_rgb_cam(libraw_data_t * lr,int index1,int index2)435   DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2)
436   {
437     if (!lr)
438       return EINVAL;
439     return lr->color.rgb_cam[LIM(index1, 0, 2)][LIM(index2, 0, 3)];
440   }
441 
libraw_get_color_maximum(libraw_data_t * lr)442   DllDef int libraw_get_color_maximum(libraw_data_t *lr)
443   {
444     if (!lr)
445       return EINVAL;
446     return lr->color.maximum;
447   }
448 
449 #ifdef __cplusplus
450 }
451 #endif
452