示例#1
0
        protected override void OnOpen(EndianBinaryReader reader)
        {
            Header = new SceGxtHeader(reader);

            Func <EndianBinaryReader, SceGxtTextureInfo> textureInfoGeneratorFunc;

            switch (Header.Version)
            {
            case 0x10000003: textureInfoGeneratorFunc = new Func <EndianBinaryReader, SceGxtTextureInfo>((r) => { return(new SceGxtTextureInfoV301(r)); }); break;

            case 0x10000002: textureInfoGeneratorFunc = new Func <EndianBinaryReader, SceGxtTextureInfo>((r) => { return(new SceGxtTextureInfoV201(r)); }); break;

            case 0x10000001: textureInfoGeneratorFunc = new Func <EndianBinaryReader, SceGxtTextureInfo>((r) => { return(new SceGxtTextureInfoV101(r)); }); break;

            default: throw new Exception("GXT version not implemented");
            }

            TextureInfos = new SceGxtTextureInfo[Header.NumTextures];
            for (int i = 0; i < TextureInfos.Length; i++)
            {
                TextureInfos[i] = textureInfoGeneratorFunc(reader);
            }

            // TODO: any other way to detect these?
            if (Encoding.ASCII.GetString(reader.ReadBytes(4)) == BUVChunk.ExpectedMagicNumber)
            {
                reader.BaseStream.Seek(-4, SeekOrigin.Current);
                BUVChunk = new BUVChunk(reader);
            }

            ReadAllBasePalettes(reader);
            ReadAllTextures(reader);
        }
 private static byte[] PixelProviderP4(BinaryReader reader, SceGxtTextureInfo info)
 {
     byte[] pixelData = new byte[info.DataSize];
     for (int i = 0; i < pixelData.Length; i++)
     {
         byte idx = reader.ReadByte();
         pixelData[i] = (byte)(idx >> 4 | idx << 4);
     }
     return(pixelData);
 }
示例#3
0
        public TextureBundle(BinaryReader reader, SceGxtTextureInfo info)
        {
            reader.BaseStream.Seek(info.DataOffset, SeekOrigin.Begin);

            Width         = info.GetWidth();
            Height        = info.GetHeight();
            PaletteIndex  = info.PaletteIndex;
            RawLineSize   = (int)(info.DataSize / info.GetHeightRounded());
            TextureFormat = info.GetTextureFormat();

            RoundedWidth  = Width;  //info.GetWidthRounded();
            RoundedHeight = Height; //info.GetHeightRounded();

            if (!PixelDataProviders.PixelFormatMap.ContainsKey(TextureFormat) || !PixelDataProviders.ProviderFunctions.ContainsKey(TextureFormat))
            {
                throw new FormatNotImplementedException(TextureFormat);
            }

            PixelFormat = PixelDataProviders.PixelFormatMap[TextureFormat];
            PixelData   = PixelDataProviders.ProviderFunctions[TextureFormat](reader, info);

            SceGxmTextureBaseFormat textureBaseFormat = info.GetTextureBaseFormat();

            // TODO: is this right? PVRTC/PVRTC2 doesn't need this, but everything else does?
            if (textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP &&
                textureBaseFormat != SceGxmTextureBaseFormat.PVRTII2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII4BPP)
            {
                SceGxmTextureType textureType = info.GetTextureType();
                switch (textureType)
                {
                case SceGxmTextureType.Linear:
                    // Nothing to be done!
                    break;

                case SceGxmTextureType.Tiled:
                    // TODO: verify me!
                    PixelData = PostProcessing.UntileTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat);
                    break;

                case SceGxmTextureType.Swizzled:
                case SceGxmTextureType.Cube:
                    // TODO: is cube really the same as swizzled? seems that way from CS' *env* files...
                    PixelData = PostProcessing.UnswizzleTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat);
                    break;

                case (SceGxmTextureType)0xA0000000:
                    // TODO: mehhhhh
                    PixelData = PostProcessing.UnswizzleTexture(PixelData, info.GetWidthRounded(), info.GetHeightRounded(), PixelFormat);
                    break;

                default:
                    throw new TypeNotImplementedException(textureType);
                }
            }
        }
示例#4
0
        private void ReadAllTextures(EndianBinaryReader reader)
        {
            PixelData = new byte[Header.NumTextures][];
            for (int i = 0; i < TextureInfos.Length; i++)
            {
                SceGxtTextureInfo info = TextureInfos[i];

                reader.BaseStream.Seek(info.DataOffset, SeekOrigin.Begin);
                PixelData[i] = reader.ReadBytes((int)info.DataSize);
            }
        }
 private static byte[] PixelProviderU8U8_RGGG(BinaryReader reader, SceGxtTextureInfo info)
 {
     byte[] pixelData = new byte[info.DataSize * 4];
     for (int i = 0; i < pixelData.Length; i += 4)
     {
         pixelData[i + 3] = reader.ReadByte();
         pixelData[i + 0] = pixelData[i + 1] = pixelData[i + 2] = reader.ReadByte();
     }
     ;
     return(pixelData);
 }
示例#6
0
        // Shim function for GXT
        public static byte[] Decompress(BinaryReader reader, SceGxtTextureInfo info)
        {
            byte[] pixelData = new byte[info.DataSize * 8];

            PVRTDecompressPVRTC(
                reader.ReadBytes((int)info.DataSize),
                (info.GetTextureBaseFormat() == SceGxmTextureBaseFormat.PVRT2BPP || info.GetTextureBaseFormat() == SceGxmTextureBaseFormat.PVRTII2BPP ? 1 : 0),
                info.GetWidth(),
                info.GetHeight(),
                (info.GetTextureBaseFormat() == SceGxmTextureBaseFormat.PVRTII2BPP || info.GetTextureBaseFormat() == SceGxmTextureBaseFormat.PVRTII4BPP ? 1 : 0),
                ref pixelData);

            return(pixelData);
        }
 private static byte[] PixelProviderU4U4U4U4_ARGB(BinaryReader reader, SceGxtTextureInfo info)
 {
     byte[] pixelData = new byte[info.DataSize * 4];
     for (int i = 0; i < pixelData.Length; i += 4)
     {
         ushort rgba = reader.ReadUInt16();
         pixelData[i + 0] = (byte)(((rgba >> 4) << 4) & 0xFF);
         pixelData[i + 1] = (byte)(((rgba >> 8) << 4) & 0xFF);
         pixelData[i + 2] = (byte)(((rgba >> 12) << 4) & 0xFF);
         pixelData[i + 3] = (byte)((rgba << 4) & 0xFF);
     }
     ;
     return(pixelData);
 }
示例#8
0
        public static byte[] Decompress(BinaryReader reader, SceGxtTextureInfo info)
        {
            byte[] pixelData = new byte[info.DataSize * 8];

            int pixelOffset = 0;

            for (int y = 0; y < info.GetHeightRounded(); y += 4)
            {
                for (int x = 0; x < info.GetWidthRounded(); x += 4)
                {
                    byte[] decodedBlock = DecompressDxtBlock(reader, info.GetTextureBaseFormat());
                    for (int b = 0; b < dxtOrder.Length; b++)
                    {
                        Buffer.BlockCopy(decodedBlock, b * 4, pixelData, pixelOffset + (dxtOrder[b] * 4), 4);
                    }
                    pixelOffset += decodedBlock.Length;
                }
            }

            return(pixelData);
        }
示例#9
0
        private Bitmap CreateBitmap(int infoIdx, int forcePaletteIdx = -1)
        {
            SceGxtTextureInfo info = TextureInfos[infoIdx];

            ImageBinary imageBinary = new ImageBinary();

            imageBinary.Width            = info.GetWidth();
            imageBinary.Height           = info.GetHeight();
            imageBinary.InputPixelFormat = PSVita.GetPixelDataFormat(info.GetTextureFormat());
            imageBinary.InputEndianness  = Endian.LittleEndian;
            imageBinary.AddInputPixels(PixelData[infoIdx]);

            // TODO: verify all this crap, GXT conversion wrt image [dimension/format/type] is fragile as all hell

            SceGxmTextureBaseFormat textureBaseFormat = info.GetTextureBaseFormat();
            SceGxmTextureType       textureType       = info.GetTextureType();

            if (textureType == SceGxmTextureType.Linear &&
                textureBaseFormat != SceGxmTextureBaseFormat.UBC1 && textureBaseFormat != SceGxmTextureBaseFormat.UBC2 && textureBaseFormat != SceGxmTextureBaseFormat.UBC3 &&
                textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP &&
                textureBaseFormat != SceGxmTextureBaseFormat.PVRTII2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRTII4BPP)
            {
                imageBinary.PhysicalWidth  = (int)(((info.DataSize / imageBinary.Height) * 8) / PSVita.GetBitsPerPixel(textureBaseFormat));
                imageBinary.PhysicalHeight = info.GetHeight();
            }
            else
            {
                imageBinary.PhysicalWidth  = info.GetWidthRounded();
                imageBinary.PhysicalHeight = info.GetHeightRounded();
            }

            if (textureBaseFormat != SceGxmTextureBaseFormat.PVRT2BPP && textureBaseFormat != SceGxmTextureBaseFormat.PVRT4BPP)
            {
                switch (textureType)
                {
                case SceGxmTextureType.Linear:
                    // Nothing to be done!
                    break;

                case SceGxmTextureType.Tiled:
                    // TODO: verify me!
                    imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingTiled3DS;
                    break;

                case SceGxmTextureType.Swizzled:
                case SceGxmTextureType.Cube:
                    // TODO: is cube really the same as swizzled? seems that way from CS' *env* files...
                    imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingSwizzledVita;
                    break;

                case (SceGxmTextureType)0xA0000000:
                    // TODO: this is odd and needs investigation, found ex. in Odin Sphere, Puyo Puyo Tetris, ...
                    imageBinary.InputPixelFormat |= PixelDataFormat.PixelOrderingSwizzledVita;
                    break;
                }
            }

            if (textureBaseFormat == SceGxmTextureBaseFormat.P4 || textureBaseFormat == SceGxmTextureBaseFormat.P8)
            {
                imageBinary.InputPaletteFormat = PSVita.GetPaletteFormat(info.GetTextureFormat());

                if (textureBaseFormat == SceGxmTextureBaseFormat.P4)
                {
                    foreach (byte[] paletteData in P4Palettes)
                    {
                        imageBinary.AddInputPalette(paletteData);
                    }
                }
                else if (textureBaseFormat == SceGxmTextureBaseFormat.P8)
                {
                    foreach (byte[] paletteData in P8Palettes)
                    {
                        imageBinary.AddInputPalette(paletteData);
                    }
                }
            }

            return(imageBinary.GetBitmap(0, forcePaletteIdx != -1 ? forcePaletteIdx : info.PaletteIndex));
        }
示例#10
0
        private static void ProcessInputFile(FileInfo inputFile, DirectoryInfo inputDir, DirectoryInfo outputDir)
        {
            try
            {
                if (!outputDir.Exists)
                {
                    Directory.CreateDirectory(outputDir.FullName);
                }

                string displayPath = inputFile.FullName.Replace(inputDir.FullName, string.Empty).TrimStart(directorySeparators);
                IndentWriteLine("File '{0}'... ", displayPath);
                baseIndent = indent++;

                string relativeDirectory = inputFile.DirectoryName.TrimEnd(directorySeparators).Replace(inputDir.FullName.TrimEnd(directorySeparators), string.Empty).TrimStart(directorySeparators);

                if (keepFiles)
                {
                    string existenceCheckPath    = Path.Combine(outputDir.FullName, relativeDirectory);
                    string existenceCheckPattern = Path.GetFileNameWithoutExtension(inputFile.Name) + "*";
                    if (Directory.Exists(existenceCheckPath) && Directory.EnumerateFiles(existenceCheckPath, existenceCheckPattern).Any())
                    {
                        IndentWriteLine("Already exists.");
                        return;
                    }
                }

                using (FileStream fileStream = new FileStream(inputFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    GxtBinary gxtInstance = new GxtBinary(fileStream);

                    for (int i = 0; i < gxtInstance.TextureInfos.Length; i++)
                    {
                        string   outputFilename = string.Format("{0} (Texture {1}).png", Path.GetFileNameWithoutExtension(inputFile.Name), i);
                        FileInfo outputFile     = new FileInfo(Path.Combine(outputDir.FullName, relativeDirectory, outputFilename));

                        SceGxtTextureInfo info = gxtInstance.TextureInfos[i];

                        IndentWriteLine("Texture #{0}: {1}x{2} ({3}, {4})", (i + 1), info.GetWidth(), info.GetHeight(), info.GetTextureFormat(), info.GetTextureType());
                        indent++;

                        if (!outputFile.Directory.Exists)
                        {
                            Directory.CreateDirectory(outputFile.Directory.FullName);
                        }
                        gxtInstance.Textures[i].Save(outputFile.FullName, System.Drawing.Imaging.ImageFormat.Png);

                        indent--;
                    }

                    if (gxtInstance.BUVChunk != null)
                    {
                        indent++;
                        for (int i = 0; i < gxtInstance.BUVTextures.Length; i++)
                        {
                            string   outputFilename = string.Format("{0} (Block {1}).png", Path.GetFileNameWithoutExtension(inputFile.Name), i);
                            FileInfo outputFile     = new FileInfo(Path.Combine(outputDir.FullName, relativeDirectory, outputFilename));

                            BUVEntry entry = gxtInstance.BUVChunk.Entries[i];

                            IndentWriteLine("Block #{0}: {1}x{2} (Origin X:{3}, Y:{4})", (i + 1), entry.Width, entry.Height, entry.X, entry.Y);
                            indent++;

                            if (!outputFile.Directory.Exists)
                            {
                                Directory.CreateDirectory(outputFile.Directory.FullName);
                            }
                            gxtInstance.BUVTextures[i].Save(outputFile.FullName, System.Drawing.Imaging.ImageFormat.Png);

                            indent--;
                        }
                        indent--;
                    }
                }
            }
#if !DEBUG
            catch (VersionNotImplementedException vniEx)
            {
                IndentWriteLine("GXT version {0:D2} (0x{1:X8}) not implemented.", (vniEx.Version & 0xFFFF), vniEx.Version);
            }
            catch (FormatNotImplementedException fniEx)
            {
                IndentWriteLine("Format '{0}' not implemented.", fniEx.Format);
            }
            catch (PaletteNotImplementedException pniEx)
            {
                IndentWriteLine("Palette '{0}' not implemented.", pniEx.Format);
            }
            catch (TypeNotImplementedException tniEx)
            {
                IndentWriteLine("Type '{0}' not implemented.", tniEx.Type);
            }
            catch (UnknownMagicException umEx)
            {
                IndentWriteLine("Unknown magic number: {0}.", umEx.Message);
            }
            catch (Exception ex)
            {
                IndentWriteLine("Exception occured: {0}.", ex.Message);
            }
#endif
            finally
            {
                indent = baseIndent;
            }
        }
示例#11
0
 private static byte[] PixelProviderPVRTC(BinaryReader reader, SceGxtTextureInfo info)
 {
     return(Compression.PVRTC.Decompress(reader, info));
 }
示例#12
0
 private static byte[] PixelProviderDirect(BinaryReader reader, SceGxtTextureInfo info)
 {
     return(reader.ReadBytes((int)info.DataSize));
 }