Example #1
0
    def image(self):
        from PIL import Image
        from decrunch import File as CrunchFile

        if self.format not in IMPLEMENTED_FORMATS:
            raise NotImplementedError("Unimplemented format %r" %
                                      (self.format))

        if self.format in (TextureFormat.DXT1, TextureFormat.DXT1Crunched):
            codec = "bcn"
            args = (1, )
        elif self.format in (TextureFormat.DXT5, TextureFormat.DXT5Crunched):
            codec = "bcn"
            args = (3, )
        else:
            codec = "raw"
            args = (self.format.pixel_format, )

        mode = "RGB" if self.format.pixel_format in ("RGB",
                                                     "RGB;16") else "RGBA"
        size = (self.width, self.height)

        data = self.image_data
        if self.format in (TextureFormat.DXT1Crunched,
                           TextureFormat.DXT5Crunched):
            data = CrunchFile(self.image_data).decode_level(0)

        # Pillow wants bytes, not bytearrays
        data = bytes(data)

        if not data and size == (0, 0):
            return None

        return Image.frombytes(mode, size, data, codec, args)
Example #2
0
    def image(self):
        from PIL import Image
        from decrunch import File as CrunchFile
        import etcpack
        # needs to be imported once in the active code, so that the codec can register itself

        if self.format not in IMPLEMENTED_FORMATS:
            raise NotImplementedError("Unimplemented format %r" %
                                      (self.format))

        if self.format in (TextureFormat.DXT1, TextureFormat.DXT1Crunched):
            codec = "bcn"
            args = (1, )
        elif self.format in (TextureFormat.DXT5, TextureFormat.DXT5Crunched):
            codec = "bcn"
            args = (3, )
        elif self.format == TextureFormat.BC7:
            codec = "bcn"
            args = (7, )
        elif self.format in (TextureFormat.ETC2_RGB, ):
            # ETC2PACKAGE_RGB_NO_MIPMAPS
            codec = "etc2"
            args = (1, )
        elif self.format in (TextureFormat.ETC2_RGBA1, ):
            # ETC2PACKAGE_RGBA1_NO_MIPMAPS
            codec = "etc2"
            args = (4, )
        elif self.format in (TextureFormat.ETC2_RGBA8, ):
            # ETC2PACKAGE_RGBA_NO_MIPMAPS
            codec = "etc2"
            args = (3, )
        else:
            codec = "raw"
            args = (self.format.pixel_format, )

        mode = "RGB" if self.format.pixel_format in ("RGB",
                                                     "RGB;16") else "RGBA"
        size = (self.width, self.height)

        data = self.image_data
        if self.format in (TextureFormat.DXT1Crunched,
                           TextureFormat.DXT5Crunched):
            data = CrunchFile(self.image_data).decode_level(0)

        # Pillow wants bytes, not bytearrays
        data = bytes(data)

        if not data and size == (0, 0):
            return None

        return Image.frombytes(mode, size, data, codec, args)
Example #3
0
    def image(self):
        from PIL import Image
        from decrunch import File as CrunchFile

        if self.format not in IMPLEMENTED_FORMATS:
            raise NotImplementedError("Unimplemented format %r" %
                                      (self.format))

        if self.format in (TextureFormat.DXT1, TextureFormat.DXT1Crunched):
            codec = "bcn"
            args = (1, )
        elif self.format in (TextureFormat.DXT5, TextureFormat.DXT5Crunched):
            codec = "bcn"
            args = (3, )
        elif self.format == TextureFormat.BC7:
            codec = "bcn"
            args = (7, )
        elif self.format in (TextureFormat.ETC_RGB4, TextureFormat.ETC2_RGB,
                             TextureFormat.ETC2_RGBA1,
                             TextureFormat.ETC2_RGBA8):
            codec = "etc2"
            args = (
                self.format,
                self.format.pixel_format,
            )
        else:
            codec = "raw"
            args = (self.format.pixel_format, )

        mode = "RGB" if self.format.pixel_format in ("RGB",
                                                     "RGB;16") else "RGBA"
        size = (self.width, self.height)

        data = self.image_data
        if self.format in (TextureFormat.DXT1Crunched,
                           TextureFormat.DXT5Crunched):
            data = CrunchFile(self.image_data).decode_level(0)
        if self.format in TextureFormat.ASTC_FORMATS():
            block_sz = self.format.astc_block_size
            data = decompress_astc(data, self.width, self.height, block_sz,
                                   block_sz, False)

        # Pillow wants bytes, not bytearrays
        data = bytes(data)

        if not data and size == (0, 0):
            return None

        return Image.frombytes(mode, size, data, codec, args)
Example #4
0
def get_image_from_texture2d(texture_2d, flip=True) -> Image:
	# init variables
	mode = "RGBA"
	codec = "raw"
	args = ("RGBA",)
	swap = []  # for 4444 types to fix their channels

	image_data = texture_2d.image_data
	texture_format = texture_2d.m_TextureFormat
	platform = texture_2d.platform

	# INT8
	if texture_format == TextureFormat.Alpha8:
		args = ('A',)

	elif texture_format == TextureFormat.R8:
		mode = 'RGB'
		args = ('R',)

	elif texture_format == TextureFormat.RG16:
		image_data_size = len(image_data)
		rgba32 = bytearray(image_data_size * 2)
		for i in range(0, image_data_size, 2):
			rgba32[i * 2 + 1] = image_data[i + 1]  # G
			rgba32[i * 2 + 0] = image_data[i]  # R
			rgba32[i * 2 + 3] = 255  # A
		image_data = bytes(rgba32)

	if texture_format == TextureFormat.ARGB4444:
		args = ('RGBA;4B',)
		swap = [2, 1, 0, 3]

	elif texture_format == TextureFormat.RGB24:
		mode = 'RGB'
		args = ('RGB',)

	elif texture_format == TextureFormat.RGBA32:
		args = ('RGBA',)

	elif texture_format == TextureFormat.ARGB32:
		args = ('ARGB',)

	elif texture_format == TextureFormat.RGBA4444:
		args = ('RGBA;4B',)
		swap = [3, 2, 1, 0]

	elif texture_format == TextureFormat.BGRA32:
		args = ('BGRA',)

	# INT16
	elif texture_format == TextureFormat.R16:
		mode = 'RGB'
		args = ('R;16',)
	# rgba32 = bytearray(image_data_size * 2)
	# for i in range(0, image_data_size, 2):
	# 	f = Half.ToHalf(image_data, i)
	# 	rgba32[i * 2 + 0] = (math.ceil(f * 255))%256  # R
	# 	rgba32[i * 2 + 3] = 255  # A
	# image_data = bytes(rgba32)

	elif texture_format == TextureFormat.RGB565:  # test passed
		mode = 'RGB'
		args = ('BGR;16',)
		image_data = swap_bytes_for_xbox(image_data, platform)

	# FLOAT
	elif texture_format == TextureFormat.RFloat:
		mode = 'RGB'
		args = ('RF',)

	elif texture_format == TextureFormat.RGBAFloat:
		mode = 'RGBA'
		args = ('RGBAF',)

	# BCN
	elif texture_format in [  # test passed
		TextureFormat.DXT1,
		TextureFormat.DXT1Crunched
	]:
		args = (1,)
		codec = 'bcn'
		image_data = swap_bytes_for_xbox(image_data, platform)

	elif texture_format in [  # test passed
		TextureFormat.DXT5,
		TextureFormat.DXT5Crunched
	]:
		args = (3,)
		codec = 'bcn'
		image_data = swap_bytes_for_xbox(image_data, platform)

	elif texture_format == TextureFormat.BC4:
		args = (4,)
		codec = 'bcn'
		mode = 'L'

	elif texture_format == TextureFormat.BC5:
		args = (5,)
		codec = 'bcn'

	elif texture_format == TextureFormat.BC6H:
		args = (6,)
		codec = 'bcn'

	elif texture_format == TextureFormat.BC7:
		args = (7,)
		codec = 'bcn'

	# ETC
	elif texture_format in [  # test passed
		TextureFormat.ETC_RGB4Crunched,
		TextureFormat.ETC_RGB4_3DS,
		TextureFormat.ETC_RGB4
	]:
		args = (0,)
		codec = 'etc2'
		mode = 'RGB'

	elif texture_format == TextureFormat.ETC2_RGB:  # test passed
		args = (1,)
		codec = 'etc2'
		mode = 'RGB'

	elif texture_format == TextureFormat.ETC2_RGBA1:
		args = (4,)
		codec = 'etc2'

	elif texture_format in [  # test passed
		TextureFormat.ETC2_RGBA8Crunched,
		TextureFormat.ETC_RGBA8_3DS,
		TextureFormat.ETC2_RGBA8
	]:
		args = (3,)
		codec = 'etc2'

	# PVRTC
	elif texture_format == TextureFormat.PVRTC_RGB2:
		args = (0,)
		codec = 'pvrtc'
		mode = 'RGBA'

	elif texture_format == TextureFormat.PVRTC_RGBA2:
		args = (0,)
		codec = 'pvrtc'
		mode = 'RGBA'

	elif texture_format == TextureFormat.PVRTC_RGB4:  # test passed
		args = (0,)
		codec = 'pvrtc'
		mode = 'RGBA'

	elif texture_format == TextureFormat.PVRTC_RGBA4:
		args = (0,)
		codec = 'pvrtc'
		mode = 'RGBA'

	# ASTC
	elif texture_format in [
		TextureFormat.ASTC_RGB_4x4,  # test pass
		TextureFormat.ASTC_RGBA_4x4,  # test pass
	]:
		codec = 'astc'
		args = (4, 4)

	elif texture_format in [
		TextureFormat.ASTC_RGB_5x5,  # test pass
		TextureFormat.ASTC_RGBA_5x5,  # test pass
	]:
		codec = 'astc'
		args = (5, 5)

	elif texture_format in [
		TextureFormat.ASTC_RGB_6x6,  # test pass
		TextureFormat.ASTC_RGBA_6x6,  # test pass
	]:
		codec = 'astc'
		args = (6, 6)

	elif texture_format in [
		TextureFormat.ASTC_RGB_8x8,  # test pass
		TextureFormat.ASTC_RGBA_8x8,  # test pass
	]:
		codec = 'astc'
		args = (8, 8)

	elif texture_format in [
		TextureFormat.ASTC_RGB_10x10,  # test pass
		TextureFormat.ASTC_RGBA_10x10,  # test pass
	]:
		codec = 'astc'
		args = (10, 10)

	elif texture_format in [
		TextureFormat.ASTC_RGB_12x12,  # test pass
		TextureFormat.ASTC_RGBA_12x12,  # test pass
	]:
		codec = 'astc'
		args = (12, 12)

	if not image_data:
		raise EOFError("No Image Data")
	# return Image.new('RGBA')

	if 'Crunched' in texture_format.name:
		# if (version[0] > 2017 or (version[0] == 2017 and version[1] >= 3) #2017.3 and up
		#		or m_TextureFormat == TextureFormat.ETC_RGB4Crunched
		#		or m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched):
		#	# Unity Crunch
		#	image_data = bytes(CrunchFile_U(image_data).decode_level(0))
		#	image_data_size = len(image_data)
		# else: #normal crunch
		# decrunch is using a modified crunch which uses the original crunch and only uses the Unity Version for etc1/2
		image_data = bytes(CrunchFile(image_data).decode_level(0))

	img = Image.frombytes(mode, (texture_2d.m_Width, texture_2d.m_Height), image_data, codec, args)
	if swap:
		channels = img.split()
		img = Image.merge(mode, [channels[x] for x in swap])

	if img and flip:
		return img.transpose(Image.FLIP_TOP_BOTTOM)
	return img
Example #5
0
    def image(self):
        #	cached ?
        image = getattr(self, '_image', False)
        if image:
            return image

        #	implemented?
        if self.format not in IMPLEMENTED_FORMATS:
            #use external tools to extract image
            if sys.platform != 'win32':
                print('Unimplemented image type.')
                return None
            try:
                self._image = processUnimplementedTexture2D(self)
                return self._image
            except NotImplementedError:
                raise NotImplementedError("Unimplemented format %r" %
                                          (self.format))
            except Exception as e:
                print('Error during external extraction\n%s' % e)
                return None

        #	extraction of implemented image
        from PIL import Image
        mode = "RGB" if self.format.pixel_format in ("RGB",
                                                     "RGB16") else "RGBA"
        size = (self.width, self.height)
        data = self.image_data

        # Pillow wants bytes, not bytearrays
        from decrunch import File as CrunchFile
        if self.format in (TextureFormat.DXT1Crunched,
                           TextureFormat.DXT5Crunched,
                           TextureFormat.ETC_RGB4Crunched,
                           TextureFormat.ETC2_RGBA8Crunched):
            data = CrunchFile(data).decode_level(0)
        data = bytes(data)

        if not data or size == (0, 0):
            return None

        # Image from bytes
        if self.format in (TextureFormat.DXT1, TextureFormat.DXT1Crunched):
            codec = "bcn"
            args = (1, )
        elif self.format in (TextureFormat.DXT5, TextureFormat.DXT5Crunched):
            codec = "bcn"
            args = (3, )
        elif self.format == TextureFormat.BC7:
            codec = "bcn"
            args = (7, )
        elif self.format in (TextureFormat.ETC_RGB4, TextureFormat.ETC2_RGB,
                             TextureFormat.ETC2_RGBA1,
                             TextureFormat.ETC2_RGBA8,
                             TextureFormat.ETC2_RGBA8Crunched):
            codec = "etc2"
            args = (
                self.format,
                self.format.pixel_format,
            )
        else:
            codec = "raw"
            args = (self.format.pixel_format, )

        image = Image.frombytes(mode, size, data, codec, args)

        # Apply Fix	~	1. flip image, 2. secondary format fix
        channels = ImageOps.flip(image).split()
        if self.format in [
                TextureFormat.RGB565,  #  7
                TextureFormat.RGBA4444  # 13
        ]:
            channels = tuple(reversed(channels))

        elif self.format in [TextureFormat.ARGB4444  # 2
                             ]:
            channels = (channels[2], channels[1], channels[0], channels[3])

        if len(channels) == 3:
            self._image = Image.merge("RGB", channels)
        else:
            self._image = Image.merge("RGBA", channels)
        return self._image
Example #6
0
    def image(self):
        from PIL import Image
        from decrunch import File as CrunchFile
        import hashlib, os, struct

        if self.format not in IMPLEMENTED_FORMATS:
            raise NotImplementedError("Unimplemented format %r" %
                                      (self.format))

        if self.format in PKM_HEADERS:
            version = b'20'
            if self.format == TextureFormat.ETC_RGB4: version = b'10'
            t = PKM_HEADERS[self.format]
            header = struct.pack('!4s2sbbHHHH', b'PKM ', version, 0, t,
                                 self.width, self.height, self.width,
                                 self.height)
            image_data = header + self.image_data
            sha1 = hashlib.sha1(image_data).hexdigest()
            infile = "%s/image_data_%s.pkm" % (tempfile.gettempdir(), sha1)
            outfile = "%s/image_data_%s.png" % (tempfile.gettempdir(), sha1)
            open(infile, "wb+").write(image_data)
            subprocess.run(
                ["etcpack", infile,
                 tempfile.gettempdir(), "-ext", "PNG"],
                stdout=subprocess.PIPE)
            im = Image.open(outfile)
            im.transpose(Image.FLIP_TOP_BOTTOM)
            os.remove(infile)
            os.remove(outfile)
            return im

        if self.format in (TextureFormat.DXT1, TextureFormat.DXT1Crunched):
            codec = "bcn"
            args = (1, )
        elif self.format in (TextureFormat.DXT5, TextureFormat.DXT5Crunched):
            codec = "bcn"
            args = (3, )
        elif self.format == TextureFormat.BC7:
            codec = "bcn"
            args = (7, )
        else:
            codec = "raw"
            args = (self.format.pixel_format, )

        mode = "RGB" if self.format.pixel_format in ("RGB",
                                                     "RGB;16") else "RGBA"
        size = (self.width, self.height)

        data = self.image_data
        if self.format in (TextureFormat.DXT1Crunched,
                           TextureFormat.DXT5Crunched):
            data = CrunchFile(self.image_data).decode_level(0)

        data = bytes(data)

        if not data and size == (0, 0):
            return None

        img = Image.frombytes(mode, size, data, codec, args)

        if self.format == TextureFormat.RGBA4444:
            a, b, g, r = img.split()
            img = Image.merge("RGBA", (r, g, b, a))

        return img