Blender V5.0
image_buttons.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 <cstdio>
10#include <cstring>
11
12#include "DNA_node_types.h"
13#include "DNA_scene_types.h"
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_listbase.h"
18#include "BLI_path_utils.hh"
19#include "BLI_string.h"
20#include "BLI_string_utf8.h"
21#include "BLI_utildefines.h"
22
23#include "BLT_translation.hh"
24
25#include "BKE_context.hh"
26#include "BKE_image.hh"
27#include "BKE_image_format.hh"
28#include "BKE_node.hh"
30#include "BKE_node_runtime.hh"
31#include "BKE_screen.hh"
32
33#include "RE_pipeline.h"
34
36#include "IMB_imbuf.hh"
37#include "IMB_imbuf_types.hh"
38
39#include "MOV_read.hh"
40
41#include "ED_image.hh"
42#include "ED_screen.hh"
43
44#include "RNA_access.hh"
45
46#include "WM_api.hh"
47#include "WM_types.hh"
48
49#include "UI_interface.hh"
51#include "UI_resources.hh"
52
53#include "image_intern.hh"
54
55#define B_NOP -1
56#define MAX_IMAGE_INFO_LEN 128
57
59{
60 if (ntree) {
61 for (bNode *node : ntree->all_nodes()) {
62 if (node->type_legacy == CMP_NODE_VIEWER) {
63 if (node->flag & NODE_DO_OUTPUT) {
64 return static_cast<ImageUser *>(node->storage);
65 }
66 }
67 }
68 }
69 return nullptr;
70}
71
72/* ********************* callbacks for standard image buttons *************** */
73
74static void ui_imageuser_slot_menu(bContext *C, uiLayout *layout, void *image_p)
75{
76 uiBlock *block = layout->block();
77 Image *image = static_cast<Image *>(image_p);
78
79 /* The scene isn't expected to be null, check since it's not a requirement
80 * for the value to be non-null for this function to work.
81 * It's OK if `has_active_render` is false. */
82 Scene *scene = CTX_data_scene(C);
83 bool has_active_render = scene && (RE_GetSceneRender(scene) != nullptr);
84
85 int slot_id;
86 LISTBASE_FOREACH_INDEX (RenderSlot *, slot, &image->renderslots, slot_id) {
87 char str[64];
88 if (slot->name[0] != '\0') {
89 STRNCPY_UTF8(str, slot->name);
90 }
91 else {
92 SNPRINTF_UTF8(str, IFACE_("Slot %d"), slot_id + 1);
93 }
94 /* Default to "blank" for nicer alignment. */
95 int icon = ICON_BLANK1;
96 if (slot_id == image->last_render_slot) {
97 if (has_active_render) {
98 icon = ICON_RENDER_RESULT;
99 }
100 }
101 else if (slot->render != nullptr) {
102 icon = ICON_DOT;
103 }
104 uiBut *but = uiDefIconTextBut(
105 block, ButType::ButMenu, B_NOP, icon, str, 0, 0, UI_UNIT_X * 5, UI_UNIT_X, nullptr, "");
106 UI_but_func_set(but, [image, slot_id](bContext & /*C*/) { image->render_slot = slot_id; });
107 }
108
109 layout->separator();
110 uiDefBut(block,
112 0,
113 IFACE_("Slot"),
114 0,
115 0,
116 UI_UNIT_X * 5,
117 UI_UNIT_Y,
118 nullptr,
119 0.0,
120 0.0,
121 "");
122}
123
124static bool ui_imageuser_slot_menu_step(bContext *C, int direction, void *image_p)
125{
126 Image *image = static_cast<Image *>(image_p);
127
128 if (ED_image_slot_cycle(image, direction)) {
130 return true;
131 }
132 return true;
133}
134
136{
137 RenderView *rv = RE_RenderViewGetById(rr, 0);
138 ImBuf *ibuf = rv->ibuf;
139 if (!ibuf) {
140 return nullptr;
141 }
142 if (ibuf->float_buffer.data) {
143 return IFACE_("Composite");
144 }
145 if (ibuf->byte_buffer.data) {
146 return IFACE_("Sequence");
147 }
148 return nullptr;
149}
150
151/* workaround for passing many args */
157
159{
160 ImageUI_Data *rnd_pt_dst = static_cast<ImageUI_Data *>(
161 MEM_mallocN(sizeof(*rnd_pt_src), __func__));
162 memcpy(rnd_pt_dst, rnd_pt_src, sizeof(*rnd_pt_src));
163 return rnd_pt_dst;
164}
165
166static void ui_imageuser_layer_menu(bContext * /*C*/, uiLayout *layout, void *rnd_pt)
167{
168 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
169 uiBlock *block = layout->block();
170 Image *image = rnd_data->image;
171 ImageUser *iuser = rnd_data->iuser;
172 Scene *scene = iuser->scene;
173
174 /* May have been freed since drawing. */
176 if (UNLIKELY(rr == nullptr)) {
177 BKE_image_release_renderresult(scene, image, rr);
178 return;
179 }
180
182 layout->column(false);
183
184 const char *fake_name = ui_imageuser_layer_fake_name(rr);
185 if (fake_name) {
186 uiDefButS(block,
188 B_NOP,
189 fake_name,
190 0,
191 0,
192 UI_UNIT_X * 5,
193 UI_UNIT_X,
194 &iuser->layer,
195 0.0,
196 0.0,
197 "");
198 }
199
200 int nr = fake_name ? 1 : 0;
201 for (RenderLayer *rl = static_cast<RenderLayer *>(rr->layers.first); rl; rl = rl->next, nr++) {
202 uiDefButS(block,
204 B_NOP,
205 rl->name,
206 0,
207 0,
208 UI_UNIT_X * 5,
209 UI_UNIT_X,
210 &iuser->layer,
211 float(nr),
212 0.0,
213 "");
214 }
215
216 layout->separator();
217 uiDefBut(block,
219 0,
220 IFACE_("Layer"),
221 0,
222 0,
223 UI_UNIT_X * 5,
224 UI_UNIT_Y,
225 nullptr,
226 0.0,
227 0.0,
228 "");
229
230 BKE_image_release_renderresult(scene, image, rr);
231}
232
233static void ui_imageuser_pass_menu(bContext * /*C*/, uiLayout *layout, void *rnd_pt)
234{
235 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
236 uiBlock *block = layout->block();
237 Image *image = rnd_data->image;
238 ImageUser *iuser = rnd_data->iuser;
239 /* (rpass_index == -1) means composite result */
240 const int rpass_index = rnd_data->rpass_index;
241 Scene *scene = iuser->scene;
242 RenderResult *rr;
243 RenderLayer *rl;
244 RenderPass *rpass;
245 int nr;
246
247 /* may have been freed since drawing */
248 rr = BKE_image_acquire_renderresult(scene, image);
249 if (UNLIKELY(rr == nullptr)) {
250 BKE_image_release_renderresult(scene, image, rr);
251 return;
252 }
253
254 rl = static_cast<RenderLayer *>(BLI_findlink(&rr->layers, rpass_index));
255
257 layout->column(false);
258
259 nr = (rl == nullptr) ? 1 : 0;
260
261 ListBase added_passes;
262 BLI_listbase_clear(&added_passes);
263
264 /* rendered results don't have a Combined pass */
265 /* multiview: the ordering must be ascending, so the left-most pass is always the one picked */
266 for (rpass = static_cast<RenderPass *>(rl ? rl->passes.first : nullptr); rpass;
267 rpass = rpass->next, nr++)
268 {
269 /* just show one pass of each kind */
270 if (BLI_findstring_ptr(&added_passes, rpass->name, offsetof(LinkData, data))) {
271 continue;
272 }
273 BLI_addtail(&added_passes, BLI_genericNodeN(rpass->name));
274
275 uiDefButS(block,
277 B_NOP,
278 IFACE_(rpass->name),
279 0,
280 0,
281 UI_UNIT_X * 5,
282 UI_UNIT_X,
283 &iuser->pass,
284 float(nr),
285 0.0,
286 "");
287 }
288
289 layout->separator();
290 uiDefBut(block,
292 0,
293 IFACE_("Pass"),
294 0,
295 0,
296 UI_UNIT_X * 5,
297 UI_UNIT_Y,
298 nullptr,
299 0.0,
300 0.0,
301 "");
302
303 BLI_freelistN(&added_passes);
304
305 BKE_image_release_renderresult(scene, image, rr);
306}
307
308/**************************** view menus *****************************/
309static void ui_imageuser_view_menu_rr(bContext * /*C*/, uiLayout *layout, void *rnd_pt)
310{
311 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
312 uiBlock *block = layout->block();
313 Image *image = rnd_data->image;
314 ImageUser *iuser = rnd_data->iuser;
315 RenderResult *rr;
316 RenderView *rview;
317 int nr;
318 Scene *scene = iuser->scene;
319
320 /* may have been freed since drawing */
321 rr = BKE_image_acquire_renderresult(scene, image);
322 if (UNLIKELY(rr == nullptr)) {
323 BKE_image_release_renderresult(scene, image, rr);
324 return;
325 }
326
328 layout->column(false);
329
330 uiDefBut(block,
332 0,
333 IFACE_("View"),
334 0,
335 0,
336 UI_UNIT_X * 5,
337 UI_UNIT_Y,
338 nullptr,
339 0.0,
340 0.0,
341 "");
342
343 layout->separator();
344
345 nr = (rr ? BLI_listbase_count(&rr->views) : 0) - 1;
346 for (rview = static_cast<RenderView *>(rr ? rr->views.last : nullptr); rview;
347 rview = rview->prev, nr--)
348 {
349 uiDefButS(block,
351 B_NOP,
352 IFACE_(rview->name),
353 0,
354 0,
355 UI_UNIT_X * 5,
356 UI_UNIT_X,
357 &iuser->view,
358 float(nr),
359 0.0,
360 "");
361 }
362
363 BKE_image_release_renderresult(scene, image, rr);
364}
365
366static void ui_imageuser_view_menu_multiview(bContext * /*C*/, uiLayout *layout, void *rnd_pt)
367{
368 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
369 uiBlock *block = layout->block();
370 Image *image = rnd_data->image;
371 ImageUser *iuser = rnd_data->iuser;
372 int nr;
373 ImageView *iv;
374
376 layout->column(false);
377
378 uiDefBut(block,
380 0,
381 IFACE_("View"),
382 0,
383 0,
384 UI_UNIT_X * 5,
385 UI_UNIT_Y,
386 nullptr,
387 0.0,
388 0.0,
389 "");
390
391 layout->separator();
392
393 nr = BLI_listbase_count(&image->views) - 1;
394 for (iv = static_cast<ImageView *>(image->views.last); iv; iv = iv->prev, nr--) {
395 uiDefButS(block,
397 B_NOP,
398 IFACE_(iv->name),
399 0,
400 0,
401 UI_UNIT_X * 5,
402 UI_UNIT_X,
403 &iuser->view,
404 float(nr),
405 0.0,
406 "");
407 }
408}
409
410/* 5 layer button callbacks... */
411static void image_multi_cb(bContext *C, void *rnd_pt, void *rr_v)
412{
413 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
414 ImageUser *iuser = rnd_data->iuser;
415
416 BKE_image_multilayer_index(static_cast<RenderResult *>(rr_v), iuser);
418}
419
420static bool ui_imageuser_layer_menu_step(bContext *C, int direction, void *rnd_pt)
421{
422 Scene *scene = CTX_data_scene(C);
423 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
424 Image *image = rnd_data->image;
425 ImageUser *iuser = rnd_data->iuser;
426 RenderResult *rr;
427 bool changed = false;
428
429 rr = BKE_image_acquire_renderresult(scene, image);
430 if (UNLIKELY(rr == nullptr)) {
431 BKE_image_release_renderresult(scene, image, rr);
432 return false;
433 }
434
435 if (direction == -1) {
436 if (iuser->layer > 0) {
437 iuser->layer--;
438 changed = true;
439 }
440 }
441 else if (direction == 1) {
442 int tot = BLI_listbase_count(&rr->layers);
443
444 if (RE_HasCombinedLayer(rr)) {
445 tot++; /* fake compo/sequencer layer */
446 }
447
448 if (iuser->layer < tot - 1) {
449 iuser->layer++;
450 changed = true;
451 }
452 }
453 else {
454 BLI_assert(0);
455 }
456
457 BKE_image_release_renderresult(scene, image, rr);
458
459 if (changed) {
462 }
463
464 return changed;
465}
466
467static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt)
468{
469 Scene *scene = CTX_data_scene(C);
470 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
471 Image *image = rnd_data->image;
472 ImageUser *iuser = rnd_data->iuser;
473 RenderResult *rr;
474 bool changed = false;
475 int layer = iuser->layer;
476 RenderLayer *rl;
477 RenderPass *rpass;
478
479 rr = BKE_image_acquire_renderresult(scene, image);
480 if (UNLIKELY(rr == nullptr)) {
481 BKE_image_release_renderresult(scene, image, rr);
482 return false;
483 }
484
485 if (RE_HasCombinedLayer(rr)) {
486 layer -= 1;
487 }
488
489 rl = static_cast<RenderLayer *>(BLI_findlink(&rr->layers, layer));
490 if (rl == nullptr) {
491 BKE_image_release_renderresult(scene, image, rr);
492 return false;
493 }
494
495 rpass = static_cast<RenderPass *>(BLI_findlink(&rl->passes, iuser->pass));
496 if (rpass == nullptr) {
497 BKE_image_release_renderresult(scene, image, rr);
498 return false;
499 }
500
501 if (direction == 1) {
502 RenderPass *rp;
503 int rp_index = iuser->pass + 1;
504
505 for (rp = rpass->next; rp; rp = rp->next, rp_index++) {
506 if (!STREQ(rp->name, rpass->name)) {
507 iuser->pass = rp_index;
508 changed = true;
509 break;
510 }
511 }
512 }
513 else if (direction == -1) {
514 RenderPass *rp;
515 int rp_index = 0;
516
517 if (iuser->pass == 0) {
518 BKE_image_release_renderresult(scene, image, rr);
519 return false;
520 }
521
522 for (rp = static_cast<RenderPass *>(rl->passes.first); rp; rp = rp->next, rp_index++) {
523 if (STREQ(rp->name, rpass->name)) {
524 iuser->pass = rp_index - 1;
525 changed = true;
526 break;
527 }
528 }
529 }
530 else {
531 BLI_assert(0);
532 }
533
534 BKE_image_release_renderresult(scene, image, rr);
535
536 if (changed) {
539 }
540
541 return changed;
542}
543
544/* 5 view button callbacks... */
545static void image_multiview_cb(bContext *C, void *rnd_pt, void * /*arg_v*/)
546{
547 ImageUI_Data *rnd_data = static_cast<ImageUI_Data *>(rnd_pt);
548 Image *ima = rnd_data->image;
549 ImageUser *iuser = rnd_data->iuser;
550
551 BKE_image_multiview_index(ima, iuser);
553}
554
556 Image *image,
557 RenderResult *rr,
558 ImageUser *iuser,
559 int w,
560 const short *render_slot)
561{
562 ImageUI_Data rnd_pt_local, *rnd_pt = nullptr;
563 uiBlock *block = layout->block();
564 uiBut *but;
565 RenderLayer *rl = nullptr;
566 int wmenu1, wmenu2, wmenu3, wmenu4;
567 const char *fake_name;
568 const char *display_name = "";
569 const bool show_stereo = (iuser->flag & IMA_SHOW_STEREO) != 0;
570
571 if (iuser->scene == nullptr) {
572 return;
573 }
574
575 layout->row(true);
576
577 /* layer menu is 1/3 larger than pass */
578 wmenu1 = (2 * w) / 5;
579 wmenu2 = (3 * w) / 5;
580 wmenu3 = (3 * w) / 6;
581 wmenu4 = (3 * w) / 6;
582
583 rnd_pt_local.image = image;
584 rnd_pt_local.iuser = iuser;
585 rnd_pt_local.rpass_index = 0;
586
587 /* menu buts */
588 if (render_slot) {
589 RenderSlot *slot = BKE_image_get_renderslot(image, *render_slot);
590 char str[sizeof(slot->name)];
591 if (slot && slot->name[0] != '\0') {
592 STRNCPY_UTF8(str, slot->name);
593 }
594 else {
595 SNPRINTF_UTF8(str, IFACE_("Slot %d"), *render_slot + 1);
596 }
597
598 rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
599 but = uiDefMenuBut(
600 block, ui_imageuser_slot_menu, image, str, 0, 0, wmenu1, UI_UNIT_Y, TIP_("Select Slot"));
602 UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
604 rnd_pt = nullptr;
605 }
606
607 if (rr) {
608 RenderPass *rpass;
609 RenderView *rview;
610 int rpass_index;
611
612 /* layer */
613 fake_name = ui_imageuser_layer_fake_name(rr);
614 rpass_index = iuser->layer - (fake_name ? 1 : 0);
615 rl = static_cast<RenderLayer *>(BLI_findlink(&rr->layers, rpass_index));
616 rnd_pt_local.rpass_index = rpass_index;
617
618 if (RE_layers_have_name(rr)) {
619 display_name = rl ? rl->name : (fake_name ? fake_name : "");
620 rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
621 but = uiDefMenuBut(block,
623 rnd_pt,
624 display_name,
625 0,
626 0,
627 wmenu2,
628 UI_UNIT_Y,
629 TIP_("Select Layer"));
631 UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
633 rnd_pt = nullptr;
634 }
635
636 /* pass */
637 rpass = static_cast<RenderPass *>(rl ? BLI_findlink(&rl->passes, iuser->pass) : nullptr);
638
639 if (rl && RE_passes_have_name(rl)) {
640 display_name = rpass ? rpass->name : "";
641 rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
642 but = uiDefMenuBut(block,
644 rnd_pt,
645 IFACE_(display_name),
646 0,
647 0,
648 wmenu3,
649 UI_UNIT_Y,
650 TIP_("Select Pass"));
652 UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
654 rnd_pt = nullptr;
655 }
656
657 /* view */
658 if (BLI_listbase_count_at_most(&rr->views, 2) > 1 &&
659 ((!show_stereo) || !RE_RenderResult_is_stereo(rr)))
660 {
661 rview = static_cast<RenderView *>(BLI_findlink(&rr->views, iuser->view));
662 display_name = rview ? rview->name : "";
663
664 rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
665 but = uiDefMenuBut(block,
667 rnd_pt,
668 display_name,
669 0,
670 0,
671 wmenu4,
672 UI_UNIT_Y,
673 TIP_("Select View"));
674 UI_but_funcN_set(but, image_multi_cb, rnd_pt, rr);
676 rnd_pt = nullptr;
677 }
678 }
679
680 /* stereo image */
681 else if ((BKE_image_is_stereo(image) && (!show_stereo)) ||
683 {
684 int nr = 0;
685
686 LISTBASE_FOREACH (ImageView *, iv, &image->views) {
687 if (nr++ == iuser->view) {
688 display_name = iv->name;
689 break;
690 }
691 }
692
693 rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
694 but = uiDefMenuBut(block,
696 rnd_pt,
697 display_name,
698 0,
699 0,
700 wmenu1,
701 UI_UNIT_Y,
702 TIP_("Select View"));
703 UI_but_funcN_set(but, image_multiview_cb, rnd_pt, nullptr);
705 rnd_pt = nullptr;
706 }
707}
708
709namespace {
710
711struct RNAUpdateCb {
712 PointerRNA ptr = {};
713 PropertyRNA *prop;
714 ImageUser *iuser;
715};
716
717}; // namespace
718
719static void rna_update_cb(bContext *C, void *arg_cb, void * /*arg*/)
720{
721 RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;
722
723 /* we call update here on the pointer property, this way the
724 * owner of the image pointer can still define its own update
725 * and notifier */
726 RNA_property_update(C, &cb->ptr, cb->prop);
727}
728
730 bContext *C,
732 const blender::StringRefNull propname,
733 PointerRNA *userptr,
734 bool compact,
735 bool multiview)
736{
737 if (!ptr->data) {
738 return;
739 }
740
741 PropertyRNA *prop = RNA_struct_find_property(ptr, propname.c_str());
742 if (!prop) {
743 printf("%s: property not found: %s.%s\n",
744 __func__,
746 propname.c_str());
747 return;
748 }
749
750 if (RNA_property_type(prop) != PROP_POINTER) {
751 printf("%s: expected pointer property for %s.%s\n",
752 __func__,
754 propname.c_str());
755 return;
756 }
757
758 uiBlock *block = layout->block();
759
761 Image *ima = static_cast<Image *>(imaptr.data);
762 ImageUser *iuser = static_cast<ImageUser *>(userptr->data);
763
764 Scene *scene = CTX_data_scene(C);
765 BKE_image_user_frame_calc(ima, iuser, scene->r.cfra);
766
767 layout->context_ptr_set("edit_image", &imaptr);
768 layout->context_ptr_set("edit_image_user", userptr);
769
770 SpaceImage *space_image = CTX_wm_space_image(C);
771 if (!compact && (space_image == nullptr || iuser != &space_image->iuser)) {
773 layout, C, ptr, propname, ima ? nullptr : "IMAGE_OT_new", "IMAGE_OT_open", nullptr);
774
775 if (ima != nullptr) {
776 layout->separator();
777 }
778 }
779
780 if (ima == nullptr) {
781 return;
782 }
783
784 if (ima->source == IMA_SRC_VIEWER) {
785 /* Viewer images. */
786 uiTemplateImageInfo(layout, C, ima, iuser);
787
788 if (ima->type == IMA_TYPE_COMPOSITE) {
789 }
790 else if (ima->type == IMA_TYPE_R_RESULT) {
791 /* browse layer/passes */
792 RenderResult *rr;
793 const float dpi_fac = UI_SCALE_FAC;
794 const int menus_width = 230 * dpi_fac;
795
796 /* Use #BKE_image_acquire_renderresult so we get the correct slot in the menu. */
797 rr = BKE_image_acquire_renderresult(scene, ima);
798 uiblock_layer_pass_buttons(layout, ima, rr, iuser, menus_width, &ima->render_slot);
799 BKE_image_release_renderresult(scene, ima, rr);
800 }
801
802 return;
803 }
804
805 /* Set custom callback for property updates. */
806 RNAUpdateCb *cb = MEM_new<RNAUpdateCb>(__func__);
807 cb->ptr = *ptr;
808 cb->prop = prop;
809 cb->iuser = iuser;
810 UI_block_funcN_set(block,
812 cb,
813 nullptr,
816
817 /* Disable editing if image was modified, to avoid losing changes. */
818 const bool is_dirty = BKE_image_is_dirty(ima);
819 if (is_dirty) {
820 uiLayout *row = &layout->row(true);
821 row->op("image.save", IFACE_("Save"), ICON_NONE);
822 row->op("image.reload", IFACE_("Discard"), ICON_NONE);
823 layout->separator();
824 }
825
826 layout = &layout->column(false);
827 layout->enabled_set(!is_dirty);
828 layout->use_property_decorate_set(false);
829
830 /* Image source */
831 {
832 uiLayout *col = &layout->column(false);
833 col->use_property_split_set(true);
834 col->prop(&imaptr, "source", UI_ITEM_NONE, std::nullopt, ICON_NONE);
835 }
836
837 /* Filepath */
838 const bool is_packed = BKE_image_has_packedfile(ima);
839 const bool no_filepath = is_packed && !BKE_image_has_filepath(ima);
840
841 if ((ima->source != IMA_SRC_GENERATED) && !no_filepath) {
842 layout->separator();
843
844 uiLayout *row = &layout->row(true);
845 if (is_packed) {
846 row->op("image.unpack", "", ICON_PACKAGE);
847 }
848 else {
849 row->op("image.pack", "", ICON_UGLYPACKAGE);
850 }
851
852 row = &row->row(true);
853 row->enabled_set(is_packed == false);
854
855 prop = RNA_struct_find_property(&imaptr, "filepath");
856 uiDefAutoButR(block, &imaptr, prop, -1, "", ICON_NONE, 0, 0, 200, UI_UNIT_Y);
857 row->op("image.file_browse", "", ICON_FILEBROWSER);
858 row->op("image.reload", "", ICON_FILE_REFRESH);
859 }
860
861 /* Image layers and Info */
862 if (ima->source == IMA_SRC_GENERATED) {
863 layout->separator();
864
865 /* Generated */
866 uiLayout *col = &layout->column(false);
867 col->use_property_split_set(true);
868
869 uiLayout *sub = &col->column(true);
870 sub->prop(&imaptr, "generated_width", UI_ITEM_NONE, IFACE_("X"), ICON_NONE);
871 sub->prop(&imaptr, "generated_height", UI_ITEM_NONE, IFACE_("Y"), ICON_NONE);
872
873 col->prop(&imaptr, "use_generated_float", UI_ITEM_NONE, std::nullopt, ICON_NONE);
874
875 col->separator();
876
877 col->prop(&imaptr, "generated_type", UI_ITEM_R_EXPAND, IFACE_("Type"), ICON_NONE);
878 ImageTile *base_tile = BKE_image_get_tile(ima, 0);
879 if (base_tile->gen_type == IMA_GENTYPE_BLANK) {
880 col->prop(&imaptr, "generated_color", UI_ITEM_NONE, std::nullopt, ICON_NONE);
881 }
882 }
883 else if (compact == 0) {
884 uiTemplateImageInfo(layout, C, ima, iuser);
885 }
886 if (ima->type == IMA_TYPE_MULTILAYER && ima->rr) {
887 layout->separator();
888
889 const float dpi_fac = UI_SCALE_FAC;
890 uiblock_layer_pass_buttons(layout, ima, ima->rr, iuser, 230 * dpi_fac, nullptr);
891 }
892
893 if (BKE_image_is_animated(ima)) {
894 /* Animation */
895 layout->separator();
896
897 uiLayout *col = &layout->column(true);
898 col->use_property_split_set(true);
899
900 uiLayout *sub = &col->column(true);
901 uiLayout *row = &sub->row(true);
902 row->prop(userptr, "frame_duration", UI_ITEM_NONE, IFACE_("Frames"), ICON_NONE);
903 row->op("IMAGE_OT_match_movie_length", "", ICON_FILE_REFRESH);
904
905 sub->prop(userptr, "frame_start", UI_ITEM_NONE, IFACE_("Start"), ICON_NONE);
906 sub->prop(userptr, "frame_offset", UI_ITEM_NONE, std::nullopt, ICON_NONE);
907
908 col->prop(userptr, "use_cyclic", UI_ITEM_NONE, std::nullopt, ICON_NONE);
909 col->prop(userptr, "use_auto_refresh", UI_ITEM_NONE, std::nullopt, ICON_NONE);
910
911 if (ima->source == IMA_SRC_MOVIE && compact == 0) {
912 col->prop(&imaptr, "use_deinterlace", UI_ITEM_NONE, IFACE_("Deinterlace"), ICON_NONE);
913 }
914 }
915
916 /* Multiview */
917 if (multiview && compact == 0) {
918 if ((scene->r.scemode & R_MULTIVIEW) != 0) {
919 layout->separator();
920
921 uiLayout *col = &layout->column(false);
922 col->use_property_split_set(true);
923 col->prop(&imaptr, "use_multiview", UI_ITEM_NONE, std::nullopt, ICON_NONE);
924
925 if (RNA_boolean_get(&imaptr, "use_multiview")) {
926 uiTemplateImageViews(layout, &imaptr);
927 }
928 }
929 }
930
931 /* Color-space and alpha. */
932 {
933 layout->separator();
934
935 uiLayout *col = &layout->column(false);
936 col->use_property_split_set(true);
937 uiTemplateColorspaceSettings(col, &imaptr, "colorspace_settings");
938
939 if (compact == 0) {
940 if (ima->source != IMA_SRC_GENERATED) {
941 if (BKE_image_has_alpha(ima)) {
942 uiLayout *sub = &col->column(false);
943 sub->prop(&imaptr, "alpha_mode", UI_ITEM_NONE, IFACE_("Alpha"), ICON_NONE);
944
946 sub->active_set(!is_data);
947 }
948
949 if (ima && iuser) {
950 void *lock;
951 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
952
953 if (ibuf && ibuf->float_buffer.data && (ibuf->foptions.flag & OPENEXR_HALF) == 0) {
954 col->prop(&imaptr, "use_half_precision", UI_ITEM_NONE, std::nullopt, ICON_NONE);
955 }
956 BKE_image_release_ibuf(ima, ibuf, lock);
957 }
958 }
959
960 col->prop(&imaptr, "use_view_as_render", UI_ITEM_NONE, std::nullopt, ICON_NONE);
961 col->prop(&imaptr, "seam_margin", UI_ITEM_NONE, std::nullopt, ICON_NONE);
962 }
963 }
964
965 UI_block_funcN_set(block, nullptr, nullptr, nullptr);
966}
967
969 bContext *C,
970 PointerRNA *imfptr,
971 bool color_management,
972 const char *panel_idname)
973{
974 ImageFormatData *imf = static_cast<ImageFormatData *>(imfptr->data);
975 ID *id = imfptr->owner_id;
976 /* Note: this excludes any video formats; for them the image template does
977 * not show the color depth. Color depth instead is shown as part of encoding UI block,
978 * which is less confusing. */
979 const int depth_ok = BKE_imtype_valid_depths(imf->imtype);
980 /* some settings depend on this being a scene that's rendered */
981 const bool is_render_out = (id && GS(id->name) == ID_SCE);
982
983 uiLayout *col;
984
985 col = &layout->column(false);
986
987 col->use_property_split_set(true);
988 col->use_property_decorate_set(false);
989
990 /* The file output node draws the media type itself. */
991 const bool is_file_output = (id && GS(id->name) == ID_NT);
992 if (!is_file_output) {
993 col->prop(imfptr, "media_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
994 }
995
996 /* Multi layer images and video media types only have a single supported format,
997 * so we needn't draw the format enum. */
998 if (imf->media_type == MEDIA_TYPE_IMAGE) {
999 col->prop(imfptr, "file_format", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1000 }
1001
1002 /* Multi-layer always saves raw unmodified channels. */
1003 if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
1004 col->row(true).prop(imfptr, "color_mode", UI_ITEM_R_EXPAND, IFACE_("Color"), ICON_NONE);
1005 }
1006
1007 /* only display depth setting if multiple depths can be used */
1008 if (ELEM(depth_ok,
1015 R_IMF_CHAN_DEPTH_32) == 0)
1016 {
1017 col->row(true).prop(imfptr, "color_depth", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
1018 }
1019
1021 col->prop(imfptr, "quality", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1022 }
1023
1025 col->prop(imfptr, "compression", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1026 }
1027
1029 col->prop(imfptr, "exr_codec", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1031 col->prop(imfptr, "quality", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1032 }
1033 }
1034 if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) {
1035 col->prop(imfptr, "use_exr_interleave", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1036 }
1037
1038 if (is_render_out && ELEM(imf->imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) {
1039 col->prop(imfptr, "use_preview", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1040 }
1041
1042 if (imf->imtype == R_IMF_IMTYPE_JP2) {
1043 col->prop(imfptr, "jpeg2k_codec", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1044
1045 col->prop(imfptr, "use_jpeg2k_cinema_preset", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1046 col->prop(imfptr, "use_jpeg2k_cinema_48", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1047
1048 col->prop(imfptr, "use_jpeg2k_ycc", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1049 }
1050
1051 if (imf->imtype == R_IMF_IMTYPE_DPX) {
1052 col->prop(imfptr, "use_cineon_log", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1053 }
1054
1055 if (imf->imtype == R_IMF_IMTYPE_CINEON) {
1056#if 1
1057 col->label(RPT_("Hard coded Non-Linear, Gamma:1.7"), ICON_NONE);
1058#else
1059 col->prop(imfptr, "use_cineon_log", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1060 col->prop(imfptr, "cineon_black", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1061 col->prop(imfptr, "cineon_white", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1062 col->prop(imfptr, "cineon_gamma", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1063#endif
1064 }
1065
1066 if (imf->imtype == R_IMF_IMTYPE_TIFF) {
1067 col->prop(imfptr, "tiff_codec", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1068 }
1069
1070 /* Override color management */
1071 if (color_management) {
1072 if (uiLayout *panel = col->panel(C,
1073 panel_idname ? panel_idname : "settings_color_management",
1074 true,
1075 IFACE_("Color Management")))
1076 {
1077 panel->separator();
1078 panel->row(true).prop(imfptr, "color_management", UI_ITEM_R_EXPAND, " ", ICON_NONE);
1079
1080 uiLayout *color_settings = &panel->column(true);
1083 PointerRNA linear_settings_ptr = RNA_pointer_get(imfptr, "linear_colorspace_settings");
1084 color_settings->prop(
1085 &linear_settings_ptr, "name", UI_ITEM_NONE, IFACE_("Color Space"), ICON_NONE);
1086 }
1087 }
1088 else {
1089 PointerRNA display_settings_ptr = RNA_pointer_get(imfptr, "display_settings");
1090 color_settings->prop(
1091 &display_settings_ptr, "display_device", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1092 uiTemplateColormanagedViewSettings(color_settings, nullptr, imfptr, "view_settings");
1094 }
1095 }
1096 }
1097}
1098
1099void uiTemplateImageStereo3d(uiLayout *layout, PointerRNA *stereo3d_format_ptr)
1100{
1101 Stereo3dFormat *stereo3d_format = static_cast<Stereo3dFormat *>(stereo3d_format_ptr->data);
1102 uiLayout *col;
1103
1104 col = &layout->column(false);
1105 col->prop(stereo3d_format_ptr, "display_mode", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1106
1107 switch (stereo3d_format->display_mode) {
1108 case S3D_DISPLAY_ANAGLYPH: {
1109 col->prop(stereo3d_format_ptr, "anaglyph_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1110 break;
1111 }
1112 case S3D_DISPLAY_INTERLACE: {
1113 col->prop(stereo3d_format_ptr, "interlace_type", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1114 col->prop(stereo3d_format_ptr, "use_interlace_swap", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1115 break;
1116 }
1118 col->prop(
1119 stereo3d_format_ptr, "use_sidebyside_crosseyed", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1121 }
1122 case S3D_DISPLAY_TOPBOTTOM: {
1123 col->prop(stereo3d_format_ptr, "use_squeezed_frame", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1124 break;
1125 }
1126 }
1127}
1128
1130 PointerRNA *ptr,
1131 PointerRNA *stereo3d_format_ptr)
1132{
1133 uiLayout *col;
1134
1135 col = &layout->column(false);
1136
1137 col->use_property_split_set(true);
1138 col->use_property_decorate_set(false);
1139
1140 col->prop(ptr, "views_format", UI_ITEM_R_EXPAND, std::nullopt, ICON_NONE);
1141
1142 if (stereo3d_format_ptr && RNA_enum_get(ptr, "views_format") == R_IMF_VIEWS_STEREO_3D) {
1143 uiTemplateImageStereo3d(col, stereo3d_format_ptr);
1144 }
1145}
1146
1148{
1149 Image *ima = static_cast<Image *>(imaptr->data);
1150
1151 if (ima->type != IMA_TYPE_MULTILAYER) {
1152 PropertyRNA *prop;
1153 PointerRNA stereo3d_format_ptr;
1154
1155 prop = RNA_struct_find_property(imaptr, "stereo_3d_format");
1156 stereo3d_format_ptr = RNA_property_pointer_get(imaptr, prop);
1157
1158 uiTemplateViewsFormat(layout, imaptr, &stereo3d_format_ptr);
1159 }
1160 else {
1161 uiTemplateViewsFormat(layout, imaptr, nullptr);
1162 }
1163}
1164
1166{
1167 ImageFormatData *imf = static_cast<ImageFormatData *>(imfptr->data);
1168
1169 if (ptr != nullptr) {
1170 layout->prop(ptr, "use_multiview", UI_ITEM_NONE, std::nullopt, ICON_NONE);
1171 if (!RNA_boolean_get(ptr, "use_multiview")) {
1172 return;
1173 }
1174 }
1175
1176 if (imf->imtype != R_IMF_IMTYPE_MULTILAYER) {
1177 PropertyRNA *prop;
1178 PointerRNA stereo3d_format_ptr;
1179
1180 prop = RNA_struct_find_property(imfptr, "stereo_3d_format");
1181 stereo3d_format_ptr = RNA_property_pointer_get(imfptr, prop);
1182
1183 uiTemplateViewsFormat(layout, imfptr, &stereo3d_format_ptr);
1184 }
1185 else {
1186 uiTemplateViewsFormat(layout, imfptr, nullptr);
1187 }
1188}
1189
1191{
1192 Scene *scene = CTX_data_scene(C);
1193
1194 /* render layers and passes */
1195 if (ima && iuser) {
1196 RenderResult *rr;
1197 const float dpi_fac = UI_SCALE_FAC;
1198 const int menus_width = 160 * dpi_fac;
1199 const bool is_render_result = (ima->type == IMA_TYPE_R_RESULT);
1200
1201 /* Use BKE_image_acquire_renderresult so we get the correct slot in the menu. */
1202 rr = BKE_image_acquire_renderresult(scene, ima);
1204 layout, ima, rr, iuser, menus_width, is_render_result ? &ima->render_slot : nullptr);
1205 BKE_image_release_renderresult(scene, ima, rr);
1206 }
1207}
1208
1210{
1211 if (ima == nullptr || iuser == nullptr) {
1212 return;
1213 }
1214
1215 /* Acquire image buffer. */
1216 void *lock;
1217 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
1218
1219 uiLayout *col = &layout->column(true);
1220 col->alignment_set(blender::ui::LayoutAlign::Right);
1221
1222 if (ibuf == nullptr) {
1223 col->label(RPT_("Cannot Load Image"), ICON_NONE);
1224 }
1225 else {
1226 char str[MAX_IMAGE_INFO_LEN] = {0};
1227 const int len = MAX_IMAGE_INFO_LEN;
1228 int ofs = 0;
1229
1230 ofs += BLI_snprintf_utf8_rlen(str + ofs, len - ofs, RPT_("%d \u00D7 %d, "), ibuf->x, ibuf->y);
1231
1232 if (ibuf->float_buffer.data) {
1233 if (ibuf->channels != 4) {
1235 str + ofs, len - ofs, RPT_("%d float channel(s)"), ibuf->channels);
1236 }
1237 else if (ibuf->planes == R_IMF_PLANES_RGBA) {
1238 ofs += BLI_strncpy_utf8_rlen(str + ofs, RPT_(" RGBA float"), len - ofs);
1239 }
1240 else {
1241 ofs += BLI_strncpy_utf8_rlen(str + ofs, RPT_(" RGB float"), len - ofs);
1242 }
1243 }
1244 else {
1245 if (ibuf->planes == R_IMF_PLANES_RGBA) {
1246 ofs += BLI_strncpy_utf8_rlen(str + ofs, RPT_(" RGBA byte"), len - ofs);
1247 }
1248 else {
1249 ofs += BLI_strncpy_utf8_rlen(str + ofs, RPT_(" RGB byte"), len - ofs);
1250 }
1251 }
1252
1254
1255 /* Try to see if this texture is a compressed format, if not, get the generic format. */
1256 if (!IMB_gpu_get_compressed_format(ibuf, &texture_format)) {
1257 texture_format = IMB_gpu_get_texture_format(
1258 ibuf, ima->flag & IMA_HIGH_BITDEPTH, ibuf->planes >= 8);
1259 }
1260
1261 const char *texture_format_description = GPU_texture_format_name(texture_format);
1262 ofs += BLI_snprintf_utf8_rlen(str + ofs, len - ofs, RPT_(", %s"), texture_format_description);
1263
1264 col->label(str, ICON_NONE);
1265 }
1266
1267 /* Frame number, even if we can't load the image. */
1269 /* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
1270 Scene *scene = CTX_data_scene(C);
1271 const int framenr = BKE_image_user_frame_get(iuser, scene->r.cfra, nullptr);
1272 char str[MAX_IMAGE_INFO_LEN];
1273 int duration = 0;
1274
1275 if (ima->source == IMA_SRC_MOVIE && BKE_image_has_anim(ima)) {
1276 MovieReader *anim = ((ImageAnim *)ima->anims.first)->anim;
1277 if (anim) {
1279 }
1280 }
1281
1282 if (duration > 0) {
1283 /* Movie duration */
1284 SNPRINTF_UTF8(str, RPT_("Frame %d / %d"), framenr, duration);
1285 }
1286 else if (ima->source == IMA_SRC_SEQUENCE && ibuf) {
1287 /* Image sequence frame number + filename */
1288 const char *filename = BLI_path_basename(ibuf->filepath);
1289 SNPRINTF_UTF8(str, RPT_("Frame %d: %s"), framenr, filename);
1290 }
1291 else {
1292 /* Frame number */
1293 SNPRINTF_UTF8(str, RPT_("Frame %d"), framenr);
1294 }
1295
1296 col->label(str, ICON_NONE);
1297 }
1298
1299 BKE_image_release_ibuf(ima, ibuf, lock);
1300}
1301
1302#undef MAX_IMAGE_INFO_LEN
1303
1305{
1306 SpaceImage *space_image = CTX_wm_space_image(C);
1307 return space_image != nullptr && space_image->image != nullptr;
1308}
1309
1310static void metadata_panel_context_draw(const bContext *C, Panel *panel)
1311{
1312 void *lock;
1313 SpaceImage *space_image = CTX_wm_space_image(C);
1314 Image *image = space_image->image;
1315 ImBuf *ibuf = BKE_image_acquire_ibuf(image, &space_image->iuser, &lock);
1316 if (ibuf != nullptr) {
1318 }
1319 BKE_image_release_ibuf(image, ibuf, lock);
1320}
1321
1323{
1324 PanelType *pt;
1325
1326 pt = MEM_callocN<PanelType>("spacetype image panel metadata");
1327 STRNCPY_UTF8(pt->idname, "IMAGE_PT_metadata");
1328 STRNCPY_UTF8(pt->label, N_("Metadata"));
1329 STRNCPY_UTF8(pt->category, "Image");
1331 pt->order = 10;
1335 BLI_addtail(&art->paneltypes, pt);
1336}
SpaceImage * CTX_wm_space_image(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RenderSlot * BKE_image_get_renderslot(Image *ima, int index)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
bool BKE_image_has_alpha(Image *image)
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
bool BKE_image_has_filepath(const Image *ima)
RenderPass * BKE_image_multilayer_index(RenderResult *rr, ImageUser *iuser)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
bool BKE_image_is_dirty(Image *image)
void BKE_image_release_renderresult(Scene *scene, Image *ima, RenderResult *render_result)
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, bool *r_is_in_range)
bool BKE_image_has_anim(Image *image)
bool BKE_image_is_stereo(const Image *ima)
bool BKE_image_is_multiview(const Image *ima)
bool BKE_image_has_packedfile(const Image *image)
bool BKE_image_is_animated(Image *image)
RenderResult * BKE_image_acquire_renderresult(Scene *scene, Image *ima)
void BKE_image_multiview_index(const Image *ima, ImageUser *iuser)
bool BKE_imtype_supports_compress(char imtype)
bool BKE_imtype_supports_quality(char imtype)
char BKE_imtype_valid_depths(char imtype)
bool BKE_imtype_requires_linear_float(char imtype)
#define CMP_NODE_VIEWER
@ PANEL_TYPE_DEFAULT_CLOSED
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ATTR_FALLTHROUGH
void * BLI_findlink(const ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:534
LinkData * BLI_genericNodeN(void *data)
Definition listbase.cc:922
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
#define LISTBASE_FOREACH_INDEX(type, var, list, index_var)
int BLI_listbase_count_at_most(const ListBase *listbase, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:511
void * BLI_findstring_ptr(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:651
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define SNPRINTF_UTF8(dst, format,...)
char size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t dst_maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
size_t BLI_snprintf_utf8_rlen(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
#define UNLIKELY(x)
#define ELEM(...)
#define STREQ(a, b)
#define RPT_(msgid)
#define TIP_(msgid)
#define IFACE_(msgid)
#define BLT_I18NCONTEXT_DEFAULT_BPYRNA
@ ID_NT
@ ID_SCE
@ IMA_SRC_MOVIE
@ IMA_SRC_GENERATED
@ IMA_SRC_VIEWER
@ IMA_SRC_SEQUENCE
@ IMA_GENTYPE_BLANK
@ IMA_HIGH_BITDEPTH
struct ImageUser ImageUser
@ IMA_TYPE_MULTILAYER
@ IMA_TYPE_R_RESULT
@ IMA_TYPE_COMPOSITE
@ IMA_SHOW_STEREO
@ NODE_DO_OUTPUT
@ R_IMF_EXR_CODEC_DWAB
@ R_IMF_EXR_CODEC_DWAA
@ MEDIA_TYPE_IMAGE
@ R_IMF_PLANES_RGBA
@ S3D_DISPLAY_ANAGLYPH
@ S3D_DISPLAY_INTERLACE
@ S3D_DISPLAY_TOPBOTTOM
@ S3D_DISPLAY_SIDEBYSIDE
@ 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_VIEWS_STEREO_3D
@ R_IMF_COLOR_MANAGEMENT_OVERRIDE
@ R_IMF_IMTYPE_TIFF
@ R_IMF_IMTYPE_DPX
@ R_IMF_IMTYPE_JP2
@ R_IMF_IMTYPE_OPENEXR
@ R_IMF_IMTYPE_MULTILAYER
@ R_IMF_IMTYPE_CINEON
@ R_MULTIVIEW
#define UI_SCALE_FAC
bool ED_image_slot_cycle(Image *image, int direction)
void ED_region_image_metadata_panel_draw(ImBuf *ibuf, uiLayout *layout)
Definition area.cc:4149
const char * GPU_texture_format_name(blender::gpu::TextureFormat format)
bool IMB_colormanagement_space_name_is_data(const char *name)
blender::gpu::TextureFormat IMB_gpu_get_texture_format(const ImBuf *ibuf, bool high_bitdepth, bool use_grayscale)
Definition util_gpu.cc:410
bool IMB_gpu_get_compressed_format(const ImBuf *ibuf, blender::gpu::TextureFormat *r_texture_format)
Definition util_gpu.cc:101
#define OPENEXR_CODEC_MASK
Read Guarded memory(de)allocation.
@ IMB_TC_RECORD_RUN
Definition MOV_enums.hh:54
@ PROP_POINTER
Definition RNA_types.hh:167
#define C
Definition RandGen.cpp:29
void UI_but_func_set(uiBut *but, std::function< void(bContext &)> func)
void * but_func_argN_copy(const void *argN)
void but_func_argN_free(void *argN)
uiBut * uiDefIconTextBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, int icon, blender::StringRef str, int x, int y, short width, short height, void *poin, std::optional< blender::StringRef > tip)
#define UI_UNIT_Y
uiBut * uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, blender::StringRef str, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
void UI_but_func_menu_step_set(uiBut *but, uiMenuStepFunc func)
void uiTemplateColormanagedViewSettings(uiLayout *layout, bContext *C, PointerRNA *ptr, blender::StringRefNull propname)
uiBut * uiDefButS(uiBlock *block, ButType type, int retval, blender::StringRef str, int x, int y, short width, short height, short *poin, float min, float max, std::optional< blender::StringRef > tip)
uiBut * uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int index, std::optional< blender::StringRef > name, int icon, int x, int y, int width, int height)
void UI_but_type_set_menu_from_pulldown(uiBut *but)
void uiTemplateID(uiLayout *layout, const bContext *C, PointerRNA *ptr, blender::StringRefNull propname, const char *newop, const char *openop, const char *unlinkop, int filter=UI_TEMPLATE_ID_FILTER_ALL, bool live_icon=false, std::optional< blender::StringRef > text=std::nullopt)
void UI_block_funcN_set(uiBlock *block, uiButHandleNFunc funcN, void *argN, void *arg2, uiButArgNFree func_argN_free_fn=MEM_freeN, uiButArgNCopy func_argN_copy_fn=MEM_dupallocN)
#define UI_UNIT_X
void uiTemplateColorspaceSettings(uiLayout *layout, PointerRNA *ptr, blender::StringRefNull propname)
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2, uiButArgNFree func_argN_free_fn=MEM_freeN, uiButArgNCopy func_argN_copy_fn=MEM_dupallocN)
uiBut * uiDefBut(uiBlock *block, uiButTypeWithPointerType but_and_ptr_type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
@ UI_ITEM_R_EXPAND
#define UI_ITEM_NONE
#define ND_DRAW
Definition WM_types.hh:461
#define NC_IMAGE
Definition WM_types.hh:384
volatile int lock
BMesh const char void * data
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
constexpr const char * c_str() const
static bool metadata_panel_context_poll(const bContext *C, PanelType *)
static void metadata_panel_context_draw(const bContext *C, Panel *panel)
#define offsetof(t, d)
#define str(s)
#define GS(x)
uint col
#define printf(...)
#define OPENEXR_HALF
static const char * ui_imageuser_layer_fake_name(RenderResult *rr)
static void uiTemplateViewsFormat(uiLayout *layout, PointerRNA *ptr, PointerRNA *stereo3d_format_ptr)
void image_buttons_register(ARegionType *art)
static void image_multiview_cb(bContext *C, void *rnd_pt, void *)
static void ui_imageuser_view_menu_rr(bContext *, uiLayout *layout, void *rnd_pt)
static void ui_imageuser_pass_menu(bContext *, uiLayout *layout, void *rnd_pt)
static void ui_imageuser_view_menu_multiview(bContext *, uiLayout *layout, void *rnd_pt)
static void image_multi_cb(bContext *C, void *rnd_pt, void *rr_v)
void uiTemplateImageLayers(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
static void ui_imageuser_slot_menu(bContext *C, uiLayout *layout, void *image_p)
ImageUser * ntree_get_active_iuser(bNodeTree *ntree)
#define MAX_IMAGE_INFO_LEN
void uiTemplateImageViews(uiLayout *layout, PointerRNA *imaptr)
static bool ui_imageuser_slot_menu_step(bContext *C, int direction, void *image_p)
static bool ui_imageuser_layer_menu_step(bContext *C, int direction, void *rnd_pt)
static void ui_imageuser_layer_menu(bContext *, uiLayout *layout, void *rnd_pt)
static ImageUI_Data * ui_imageuser_data_copy(const ImageUI_Data *rnd_pt_src)
void uiTemplateImageStereo3d(uiLayout *layout, PointerRNA *stereo3d_format_ptr)
void uiTemplateImageFormatViews(uiLayout *layout, PointerRNA *imfptr, PointerRNA *ptr)
static void uiblock_layer_pass_buttons(uiLayout *layout, Image *image, RenderResult *rr, ImageUser *iuser, int w, const short *render_slot)
static bool metadata_panel_context_poll(const bContext *C, PanelType *)
static void rna_update_cb(bContext *C, void *arg_cb, void *)
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const blender::StringRefNull propname, PointerRNA *userptr, bool compact, bool multiview)
void uiTemplateImageSettings(uiLayout *layout, bContext *C, PointerRNA *imfptr, bool color_management, const char *panel_idname)
static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt)
static void metadata_panel_context_draw(const bContext *C, Panel *panel)
void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *iuser)
#define B_NOP
Definition interface.cc:97
static void rna_update_cb(bContext &C, const RNAUpdateCb &cb)
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
int MOV_get_duration_frames(MovieReader *anim, IMB_Timecode_Type tc)
void block_layout_set_current(uiBlock *block, uiLayout *layout)
bool RE_HasCombinedLayer(const RenderResult *result)
RenderView * RE_RenderViewGetById(RenderResult *rr, const int view_id)
bool RE_RenderResult_is_stereo(const RenderResult *result)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
PropertyType RNA_property_type(PropertyRNA *prop)
PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
const char * RNA_struct_identifier(const StructRNA *type)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
bool RE_passes_have_name(RenderLayer *rl)
bool RE_layers_have_name(RenderResult *result)
Render * RE_GetSceneRender(const Scene *scene)
ListBase paneltypes
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
char filepath[IMB_FILEPATH_SIZE]
ImBufFloatBuffer float_buffer
ImbFormatOptions foptions
ImBufByteBuffer byte_buffer
unsigned char planes
ImageUser * iuser
struct Scene * scene
char name[64]
struct ImageView * prev
short last_render_slot
ListBase anims
ColorManagedColorspaceSettings colorspace_settings
ListBase renderslots
short source
short render_slot
struct RenderResult * rr
ListBase views
void * last
void * first
void(* draw)(const bContext *C, Panel *panel)
char idname[BKE_ST_MAXNAME]
bool(* poll)(const bContext *C, PanelType *pt)
char translation_context[BKE_ST_MAXNAME]
char category[BKE_ST_MAXNAME]
char label[BKE_ST_MAXNAME]
struct uiLayout * layout
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
ListBase passes
Definition RE_pipeline.h:94
char name[RE_MAXNAME]
Definition RE_pipeline.h:89
struct RenderLayer * next
Definition RE_pipeline.h:86
char name[64]
Definition RE_pipeline.h:55
struct RenderPass * next
Definition RE_pipeline.h:53
ListBase views
ListBase layers
char name[64]
struct ImBuf * ibuf
Definition RE_pipeline.h:49
struct RenderView * prev
Definition RE_pipeline.h:41
char name[64]
Definition RE_pipeline.h:42
struct RenderData r
struct ImageUser iuser
struct Image * image
void use_property_decorate_set(bool is_sep)
uiBlock * block() const
uiLayout & column(bool align)
void active_set(bool active)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void enabled_set(bool enabled)
void context_ptr_set(blender::StringRef name, const PointerRNA *ptr)
uiLayout & row(bool align)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
void * BKE_image_get_tile
Definition stubs.c:36
uint len
#define N_(msgid)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition wm_files.cc:4238