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 #ifdef LIBRAW_WIN32_UNICODEPATHS
libraw_open_wfile(libraw_data_t * lr,const wchar_t * file)109   int libraw_open_wfile(libraw_data_t *lr, const wchar_t *file)
110   {
111     if (!lr)
112       return EINVAL;
113     LibRaw *ip = (LibRaw *)lr->parent_class;
114     return ip->open_file(file);
115   }
116 
117 #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM
libraw_open_wfile_ex(libraw_data_t * lr,const wchar_t * file,INT64 sz)118   int libraw_open_wfile_ex(libraw_data_t *lr, const wchar_t *file, INT64 sz)
119   {
120     if (!lr)
121       return EINVAL;
122     LibRaw *ip = (LibRaw *)lr->parent_class;
123     return ip->open_file(file, sz);
124   }
125 #endif
126 #endif
libraw_open_buffer(libraw_data_t * lr,const void * buffer,size_t size)127   int libraw_open_buffer(libraw_data_t *lr, const void *buffer, size_t size)
128   {
129     if (!lr)
130       return EINVAL;
131     LibRaw *ip = (LibRaw *)lr->parent_class;
132     return ip->open_buffer(buffer, size);
133   }
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)134   int libraw_open_bayer(libraw_data_t *lr, unsigned char *data,
135                         unsigned datalen, ushort _raw_width, ushort _raw_height,
136                         ushort _left_margin, ushort _top_margin,
137                         ushort _right_margin, ushort _bottom_margin,
138                         unsigned char procflags, unsigned char bayer_pattern,
139                         unsigned unused_bits, unsigned otherflags,
140                         unsigned black_level)
141   {
142     if (!lr)
143       return EINVAL;
144     LibRaw *ip = (LibRaw *)lr->parent_class;
145     return ip->open_bayer(data, datalen, _raw_width, _raw_height, _left_margin,
146                           _top_margin, _right_margin, _bottom_margin, procflags,
147                           bayer_pattern, unused_bits, otherflags, black_level);
148   }
libraw_unpack(libraw_data_t * lr)149   int libraw_unpack(libraw_data_t *lr)
150   {
151     if (!lr)
152       return EINVAL;
153     LibRaw *ip = (LibRaw *)lr->parent_class;
154     return ip->unpack();
155   }
libraw_unpack_thumb(libraw_data_t * lr)156   int libraw_unpack_thumb(libraw_data_t *lr)
157   {
158     if (!lr)
159       return EINVAL;
160     LibRaw *ip = (LibRaw *)lr->parent_class;
161     return ip->unpack_thumb();
162   }
libraw_recycle_datastream(libraw_data_t * lr)163   void libraw_recycle_datastream(libraw_data_t *lr)
164   {
165     if (!lr)
166       return;
167     LibRaw *ip = (LibRaw *)lr->parent_class;
168     ip->recycle_datastream();
169   }
libraw_recycle(libraw_data_t * lr)170   void libraw_recycle(libraw_data_t *lr)
171   {
172     if (!lr)
173       return;
174     LibRaw *ip = (LibRaw *)lr->parent_class;
175     ip->recycle();
176   }
libraw_close(libraw_data_t * lr)177   void libraw_close(libraw_data_t *lr)
178   {
179     if (!lr)
180       return;
181     LibRaw *ip = (LibRaw *)lr->parent_class;
182     delete ip;
183   }
184 
libraw_set_exifparser_handler(libraw_data_t * lr,exif_parser_callback cb,void * data)185   void libraw_set_exifparser_handler(libraw_data_t *lr, exif_parser_callback cb,
186                                      void *data)
187   {
188     if (!lr)
189       return;
190     LibRaw *ip = (LibRaw *)lr->parent_class;
191     ip->set_exifparser_handler(cb, data);
192   }
193 
libraw_set_memerror_handler(libraw_data_t * lr,memory_callback cb,void * data)194   void libraw_set_memerror_handler(libraw_data_t *lr, memory_callback cb,
195                                    void *data)
196   {
197     if (!lr)
198       return;
199     LibRaw *ip = (LibRaw *)lr->parent_class;
200     ip->set_memerror_handler(cb, data);
201   }
libraw_set_dataerror_handler(libraw_data_t * lr,data_callback func,void * data)202   void libraw_set_dataerror_handler(libraw_data_t *lr, data_callback func,
203                                     void *data)
204   {
205     if (!lr)
206       return;
207     LibRaw *ip = (LibRaw *)lr->parent_class;
208     ip->set_dataerror_handler(func, data);
209   }
libraw_set_progress_handler(libraw_data_t * lr,progress_callback cb,void * data)210   void libraw_set_progress_handler(libraw_data_t *lr, progress_callback cb,
211                                    void *data)
212   {
213     if (!lr)
214       return;
215     LibRaw *ip = (LibRaw *)lr->parent_class;
216     ip->set_progress_handler(cb, data);
217   }
218 
219   // DCRAW
libraw_adjust_sizes_info_only(libraw_data_t * lr)220   int libraw_adjust_sizes_info_only(libraw_data_t *lr)
221   {
222     if (!lr)
223       return EINVAL;
224     LibRaw *ip = (LibRaw *)lr->parent_class;
225     return ip->adjust_sizes_info_only();
226   }
libraw_dcraw_ppm_tiff_writer(libraw_data_t * lr,const char * filename)227   int libraw_dcraw_ppm_tiff_writer(libraw_data_t *lr, const char *filename)
228   {
229     if (!lr)
230       return EINVAL;
231     LibRaw *ip = (LibRaw *)lr->parent_class;
232     return ip->dcraw_ppm_tiff_writer(filename);
233   }
libraw_dcraw_thumb_writer(libraw_data_t * lr,const char * fname)234   int libraw_dcraw_thumb_writer(libraw_data_t *lr, const char *fname)
235   {
236     if (!lr)
237       return EINVAL;
238     LibRaw *ip = (LibRaw *)lr->parent_class;
239     return ip->dcraw_thumb_writer(fname);
240   }
libraw_dcraw_process(libraw_data_t * lr)241   int libraw_dcraw_process(libraw_data_t *lr)
242   {
243     if (!lr)
244       return EINVAL;
245     LibRaw *ip = (LibRaw *)lr->parent_class;
246     return ip->dcraw_process();
247   }
libraw_dcraw_make_mem_image(libraw_data_t * lr,int * errc)248   libraw_processed_image_t *libraw_dcraw_make_mem_image(libraw_data_t *lr,
249                                                         int *errc)
250   {
251     if (!lr)
252     {
253       if (errc)
254         *errc = EINVAL;
255       return NULL;
256     }
257     LibRaw *ip = (LibRaw *)lr->parent_class;
258     return ip->dcraw_make_mem_image(errc);
259   }
libraw_dcraw_make_mem_thumb(libraw_data_t * lr,int * errc)260   libraw_processed_image_t *libraw_dcraw_make_mem_thumb(libraw_data_t *lr,
261                                                         int *errc)
262   {
263     if (!lr)
264     {
265       if (errc)
266         *errc = EINVAL;
267       return NULL;
268     }
269     LibRaw *ip = (LibRaw *)lr->parent_class;
270     return ip->dcraw_make_mem_thumb(errc);
271   }
272 
libraw_dcraw_clear_mem(libraw_processed_image_t * p)273   void libraw_dcraw_clear_mem(libraw_processed_image_t *p)
274   {
275     LibRaw::dcraw_clear_mem(p);
276   }
277 
libraw_raw2image(libraw_data_t * lr)278   int libraw_raw2image(libraw_data_t *lr)
279   {
280     if (!lr)
281       return EINVAL;
282     LibRaw *ip = (LibRaw *)lr->parent_class;
283     return ip->raw2image();
284   }
libraw_free_image(libraw_data_t * lr)285   void libraw_free_image(libraw_data_t *lr)
286   {
287     if (!lr)
288       return;
289     LibRaw *ip = (LibRaw *)lr->parent_class;
290     ip->free_image();
291   }
libraw_get_decoder_info(libraw_data_t * lr,libraw_decoder_info_t * d)292   int libraw_get_decoder_info(libraw_data_t *lr, libraw_decoder_info_t *d)
293   {
294     if (!lr || !d)
295       return EINVAL;
296     LibRaw *ip = (LibRaw *)lr->parent_class;
297     return ip->get_decoder_info(d);
298   }
libraw_COLOR(libraw_data_t * lr,int row,int col)299   int libraw_COLOR(libraw_data_t *lr, int row, int col)
300   {
301     if (!lr)
302       return EINVAL;
303     LibRaw *ip = (LibRaw *)lr->parent_class;
304     return ip->COLOR(row, col);
305   }
306 
307   /* getters/setters used by 3DLut Creator */
libraw_set_demosaic(libraw_data_t * lr,int value)308   DllDef void libraw_set_demosaic(libraw_data_t *lr, int value)
309   {
310     if (!lr)
311       return;
312     LibRaw *ip = (LibRaw *)lr->parent_class;
313     ip->imgdata.params.user_qual = value;
314   }
315 
libraw_set_output_color(libraw_data_t * lr,int value)316   DllDef void libraw_set_output_color(libraw_data_t *lr, int value)
317   {
318     if (!lr)
319       return;
320     LibRaw *ip = (LibRaw *)lr->parent_class;
321     ip->imgdata.params.output_color = value;
322   }
323 
libraw_set_output_bps(libraw_data_t * lr,int value)324   DllDef void libraw_set_output_bps(libraw_data_t *lr, int value)
325   {
326     if (!lr)
327       return;
328     LibRaw *ip = (LibRaw *)lr->parent_class;
329     ip->imgdata.params.output_bps = value;
330   }
331 
libraw_set_output_tif(libraw_data_t * lr,int value)332   	DllDef void libraw_set_output_tif(libraw_data_t *lr, int value)
333   {
334     if (!lr)
335       return;
336     LibRaw *ip = (LibRaw *)lr->parent_class;
337     ip->imgdata.params.output_tiff = value;
338   }
339 
340 #define MIN(a, b) ((a) < (b) ? (a) : (b))
341 #define MAX(a, b) ((a) > (b) ? (a) : (b))
342 #define LIM(x, min, max) MAX(min, MIN(x, max))
343 
libraw_set_user_mul(libraw_data_t * lr,int index,float val)344   DllDef void libraw_set_user_mul(libraw_data_t *lr, int index, float val)
345   {
346     if (!lr)
347       return;
348     LibRaw *ip = (LibRaw *)lr->parent_class;
349     ip->imgdata.params.user_mul[LIM(index, 0, 3)] = val;
350   }
351 
libraw_set_gamma(libraw_data_t * lr,int index,float value)352   DllDef void libraw_set_gamma(libraw_data_t *lr, int index, float value)
353   {
354     if (!lr)
355       return;
356     LibRaw *ip = (LibRaw *)lr->parent_class;
357     ip->imgdata.params.gamm[LIM(index, 0, 5)] = value;
358   }
359 
libraw_set_no_auto_bright(libraw_data_t * lr,int value)360   DllDef void libraw_set_no_auto_bright(libraw_data_t *lr, int value)
361   {
362     if (!lr)
363       return;
364     LibRaw *ip = (LibRaw *)lr->parent_class;
365     ip->imgdata.params.no_auto_bright = value;
366   }
367 
libraw_set_bright(libraw_data_t * lr,float value)368   DllDef void libraw_set_bright(libraw_data_t *lr, float value)
369   {
370     if (!lr)
371       return;
372     LibRaw *ip = (LibRaw *)lr->parent_class;
373     ip->imgdata.params.bright = value;
374   }
375 
libraw_set_highlight(libraw_data_t * lr,int value)376   DllDef void libraw_set_highlight(libraw_data_t *lr, int value)
377   {
378     if (!lr)
379       return;
380     LibRaw *ip = (LibRaw *)lr->parent_class;
381     ip->imgdata.params.highlight = value;
382   }
383 
libraw_set_fbdd_noiserd(libraw_data_t * lr,int value)384   DllDef void libraw_set_fbdd_noiserd(libraw_data_t *lr, int value)
385   {
386     if (!lr)
387       return;
388     LibRaw *ip = (LibRaw *)lr->parent_class;
389     ip->imgdata.params.fbdd_noiserd = value;
390   }
391 
libraw_get_raw_height(libraw_data_t * lr)392   DllDef int libraw_get_raw_height(libraw_data_t *lr)
393   {
394     if (!lr)
395       return EINVAL;
396     return lr->sizes.raw_height;
397   }
398 
libraw_get_raw_width(libraw_data_t * lr)399   DllDef int libraw_get_raw_width(libraw_data_t *lr)
400   {
401     if (!lr)
402       return EINVAL;
403     return lr->sizes.raw_width;
404   }
405 
libraw_get_iheight(libraw_data_t * lr)406   DllDef int libraw_get_iheight(libraw_data_t *lr)
407   {
408     if (!lr)
409       return EINVAL;
410     return lr->sizes.iheight;
411   }
412 
libraw_get_iwidth(libraw_data_t * lr)413   DllDef int libraw_get_iwidth(libraw_data_t *lr)
414   {
415     if (!lr)
416       return EINVAL;
417     return lr->sizes.iwidth;
418   }
419 
libraw_get_cam_mul(libraw_data_t * lr,int index)420   DllDef float libraw_get_cam_mul(libraw_data_t *lr, int index)
421   {
422     if (!lr)
423       return EINVAL;
424     return lr->color.cam_mul[LIM(index, 0, 3)];
425   }
426 
libraw_get_pre_mul(libraw_data_t * lr,int index)427   DllDef float libraw_get_pre_mul(libraw_data_t *lr, int index)
428   {
429     if (!lr)
430       return EINVAL;
431     return lr->color.pre_mul[LIM(index, 0, 3)];
432   }
433 
libraw_get_rgb_cam(libraw_data_t * lr,int index1,int index2)434   DllDef float libraw_get_rgb_cam(libraw_data_t *lr, int index1, int index2)
435   {
436     if (!lr)
437       return EINVAL;
438     return lr->color.rgb_cam[LIM(index1, 0, 2)][LIM(index2, 0, 3)];
439   }
440 
libraw_get_color_maximum(libraw_data_t * lr)441   DllDef int libraw_get_color_maximum(libraw_data_t *lr)
442   {
443     if (!lr)
444       return EINVAL;
445     return lr->color.maximum;
446   }
447 
448 #ifdef __cplusplus
449 }
450 #endif
451