pngdxt

Why are these red and green squares showing up on my PNG?


I have a VTF file that looks like this inside VTFEdit:

Image as it appears inside VTFEdit (or as a tga/png/jpg)

I tried to convert it to a PNG in Python using the code below:

import texture2ddecoder, numpy, cv2
from PIL import Image

img_width =  64
img_height = 64
encoded_binary = open('bracketsTest.vtf','rb').read()

#decompressing dxt5 (compression used for this VTF file) to get actual pixel colors, returns BGRA bytes
decoded_binary = texture2ddecoder.decode_bc5(encoded_binary, img_width, img_height)

#creating RGBA png, converting from BGRA (no support for BRGA in PIL it seems)
dec_img = Image.frombytes("RGBA", (img_width, img_height), decoded_binary, 'raw', ("BGRA"))

dec_img.show()
dec_img.save('testpng.png')

And the resulting image came out like this: Screenshot of resulting 64x64 PNG image

As the resulting image does not look the same as it does in VTFEdit, obviously something went wrong. I suspected that it was an issue with the color channel going from BGRA (VTFs are BRGA by default + texture2ddecoder produces BRGA bytes when decompressing) to RGBA, so I tried the following code to convert the image from RGBA to BRGA:

# trying to convert png back to BGRA
image = cv2.imread('testpng.png')
image_bgra = cv2.cvtColor(image, cv2.COLOR_RGBA2BGRA)
cv2.imshow('image',image_bgra)

But the resulting image came out basically the same as before the conversion only with blue squares instead of red ones. What's going on here and how can I fix it? Is there a name for these odd squares?


Solution

  • DXT5 is actually known as Block Compression 3 (BC3). In my case, I incorrectly assumed BC5 = DXT5, so the decompression was wrong (see this wikipedia article for a better explanation). I changed the line decoded_binary = texture2ddecoder.decode_bc5(encoded_binary, img_width, img_height) to decoded_binary = texture2ddecoder.decode_bc3(encoded_binary, img_width, img_height) and the resulting image looked like this:

    Decompression after BC3 (header+low-res thumbnail data still included)

    There are still some odd squares at the top, but deleting/ignoring the header info and low-res thumbnail data seems to fix it:

    Decompression after BC3 (header+low-res thumbnail data not included

    Know your decompression algorithms!!!