From c61e25e6ac37296c13c0949b8363cc168125d750 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 May 2010 21:52:18 +0000 Subject: blend file thumbnailing - uses same thumbnail system as image browser - blend files show thumbnails in ubuntu/gnome (freedesktop spec) - 128x128 images are embedded into the blend file header, a simple loader avoids reading the entire blend file to extract it when generating thumbnails in the file selector. When the image browser reads a directory it loads images and creates thumbnails, blend files embedded images are treated just like loading an image. - the thumbnail is created from the camera view in solid mode. (no camera == no thumbnal). - readfile/writefile.c: had to use the 'TEST' code name to save thumbnails, anything else would segfault older blender versions on load. (its not used elsewhere). --- source/blender/blenloader/BLO_writefile.h | 4 +++- source/blender/blenloader/intern/readfile.c | 2 +- source/blender/blenloader/intern/writefile.c | 24 ++++++++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) (limited to 'source/blender/blenloader') diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h index a95e5867c7e..182c582cc0f 100644 --- a/source/blender/blenloader/BLO_writefile.h +++ b/source/blender/blenloader/BLO_writefile.h @@ -35,10 +35,12 @@ struct MemFile; struct Main; struct ReportList; -extern int BLO_write_file(struct Main *mainvar, char *dir, int write_flags, struct ReportList *reports); +extern int BLO_write_file(struct Main *mainvar, char *dir, int write_flags, struct ReportList *reports, int *thumb); extern int BLO_write_file_mem(struct Main *mainvar, struct MemFile *compare, struct MemFile *current, int write_flags, struct ReportList *reports); extern int BLO_write_runtime(struct Main *mainvar, char *file, char *exename, struct ReportList *reports); +#define BLEN_THUMB_SIZE 128 + #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 381fc868a0d..8dbf2682bb6 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -10971,7 +10971,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filename) switch(bhead->code) { case DATA: case DNA1: - case TEST: + case TEST: /* used as preview since 2.5x */ case REND: bhead = blo_nextbhead(fd, bhead); break; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5f2ee73e129..35fda1d8aa7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -62,6 +62,7 @@ Any case: direct data is ALWAYS after the lib block - write library block - per LibBlock - write the ID of LibBlock +- write TEST (128x128, blend file preview, optional) - write FileGlobal (some global vars) - write SDNA - write USER if filename is ~/.B.blend @@ -2390,9 +2391,19 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) writestruct(wd, GLOB, "FileGlobal", 1, &fg); } +/* preview image, first 2 values are width and height + * second are an RGBA image (unsigned char) + * note, this uses 'TEST' since new types will segfault on file load for older blender versions. + */ +static void write_thumb(WriteData *wd, int *img) +{ + if(img) + writedata(wd, TEST, (2 + img[0] * img[1]) * sizeof(int), img); +} + /* if MemFile * there's filesave to memory */ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFile *current, - int write_user_block, int write_flags) + int write_user_block, int write_flags, int *thumb) { BHead bhead; ListBase mainlist; @@ -2407,6 +2418,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil mywrite(wd, buf, 12); write_renderinfo(wd, mainvar); + write_thumb(wd, thumb); write_global(wd, write_flags, mainvar); /* no UI save in undo */ @@ -2458,7 +2470,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil } /* return: success (1) */ -int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *reports) +int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *reports, int *thumb) { char userfilename[FILE_MAXDIR+FILE_MAXFILE]; char tempname[FILE_MAXDIR+FILE_MAXFILE+1]; @@ -2497,7 +2509,7 @@ int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *report makeFilesRelative(dir, NULL); /* note, making relative to something OTHER then G.sce */ /* actual file writing */ - err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags); + err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags, thumb); close(file); /* rename/compress */ @@ -2550,7 +2562,7 @@ int BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int wr { int err; - err= write_file_handle(mainvar, 0, compare, current, 0, write_flags); + err= write_file_handle(mainvar, 0, compare, current, 0, write_flags, NULL); if(err==0) return 1; return 0; @@ -2646,7 +2658,7 @@ int BLO_write_runtime(Main *mainvar, char *file, char *exename, ReportList *repo outfd= open(gamename, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0777); if (outfd != -1) { - write_file_handle(mainvar, outfd, NULL,NULL, 0, G.fileflags); + write_file_handle(mainvar, outfd, NULL,NULL, 0, G.fileflags, NULL); if (write(outfd, " ", 1) != 1) { BKE_report(reports, RPT_ERROR, "Unable to write to output file."); @@ -2732,7 +2744,7 @@ int BLO_write_runtime(Main *mainvar, char *file, char *exename, ReportList *repo datastart= lseek(outfd, 0, SEEK_CUR); - write_file_handle(mainvar, outfd, NULL,NULL, 0, G.fileflags); + write_file_handle(mainvar, outfd, NULL,NULL, 0, G.fileflags, NULL); if (!handle_write_msb_int(outfd, datastart) || (write(outfd, "BRUNTIME", 8)!=8)) { BKE_report(reports, RPT_ERROR, "Unable to write to output file."); -- cgit v1.2.3