def readGFD(f): gfd = GFDData() pos = 0 header = GFDHeader() header.data(f, pos) if header.magic != b'Gfx2': raise ValueError("Invalid file header!") pos += header.size blockB = False blockC = False images = 0 imgInfo = 0 gfd.dim = [] gfd.width = [] gfd.height = [] gfd.depth = [] gfd.numMips = [] gfd.format = [] gfd.aa = [] gfd.use = [] gfd.imageSize = [] gfd.imagePtr = [] gfd.mipSize = [] gfd.mipPtr = [] gfd.tileMode = [] gfd.swizzle = [] gfd.alignment = [] gfd.pitch = [] gfd.compSel = [] gfd.realSize = [] gfd.dataSize = [] gfd.data = [] gfd.mipOffsets = [] gfd.mipData = {} while pos < len( f ): # Loop through the entire file, stop if reached the end of the file. block = GFDBlockHeader() block.data(f, pos) if block.magic != b'BLK{': print(block.magic) print(pos) raise ValueError("Invalid block header!") pos += block.size if block.type_ == 0x0B: imgInfo += 1 blockB = True surface = GX2Surface() surface.data(f, pos) pos += surface.size if surface.numMips > 14: print("") print("Invalid number of mipmaps for image " + str(imgInfo - 1)) print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) mipOffsets = [] for i in range(13): mipOffsets.append(f[i * 4 + pos] << 24 | f[i * 4 + 1 + pos] << 16 | f[i * 4 + 2 + pos] << 8 | f[i * 4 + 3 + pos]) gfd.mipOffsets.append(mipOffsets) pos += 68 compSel = [] for i in range(4): comp = f[pos + i] if comp == 4: # Sorry, but this is unsupported. comp = i compSel.append(comp) pos += 24 gfd.dim.append(surface.dim) gfd.width.append(surface.width) gfd.height.append(surface.height) gfd.depth.append(surface.depth) gfd.numMips.append(surface.numMips) gfd.format.append(surface.format_) gfd.aa.append(surface.aa) gfd.use.append(surface.use) gfd.imageSize.append(surface.imageSize) gfd.imagePtr.append(surface.imagePtr) gfd.mipSize.append(surface.mipSize) gfd.mipPtr.append(surface.mipPtr) gfd.tileMode.append(surface.tileMode) gfd.swizzle.append(surface.swizzle) gfd.alignment.append(surface.alignment) gfd.pitch.append(surface.pitch) gfd.compSel.append(compSel) if surface.format_ in BCn_formats: gfd.realSize.append( ((surface.width + 3) >> 2) * ((surface.height + 3) >> 2) * (addrlib.surfaceGetBitsPerPixel(surface.format_) // 8)) else: gfd.realSize.append( surface.width * surface.height * (addrlib.surfaceGetBitsPerPixel(surface.format_) // 8)) elif block.type_ == 0x0C: images += 1 blockC = True gfd.dataSize.append(block.dataSize) gfd.data.append(f[pos:pos + block.dataSize]) pos += block.dataSize elif block.type_ == 0x0D: gfd.mipData[images - 1] = f[pos:pos + block.dataSize] pos += block.dataSize else: pos += block.dataSize if images != imgInfo: print("") print("Whoops, fail! XD") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if blockB: if not blockC: print("") print("Image info was found but no Image data was found.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if not blockB: if not blockC: print("") print("No Image was found in this file.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) elif blockC: print("") print("Image data was found but no Image info was found.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) gfd.numImages = images return gfd
def writeGFD(f, tileMode, swizzle_, SRGB, n, numImages): width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS( f, SRGB) if 0 in [width, dataSize] and data == []: if n != (numImages - 1): print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if format_ not in formats: print("") print("Unsupported DDS format!") print("") if n != (numImages - 1): print("") print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if numMips > 13: print("") print("Invalid number of mipmaps for " + f) print("") if n != (numImages - 1): print("") print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 if format_ in BCn_formats: if format_ in [0x31, 0x431, 0x234, 0x34]: align = 0xEE4 mipAlign = 0xFC0 else: align = 0x1EE4 mipAlign = 0x1FC0 else: align = 0x6E4 mipAlign = 0x7C0 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if surfOut.depth != 1: print("") print("Unsupported depth!") print("") if n != (numImages - 1): print("Continuing in 5 seconds...") time.sleep(5) return b'' else: print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if tileMode in [1, 2, 3, 16]: s = 0 else: s = 0xd0000 s |= swizzle_ << 8 swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: print( str(i) + ": " + str(max(1, width >> i)) + "x" + str(max(1, height >> i))) offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ in BCn_formats) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: offset += padSize if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(offset) mipSize += len(data) swizzled_data.append( addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) compSels = ["R", "G", "B", "A", "0", "1"] """print("") print("// ----- GX2Surface Info ----- ") print(" dim = 1") print(" width = " + str(width)) print(" height = " + str(height)) print(" depth = 1") print(" numMips = " + str(numMips)) print(" format = " + formats[format_]) print(" aa = 0") print(" use = 1") print(" imageSize = " + str(imageSize)) print(" mipSize = " + str(mipSize)) print(" tileMode = " + str(tileMode)) print(" swizzle = " + str(s) + ", " + hex(s)) print(" alignment = " + str(alignment)) print(" pitch = " + str(pitch)) print("") print(" GX2 Component Selector:") print(" Red Channel: " + str(compSels[compSel[0]])) print(" Green Channel: " + str(compSels[compSel[1]])) print(" Blue Channel: " + str(compSels[compSel[2]])) print(" Alpha Channel: " + str(compSels[compSel[3]])) print("") print(" bits per pixel = " + str(bpp << 3)) print(" bytes per pixel = " + str(bpp)) print(" realSize = " + str(len(imageData)))""" block_head_struct = GFDBlockHeader() gx2surf_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xb, 0x9c, 0, 0) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) align_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, align, 0, 0) image_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xc, imageSize, 0, 0) mipAlign_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, mipAlign, 0, 0) mip_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xd, mipSize, 0, 0) output = gx2surf_blk_head + gx2surf if numMips > 1: i = 0 for offset in mipOffsets: output += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): output += 0.to_bytes(4, 'big') else: output += b"\x00" * 56 output += numMips.to_bytes(4, 'big') output += b"\x00" * 4 output += 1.to_bytes(4, 'big') for value in compSel: output += value.to_bytes(1, 'big') output += b"\x00" * 20 output += align_blk_head output += b"\x00" * align output += image_blk_head output += swizzled_data[0] if numMips > 1: output += mipAlign_blk_head output += b"\x00" * mipAlign output += mip_blk_head i = 0 for data in swizzled_data: if i != 0: output += data i += 1 return output
def writeGX2Surface_Data(f, tileMode, swizzle_, SRGB): width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS( f, SRGB) if 0 in [width, dataSize] and data == []: return False if format_ not in formats: print("Unsupported DDS format!") return b'', [] if numMips > 13: print("Invalid number of mipmaps!") return b'', [] imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if surfOut.depth != 1: print("Unsupported depth!") return b'', [] if tileMode in [1, 2, 3, 16]: s = 0 else: s = 0xd0000 s |= swizzle_ swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ in BCn_formats) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(mipSize) mipSize += len(data) swizzled_data.append( addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) if numMips > 1: i = 0 for offset in mipOffsets: gx2surf += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): gx2surf += 0.to_bytes(4, 'big') else: gx2surf += b"\x00" * 56 gx2surf += numMips.to_bytes(4, 'big') gx2surf += b"\x00" * 4 gx2surf += 1.to_bytes(4, 'big') for value in compSel: gx2surf += value.to_bytes(1, 'big') gx2surf += b"\x00" * 20 return gx2surf, swizzled_data
def FTEXtoDDS(ftex_pos, f, name, folder): ftex = f[ftex_pos:ftex_pos + 0xC0] pos = 4 surface = GX2Surface() surface.data(ftex, pos) pos += surface.size format_ = surface.format_ if format_ in formats: if surface.numMips > 14: print('') print(name) print("Number of mipmaps exceeded 13") return 0, 0 mipOffsets = [] for i in range(13): mipOffsets.append(ftex[i * 4 + pos] << 24 | ftex[i * 4 + 1 + pos] << 16 | ftex[i * 4 + 2 + pos] << 8 | ftex[i * 4 + 3 + pos]) pos += 68 compSel = [] for i in range(4): comp = ftex[pos + i] if comp == 4: # Sorry, but this is unsupported. comp = i compSel.append(comp) dataSize = surface.imageSize mipSize = surface.mipSize data_pos = struct.unpack(">I", ftex[0xB0:0xB4])[0] + ftex_pos + 0xB0 mip_pos = struct.unpack(">I", ftex[0xB4:0xB8])[0] data = f[data_pos:data_pos + dataSize] if not (mip_pos and mipSize): mipData = b"" else: mip_pos += ftex_pos + 0xB4 mipData = f[mip_pos:mip_pos + mipSize] numMips = surface.numMips width = surface.width height = surface.height depth = surface.depth dim = surface.dim aa = surface.aa tileMode = surface.tileMode swizzle_ = surface.swizzle bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 if format_ in BCn_formats: realSize = ((width + 3) >> 2) * ((height + 3) >> 2) * bpp else: realSize = width * height * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, depth, dim, tileMode, aa, 0) if aa: print('') print(name) print("Unsupported AA mode") return 0, 0 if format_ == 0x1a or format_ == 0x41a: format__ = 28 elif format_ == 0x19: format__ = 24 elif format_ == 0x8: format__ = 85 elif format_ == 0xa: format__ = 86 elif format_ == 0xb: format__ = 115 elif format_ == 0x1: format__ = 61 elif format_ == 0x7: format__ = 49 elif format_ == 0x2: format__ = 112 elif format_ == 0x31 or format_ == 0x431: format__ = "BC1" elif format_ == 0x32 or format_ == 0x432: format__ = "BC2" elif format_ == 0x33 or format_ == 0x433: format__ = "BC3" elif format_ == 0x34: format__ = "BC4U" elif format_ == 0x234: format__ = "BC4S" elif format_ == 0x35: format__ = "BC5U" elif format_ == 0x235: format__ = "BC5S" if surfOut.depth != 1: print('') print(name) print("Unsupported depth") return 0, 0 result = [] for level in range(numMips): if level != 0: if level == 1: mipOffset = mipOffsets[level - 1] - surfOut.surfSize else: mipOffset = mipOffsets[level - 1] surfOut = addrlib.getSurfaceInfo(format_, width, height, depth, dim, tileMode, aa, level) data = mipData[mipOffset:mipOffset + surfOut.surfSize] deswizzled = addrlib.deswizzle(max(1, width >> level), max(1, height >> level), surfOut.height, format_, surfOut.tileMode, swizzle_, surfOut.pitch, surfOut.bpp, data) if format_ in BCn_formats: size = ((max(1, width >> level) + 3) >> 2) * ( (max(1, height >> level) + 3) >> 2) * bpp else: size = max(1, width >> level) * max(1, height >> level) * bpp if format_ == 0xa: data = form_conv.toDDSrgb5a1(deswizzled[:size]) elif format_ == 0xb: data = form_conv.toDDSrgba4(deswizzled[:size]) else: data = deswizzled[:size] result.append(data) hdr = dds.generateHeader(numMips, width, height, format__, compSel, realSize, format_ in BCn_formats) with open(folder + "/" + name + ".dds", "wb") as output: output.write(hdr) for data in result: output.write(data) return format_, numMips else: print('') print(name) print("Unsupported format: " + hex(format_)) return format_, 0
def writeGFD(f): tileMode = 4 width, height, format_, fourcc, dataSize, compSel, numMips, data = dds.readDDS(f) imageData = data[:dataSize] mipData = data[dataSize:] numMips += 1 if format_ == 0x33: align = 0x1EE4 mipAlign = 0x1FC0 else: align = 0x6E4 mipAlign = 0x7C0 bpp = addrlib.surfaceGetBitsPerPixel(format_) >> 3 alignment = 512 * bpp surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, 0) pitch = surfOut.pitch if format_ == 0x33: s = 0x40000 else: s = 0xd0000 swizzled_data = [] imageSize = 0 mipSize = 0 mipOffsets = [] for i in range(numMips): if i == 0: data = imageData imageSize = surfOut.surfSize else: offset, dataSize = get_curr_mip_off_size(width, height, bpp, i, format_ == 0x33) data = mipData[offset:offset + dataSize] surfOut = addrlib.getSurfaceInfo(format_, width, height, 1, 1, tileMode, 0, i) padSize = surfOut.surfSize - dataSize data += padSize * b"\x00" if i != 0: offset += padSize if i == 1: mipOffsets.append(imageSize) else: mipOffsets.append(offset) mipSize += len(data) swizzled_data.append(addrlib.swizzle(max(1, width >> i), max(1, height >> i), surfOut.height, format_, surfOut.tileMode, s, surfOut.pitch, surfOut.bpp, data)) block_head_struct = GFDBlockHeader() gx2surf_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xb, 0x9c, 0, 0) gx2surf_struct = GX2Surface() gx2surf = gx2surf_struct.pack(1, width, height, 1, numMips, format_, 0, 1, imageSize, 0, mipSize, 0, tileMode, s, alignment, pitch) align_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, align, 0, 0) image_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xc, imageSize, 0, 0) mipAlign_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 2, mipAlign, 0, 0) mip_blk_head = block_head_struct.pack(b"BLK{", 32, 1, 0, 0xd, mipSize, 0, 0) output = gx2surf_blk_head + gx2surf if numMips > 1: i = 0 for offset in mipOffsets: output += offset.to_bytes(4, 'big') i += 1 for z in range(14 - i): output += (0).to_bytes(4, 'big') else: output += b"\x00" * 56 output += numMips.to_bytes(4, 'big') output += b"\x00" * 4 output += (1).to_bytes(4, 'big') for value in compSel: output += value.to_bytes(1, 'big') output += b"\x00" * 20 output += align_blk_head output += b"\x00" * align output += image_blk_head output += swizzled_data[0] if numMips > 1: output += mipAlign_blk_head output += b"\x00" * mipAlign output += mip_blk_head i = 0 for data in swizzled_data: if i != 0: output += data i += 1 return output
def main(): """ This place is a mess... """ print("GTX Extractor v5.0") print("(C) 2014 Treeki, 2015-2017 AboodXD") if len(sys.argv) != 2: if len(sys.argv) != 3: print("") print("Usage (If converting from .gtx to .dds, and using source code): python gtx_extract.py input") print("Usage (If converting from .gtx to .dds, and using exe): gtx_extract.exe input") print( "Usage (If converting from .dds to .gtx, and using source code): python gtx_extract.py input(.dds) input(.gtx)") print("Usage (If converting from .dds to .gtx, and using exe): gtx_extract.exe input(.dds) input(.gtx)") print("") print("Supported formats:") print(" - GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM") print(" - GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB") print(" - GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM") print(" - GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM") print(" - GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM") print(" - GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM") print(" - GX2_SURFACE_FORMAT_TC_R8_UNORM") print(" - GX2_SURFACE_FORMAT_TC_R8_G8_UNORM") print(" - GX2_SURFACE_FORMAT_TC_R4_G4_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC1_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC1_SRGB") print(" - GX2_SURFACE_FORMAT_T_BC2_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC2_SRGB") print(" - GX2_SURFACE_FORMAT_T_BC3_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC3_SRGB") print(" - GX2_SURFACE_FORMAT_T_BC4_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC4_SNORM") print(" - GX2_SURFACE_FORMAT_T_BC5_UNORM") print(" - GX2_SURFACE_FORMAT_T_BC5_SNORM") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if sys.argv[1].endswith('.gtx'): with open(sys.argv[1], "rb") as inf: print('Converting: ' + sys.argv[1]) inb = inf.read() inf.close() elif sys.argv[1].endswith('.dds'): with open(sys.argv[2], "rb") as inf: with open(sys.argv[1], "rb") as img: print('Converting: ' + sys.argv[1]) inb = inf.read() img1 = img.read() inf.close() img.close() compSel = ["Red", "Green", "Blue", "Alpha", "0", "1"] gfd = readGFD(inb) for i in range(gfd.numImages): print("") print("// ----- GX2Surface Info ----- ") print(" dim = " + str(gfd.dim[i])) print(" width = " + str(gfd.width[i])) print(" height = " + str(gfd.height[i])) print(" depth = " + str(gfd.depth[i])) print(" numMips = " + str(gfd.numMips[i])) if gfd.format[i] in formats: print(" format = " + formats[gfd.format[i]]) else: print(" format = " + hex(gfd.format[i])) print(" aa = " + str(gfd.aa[i])) print(" use = " + str(gfd.use[i])) print(" imageSize = " + str(gfd.imageSize[i])) print(" mipSize = " + str(gfd.mipSize[i])) print(" tileMode = " + str(gfd.tileMode[i])) print(" swizzle = " + str(gfd.swizzle[i]) + ", " + hex(gfd.swizzle[i])) print(" alignment = " + str(gfd.alignment[i])) print(" pitch = " + str(gfd.pitch[i])) bpp = addrlib.surfaceGetBitsPerPixel(gfd.format[i]) print("") print(" GX2 Component Selector:") print(" Channel 1: " + str(compSel[gfd.compSel[i][0]])) print(" Channel 2: " + str(compSel[gfd.compSel[i][1]])) print(" Channel 3: " + str(compSel[gfd.compSel[i][2]])) print(" Channel 4: " + str(compSel[gfd.compSel[i][3]])) print("") print(" bits per pixel = " + str(bpp)) print(" bytes per pixel = " + str(bpp // 8)) print(" realSize = " + str(gfd.realSize[i])) name = os.path.splitext(sys.argv[1])[0] if sys.argv[1].endswith('.gtx'): if gfd.numImages > 1: name += str(i) hdr, data = get_deswizzled_data(i, gfd.numImages, gfd.width[i], gfd.height[i], gfd.depth[i], gfd.dim[i], gfd.format[i],gfd.aa[i], gfd.tileMode[i], gfd.swizzle[i], gfd.pitch[i], gfd.compSel[i], gfd.data[i], gfd.realSize[i], gfd.surfOut[i]) if data == b'': pass else: output = open(name + '.dds', 'wb+') output.write(hdr) output.write(data) output.close() elif sys.argv[1].endswith('.dds'): if gfd.numImages > 1: print("") print("Nope, you still can't do this... :P") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) data = writeGFD(gfd.width[i], gfd.height[i], gfd.depth[i], gfd.dim[i], gfd.format[i], gfd.aa[i], gfd.tileMode[i], gfd.swizzle[i], gfd.pitch[i], gfd.imageSize[i], inb, img1, gfd.surfOut[i]) if os.path.isfile(name + ".gtx"): # i = 2 # while os.path.isfile(name + str(i) + ".gtx"): # i += 1 # output = open(name + str(i) + ".gtx", 'wb+') output = open(name + "2.gtx", 'wb+') else: output = open(name + ".gtx", 'wb+') output.write(data) output.close() print('') print('Finished converting: ' + sys.argv[1])
def readGFD(f): gfd = GFDData() pos = 0 header = GFDHeader() header.data(f, pos) if header.magic != b'Gfx2': raise ValueError("Invalid file header!") pos += header.size blockB = False blockC = False images = 0 imgInfo = 0 gfd.dim = [] gfd.width = [] gfd.height = [] gfd.depth = [] gfd.numMips = [] gfd.format = [] gfd.aa = [] gfd.use = [] gfd.imageSize = [] gfd.imagePtr = [] gfd.mipSize = [] gfd.mipPtr = [] gfd.tileMode = [] gfd.swizzle = [] gfd.alignment = [] gfd.pitch = [] gfd.compSel = [] gfd.surfOut = [] gfd.realSize = [] gfd.dataSize = [] gfd.data = [] while pos < len(f): # Loop through the entire file, stop if reached the end of the file. block = GFDBlockHeader() block.data(f, pos) if block.magic != b'BLK{': raise ValueError("Invalid block header!") pos += block.size if block.type_ == 0x0B: imgInfo += 1 blockB = True surface = GX2Surface() surface.data(f, pos) pos += surface.size pos += 68 compSel = [] for i in range(4): compSel.append(f[pos + i]) pos += 24 if surface.format_ in BCn_formats: width = surface.width // 4 height = surface.height // 4 else: width = surface.width height = surface.height surfOut = addrlib.getSurfaceInfo(surface.format_, width, height, surface.depth, surface.dim, surface.tileMode, surface.aa, 0) gfd.dim.append(surface.dim) gfd.width.append(surface.width) gfd.height.append(surface.height) gfd.depth.append(surface.depth) gfd.numMips.append(surface.numMips) gfd.format.append(surface.format_) gfd.aa.append(surface.aa) gfd.use.append(surface.use) gfd.imageSize.append(surface.imageSize) gfd.imagePtr.append(surface.imagePtr) gfd.mipSize.append(surface.mipSize) gfd.mipPtr.append(surface.mipPtr) gfd.tileMode.append(surface.tileMode) gfd.swizzle.append(surface.swizzle) gfd.alignment.append(surface.alignment) gfd.pitch.append(surfOut.pitch) gfd.compSel.append(compSel) gfd.surfOut.append(surfOut) if surface.format_ in BCn_formats: gfd.realSize.append(((surface.width + 3) >> 2) * ((surface.height + 3) >> 2) * ( addrlib.surfaceGetBitsPerPixel(surface.format_) // 8)) else: gfd.realSize.append( surface.width * surface.height * (addrlib.surfaceGetBitsPerPixel(surface.format_) // 8)) elif block.type_ == 0x0C: images += 1 blockC = True gfd.dataSize.append(block.dataSize) gfd.data.append(f[pos:pos + block.dataSize]) pos += block.dataSize else: pos += block.dataSize if images != imgInfo: print("") print("Whoops, fail! XD") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if blockB: if not blockC: print("") print("Image info was found but no Image data was found.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) if not blockB: if not blockC: print("") print("No Image was found in this file.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) elif blockC: print("") print("Image data was found but no Image info was found.") print("") print("Exiting in 5 seconds...") time.sleep(5) sys.exit(1) gfd.numImages = images return gfd