mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-17 21:48:19 +00:00
102 lines
2.5 KiB
Python
102 lines
2.5 KiB
Python
|
import struct, zlib, sys
|
||
|
|
||
|
class image:
|
||
|
w = 0
|
||
|
h = 0
|
||
|
data = []
|
||
|
|
||
|
def read_tga(f):
|
||
|
image = f.read()
|
||
|
img_type = struct.unpack("<B", image[2:3])[0]
|
||
|
img_bpp = struct.unpack("<B", image[16:17])[0]
|
||
|
img_width = struct.unpack("<H", image[12:14])[0]
|
||
|
img_height = struct.unpack("<H", image[14:16])[0]
|
||
|
|
||
|
if img_type != 2 or img_bpp != 32:
|
||
|
print "image must be a RGBA"
|
||
|
|
||
|
start = 18+struct.unpack("B", image[0])[0]
|
||
|
end = start + img_width*img_height*4
|
||
|
image_data = image[start:end] # fetch raw data
|
||
|
return image_data
|
||
|
|
||
|
def write_tga(f, w, h, bpp, data):
|
||
|
f.write(struct.pack("<BBBHHBHHHHBB", 0, 0, 2, 0, 0, 0, 0, 0, w, h, bpp, 0) + data)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
def load_png(f):
|
||
|
def read(fmt): return struct.unpack("!"+fmt, f.read(struct.calcsize("!"+fmt)))
|
||
|
def skip(count): f.read(count)
|
||
|
|
||
|
# read signature
|
||
|
if read("cccccccc") != ('\x89', 'P', 'N', 'G', '\r', '\n', '\x1a', '\n'):
|
||
|
return 0
|
||
|
|
||
|
# read chunks
|
||
|
width = -1
|
||
|
height = -1
|
||
|
imagedata = ""
|
||
|
while 1:
|
||
|
size, id = read("I4s")
|
||
|
if id == "IHDR": # read header
|
||
|
width, height, bpp, colortype, compression, filter, interlace = read("IIBBBBB")
|
||
|
if bpp != 8 or compression != 0 or filter != 0 or interlace != 0 or (colortype != 2 and colortype != 6):
|
||
|
print "can't handle png of this type"
|
||
|
print width, height, bpp, colortype, compression, filter, interlace
|
||
|
return 0
|
||
|
skip(4)
|
||
|
elif id == "IDAT":
|
||
|
imagedata += f.read(size)
|
||
|
skip(4) # read data
|
||
|
elif id == "IEND":
|
||
|
break # we are done! \o/
|
||
|
else:
|
||
|
skip(size+4) # skip unknown chunks
|
||
|
|
||
|
# decompress image data
|
||
|
rawdata = map(ord, zlib.decompress(imagedata))
|
||
|
|
||
|
# apply per scanline filters
|
||
|
pitch = width*4+1
|
||
|
bpp = 4
|
||
|
imgdata = []
|
||
|
prevline = [0 for x in xrange(0, (width+1)*bpp)]
|
||
|
for y in xrange(0,height):
|
||
|
filter = rawdata[pitch*y]
|
||
|
pixeldata = rawdata[pitch*y+1:pitch*y+pitch]
|
||
|
thisline = [0 for x in xrange(0,bpp)]
|
||
|
def paeth(a, b, c):
|
||
|
p = a + b - c
|
||
|
pa = abs(p - a)
|
||
|
pb = abs(p - b)
|
||
|
pc = abs(p - c)
|
||
|
if pa <= pb and pa <= pc:
|
||
|
return a
|
||
|
if pb <= pc:
|
||
|
return b
|
||
|
return c
|
||
|
|
||
|
if filter == 0: f = lambda a,b,c: 0
|
||
|
elif filter == 1: f = lambda a,b,c: a
|
||
|
elif filter == 2: f = lambda a,b,c: b
|
||
|
elif filter == 3: f = lambda a,b,c: (a+b)/2
|
||
|
elif filter == 4: f = paeth
|
||
|
|
||
|
for x in xrange(0, width*bpp):
|
||
|
thisline += [(pixeldata[x] + f(thisline[x], prevline[x+bpp], prevline[x])) % 256]
|
||
|
|
||
|
prevline = thisline
|
||
|
imgdata += thisline[4:]
|
||
|
|
||
|
raw = ""
|
||
|
for x in imgdata:
|
||
|
raw += struct.pack("B", x)
|
||
|
|
||
|
#print len(raw), width*height*4
|
||
|
write_tga(file("test2.tga", "w"), width, height, 32, raw)
|
||
|
return 0
|
||
|
|
||
|
load_png(file("butterfly2.png", "rb"))
|