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