Python 的 DXT 压缩

Posted

技术标签:

【中文标题】Python 的 DXT 压缩【英文标题】:DXT Compression for Python 【发布时间】:2012-06-10 21:46:28 【问题描述】:

我目前正在处理图像,其中一些是 DXT 压缩的,我需要一种简单的方法来使用 Python 解压缩和压缩这些文件。不幸的是,我找不到任何可以为我做这件事的图书馆。

有没有人知道一个好的 库,或者一个压缩库的接口?

-- dav1d

编辑:

libsquish 是这里的方法,但不幸的是 Python 绑定不起作用,所以这里是解决方案。

在 C++ 中创建一个 squish-Wrapper,它导出内部访问 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);
    

创建一个动态库(windows上的dll,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

【问题讨论】:

【参考方案1】:

libSquish 拥有a patch to add Python bindings。

编辑:安装过程好像是

    下载squish-1.11.zip 解压并编译 - 应该会生成一个 libsquish.a 文件 下载并安装Cython(听起来像你这样做) 创建一个临时目录并“应用”补丁 - 它会丢弃一堆作为绑定代码的新文件 运行安装程序(sudo python setup.py install)

如果你这样做了但仍然有错误,那么也许你应该 (a) 分享实际的错误消息以便我们找出原因,或者 (b) 直接联系补丁作者 - 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。

【讨论】:

谢谢,请看一下xioxox的评论。 感谢您的努力,libsquish 是正确的提示,我会接受这个答案,我会编辑我的问题并解释我是如何做到的。【参考方案2】:

libsquish 有一些贡献的 python 绑定:http://code.google.com/p/libsquish/issues/detail?id=17 但是我没有使用它们。

【讨论】:

谢谢!我试过了,不幸的是它们不起作用。我安装了 Cython2 (Archlinux-Package) 并尝试使用 setup.py 但编译器给了我错误消息。

以上是关于Python 的 DXT 压缩的主要内容,如果未能解决你的问题,请参考以下文章

DXT 纹理压缩?

Unity ETC 压缩

OpenGL RGB DXT1压缩纹理mipmap上传

纹理压缩简介 DXT PVR ETC

dds后缀名的文件怎么打开

在硬件中高效实现 DXT1 纹理解压