X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=blender_export.py;fp=blender_export.py;h=19e68f0b64c66cc37d8e87bb16d7e1214c129a1e;hb=b440efbe5785d114d08bb3f5ec0e09cad943006d;hp=b1e7677fb232cf5c071a74ff4cff5f6a26af3e21;hpb=81099ee81c1a09ead474333101408b7b8a4a94fc;p=carveJwlIkooP6JGAAIwe30JlM.git diff --git a/blender_export.py b/blender_export.py index b1e7677..19e68f0 100644 --- a/blender_export.py +++ b/blender_export.py @@ -1,5 +1,6 @@ -import bpy, blf, math, gpu, os +import bpy, blf, math, gpu, os, time import cProfile +import numpy as np from ctypes import * from mathutils import * from gpu_extras.batch import batch_for_shader @@ -4999,176 +5000,43 @@ def unregister(): bpy.types.SpaceView3D.draw_handler_remove(cv_view_pixel_handler,'WINDOW') #} -# ---------------------------------------------------------------------------- # -# # -# QOI encoder # -# # -# ---------------------------------------------------------------------------- # -# # -# Transliteration of: # -# https://github.com/phoboslab/qoi/blob/master/qoi.h # -# # -# Copyright (c) 2021, Dominic Szablewski - https://phoboslab.org # -# SPDX-License-Identifier: MIT # -# QOI - The "Quite OK Image" format for fast, lossless image compression # -# # -# ---------------------------------------------------------------------------- # - -class qoi_rgba_t(Structure): -#{ - _pack_ = 1 - _fields_ = [("r",c_uint8), - ("g",c_uint8), - ("b",c_uint8), - ("a",c_uint8)] -#} - -QOI_OP_INDEX = 0x00 # 00xxxxxx -QOI_OP_DIFF = 0x40 # 01xxxxxx -QOI_OP_LUMA = 0x80 # 10xxxxxx -QOI_OP_RUN = 0xc0 # 11xxxxxx -QOI_OP_RGB = 0xfe # 11111110 -QOI_OP_RGBA = 0xff # 11111111 - -QOI_MASK_2 = 0xc0 # 11000000 - -def qoi_colour_hash( c ): -#{ - return c.r*3 + c.g*5 + c.b*7 + c.a*11 -#} - -def qoi_eq( a, b ): -#{ - return (a.r==b.r) and (a.g==b.g) and (a.b==b.b) and (a.a==b.a) -#} - -def qoi_32bit( v ): -#{ - return bytearray([ (0xff000000 & v) >> 24, \ - (0x00ff0000 & v) >> 16, \ - (0x0000ff00 & v) >> 8, \ - (0x000000ff & v) ]) -#} +qoi_lib = None +qoi_encode_rgbaf32 = None +qoi_free = None def qoi_encode( img ): #{ - data = bytearray() + global qoi_lib + global qoi_encode_rgbaf32 + global qoi_free + if not qoi_lib: + #{ + ext = '.dll' if os.name=='nt' else '.so' + path = F'{os.path.dirname(__file__)}/qoi{ext}' + qoi_lib = cdll.LoadLibrary( path ) + qoi_encode_rgbaf32 = qoi_lib.qoi_encode_rgbaf32 + qoi_encode_rgbaf32.argtypes = \ + [ np.ctypeslib.ndpointer(dtype=np.float32,\ + ndim=1,\ + flags='C_CONTIGUOUS'), \ + c_uint32, c_uint32, POINTER(c_int32) ] + qoi_encode_rgbaf32.restype = POINTER(c_uint8) + + qoi_free = qoi_lib.qoi_free + qoi_free.argtypes = [ POINTER(c_uint8) ] + #} + print(F"{' ':<30}",end='\r') print(F"[QOI] Encoding {img.name}.qoi[{img.size[0]},{img.size[1]}]",end='\r') - index = [ qoi_rgba_t() for _ in range(64) ] - - # Header - # - data.extend( bytearray(c_uint32(0x66696f71)) ) - data.extend( qoi_32bit( img.size[0] ) ) - data.extend( qoi_32bit( img.size[1] ) ) - data.extend( bytearray(c_uint8(4)) ) - data.extend( bytearray(c_uint8(0)) ) - - run = 0 - px_prev = qoi_rgba_t() - px_prev.r = c_uint8(0) - px_prev.g = c_uint8(0) - px_prev.b = c_uint8(0) - px_prev.a = c_uint8(255) - - px = qoi_rgba_t() - px.r = c_uint8(0) - px.g = c_uint8(0) - px.b = c_uint8(0) - px.a = c_uint8(255) - - px_len = img.size[0] * img.size[1] - paxels = [ int(min(max(_,0),1)*255) for _ in img.pixels ] - - for px_pos in range( px_len ): #{ - idx = px_pos * img.channels - nc = img.channels-1 - - px.r = paxels[idx+min(0,nc)] - px.g = paxels[idx+min(1,nc)] - px.b = paxels[idx+min(2,nc)] - px.a = paxels[idx+min(3,nc)] - - if qoi_eq( px, px_prev ): #{ - run += 1 - - if (run == 62) or (px_pos == px_len-1): #{ - data.extend( bytearray( c_uint8(QOI_OP_RUN | (run-1))) ) - run = 0 - #} - #} - else: #{ - if run > 0: #{ - data.extend( bytearray( c_uint8(QOI_OP_RUN | (run-1))) ) - run = 0 - #} - - index_pos = qoi_colour_hash(px) % 64 - - if qoi_eq( index[index_pos], px ): #{ - data.extend( bytearray( c_uint8(QOI_OP_INDEX | index_pos)) ) - #} - else: #{ - index[ index_pos ].r = px.r - index[ index_pos ].g = px.g - index[ index_pos ].b = px.b - index[ index_pos ].a = px.a - - if px.a == px_prev.a: #{ - vr = int(px.r) - int(px_prev.r) - vg = int(px.g) - int(px_prev.g) - vb = int(px.b) - int(px_prev.b) - - vg_r = vr - vg - vg_b = vb - vg - - if (vr > -3) and (vr < 2) and\ - (vg > -3) and (vg < 2) and\ - (vb > -3) and (vb < 2): - #{ - op = QOI_OP_DIFF | (vr+2) << 4 | (vg+2) << 2 | (vb+2) - data.extend( bytearray( c_uint8(op) )) - #} - elif (vg_r > -9) and (vg_r < 8) and\ - (vg > -33) and (vg < 32 ) and\ - (vg_b > -9) and (vg_b < 8): - #{ - op = QOI_OP_LUMA | (vg+32) - delta = (vg_r+8) << 4 | (vg_b + 8) - data.extend( bytearray( c_uint8(op) ) ) - data.extend( bytearray( c_uint8(delta) )) - #} - else: #{ - data.extend( bytearray( c_uint8(QOI_OP_RGB) ) ) - data.extend( bytearray( c_uint8(px.r) )) - data.extend( bytearray( c_uint8(px.g) )) - data.extend( bytearray( c_uint8(px.b) )) - #} - #} - else: #{ - data.extend( bytearray( c_uint8(QOI_OP_RGBA) ) ) - data.extend( bytearray( c_uint8(px.r) )) - data.extend( bytearray( c_uint8(px.g) )) - data.extend( bytearray( c_uint8(px.b) )) - data.extend( bytearray( c_uint8(px.a) )) - #} - #} - #} - - px_prev.r = px.r - px_prev.g = px.g - px_prev.b = px.b - px_prev.a = px.a - #} - - # Padding - for i in range(7): - data.extend( bytearray( c_uint8(0) )) - data.extend( bytearray( c_uint8(1) )) - bytearray_align_to( data, 16, b'\x00' ) + crab = np.asarray(img.pixels, dtype=np.float32) + cock = c_int() + comped = qoi_encode_rgbaf32( crab, img.size[0], img.size[1], byref(cock) ) + end = time.time() - return data + bingo = bytearray(comped[:cock.value]) + bytearray_align_to( bingo, 16, b'\x00' ) + qoi_free( comped ) + return bingo #}