Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys, time
- # ----------\/-Start of libtxc_dxtn section-\/---------- #
- def EXP5TO8R(packedcol):
- return int((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x07))
- def EXP6TO8G(packedcol):
- return int((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x03))
- def EXP5TO8B(packedcol):
- return int((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x07))
- def EXP4TO8(col):
- return int((col) | ((col) << 4))
- # inefficient. To be efficient, it would be necessary to decode 16 pixels at once
- def dxt135_decode_imageblock(pixdata, img_block_src, i, j, dxt_type):
- color0 = pixdata[img_block_src] | (pixdata[img_block_src + 1] << 8)
- color1 = pixdata[img_block_src + 2] | (pixdata[img_block_src + 3] << 8)
- bits = pixdata[img_block_src + 4] | (pixdata[img_block_src + 5] << 8) | (pixdata[img_block_src + 6] << 16) | (pixdata[img_block_src + 7] << 24)
- # What about big/little endian?
- bit_pos = 2 * (j * 4 + i)
- code = (bits >> bit_pos) & 3
- ACOMP = 255
- if code == 0:
- RCOMP = EXP5TO8R(color0)
- GCOMP = EXP6TO8G(color0)
- BCOMP = EXP5TO8B(color0)
- elif code == 1:
- RCOMP = EXP5TO8R(color1)
- GCOMP = EXP6TO8G(color1)
- BCOMP = EXP5TO8B(color1)
- elif code == 2:
- if (dxt_type > 1) or (color0 > color1):
- RCOMP = ((EXP5TO8R(color0) * 2 + EXP5TO8R(color1)) // 3)
- GCOMP = ((EXP6TO8G(color0) * 2 + EXP6TO8G(color1)) // 3)
- BCOMP = ((EXP5TO8B(color0) * 2 + EXP5TO8B(color1)) // 3)
- else:
- RCOMP = ((EXP5TO8R(color0) + EXP5TO8R(color1)) // 2)
- GCOMP = ((EXP6TO8G(color0) + EXP6TO8G(color1)) // 2)
- BCOMP = ((EXP5TO8B(color0) + EXP5TO8B(color1)) // 2)
- elif code == 3:
- if (dxt_type > 1) or (color0 > color1):
- RCOMP = ((EXP5TO8R(color0) + EXP5TO8R(color1) * 2) // 3)
- GCOMP = ((EXP6TO8G(color0) + EXP6TO8G(color1) * 2) // 3)
- BCOMP = ((EXP5TO8B(color0) + EXP5TO8B(color1) * 2) // 3)
- else:
- RCOMP = 0
- GCOMP = 0
- BCOMP = 0
- if dxt_type == 1: ACOMP = 0
- else:
- # CANNOT happen (I hope)
- print("")
- print("Whoops, something went wrong while decompressing...")
- print("")
- print("Exiting in 5 seconds...")
- time.sleep(5)
- sys.exit(1)
- return ACOMP, RCOMP, GCOMP, BCOMP
- def fetch_2d_texel_rgba_dxt1(srcRowStride, pixdata, i, j):
- """
- Extract the (i,j) pixel from pixdata and return it
- in RCOMP, GCOMP, BCOMP, ACOMP.
- """
- blksrc = ((srcRowStride + 3) // 4 * (j // 4) + (i // 4)) * 8
- test = pixdata[blksrc]
- ACOMP, RCOMP, GCOMP, BCOMP = dxt135_decode_imageblock(pixdata, blksrc, i & 3, j & 3, 1)
- return bytes([RCOMP, GCOMP, BCOMP, ACOMP])
- def fetch_2d_texel_rgba_dxt3(srcRowStride, pixdata, i, j):
- """
- Extract the (i,j) pixel from pixdata and return it
- in RCOMP, GCOMP, BCOMP, ACOMP.
- """
- blksrc = ((srcRowStride + 3) // 4 * (j // 4) + (i // 4)) * 16
- anibble = (pixdata[blksrc + ((j & 3) * 4 + (i & 3)) // 2] >> (4 * (i & 1))) & 0x0f
- ACOMP, RCOMP, GCOMP, BCOMP = dxt135_decode_imageblock(pixdata, blksrc + 8, i & 3, j & 3, 2)
- ACOMP = EXP4TO8(anibble)
- return bytes([RCOMP, GCOMP, BCOMP, ACOMP])
- def fetch_2d_texel_rgba_dxt5(srcRowStride, pixdata, i, j):
- """
- Extract the (i,j) pixel from pixdata and return it
- in RCOMP, GCOMP, BCOMP, ACOMP.
- """
- blksrc = ((srcRowStride + 3) // 4 * (j // 4) + (i // 4)) * 16
- alpha0 = pixdata[blksrc]
- alpha1 = pixdata[blksrc + 1]
- # TODO test this!
- bit_pos = ((j & 3) * 4 + (i & 3)) * 3
- acodelow = pixdata[blksrc + 2 + bit_pos // 8]
- acodehigh = pixdata[blksrc + 3 + bit_pos // 8]
- code = (acodelow >> (bit_pos & 0x07) |
- (acodehigh << (8 - (bit_pos & 0x07)))) & 0x07
- ACOMP, RCOMP, GCOMP, BCOMP = dxt135_decode_imageblock(pixdata, blksrc + 8, i & 3, j & 3, 2)
- if code == 0:
- ACOMP = alpha0
- elif code == 1:
- ACOMP = alpha1
- elif alpha0 > alpha1:
- ACOMP = (alpha0 * (8 - code) + (alpha1 * (code - 1))) // 7
- elif code < 6:
- ACOMP = (alpha0 * (6 - code) + (alpha1 * (code - 1))) // 5
- elif code == 6:
- ACOMP = 0
- else:
- ACOMP = 255
- return bytes([RCOMP, GCOMP, BCOMP, ACOMP])
- def decompress(data, width, height, format_):
- """
- Does the decompression for DXT compressed images.
- """
- output = bytearray(width * height * 4)
- for y in range(height):
- for x in range(width):
- if (format_ == 0x31 or format_ == 0x431):
- outValue = fetch_2d_texel_rgba_dxt1(width, data, x, y)
- pos__ = (y * width + x) * 4
- output[pos__:pos__ + 4] = outValue
- elif (format_ == 0x32 or format_ == 0x432):
- outValue = fetch_2d_texel_rgba_dxt3(width, data, x, y)
- pos__ = (y * width + x) * 4
- output[pos__:pos__ + 4] = outValue
- elif (format_ == 0x33 or format_ == 0x433):
- outValue = fetch_2d_texel_rgba_dxt5(width, data, x, y)
- pos__ = (y * width + x) * 4
- output[pos__:pos__ + 4] = outValue
- return output # Output is a RGBA8_UNORM image
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement