Сжатие DXT для Python
В настоящее время я работаю с изображениями, и некоторые из них сжаты DXT, мне нужен простой способ распаковки и сжатия этих файлов с помощью Python. К сожалению, я не смог найти ни одной библиотеки, которая сделала бы это для меня.
Кто-нибудь знает хорошую библиотеку DXT-Compression для Python или интерфейс к библиотеке сжатия?
- dav1d
Редактировать:
libsquish был подходом, но, к сожалению, Python-Bindings не работают, поэтому здесь решение.
Создайте squish-Wrapper в C++, который экспортирует функции, которые имеют внутренний доступ к 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);
}
}
Создать динамическую библиотеку (DLL на Windows, или так на Linux, я назвал это libsquishc.so
) и откройте его ctypes
,
Мой подход (просто экспортирует нужные мне функции):
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
2 ответа
В libSquish есть патч для добавления привязок Python.
Изменить: процедура установки, кажется,
- скачать squish-1.11.zip
- распаковать и скомпилировать - должен привести к файлу libsquish.a
- скачать и установить Cython (похоже, что вы сделали это)
- создать временный каталог и "применить" патч - он сбрасывает кучу новых файлов, которые являются кодом привязки
- запустить установку (sudo python setup.py install)
Если вы сделали это и у вас все еще есть ошибки, то, возможно, вам следует (а) поделиться реальными сообщениями об ошибках, чтобы мы могли выяснить, почему, или (б) связаться с автором патча напрямую - mat (at) kivy.org
Edit2: ошибка компиляции достаточно коротка, чтобы я включил ее здесь:
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
Соответствующий раздел squish.h выглядит так
#ifndef SQUISH_H
#define SQUISH_H
//! All squish API functions live in this namespace.
namespace squish {
// -----------------------------------------------------------------------------
и похоже, что он задыхается namespace
Ключевое слово, которое я бы сказал, означает, что он компилируется как C, когда он должен быть скомпилирован как C++.
У libsquish есть некоторые привязанные к Python привязки: http://code.google.com/p/libsquish/issues/detail?id=17 я их не использовал.