Blender V4.5
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.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
47
56
61
63{
64 /* If the color space is set to a data space, this is probably the user's intention, so leave it
65 * as is. */
66 if (IMB_colormanagement_space_name_is_data(format->linear_colorspace_settings.name)) {
67 return;
68 }
69
70 const bool image_requires_linear = BKE_imtype_requires_linear_float(format->imtype);
72 format->linear_colorspace_settings.name);
73
74 /* The color space is either not set or is linear but the image requires non-linear or vice
75 * versa. So set to the default for the image type. */
76 if (format->linear_colorspace_settings.name[0] == '\0' || image_requires_linear != is_linear) {
77 const int role = image_requires_linear ? COLOR_ROLE_DEFAULT_FLOAT : COLOR_ROLE_DEFAULT_BYTE;
78 const char *default_color_space = IMB_colormanagement_role_colorspace_name_get(role);
79 STRNCPY(format->linear_colorspace_settings.name, default_color_space);
80 }
81}
82
87
92
93void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype)
94{
95 imf->imtype = imtype;
96
97 const bool is_render = (owner_id && GS(owner_id->name) == ID_SCE);
98 /* see note below on why this is */
99 const char chan_flag = BKE_imtype_valid_channels(imf->imtype) |
100 (is_render ? IMA_CHAN_FLAG_BW : 0);
101
102 /* ensure depth and color settings match */
103 if ((imf->planes == R_IMF_PLANES_BW) && !(chan_flag & IMA_CHAN_FLAG_BW)) {
105 }
106 if ((imf->planes == R_IMF_PLANES_RGBA) && !(chan_flag & IMA_CHAN_FLAG_RGBA)) {
108 }
109
110 /* ensure usable depth */
111 {
112 const int depth_ok = BKE_imtype_valid_depths(imf->imtype);
113 if ((imf->depth & depth_ok) == 0) {
114 imf->depth = BKE_imtype_first_valid_depth(depth_ok);
115 }
116 }
117
118 if (owner_id && GS(owner_id->name) == ID_SCE) {
119 Scene *scene = reinterpret_cast<Scene *>(owner_id);
120 RenderData *rd = &scene->r;
122 }
123
125}
126
127/* File Types */
128
129int BKE_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options)
130{
131 memset(r_options, 0, sizeof(*r_options));
132
133 if (imtype == R_IMF_IMTYPE_TARGA) {
134 return IMB_FTYPE_TGA;
135 }
136 if (imtype == R_IMF_IMTYPE_RAWTGA) {
137 r_options->flag = RAWTGA;
138 return IMB_FTYPE_TGA;
139 }
140 if (imtype == R_IMF_IMTYPE_IRIS) {
141 return IMB_FTYPE_IRIS;
142 }
143 if (imtype == R_IMF_IMTYPE_RADHDR) {
144 return IMB_FTYPE_RADHDR;
145 }
146 if (imtype == R_IMF_IMTYPE_PNG) {
147 r_options->quality = 15;
148 return IMB_FTYPE_PNG;
149 }
150 if (imtype == R_IMF_IMTYPE_DDS) {
151 return IMB_FTYPE_DDS;
152 }
153 if (imtype == R_IMF_IMTYPE_BMP) {
154 return IMB_FTYPE_BMP;
155 }
156 if (imtype == R_IMF_IMTYPE_TIFF) {
157 return IMB_FTYPE_TIF;
158 }
160 r_options->quality = 90;
161 return IMB_FTYPE_OPENEXR;
162 }
163#ifdef WITH_IMAGE_CINEON
164 if (imtype == R_IMF_IMTYPE_CINEON) {
165 return IMB_FTYPE_CINEON;
166 }
167 if (imtype == R_IMF_IMTYPE_DPX) {
168 return IMB_FTYPE_DPX;
169 }
170#endif
171#ifdef WITH_IMAGE_OPENJPEG
172 if (imtype == R_IMF_IMTYPE_JP2) {
173 r_options->flag |= JP2_JP2;
174 r_options->quality = 90;
175 return IMB_FTYPE_JP2;
176 }
177#endif
178#ifdef WITH_IMAGE_WEBP
179 if (imtype == R_IMF_IMTYPE_WEBP) {
180 r_options->quality = 90;
181 return IMB_FTYPE_WEBP;
182 }
183#endif
184
185 r_options->quality = 90;
186 return IMB_FTYPE_JPG;
187}
188
189char BKE_ftype_to_imtype(const int ftype, const ImbFormatOptions *options)
190{
191 if (ftype == IMB_FTYPE_NONE) {
192 return R_IMF_IMTYPE_TARGA;
193 }
194 if (ftype == IMB_FTYPE_IRIS) {
195 return R_IMF_IMTYPE_IRIS;
196 }
197 if (ftype == IMB_FTYPE_RADHDR) {
198 return R_IMF_IMTYPE_RADHDR;
199 }
200 if (ftype == IMB_FTYPE_PNG) {
201 return R_IMF_IMTYPE_PNG;
202 }
203 if (ftype == IMB_FTYPE_DDS) {
204 return R_IMF_IMTYPE_DDS;
205 }
206 if (ftype == IMB_FTYPE_BMP) {
207 return R_IMF_IMTYPE_BMP;
208 }
209 if (ftype == IMB_FTYPE_TIF) {
210 return R_IMF_IMTYPE_TIFF;
211 }
212 if (ftype == IMB_FTYPE_OPENEXR) {
214 }
215#ifdef WITH_IMAGE_CINEON
216 if (ftype == IMB_FTYPE_CINEON) {
217 return R_IMF_IMTYPE_CINEON;
218 }
219 if (ftype == IMB_FTYPE_DPX) {
220 return R_IMF_IMTYPE_DPX;
221 }
222#endif
223 if (ftype == IMB_FTYPE_TGA) {
224 if (options && (options->flag & RAWTGA)) {
225 return R_IMF_IMTYPE_RAWTGA;
226 }
227
228 return R_IMF_IMTYPE_TARGA;
229 }
230#ifdef WITH_IMAGE_OPENJPEG
231 if (ftype == IMB_FTYPE_JP2) {
232 return R_IMF_IMTYPE_JP2;
233 }
234#endif
235#ifdef WITH_IMAGE_WEBP
236 if (ftype == IMB_FTYPE_WEBP) {
237 return R_IMF_IMTYPE_WEBP;
238 }
239#endif
240
241 return R_IMF_IMTYPE_JPEG90;
242}
243
244bool BKE_imtype_is_movie(const char imtype)
245{
246 switch (imtype) {
253 case R_IMF_IMTYPE_AV1:
254 return true;
255 }
256 return false;
257}
258
259bool BKE_imtype_supports_compress(const char imtype)
260{
261 switch (imtype) {
262 case R_IMF_IMTYPE_PNG:
263 return true;
264 }
265 return false;
266}
267
268bool BKE_imtype_supports_quality(const char imtype)
269{
270 switch (imtype) {
272 case R_IMF_IMTYPE_JP2:
275 return true;
276 }
277 return false;
278}
279
280bool BKE_imtype_requires_linear_float(const char imtype)
281{
282 switch (imtype) {
284 case R_IMF_IMTYPE_DPX:
288 return true;
289 }
290 return false;
291}
292
293char BKE_imtype_valid_channels(const char imtype)
294{
295 char chan_flag = IMA_CHAN_FLAG_RGB; /* Assume all support RGB. */
296
297 /* Alpha. */
298 switch (imtype) {
299 case R_IMF_IMTYPE_BMP:
303 case R_IMF_IMTYPE_PNG:
307 case R_IMF_IMTYPE_DDS:
308 case R_IMF_IMTYPE_JP2:
309 case R_IMF_IMTYPE_DPX:
311 chan_flag |= IMA_CHAN_FLAG_RGBA;
312 break;
313 }
314
315 /* BW. */
316 switch (imtype) {
317 case R_IMF_IMTYPE_BMP:
318 case R_IMF_IMTYPE_PNG:
325 chan_flag |= IMA_CHAN_FLAG_BW;
326 break;
327 }
328
329 return chan_flag;
330}
331
332char BKE_imtype_valid_depths(const char imtype)
333{
334 switch (imtype) {
336 return R_IMF_CHAN_DEPTH_32;
343 /* NOTE: CINEON uses an unusual 10bits-LOG per channel. */
344 case R_IMF_IMTYPE_DPX:
347 return R_IMF_CHAN_DEPTH_10;
348 case R_IMF_IMTYPE_JP2:
350 case R_IMF_IMTYPE_PNG:
352 /* Most formats are 8bit only. */
353 default:
354 return R_IMF_CHAN_DEPTH_8;
355 }
356}
357
358char BKE_imtype_valid_depths_with_video(char imtype, const ID *owner_id)
359{
360 UNUSED_VARS(owner_id); /* Might be unused depending on build options. */
361
362 int depths = BKE_imtype_valid_depths(imtype);
363 /* Depending on video codec selected, valid color bit depths might vary. */
364 if (imtype == R_IMF_IMTYPE_FFMPEG) {
365 const bool is_render_out = (owner_id && GS(owner_id->name) == ID_SCE);
366 if (is_render_out) {
367 const Scene *scene = (const Scene *)owner_id;
368 depths |= MOV_codec_valid_bit_depths(scene->r.ffcodecdata.codec_id_get());
369 }
370 }
371 return depths;
372}
373
374char BKE_imtype_first_valid_depth(const char valid_depths)
375{
376 /* set first available depth */
377 const char depth_ls[] = {
385 0,
386 };
387 for (int i = 0; depth_ls[i]; i++) {
388 if (valid_depths & depth_ls[i]) {
389 return depth_ls[i];
390 }
391 }
392 return R_IMF_CHAN_DEPTH_8;
393}
394
395char BKE_imtype_from_arg(const char *imtype_arg)
396{
397 if (STREQ(imtype_arg, "TGA")) {
398 return R_IMF_IMTYPE_TARGA;
399 }
400 if (STREQ(imtype_arg, "IRIS")) {
401 return R_IMF_IMTYPE_IRIS;
402 }
403 if (STREQ(imtype_arg, "JPEG")) {
404 return R_IMF_IMTYPE_JPEG90;
405 }
406 if (STREQ(imtype_arg, "RAWTGA")) {
407 return R_IMF_IMTYPE_RAWTGA;
408 }
409 if (STREQ(imtype_arg, "AVIRAW")) {
410 return R_IMF_IMTYPE_AVIRAW;
411 }
412 if (STREQ(imtype_arg, "AVIJPEG")) {
414 }
415 if (STREQ(imtype_arg, "PNG")) {
416 return R_IMF_IMTYPE_PNG;
417 }
418 if (STREQ(imtype_arg, "BMP")) {
419 return R_IMF_IMTYPE_BMP;
420 }
421 if (STREQ(imtype_arg, "HDR")) {
422 return R_IMF_IMTYPE_RADHDR;
423 }
424 if (STREQ(imtype_arg, "TIFF")) {
425 return R_IMF_IMTYPE_TIFF;
426 }
427#ifdef WITH_IMAGE_OPENEXR
428 if (STREQ(imtype_arg, "OPEN_EXR")) {
430 }
431 if (STREQ(imtype_arg, "OPEN_EXR_MULTILAYER")) {
433 }
434 if (STREQ(imtype_arg, "EXR")) {
436 }
437 if (STREQ(imtype_arg, "MULTILAYER")) {
439 }
440#endif
441#ifdef WITH_FFMPEG
442 if (STREQ(imtype_arg, "FFMPEG")) {
443 return R_IMF_IMTYPE_FFMPEG;
444 }
445#endif
446#ifdef WITH_IMAGE_CINEON
447 if (STREQ(imtype_arg, "CINEON")) {
448 return R_IMF_IMTYPE_CINEON;
449 }
450 if (STREQ(imtype_arg, "DPX")) {
451 return R_IMF_IMTYPE_DPX;
452 }
453#endif
454#ifdef WITH_IMAGE_OPENJPEG
455 if (STREQ(imtype_arg, "JP2")) {
456 return R_IMF_IMTYPE_JP2;
457 }
458#endif
459#ifdef WITH_IMAGE_WEBP
460 if (STREQ(imtype_arg, "WEBP")) {
461 return R_IMF_IMTYPE_WEBP;
462 }
463#endif
464
466}
467
468/* File Paths */
469
470static int image_path_ext_from_imformat_impl(const char imtype,
471 const ImageFormatData *im_format,
472 const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
473{
474 int ext_num = 0;
475 (void)im_format; /* may be unused, depends on build options */
476
477 if (imtype == R_IMF_IMTYPE_IRIS) {
478 r_ext[ext_num++] = ".rgb";
479 }
480 else if (imtype == R_IMF_IMTYPE_IRIZ) {
481 r_ext[ext_num++] = ".rgb";
482 }
483 else if (imtype == R_IMF_IMTYPE_RADHDR) {
484 r_ext[ext_num++] = ".hdr";
485 }
486 else if (ELEM(imtype,
493 {
494 r_ext[ext_num++] = ".png";
495 }
496 else if (imtype == R_IMF_IMTYPE_DDS) {
497 r_ext[ext_num++] = ".dds";
498 }
499 else if (ELEM(imtype, R_IMF_IMTYPE_TARGA, R_IMF_IMTYPE_RAWTGA)) {
500 r_ext[ext_num++] = ".tga";
501 }
502 else if (imtype == R_IMF_IMTYPE_BMP) {
503 r_ext[ext_num++] = ".bmp";
504 }
505 else if (imtype == R_IMF_IMTYPE_TIFF) {
506 r_ext[ext_num++] = ".tif";
507 r_ext[ext_num++] = ".tiff";
508 }
509 else if (imtype == R_IMF_IMTYPE_PSD) {
510 r_ext[ext_num++] = ".psd";
511 }
512#ifdef WITH_IMAGE_OPENEXR
514 r_ext[ext_num++] = ".exr";
515 }
516#endif
517#ifdef WITH_IMAGE_CINEON
518 else if (imtype == R_IMF_IMTYPE_CINEON) {
519 r_ext[ext_num++] = ".cin";
520 }
521 else if (imtype == R_IMF_IMTYPE_DPX) {
522 r_ext[ext_num++] = ".dpx";
523 }
524#endif
525#ifdef WITH_IMAGE_OPENJPEG
526 else if (imtype == R_IMF_IMTYPE_JP2) {
527 if (im_format) {
528 if (im_format->jp2_codec == R_IMF_JP2_CODEC_JP2) {
529 r_ext[ext_num++] = ".jp2";
530 }
531 else if (im_format->jp2_codec == R_IMF_JP2_CODEC_J2K) {
532 r_ext[ext_num++] = ".j2c";
533 }
534 else {
535 BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
536 }
537 }
538 else {
539 r_ext[ext_num++] = ".jp2";
540 }
541 }
542#endif
543#ifdef WITH_IMAGE_WEBP
544 else if (imtype == R_IMF_IMTYPE_WEBP) {
545 r_ext[ext_num++] = ".webp";
546 }
547#endif
548 else {
549 /* Handles: #R_IMF_IMTYPE_AVIRAW, #R_IMF_IMTYPE_AVIJPEG, #R_IMF_IMTYPE_JPEG90 etc. */
550 r_ext[ext_num++] = ".jpg";
551 r_ext[ext_num++] = ".jpeg";
552 }
554 r_ext[ext_num] = nullptr;
555 return ext_num;
556}
557
559 const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
560{
561 return image_path_ext_from_imformat_impl(im_format->imtype, im_format, r_ext);
562}
563
564int BKE_image_path_ext_from_imtype(const char imtype, const char *r_ext[BKE_IMAGE_PATH_EXT_MAX])
565{
566 return image_path_ext_from_imformat_impl(imtype, nullptr, r_ext);
567}
568
569static bool do_ensure_image_extension(char *filepath,
570 const size_t filepath_maxncpy,
571 const char imtype,
572 const ImageFormatData *im_format)
573{
574 const char *ext_array[BKE_IMAGE_PATH_EXT_MAX];
575 int ext_array_num = image_path_ext_from_imformat_impl(imtype, im_format, ext_array);
576 if (ext_array_num && !BLI_path_extension_check_array(filepath, ext_array)) {
577 /* Removing *any* extension may remove part of the user defined name (if they include '.')
578 * however in the case there is already a known image extension,
579 * remove it to avoid`.png.tga`, for example. */
581 return BLI_path_extension_replace(filepath, filepath_maxncpy, ext_array[0]);
582 }
583 return BLI_path_extension_ensure(filepath, filepath_maxncpy, ext_array[0]);
584 }
585
586 return false;
587}
588
590 const size_t filepath_maxncpy,
591 const ImageFormatData *im_format)
592{
593 return do_ensure_image_extension(filepath, filepath_maxncpy, im_format->imtype, im_format);
594}
595
597 const size_t filepath_maxncpy,
598 const char imtype)
599{
600 return do_ensure_image_extension(filepath, filepath_maxncpy, imtype, nullptr);
601}
602
604 char filepath[FILE_MAX],
605 const char *base,
606 const char *relbase,
607 const path_templates::VariableMap *template_variables,
608 int frame,
609 const char imtype,
610 const ImageFormatData *im_format,
611 const bool use_ext,
612 const bool use_frames,
613 const char *suffix)
614{
615 if (filepath == nullptr) {
616 return {};
617 }
618 BLI_strncpy(filepath, base, FILE_MAX - 10); /* weak assumption */
619
620 if (template_variables) {
622 filepath, FILE_MAX, *template_variables);
623 if (!variable_errors.is_empty()) {
624 return variable_errors;
625 }
626 }
627
628 BLI_path_abs(filepath, relbase);
629
630 if (use_frames) {
631 BLI_path_frame(filepath, FILE_MAX, frame, 4);
632 }
633
634 if (suffix) {
635 BLI_path_suffix(filepath, FILE_MAX, suffix, "");
636 }
637
638 if (use_ext) {
639 do_ensure_image_extension(filepath, FILE_MAX, imtype, im_format);
640 }
641
642 return {};
643}
644
646 char *filepath,
647 const char *base,
648 const char *relbase,
649 const path_templates::VariableMap *template_variables,
650 int frame,
651 const ImageFormatData *im_format,
652 const bool use_ext,
653 const bool use_frames,
654 const char *suffix)
655{
656 return do_makepicstring(filepath,
657 base,
658 relbase,
659 template_variables,
660 frame,
661 im_format->imtype,
662 im_format,
663 use_ext,
664 use_frames,
665 suffix);
666}
667
669 char *filepath,
670 const char *base,
671 const char *relbase,
672 const path_templates::VariableMap *template_variables,
673 int frame,
674 const char imtype,
675 const bool use_ext,
676 const bool use_frames,
677 const char *suffix)
678{
679 return do_makepicstring(filepath,
680 base,
681 relbase,
682 template_variables,
683 frame,
684 imtype,
685 nullptr,
686 use_ext,
687 use_frames,
688 suffix);
689}
690
691/* ImBuf Conversion */
692
694{
695 /* Write to ImBuf in preparation for file writing. */
696 char imtype = imf->imtype;
697 char compress = imf->compress;
698 char quality = imf->quality;
699
700 /* initialize all from image format */
701 ibuf->foptions.flag = 0;
702
703 if (imtype == R_IMF_IMTYPE_IRIS) {
704 ibuf->ftype = IMB_FTYPE_IRIS;
705 }
706 else if (imtype == R_IMF_IMTYPE_RADHDR) {
707 ibuf->ftype = IMB_FTYPE_RADHDR;
708 }
709 else if (ELEM(imtype,
716 {
717 ibuf->ftype = IMB_FTYPE_PNG;
718
719 if (imtype == R_IMF_IMTYPE_PNG) {
720 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
721 ibuf->foptions.flag |= PNG_16BIT;
722 }
723
724 ibuf->foptions.quality = compress;
725 }
726 }
727 else if (imtype == R_IMF_IMTYPE_DDS) {
728 ibuf->ftype = IMB_FTYPE_DDS;
729 }
730 else if (imtype == R_IMF_IMTYPE_BMP) {
731 ibuf->ftype = IMB_FTYPE_BMP;
732 }
733 else if (imtype == R_IMF_IMTYPE_TIFF) {
734 ibuf->ftype = IMB_FTYPE_TIF;
735
736 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
737 ibuf->foptions.flag |= TIF_16BIT;
738 }
739 if (imf->tiff_codec == R_IMF_TIFF_CODEC_NONE) {
741 }
742 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_DEFLATE) {
744 }
745 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_LZW) {
747 }
748 else if (imf->tiff_codec == R_IMF_TIFF_CODEC_PACKBITS) {
750 }
751 }
752#ifdef WITH_IMAGE_OPENEXR
754 ibuf->ftype = IMB_FTYPE_OPENEXR;
755 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
756 ibuf->foptions.flag |= OPENEXR_HALF;
757 }
758 ibuf->foptions.flag |= (imf->exr_codec & OPENEXR_CODEC_MASK);
759 ibuf->foptions.quality = quality;
760 }
761#endif
762#ifdef WITH_IMAGE_CINEON
763 else if (imtype == R_IMF_IMTYPE_CINEON) {
764 ibuf->ftype = IMB_FTYPE_CINEON;
766 ibuf->foptions.flag |= CINEON_LOG;
767 }
768 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
769 ibuf->foptions.flag |= CINEON_16BIT;
770 }
771 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
772 ibuf->foptions.flag |= CINEON_12BIT;
773 }
774 else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
775 ibuf->foptions.flag |= CINEON_10BIT;
776 }
777 }
778 else if (imtype == R_IMF_IMTYPE_DPX) {
779 ibuf->ftype = IMB_FTYPE_DPX;
781 ibuf->foptions.flag |= CINEON_LOG;
782 }
783 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
784 ibuf->foptions.flag |= CINEON_16BIT;
785 }
786 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
787 ibuf->foptions.flag |= CINEON_12BIT;
788 }
789 else if (imf->depth == R_IMF_CHAN_DEPTH_10) {
790 ibuf->foptions.flag |= CINEON_10BIT;
791 }
792 }
793#endif
794 else if (imtype == R_IMF_IMTYPE_TARGA) {
795 ibuf->ftype = IMB_FTYPE_TGA;
796 }
797 else if (imtype == R_IMF_IMTYPE_RAWTGA) {
798 ibuf->ftype = IMB_FTYPE_TGA;
799 ibuf->foptions.flag = RAWTGA;
800 }
801#ifdef WITH_IMAGE_OPENJPEG
802 else if (imtype == R_IMF_IMTYPE_JP2) {
803 if (quality < 10) {
804 quality = 90;
805 }
806 ibuf->ftype = IMB_FTYPE_JP2;
807 ibuf->foptions.quality = quality;
808
809 if (imf->depth == R_IMF_CHAN_DEPTH_16) {
810 ibuf->foptions.flag |= JP2_16BIT;
811 }
812 else if (imf->depth == R_IMF_CHAN_DEPTH_12) {
813 ibuf->foptions.flag |= JP2_12BIT;
814 }
815
816 if (imf->jp2_flag & R_IMF_JP2_FLAG_YCC) {
817 ibuf->foptions.flag |= JP2_YCC;
818 }
819
821 ibuf->foptions.flag |= JP2_CINE;
822 if (imf->jp2_flag & R_IMF_JP2_FLAG_CINE_48) {
823 ibuf->foptions.flag |= JP2_CINE_48FPS;
824 }
825 }
826
827 if (imf->jp2_codec == R_IMF_JP2_CODEC_JP2) {
828 ibuf->foptions.flag |= JP2_JP2;
829 }
830 else if (imf->jp2_codec == R_IMF_JP2_CODEC_J2K) {
831 ibuf->foptions.flag |= JP2_J2K;
832 }
833 else {
834 BLI_assert_msg(0, "Unsupported jp2 codec was specified in im_format->jp2_codec");
835 }
836 }
837#endif
838#ifdef WITH_IMAGE_WEBP
839 else if (imtype == R_IMF_IMTYPE_WEBP) {
840 ibuf->ftype = IMB_FTYPE_WEBP;
841 ibuf->foptions.quality = quality;
842 }
843#endif
844 else {
845 /* #R_IMF_IMTYPE_JPEG90, etc. default to JPEG. */
846 if (quality < 10) {
847 quality = 90;
848 }
849 ibuf->ftype = IMB_FTYPE_JPG;
850 ibuf->foptions.quality = quality;
851 }
852}
853
854static char imtype_best_depth(const ImBuf *ibuf, const char imtype)
855{
856 const char depth_ok = BKE_imtype_valid_depths(imtype);
857
858 if (ibuf->float_buffer.data) {
859 if (depth_ok & R_IMF_CHAN_DEPTH_32) {
860 return R_IMF_CHAN_DEPTH_32;
861 }
862 if (depth_ok & R_IMF_CHAN_DEPTH_24) {
863 return R_IMF_CHAN_DEPTH_24;
864 }
865 if (depth_ok & R_IMF_CHAN_DEPTH_16) {
866 return R_IMF_CHAN_DEPTH_16;
867 }
868 if (depth_ok & R_IMF_CHAN_DEPTH_12) {
869 return R_IMF_CHAN_DEPTH_12;
870 }
871 return R_IMF_CHAN_DEPTH_8;
872 }
873
874 if (depth_ok & R_IMF_CHAN_DEPTH_8) {
875 return R_IMF_CHAN_DEPTH_8;
876 }
877 if (depth_ok & R_IMF_CHAN_DEPTH_12) {
878 return R_IMF_CHAN_DEPTH_12;
879 }
880 if (depth_ok & R_IMF_CHAN_DEPTH_16) {
881 return R_IMF_CHAN_DEPTH_16;
882 }
883 if (depth_ok & R_IMF_CHAN_DEPTH_24) {
884 return R_IMF_CHAN_DEPTH_24;
885 }
886 if (depth_ok & R_IMF_CHAN_DEPTH_32) {
887 return R_IMF_CHAN_DEPTH_32;
888 }
889 return R_IMF_CHAN_DEPTH_8; /* fallback, should not get here */
890}
891
893{
894 /* Read from ImBuf after file read. */
895 int ftype = imbuf->ftype;
896 int custom_flags = imbuf->foptions.flag;
897 char quality = imbuf->foptions.quality;
898 bool is_depth_set = false;
899
900 BKE_image_format_init(im_format, false);
901
902 /* file type */
903 if (ftype == IMB_FTYPE_IRIS) {
904 im_format->imtype = R_IMF_IMTYPE_IRIS;
905 }
906 else if (ftype == IMB_FTYPE_RADHDR) {
907 im_format->imtype = R_IMF_IMTYPE_RADHDR;
908 }
909 else if (ftype == IMB_FTYPE_PNG) {
910 im_format->imtype = R_IMF_IMTYPE_PNG;
911
912 if (custom_flags & PNG_16BIT) {
913 im_format->depth = R_IMF_CHAN_DEPTH_16;
914 is_depth_set = true;
915 }
916
917 im_format->compress = quality;
918 }
919 else if (ftype == IMB_FTYPE_DDS) {
920 im_format->imtype = R_IMF_IMTYPE_DDS;
921 }
922 else if (ftype == IMB_FTYPE_BMP) {
923 im_format->imtype = R_IMF_IMTYPE_BMP;
924 }
925 else if (ftype == IMB_FTYPE_TIF) {
926 im_format->imtype = R_IMF_IMTYPE_TIFF;
927 if (custom_flags & TIF_16BIT) {
928 im_format->depth = R_IMF_CHAN_DEPTH_16;
929 is_depth_set = true;
930 }
931 if (custom_flags & TIF_COMPRESS_NONE) {
933 }
934 if (custom_flags & TIF_COMPRESS_DEFLATE) {
936 }
937 if (custom_flags & TIF_COMPRESS_LZW) {
938 im_format->tiff_codec = R_IMF_TIFF_CODEC_LZW;
939 }
940 if (custom_flags & TIF_COMPRESS_PACKBITS) {
942 }
943 }
944
945#ifdef WITH_IMAGE_OPENEXR
946 else if (ftype == IMB_FTYPE_OPENEXR) {
947 im_format->imtype = R_IMF_IMTYPE_OPENEXR;
948 char exr_codec = custom_flags & OPENEXR_CODEC_MASK;
949 if (custom_flags & OPENEXR_HALF) {
950 im_format->depth = R_IMF_CHAN_DEPTH_16;
951 is_depth_set = true;
952 }
953 else if (ELEM(exr_codec, R_IMF_EXR_CODEC_B44, R_IMF_EXR_CODEC_B44A)) {
954 /* B44 and B44A are only selectable for half precision images, default to ZIP compression */
955 exr_codec = R_IMF_EXR_CODEC_ZIP;
956 }
957 if (exr_codec < R_IMF_EXR_CODEC_MAX) {
958 im_format->exr_codec = exr_codec;
959 }
960 }
961#endif
962
963#ifdef WITH_IMAGE_CINEON
964 else if (ftype == IMB_FTYPE_CINEON) {
965 im_format->imtype = R_IMF_IMTYPE_CINEON;
966 }
967 else if (ftype == IMB_FTYPE_DPX) {
968 im_format->imtype = R_IMF_IMTYPE_DPX;
969 }
970#endif
971 else if (ftype == IMB_FTYPE_TGA) {
972 if (custom_flags & RAWTGA) {
973 im_format->imtype = R_IMF_IMTYPE_RAWTGA;
974 }
975 else {
976 im_format->imtype = R_IMF_IMTYPE_TARGA;
977 }
978 }
979#ifdef WITH_IMAGE_OPENJPEG
980 else if (ftype == IMB_FTYPE_JP2) {
981 im_format->imtype = R_IMF_IMTYPE_JP2;
982 im_format->quality = quality;
983
984 if (custom_flags & JP2_16BIT) {
985 im_format->depth = R_IMF_CHAN_DEPTH_16;
986 is_depth_set = true;
987 }
988 else if (custom_flags & JP2_12BIT) {
989 im_format->depth = R_IMF_CHAN_DEPTH_12;
990 is_depth_set = true;
991 }
992
993 if (custom_flags & JP2_YCC) {
994 im_format->jp2_flag |= R_IMF_JP2_FLAG_YCC;
995 }
996
997 if (custom_flags & JP2_CINE) {
999 if (custom_flags & JP2_CINE_48FPS) {
1000 im_format->jp2_flag |= R_IMF_JP2_FLAG_CINE_48;
1001 }
1002 }
1003
1004 if (custom_flags & JP2_JP2) {
1005 im_format->jp2_codec = R_IMF_JP2_CODEC_JP2;
1006 }
1007 else if (custom_flags & JP2_J2K) {
1008 im_format->jp2_codec = R_IMF_JP2_CODEC_J2K;
1009 }
1010 else {
1011 BLI_assert_msg(0, "Unsupported jp2 codec was specified in file type");
1012 }
1013 }
1014#endif
1015#ifdef WITH_IMAGE_WEBP
1016 else if (ftype == IMB_FTYPE_WEBP) {
1017 im_format->imtype = R_IMF_IMTYPE_WEBP;
1018 im_format->quality = quality;
1019 }
1020#endif
1021
1022 else {
1023 im_format->imtype = R_IMF_IMTYPE_JPEG90;
1024 im_format->quality = quality;
1025 }
1026
1027 /* Default depth, accounting for float buffer and format support */
1028 if (!is_depth_set) {
1029 im_format->depth = imtype_best_depth(imbuf, im_format->imtype);
1030 }
1031
1032 /* planes */
1033 im_format->planes = imbuf->planes;
1034}
1035
1037{
1038 return (imf->depth == R_IMF_CHAN_DEPTH_8) && (BKE_imtype_valid_depths(imf->imtype) & imf->depth);
1039}
1040
1041/* Color Management */
1042
1052
1062
1063/* Output */
1064
1066 const Scene *scene_src,
1067 const ImageFormatData *imf_src)
1068{
1069 *imf = (imf_src) ? *imf_src : scene_src->r.im_format;
1070
1071 if (imf_src && imf_src->color_management == R_IMF_COLOR_MANAGEMENT_OVERRIDE) {
1072 /* Use settings specific to one node, image save operation, etc. */
1076 &imf_src->linear_colorspace_settings);
1077 }
1079 /* Use scene settings specific to render output. */
1081 &scene_src->r.im_format.display_settings);
1083 &scene_src->r.im_format.view_settings);
1086 }
1087 else {
1088 /* Use general scene settings also used for display. */
1093 }
1094}
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_init_default(ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_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_render(ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, const char *view_transform)
void BKE_color_managed_view_settings_blend_write(BlendWriter *writer, 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 applying templates with variable expressions to filepaths.
#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 * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_NONNULL(1
#define UNUSED_VARS(...)
#define ELEM(...)
#define STREQ(a, b)
@ ID_SCE
#define DNA_struct_default_get(struct_name)
@ 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_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_AVIJPEG
@ R_IMF_IMTYPE_H264
@ 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_AVIRAW
@ R_IMF_IMTYPE_THEORA
@ R_IMF_IMTYPE_JP2
@ R_IMF_IMTYPE_OPENEXR
@ R_IMF_IMTYPE_MULTILAYER
@ R_IMF_IMTYPE_PNG
@ R_IMF_IMTYPE_AV1
@ R_IMF_IMTYPE_CINEON
@ R_IMF_IMTYPE_RAWTGA
@ R_IMF_IMTYPE_XVID
@ R_IMF_COLOR_MANAGEMENT_OVERRIDE
@ 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_EXR_CODEC_B44
@ R_IMF_EXR_CODEC_MAX
@ R_IMF_EXR_CODEC_B44A
@ R_IMF_EXR_CODEC_ZIP
@ R_IMF_TIFF_CODEC_PACKBITS
@ R_IMF_TIFF_CODEC_DEFLATE
@ R_IMF_TIFF_CODEC_NONE
@ R_IMF_TIFF_CODEC_LZW
@ R_IMF_JP2_CODEC_JP2
@ R_IMF_JP2_CODEC_J2K
@ R_IMF_CINEON_FLAG_LOG
bool IMB_colormanagement_space_name_is_scene_linear(const char *name)
bool IMB_colormanagement_space_name_is_data(const char *name)
@ COLOR_ROLE_DEFAULT_FLOAT
@ COLOR_ROLE_DEFAULT_BYTE
@ COLOR_ROLE_SCENE_LINEAR
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 TIF_16BIT
const char * imb_ext_image[]
bool is_empty() const
CCL_NAMESPACE_BEGIN struct Options options
#define GS(a)
#define OPENEXR_HALF
void BKE_image_format_free(ImageFormatData *imf)
void BKE_image_format_init(ImageFormatData *imf, const bool render)
bool BKE_imtype_supports_compress(const char imtype)
void BKE_image_format_init_for_write(ImageFormatData *imf, const Scene *scene_src, const ImageFormatData *imf_src)
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)
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_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)
bool BKE_imtype_supports_quality(const char imtype)
void BKE_image_format_to_imbuf(ImBuf *ibuf, const ImageFormatData *imf)
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)
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)
blender::Vector< Error > BKE_path_apply_template(char *path, int path_max_length, const VariableMap &template_variables)
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
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