Blender V5.0
image_format.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
11#include "DNA_defaults.h"
12#include "DNA_scene_types.h"
13
14#include "BLI_path_utils.hh"
15#include "BLI_string_utf8.h"
16#include "BLI_utildefines.h"
17
19#include "IMB_imbuf_types.hh"
20
21#include "MOV_util.hh"
22
23#include "BKE_colortools.hh"
24#include "BKE_image_format.hh"
25#include "BKE_path_templates.hh"
26
28
29/* Init/Copy/Free */
30
41
50
55
57{
58 /* If the color space is set to a data space, this is probably the user's intention, so leave it
59 * as is. */
60 if (IMB_colormanagement_space_name_is_data(format->linear_colorspace_settings.name)) {
61 return;
62 }
63
64 const bool image_requires_linear = BKE_imtype_requires_linear_float(format->imtype);
66 format->linear_colorspace_settings.name);
67
68 /* The color space is either not set or is linear but the image requires non-linear or vice
69 * versa. So set to the default for the image type. */
70 if (format->linear_colorspace_settings.name[0] == '\0' || image_requires_linear != is_linear) {
71 const int role = image_requires_linear ? COLOR_ROLE_DEFAULT_FLOAT : COLOR_ROLE_DEFAULT_BYTE;
72 const char *default_color_space = IMB_colormanagement_role_colorspace_name_get(role);
73 STRNCPY_UTF8(format->linear_colorspace_settings.name, default_color_space);
74 }
75}
76
81
86
88 ID *owner_id,
89 const MediaType media_type)
90{
91 format->media_type = media_type;
92
93 switch (media_type) {
95 if (!BKE_imtype_is_image(format->imtype)) {
97 }
98 break;
102 }
103 break;
104 case MEDIA_TYPE_VIDEO:
105 if (!BKE_imtype_is_movie(format->imtype)) {
107 }
108 break;
109 }
110}
111
112void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype)
113{
114 imf->imtype = imtype;
115
116 /* Update media type in case it doesn't match the new imtype. Note that normally, one would use
117 * the BKE_image_format_media_type_set function to set the media type, but that function itself
118 * calls this function to update the imtype, and while this wouldn't case recursion since the
119 * imtype is already conforming, it is better to err on the side of caution and set the media
120 * type manually. */
121 if (BKE_imtype_is_image(imf->imtype)) {
123 }
126 }
127 else if (BKE_imtype_is_movie(imf->imtype)) {
129 }
130 else {
132 }
133
134 const bool is_render = (owner_id && GS(owner_id->name) == ID_SCE);
135 /* see note below on why this is */
136 const char chan_flag = BKE_imtype_valid_channels(imf->imtype) |
137 (is_render ? IMA_CHAN_FLAG_BW : 0);
138
139 /* ensure depth and color settings match */
140 if ((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) {
142 }
143 if ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_RGBA)) {
145 }
146
147 /* ensure usable depth */
148 {
149 const int depth_ok = BKE_imtype_valid_depths(imf->imtype);
150 if ((imf->depth & depth_ok) == 0) {
151 imf->depth = BKE_imtype_first_valid_depth(depth_ok);
152 }
153 }
154
155 if (owner_id && GS(owner_id->name) == ID_SCE) {
156 Scene *scene = reinterpret_cast<Scene *>(owner_id);
157 RenderData *rd = &scene->r;
159 }
160
161 /* Verify `imf->views_format`. */
162 if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) {
165 }
166 }
167 else if (imf->imtype != R_IMF_IMTYPE_OPENEXR) {
170 }
171 }
172
174}
175
176/* File Types */
177
178int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
179{
180 memset(r_options, 0, sizeof(*r_options));
181
182 if (imtype == R_IMF_IMTYPE_TARGA) {
183 return IMB_FTYPE_TGA;
184 }
185 if (imtype == R_IMF_IMTYPE_RAWTGA) {
186 r_options->flag = RAWTGA;
187 return IMB_FTYPE_TGA;
188 }
189 if (imtype == R_IMF_IMTYPE_IRIS) {
190 return IMB_FTYPE_IRIS;
191 }
192 if (imtype == R_IMF_IMTYPE_RADHDR) {
193 return IMB_FTYPE_RADHDR;
194 }
195 if (imtype == R_IMF_IMTYPE_PNG) {
196 r_options->quality = 15;
197 return IMB_FTYPE_PNG;
198 }
199 if (imtype == R_IMF_IMTYPE_DDS) {
200 return IMB_FTYPE_DDS;
201 }
202 if (imtype == R_IMF_IMTYPE_BMP) {
203 return IMB_FTYPE_BMP;
204 }
205 if (imtype == R_IMF_IMTYPE_TIFF) {
206 return IMB_FTYPE_TIF;
207 }
209 r_options->quality = 90;
210 return IMB_FTYPE_OPENEXR;
211 }
212#ifdef WITH_IMAGE_CINEON
213 if (imtype == R_IMF_IMTYPE_CINEON) {
214 return IMB_FTYPE_CINEON;
215 }
216 if (imtype == R_IMF_IMTYPE_DPX) {
217 return IMB_FTYPE_DPX;
218 }
219#endif
220#ifdef WITH_IMAGE_OPENJPEG
221 if (imtype == R_IMF_IMTYPE_JP2) {
222 r_options->flag |= JP2_JP2;
223 r_options->quality = 90;
224 return IMB_FTYPE_JP2;
225 }
226#endif
227#ifdef WITH_IMAGE_WEBP
228 if (imtype == R_IMF_IMTYPE_WEBP) {
229 r_options->quality = 90;
230 return IMB_FTYPE_WEBP;
231 }
232#endif
233
234 r_options->quality = 90;
235 return IMB_FTYPE_JPG;
236}
237
238char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
239{
240 if (ftype == IMB_FTYPE_NONE) {
241 return R_IMF_IMTYPE_TARGA;
242 }
243 if (ftype == IMB_FTYPE_IRIS) {
244 return R_IMF_IMTYPE_IRIS;
245 }
246 if (ftype == IMB_FTYPE_RADHDR) {
247 return R_IMF_IMTYPE_RADHDR;
248 }
249 if (ftype == IMB_FTYPE_PNG) {
250 return R_IMF_IMTYPE_PNG;
251 }
252 if (ftype == IMB_FTYPE_DDS) {
253 return R_IMF_IMTYPE_DDS;
254 }
255 if (ftype == IMB_FTYPE_BMP) {
256 return R_IMF_IMTYPE_BMP;
257 }
258 if (ftype == IMB_FTYPE_TIF) {
259 return R_IMF_IMTYPE_TIFF;
260 }
261 if (ftype == IMB_FTYPE_OPENEXR) {
263 }
264#ifdef WITH_IMAGE_CINEON
265 if (ftype == IMB_FTYPE_CINEON) {
266 return R_IMF_IMTYPE_CINEON;
267 }
268 if (ftype == IMB_FTYPE_DPX) {
269 return R_IMF_IMTYPE_DPX;
270 }
271#endif
272 if (ftype == IMB_FTYPE_TGA) {
273 if (options && (options->flag & RAWTGA)) {
274 return R_IMF_IMTYPE_RAWTGA;
275 }
276
277 return R_IMF_IMTYPE_TARGA;
278 }
279#ifdef WITH_IMAGE_OPENJPEG
280 if (ftype == IMB_FTYPE_JP2) {
281 return R_IMF_IMTYPE_JP2;
282 }
283#endif
284#ifdef WITH_IMAGE_WEBP
285 if (ftype == IMB_FTYPE_WEBP) {
286 return R_IMF_IMTYPE_WEBP;
287 }
288#endif
289
290 return R_IMF_IMTYPE_JPEG90;
291}
292
293bool BKE_imtype_is_image(const char imtype)
294{
295 return !BKE_imtype_is_multi_layer_image(imtype) && !BKE_imtype_is_movie(imtype);
296}
297
298bool BKE_imtype_is_multi_layer_image(const char imtype)
299{
300 return imtype == R_IMF_IMTYPE_MULTILAYER;
301}
302
303bool BKE_imtype_is_movie(const char imtype)
304{
305 return imtype == R_IMF_IMTYPE_FFMPEG;
306}
307
308bool BKE_imtype_supports_compress(const char imtype)
309{
310 switch (imtype) {
311 case R_IMF_IMTYPE_PNG:
312 return true;
313 }
314 return false;
315}
316
317bool BKE_imtype_supports_quality(const char imtype)
318{
319 switch (imtype) {
321 case R_IMF_IMTYPE_JP2:
323 return true;
324 }
325 return false;
326}
327
328bool BKE_imtype_requires_linear_float(const char imtype)
329{
330 switch (imtype) {
332 case R_IMF_IMTYPE_DPX:
336 return true;
337 }
338 return false;
339}
340
341char BKE_imtype_valid_channels(const char imtype)
342{
343 char chan_flag = IMA_CHAN_FLAG_RGB; /* Assume all support RGB. */
344
345 /* Alpha. */
346 switch (imtype) {
347 case R_IMF_IMTYPE_BMP:
351 case R_IMF_IMTYPE_PNG:
355 case R_IMF_IMTYPE_DDS:
356 case R_IMF_IMTYPE_JP2:
357 case R_IMF_IMTYPE_DPX:
359 chan_flag |= IMA_CHAN_FLAG_RGBA;
360 break;
361 }
362
363 /* BW. */
364 switch (imtype) {
365 case R_IMF_IMTYPE_BMP:
366 case R_IMF_IMTYPE_PNG:
373 chan_flag |= IMA_CHAN_FLAG_BW;
374 break;
375 }
376
377 return chan_flag;
378}
379
380char BKE_imtype_valid_depths(const char imtype)
381{
382 switch (imtype) {
384 return R_IMF_CHAN_DEPTH_32;
391 /* NOTE: CINEON uses an unusual 10bits-LOG per channel. */
392 case R_IMF_IMTYPE_DPX:
395 return R_IMF_CHAN_DEPTH_10;
396 case R_IMF_IMTYPE_JP2:
398 case R_IMF_IMTYPE_PNG:
400 /* Most formats are 8bit only. */
401 default:
402 return R_IMF_CHAN_DEPTH_8;
403 }
404}
405
406char BKE_imtype_valid_depths_with_video(char imtype, const ID *owner_id)
407{
408 UNUSED_VARS(owner_id); /* Might be unused depending on build options. */
409
410 int depths = BKE_imtype_valid_depths(imtype);
411 /* Depending on video codec selected, valid color bit depths might vary. */
412 if (imtype == R_IMF_IMTYPE_FFMPEG) {
413 const bool is_render_out = (owner_id && GS(owner_id->name) == ID_SCE);
414 if (is_render_out) {
415 const Scene *scene = (const Scene *)owner_id;
416 depths |= MOV_codec_valid_bit_depths(scene->r.ffcodecdata.codec_id_get());
417 }
418 }
419 return depths;
420}
421
422char BKE_imtype_first_valid_depth(const char valid_depths)
423{
424 /* set first available depth */
425 const char depth_ls[] = {
433 0,
434 };
435 for (int i = 0; depth_ls[i]; i++) {
436 if (valid_depths & depth_ls[i]) {
437 return depth_ls[i];
438 }
439 }
440 return R_IMF_CHAN_DEPTH_8;
441}
442
443char BKE_imtype_from_arg(const char *imtype_arg)
444{
445 if (STREQ(imtype_arg, "TGA")) {
446 return R_IMF_IMTYPE_TARGA;
447 }
448 if (STREQ(imtype_arg, "IRIS")) {
449 return R_IMF_IMTYPE_IRIS;
450 }
451 if (STREQ(imtype_arg, "JPEG")) {
452 return R_IMF_IMTYPE_JPEG90;
453 }
454 if (STREQ(imtype_arg, "RAWTGA")) {
455 return R_IMF_IMTYPE_RAWTGA;
456 }
457 if (STREQ(imtype_arg, "PNG")) {
458 return R_IMF_IMTYPE_PNG;
459 }
460 if (STREQ(imtype_arg, "BMP")) {
461 return R_IMF_IMTYPE_BMP;
462 }
463 if (STREQ(imtype_arg, "HDR")) {
464 return R_IMF_IMTYPE_RADHDR;
465 }
466 if (STREQ(imtype_arg, "TIFF")) {
467 return R_IMF_IMTYPE_TIFF;
468 }
469#ifdef WITH_IMAGE_OPENEXR
470 if (STREQ(imtype_arg, "OPEN_EXR")) {
472 }
473 if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) {
475 }
476 if (STREQ(imtype_arg, "EXR")) {
478 }
479 if (STREQ(imtype_arg, "MULTILAYER")) {
481 }
482#endif
483#ifdef WITH_FFMPEG
484 if (STREQ(imtype_arg, "FFMPEG")) {
485 return R_IMF_IMTYPE_FFMPEG;
486 }
487#endif
488#ifdef WITH_IMAGE_CINEON
489 if (STREQ(imtype_arg, "CINEON")) {
490 return R_IMF_IMTYPE_CINEON;
491 }
492 if (STREQ(imtype_arg, "DPX")) {
493 return R_IMF_IMTYPE_DPX;
494 }
495#endif
496#ifdef WITH_IMAGE_OPENJPEG
497 if (STREQ(imtype_arg, "JP2")) {
498 return R_IMF_IMTYPE_JP2;
499 }
500#endif
501#ifdef WITH_IMAGE_WEBP
502 if (STREQ(imtype_arg, "WEBP")) {
503 return R_IMF_IMTYPE_WEBP;
504 }
505#endif
506
508}
509
510/* File Paths */
511
512static int image_path_ext_from_imformat_impl(const char imtype,
513 const ImageFormatData *im_format,
514 const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
515{
516 int ext_num = 0;
517 (void)im_format; /* may be unused, depends on build options */
518
519 if (imtype == R_IMF_IMTYPE_IRIS) {
520 r_ext[ext_num++] = ".rgb";
521 }
522 else if (imtype == R_IMF_IMTYPE_IRIZ) {
523 r_ext[ext_num++] = ".rgb";
524 }
525 else if (imtype == R_IMF_IMTYPE_RADHDR) {
526 r_ext[ext_num++] = ".hdr";
527 }
528 else if (ELEM(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG)) {
529 r_ext[ext_num++] = ".png";
530 }
531 else if (imtype == R_IMF_IMTYPE_DDS) {
532 r_ext[ext_num++] = ".dds";
533 }
534 else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
535 r_ext[ext_num++] = ".tga";
536 }
537 else if (imtype == R_IMF_IMTYPE_BMP) {
538 r_ext[ext_num++] = ".bmp";
539 }
540 else if (imtype == R_IMF_IMTYPE_TIFF) {
541 r_ext[ext_num++] = ".tif";
542 r_ext[ext_num++] = ".tiff";
543 }
544 else if (imtype == R_IMF_IMTYPE_PSD) {
545 r_ext[ext_num++] = ".psd";
546 }
547#ifdef WITH_IMAGE_OPENEXR
549 r_ext[ext_num++] = ".exr";
550 }
551#endif
552#ifdef WITH_IMAGE_CINEON
553 else if (imtype == R_IMF_IMTYPE_CINEON) {
554 r_ext[ext_num++] = ".cin";
555 }
556 else if (imtype == R_IMF_IMTYPE_DPX) {
557 r_ext[ext_num++] = ".dpx";
558 }
559#endif
560#ifdef WITH_IMAGE_OPENJPEG
561 else if (imtype == R_IMF_IMTYPE_JP2) {
562 if (im_format) {
563 if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
564 r_ext[ext_num++] = ".jp2";
565 }
566 else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
567 r_ext[ext_num++] = ".j2c";
568 }
569 else {
570 BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
571 }
572 }
573 else {
574 r_ext[ext_num++] = ".jp2";
575 }
576 }
577#endif
578#ifdef WITH_IMAGE_WEBP
579 else if (imtype == R_IMF_IMTYPE_WEBP) {
580 r_ext[ext_num++] = ".webp";
581 }
582#endif
583 else {
584 /* Handles: #R_IMF_IMTYPE_JPEG90 etc. */
585 r_ext[ext_num++] = ".jpg";
586 r_ext[ext_num++] = ".jpeg";
587 }
589 r_ext[ext_num] = nullptr;
590 return ext_num;
591}
592
594 const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
595{
596 return image_path_ext_from_imformat_impl(im_format->imtype, im_format, r_ext);
597}
598
599int BKE_image_path_ext_from_imtype(const char imtype, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
600{
601 return image_path_ext_from_imformat_impl(imtype, nullptr, r_ext);
602}
603
604static bool do_ensure_image_extension(char *filepath,
605 const size_t filepath_maxncpy,
606 const char imtype,
607 const ImageFormatData *im_format)
608{
609 const char *ext_array[BKE_IMAGE_PATH_EXT_MAX];
610 int ext_array_num = image_path_ext_from_imformat_impl(imtype, im_format, ext_array);
611 if (ext_array_num && !BLI_path_extension_check_array(filepath, ext_array)) {
612 /* Removing *any* extension may remove part of the user defined name (if they include '.')
613 * however in the case there is already a known image extension,
614 * remove it to avoid`.png.tga`, for example. */
616 return BLI_path_extension_replace(filepath, filepath_maxncpy, ext_array[0]);
617 }
618 return BLI_path_extension_ensure(filepath, filepath_maxncpy, ext_array[0]);
619 }
620
621 return false;
622}
623
625 const size_t filepath_maxncpy,
626 const ImageFormatData *im_format)
627{
628 return do_ensure_image_extension(filepath, filepath_maxncpy, im_format->imtype, im_format);
629}
630
632 const size_t filepath_maxncpy,
633 const char imtype)
634{
635 return do_ensure_image_extension(filepath, filepath_maxncpy, imtype, nullptr);
636}
637
639 char filepath[FILE_MAX],
640 const char *base,
641 const char *relbase,
642 const path_templates::VariableMap *template_variables,
643 int frame,
644 const char imtype,
645 const ImageFormatData *im_format,
646 const bool use_ext,
647 const bool use_frames,
648 const char *suffix)
649{
650 if (filepath == nullptr) {
651 return {};
652 }
653 BLI_strncpy(filepath, base, FILE_MAX - 10); /* weak assumption */
654
655 if (template_variables) {
657 filepath, FILE_MAX, *template_variables);
658 if (!variable_errors.is_empty()) {
659 return variable_errors;
660 }
661 }
662
663 BLI_path_abs(filepath, relbase);
664
665 if (use_frames) {
666 BLI_path_frame(filepath, FILE_MAX, frame, 4);
667 }
668
669 if (suffix) {
670 BLI_path_suffix(filepath, FILE_MAX, suffix, "");
671 }
672
673 if (use_ext) {
674 do_ensure_image_extension(filepath, FILE_MAX, imtype, im_format);
675 }
676
677 return {};
678}
679
681 char *filepath,
682 const char *base,
683 const char *relbase,
684 const path_templates::VariableMap *template_variables,
685 int frame,
686 const ImageFormatData *im_format,
687 const bool use_ext,
688 const bool use_frames,
689 const char *suffix)
690{
691 return do_makepicstring(filepath,
692 base,
693 relbase,
694 template_variables,
695 frame,
696 im_format->imtype,
697 im_format,
698 use_ext,
699 use_frames,
700 suffix);
701}
702
704 char *filepath,
705 const char *base,
706 const char *relbase,
707 const path_templates::VariableMap *template_variables,
708 int frame,
709 const char imtype,
710 const bool use_ext,
711 const bool use_frames,
712 const char *suffix)
713{
714 return do_makepicstring(filepath,
715 base,
716 relbase,
717 template_variables,
718 frame,
719 imtype,
720 nullptr,
721 use_ext,
722 use_frames,
723 suffix);
724}
725
726/* ImBuf Conversion */
727
729{
730 /* Write to ImBuf in preparation for file writing. */
731 char imtype = imf->imtype;
732 char compress = imf->compress;
733 char quality = imf->quality;
734
735 /* initialize all from image format */
736 ibuf->foptions.flag = 0;
737
738 if (imtype == R_IMF_IMTYPE_IRIS) {
739 ibuf->ftype = IMB_FTYPE_IRIS;
740 }
741 else if (imtype == R_IMF_IMTYPE_RADHDR) {
742 ibuf->ftype = IMB_FTYPE_RADHDR;
743 }
744 else if (ELEM(imtype, R_IMF_IMTYPE_PNG, R_IMF_IMTYPE_FFMPEG)) {
745 ibuf->ftype = IMB_FTYPE_PNG;
746
747 if (imtype == R_IMF_IMTYPE_PNG) {
748 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
749 ibuf->foptions.flag |= PNG_16BIT;
750 }
751
752 ibuf->foptions.quality = compress;
753 }
754 }
755 else if (imtype == R_IMF_IMTYPE_DDS) {
756 ibuf->ftype = IMB_FTYPE_DDS;
757 }
758 else if (imtype == R_IMF_IMTYPE_BMP) {
759 ibuf->ftype = IMB_FTYPE_BMP;
760 }
761 else if (imtype == R_IMF_IMTYPE_TIFF) {
762 ibuf->ftype = IMB_FTYPE_TIF;
763
764 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
765 ibuf->foptions.flag |= TIF_16BIT;
766 }
767 if (imf->tiff_codec == R_IMF_TIFF_CODEC_NONE) {
769 }
770 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_DEFLATE) {
772 }
773 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_LZW) {
775 }
776 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_PACKBITS) {
778 }
779 }
780#ifdef WITH_IMAGE_OPENEXR
782 ibuf->ftype = IMB_FTYPE_OPENEXR;
783 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
784 ibuf->foptions.flag |= OPENEXR_HALF;
785 }
786 ibuf->foptions.flag |= (imf->exr_codec & OPENEXR_CODEC_MASK);
787 ibuf->foptions.quality = quality;
790 }
791 }
792#endif
793#ifdef WITH_IMAGE_CINEON
794 else if (imtype == R_IMF_IMTYPE_CINEON) {
795 ibuf->ftype = IMB_FTYPE_CINEON;
797 ibuf->foptions.flag |= CINEON_LOG;
798 }
799 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
800 ibuf->foptions.flag |= CINEON_16BIT;
801 }
802 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
803 ibuf->foptions.flag |= CINEON_12BIT;
804 }
805 else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
806 ibuf->foptions.flag |= CINEON_10BIT;
807 }
808 }
809 else if (imtype == R_IMF_IMTYPE_DPX) {
810 ibuf->ftype = IMB_FTYPE_DPX;
812 ibuf->foptions.flag |= CINEON_LOG;
813 }
814 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
815 ibuf->foptions.flag |= CINEON_16BIT;
816 }
817 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
818 ibuf->foptions.flag |= CINEON_12BIT;
819 }
820 else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
821 ibuf->foptions.flag |= CINEON_10BIT;
822 }
823 }
824#endif
825 else if (imtype == R_IMF_IMTYPE_TARGA) {
826 ibuf->ftype = IMB_FTYPE_TGA;
827 }
828 else if (imtype == R_IMF_IMTYPE_RAWTGA) {
829 ibuf->ftype = IMB_FTYPE_TGA;
830 ibuf->foptions.flag = RAWTGA;
831 }
832#ifdef WITH_IMAGE_OPENJPEG
833 else if (imtype == R_IMF_IMTYPE_JP2) {
834 if (quality < 10) {
835 quality = 90;
836 }
837 ibuf->ftype = IMB_FTYPE_JP2;
838 ibuf->foptions.quality = quality;
839
840 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
841 ibuf->foptions.flag |= JP2_16BIT;
842 }
843 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
844 ibuf->foptions.flag |= JP2_12BIT;
845 }
846
847 if (imf->jp2_flag & R_IMF_JP2_FLAG_YCC) {
848 ibuf->foptions.flag |= JP2_YCC;
849 }
850
852 ibuf->foptions.flag |= JP2_CINE;
853 if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48) {
854 ibuf->foptions.flag |= JP2_CINE_48FPS;
855 }
856 }
857
858 if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2) {
859 ibuf->foptions.flag |= JP2_JP2;
860 }
861 else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K) {
862 ibuf->foptions.flag |= JP2_J2K;
863 }
864 else {
865 BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
866 }
867 }
868#endif
869#ifdef WITH_IMAGE_WEBP
870 else if (imtype == R_IMF_IMTYPE_WEBP) {
871 ibuf->ftype = IMB_FTYPE_WEBP;
872 ibuf->foptions.quality = quality;
873 }
874#endif
875 else {
876 /* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */
877 if (quality < 10) {
878 quality = 90;
879 }
880 ibuf->ftype = IMB_FTYPE_JPG;
881 ibuf->foptions.quality = quality;
882 }
883}
884
885static char imtype_best_depth(const ImBuf *ibuf, const char imtype)
886{
887 const char depth_ok = BKE_imtype_valid_depths(imtype);
888
889 if (ibuf->float_buffer.data) {
890 if (depth_ok & R_IMF_CHAN_DEPTH_32) {
891 return R_IMF_CHAN_DEPTH_32;
892 }
893 if (depth_ok & R_IMF_CHAN_DEPTH_24) {
894 return R_IMF_CHAN_DEPTH_24;
895 }
896 if (depth_ok & R_IMF_CHAN_DEPTH_16) {
897 return R_IMF_CHAN_DEPTH_16;
898 }
899 if (depth_ok & R_IMF_CHAN_DEPTH_12) {
900 return R_IMF_CHAN_DEPTH_12;
901 }
902 return R_IMF_CHAN_DEPTH_8;
903 }
904
905 if (depth_ok & R_IMF_CHAN_DEPTH_8) {
906 return R_IMF_CHAN_DEPTH_8;
907 }
908 if (depth_ok & R_IMF_CHAN_DEPTH_12) {
909 return R_IMF_CHAN_DEPTH_12;
910 }
911 if (depth_ok & R_IMF_CHAN_DEPTH_16) {
912 return R_IMF_CHAN_DEPTH_16;
913 }
914 if (depth_ok & R_IMF_CHAN_DEPTH_24) {
915 return R_IMF_CHAN_DEPTH_24;
916 }
917 if (depth_ok & R_IMF_CHAN_DEPTH_32) {
918 return R_IMF_CHAN_DEPTH_32;
919 }
920 return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */
921}
922
924{
925 /* Read from ImBuf after file read. */
926 int ftype = imbuf->ftype;
927 int custom_flags = imbuf->foptions.flag;
928 char quality = imbuf->foptions.quality;
929 bool is_depth_set = false;
930
931 BKE_image_format_init(im_format);
932 im_format->media_type = MEDIA_TYPE_IMAGE;
933
934 /* file type */
935 if (ftype == IMB_FTYPE_IRIS) {
936 im_format->imtype = R_IMF_IMTYPE_IRIS;
937 }
938 else if (ftype == IMB_FTYPE_RADHDR) {
939 im_format->imtype = R_IMF_IMTYPE_RADHDR;
940 }
941 else if (ftype == IMB_FTYPE_PNG) {
942 im_format->imtype = R_IMF_IMTYPE_PNG;
943
944 if (custom_flags & PNG_16BIT) {
945 im_format->depth = R_IMF_CHAN_DEPTH_16;
946 is_depth_set = true;
947 }
948
949 im_format->compress = quality;
950 }
951 else if (ftype == IMB_FTYPE_DDS) {
952 im_format->imtype = R_IMF_IMTYPE_DDS;
953 }
954 else if (ftype == IMB_FTYPE_BMP) {
955 im_format->imtype = R_IMF_IMTYPE_BMP;
956 }
957 else if (ftype == IMB_FTYPE_TIF) {
958 im_format->imtype = R_IMF_IMTYPE_TIFF;
959 if (custom_flags & TIF_16BIT) {
960 im_format->depth = R_IMF_CHAN_DEPTH_16;
961 is_depth_set = true;
962 }
963 if (custom_flags & TIF_COMPRESS_NONE) {
965 }
966 if (custom_flags & TIF_COMPRESS_DEFLATE) {
968 }
969 if (custom_flags & TIF_COMPRESS_LZW) {
970 im_format->tiff_codec = R_IMF_TIFF_CODEC_LZW;
971 }
972 if (custom_flags & TIF_COMPRESS_PACKBITS) {
974 }
975 }
976
977#ifdef WITH_IMAGE_OPENEXR
978 else if (ftype == IMB_FTYPE_OPENEXR) {
979 im_format->imtype = R_IMF_IMTYPE_OPENEXR;
980 char exr_codec = custom_flags & OPENEXR_CODEC_MASK;
981 if (custom_flags & OPENEXR_HALF) {
982 im_format->depth = R_IMF_CHAN_DEPTH_16;
983 is_depth_set = true;
984 }
985 else if (ELEM(exr_codec, R_IMF_EXR_CODEC_B44, R_IMF_EXR_CODEC_B44A)) {
986 /* B44 and B44A are only selectable for half precision images, default to ZIP compression */
987 exr_codec = R_IMF_EXR_CODEC_ZIP;
988 }
989 if (exr_codec < R_IMF_EXR_CODEC_MAX) {
990 im_format->exr_codec = exr_codec;
991 }
992 if (custom_flags & OPENEXR_MULTIPART) {
994 }
995 }
996#endif
997
998#ifdef WITH_IMAGE_CINEON
999 else if (ftype == IMB_FTYPE_CINEON) {
1000 im_format->imtype = R_IMF_IMTYPE_CINEON;
1001 }
1002 else if (ftype == IMB_FTYPE_DPX) {
1003 im_format->imtype = R_IMF_IMTYPE_DPX;
1004 }
1005#endif
1006 else if (ftype == IMB_FTYPE_TGA) {
1007 if (custom_flags & RAWTGA) {
1008 im_format->imtype = R_IMF_IMTYPE_RAWTGA;
1009 }
1010 else {
1011 im_format->imtype = R_IMF_IMTYPE_TARGA;
1012 }
1013 }
1014#ifdef WITH_IMAGE_OPENJPEG
1015 else if (ftype == IMB_FTYPE_JP2) {
1016 im_format->imtype = R_IMF_IMTYPE_JP2;
1017 im_format->quality = quality;
1018
1019 if (custom_flags & JP2_16BIT) {
1020 im_format->depth = R_IMF_CHAN_DEPTH_16;
1021 is_depth_set = true;
1022 }
1023 else if (custom_flags & JP2_12BIT) {
1024 im_format->depth = R_IMF_CHAN_DEPTH_12;
1025 is_depth_set = true;
1026 }
1027
1028 if (custom_flags & JP2_YCC) {
1029 im_format->jp2_flag |= R_IMF_JP2_FLAG_YCC;
1030 }
1031
1032 if (custom_flags & JP2_CINE) {
1034 if (custom_flags & JP2_CINE_48FPS) {
1035 im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
1036 }
1037 }
1038
1039 if (custom_flags & JP2_JP2) {
1040 im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
1041 }
1042 else if (custom_flags & JP2_J2K) {
1043 im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
1044 }
1045 else {
1046 BLI_assert_msg(0, "Unsupported jp2 codec was specified in file type");
1047 }
1048 }
1049#endif
1050#ifdef WITH_IMAGE_WEBP
1051 else if (ftype == IMB_FTYPE_WEBP) {
1052 im_format->imtype = R_IMF_IMTYPE_WEBP;
1053 im_format->quality = quality;
1054 }
1055#endif
1056
1057 else {
1058 im_format->imtype = R_IMF_IMTYPE_JPEG90;
1059 im_format->quality = quality;
1060 }
1061
1062 /* Default depth, accounting for float buffer and format support */
1063 if (!is_depth_set) {
1064 im_format->depth = imtype_best_depth(imbuf, im_format->imtype);
1065 }
1066
1067 /* planes */
1068 im_format->planes = imbuf->planes;
1069}
1070
1072{
1073 return (imf->depth == R_IMF_CHAN_DEPTH_8) && (BKE_imtype_valid_depths(imf->imtype) & imf->depth);
1074}
1075
1076/* Color Management */
1077
1087
1097
1098/* Output */
1099
1101 const Scene *scene_src,
1102 const ImageFormatData *imf_src,
1103 const bool allow_video)
1104{
1105 *imf = (imf_src) ? *imf_src : scene_src->r.im_format;
1106
1107 /* For image saving we can not have use media type video. */
1108 if (!allow_video) {
1109 if (scene_src && imf->media_type == MEDIA_TYPE_VIDEO) {
1110 BKE_image_format_media_type_set(imf, const_cast<ID *>(&scene_src->id), MEDIA_TYPE_IMAGE);
1111 }
1112 }
1113
1114 if (imf_src && imf_src->color_management == R_IMF_COLOR_MANAGEMENT_OVERRIDE) {
1115 /* Use settings specific to one node, image save operation, etc. */
1119 &imf_src->linear_colorspace_settings);
1120 }
1122 /* Use scene settings specific to render output. */
1124 &scene_src->r.im_format.display_settings);
1126 &scene_src->r.im_format.view_settings);
1129 }
1130 else {
1131 /* Use general scene settings also used for display. */
1136 }
1137}
void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings)
void BKE_color_managed_view_settings_blend_read_data(BlendDataReader *reader, ColorManagedViewSettings *settings)
void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_settings, const ColorManagedDisplaySettings *settings)
void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings)
void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings)
void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings, const ColorManagedViewSettings *settings)
void BKE_color_managed_view_settings_init(ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const char *view_transform)
void BKE_color_managed_view_settings_blend_write(BlendWriter *writer, const ColorManagedViewSettings *settings)
void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings, const ColorManagedColorspaceSettings *settings)
#define IMA_CHAN_FLAG_RGB
#define IMA_CHAN_FLAG_RGBA
#define IMA_CHAN_FLAG_BW
#define BKE_IMAGE_PATH_EXT_MAX
Functions and classes for evaluating template expressions in filepaths.
blender::Vector< blender::bke::path_templates::Error > BKE_path_apply_template(char *path, int path_maxncpy, const blender::bke::path_templates::VariableMap &template_variables)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
bool BLI_path_abs(char path[FILE_MAX], const char *basepath) ATTR_NONNULL(1
bool bool BLI_path_suffix(char *path, size_t path_maxncpy, const char *suffix, const char *sep) ATTR_NONNULL(1
bool BLI_path_extension_check_array(const char *path, const char **ext_array) ATTR_NONNULL(1
#define FILE_MAX
bool BLI_path_extension_replace(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
bool BLI_path_extension_ensure(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
bool BLI_path_frame(char *path, size_t path_maxncpy, int frame, int digits) ATTR_NONNULL(1)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define UNUSED_VARS(...)
#define ELEM(...)
#define STREQ(a, b)
@ ID_SCE
#define DNA_struct_default_get(struct_name)
@ R_IMF_EXR_CODEC_B44
@ R_IMF_EXR_CODEC_MAX
@ R_IMF_EXR_CODEC_B44A
@ R_IMF_EXR_CODEC_ZIP
MediaType
@ MEDIA_TYPE_MULTI_LAYER_IMAGE
@ MEDIA_TYPE_VIDEO
@ MEDIA_TYPE_IMAGE
@ R_IMF_JP2_FLAG_CINE_48
@ R_IMF_JP2_FLAG_CINE_PRESET
@ R_IMF_JP2_FLAG_YCC
@ R_IMF_PLANES_RGB
@ R_IMF_PLANES_RGBA
@ R_IMF_PLANES_BW
@ R_IMF_TIFF_CODEC_PACKBITS
@ R_IMF_TIFF_CODEC_DEFLATE
@ R_IMF_TIFF_CODEC_NONE
@ R_IMF_TIFF_CODEC_LZW
@ R_IMF_CHAN_DEPTH_24
@ R_IMF_CHAN_DEPTH_8
@ R_IMF_CHAN_DEPTH_16
@ R_IMF_CHAN_DEPTH_12
@ R_IMF_CHAN_DEPTH_1
@ R_IMF_CHAN_DEPTH_10
@ R_IMF_CHAN_DEPTH_32
@ R_IMF_JP2_CODEC_JP2
@ R_IMF_JP2_CODEC_J2K
@ R_IMF_VIEWS_MULTIVIEW
@ R_IMF_VIEWS_STEREO_3D
@ R_IMF_VIEWS_INDIVIDUAL
@ R_IMF_COLOR_MANAGEMENT_OVERRIDE
@ R_IMF_CINEON_FLAG_LOG
@ R_IMF_EXR_FLAG_MULTIPART
@ R_IMF_IMTYPE_DDS
@ R_IMF_IMTYPE_INVALID
@ R_IMF_IMTYPE_IRIS
@ R_IMF_IMTYPE_FFMPEG
@ R_IMF_IMTYPE_WEBP
@ R_IMF_IMTYPE_BMP
@ R_IMF_IMTYPE_JPEG90
@ R_IMF_IMTYPE_TIFF
@ R_IMF_IMTYPE_IRIZ
@ R_IMF_IMTYPE_RADHDR
@ R_IMF_IMTYPE_PSD
@ R_IMF_IMTYPE_TARGA
@ R_IMF_IMTYPE_DPX
@ R_IMF_IMTYPE_JP2
@ R_IMF_IMTYPE_OPENEXR
@ R_IMF_IMTYPE_MULTILAYER
@ R_IMF_IMTYPE_PNG
@ R_IMF_IMTYPE_CINEON
@ R_IMF_IMTYPE_RAWTGA
bool IMB_colormanagement_space_name_is_scene_linear(const char *name)
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_DEFAULT_BYTE
@ COLOR_ROLE_SCENE_LINEAR
bool IMB_colormanagement_space_name_is_data(const char *name)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
@ IMB_FTYPE_BMP
@ IMB_FTYPE_JPG
@ IMB_FTYPE_TGA
@ IMB_FTYPE_RADHDR
@ IMB_FTYPE_IRIS
@ IMB_FTYPE_TIF
@ IMB_FTYPE_DDS
@ IMB_FTYPE_OPENEXR
@ IMB_FTYPE_NONE
@ IMB_FTYPE_PNG
#define TIF_COMPRESS_PACKBITS
#define TIF_COMPRESS_NONE
#define TIF_COMPRESS_DEFLATE
#define RAWTGA
#define TIF_COMPRESS_LZW
#define PNG_16BIT
#define OPENEXR_CODEC_MASK
#define OPENEXR_MULTIPART
#define TIF_16BIT
const char * imb_ext_image[]
bool is_empty() const
CCL_NAMESPACE_BEGIN struct Options options
#define GS(x)
#define OPENEXR_HALF
void BKE_image_format_free(ImageFormatData *imf)
bool BKE_imtype_supports_compress(const char imtype)
blender::Vector< path_templates::Error > BKE_image_path_from_imformat(char *filepath, const char *base, const char *relbase, const path_templates::VariableMap *template_variables, int frame, const ImageFormatData *im_format, const bool use_ext, const bool use_frames, const char *suffix)
blender::Vector< path_templates::Error > BKE_image_path_from_imtype(char *filepath, const char *base, const char *relbase, const path_templates::VariableMap *template_variables, int frame, const char imtype, const bool use_ext, const bool use_frames, const char *suffix)
static blender::Vector< path_templates::Error > do_makepicstring(char filepath[FILE_MAX], const char *base, const char *relbase, const path_templates::VariableMap *template_variables, int frame, const char imtype, const ImageFormatData *im_format, const bool use_ext, const bool use_frames, const char *suffix)
bool BKE_imtype_requires_linear_float(const char imtype)
static int image_path_ext_from_imformat_impl(const char imtype, const ImageFormatData *im_format, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
void BKE_image_format_color_management_copy(ImageFormatData *imf, const ImageFormatData *imf_src)
char BKE_imtype_valid_depths(const char imtype)
void BKE_image_format_from_imbuf(ImageFormatData *im_format, const ImBuf *imbuf)
bool BKE_imtype_is_image(const char imtype)
int BKE_image_path_ext_from_imformat(const ImageFormatData *im_format, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
void BKE_image_format_blend_write(BlendWriter *writer, ImageFormatData *imf)
void BKE_image_format_blend_read_data(BlendDataReader *reader, ImageFormatData *imf)
char BKE_imtype_from_arg(const char *imtype_arg)
void BKE_image_format_init_for_write(ImageFormatData *imf, const Scene *scene_src, const ImageFormatData *imf_src, const bool allow_video)
void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype)
char BKE_imtype_first_valid_depth(const char valid_depths)
char BKE_imtype_valid_channels(const char imtype)
void BKE_image_format_update_color_space_for_type(ImageFormatData *format)
int BKE_image_path_ext_from_imtype(const char imtype, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
bool BKE_imtype_is_movie(const char imtype)
void BKE_image_format_media_type_set(ImageFormatData *format, ID *owner_id, const MediaType media_type)
bool BKE_imtype_supports_quality(const char imtype)
void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
bool BKE_imtype_is_multi_layer_image(const char imtype)
int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
int BKE_image_path_ext_from_imtype_ensure(char *filepath, const size_t filepath_maxncpy, const char imtype)
void BKE_image_format_color_management_copy_from_scene(ImageFormatData *imf, const Scene *scene)
bool BKE_image_format_is_byte(const ImageFormatData *imf)
static char imtype_best_depth(const ImBuf *ibuf, const char imtype)
void BKE_image_format_init(ImageFormatData *imf)
int BKE_image_path_ext_from_imformat_ensure(char *filepath, const size_t filepath_maxncpy, const ImageFormatData *im_format)
void BKE_image_format_copy(ImageFormatData *imf_dst, const ImageFormatData *imf_src)
static bool do_ensure_image_extension(char *filepath, const size_t filepath_maxncpy, const char imtype, const ImageFormatData *im_format)
char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
char BKE_imtype_valid_depths_with_video(char imtype, const ID *owner_id)
format
int MOV_codec_valid_bit_depths(IMB_Ffmpeg_Codec_ID codec_id)
void MOV_validate_output_settings(RenderData *rd, const ImageFormatData *imf)
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
ImBufFloatBuffer float_buffer
ImbFormatOptions foptions
unsigned char planes
enum eImbFileType ftype
ColorManagedColorspaceSettings linear_colorspace_settings
ColorManagedDisplaySettings display_settings
ColorManagedViewSettings view_settings
struct ImageFormatData im_format
struct FFMpegCodecData ffcodecdata
ColorManagedViewSettings view_settings
struct RenderData r
ColorManagedDisplaySettings display_settings
i
Definition text_draw.cc:230