| # basic_test.py |
| import sys |
| sys.path.append("basisu_py") # make sure Python can load the .so |
| |
| import basisu_python as bu |
| from constants import * |
| |
| import ctypes |
| import math |
| |
| def generate_swirl_rgba8(width, height): |
| """ |
| Generate a smooth colorful swirl procedural RGBA8 test image. |
| Returns: a ctypes array of type (c_ubyte * (width * height * 4)) |
| """ |
| pixel_count = width * height * 4 |
| img = (ctypes.c_ubyte * pixel_count)() |
| |
| for y in range(height): |
| for x in range(width): |
| i = (y * width + x) * 4 |
| |
| dx = x - width / 2 |
| dy = y - height / 2 |
| |
| dist = math.hypot(dx, dy) |
| angle = math.atan2(dy, dx) |
| |
| # Color swirl pattern |
| r = int((math.sin(dist * 0.15) * 0.5 + 0.5) * 255) |
| g = int((math.sin(angle * 3.0) * 0.5 + 0.5) * 255) |
| b = int((math.cos(dist * 0.10 + angle * 2.0) * 0.5 + 0.5) * 255) |
| |
| img[i + 0] = r & 255 |
| img[i + 1] = g & 255 |
| img[i + 2] = b & 255 |
| img[i + 3] = 255 |
| |
| return img |
| |
| def generate_test_pattern_rgba8(width, height): |
| """ |
| Generate a simple deterministic RGBA8 test pattern: |
| R = x |
| G = y |
| B = x^y |
| A = 255 |
| """ |
| import ctypes |
| |
| pixel_count = width * height * 4 |
| img = (ctypes.c_ubyte * pixel_count)() |
| |
| for y in range(height): |
| for x in range(width): |
| i = (y * width + x) * 4 |
| |
| img[i + 0] = x & 0xFF |
| img[i + 1] = y & 0xFF |
| img[i + 2] = (x ^ y) & 0xFF |
| img[i + 3] = 255 |
| |
| return img |
| |
| # ------------------------------------------------------------ |
| # BasisU compression test (NATIVE C++) |
| # ------------------------------------------------------------ |
| |
| print("Native BasisU version:", bu.get_version()) |
| bu.init() |
| |
| # Create comp params |
| params = bu.new_params() |
| print("Params handle:", params) |
| |
| # Create RGBA8 swirl (64 x 64) |
| W, H = 512, 512 |
| pixel_count = W * H * 4 |
| |
| # Generate swirl image in PYTHON memory |
| |
| img = generate_swirl_rgba8(W, H) |
| #img = generate_test_pattern_rgba8(W, H) |
| |
| # Allocate memory inside NATIVE C++ heap |
| img_ptr = bu.alloc(pixel_count) |
| |
| # Copy Python swirl image ? C++ heap buffer |
| ctypes.memmove(img_ptr, img, pixel_count) |
| |
| # Set into BasisU |
| pitch = W * 4 |
| ok = bu.set_image_rgba32(params, 0, img_ptr, W, H, pitch) |
| print("Set image:", ok) |
| |
| # Compress (UASTC LDR 4x4 = 1) |
| ok = bu.compress( |
| params, |
| BasisTexFormat.cASTC_LDR_4x4, # basis_tex_format |
| BasisQuality.MAX, # quality |
| BasisEffort.DEFAULT, # effort |
| BasisFlags.KTX2_OUTPUT | BasisFlags.SRGB | BasisFlags.THREADED | BasisFlags.DEBUG_OUTPUT | BasisFlags.VERBOSE, # flags |
| 0.0 # rdo |
| ) |
| print("Compress:", ok) |
| |
| # Retrieve compressed data |
| size = bu.get_comp_data_size(params) |
| ofs = bu.get_comp_data_ofs(params) |
| |
| print("Output size =", size, "ptr =", ofs) |
| |
| # Copy bytes out of native memory |
| byte_ptr = ctypes.cast(ofs, ctypes.POINTER(ctypes.c_ubyte)) |
| blob = bytes(byte_ptr[i] for i in range(size)) |
| |
| print("First 16 bytes:", blob[:16]) |
| |
| # Save to KTX2 |
| with open("out_native.ktx2", "wb") as f: |
| f.write(blob) |
| |
| print("Saved out_native.ktx2") |
| |
| # Cleanup |
| bu.delete_params(params) |
| bu.free(img_ptr) |