Skip to content

Instantly share code, notes, and snippets.

@yin8086
Created March 8, 2016 18:23
Show Gist options
  • Save yin8086/6ce83c5d8e4cf1ac9879 to your computer and use it in GitHub Desktop.
Save yin8086/6ce83c5d8e4cf1ac9879 to your computer and use it in GitHub Desktop.
arm etc2(Ericsson Texture Compression, Unity asset) to png, and png to etc2, use official `etcpack.exe` from [Mali GPU Texture Compression Tool](http://malideveloper.arm.com/resources/tools/mali-gpu-texture-compression-tool/)
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 07 00:55:12 2016
@author: Stardrad
"""
import os, struct, fnmatch, time
from PIL import Image
def walk(adr):
#root,dirs,files = os.walk(adr).next()
for root,dirs, files in os.walk(adr):
for name in files:
if fnmatch.fnmatch(name, '*.tex') :
yield os.path.join(root, name)
if __name__ == '__main__':
ntime = time.time()
for curName in walk(ur'.'):
ind = 0
fName = curName[curName.rindex('\\') + 1:]
print 'Process %s' % fName
with open(curName,'rb') as fUnityIn:
print '....',
fUnityIn.seek(0)
fNameLen, = struct.unpack('<I', fUnityIn.read(4))
curPos = fUnityIn.tell()
curPos += fNameLen
curPos = (curPos + 4 - 1) / 4 * 4
fUnityIn.seek(curPos)
width, height, = struct.unpack('<II', fUnityIn.read(8))
dataSize, = struct.unpack('<I', fUnityIn.read(4))
unityType, = struct.unpack('<I', fUnityIn.read(4))
if unityType != 0x2f :
print 'Pass type = %08x' % unityType
continue
originalPos = fUnityIn.tell()
fUnityIn.seek(0,2)
fileSize = fUnityIn.tell()
fUnityIn.seek(originalPos + 0x4 * 10)
dataSize_2, = struct.unpack('<I', fUnityIn.read(4))
tarBpp = float(dataSize * 8) / ( width * height)
if dataSize_2 == dataSize:
fUnityIn.seek(originalPos + 0x4 * 10 + 4)
else:
fUnityIn.seek(fileSize - dataSize)
etc2data = fUnityIn.read(dataSize)
assert len(etc2data) == dataSize
assert width % 4 == 0 and height % 4 == 0
with open(curName + '.pkm','wb') as fPKMOut:
fPKMOut.write('PKM ')
fPKMOut.write('20') # version
fPKMOut.write(struct.pack('>H', 3)) # type, 3 = ETC2_RGBA
fPKMOut.write(struct.pack('>H', width)) # extend_width
fPKMOut.write(struct.pack('>H', height)) # extend_height
fPKMOut.write(struct.pack('>H', width)) # width
fPKMOut.write(struct.pack('>H', height)) # height
fPKMOut.write(etc2data)
args1 = r'@PATH="D:\Program Files\ARM\Mali Developer Tools\Mali Texture Compression Tool v4.3.0\bin";%PATH'
args = 'etcpack.exe %s . -ext PNG' % ( curName + '.pkm')
os.system(args1)
os.system(args)
os.remove(curName + '.pkm')
im1 = Image.open(curName + '.png')
im1 = im1.transpose(Image.FLIP_TOP_BOTTOM)
im1.save(curName + '.png');
print 'save to png'
print 'Total time: %lf' % (time.time() - ntime)
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 09 01:48:51 2016
@author: Stardrad
"""
import os, struct, fnmatch, time
from PIL import Image
def walk(adr):
#root,dirs,files = os.walk(adr).next()
for root,dirs, files in os.walk(adr):
for name in files:
if fnmatch.fnmatch(name, '*.png') :
yield os.path.join(root, name)
if __name__ == '__main__':
ntime = time.time()
for curName in walk(ur'.'):
ind = 0
fName = curName[curName.rindex('\\') + 1:]
print 'Process %s' % fName
print '....',
orig_fName = curName[:-4]
im = Image.open( curName ).convert('RGBA')
im = im.transpose(Image.FLIP_TOP_BOTTOM)
png_width,png_height, = im.size
im.save(curName);
args = 'etcpack.exe %s . -f RGBA' % curName
os.system(args)
with open(orig_fName + '.pkm','rb') as fETC2In:
fETC2In.seek(0x10)
etc2Data = fETC2In.read()
os.remove(orig_fName + '.pkm')
with open(orig_fName,'rb+') as fUnityIn:
fUnityIn.seek(0)
fNameLen, = struct.unpack('<I', fUnityIn.read(4))
curPos = fUnityIn.tell()
curPos += fNameLen
curPos = (curPos + 4 - 1) / 4 * 4
fUnityIn.seek(curPos)
width, height, = struct.unpack('<II', fUnityIn.read(8))
if png_width != width or png_height != height:
print 'Pass , size not match'
continue
sizePos = fUnityIn.tell()
dataSize, = struct.unpack('<I', fUnityIn.read(4))
unityType, = struct.unpack('<I', fUnityIn.read(4))
if unityType != 0x2f :
print 'Pass type = %08x' % unityType
continue
originalPos = fUnityIn.tell()
fUnityIn.seek(0,2)
fileSize = fUnityIn.tell()
fUnityIn.seek(originalPos + 0x4 * 10)
dataSize_2, = struct.unpack('<I', fUnityIn.read(4))
tarBpp = float(dataSize * 8) / ( width * height)
if dataSize_2 == dataSize:
fUnityIn.seek(originalPos + 0x4 * 10 + 4)
else:
fUnityIn.seek(fileSize - dataSize)
assert len(etc2Data) == dataSize
fUnityIn.write(etc2Data)
print 'import to %s' % orig_fName
print 'Total time: %lf' % (time.time() - ntime)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment