Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
imageio_rawspeed.cc
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011, 2013-2014 johannes hanika.
4 Copyright (C) 2011 Antony Dovgal.
5 Copyright (C) 2011 Brian Teague.
6 Copyright (C) 2011-2012 Henrik Andersson.
7 Copyright (C) 2011-2014, 2016 Tobias Ellinghaus.
8 Copyright (C) 2012 Jérémy Rosen.
9 Copyright (C) 2012 Richard Wonka.
10 Copyright (C) 2013-2014 Pascal de Bruijn.
11 Copyright (C) 2013-2017, 2019-2021, 2023 Roman Lebedev.
12 Copyright (C) 2013 Simon Spannagel.
13 Copyright (C) 2014 Dan Torop.
14 Copyright (C) 2014-2016 Pedro Côrte-Real.
15 Copyright (C) 2014 Ulrich Pegelow.
16 Copyright (C) 2016-2017 Peter Budai.
17 Copyright (C) 2018 Heiko Bauke.
18 Copyright (C) 2018 Kelvie Wong.
19 Copyright (C) 2019 Aldric Renaudin.
20 Copyright (C) 2019 Andreas Schneider.
21 Copyright (C) 2019 Edgardo Hoszowski.
22 Copyright (C) 2019-2020 Hanno Schwalm.
23 Copyright (C) 2019-2020 Philippe Weyland.
24 Copyright (C) 2020-2022 Pascal Obry.
25 Copyright (C) 2021 Daniel Vogelbacher.
26 Copyright (C) 2022-2026 Aurélien PIERRE.
27 Copyright (C) 2022 Martin Bařinka.
28 Copyright (C) 2022 paolodepetrillo.
29 Copyright (C) 2022 Philipp Lutz.
30 Copyright (C) 2025 Alynx Zhou.
31
32 darktable is free software: you can redistribute it and/or modify
33 it under the terms of the GNU General Public License as published by
34 the Free Software Foundation, either version 3 of the License, or
35 (at your option) any later version.
36
37 darktable is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
41
42 You should have received a copy of the GNU General Public License
43 along with darktable. If not, see <http://www.gnu.org/licenses/>.
44*/
45
46#ifdef _OPENMP
47#include <omp.h>
48#endif
49
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"
55
56#define TYPE_FLOAT32 RawImageType::F32
57#define TYPE_USHORT16 RawImageType::UINT16
58
59#include <memory>
60
61#define __STDC_LIMIT_MACROS
62
63#include "glib.h"
64
65#include "common/colorspaces.h"
66#include "common/darktable.h"
67#include "common/debug.h"
68#include "common/exif.h"
70#include "common/imageio.h"
72#include "common/tags.h"
73#include "control/conf.h"
74#include "develop/imageop.h"
75#include <stdint.h>
76
77// define this function, it is only declared in rawspeed:
79{
80#ifdef _OPENMP
81 return omp_get_num_procs();
82#else
83 return 1;
84#endif
85}
86
87using namespace rawspeed;
88
90 const RawImage r,
92static CameraMetaData *meta = NULL;
93
95{
96 /* Load rawspeed cameras.xml meta file once */
97 if(IS_NULL_PTR(meta))
98 {
100 if(IS_NULL_PTR(meta))
101 {
102 char datadir[PATH_MAX] = { 0 }, camfile[PATH_MAX] = { 0 };
103 dt_loc_get_datadir(datadir, sizeof(datadir));
104 dt_concat_path_file(camfile, datadir, "rawspeed/cameras.xml");
105 // never cleaned up (only when dt closes)
106 meta = new CameraMetaData(camfile);
107 }
109 }
110}
111
113 const char *model,
114 char *mk,
115 int mk_len,
116 char *md,
117 int md_len,
118 char *al,
119 int al_len)
120{
121 gboolean got_it_done = FALSE;
122 try {
124 // Look for camera in any mode available
125 const Camera *cam = meta->getCamera(maker, model);
126 if(cam)
127 {
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);
131 got_it_done = TRUE;
132 }
133 }
134 catch(const std::exception &exc)
135 {
136 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] %s", exc.what());
137 }
138
139 if(!got_it_done)
140 {
141 // We couldn't find the camera or caught some exception, just punt and pass
142 // through the same values
143 g_strlcpy(mk, maker, mk_len);
144 g_strlcpy(md, model, md_len);
145 g_strlcpy(al, model, al_len);
146 }
147 return got_it_done;
148}
149
150uint32_t dt_rawspeed_crop_dcraw_filters(uint32_t filters, uint32_t crop_x, uint32_t crop_y)
151{
152 if(!filters || filters == 9u) return filters;
153
154 return ColorFilterArray::shiftDcrawFilter(filters, crop_x, crop_y);
155}
156
157// CR3 files are for now handled by LibRAW, we do not want rawspeed to try to open them
158// as this issues lot of error message on the console.
159static gboolean _ignore_image(const gchar *filename)
160{
161 const char *extensions_whitelist[] = { "cr3", NULL };
162 char *ext = g_strrstr(filename, ".");
163 if(IS_NULL_PTR(ext)) return FALSE;
164 ext++;
165 for(const char **i = extensions_whitelist; !IS_NULL_PTR(*i); i++)
166 if(!g_ascii_strncasecmp(ext, *i, strlen(*i)))
167 {
168 return TRUE;
169 }
170 return FALSE;
171}
172
174 const char *filename,
175 dt_mipmap_buffer_t *mbuf)
176{
177 if(_ignore_image(filename))
179
180 if(!img)
181 {
182 dt_print(DT_DEBUG_ALWAYS, "[dt_imageio_open_rawspeed] failed to get dt_image_t for '%s' at %p",
183 filename, mbuf);
185 }
186
187 if(!img->exif_inited)
188 (void)dt_exif_read(img, filename);
189
190 char filen[PATH_MAX] = { 0 };
191 snprintf(filen, sizeof(filen), "%s", filename);
192 FileReader f(filen);
193
194 try
195 {
197
199 auto [storage, storageBuf] = f.readFile();
201
202 RawParser t(storageBuf);
203 std::unique_ptr<RawDecoder> d = t.getDecoder(meta);
204
205 if(!d.get()) return DT_IMAGEIO_UNSUPPORTED_FORMAT;
206
207 d->failOnUnknown = true;
208 d->checkSupport(meta);
209 d->decodeRaw();
210 d->decodeMetaData(meta);
211 RawImage r = d->mRaw;
212
213 const auto errors = r->getErrors();
214 for(const auto &error : errors)
215 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) %s", img->filename, error.c_str());
216
217 g_strlcpy(img->camera_maker, r->metadata.canonical_make.c_str(), sizeof(img->camera_maker));
218 g_strlcpy(img->camera_model, r->metadata.canonical_model.c_str(), sizeof(img->camera_model));
219 g_strlcpy(img->camera_alias, r->metadata.canonical_alias.c_str(), sizeof(img->camera_alias));
221
222 // We used to partial match the Canon local rebrandings so lets pass on
223 // the value just in those cases to be able to fix old history stacks
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"},
256 };
257
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()))
260 {
261 g_strlcpy(img->camera_legacy_makermodel, legacy_aliases[i].mungedname, sizeof(img->camera_legacy_makermodel));
262 break;
263 }
264
265 img->raw_black_level = r->blackLevel;
266 img->raw_white_point = r->whitePoint.value_or((1U << 16)-1);
267
268 // NOTE: while it makes sense to always sample black areas when they exist,
269 // black area handling is broken in rawspeed, so don't do that for now.
270 // https://github.com/darktable-org/rawspeed/issues/389
271 if(!r->blackLevelSeparate)
272 {
273 r->calculateBlackAreas();
274 }
275
276 const auto bl = *(r->blackLevelSeparate->getAsArray1DRef());
277 for(uint8_t i = 0; i < 4; i++)
278 img->raw_black_level_separate[i] = bl(i);
279
280 if(r->blackLevel == -1)
281 {
282 float black = 0.0f;
283 for(uint8_t i = 0; i < 4; i++)
284 {
285 black += img->raw_black_level_separate[i];
286 }
287 black /= 4.0f;
288
289 img->raw_black_level = CLAMP(roundf(black), 0, UINT16_MAX);
290 }
291
292 /*
293 * FIXME
294 * if(r->whitePoint == 65536)
295 * ???
296 */
297
298 /* free auto pointers on spot */
299 d.reset();
300 storage.reset();
301
302 // Grab the WB
303 if(r->metadata.wbCoeffs)
304 {
305 for(int i = 0; i < 4; i++)
306 img->wb_coeffs[i] = (*r->metadata.wbCoeffs)[i];
307 }
308 else
309 {
310 for(int i = 0; i < 4; i++)
311 img->wb_coeffs[i] = 0.0;
312 }
313
314 // Grab the Adobe coeffs
315 const int msize = r->metadata.colorMatrix.size();
316 for(int k = 0; k < 4; k++)
317 for(int i = 0; i < 3; i++)
318 {
319 const int idx = k*3 + i;
320 if(idx < msize)
321 img->adobe_XYZ_to_CAM[k][i] = float(r->metadata.colorMatrix[idx]);
322 else
323 img->adobe_XYZ_to_CAM[k][i] = 0.0f;
324 }
325
326 // Get additional exif tags that are not cached in the database
328
329 if(r->getDataType() == TYPE_FLOAT32)
330 {
331 img->flags |= DT_IMAGE_HDR;
332
333 // We assume that float images should already be normalized.
334 // Also consider 1.0f in binary32 (legacy dt HDR files) as white point magic value;
335 // otherwise (e.g. HDRMerge files), let rawprepare normalize as usual.
336 if(r->whitePoint == 0x3F800000) img->raw_white_point = 1;
337 if(img->raw_white_point == 1)
338 for(int k = 0; k < 4; k++) img->dsc.processed_maximum[k] = 1.0f;
339 }
340 else
341 {
342 // Integer raw (the common case, incl. 8/16-bit Linear Raw / sRAW from film scanners): this
343 // is NOT high dynamic range. rawspeed is the only authority on the *source* datatype here,
344 // because an sRAW is always re-stored as a TYPE_FLOAT buffer in RAM (see the sraw loader),
345 // which makes dt_image_buffer_resolve_flags() unable to tell an integer sRAW from a float
346 // one. We must therefore clear any stale DT_IMAGE_HDR (e.g. a corrupted bit persisted in the
347 // DB) explicitly, otherwise rawprepare picks the HDR normalizer (1.0 instead of the white
348 // level) and divides the already-normalized data to near-zero -> black image (issue: VueScan
349 // 8-bit Linear Raw DNGs with WhiteLevel=65535).
350 img->flags &= ~DT_IMAGE_HDR;
351 }
352
353 img->dsc.filters = 0u;
354
355 // dimensions of uncropped image
356 const iPoint2D dimUncropped = r->getUncroppedDim();
357 img->width = dimUncropped.x;
358 img->height = dimUncropped.y;
359
360 // dimensions of cropped image
361 const iPoint2D dimCropped = r->dim;
362
363 // crop - Top,Left corner
364 const iPoint2D cropTL = r->getCropOffset();
365 img->crop_x = cropTL.x;
366 img->crop_y = cropTL.y;
367
368 // crop - Bottom,Right corner
369 const iPoint2D cropBR = dimUncropped - dimCropped - cropTL;
370 img->crop_width = cropBR.x;
371 img->crop_height = cropBR.y;
372 img->p_width = img->width - img->crop_x - img->crop_width;
373 img->p_height = img->height - img->crop_y - img->crop_height;
374
375 img->fuji_rotation_pos = r->metadata.fujiRotationPos;
376 img->pixel_aspect_ratio = (float)r->metadata.pixelAspectRatio;
377
378 if(!r->isCFA)
379 {
381 return ret;
382 }
383
384 if((r->getDataType() != TYPE_USHORT16) && (r->getDataType() != TYPE_FLOAT32))
386
387 if((r->getBpp() != sizeof(uint16_t)) && (r->getBpp() != sizeof(float)))
389
390 if((r->getDataType() == TYPE_USHORT16) && (r->getBpp() != sizeof(uint16_t)))
392
393 if((r->getDataType() == TYPE_FLOAT32) && (r->getBpp() != sizeof(float)))
395
396 const float cpp = r->getCpp();
397 if(cpp != 1) return DT_IMAGEIO_LOAD_FAILED;
398
399 img->dsc.channels = 1;
400
401 switch(r->getBpp())
402 {
403 case sizeof(uint16_t):
404 img->dsc.datatype = TYPE_UINT16;
405 img->dsc.bpp = sizeof(uint16_t);
406 break;
407 case sizeof(float):
408 img->dsc.datatype = TYPE_FLOAT;
409 img->dsc.bpp = sizeof(float);
410 break;
411 default:
413 }
414
415 // as the X-Trans filters comments later on states, these are for
416 // cropped image, so we need to uncrop them.
417 img->dsc.filters = dt_rawspeed_crop_dcraw_filters(r->cfa.getDcrawFilter(), cropTL.x, cropTL.y);
418
420
421 if(img->dsc.filters)
422 {
423 img->flags &= ~DT_IMAGE_LDR;
424 img->flags |= DT_IMAGE_RAW;
425
426 // special handling for x-trans sensors
427 if(img->dsc.filters == 9u)
428 {
429 // get 6x6 CFA offset from top left of cropped image
430 // NOTE: This is different from how things are done with Bayer
431 // sensors. For these, the CFA in cameras.xml is pre-offset
432 // depending on the distance modulo 2 between raw and usable
433 // image data. For X-Trans, the CFA in cameras.xml is
434 // (currently) aligned with the top left of the raw data.
435 for(int i = 0; i < 6; ++i)
436 for(int j = 0; j < 6; ++j)
437 {
438 img->dsc.xtrans[j][i] = (uint8_t)r->cfa.getColorAt(i % 6, j % 6);
439 }
440 }
441 }
442 // if buf is NULL, we quit the fct here
443 if(!mbuf)
444 {
445 img->dsc.cst = IOP_CS_RAW;
446 img->loader = LOADER_RAWSPEED;
447 return DT_IMAGEIO_OK;
448 }
449
450 void *buf = dt_mipmap_cache_alloc(mbuf, img);
451 if(IS_NULL_PTR(buf)) return DT_IMAGEIO_CACHE_FULL;
452
453 /*
454 * since we do not want to crop black borders at this stage,
455 * and we do not want to rotate image, we can just use memcpy,
456 * as it is faster than dt_imageio_flip_buffers, but only if
457 * buffer sizes are equal,
458 * (from Klaus: r->pitch may differ from DT pitch (line to line spacing))
459 * else fallback to generic dt_imageio_flip_buffers()
460 */
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)
464 {
465 memcpy(buf, (char *)(&(r->getByteDataAsUncroppedArray2DRef()(0, 0))), bufSize_mipmap);
466 }
467 else
468 {
469 dt_imageio_flip_buffers((char *)buf, (char *)(&(r->getByteDataAsUncroppedArray2DRef()(0, 0))), r->getBpp(),
470 dimUncropped.x, dimUncropped.y, dimUncropped.x, dimUncropped.y, r->pitch,
472 }
473
474 // Check if the camera is missing samples
475 const Camera *cam = meta->getCamera(r->metadata.make.c_str(),
476 r->metadata.model.c_str(),
477 r->metadata.mode.c_str());
478
479 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
481 }
482 catch(const rawspeed::IOException &exc)
483 {
484 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) I/O error: %s", img->filename, exc.what());
485 return DT_IMAGEIO_IOERROR;
486 }
487 catch(const rawspeed::FileIOException &exc)
488 {
489 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) File I/O error: %s", img->filename, exc.what());
490 return DT_IMAGEIO_IOERROR;
491 }
492 catch(const rawspeed::RawDecoderException &exc)
493 {
494 const char *msg = exc.what();
495 // FIXME FIXME
496 // The following is a nasty hack which will break if exception messages change.
497 // The proper way to handle this is to add two new exception types to Rawspeed and
498 // have them throw the appropriate ones on encountering an unsupported camera model
499 // or unsupported feature (e.g. bit depth, compression, aspect ratio mode, ...)
500 if(msg && (strstr(msg, "Camera not supported") || strstr(msg, "not supported, and not allowed to guess")))
501 {
502 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] Unsupported camera model for %s", img->filename);
504 }
505 else if (msg && strstr(msg, "supported"))
506 {
507 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) %s", img->filename, msg);
509 }
510 else
511 {
512 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] %s corrupt: %s", img->filename, exc.what());
513 // We can end up here if the loader is called on what is actually
514 // a TIFF file, which mistakenly contains the signature of a raw
515 // format in a TIFF container. So it is very important that the
516 // return code from here directs the execution path through the
517 // fallback loader chain.
519 }
520 }
521 catch(const rawspeed::RawParserException &exc)
522 {
523 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) CIFF/FIFF error: %s", img->filename, exc.what());
525 }
526 catch(const rawspeed::CameraMetadataException &exc)
527 {
528 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) metadata error: %s", img->filename, exc.what());
530 }
531 catch(const std::exception &exc)
532 {
533 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] (%s) %s", img->filename, exc.what());
534
535 /* if an exception is raised lets not retry or handle the
536 specific ones, consider the file as corrupted */
538 }
539 catch(...)
540 {
541 dt_print(DT_DEBUG_ALWAYS, "[rawspeed] unhandled exception in imageio_rawspeed");
543 }
544
545 img->dsc.cst = IOP_CS_RAW;
546 img->loader = LOADER_RAWSPEED;
547
548 return DT_IMAGEIO_OK;
549}
550
552 const RawImage r,
553 dt_mipmap_buffer_t *mbuf)
554{
555 // sraw aren't real raw, but not ldr either (need white balance and stuff)
556 img->flags &= ~DT_IMAGE_LDR;
557 img->flags &= ~DT_IMAGE_RAW;
558 img->flags |= DT_IMAGE_S_RAW;
559
560 // actually we want to store full floats here:
561 img->dsc.channels = 4;
562 img->dsc.datatype = TYPE_FLOAT;
563 img->dsc.bpp = 4 * sizeof(float);
564
565 if(r->getDataType() != TYPE_USHORT16 && r->getDataType() != TYPE_FLOAT32)
567
568 const uint32_t cpp = r->getCpp();
569 if(cpp != 1 && cpp != 3 && cpp != 4) return DT_IMAGEIO_FILE_CORRUPTED;
570
571 // if buf is NULL, we quit the fct here
572 if(!mbuf)
573 {
574 img->dsc.cst = IOP_CS_RAW;
575 img->loader = LOADER_RAWSPEED;
576 return DT_IMAGEIO_OK;
577 }
578
579 if(cpp == 1) img->flags |= DT_IMAGE_MONOCHROME;
580
581 void *buf = dt_mipmap_cache_alloc(mbuf, img);
582 if(IS_NULL_PTR(buf)) return DT_IMAGEIO_CACHE_FULL;
583
584 const int height = img->height;
585 const int width = img->width;
586
587 if(cpp == 1)
588 {
589 /*
590 * monochrome image (e.g. Leica M9 monochrom),
591 * we need to copy data from only channel to each of 3 channels
592 */
593
594 if(r->getDataType() == TYPE_USHORT16)
595 {
596 __OMP_PARALLEL_FOR_CPP__(shared(r) firstprivate(height, width, buf, cpp))
597 for(int j = 0; j < height; j++)
598 {
599 const Array2DRef<uint16_t> in = r->getU16DataAsUncroppedArray2DRef();
600 float *out = ((float *)buf) + (size_t)4 * j * width;
601
602 for(int i = 0; i < width; i++, out += 4)
603 {
604 out[0] = out[1] = out[2] = (float)in(j, cpp * i) / (float)UINT16_MAX;
605 out[3] = 0.0f;
606 }
607 }
608
609 }
610 else // r->getDataType() == TYPE_FLOAT32
611 {
612 __OMP_PARALLEL_FOR_CPP__(shared(r) firstprivate(height, width, buf, cpp))
613 for(int j = 0; j < height; j++)
614 {
615 const Array2DRef<float> in = r->getF32DataAsUncroppedArray2DRef();
616 float *out = ((float *)buf) + (size_t)4 * j * width;
617
618 for(int i = 0; i < width; i++, out += 4)
619 {
620 out[0] = out[1] = out[2] = in(j, cpp * i);
621 out[3] = 0.0f;
622 }
623 }
624
625 }
626 }
627 else // case cpp == 3 or 4
628 {
629 /*
630 * standard 3-ch image
631 * just copy 3 ch to 3 ch
632 */
633
634 if(r->getDataType() == TYPE_USHORT16)
635 {
636 __OMP_PARALLEL_FOR_CPP__(shared(r) firstprivate(height, width, buf, cpp))
637 for(int j = 0; j < height; j++)
638 {
639 const Array2DRef<uint16_t> in = r->getU16DataAsUncroppedArray2DRef();
640 float *out = ((float *)buf) + (size_t)4 * j * width;
641
642 for(int i = 0; i < width; i++, out += 4)
643 {
644 for(int k = 0; k < 3; k++)
645 out[k] = (float)in(j, cpp * i + k) / (float)UINT16_MAX;
646 out[3] = 0.0f;
647 }
648 }
649
650 }
651 else // r->getDataType() == TYPE_FLOAT32
652 {
653 __OMP_PARALLEL_FOR_CPP__(shared(r) firstprivate(height, width, buf, cpp))
654 for(int j = 0; j < height; j++)
655 {
656 const Array2DRef<float> in = r->getF32DataAsUncroppedArray2DRef();
657 float *out = ((float *)buf) + (size_t)4 * j * width;
658
659 for(int i = 0; i < width; i++, out += 4)
660 {
661 for(int k = 0; k < 3; k++)
662 out[k] = in(j, cpp * i + k);
663 out[3] = 0.0f;
664 }
665 }
666
667 }
668 }
669
670 img->dsc.cst = IOP_CS_RGB;
671 img->loader = LOADER_RAWSPEED;
672
673 // Check if the camera is missing samples
674 const Camera *cam = meta->getCamera(r->metadata.make.c_str(),
675 r->metadata.model.c_str(),
676 r->metadata.mode.c_str());
677
678 if(cam && cam->supportStatus == Camera::SupportStatus::SupportedNoSamples)
680
681 return DT_IMAGEIO_OK;
682}
683
684// clang-format off
685// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
686// vim: shiftwidth=2 expandtab tabstop=2 cindent
687// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
688// clang-format on
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
@ IOP_CS_RAW
@ IOP_CS_RGB
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)
Definition darktable.c:1889
darktable_t darktable
Definition darktable.c:181
void dt_print(dt_debug_thread_t thread, const char *msg,...)
Definition darktable.c:1542
@ DT_DEBUG_ALWAYS
Definition darktable.h:713
#define __OMP_PARALLEL_FOR_CPP__(...)
Definition darktable.h:265
#define PATH_MAX
Definition darktable.h:1062
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:374
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:364
int dt_exif_read(dt_image_t *img, const char *path)
Definition exif.cc:1753
void dt_exif_img_check_additional_tags(dt_image_t *img, const char *filename)
Definition exif.cc:836
void dt_loc_get_datadir(char *datadir, size_t bufsize)
@ TYPE_FLOAT
Definition format.h:46
@ TYPE_UINT16
Definition format.h:47
@ ORIENTATION_NONE
Definition image.h:205
dt_imageio_retval_t
Definition image.h:78
@ DT_IMAGEIO_LOAD_FAILED
Definition image.h:86
@ DT_IMAGEIO_OK
Definition image.h:79
@ DT_IMAGEIO_CACHE_FULL
Definition image.h:82
@ DT_IMAGEIO_UNSUPPORTED_FEATURE
Definition image.h:84
@ DT_IMAGEIO_FILE_CORRUPTED
Definition image.h:81
@ DT_IMAGEIO_UNSUPPORTED_FORMAT
Definition image.h:83
@ DT_IMAGEIO_IOERROR
Definition image.h:87
@ DT_IMAGEIO_UNSUPPORTED_CAMERA
Definition image.h:85
@ DT_IMAGE_S_RAW
Definition image.h:134
@ DT_IMAGE_RAW
Definition image.h:111
@ DT_IMAGE_4BAYER
Definition image.h:127
@ DT_IMAGE_MONOCHROME
Definition image.h:129
@ DT_IMAGE_HDR
Definition image.h:113
@ LOADER_RAWSPEED
Definition image.h:231
__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)
Definition imageio.c:398
#define FILTERS_ARE_4BAYER(filters)
Definition imageio.h:55
static CameraMetaData * meta
#define TYPE_USHORT16
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)
#define TYPE_FLOAT32
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)
const char * maker
const char * model
const int t
float *const restrict const size_t k
void * dt_mipmap_cache_alloc(dt_mipmap_buffer_t *buf, const dt_image_t *img)
const float r
dt_pthread_mutex_t readFile_mutex
Definition darktable.h:803
dt_pthread_mutex_t plugin_threadsafe
Definition darktable.h:793
float pixel_aspect_ratio
Definition image.h:356
int32_t height
Definition image.h:315
gboolean camera_missing_sample
Definition image.h:302
char camera_model[64]
Definition image.h:298
uint16_t raw_black_level
Definition image.h:350
dt_image_loader_t loader
Definition image.h:335
char camera_maker[64]
Definition image.h:297
uint32_t raw_white_point
Definition image.h:352
int32_t exif_inited
Definition image.h:283
int32_t crop_height
Definition image.h:316
char camera_legacy_makermodel[128]
Definition image.h:301
int32_t flags
Definition image.h:319
int32_t width
Definition image.h:315
int32_t crop_y
Definition image.h:316
char camera_alias[64]
Definition image.h:299
int32_t crop_x
Definition image.h:316
int32_t p_height
Definition image.h:315
dt_iop_buffer_dsc_t dsc
Definition image.h:337
int32_t p_width
Definition image.h:315
float adobe_XYZ_to_CAM[4][3]
Definition image.h:362
int32_t crop_width
Definition image.h:316
char filename[DT_MAX_FILENAME_LEN]
Definition image.h:304
uint16_t raw_black_level_separate[4]
Definition image.h:351
dt_aligned_pixel_t wb_coeffs
Definition image.h:359
uint32_t fuji_rotation_pos
Definition image.h:355
uint32_t filters
Definition format.h:60
unsigned int channels
Definition format.h:54
uint8_t xtrans[6][6]
Definition format.h:70
dt_iop_buffer_type_t datatype
Definition format.h:56
dt_aligned_pixel_t processed_maximum
Definition format.h:85