50#include "RawSpeed-API.h"
51#include "io/FileIOException.h"
52#include "metadata/CameraMetadataException.h"
53#include "parsers/RawParserException.h"
54#include "parsers/FiffParserException.h"
56#define TYPE_FLOAT32 RawImageType::F32
57#define TYPE_USHORT16 RawImageType::UINT16
61#define __STDC_LIMIT_MACROS
81 return omp_get_num_procs();
87using namespace rawspeed;
92static CameraMetaData *
meta = NULL;
106 meta =
new CameraMetaData(camfile);
121 gboolean got_it_done =
FALSE;
128 g_strlcpy(mk, cam->canonical_make.c_str(), mk_len);
129 g_strlcpy(md, cam->canonical_model.c_str(), md_len);
130 g_strlcpy(al, cam->canonical_alias.c_str(), al_len);
134 catch(
const std::exception &exc)
143 g_strlcpy(mk,
maker, mk_len);
144 g_strlcpy(md,
model, md_len);
145 g_strlcpy(al,
model, al_len);
152 if(!filters || filters == 9u)
return filters;
154 return ColorFilterArray::shiftDcrawFilter(filters, crop_x, crop_y);
161 const char *extensions_whitelist[] = {
"cr3", NULL };
162 char *ext = g_strrstr(filename,
".");
166 if(!g_ascii_strncasecmp(ext, *
i, strlen(*
i)))
174 const char *filename,
191 snprintf(filen,
sizeof(filen),
"%s", filename);
199 auto [storage, storageBuf] =
f.readFile();
202 RawParser
t(storageBuf);
203 std::unique_ptr<RawDecoder>
d =
t.getDecoder(
meta);
207 d->failOnUnknown =
true;
208 d->checkSupport(
meta);
210 d->decodeMetaData(
meta);
211 RawImage
r =
d->mRaw;
213 const auto errors =
r->getErrors();
214 for(
const auto &
error : errors)
224 static const struct {
225 const char *mungedname;
226 const char *origname;
227 } legacy_aliases[] = {
228 {
"Canon EOS",
"Canon EOS REBEL SL1"},
229 {
"Canon EOS",
"Canon EOS Kiss X7"},
230 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XT"},
231 {
"Canon EOS",
"Canon EOS Kiss Digital N"},
232 {
"Canon EOS",
"Canon EOS 350D"},
233 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XSi"},
234 {
"Canon EOS",
"Canon EOS Kiss Digital X2"},
235 {
"Canon EOS",
"Canon EOS Kiss X2"},
236 {
"Canon EOS",
"Canon EOS REBEL T5i"},
237 {
"Canon EOS",
"Canon EOS Kiss X7i"},
238 {
"Canon EOS",
"Canon EOS Rebel T6i"},
239 {
"Canon EOS",
"Canon EOS Kiss X8i"},
240 {
"Canon EOS",
"Canon EOS Rebel T6s"},
241 {
"Canon EOS",
"Canon EOS 8000D"},
242 {
"Canon EOS",
"Canon EOS REBEL T1i"},
243 {
"Canon EOS",
"Canon EOS Kiss X3"},
244 {
"Canon EOS",
"Canon EOS REBEL T2i"},
245 {
"Canon EOS",
"Canon EOS Kiss X4"},
246 {
"Canon EOS REBEL T3",
"Canon EOS REBEL T3i"},
247 {
"Canon EOS",
"Canon EOS Kiss X5"},
248 {
"Canon EOS",
"Canon EOS REBEL T4i"},
249 {
"Canon EOS",
"Canon EOS Kiss X6i"},
250 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XS"},
251 {
"Canon EOS",
"Canon EOS Kiss Digital F"},
252 {
"Canon EOS",
"Canon EOS REBEL T5"},
253 {
"Canon EOS",
"Canon EOS Kiss X70"},
254 {
"Canon EOS",
"Canon EOS DIGITAL REBEL XTi"},
255 {
"Canon EOS",
"Canon EOS Kiss Digital X"},
258 for(uint32_t
i = 0;
i < (
sizeof(legacy_aliases) /
sizeof(legacy_aliases[1]));
i++)
259 if(!strcmp(legacy_aliases[
i].origname,
r->metadata.model.c_str()))
271 if(!
r->blackLevelSeparate)
273 r->calculateBlackAreas();
276 const auto bl = *(
r->blackLevelSeparate->getAsArray1DRef());
277 for(uint8_t
i = 0;
i < 4;
i++)
280 if(
r->blackLevel == -1)
283 for(uint8_t
i = 0;
i < 4;
i++)
303 if(
r->metadata.wbCoeffs)
305 for(
int i = 0;
i < 4;
i++)
310 for(
int i = 0;
i < 4;
i++)
315 const int msize =
r->metadata.colorMatrix.size();
316 for(
int k = 0;
k < 4;
k++)
317 for(
int i = 0;
i < 3;
i++)
319 const int idx =
k*3 +
i;
350 img->
flags &= ~DT_IMAGE_HDR;
356 const iPoint2D dimUncropped =
r->getUncroppedDim();
357 img->
width = dimUncropped.x;
358 img->
height = dimUncropped.y;
361 const iPoint2D dimCropped =
r->dim;
364 const iPoint2D cropTL =
r->getCropOffset();
369 const iPoint2D cropBR = dimUncropped - dimCropped - cropTL;
387 if((
r->getBpp() !=
sizeof(uint16_t)) && (
r->getBpp() !=
sizeof(
float)))
390 if((
r->getDataType() ==
TYPE_USHORT16) && (
r->getBpp() !=
sizeof(uint16_t)))
393 if((
r->getDataType() ==
TYPE_FLOAT32) && (
r->getBpp() !=
sizeof(
float)))
396 const float cpp =
r->getCpp();
403 case sizeof(uint16_t):
405 img->
dsc.
bpp =
sizeof(uint16_t);
409 img->
dsc.
bpp =
sizeof(float);
423 img->
flags &= ~DT_IMAGE_LDR;
435 for(
int i = 0;
i < 6; ++
i)
436 for(
int j = 0; j < 6; ++j)
438 img->
dsc.
xtrans[j][
i] = (uint8_t)
r->cfa.getColorAt(
i % 6, j % 6);
461 const size_t bufSize_mipmap = (size_t)img->
width * img->
height *
r->getBpp();
462 const size_t bufSize_rawspeed = (size_t)
r->pitch * dimUncropped.y;
463 if(bufSize_mipmap == bufSize_rawspeed)
465 memcpy(buf, (
char *)(&(
r->getByteDataAsUncroppedArray2DRef()(0, 0))), bufSize_mipmap);
470 dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y,
r->pitch,
475 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
476 r->metadata.model.c_str(),
477 r->metadata.mode.c_str());
479 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
482 catch(
const rawspeed::IOException &exc)
487 catch(
const rawspeed::FileIOException &exc)
492 catch(
const rawspeed::RawDecoderException &exc)
494 const char *msg = exc.what();
500 if(msg && (strstr(msg,
"Camera not supported") || strstr(msg,
"not supported, and not allowed to guess")))
505 else if (msg && strstr(msg,
"supported"))
521 catch(
const rawspeed::RawParserException &exc)
526 catch(
const rawspeed::CameraMetadataException &exc)
531 catch(
const std::exception &exc)
556 img->
flags &= ~DT_IMAGE_LDR;
557 img->
flags &= ~DT_IMAGE_RAW;
563 img->
dsc.
bpp = 4 *
sizeof(float);
568 const uint32_t cpp =
r->getCpp();
597 for(
int j = 0; j <
height; j++)
599 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
600 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
604 out[0] =
out[1] =
out[2] = (float)in(j, cpp *
i) / (float)UINT16_MAX;
613 for(
int j = 0; j <
height; j++)
615 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
616 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
637 for(
int j = 0; j <
height; j++)
639 const Array2DRef<uint16_t> in =
r->getU16DataAsUncroppedArray2DRef();
640 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
644 for(
int k = 0;
k < 3;
k++)
645 out[
k] = (
float)in(j, cpp *
i +
k) / (float)UINT16_MAX;
654 for(
int j = 0; j <
height; j++)
656 const Array2DRef<float> in =
r->getF32DataAsUncroppedArray2DRef();
657 float *
out = ((
float *)buf) + (size_t)4 * j *
width;
661 for(
int k = 0;
k < 3;
k++)
662 out[
k] = in(j, cpp *
i +
k);
674 const Camera *cam =
meta->getCamera(
r->metadata.make.c_str(),
675 r->metadata.model.c_str(),
676 r->metadata.mode.c_str());
678 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
static void error(char *msg)
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
void dt_image_refresh_makermodel(dt_image_t *img)
void dt_concat_path_file(char destination[PATH_MAX], const char path[PATH_MAX], const char *const file)
void dt_print(dt_debug_thread_t thread, const char *msg,...)
#define __OMP_PARALLEL_FOR_CPP__(...)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
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)
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
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)
float *const restrict const size_t k
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
dt_pthread_mutex_t readFile_mutex
dt_pthread_mutex_t plugin_threadsafe
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