diff options
Diffstat (limited to 'source/blender/blenkernel/intern/image.cc')
-rw-r--r-- | source/blender/blenkernel/intern/image.cc | 117 |
1 files changed, 89 insertions, 28 deletions
diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index bc21e706d1e..f8b2d841028 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -1172,24 +1172,83 @@ Image *BKE_image_add_generated(Main *bmain, return ima; } -Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name) +static void image_colorspace_from_imbuf(Image *image, const ImBuf *ibuf) { - Image *ima; + const char *colorspace_name = NULL; + if (ibuf->rect_float) { + if (ibuf->float_colorspace) { + colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->float_colorspace); + } + else { + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT); + } + } + + if (ibuf->rect && !colorspace_name) { + if (ibuf->rect_colorspace) { + colorspace_name = IMB_colormanagement_colorspace_get_name(ibuf->rect_colorspace); + } + else { + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE); + } + } + + if (colorspace_name) { + STRNCPY(image->colorspace_settings.name, colorspace_name); + } +} + +Image *BKE_image_add_from_imbuf(Main *bmain, ImBuf *ibuf, const char *name) +{ if (name == nullptr) { name = BLI_path_basename(ibuf->name); } - ima = image_alloc(bmain, name, IMA_SRC_FILE, IMA_TYPE_IMAGE); + /* When the image buffer has valid path create a new image with "file" source and copy the path + * from the image buffer. + * Otherwise create "generated" image, avoiding invalid configuration with an empty file path. */ + const eImageSource source = ibuf->name[0] != '\0' ? IMA_SRC_FILE : IMA_SRC_GENERATED; - if (ima) { - STRNCPY(ima->filepath, ibuf->name); - image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + Image *ima = image_alloc(bmain, name, source, IMA_TYPE_IMAGE); + + if (!ima) { + return nullptr; } + BKE_image_replace_imbuf(ima, ibuf); + return ima; } +void BKE_image_replace_imbuf(Image *image, ImBuf *ibuf) +{ + BLI_assert(image->type == IMA_TYPE_IMAGE && + ELEM(image->source, IMA_SRC_FILE, IMA_SRC_GENERATED)); + + BKE_image_free_buffers(image); + + image_assign_ibuf(image, ibuf, IMA_NO_INDEX, 0); + image_colorspace_from_imbuf(image, ibuf); + + /* Keep generated image type flags consistent with the image buffer. */ + if (image->source == IMA_SRC_GENERATED) { + if (ibuf->rect_float) { + image->gen_flag |= IMA_GEN_FLOAT; + } + else { + image->gen_flag &= ~IMA_GEN_FLOAT; + } + + image->gen_x = ibuf->x; + image->gen_y = ibuf->y; + } + + /* Consider image dirty since its content can not be re-created unless the image is explicitly + * saved. */ + BKE_image_mark_dirty(image, ibuf); +} + /** Pack image buffer to memory as PNG or EXR. */ static bool image_memorypack_imbuf( Image *ima, ImBuf *ibuf, int view, int tile_number, const char *filepath) @@ -1582,7 +1641,7 @@ static void stampdata( } if (use_dynamic && scene->r.stamp & R_STAMP_MARKER) { - const char *name = BKE_scene_find_last_marker_name(scene, CFRA); + const char *name = BKE_scene_find_last_marker_name(scene, scene->r.cfra); if (name) { STRNCPY(text, name); @@ -1730,7 +1789,7 @@ static void stampdata_from_template(StampData *stamp_data, stamp_data->file[0] = '\0'; } if (scene->r.stamp & R_STAMP_NOTE) { - SNPRINTF(stamp_data->note, "%s", stamp_data_template->note); + STRNCPY(stamp_data->note, stamp_data_template->note); } else { stamp_data->note[0] = '\0'; @@ -1950,7 +2009,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Rendertime */ + /* Top left corner, below File, Date, Render-time */ if (TEXT_SIZE_CHECK(stamp_data.memory, w, h)) { y -= h; @@ -1973,7 +2032,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Rendertime, Memory */ + /* Top left corner, below: File, Date, Render-time, Memory. */ if (TEXT_SIZE_CHECK(stamp_data.hostname, w, h)) { y -= h; @@ -1996,7 +2055,7 @@ void BKE_image_stamp_buf(Scene *scene, y -= BUFF_MARGIN_Y * 2; } - /* Top left corner, below File, Date, Memory, Rendertime, Hostname */ + /* Top left corner, below: File, Date, Memory, Render-time, Host-name. */ BLF_enable(mono, BLF_WORD_WRAP); if (TEXT_SIZE_CHECK_WORD_WRAP(stamp_data.note, w, h)) { y -= h; @@ -2416,7 +2475,10 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, const ImageFormatData *imf) return ok; } -int BKE_imbuf_write_as(ImBuf *ibuf, const char *name, ImageFormatData *imf, const bool save_copy) +int BKE_imbuf_write_as(ImBuf *ibuf, + const char *name, + const ImageFormatData *imf, + const bool save_copy) { ImBuf ibuf_back = *ibuf; int ok; @@ -2929,6 +2991,7 @@ void BKE_image_signal(Main *bmain, Image *ima, ImageUser *iuser, int signal) MEM_freeN(tile); } base_tile->next = nullptr; + base_tile->tile_number = 1001; ima->tiles.last = base_tile; } @@ -3111,7 +3174,9 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *r_tile_start, char filename[FILE_MAXFILE], dirname[FILE_MAXDIR]; BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename)); - BKE_image_ensure_tile_token(filename); + if (!BKE_image_is_filename_tokenized(filename)) { + BKE_image_ensure_tile_token(filename); + } eUDIM_TILE_FORMAT tile_format; char *udim_pattern = BKE_image_get_tile_strformat(filename, &tile_format); @@ -3145,10 +3210,7 @@ bool BKE_image_get_tile_info(char *filepath, ListBase *tiles, int *r_tile_start, BLI_filelist_free(dirs, dirs_num); MEM_SAFE_FREE(udim_pattern); - /* Ensure that all discovered UDIMs are valid and that there's at least 2 files in total. - * Downstream code checks the range value to determine tiled-ness; it's important we match that - * expectation here too (T97366). */ - if (all_valid_udim && min_udim <= IMA_UDIM_MAX && max_udim > min_udim) { + if (all_valid_udim && min_udim <= IMA_UDIM_MAX) { BLI_join_dirfile(filepath, FILE_MAX, dirname, filename); *r_tile_start = min_udim; @@ -3315,13 +3377,18 @@ bool BKE_image_fill_tile(struct Image *ima, return false; } +bool BKE_image_is_filename_tokenized(char *filepath) +{ + const char *filename = BLI_path_basename(filepath); + return strstr(filename, "<UDIM>") != nullptr || strstr(filename, "<UVTILE>") != nullptr; +} + void BKE_image_ensure_tile_token(char *filename) { BLI_assert_msg(BLI_path_slash_find(filename) == nullptr, "Only the file-name component should be used!"); - /* Is there a '<' character in the filename? Assume tokens already present. */ - if (strstr(filename, "<") != nullptr) { + if (BKE_image_is_filename_tokenized(filename)) { return; } @@ -3890,7 +3957,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame) } if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D) { - IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); + IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], ibuf_arr.data(), &ibuf_arr[1]); } for (int i = 0; i < totviews; i++) { @@ -4059,7 +4126,7 @@ static ImBuf *image_load_image_file( /* multi-views/multi-layers OpenEXR files directly populate ima, and return null ibuf... */ if (BKE_image_is_stereo(ima) && ima->views_format == R_IMF_VIEWS_STEREO_3D && ibuf_arr[0] && tot_viewfiles == 1 && totviews >= 2) { - IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); + IMB_ImBufFromStereo3d(ima->stereo3d_format, ibuf_arr[0], ibuf_arr.data(), &ibuf_arr[1]); } /* return the original requested ImBuf */ @@ -4993,13 +5060,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *r_width, int *r_hei } else if (image != nullptr && image->type == IMA_TYPE_R_RESULT && iuser != nullptr && iuser->scene != nullptr) { - Scene *scene = iuser->scene; - *r_width = (scene->r.xsch * scene->r.size) / 100; - *r_height = (scene->r.ysch * scene->r.size) / 100; - if ((scene->r.mode & R_BORDER) && (scene->r.mode & R_CROP)) { - *r_width *= BLI_rctf_size_x(&scene->r.border); - *r_height *= BLI_rctf_size_y(&scene->r.border); - } + BKE_render_resolution(&iuser->scene->r, true, r_width, r_height); } else { *r_width = IMG_SIZE_FALLBACK; |