UnityPack
UnityPack copied to clipboard
Support for ETC_RGB4?
Traceback (most recent call last):
File "/usr/local/bin/unityextract", line 146, in <module>
main()
File "/usr/local/bin/unityextract", line 143, in main
exit(app.run())
File "/usr/local/bin/unityextract", line 56, in run
self.handle_asset(asset)
File "/usr/local/bin/unityextract", line 127, in handle_asset
image = d.image
File "/usr/local/lib/python3.5/site-packages/unitypack/engine/texture.py", line 151, in image
raise NotImplementedError("Unimplemented format %r" % (self.format))
NotImplementedError: Unimplemented format <TextureFormat.ETC_RGB4: 34>
An ETC decoder needs to be added to Pillow for this.
Python and Unity are both completely new to me, but perhaps you could bundle a decoder:
http://pillow.readthedocs.io/en/latest/handbook/writing-your-own-file-decoder.html
using this tool: http://malideveloper.arm.com/resources/tools/mali-gpu-texture-compression-tool/
and this gist: https://gist.github.com/yin8086/6ce83c5d8e4cf1ac9879
as reference?
Thanks. ill take a look.
Edit: Uh, that's no good. It's subprocessing the texture to a separate executable...
Drat, I didn't catch that.
Hi !
And what about that : https://github.com/hglm/texgenpack ?
It is C code but maybe something is possible ?
There is a python library supporting unpacking ETC (and other) images if you are open to using another besides Pillow. Specifically, tex2img. Though I saw in PR #52 that someone may be trying to add Pillow support.
In any case, here's some code using it to unpack ETC and ETC2 images that unityextract doesn't support if anyone finds it useful. I modified unityextract to save as a pickle the image when the format was unsupported first.
# Line 134 of unityextract
try:
image = d.image
except NotImplementedError as e:
print("WARNING: Texture format not implemented. Skipping %r." % (filename),e)
print('\tWriting Data Directly')
python_data = pickle.dumps(d._obj)
self.write_to_file(d.name + ".pickle", python_data, mode="wb")
continue
The decompression code:
Show Code
#!/usr/bin/python3
import pickle,enum
with open('ETC_Image.pickle','rb') as f:
data = pickle.load(f)
#print(data.keys()) odict_keys(['m_Name', 'm_Width', 'm_Height', 'm_CompleteImageSize', 'm_TextureFormat', 'm_MipCount', 'm_IsReadable', 'm_ReadAllowed', 'm_ImageCount', 'm_TextureDimension', 'm_TextureSettings', 'm_LightmapFormat', 'm_ColorSpace', 'image data', 'm_StreamData'])
from enum import IntEnum
class TextureFormat(IntEnum):
# From UnityPack
Alpha8 = 1
ARGB4444 = 2
RGB24 = 3
RGBA32 = 4
ARGB32 = 5
RGB565 = 7
# Direct3D
DXT1 = 10
DXT5 = 12
RGBA4444 = 13
BGRA32 = 14
BC6H = 24
BC7 = 25
DXT1Crunched = 28
DXT5Crunched = 29
# PowerVR
PVRTC_RGB2 = PVRTC_2BPP_RGB = 30
PVRTC_RGBA2 = PVRTC_2BPP_RGBA = 31
PVRTC_RGB4 = PVRTC_4BPP_RGB = 32
PVRTC_RGBA4 = PVRTC_4BPP_RGBA = 33
# Ericsson (Android)
ETC_RGB4 = 34
ATC_RGB4 = 35
ATC_RGBA8 = 36
# Adobe ATF
ATF_RGB_DXT1 = 38
ATF_RGBA_JPG = 39
ATF_RGB_JPG = 40
# Ericsson
EAC_R = 41
EAC_R_SIGNED = 42
EAC_RG = 43
EAC_RG_SIGNED = 44
ETC2_RGB = 45
ETC2_RGBA1 = 46
ETC2_RGBA8 = 47
# OpenGL / GLES
ASTC_RGB_4x4 = 48
ASTC_RGB_5x5 = 49
ASTC_RGB_6x6 = 50
ASTC_RGB_8x8 = 51
ASTC_RGB_10x10 = 52
ASTC_RGB_12x12 = 53
ASTC_RGBA_4x4 = 54
ASTC_RGBA_5x5 = 55
ASTC_RGBA_6x6 = 56
ASTC_RGBA_8x8 = 57
ASTC_RGBA_10x10 = 58
ASTC_RGBA_12x12 = 59
@property
def pixel_format(self):
if self == TextureFormat.RGB24:
return "RGB"
elif self == TextureFormat.ARGB32:
return "ARGB"
elif self == TextureFormat.RGB565:
return "RGB;16"
elif self == TextureFormat.Alpha8:
return "A"
elif self == TextureFormat.RGBA4444:
return "RGBA;4B"
elif self == TextureFormat.ARGB4444:
return "RGBA;4B"
return "RGBA"
for k in data.keys():
if k in ('image data',):#, 'm_StreamData'):
print(k,len(data[k]))
else:
print(k,data[k])
tf = TextureFormat(data['m_TextureFormat'])
print(tf)
from tex2img import *
# Formats
ETC1_RGB_NO_MIPMAPS = 0
ETC2PACKAGE_RGB_NO_MIPMAPS = 1
ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD = 2
ETC2PACKAGE_RGBA_NO_MIPMAPS = 3
ETC2PACKAGE_RGBA1_NO_MIPMAPS = 4
ETC2PACKAGE_R_NO_MIPMAPS = 5
ETC2PACKAGE_RG_NO_MIPMAPS = 6
ETC2PACKAGE_R_SIGNED_NO_MIPMAPS = 7
ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS = 8
ETC2PACKAGE_sRGB_NO_MIPMAPS = 9
ETC2PACKAGE_sRGBA_NO_MIPMAPS = 10
ETC2PACKAGE_sRGBA1_NO_MIPMAPS = 11
# TODO: SRGB Check
ex_unpack = {
TextureFormat.ETC_RGB4 : lambda data,w,h : decompress_etc(data,w,h,ETC1_RGB_NO_MIPMAPS)
TextureFormat.ETC2_RGB : lambda data,w,h : decompress_etc(data,w,h,ETC2PACKAGE_RGB_NO_MIPMAPS)
TextureFormat.ETC2_RGBA1 : lambda data,w,h : decompress_etc(data,w,h,ETC2PACKAGE_RGBA1_NO_MIPMAPS)
TextureFormat.ETC2_RGBA8 : lambda data,w,h : decompress_etc(data,w,h,ETC2PACKAGE_RGBA_NO_MIPMAPS)
}
from PIL import Image
if tf in ex_unpack:
img_data,w,h = data['image data'],data['m_Width'],data['m_Height']
name = data['m_Name']
image_data = ex_unpack[tf](img_data,w,h)
image = Image.frombytes('RGBA', (w,h), image_data, 'raw')
image.save(open(name+'.png','wb'), format="png")