removed some unused WiiPy stuff (drops PIL dependency/Qwad now runs fine on Python3)

This commit is contained in:
Christopher Roy Bratusek 2012-11-10 18:06:55 +01:00
parent 8345dcc36a
commit e300653b3a
5 changed files with 1 additions and 987 deletions

View File

@ -4,7 +4,6 @@ from common import *
from formats import * from formats import *
from title import * from title import *
from disc import * from disc import *
from image import *
from archive import * from archive import *
from export import * from export import *
from compression import * from compression import *

View File

@ -1,182 +0,0 @@
from Struct import *
from pyglet import clock, window, image
from pyglet.gl import *
import cStringIO
import math
from time import time
class THP():
class THPHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.string(4)
self.version = Struct.uint32
self.bufSize = Struct.uint32
self.audioMaxSamples = Struct.uint32
self.frameRate = Struct.float
self.numFrames = Struct.uint32
self.firstFrameSize = Struct.uint32
self.movieDataSize = Struct.uint32
self.compInfoDataOffsets = Struct.uint32
self.offsetDataOffsets = Struct.uint32 #Offset to a offset table, containing offsets to each frame, this allows for starting playback from any frame. If this is 0 then it does not exist.
self.movieDataOffsets = Struct.uint32
self.finalFrameDataOffsets = Struct.uint32
def __str__(self):
ret = "\n"
ret += "Magic: %s\n" % self.magic
ret += "Version: %d.%d.%d\n" % (((self.version & 0xFFFF0000) >> 16), ((self.version & 0xFF00) >> 8), ((self.version & 0xFF)))
ret += "bufSize: %s\n" % self.bufSize
ret += "audioMaxSamples: %d\n" % self.audioMaxSamples
ret += "frameRate: %f\n" % self.frameRate
ret += "numFrames: %d\n" % self.numFrames
ret += "firstFrameSize: %d\n" % self.firstFrameSize
ret += "movieDataSize: %d\n" % self.movieDataSize
ret += "compInfoDataOffsets: 0x%08X\n" % self.compInfoDataOffsets
ret += "offsetDataOffsets: 0x%08X\n" % self.offsetDataOffsets
ret += "movieDataOffsets: 0x%08X\n" % self.movieDataOffsets
ret += "finalFrameDataOffsets: 0x%08X\n" % self.finalFrameDataOffsets
return ret
class THPFrameCompInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.numComponents = Struct.uint32
self.frameComp = Struct.uint8[16]
def __str__(self):
ret = ""
ret += "Number of Components: %d\n" % self.numComponents
return ret
class THPCompVideoInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.width = Struct.uint32
self.height = Struct.uint32
self.videoType = Struct.uint32
def __str__(self):
tempType = ("Non-Interlaced", "Interlaced", "Odd Interlace", "3", "Even Interlace")
ret = ""
ret += "Width: %d\n" % self.width
ret += "Height: %d\n" % self.height
ret += "VideoType: %s\n" % tempType[self.videoType]
return ret
class THPCompAudioInfo(Struct):
__endian__ = Struct.BE
def __format__(self):
self.sndChannels = Struct.uint32
self.sndFrequency = Struct.uint32
self.sndNumberSamples = Struct.uint32
self.sndNumberTracks = Struct.uint32
def __str__(self):
ret = ""
ret += "Channels: %d\n" % self.sndChannels
ret += "Frequency: %d\n" % self.sndFrequency
ret += "Samples: %d\n" % self.sndNumberSamples
ret += "Tracks: %d\n" % self.sndNumberTracks
return ret
class THPFrameHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.frameSizeNext = Struct.uint32
self.frameSizePrev = Struct.uint32
self.vidFileSize = Struct.uint32
self.sndFileSize = Struct.uint32
def __str__(self):
ret = ""
ret += "next Frame Size: %d\n" % self.frameSizeNext
ret += "previous Frame Size: %d\n" % self.frameSizePrev
ret += "Video frame data size: %d\n" % self.vidFileSize
ret += "Track file size: %d\n" % self.sndFileSize
return ret
def readData(self, fp, i=0):
self.frameImage = fp.read(self.vidFileSize)
#fileName = "frame%06d.jpg" % i
#open("out/" + fileName, 'w+b').write(self.frameImage)
#print "Frame: %d" % i
startTime = time()
start = self.frameImage.find('\xff\xda')
end = self.frameImage.rfind('\xff\xd9')
#print "find(%d): This took "%i, time()-startTime,start,end
startTime = time()
startStr = self.frameImage[:start+2]
endStr = self.frameImage[end:]
#print "extr(%d): This took "%i, time()-startTime
self.frameImage = self.frameImage[start+2:end]
self.frameImage = startStr + self.frameImage.replace('\xff','\xff\x00') + endStr
#print self.frameImage
return cStringIO.StringIO(self.frameImage)
def __init__(self, movieFile=None):
if(movieFile==None):
print "Usage: python thp.py filename.thp"
exit(-1)
fp = file(movieFile, 'rb')
HEADER = self.THPHeader()
HEADER.unpack(fp.read(len(HEADER)))
print HEADER
fp.seek(HEADER.compInfoDataOffsets)
CompInfo = self.THPFrameCompInfo()
CompInfo.unpack(fp.read(len(CompInfo)))
print CompInfo
for i in range(0, CompInfo.numComponents):
if(CompInfo.frameComp[i] == 0):
VideoInfo = self.THPCompVideoInfo()
VideoInfo.unpack(fp.read(len(VideoInfo)))
print VideoInfo
if(CompInfo.frameComp[i] == 1):
AudioInfo = self.THPCompAudioInfo()
AudioInfo.unpack(fp.read(len(AudioInfo)))
print AudioInfo
clock.set_fps_limit(HEADER.frameRate)
currOff = HEADER.movieDataOffsets
currSize = HEADER.firstFrameSize
fp.seek(currOff)
win = window.Window(VideoInfo.width, VideoInfo.height)
fps_display = clock.ClockDisplay()
i = 1
j = 1
image_index = 0
image_period = 1.0 / HEADER.frameRate # Reciprocal of the frame rate
remained = 0
while not win.has_exit:
win.dispatch_events()
win.clear()
dt = clock.tick()
skip = math.floor((dt+remained)/image_period)
j += skip
print skip, ":break:", i, j, skip
remained = dt - skip * image_period
tempFrame = self.THPFrameHeader()
tempFrame.unpack(fp.read(len(tempFrame)))
for xx in range(1,skip):
currOff = currOff+currSize
currSize = tempFrame.frameSizeNext
fp.seek(currOff)
tempFrame = self.THPFrameHeader()
tempFrame.unpack(fp.read(len(tempFrame)))
imagedat = tempFrame.readData(fp, i)
pic = image.load("image.jpg",imagedat)
pic.blit(0,0)
currOff = currOff+currSize
currSize = tempFrame.frameSizeNext
fp.seek(currOff)
fps_display.draw()
win.flip()
i += 1
if __name__=='__main__':
THP(*sys.argv[1:])

View File

@ -1,6 +1,5 @@
from common import * from common import *
from title import * from title import *
from image import *
class Savegame(): class Savegame():
class savegameHeader(Struct): class savegameHeader(Struct):

View File

@ -1,802 +0,0 @@
#!/usr/bin/env python
from common import *
import wx
def flatten(myTuple):
if (len(myTuple) == 4):
return myTuple[0] << 0 | myTuple[1] << 8 | myTuple[2] << 16 | myTuple[3] << 24
else:
return myTuple[0] << 0 | myTuple[1] << 8 | myTuple[2] << 16 | 0xff << 24
def round_up(x, n):
left = x % n
return x + left
def avg(w0, w1, c0, c1):
a0 = c0 >> 11
a1 = c1 >> 11
a = (w0*a0 + w1*a1) / (w0 + w1)
c = (a << 11) & 0xffff
a0 = (c0 >> 5) & 63
a1 = (c1 >> 5) & 63
a = (w0*a0 + w1*a1) / (w0 + w1)
c = c | ((a << 5) & 0xffff)
a0 = c0 & 31
a1 = c1 & 31
a = (w0*a0 + w1*a1) / (w0 + w1)
c = c | a
return c
class TPL():
"""This is the class to generate TPL texutres from PNG images, and to convert TPL textures to PNG images. The parameter file specifies the filename of the source, either a PNG image or a TPL image.
Currently supported are the following formats to convert from TPL (all formats): RGBA8, RGB565, RGB5A3, I4, IA4, I8, IA8, CI4, CI8, CMP, CI14X2.
Currently supported to convert to TPL: I4, I8, IA4, IA8, RBG565, RBGA8, RGB5A3. Currently not supported are CI4, CI8, CMP, CI14X2."""
class TPLHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.magic = Struct.uint32
self.ntextures = Struct.uint32
self.header_size = Struct.uint32
class TPLTexture(Struct):
__endian__ = Struct.BE
def __format__(self):
self.header_offset = Struct.uint32
self.palette_offset = Struct.uint32
class TPLTextureHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.height = Struct.uint16
self.width = Struct.uint16
self.format = Struct.uint32
self.data_off = Struct.uint32
self.wrap = Struct.uint32[2]
self.filter = Struct.uint32[2]
self.lod_bias = Struct.float
self.edge_lod = Struct.uint8
self.min_lod = Struct.uint8
self.max_lod = Struct.uint8
self.unpacked = Struct.uint8
class TPLPaletteHeader(Struct):
__endian__ = Struct.BE
def __format__(self):
self.nitems = Struct.uint16
self.unpacked = Struct.uint8
self.pad = Struct.uint8
self.format = Struct.uint32
self.offset = Struct.uint32
def __init__(self, file):
if(not ("\x00" in file) and os.path.isfile(file)):
self.file = file
self.data = None
else:
self.file = None
self.data = file
def toTPL(self, outfile, (width, height) = (None, None), format = "RGBA8"): #single texture only
"""This converts an image into a TPL. The image is specified as the file parameter to the class initializer, while the output filename is specified here as the parameter outfile. Width and height are optional parameters and specify the size to resize the image to, if needed. Returns the output filename.
This only can create TPL images with a single texture."""
head = self.TPLHeader()
head.magic = 0x0020AF30
head.ntextures = 1
head.header_size = 0x0C
tex = self.TPLTexture()
tex.header_offset = 0x14
tex.pallete_offset = 0
img = Image.open(self.file)
theWidth, theHeight = img.size
if(width != None and height != None and (width != theWidth or height != theHeight)):
img = img.resize((width, height), Image.ANTIALIAS)
w, h = img.size
texhead = self.TPLTextureHeader()
texhead.height = h
texhead.width = w
if format == "I4":
texhead.format = 0
tpldata = self.toI4((w, h), img)
elif format == "I8":
texhead.format = 1
tpldata = self.toI8((w, h), img)
elif format == "IA4":
texhead.format = 2
tpldata = self.toIA4((w, h), img)
elif format == "IA8":
texhead.format = 3
tpldata = self.toIA8((w, h), img)
elif format == "RGB565":
texhead.format = 4
tpldata = self.toRGB565((w, h), img)
elif format == "RGB5A3":
texhead.format = 5
tpldata = self.toRGB5A3((w, h), img)
elif format == "RGBA8":
texhead.format = 6
tpldata = self.toRGBA8((w, h), img)
elif format == "CI4":
texhead.format = 8
''' ADD toCI4 '''
raise Exception("toCI4 not done")
#tpldata = self.toCI4((w, h), img)
elif format == "CI8":
texhead.format = 9
''' ADD toCI8 '''
raise Exception("toCI8 not done")
#tpldata = self.toCI8((w, h), img)
elif format == "CI14X2":
texhead.format = 10
''' ADD toCI14X2 '''
raise Exception("toCI14X2 not done")
#tpldata = self.toCI14X2((w, h), img)
elif format == "CMP":
texhead.format = 14
''' ADD toCMP '''
raise Exception("toCMP not done")
#tpldata = self.toCMP((w, h), img)
texhead.data_off = 0x14 + len(texhead)
texhead.wrap = [0, 0]
texhead.filter = [1, 1]
texhead.lod_bias = 0
texhead.edge_lod = 0
texhead.min_lod = 0
texhead.max_lod = 0
texhead.unpacked = 0
f = open(outfile, "wb")
f.write(head.pack())
f.write(tex.pack())
f.write(texhead.pack())
if format == "I4":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) / 2) + "B", *tpldata))
if format == "I8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "B", *tpldata))
if format == "IA4":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "B", *tpldata))
if format == "IA8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGB565":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGB5A3":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 1) + "H", *tpldata))
if format == "RGBA8":
f.write(struct.pack(">" + str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI4":
''' ADD toCI4 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI8":
''' ADD toCI8 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CI14X2":
''' ADD toCI14X2 '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
if format == "CMP":
''' ADD toCMP '''
#f.write(struct.pack(">"+ str(align(w,4) * align(h,4) * 4) + "B", *tpldata))
f.close()
return outfile
def toI4(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4) / 2)]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 8):
for x1 in range(0, w, 8):
for y in range(y1, y1+8, 1):
for x in range(x1, x1+8, 2):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
rgba = flatten(inp[x+1+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i2 = ((r + g + b) / 3) & 0xff
newpixel = (((i1 * 15) / 255) << 4)
newpixel |= (((i2 * 15) / 255) & 0xf)
out[outp] = newpixel
outp += 1
return out
def toI8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 8):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+8, 1):
rgba = flatten(inp[x + (y * w)])
if x>= w or y>=h:
i1 = 0
else:
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
out[outp] = i1
outp += 1
return out
def toIA4(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 8):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+8, 1):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * w)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
a1 = (rgba >> 24) & 0xff
newpixel = (((i1 * 15) / 255) & 0xf)
newpixel = newpixel | (((a1 * 15) / 255) << 4)
out[outp] = newpixel
outp += 1
return out
def toIA8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * w)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
i1 = ((r + g + b) / 3) & 0xff
a1 = (rgba >> 24) & 0xff
newpixel = i1 << 8
newpixel = newpixel | a1
out[outp] = newpixel
outp += 1
return out
def toRGB565(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = img.getdata()
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
newpixel = 0
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x+y*w])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
newpixel = ((b >>3) << 11) | ((g >>2) << 5) | ((r >>3) << 0)
out[outp] = newpixel
outp += 1
return out
def toRGB5A3(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4))]
outp = 0
inp = list(img.getdata())
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1+4, 1):
for x in range(x1, x1+4, 1):
newpixel = 0
if x>=w or y>=h:
newpixel = 0
else:
rgba = flatten(inp[x + (y * h)])
r = (rgba >> 0) & 0xff
g = (rgba >> 8) & 0xff
b = (rgba >> 16) & 0xff
a = (rgba >> 24) & 0xff
if (a <= 0xda):
newpixel &= ~(1 << 15)
r = ((r * 15) / 255) & 0xf
g = ((g * 15) / 255) & 0xf
b = ((b * 15) / 255) & 0xf
a = ((a * 7) / 255) & 0x7
#newpixel |= r << 12
#newpixel |= g << 8
#newpixel |= b << 4
#newpixel |= a << 0
newpixel |= a << 12
newpixel |= b << 8
newpixel |= g << 4
newpixel |= r << 0
else:
newpixel |= (1 << 15)
r = ((r * 31) / 255) & 0x1f
g = ((g * 31) / 255) & 0x1f
b = ((b * 31) / 255) & 0x1f
newpixel |= b << 10
newpixel |= g << 5
newpixel |= r << 0
out[outp] = newpixel
outp += 1
return out
def toRGBA8(self, (w, h), img):
out = [0 for i in range(align(w, 4) * align(h, 4) * 4)]
inp = list(img.getdata())
iv = 0
z = 0
lr = [0 for i in range(32)]
lg = [0 for i in range(32)]
lb = [0 for i in range(32)]
la = [0 for i in range(32)]
for y1 in range(0, h, 4):
for x1 in range(0, w, 4):
for y in range(y1, y1 + 4, 1):
for x in range(x1, x1 + 4, 1):
if(y >= h or x >= w):
lr[z] = 0
lg[z] = 0
lb[z] = 0
la[z] = 0
else:
rgba = flatten(inp[x + (y * w)])
lr[z] = (rgba >> 0) & 0xff
lg[z] = (rgba >> 8) & 0xff
lb[z] = (rgba >> 16) & 0xff
la[z] = (rgba >> 24) & 0xff
z += 1
if(z == 16):
for i in range(16):
out[iv] = la[i] & 0xff
iv += 1
out[iv] = lr[i] & 0xff
iv += 1
for i in range(16):
out[iv] = lg[i] & 0xff
iv += 1
out[iv] = lb[i] & 0xff
iv += 1
z = 0
return out
def toImage(self, outfile):
"""This converts a TPL texture to a PNG image. You specify the input TPL filename in the initializer, and you specify the output filename in the outfile parameter to this method. Returns the output filename.
This only supports single textured TPL images."""
if(self.file):
data = open(self.file, "rb").read()
else:
data = self.data
header = self.TPLHeader()
textures = []
pos = 0
header.unpack(data[pos:pos + len(header)])
pos += len(header)
palette_offsets = []
for i in range(header.ntextures):
tmp = self.TPLTexture()
tmp.unpack(data[pos:pos + len(tmp)])
textures.append(tmp)
pos += len(tmp)
if(tmp.palette_offset > 0):
palette_offsets.append(tmp.palette_offset)
if(header.ntextures > 1):
raise ValueError("Only one texture supported. Don't touch me!")
for i in range(header.ntextures):
head = textures[i]
tex = self.TPLTextureHeader()
tex.unpack(data[head.header_offset:head.header_offset + len(tex)])
w = tex.width
h = tex.height
print tex.format
if(tex.format == 0): #I4, 4-bit
tpldata = struct.unpack(">" + str((w * h) / 2) + "B", data[tex.data_off:tex.data_off + ((w * h) / 2)])
rgbdata = self.I4((w, h), tpldata)
elif(tex.format == 1): #I8, 8-bit
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.I8((w, h), tpldata)
elif(tex.format == 2): #IA4, 8-bit
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.IA4((w, h), tpldata)
elif(tex.format == 4): #RGB565, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGB565((w, h), tpldata)
elif(tex.format == 5): #RGB5A3, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGB5A3((w, h), tpldata)
elif(tex.format == 3): #IA8, 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.IA8((w, h), tpldata)
elif(tex.format == 6): #RGBA8, 32-bit, but for easyness's sake lets do it with 16-bit
tpldata = data[tex.data_off:]
rgbdata = self.RGBA8((w, h), tpldata)
elif(tex.format == 8 or tex.format == 9 or tex.format == 10):
palhead = self.TPLPaletteHeader()
offs = palette_offsets.pop(0)
palhead.unpack(data[offs:offs + len(palhead)])
tpldata = struct.unpack(">" + str(palhead.nitems) + "H", data[palhead.offset:palhead.offset + (palhead.nitems * 2)])
if(palhead.format == 0):
palette_data = self.IA8((palhead.nitems, 1), tpldata)[0]
elif(palhead.format == 1):
palette_data = self.RGB565((palhead.nitems, 1), tpldata)[0]
elif(palhead.format == 2):
palette_data = self.RGB5A3((palhead.nitems, 1), tpldata)[0]
paldata = []
for i in range(0, palhead.nitems * 4, 4):
tmp = 0
tmp |= palette_data[i + 0] << 24
tmp |= palette_data[i + 1] << 16
tmp |= palette_data[i + 2] << 8
tmp |= palette_data[i + 3] << 0
paldata.append(tmp)
if(tex.format == 8):
tpldata = struct.unpack(">" + str((w * h) / 2) + "B", data[tex.data_off:tex.data_off + ((w * h) / 2)])
rgbdata = self.CI4((w, h), tpldata, paldata)
if(tex.format == 9):
tpldata = struct.unpack(">" + str(w * h) + "B", data[tex.data_off:tex.data_off + (w * h * 1)])
rgbdata = self.CI8((w, h), tpldata, paldata)
if(tex.format == 10):
tpldata = struct.unpack(">" + str(w * h) + "H", data[tex.data_off:tex.data_off + (w * h * 2)])
rgbdata = self.CI14X2((w, h), tpldata, paldata)
elif(tex.format == 14):
tpldata = ''.join(data[tex.data_off:])
rgbdata = self.CMP((w, h), tpldata)
else:
raise TypeError("Unsupported TPL Format: " + str(tex.format))
output = Image.fromstring("RGBA", (w, h), rgbdata)
ext = outfile[outfile.rfind(".")+1:]
output.save(outfile, ext)
return outfile
def getSizes(self):
"""This returns a tuple containing the width and height of the TPL image filename in the class initializer. Will only return the size of single textured TPL images."""
data = open(self.file, "rb").read()
header = self.TPLHeader()
textures = []
pos = 0
header.unpack(data[pos:pos + len(header)])
pos += len(header)
for i in range(header.ntextures):
tmp = self.TPLTexture()
tmp.unpack(data[pos:pos + len(tmp)])
textures.append(tmp)
pos += len(tmp)
for i in range(header.ntextures):
head = textures[i]
tex = self.TPLTextureHeader()
tex.unpack(data[head.header_offset:head.header_offset + len(tex)])
w = tex.width
h = tex.height
return (w, h)
def toScreen(self): #single texture only
"""This will draw a simple window with the TPL image displayed on it. It uses WxPython for the window creation and management. The window has a minimum width and height of 300 x 200. Does not return a value.
Again, only a single texture is supported."""
import wx
class imp(wx.Dialog):
def __init__(self, title, im):
w = img.GetWidth()
h = img.GetHeight()
wx.Dialog.__init__(self, None, -1, title, size = (max(w, 300), max(h, 200)))
wx.StaticBitmap(self, -1, im, ( ((max(w, 300) - w) / 2), ((max(h, 200) - h) / 2) ), (w, h))
self.toImage("tmp.png")
img = wx.Image("tmp.png", wx.BITMAP_TYPE_ANY).ConvertToBitmap()
w = img.GetWidth()
h = img.GetHeight()
dialog = imp("TPL (" + str(w) + ", " + str(h) + ")", img)
dialog.ShowModal()
dialog.Destroy()
os.unlink("tmp.png")
def RGBA8(self, (x, y), data):
out = [0 for i in range(x * y)]
inp = 0
for i in xrange(0, y, 4):
for j in xrange(0, x, 4):
for k in xrange(2):
for l in xrange(i, i + 4, 1):
for m in xrange(j, j + 4, 1):
texel = Struct.uint16(data[inp * 2:inp * 2 + 2], endian = '>')
inp += 1
if (m >= x) or (l >= y):
continue
if k == 0:
a = (texel >> 8) & 0xff
r = (texel >> 0) & 0xff
out[m + (l * x)] |= ((r << 0) | (a << 24))
else:
g = (texel >> 8) & 0xff
b = (texel >> 0) & 0xff
out[m + (l * x)] |= ((g << 8) | (b << 16))
return ''.join(Struct.uint32(p) for p in out)
def RGB5A3(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
if(pixel & (1 << 15)): #RGB555
b = (((pixel >> 10) & 0x1F) * 255) / 31
g = (((pixel >> 5) & 0x1F) * 255) / 31
r = (((pixel >> 0) & 0x1F) * 255) / 31
a = 255
else: #RGB4A3
a = (((pixel >> 12) & 0x07) * 255) / 7
b = (((pixel >> 8) & 0x0F) * 255) / 15
g = (((pixel >> 4) & 0x0F) * 255) / 15
r = (((pixel >> 0) & 0x0F) * 255)/ 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[(y1 * w) + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def RGB565(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
b = (((pixel >> 11) & 0x1F) << 3) & 0xff
g = (((pixel >> 5) & 0x3F) << 2) & 0xff
r = (((pixel >> 0) & 0x1F) << 3) & 0xff
a = 255
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def I4(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 8):
for x in range(0, w, 8):
for y1 in range(y, y + 8):
for x1 in range(x, x + 8, 2):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
r = (pixel >> 4) * 255 / 15
g = (pixel >> 4) * 255 / 15
b = (pixel >> 4) * 255 / 15
a = (pixel >> 4) * 255 / 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pixel & 0x0F) * 255 / 15
g = (pixel & 0x0F) * 255 / 15
b = (pixel & 0x0F) * 255 / 15
a = (pixel & 0x0F) * 255 / 15
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1 + 1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def IA4(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = ((pixel & 0x0F) * 255 / 15) & 0xff
g = ((pixel & 0x0F) * 255 / 15) & 0xff
b = ((pixel & 0x0F) * 255 / 15) & 0xff
a = (((pixel >> 4) * 255) / 15) & 0xff
rgba = ( r<< 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def I8(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = pixel
g = pixel
b = pixel
a = 255
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def IA8(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = Struct.uint16(jar[i * 2:i * 2 + 2], endian='>')
i += 1
r = (pixel >> 8) & 0xff
g = (pixel >> 8) & 0xff
b = (pixel >> 8) & 0xff
a = pixel & 0xff
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CI4(self, (w, h), jar, pal):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 8):
for x in range(0, w, 8):
for y1 in range(y, y + 8):
for x1 in range(x, x + 8, 2):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1 + 1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CI8(self, (w, h), jar, pal):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 8):
for y1 in range(y, y + 4):
for x1 in range(x, x + 8):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel] & 0xFF000000) >> 24
g = (pal[pixel] & 0x00FF0000) >> 16
b = (pal[pixel] & 0x0000FF00) >> 8
a = (pal[pixel] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
def CMP(self, (w, h), data):
temp = [0 for i in range(w * h)]
pix = [ 0 , 0 , 0 ]
c = [ 0 , 0 , 0 , 0 ]
outp = 0
for y in xrange(h):
for x in xrange(w):
ww = round_up(w, 8)
x0 = x & 0x03
x1 = (x >> 2) & 0x01
x2 = x >> 3
y0 = y & 0x03
y1 = (y >> 2) & 0x01
y2 = y >> 3
off = (8 * x1) + (16 * y1) + (32 * x2) + (4 * ww * y2)
c[0] = Struct.uint16(data[off + 0:off + 2], endian='>')
c[1] = Struct.uint16(data[off + 2:off + 4], endian='>')
if(c[0] > c[1]):
c[2] = avg(2, 1, c[0], c[1])
c[3] = avg(1, 2, c[0], c[1])
else:
c[2] = avg(1, 1, c[0], c[1])
c[3] = 0
px = Struct.uint32(data[off+4:off + 8], endian='>')
ix = x0 + ( 4 * y0 )
raw = c[(px >> (30 - (2 * ix))) & 0x03]
pix[0] = (raw >> 8) & 0xf8
pix[1] = (raw >> 3) & 0xf8
pix[2] = (raw << 3) & 0xf8
temp[outp] = (pix[0] <<0) | (pix[1] << 8) | (pix[2] << 16) | (255 << 24)
outp += 1
return ''.join(Struct.uint32(p) for p in temp)
def CI14X2(self, (w, h), jar):
out = [0 for i in range(w * h)]
i = 0
for y in range(0, h, 4):
for x in range(0, w, 4):
for y1 in range(y, y + 4):
for x1 in range(x, x + 4):
if(y1 >= h or x1 >= w):
continue
pixel = jar[i]
i += 1
r = (pal[pixel & 0x3FFF] & 0xFF000000) >> 24
g = (pal[pixel & 0x3FFF] & 0x00FF0000) >> 16
b = (pal[pixel & 0x3FFF] & 0x0000FF00) >> 8
a = (pal[pixel & 0x3FFF] & 0x000000FF) >> 0
rgba = (r << 0) | (g << 8) | (b << 16) | (a << 24)
out[y1 * w + x1] = rgba
return ''.join(Struct.uint32(p) for p in out)
if __name__=='__main__':
app = wx.PySimpleApp()
app.MainLoop()
TPL(*sys.argv[1:]).toScreen()

2
qwad
View File

@ -1,3 +1,3 @@
#!/bin/sh #!/bin/sh
cd /usr/share/Qwad cd /usr/share/Qwad
python2 Qwad.pyw $@ python Qwad.pyw $@