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
예제 #3
0
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
예제 #4
0
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
예제 #5
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
예제 #6
0
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])
예제 #7
0
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