[Bf-blender-cvs] [a67a51e] master: IMB_thumb: Allow blen-handling func to also load datablock previews from .blend file.

Bastien Montagne noreply at git.blender.org
Tue Aug 18 14:35:00 CEST 2015


Commit: a67a51ed55da8728ba2cc05f7b9bc026183080cb
Author: Bastien Montagne
Date:   Tue Aug 18 14:32:13 2015 +0200
Branches: master
https://developer.blender.org/rBa67a51ed55da8728ba2cc05f7b9bc026183080cb

IMB_thumb: Allow blen-handling func to also load datablock previews from .blend file.

Notes:
* Not yet used, this is the last piece of 'side changes' before the big filebrowser commit.
* We can probably be more effective here (like e.g. reading and storing all previews for a given
  group in thumbnails cache at once, instead of re-opening and parsing the whole file each time),
  but will do this later.

===================================================================

M	source/blender/imbuf/IMB_thumbs.h
M	source/blender/imbuf/intern/thumbs.c
M	source/blender/imbuf/intern/thumbs_blend.c

===================================================================

diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
index 13237fe..aaa5eea 100644
--- a/source/blender/imbuf/IMB_thumbs.h
+++ b/source/blender/imbuf/IMB_thumbs.h
@@ -84,7 +84,7 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source);
 void IMB_thumb_makedirs(void);
 
 /* special function for loading a thumbnail embedded into a blend file */
-ImBuf *IMB_thumb_load_blend(const char *path);
+ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id);
 void   IMB_thumb_overlay_blend(unsigned int *thumb, int width, int height, float aspect);
 
 /* special function for previewing fonts */
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index f67718f..3355f4d 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -44,6 +44,8 @@
 #include "BLI_threads.h"
 #include BLI_SYSTEM_PID_H
 
+#include "BLO_readfile.h"
+
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
 #include "IMB_thumbs.h"
@@ -314,6 +316,7 @@ void IMB_thumb_makedirs(void)
 /* create thumbnail for file and returns new imbuf for thumbnail */
 static ImBuf *thumb_create_ex(
         const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash,
+        const char *blen_group, const char *blen_id,
         ThumbSize size, ThumbSource source, ImBuf *img)
 {
 	char desc[URI_MAX + 22];
@@ -371,7 +374,7 @@ static ImBuf *thumb_create_ex(
 							img = IMB_loadiffname(file_path, IB_rect | IB_metadata, NULL);
 							break;
 						case THB_SOURCE_BLEND:
-							img = IMB_thumb_load_blend(file_path);
+							img = IMB_thumb_load_blend(file_path, blen_group, blen_id);
 							break;
 						case THB_SOURCE_FONT:
 							img = IMB_thumb_load_font(file_path, tsize, tsize);
@@ -464,13 +467,13 @@ static ImBuf *thumb_create_ex(
 
 static ImBuf *thumb_create_or_fail(
         const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash,
-        ThumbSize size, ThumbSource source)
+        const char *blen_group, const char *blen_id, ThumbSize size, ThumbSource source)
 {
-	ImBuf *img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, size, source, NULL);
+	ImBuf *img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL);
 
 	if (!img) {
 		/* thumb creation failed, write fail thumb */
-		img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, THB_FAIL, source, NULL);
+		img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL);
 		if (img) {
 			/* we don't need failed thumb anymore */
 			IMB_freeImBuf(img);
@@ -489,7 +492,7 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im
 	uri_from_filename(path, uri);
 	thumbname_from_uri(uri, thumb_name, sizeof(thumb_name));
 
-	return thumb_create_ex(path, uri, thumb_name, false, THUMB_DEFAULT_HASH, size, source, img);
+	return thumb_create_ex(path, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img);
 }
 
 /* read thumbnail for file and returns new imbuf for thumbnail */
@@ -535,12 +538,25 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 	char thumb_path[FILE_MAX];
 	char thumb_name[40];
 	char uri[URI_MAX];
+	char path_buff[FILE_MAX];
 	const char *file_path;
 	const char *path;
 	BLI_stat_t st;
 	ImBuf *img = NULL;
+	char *blen_group = NULL, *blen_id = NULL;
 
 	path = file_path = org_path;
+	if (source == THB_SOURCE_BLEND) {
+		if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
+			if (blen_group) {
+				if (!blen_id) {
+					/* No preview for blen groups */
+					return NULL;
+				}
+				file_path = path_buff;  /* path needs to be a valid file! */
+			}
+		}
+	}
 
 	if (BLI_stat(file_path, &st) == -1) {
 		return NULL;
@@ -551,7 +567,7 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 	if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) {
 		/* failure thumb exists, don't try recreating */
 		if (BLI_exists(thumb_path)) {
-			/* clear out of date fail case */
+			/* clear out of date fail case (note for blen IDs we use blender file itself here) */
 			if (BLI_file_older(thumb_path, file_path)) {
 				BLI_delete(thumb_path, false, false);
 			}
@@ -600,14 +616,16 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source
 					IMB_thumb_delete(path, THB_NORMAL);
 					IMB_thumb_delete(path, THB_LARGE);
 					IMB_thumb_delete(path, THB_FAIL);
-					img = thumb_create_or_fail(file_path, uri, thumb_name, use_hash, thumb_hash, size, source);
+					img = thumb_create_or_fail(
+					          file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
 				}
 			}
 			else {
 				char thumb_hash[33];
 				const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
 
-				img = thumb_create_or_fail(file_path, uri, thumb_name, use_hash, thumb_hash, size, source);
+				img = thumb_create_or_fail(
+				          file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
 			}
 		}
 	}
diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c
index d7b9089..17d9f3d 100644
--- a/source/blender/imbuf/intern/thumbs_blend.c
+++ b/source/blender/imbuf/intern/thumbs_blend.c
@@ -25,6 +25,7 @@
  */
 
 
+#include <stdlib.h>
 #include <string.h>
 
 #include "zlib.h"
@@ -32,10 +33,16 @@
 #include "BLI_utildefines.h"
 #include "BLI_endian_switch.h"
 #include "BLI_fileops.h"
+#include "BLI_linklist.h"
 
 #include "BLO_blend_defs.h"
+#include "BLO_readfile.h"
 
 #include "BKE_global.h"
+#include "BKE_idcode.h"
+#include "BKE_icons.h"
+
+#include "DNA_ID.h"  /* For preview images... */
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -121,22 +128,76 @@ static ImBuf *loadblend_thumb(gzFile gzfile)
 	return NULL;
 }
 
-ImBuf *IMB_thumb_load_blend(const char *path)
+ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id)
 {
-	gzFile gzfile;
-	/* not necessarily a gzip */
-	gzfile = BLI_gzopen(path, "rb");
+	if (blen_group && blen_id) {
+		LinkNode *ln, *names, *lp, *previews = NULL;
+		struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, NULL);
+		ImBuf *ima = NULL;
+		int idcode = BKE_idcode_from_name(blen_group);
+		int i, nprevs, nnames;
 
-	if (NULL == gzfile) {
-		return NULL;
+		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, &nnames);
+		previews = BLO_blendhandle_get_previews(libfiledata, idcode, &nprevs);
+
+		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_free(names, free);
+			return ima;
+		}
+
+		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) {
+					unsigned int w = img->w[ICON_SIZE_PREVIEW];
+					unsigned int h = img->h[ICON_SIZE_PREVIEW];
+					unsigned int *rect = img->rect[ICON_SIZE_PREVIEW];
+
+					if (w > 0 && h > 0 && rect) {
+						/* first allocate imbuf for copying preview into it */
+						ima = IMB_allocImBuf(w, h, 32, IB_rect);
+						memcpy(ima->rect, rect, w * h * sizeof(unsigned int));
+					}
+				}
+				break;
+			}
+		}
+
+		BLI_linklist_free(previews, BKE_previewimg_freefunc);
+		BLI_linklist_free(names, free);
+		return ima;
 	}
 	else {
-		ImBuf *img = loadblend_thumb(gzfile);
+		gzFile gzfile;
+		/* not necessarily a gzip */
+		gzfile = BLI_gzopen(blen_path, "rb");
 
-		/* read ok! */
-		gzclose(gzfile);
+		if (NULL == gzfile) {
+			return NULL;
+		}
+		else {
+			ImBuf *img = loadblend_thumb(gzfile);
 
-		return img;
+			/* read ok! */
+			gzclose(gzfile);
+
+			return img;
+		}
 	}
 }




More information about the Bf-blender-cvs mailing list