50#include "RawSpeed-API.h"
52#include "io/FileIOException.h"
53#include "metadata/CameraMetadataException.h"
54#include "parsers/RawParserException.h"
55#include "parsers/FiffParserException.h"
57#define TYPE_FLOAT32 RawImageType::F32
58#define TYPE_USHORT16 RawImageType::UINT16
63#define __STDC_LIMIT_MACROS
79 return omp_get_num_procs();
85using namespace rawspeed;
90static CameraMetaData *
meta = NULL;
112 meta =
new CameraMetaData(camfile);
125 gboolean got_it_done =
FALSE;
132 g_strlcpy(mk, cam->canonical_make.c_str(), mk_len);
133 g_strlcpy(md, cam->canonical_model.c_str(), md_len);
134 g_strlcpy(al, cam->canonical_alias.c_str(), al_len);
138 catch(
const std::exception &exc)
147 g_strlcpy(mk,
maker, mk_len);
148 g_strlcpy(md,
model, md_len);
149 g_strlcpy(al,
model, al_len);
156 if(!filters || filters == 9u)
return filters;
158 return ColorFilterArray::shiftDcrawFilter(filters, crop_x, crop_y);
165 const char *extensions_whitelist[] = {
"cr3", NULL };
166 char *ext = g_strrstr(filename,
".");
170 if(!g_ascii_strncasecmp(ext, *
i, strlen(*
i)))
178 const char *filename,
195 snprintf(filen,
sizeof(filen),
"%s", filename);
206 auto [storage, storageBuf] =
f.readFile();
208 RawParser
t(storageBuf);
209 std::unique_ptr<RawDecoder>
d =
t.getDecoder(
meta);
213 d->failOnUnknown =
true;
214 d->checkSupport(
meta);
216 d->decodeMetaData(
meta);
217 RawImage
r =
d->mRaw;
219 const auto errors =
r->getErrors();
220 for(
const auto &
error : errors)
230 static const struct {
231 const char *mungedname;
232 const char *origname;
233 } legacy_aliases[] = {
234 {
"Canon EOS",
"Canon EOS REBEL SL1"},
235 {
"Canon EOS",
"Canon EOS Kiss X7"},
236 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XT"},
237 {
"Canon EOS",
"Canon EOS Kiss Digital N"},
238 {
"Canon EOS",
"Canon EOS 350D"},
239 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XSi"},
240 {
"Canon EOS",
"Canon EOS Kiss Digital X2"},
241 {
"Canon EOS",
"Canon EOS Kiss X2"},
242 {
"Canon EOS",
"Canon EOS REBEL T5i"},
243 {
"Canon EOS",
"Canon EOS Kiss X7i"},
244 {
"Canon EOS",
"Canon EOS Rebel T6i"},
245 {
"Canon EOS",
"Canon EOS Kiss X8i"},
246 {
"Canon EOS",
"Canon EOS Rebel T6s"},
247 {
"Canon EOS",
"Canon EOS 8000D"},
248 {
"Canon EOS",
"Canon EOS REBEL T1i"},
249 {
"Canon EOS",
"Canon EOS Kiss X3"},
250 {
"Canon EOS",
"Canon EOS REBEL T2i"},
251 {
"Canon EOS",
"Canon EOS Kiss X4"},
252 {
"Canon EOS REBEL T3",
"Canon EOS REBEL T3i"},
253 {
"Canon EOS",
"Canon EOS Kiss X5"},
254 {
"Canon EOS",
"Canon EOS REBEL T4i"},
255 {
"Canon EOS",
"Canon EOS Kiss X6i"},
256 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XS"},
257 {
"Canon EOS",
"Canon EOS Kiss Digital F"},
258 {
"Canon EOS",
"Canon EOS REBEL T5"},
259 {
"Canon EOS",
"Canon EOS Kiss X70"},
260 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XTi"},
261 {
"Canon EOS",
"Canon EOS Kiss Digital X"},
264 for(uint32_t
i = 0;
i < (
sizeof(legacy_aliases) /
sizeof(legacy_aliases[1]));
i++)
265 if(!strcmp(legacy_aliases[
i].origname,
r->metadata.model.c_str()))
277 if(!
r->blackLevelSeparate)
279 r->calculateBlackAreas();
282 const auto bl = *(
r->blackLevelSeparate->getAsArray1DRef());
283 for(uint8_t
i = 0;
i < 4;
i++)
286 if(
r->blackLevel == -1)
289 for(uint8_t
i = 0;
i < 4;
i++)
309 if(
r->metadata.wbCoeffs)
311 for(
int i = 0;
i < 4;
i++)
316 for(
int i = 0;
i < 4;
i++)
321 const int msize =
r->metadata.colorMatrix.size();
322 for(
int k = 0;
k < 4;
k++)
323 for(
int i = 0;
i < 3;
i++)
325 const int idx =
k*3 +
i;
356 img->
flags &= ~DT_IMAGE_HDR;
362 const iPoint2D dimUncropped =
r->getUncroppedDim();
363 img->
width = dimUncropped.x;
364 img->
height = dimUncropped.y;
367 const iPoint2D dimCropped =
r->dim;
370 const iPoint2D cropTL =
r->getCropOffset();
375 const iPoint2D cropBR = dimUncropped - dimCropped - cropTL;
393 if((
r->getBpp() !=
sizeof(uint16_t)) && (
r->getBpp() !=
sizeof(
float)))
396 if((
r->getDataType() ==
TYPE_USHORT16) && (
r->getBpp() !=
sizeof(uint16_t)))
399 if((
r->getDataType() ==
TYPE_FLOAT32) && (
r->getBpp() !=
sizeof(
float)))
402 const float cpp =
r->getCpp();
409 case sizeof(uint16_t):
411 img->
dsc.
bpp =
sizeof(uint16_t);
415 img->
dsc.
bpp =
sizeof(float);
429 img->
flags &= ~DT_IMAGE_LDR;
441 for(
int i = 0;
i < 6; ++
i)
442 for(
int j = 0; j < 6; ++j)
444 img->
dsc.
xtrans[j][
i] = (uint8_t)
r->cfa.getColorAt(
i % 6, j % 6);
467 const size_t bufSize_mipmap = (size_t)img->
width * img->
height *
r->getBpp();
468 const size_t bufSize_rawspeed = (size_t)
r->pitch * dimUncropped.y;
469 if(bufSize_mipmap == bufSize_rawspeed)
471 memcpy(buf, (
char *)(&(
r->getByteDataAsUncroppedArray2DRef()(0, 0))), bufSize_mipmap);
476 dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y,
r->pitch,
481 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
482 r->metadata.model.c_str(),
483 r->metadata.mode.c_str());
485 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
488 catch(
const rawspeed::IOException &exc)
493 catch(
const rawspeed::FileIOException &exc)
498 catch(
const rawspeed::RawDecoderException &exc)
500 const char *msg = exc.what();
506 if(msg && (strstr(msg,
"Camera not supported") || strstr(msg,
"not supported, and not allowed to guess")))
511 else if (msg && strstr(msg,
"supported"))
527 catch(
const rawspeed::RawParserException &exc)
532 catch(
const rawspeed::CameraMetadataException &exc)
537 catch(
const std::exception &exc)
562 img->
flags &= ~DT_IMAGE_LDR;
563 img->
flags &= ~DT_IMAGE_RAW;
569 img->
dsc.
bpp = 4 *
sizeof(float);
574 const uint32_t cpp =
r->getCpp();
604 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
606 for(
int j = 0; j <
height; j++)
608 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
612 out[0] =
out[1] =
out[2] = (float)in(j, cpp *
i) / (float)UINT16_MAX;
622 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
624 for(
int j = 0; j <
height; j++)
626 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
648 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
650 for(
int j = 0; j <
height; j++)
652 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
656 for(
int k = 0;
k < 3;
k++)
657 out[
k] = (
float)in(j, cpp *
i +
k) / (float)UINT16_MAX;
667 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
669 for(
int j = 0; j <
height; j++)
671 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
675 for(
int k = 0;
k < 3;
k++)
676 out[
k] = in(j, cpp *
i +
k);
688 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
689 r->metadata.model.c_str(),
690 r->metadata.mode.c_str());
692 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_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
static std::once_flag meta_once
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)
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