v 0. Pasted by Anonymous as python at 2008-10-05 15:45:41 MSK and set expiration to never.
v 1. Edited by _W as python at 2008-10-05 16:34:04 MSK and set expiration to never.

Paste will expire never.

  1. import zlib
  2. import struct
  3. import sys
  4.  
  5. try:
  6.     input_dds_filename = sys.argv[1]
  7. except IndexError:
  8.     print "usage: python zdxt.py input_dxt1.dds"
  9.     exit(1)
  10.    
  11. data = open(input_dds_filename, 'rb').read()
  12.  
  13. def cm(d):
  14.     return zlib.compress(d, 9)
  15.    
  16. def cml(d):
  17.     return len(cm(d))
  18.  
  19. def interleave(a0, a1):
  20.     return ''.join((aa0 + aa1 for aa0, aa1 in zip(a0, a1)))   
  21. def unleave(data):
  22.     return data[0::2], data[1::2]
  23.        
  24. def decompose_colors_indices(img_data, w, h):
  25.     blocks = [img_data[i*8:i*8 + 8] for i in range(w*h/16)]
  26.  
  27.     colors = ''.join([b[0:4] for b in blocks])
  28.     indices = ''.join([b[4:8] for b in blocks])
  29.    
  30.     return colors, indices
  31.  
  32. def prepare_and_check(data):   
  33.     header, img_data = data[:128], data[128:]
  34.  
  35.     assert header[0:4] == "DDS "
  36.     assert header[0x54:0x58] == "DXT1", ("only DXT1 compression test is implemented (got %s)" % header[0x54:0x58])
  37.     h, w = struct.unpack("<II", header[12:20])
  38.    
  39.     if struct.unpack("<I", header[0x6c:0x70])[0] & 0x00000008:
  40.         print >> sys.stderr, "warning, mipmaps and non-main surfaces are ignored."
  41.         img_data = img_data[:w*h / 2]
  42.    
  43.     assert w%4 == 0 and h%4 == 0
  44.     #print "size:", w, h
  45.    
  46.     return header, img_data, w, h
  47.    
  48.  
  49. def compress_dxt1(header, img_data, w, h):
  50.     colors, indices = decompose_colors_indices(img_data, w, h)
  51.     return cm(header), cm(indices), cm(colors)
  52.    
  53. def decompress(header, indices, colors):
  54.     header, indices, colors = map(zlib.decompress, (header, indices, colors))
  55.  
  56.     block_indices = [indices[i:i+4] for i in range(0, len(indices), 4) ]
  57.     block_colors = [colors[i:i+4] for i in range(0, len(colors), 4) ]
  58.    
  59.     assert len(block_indices) == len(block_colors)
  60.     blocks = [c + i for c, i in zip(block_colors, block_indices)]
  61.    
  62.     img_data = ''.join(blocks)
  63.     return header + img_data
  64.    
  65.  
  66. header, img_data, w, h = prepare_and_check(data)
  67. data = header + img_data
  68. tmp = compress_dxt1(header, img_data, w, h)
  69. data2 = decompress(*tmp)
  70.  
  71. assert data == data2
  72.  
  73. #print "decomposed compression:", sum(map(len, tmp))
  74. #print "simple compression:    ", cml(data)
  75. #print "original:              ", len(data)
  76.  
  77. print "%.2f%%" % (100.0*sum(map(len, tmp)) / len(data)), "%.2f%%" % (100.0*cml(data) / len(data))
  78.  
  79. open('img_dxtex.test.dds', 'wb').write(data2)