diff options
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r-- | source/blender/imbuf/IMB_thumbs.h | 7 | ||||
-rw-r--r-- | source/blender/imbuf/intern/thumbs.c | 25 | ||||
-rw-r--r-- | source/blender/imbuf/intern/thumbs_blend.c | 122 |
3 files changed, 144 insertions, 10 deletions
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index c7e39b9e0d7..ecb0ba8abd1 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -50,13 +50,14 @@ typedef enum ThumbSize { typedef enum ThumbSource { THB_SOURCE_IMAGE, - THB_SOURCE_MOVIE + THB_SOURCE_MOVIE, + THB_SOURCE_BLEND } ThumbSource; // IB_metadata /* create thumbnail for file and returns new imbuf for thumbnail */ -ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source); +ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source, ImBuf *ibuf); /* read thumbnail for file and returns new imbuf for thumbnail */ ImBuf* IMB_thumb_read(const char* path, ThumbSize size); @@ -70,6 +71,8 @@ ImBuf* IMB_thumb_manage(const char* path, ThumbSize size, ThumbSource source); /* create the necessary dirs to store the thumbnails */ void IMB_thumb_makedirs(); +/* special function for loading a thumbnail embedded into a blend file */ +ImBuf *IMB_loadblend_thumb(const char *path); #endif /* _IMB_THUMBS_H */ diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 45fbf49dbbd..8c75f5ab1ab 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -241,9 +241,8 @@ void IMB_thumb_makedirs() } /* create thumbnail for file and returns new imbuf for thumbnail */ -ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source) +ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source, ImBuf *img) { - ImBuf *img = 0; char uri[URI_MAX]; char desc[URI_MAX+22]; char tpath[FILE_MAX]; @@ -285,8 +284,18 @@ ImBuf* IMB_thumb_create(const char* path, ThumbSize size, ThumbSource source) img = IMB_allocImBuf(0,0,32, IB_rect | IB_metadata, 0); if (!img) return 0; } else { - if (THB_SOURCE_IMAGE == source) { - img = IMB_loadiffname(path, IB_rect | IB_metadata); + if (THB_SOURCE_IMAGE == source || THB_SOURCE_BLEND == source) { + + /* only load if we didnt give an image */ + if(img==NULL) { + if(THB_SOURCE_BLEND == source) { + img = IMB_loadblend_thumb(path); + } + else { + img = IMB_loadiffname(path, IB_rect | IB_metadata); + } + } + if (img != NULL) { stat(path, &info); sprintf(mtime, "%ld", info.st_mtime); @@ -425,10 +434,10 @@ ImBuf* IMB_thumb_manage(const char* path, ThumbSize size, ThumbSource source) IMB_thumb_delete(path, THB_NORMAL); IMB_thumb_delete(path, THB_LARGE); IMB_thumb_delete(path, THB_FAIL); - img = IMB_thumb_create(path, size, source); + img = IMB_thumb_create(path, size, source, NULL); if(!img){ /* thumb creation failed, write fail thumb */ - img = IMB_thumb_create(path, THB_FAIL, source); + img = IMB_thumb_create(path, THB_FAIL, source, NULL); if (img) { /* we don't need failed thumb anymore */ IMB_freeImBuf(img); @@ -438,10 +447,10 @@ ImBuf* IMB_thumb_manage(const char* path, ThumbSize size, ThumbSource source) } } } else { - img = IMB_thumb_create(path, size, source); + img = IMB_thumb_create(path, size, source, NULL); if(!img){ /* thumb creation failed, write fail thumb */ - img = IMB_thumb_create(path, THB_FAIL, source); + img = IMB_thumb_create(path, THB_FAIL, source, NULL); if (img) { /* we don't need failed thumb anymore */ IMB_freeImBuf(img); diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c new file mode 100644 index 00000000000..f38975f1da1 --- /dev/null +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -0,0 +1,122 @@ +/** + * $Id: + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Campbell Barton. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <string.h> + +#include "zlib.h" + +#include "BKE_utildefines.h" +#include "BKE_global.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" +#include "IMB_thumbs.h" + +#include "MEM_guardedalloc.h" + +ImBuf *IMB_loadblend_thumb(const char *path) +{ + char buf[8]; + int code= 0; + char endian, pointer_size; + char endian_switch; + int len, im_len, x, y; + int *rect= NULL; + + gzFile gzfile; + + ImBuf *img; + + /* not necessarily a gzip */ + gzfile = gzopen(path, "rb"); + + if (NULL == gzfile ) { + return NULL; + } + + /* read the blend file header */ + if(gzread(gzfile, buf, 8) < 8) goto thumb_error; + if(strncmp(buf, "BLENDER", 7)) goto thumb_error; + + if(buf[7]=='-') pointer_size= 8; + else if(buf[7]=='_') pointer_size= 4; + else goto thumb_error; + + /* read the next 4 bytes, only need the first char, ignore the version */ + /* endian and vertsion (ignored) */ + if(gzread(gzfile, buf, 4) < 4) goto thumb_error; + + if(buf[0]=='V') endian= B_ENDIAN; /* big: PPC */ + else if(buf[0]=='v') endian= L_ENDIAN; /* little: x86 */ + else goto thumb_error; + + while(gzread(gzfile, &code, 4) == 4) { + endian_switch = ((ENDIAN_ORDER != endian)) ? 1 : 0; + + if(gzread(gzfile, buf, 4) < 4) goto thumb_error; + len = *( (int *)((void *)buf) ); + if(endian_switch) SWITCH_INT(len); + + /* finally read the rest of the bhead struct, pointer and 2 ints */ + if(gzread(gzfile, buf, pointer_size) < pointer_size) goto thumb_error; + if(gzread(gzfile, buf, 8) < 8) goto thumb_error; + /* we dont actually care whats in the bhead */ + + if (code==REND) { + gzseek(gzfile, len, SEEK_CUR); /* skip to the next */ + } + else { + break; + } + } + + /* using 'TEST' since new names segfault when loading in old blenders */ + if(code != TEST) goto thumb_error; + + /* finally malloc and read the data */ + rect= MEM_mallocN(len, "imb_loadblend_thumb"); + + if(gzread(gzfile, rect, len) < len) goto thumb_error; + + /* read ok! */ + gzclose(gzfile); + + x= rect[0]; y= rect[1]; + if(endian_switch) { SWITCH_INT(x); SWITCH_INT(y); } + + im_len = x * y * sizeof(int); + + img = IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata, 0); + + memcpy(img->rect, rect + 2, im_len); + + MEM_freeN(rect); + + return img; + +thumb_error: + gzclose(gzfile); + if(rect) MEM_freeN(rect); + return NULL; +} |