forked from bartvdbraak/blender
simplify thumbnail reading and remove some warnings
This commit is contained in:
parent
71c22fefea
commit
4cc05dfc1b
@ -25,57 +25,54 @@ To run automatically with nautilus:
|
|||||||
gconftool --type string --set /desktop/gnome/thumbnailers/application@x-blender/command "blender-thumbnailer.py %i %o"
|
gconftool --type string --set /desktop/gnome/thumbnailers/application@x-blender/command "blender-thumbnailer.py %i %o"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import struct
|
import struct
|
||||||
import sys
|
|
||||||
|
|
||||||
def blend_extract_thumb(path):
|
def blend_extract_thumb(path):
|
||||||
|
import os
|
||||||
|
|
||||||
# def MAKE_ID(tag): ord(tag[0])<<24 | ord(tag[1])<<16 | ord(tag[2])<<8 | ord(tag[3])
|
# def MAKE_ID(tag): ord(tag[0])<<24 | ord(tag[1])<<16 | ord(tag[2])<<8 | ord(tag[3])
|
||||||
REND = 1145980242 # MAKE_ID(b'REND')
|
REND = 1145980242 # MAKE_ID(b'REND')
|
||||||
TEST = 1414743380 # MAKE_ID(b'TEST')
|
TEST = 1414743380 # MAKE_ID(b'TEST')
|
||||||
|
|
||||||
blendfile = open(path, 'rb')
|
blendfile = open(path, 'rb')
|
||||||
|
|
||||||
head = blendfile.read(7)
|
head = blendfile.read(12)
|
||||||
|
|
||||||
if head[0:2] == b'\x1f\x8b': # gzip magic
|
if head[0:2] == b'\x1f\x8b': # gzip magic
|
||||||
import gzip
|
import gzip
|
||||||
blendfile.close()
|
blendfile.close()
|
||||||
blendfile = gzip.open(path, 'rb')
|
blendfile = gzip.open(path, 'rb')
|
||||||
head = blendfile.read(7)
|
head = blendfile.read(12)
|
||||||
|
|
||||||
if head != b'BLENDER':
|
if not head.startswith(b'BLENDER'):
|
||||||
blendfile.close()
|
blendfile.close()
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
|
|
||||||
is_64_bit = (blendfile.read(1) == b'-')
|
is_64_bit = (head[7] == b'-')
|
||||||
|
|
||||||
# true for PPC, false for X86
|
# true for PPC, false for X86
|
||||||
is_big_endian = (blendfile.read(1) == b'V')
|
is_big_endian = (head[8] == b'V')
|
||||||
|
|
||||||
# Now read the bhead chunk!!!
|
# blender pre 2.5 had no thumbs
|
||||||
blendfile.read(3) # skip the version
|
if head[9:11] <= b'24':
|
||||||
|
return None, 0, 0
|
||||||
sizeof_pointer = 8 if is_64_bit else 4
|
|
||||||
|
|
||||||
sizeof_bhead = 24 if is_64_bit else 20
|
sizeof_bhead = 24 if is_64_bit else 20
|
||||||
|
|
||||||
int_endian = '>i' if is_big_endian else '<i'
|
|
||||||
int_endian_pair = '>ii' if is_big_endian else '<ii'
|
int_endian_pair = '>ii' if is_big_endian else '<ii'
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
bhead = blendfile.read(sizeof_bhead)
|
||||||
code, length = struct.unpack(int_endian_pair, blendfile.read(8)) # 8 == sizeof(int) * 2
|
|
||||||
except IOError:
|
if len(bhead) < sizeof_bhead:
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
|
|
||||||
# finally read the rest of the bhead struct, pointer and 2 ints
|
code, length = struct.unpack(int_endian_pair, bhead[0:8]) # 8 == sizeof(int) * 2
|
||||||
blendfile.seek(sizeof_bhead - 8, os.SEEK_CUR)
|
|
||||||
|
|
||||||
if code == REND:
|
if code == REND:
|
||||||
blendfile.seek(length, os.SEEK_CUR)
|
blendfile.seek(length, os.SEEK_CUR)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
||||||
if code != TEST:
|
if code != TEST:
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
@ -86,12 +83,12 @@ def blend_extract_thumb(path):
|
|||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
|
|
||||||
length -= 8 # sizeof(int) * 2
|
length -= 8 # sizeof(int) * 2
|
||||||
|
|
||||||
if length != x * y * 4:
|
if length != x * y * 4:
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
|
|
||||||
image_buffer = blendfile.read(length)
|
image_buffer = blendfile.read(length)
|
||||||
|
|
||||||
if len(image_buffer) != length:
|
if len(image_buffer) != length:
|
||||||
return None, 0, 0
|
return None, 0, 0
|
||||||
|
|
||||||
@ -104,7 +101,7 @@ def write_png(buf, width, height):
|
|||||||
# reverse the vertical line order and add null bytes at the start
|
# reverse the vertical line order and add null bytes at the start
|
||||||
width_byte_4 = width * 4
|
width_byte_4 = width * 4
|
||||||
raw_data = b"".join([b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4)])
|
raw_data = b"".join([b'\x00' + buf[span:span + width_byte_4] for span in range((height - 1) * width * 4, -1, - width_byte_4)])
|
||||||
|
|
||||||
def png_pack(png_tag, data):
|
def png_pack(png_tag, data):
|
||||||
chunk_head = png_tag + data
|
chunk_head = png_tag + data
|
||||||
return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
|
return struct.pack("!I", len(data)) + chunk_head + struct.pack("!I", 0xFFFFFFFF & zlib.crc32(chunk_head))
|
||||||
@ -117,6 +114,8 @@ def write_png(buf, width, height):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
import sys
|
||||||
|
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
print("Expected 2 arguments <input.blend> <output.png>")
|
print("Expected 2 arguments <input.blend> <output.png>")
|
||||||
else:
|
else:
|
||||||
|
@ -195,7 +195,7 @@ static void id_search_cb(const bContext *C, void *arg_template, char *str, uiSea
|
|||||||
|
|
||||||
RNA_parameter_set_lookup(&parms, "context", &C);
|
RNA_parameter_set_lookup(&parms, "context", &C);
|
||||||
|
|
||||||
if (RNA_function_call(C, &reports, &ptr, func, &parms) == 0) {
|
if (RNA_function_call((bContext *)C, &reports, &ptr, func, &parms) == 0) {
|
||||||
int* ret;
|
int* ret;
|
||||||
RNA_parameter_get_lookup(&parms, "ret", (void **)&ret);
|
RNA_parameter_get_lookup(&parms, "ret", (void **)&ret);
|
||||||
|
|
||||||
|
@ -40,16 +40,14 @@
|
|||||||
|
|
||||||
static ImBuf *loadblend_thumb(gzFile gzfile)
|
static ImBuf *loadblend_thumb(gzFile gzfile)
|
||||||
{
|
{
|
||||||
char buf[8];
|
char buf[12];
|
||||||
int code= 0;
|
int bhead[24/sizeof(int)]; /* max size on 64bit */
|
||||||
char endian, pointer_size;
|
char endian, pointer_size;
|
||||||
char endian_switch;
|
char endian_switch;
|
||||||
int len, im_len, x, y;
|
int sizeof_bhead ;
|
||||||
ImBuf *img= NULL;
|
|
||||||
|
|
||||||
|
|
||||||
/* read the blend file header */
|
/* read the blend file header */
|
||||||
if(gzread(gzfile, buf, 8) != 8)
|
if(gzread(gzfile, buf, 12) != 12)
|
||||||
return NULL;
|
return NULL;
|
||||||
if(strncmp(buf, "BLENDER", 7))
|
if(strncmp(buf, "BLENDER", 7))
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -61,38 +59,23 @@ static ImBuf *loadblend_thumb(gzFile gzfile)
|
|||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* read the next 4 bytes, only need the first char, ignore the version */
|
sizeof_bhead = 16 + pointer_size;
|
||||||
/* endian and vertsion (ignored) */
|
|
||||||
if(gzread(gzfile, buf, 4) != 4)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if(buf[0]=='V')
|
if(buf[8]=='V')
|
||||||
endian= B_ENDIAN; /* big: PPC */
|
endian= B_ENDIAN; /* big: PPC */
|
||||||
else if(buf[0]=='v')
|
else if(buf[8]=='v')
|
||||||
endian= L_ENDIAN; /* little: x86 */
|
endian= L_ENDIAN; /* little: x86 */
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
while(gzread(gzfile, &code, sizeof(int)) == sizeof(int)) {
|
endian_switch = ((ENDIAN_ORDER != endian)) ? 1 : 0;
|
||||||
endian_switch = ((ENDIAN_ORDER != endian)) ? 1 : 0;
|
|
||||||
|
|
||||||
if(gzread(gzfile, buf, sizeof(int)) != sizeof(int))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
len = *( (int *)((void *)buf) );
|
|
||||||
|
|
||||||
|
while(gzread(gzfile, bhead, sizeof_bhead) == sizeof_bhead) {
|
||||||
if(endian_switch)
|
if(endian_switch)
|
||||||
SWITCH_INT(len);
|
SWITCH_INT(bhead[1]); /* length */
|
||||||
|
|
||||||
/* finally read the rest of the bhead struct, pointer and 2 ints */
|
if (bhead[0]==REND) {
|
||||||
if(gzread(gzfile, buf, pointer_size) != pointer_size)
|
gzseek(gzfile, bhead[1], SEEK_CUR); /* skip to the next */
|
||||||
return NULL;
|
|
||||||
if(gzread(gzfile, buf, sizeof(int) * 2) != sizeof(int) * 2)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* we dont actually care whats in the bhead */
|
|
||||||
if (code==REND) {
|
|
||||||
gzseek(gzfile, len, SEEK_CUR); /* skip to the next */
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
@ -100,35 +83,36 @@ static ImBuf *loadblend_thumb(gzFile gzfile)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* using 'TEST' since new names segfault when loading in old blenders */
|
/* using 'TEST' since new names segfault when loading in old blenders */
|
||||||
if(code != TEST)
|
if(bhead[0] == TEST) {
|
||||||
return NULL;
|
ImBuf *img= NULL;
|
||||||
|
int size[2];
|
||||||
|
|
||||||
if(gzread(gzfile, &x, sizeof(int)) != sizeof(int))
|
if(gzread(gzfile, size, sizeof(size)) != sizeof(size))
|
||||||
return NULL;
|
return NULL;
|
||||||
if(gzread(gzfile, &y, sizeof(int)) != sizeof(int))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
len -= sizeof(int) * 2;
|
if(endian_switch) {
|
||||||
|
SWITCH_INT(size[0]);
|
||||||
|
SWITCH_INT(size[1]);
|
||||||
|
}
|
||||||
|
/* length */
|
||||||
|
bhead[1] -= sizeof(int) * 2;
|
||||||
|
|
||||||
if(endian_switch) {
|
/* inconsistant image size, quit early */
|
||||||
SWITCH_INT(x);
|
if(bhead[1] != size[0] * size[1] * sizeof(int))
|
||||||
SWITCH_INT(y);
|
return NULL;
|
||||||
|
|
||||||
|
/* finally malloc and read the data */
|
||||||
|
img= IMB_allocImBuf(size[0], size[1], 32, IB_rect | IB_metadata, 0);
|
||||||
|
|
||||||
|
if(gzread(gzfile, img->rect, bhead[1]) != bhead[1]) {
|
||||||
|
IMB_freeImBuf(img);
|
||||||
|
img= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return img;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inconsistant image size, quit early */
|
return NULL;
|
||||||
im_len = x * y * sizeof(int);
|
|
||||||
if(im_len != len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* finally malloc and read the data */
|
|
||||||
img= IMB_allocImBuf(x, y, 32, IB_rect | IB_metadata, 0);
|
|
||||||
|
|
||||||
if(gzread(gzfile, img->rect, len) != len) {
|
|
||||||
IMB_freeImBuf(img);
|
|
||||||
img= NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return img;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImBuf *IMB_loadblend_thumb(const char *path)
|
ImBuf *IMB_loadblend_thumb(const char *path)
|
||||||
|
@ -103,6 +103,7 @@ static void rna_Controller_state_number_set(struct PointerRNA *ptr, const int va
|
|||||||
cont->state_mask = (1 << (value - 1));
|
cont->state_mask = (1 << (value - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* editable is set to false, comment for now. */
|
||||||
static void rna_Controller_state_get(PointerRNA *ptr, int *values)
|
static void rna_Controller_state_get(PointerRNA *ptr, int *values)
|
||||||
{
|
{
|
||||||
bController *cont= (bController *)ptr->data;
|
bController *cont= (bController *)ptr->data;
|
||||||
@ -113,7 +114,6 @@ static void rna_Controller_state_get(PointerRNA *ptr, int *values)
|
|||||||
values[i] = (cont->state_mask & (1<<i));
|
values[i] = (cont->state_mask & (1<<i));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* editable is set to false, comment for now. */
|
|
||||||
static void rna_Controller_state_set(PointerRNA *ptr, const int *values)
|
static void rna_Controller_state_set(PointerRNA *ptr, const int *values)
|
||||||
{
|
{
|
||||||
bController *cont= (bController *)ptr->data;
|
bController *cont= (bController *)ptr->data;
|
||||||
|
@ -689,14 +689,14 @@ void wm_autosave_location(char *filename)
|
|||||||
sprintf(pidstr, "%d.blend", abs(getpid()));
|
sprintf(pidstr, "%d.blend", abs(getpid()));
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// XXX Need to investigate how to handle default location of '/tmp/'
|
/* XXX Need to investigate how to handle default location of '/tmp/'
|
||||||
// This is a relative directory on Windows, and it may be
|
* This is a relative directory on Windows, and it may be
|
||||||
// found. Example:
|
* found. Example:
|
||||||
// Blender installed on D:\ drive, D:\ drive has D:\tmp\
|
* Blender installed on D:\ drive, D:\ drive has D:\tmp\
|
||||||
// Now, BLI_exists() will find '/tmp/' exists, but
|
* Now, BLI_exists() will find '/tmp/' exists, but
|
||||||
// BLI_make_file_string will create string that has it most likely on C:\
|
* BLI_make_file_string will create string that has it most likely on C:\
|
||||||
// through get_default_root().
|
* through get_default_root().
|
||||||
// If there is no C:\tmp autosave fails.
|
* If there is no C:\tmp autosave fails. */
|
||||||
if (!BLI_exists(U.tempdir)) {
|
if (!BLI_exists(U.tempdir)) {
|
||||||
savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
|
savedir = BLI_get_folder_create(BLENDER_USER_AUTOSAVE, NULL);
|
||||||
BLI_make_file_string("/", filename, savedir, pidstr);
|
BLI_make_file_string("/", filename, savedir, pidstr);
|
||||||
|
@ -2702,7 +2702,7 @@ int WM_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
|
|||||||
float dist;
|
float dist;
|
||||||
double new_value = RNA_float_get(op->ptr, "new_value");
|
double new_value = RNA_float_get(op->ptr, "new_value");
|
||||||
int ret = OPERATOR_RUNNING_MODAL;
|
int ret = OPERATOR_RUNNING_MODAL;
|
||||||
float initial_value = RNA_float_get(op->ptr, "initial_value");
|
// float initial_value = RNA_float_get(op->ptr, "initial_value");
|
||||||
|
|
||||||
mode = RNA_int_get(op->ptr, "mode");
|
mode = RNA_int_get(op->ptr, "mode");
|
||||||
RNA_int_get_array(op->ptr, "initial_mouse", initial_mouse);
|
RNA_int_get_array(op->ptr, "initial_mouse", initial_mouse);
|
||||||
|
Loading…
Reference in New Issue
Block a user