I am currently working with Images and some are DXT compressed, I need a easy way of decompressing and compressing of these files with Python. Unfortunatly I was unable to find any library which does that for me.
Does anyone know a good DXT-Compression library for Python, or an interface to a compresion library?
-- dav1d
Edit:
libsquish was the way to go here, but unfortunatly the Python-Bindings don't work, so here the solution.
Make a squish-Wrapper in C++ which exports functions which internally access libsquish:
#include <squish.h>
typedef unsigned char u8;
extern "C" {
void CompressMasked( u8 const* rgba, int mask, void* block, int flags ) {
squish::CompressMasked(rgba, mask, block, flags);
}
void Compress( u8 const* rgba, void* block, int flags ) {
squish::Compress(rgba, block, flags);
}
void Decompress( u8* rgba, void const* block, int flags ) {
squish::Decompress(rgba, block, flags);
}
int GetStorageRequirements( int width, int height, int flags ) {
return squish::GetStorageRequirements(width, height, flags);
}
void CompressImage( u8 const* rgba, int width, int height, void* blocks, int flags ) {
squish::CompressImage(rgba, width, height, blocks, flags);
}
void DecompressImage( u8* rgba, int width, int height, void const* blocks, int flags ) {
squish::DecompressImage(rgba, width, height, blocks, flags);
}
}
Create a dynamic library (a dll on windows, or a so on linux, I called it libsquishc.so
) and open it with ctypes
.
My approach (just exports the functions I need):
from ctypes import CDLL, c_int, byref, create_string_buffer
import os.path
libsquish_path = os.path.join(os.path.split(os.path.abspath(__file__))[0], 'libsquishc.so')
libsquish = CDLL(libsquish_path)
DXT1 = 1 << 0
DXT3 = 1 << 1
DXT5 = 1 << 2
COLOR_ITERATIVE_CLUSTER_FIT = 1 << 8
COLOR_CLUSTER_FIT = 1 << 3
COLOR_RANGE_FIT = 1 << 4
WEIGHT_COLOR_BY_ALPHA = 1 << 7
GetStorageRequirements = libsquish.GetStorageRequirements
GetStorageRequirements.argtypes = [c_int, c_int, c_int]
GetStorageRequirements.restype = c_int
def compress_image(rgba, width, height, flags):
rgba = create_string_buffer(rgba)
c = GetStorageRequirements(width, height, flags)
buffer = create_string_buffer(c)
libsquish.Compress(byref(rgba), byref(buffer), c_int(flags))
return buffer.raw
def decompress_image(block, width, height, flags):
block = create_string_buffer(block)
c = width*height*4
rgba = create_string_buffer(c)
libsquish.DecompressImage(byref(rgba), c_int(width), c_int(height), byref(block), c_int(flags))
return rgba.raw
libSquish has a patch to add Python bindings.
Edit: Installation procedure seems to be
If you did this and still have errors then maybe you should (a) share the actual error messages so we can figure out why, or (b) contact the patch author directly - mat (at) kivy.org
Edit2: the compile error is short enough that I will include it here:
running install
running build
running build_ext
skipping 'squish.c' Cython extension (up-to-date)
building 'squish' extension
gcc -pthread -fno-strict-aliasing -march=i686 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -DNDEBUG -march=i686 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -fPIC -I.. -I/usr/include/python2.7 -c squish.c -o build/temp.linux-i686-2.7/squish.o
In file included from squish.c:274:0:
/usr/include/squish.h:32:1: error: unknown type name 'namespace'
/usr/include/squish.h:32:18: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
squish.c: In function '__pyx_pf_6squish_compressImage':
squish.c:790:22: error: 'squish' undeclared (first use in this function)
squish.c:790:22: note: each undeclared identifier is reported only once for each function it appears in
squish.c:790:28: error: expected ';' before ':' token
squish.c:866:10: error: expected expression before ':' token
squish.c: In function '__pyx_pf_6squish_2decompressImage':
squish.c:1202:10: error: expected expression before ':' token
error: command 'gcc' failed with exit status 1
The relevant section of squish.h looks like
#ifndef SQUISH_H
#define SQUISH_H
//! All squish API functions live in this namespace.
namespace squish {
// -----------------------------------------------------------------------------
and it looks like it's choking on the namespace
keyword, which I'd say means it's compiling as C when it should be compiled as C++.