#!/usr/bin/env python
# /*
# (c) 2013 +++ Filip Stoklas, aka FipS, http://www.4FipS.com +++
# THIS CODE IS FREE - LICENSED UNDER THE MIT LICENSE
# ARTICLE URL: http://forums.4fips.com/viewtopic.php?f=3&t=1071
# */
import ctypes as ct
import png
class Texture_format8:
Rgb = 0
Rgba = 1
class c_Blob(ct.Structure):
_fields_ = [
("tag", ct.c_uint8 * 4),
("size", ct.c_uint32)
]
class c_Block(ct.Structure):
_fields_ = [
("size", ct.c_uint32),
("offset", ct.c_uint32)
]
class c_Header(ct.Structure):
_fields_ = [
("version", ct.c_uint8),
("reserved0", ct.c_uint8),
("reserved1", ct.c_uint8),
("format", ct.c_uint8),
("width", ct.c_uint32),
("height", ct.c_uint32),
("size", ct.c_uint32)
]
def c_Data_factory(size):
"""Parametrized by 'size'."""
class c_Data(ct.Structure):
_fields_ = [
("data", ct.c_uint8 * size)
]
return c_Data
def c_Texture_factory(c_Data):
"""Parametrized by 'c_Data'."""
class c_Texture(ct.Structure):
_fields_ = [
("blob", c_Blob),
("header_block", c_Block),
("data_block", c_Block),
("header", c_Header),
("data", c_Data)
]
return c_Texture
def create_texture(width, height, format, pixels):
c_Data = c_Data_factory(len(pixels))
c_Texture = c_Texture_factory(c_Data)
return c_Texture(
c_Blob(tuple([ord(x) for x in "TEX!"]), ct.sizeof(c_Texture)), # blob [tag, size]
c_Block(ct.sizeof(c_Header), c_Texture.header.offset), # header_block [size, offset]
c_Block(ct.sizeof(c_Data), c_Texture.data.offset), # data_block [size, offset]
c_Header(
1, # version
0, # reserved0
0, # reserved1
format,
width,
height,
len(pixels) # size
),
c_Data(tuple(pixels))
)
def load_image(fname):
r = png.Reader(fname)
width, height, pixels, meta = r.read_flat()
bitdepth = meta["bitdepth"]
assert bitdepth == 8
planes = meta["planes"]
assert planes == 3 or planes == 4
format = Texture_format8.Rgb if planes == 3 else Texture_format8.Rgba
return width, height, format, pixels
def save_texture(texture, fname):
with open(fname, "wb") as f:
f.write(texture)
def main():
width, height, format, pixels = load_image("texture.png")
texture = create_texture(width, height, format, pixels)
save_texture(texture, "texture.blob")
main()