Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenloader/BLO_readfile.h3
-rw-r--r--source/blender/blenloader/intern/readblenentry.c118
-rw-r--r--source/blender/imbuf/intern/thumbs_blend.c42
3 files changed, 103 insertions, 60 deletions
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index dbdb181281a..4b7f29dd7dc 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -172,6 +172,9 @@ struct LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
int ofblocktype,
int *r_tot_info_items);
struct LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_tot_prev);
+struct PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
+ int ofblocktype,
+ const char *name);
struct LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh);
void BLO_blendhandle_close(BlendHandle *bh);
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 44a26b9bf85..f67ff0f7ac7 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -217,6 +217,96 @@ LinkNode *BLO_blendhandle_get_datablock_info(BlendHandle *bh,
}
/**
+ * Read the preview rects and store in `result`.
+ *
+ * `bhead` should point to the block that sourced the `preview_from_file`
+ * parameter.
+ * `bhead` parameter is consumed. The correct bhead pointing to the next bhead in the file after
+ * the preview rects is returned by this function.
+ * \param fd: The filedata to read the data from.
+ * \param bhead: should point to the block that sourced the `preview_from_file parameter`.
+ * bhead is consumed. the new bhead is returned by this function.
+ * \param result: the Preview Image where the preview rect will be stored.
+ * \param preview_from_file: The read PreviewImage where the bhead points to. The rects of this
+ * \return PreviewImage or NULL when no preview Images have been found. Caller owns the returned
+ */
+static BHead *blo_blendhandle_read_preview_rects(FileData *fd,
+ BHead *bhead,
+ PreviewImage *result,
+ const PreviewImage *preview_from_file)
+{
+ for (int preview_index = 0; preview_index < NUM_ICON_SIZES; preview_index++) {
+ if (preview_from_file->rect[preview_index] && preview_from_file->w[preview_index] &&
+ preview_from_file->h[preview_index]) {
+ bhead = blo_bhead_next(fd, bhead);
+ BLI_assert((preview_from_file->w[preview_index] * preview_from_file->h[preview_index] *
+ sizeof(uint)) == bhead->len);
+ result->rect[preview_index] = BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect");
+ }
+ else {
+ /* This should not be needed, but can happen in 'broken' .blend files,
+ * better handle this gracefully than crashing. */
+ BLI_assert(preview_from_file->rect[preview_index] == NULL &&
+ preview_from_file->w[preview_index] == 0 &&
+ preview_from_file->h[preview_index] == 0);
+ result->rect[preview_index] = NULL;
+ result->w[preview_index] = result->h[preview_index] = 0;
+ }
+ BKE_previewimg_finish(result, preview_index);
+ }
+
+ return bhead;
+}
+
+/**
+ * Get the PreviewImage of a single data block in a file.
+ * (e.g. all the scene previews in a file).
+ *
+ * \param bh: The blendhandle to access.
+ * \param ofblocktype: The type of names to get.
+ * \param name: Name of the block without the ID_ prefix, to read the preview image from.
+ * \return PreviewImage or NULL when no preview Images have been found. Caller owns the returned
+ */
+PreviewImage *BLO_blendhandle_get_preview_for_id(BlendHandle *bh,
+ int ofblocktype,
+ const char *name)
+{
+ FileData *fd = (FileData *)bh;
+ bool looking = false;
+ const int sdna_preview_image = DNA_struct_find_nr(fd->filesdna, "PreviewImage");
+
+ for (BHead *bhead = blo_bhead_first(fd); bhead; bhead = blo_bhead_next(fd, bhead)) {
+ if (bhead->code == DATA) {
+ if (looking && bhead->SDNAnr == sdna_preview_image) {
+ PreviewImage *preview_from_file = BLO_library_read_struct(fd, bhead, "PreviewImage");
+
+ if (preview_from_file == NULL) {
+ break;
+ }
+
+ PreviewImage *result = MEM_dupallocN(preview_from_file);
+ bhead = blo_blendhandle_read_preview_rects(fd, bhead, result, preview_from_file);
+ MEM_freeN(preview_from_file);
+ return result;
+ }
+ }
+ else if (looking || bhead->code == ENDB) {
+ /* We were looking for a preview image, but didn't find any belonging to block. So it doesn't
+ * exist. */
+ break;
+ }
+ else if (bhead->code == ofblocktype) {
+ const char *idname = blo_bhead_id_name(fd, bhead);
+ if (STREQ(&idname[2], name)) {
+ looking = true;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+/**
* Gets the previews of all the data-blocks in a file of a certain type
* (e.g. all the scene previews in a file).
*
@@ -264,33 +354,7 @@ LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype, int *r_
if (prv) {
memcpy(new_prv, prv, sizeof(PreviewImage));
- if (prv->rect[0] && prv->w[0] && prv->h[0]) {
- bhead = blo_bhead_next(fd, bhead);
- BLI_assert((new_prv->w[0] * new_prv->h[0] * sizeof(uint)) == bhead->len);
- new_prv->rect[0] = BLO_library_read_struct(fd, bhead, "PreviewImage Icon Rect");
- }
- else {
- /* This should not be needed, but can happen in 'broken' .blend files,
- * better handle this gracefully than crashing. */
- BLI_assert(prv->rect[0] == NULL && prv->w[0] == 0 && prv->h[0] == 0);
- new_prv->rect[0] = NULL;
- new_prv->w[0] = new_prv->h[0] = 0;
- }
- BKE_previewimg_finish(new_prv, 0);
-
- if (prv->rect[1] && prv->w[1] && prv->h[1]) {
- bhead = blo_bhead_next(fd, bhead);
- BLI_assert((new_prv->w[1] * new_prv->h[1] * sizeof(uint)) == bhead->len);
- new_prv->rect[1] = BLO_library_read_struct(fd, bhead, "PreviewImage Image Rect");
- }
- else {
- /* This should not be needed, but can happen in 'broken' .blend files,
- * better handle this gracefully than crashing. */
- BLI_assert(prv->rect[1] == NULL && prv->w[1] == 0 && prv->h[1] == 0);
- new_prv->rect[1] = NULL;
- new_prv->w[1] = new_prv->h[1] = 0;
- }
- BKE_previewimg_finish(new_prv, 1);
+ bhead = blo_blendhandle_read_preview_rects(fd, bhead, new_prv, prv);
MEM_freeN(prv);
}
}
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index 878aa44f0d9..085620cb785 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -41,53 +41,29 @@
#include "MEM_guardedalloc.h"
+/* NOTE: we should handle all previews for a same group at once, would avoid reopening
+ * `.blend` file for each and every ID. However, this adds some complexity,
+ * so keep it for later. */
static ImBuf *imb_thumb_load_from_blend_id(const char *blen_path,
const char *blen_group,
const char *blen_id)
{
ImBuf *ima = NULL;
- LinkNode *ln, *names, *lp, *previews = NULL;
BlendFileReadReport bf_reports = {.reports = NULL};
- struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, &bf_reports);
- int idcode = BKE_idtype_idcode_from_name(blen_group);
- int i, nprevs, nnames;
+ struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, &bf_reports);
if (libfiledata == NULL) {
return NULL;
}
- /* NOTE: we should handle all previews for a same group at once, would avoid reopening
- * `.blend` file for each and every ID. However, this adds some complexity,
- * so keep it for later. */
- names = BLO_blendhandle_get_datablock_names(libfiledata, idcode, false, &nnames);
- previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs);
-
+ int idcode = BKE_idtype_idcode_from_name(blen_group);
+ PreviewImage *preview = BLO_blendhandle_get_preview_for_id(libfiledata, idcode, blen_id);
BLO_blendhandle_close(libfiledata);
- if (!previews || (nnames != nprevs)) {
- if (previews != 0) {
- /* No previews at all is not a bug! */
- printf("%s: error, found %d items, %d previews\n", __func__, nnames, nprevs);
- }
- BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_freeN(names);
- return NULL;
+ if (preview) {
+ ima = BKE_previewimg_to_imbuf(preview, ICON_SIZE_PREVIEW);
+ BKE_previewimg_freefunc(preview);
}
-
- for (i = 0, ln = names, lp = previews; i < nnames; i++, ln = ln->next, lp = lp->next) {
- const char *blockname = ln->link;
- PreviewImage *img = lp->link;
-
- if (STREQ(blockname, blen_id)) {
- if (img) {
- ima = BKE_previewimg_to_imbuf(img, ICON_SIZE_PREVIEW);
- }
- break;
- }
- }
-
- BLI_linklist_free(previews, BKE_previewimg_freefunc);
- BLI_linklist_freeN(names);
return ima;
}