51#include "RawSpeed-API.h"
53#include "io/FileIOException.h"
54#include "metadata/CameraMetadataException.h"
55#include "parsers/RawParserException.h"
56#include "parsers/FiffParserException.h"
58#define TYPE_FLOAT32 RawImageType::F32
59#define TYPE_USHORT16 RawImageType::UINT16
64#define __STDC_LIMIT_MACROS
80 return omp_get_num_procs();
86using namespace rawspeed;
91static CameraMetaData *
meta = NULL;
122 meta =
new CameraMetaData(camfile);
134 gboolean got_it_done =
FALSE;
141 g_strlcpy(mk, cam->canonical_make.c_str(), mk_len);
142 g_strlcpy(md, cam->canonical_model.c_str(), md_len);
143 g_strlcpy(al, cam->canonical_alias.c_str(), al_len);
147 catch(
const std::exception &exc)
156 g_strlcpy(mk,
maker, mk_len);
157 g_strlcpy(md,
model, md_len);
158 g_strlcpy(al,
model, al_len);
165 if(!filters || filters == 9u)
return filters;
167 return ColorFilterArray::shiftDcrawFilter(filters, crop_x, crop_y);
174 const char *extensions_whitelist[] = {
"cr3", NULL };
175 char *ext = g_strrstr(filename,
".");
179 if(!g_ascii_strncasecmp(ext, *
i, strlen(*
i)))
187 const char *filename,
204 snprintf(filen,
sizeof(filen),
"%s", filename);
215 auto [storage, storageBuf] =
f.readFile();
217 RawParser
t(storageBuf);
218 std::unique_ptr<RawDecoder>
d =
t.getDecoder(
meta);
222 d->failOnUnknown =
true;
223 d->checkSupport(
meta);
225 d->decodeMetaData(
meta);
226 RawImage
r =
d->mRaw;
228 const auto errors =
r->getErrors();
229 for(
const auto &
error : errors)
239 static const struct {
240 const char *mungedname;
241 const char *origname;
242 } legacy_aliases[] = {
243 {
"Canon EOS",
"Canon EOS REBEL SL1"},
244 {
"Canon EOS",
"Canon EOS Kiss X7"},
245 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XT"},
246 {
"Canon EOS",
"Canon EOS Kiss Digital N"},
247 {
"Canon EOS",
"Canon EOS 350D"},
248 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XSi"},
249 {
"Canon EOS",
"Canon EOS Kiss Digital X2"},
250 {
"Canon EOS",
"Canon EOS Kiss X2"},
251 {
"Canon EOS",
"Canon EOS REBEL T5i"},
252 {
"Canon EOS",
"Canon EOS Kiss X7i"},
253 {
"Canon EOS",
"Canon EOS Rebel T6i"},
254 {
"Canon EOS",
"Canon EOS Kiss X8i"},
255 {
"Canon EOS",
"Canon EOS Rebel T6s"},
256 {
"Canon EOS",
"Canon EOS 8000D"},
257 {
"Canon EOS",
"Canon EOS REBEL T1i"},
258 {
"Canon EOS",
"Canon EOS Kiss X3"},
259 {
"Canon EOS",
"Canon EOS REBEL T2i"},
260 {
"Canon EOS",
"Canon EOS Kiss X4"},
261 {
"Canon EOS REBEL T3",
"Canon EOS REBEL T3i"},
262 {
"Canon EOS",
"Canon EOS Kiss X5"},
263 {
"Canon EOS",
"Canon EOS REBEL T4i"},
264 {
"Canon EOS",
"Canon EOS Kiss X6i"},
265 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XS"},
266 {
"Canon EOS",
"Canon EOS Kiss Digital F"},
267 {
"Canon EOS",
"Canon EOS REBEL T5"},
268 {
"Canon EOS",
"Canon EOS Kiss X70"},
269 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XTi"},
270 {
"Canon EOS",
"Canon EOS Kiss Digital X"},
273 for(uint32_t
i = 0;
i < (
sizeof(legacy_aliases) /
sizeof(legacy_aliases[1]));
i++)
274 if(!strcmp(legacy_aliases[
i].origname,
r->metadata.model.c_str()))
286 if(!
r->blackLevelSeparate)
288 r->calculateBlackAreas();
291 const auto bl = *(
r->blackLevelSeparate->getAsArray1DRef());
292 for(uint8_t
i = 0;
i < 4;
i++)
295 if(
r->blackLevel == -1)
298 for(uint8_t
i = 0;
i < 4;
i++)
318 if(
r->metadata.wbCoeffs)
320 for(
int i = 0;
i < 4;
i++)
325 for(
int i = 0;
i < 4;
i++)
330 const int msize =
r->metadata.colorMatrix.size();
331 for(
int k = 0;
k < 4;
k++)
332 for(
int i = 0;
i < 3;
i++)
334 const int idx =
k*3 +
i;
365 img->
flags &= ~DT_IMAGE_HDR;
371 const iPoint2D dimUncropped =
r->getUncroppedDim();
372 img->
width = dimUncropped.x;
373 img->
height = dimUncropped.y;
376 const iPoint2D dimCropped =
r->dim;
379 const iPoint2D cropTL =
r->getCropOffset();
384 const iPoint2D cropBR = dimUncropped - dimCropped - cropTL;
402 if((
r->getBpp() !=
sizeof(uint16_t)) && (
r->getBpp() !=
sizeof(
float)))
405 if((
r->getDataType() ==
TYPE_USHORT16) && (
r->getBpp() !=
sizeof(uint16_t)))
408 if((
r->getDataType() ==
TYPE_FLOAT32) && (
r->getBpp() !=
sizeof(
float)))
411 const float cpp =
r->getCpp();
418 case sizeof(uint16_t):
420 img->
dsc.
bpp =
sizeof(uint16_t);
424 img->
dsc.
bpp =
sizeof(float);
438 img->
flags &= ~DT_IMAGE_LDR;
450 for(
int i = 0;
i < 6; ++
i)
451 for(
int j = 0; j < 6; ++j)
453 img->
dsc.
xtrans[j][
i] = (uint8_t)
r->cfa.getColorAt(
i % 6, j % 6);
476 const size_t bufSize_mipmap = (size_t)img->
width * img->
height *
r->getBpp();
477 const size_t bufSize_rawspeed = (size_t)
r->pitch * dimUncropped.y;
478 if(bufSize_mipmap == bufSize_rawspeed)
480 memcpy(buf, (
char *)(&(
r->getByteDataAsUncroppedArray2DRef()(0, 0))), bufSize_mipmap);
485 dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y,
r->pitch,
490 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
491 r->metadata.model.c_str(),
492 r->metadata.mode.c_str());
494 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
497 catch(
const rawspeed::IOException &exc)
504 catch(
const rawspeed::FileIOException &exc)
509 catch(
const rawspeed::RawDecoderException &exc)
511 const char *msg = exc.what();
517 if(msg && (strstr(msg,
"Camera not supported") || strstr(msg,
"not supported, and not allowed to guess")))
522 else if (msg && strstr(msg,
"supported"))
538 catch(
const rawspeed::RawParserException &exc)
543 catch(
const rawspeed::CameraMetadataException &exc)
548 catch(
const std::exception &exc)
573 img->
flags &= ~DT_IMAGE_LDR;
574 img->
flags &= ~DT_IMAGE_RAW;
580 img->
dsc.
bpp = 4 *
sizeof(float);
585 const uint32_t cpp =
r->getCpp();
615 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
617 for(
int j = 0; j <
height; j++)
619 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
623 out[0] =
out[1] =
out[2] = (float)in(j, cpp *
i) / (float)UINT16_MAX;
633 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
635 for(
int j = 0; j <
height; j++)
637 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
659 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
661 for(
int j = 0; j <
height; j++)
663 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
667 for(
int k = 0;
k < 3;
k++)
668 out[
k] = (
float)in(j, cpp *
i +
k) / (float)UINT16_MAX;
678 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
680 for(
int j = 0; j <
height; j++)
682 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
686 for(
int k = 0;
k < 3;
k++)
687 out[
k] = in(j, cpp *
i +
k);
699 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
700 r->metadata.model.c_str(),
701 r->metadata.mode.c_str());
703 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
static void error(char *msg)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_image_refresh_makermodel(dt_image_t *img)
int dt_exif_read(dt_image_t *img, const char *path)
void dt_exif_img_check_additional_tags(dt_image_t *img, const char *filename)
What a photograph says about itself: the EXIF, IPTC and XMP tags a camera and a cataloguer write,...
void dt_loc_get_datadir(char *datadir, size_t bufsize)
dt_imageio_retval_t
Return value of image io functions: loading, exporting, and making a thumbnail.
@ DT_IMAGEIO_UNSUPPORTED_FEATURE
@ DT_IMAGEIO_FILE_CORRUPTED
@ DT_IMAGEIO_UNSUPPORTED_FORMAT
@ DT_IMAGEIO_UNSUPPORTED_CAMERA
__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)
static CameraMetaData * meta
uint32_t dt_rawspeed_crop_dcraw_filters(uint32_t filters, uint32_t crop_x, uint32_t crop_y)
gboolean dt_rawspeed_lookup_makermodel(const char *maker, const char *model, char *mk, int mk_len, char *md, int md_len, char *al, int al_len)
static gboolean _ignore_image(const gchar *filename)
static std::mutex meta_mutex
int rawspeed_get_number_of_processor_cores()
static dt_imageio_retval_t dt_imageio_open_rawspeed_sraw(dt_image_t *img, const RawImage r, dt_mipmap_buffer_t *buf)
static void dt_rawspeed_load_meta()
dt_imageio_retval_t dt_imageio_open_rawspeed(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *mbuf)
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.
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...
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
#define __OMP_PARALLEL_FOR_CPP__(...)
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
gboolean camera_missing_sample
char camera_legacy_makermodel[128]
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
uint32_t fuji_rotation_pos
dt_iop_buffer_type_t datatype
dt_aligned_pixel_t processed_maximum