示例#1
0
        public void Save(Stream file)
        {
            int width    = (Image.Width + 0x7) & ~0x7;
            int height   = (Image.Height + 0x7) & ~0x7;
            var settings = new ImageSettings(Support.Format[header.imageFormat], width, height)
            {
                Swizzle = new ImgcSwizzle(width, height)
            };

            byte[] pic = Kolors.Save(Image, settings);

            using (var bw = new BinaryWriterX(file, true))
            {
                //Header
                header.width  = (short)Image.Width;
                header.height = (short)Image.Height;

                //tile table
                var    table     = new MemoryStream();
                byte[] importPic = Deflate(pic, Support.Format[header.imageFormat].BitDepth, out table);

                //Table
                bw.BaseStream.Position = 0x48;
                var comp = Compressor.Compress(table, tableComp);
                bw.Write(comp);
                header.tableSize1 = comp.Length;
                header.tableSize2 = (header.tableSize1 + 3) & ~3;

                //Image
                bw.BaseStream.Position = 0x48 + header.tableSize2;
                header.imageFormat     = (editMode) ? (byte)28 : header.imageFormat;
                comp = Compressor.Compress(new MemoryStream(importPic), picComp);
                bw.Write(comp);
                bw.WriteAlignment(4);
                header.imgDataSize = comp.Length;

                //Header
                bw.BaseStream.Position = 0;
                bw.WriteType(header);
            }
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="output"></param>
        public void Save(Stream output)
        {
            using (var bw = new BinaryWriterX(output, true))
            {
                // Updates
                Header.Width  = (short)Texture.Width;
                Header.Height = (short)Texture.Height;

                // Header
                bw.WriteType(Header);
                bw.WriteAlignment();
                bw.WriteString(FileName, Encoding.ASCII, false);
                bw.WriteAlignment();

                // Setup
                if (Header.Format == ImageFormat.Palette_8)
                {
                    var settings = new IndexedImageSettings(IndexEncodings[(int)Header.Format], PaletteEncodings[(int)Header.Format], Header.Width, Header.Height)
                    {
                        QuantizationSettings = new QuantizationSettings(new WuColorQuantizer(6, 3), Header.Width, Header.Height)
                        {
                            ColorCount    = 256,
                            ParallelCount = 8
                        }
                    };
                    var data = Kolors.Save(Texture, settings);

                    bw.Write(data.indexData);
                    bw.Write(data.paletteData);
                }
                else
                {
                    var settings = new ImageSettings(Encodings[(int)Header.Format], Header.Width, Header.Height);
                    var data     = Kolors.Save(Texture, settings);

                    bw.Write(data);
                }
            }
        }
示例#3
0
        public void Save(Stream output)
        {
            using (var bw = new BinaryWriterX(output, ByteOrder))
            {
                if (SwitchUnknownData != null)
                {
                    HeaderInfo.MipMapCount--;
                }
                Header.Block1 = (uint)((int)HeaderInfo.Version | (HeaderInfo.Unknown1 << 12) | (HeaderInfo.Unused1 << 24) | ((int)HeaderInfo.AlphaChannelFlags << 28));
                Header.Block2 = (uint)(HeaderInfo.MipMapCount | (HeaderInfo.Width << 6) | (HeaderInfo.Height << 19));
                Header.Block3 = (uint)(HeaderInfo.Unknown2 | ((int)HeaderInfo.Format << 8) | (HeaderInfo.Unknown3 << 16));
                bw.WriteType(Header);
                if (HeaderInfo.Version == Version._Switchv1 && SwitchUnknownData != null)
                {
                    bw.Write(SwitchUnknownData);
                }

                //var format = HeaderInfo.Format.ToString().StartsWith("DXT1") ? Format.DXT1 : HeaderInfo.Format.ToString().StartsWith("DXT5") ? Format.DXT5 : HeaderInfo.Format;
                var encoding = (HeaderInfo.Version == Version._Switchv1) ? SwitchFormats[HeaderInfo.Format] : Formats[HeaderInfo.Format];

                // Mipmap Downsampling
                if (Bitmaps.Count > 1 && HeaderInfo.MipMapCount > 1)
                {
                    var firstBitmap = Bitmaps[0].Image;
                    var width       = firstBitmap.Width;
                    var height      = firstBitmap.Height;
                    for (var i = 0; i < HeaderInfo.MipMapCount - 1; i++)
                    {
                        var bmp = new Bitmap(width / 2, height / 2);
                        var gfx = Graphics.FromImage(bmp);
                        gfx.InterpolationMode  = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                        gfx.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                        gfx.PixelOffsetMode    = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
                        gfx.DrawImage(firstBitmap, new Rectangle(0, 0, bmp.Width, bmp.Height));
                        Bitmaps[0].MipMaps[i] = bmp;
                        width  = bmp.Width;
                        height = bmp.Height;
                    }
                }

                var bitmaps = new List <byte[]>();

                Settings = new ImageSettings(encoding, Bitmaps[0].Image.Width, Bitmaps[0].Image.Height);

                //Set possible Swizzles
                if (HeaderInfo.Version == Version._3DSv1 || HeaderInfo.Version == Version._3DSv2 || HeaderInfo.Version == Version._3DSv3)
                {
                    Settings.Swizzle = new CTRSwizzle(Bitmaps[0].Image.Width, Bitmaps[0].Image.Height, CtrTransformation.None, true);
                }
                else if (HeaderInfo.Version == Version._Switchv1)
                {
                    Settings.Swizzle = new SwitchSwizzle(Bitmaps[0].Image.Width, Bitmaps[0].Image.Height, Settings.Encoding.BitDepth, GetSwitchSwizzleFormat(Settings.Encoding.FormatName), true);    //Switch Swizzle
                }
                else if (Settings.Encoding.FormatName.Contains("DXT"))
                {
                    Settings.Swizzle = new BCSwizzle(Bitmaps[0].Image.Width, Bitmaps[0].Image.Height);
                }

                if ((Format)HeaderInfo.Format == Format.DXT5_B)
                {
                    Settings.PixelShader = ToNoAlpha;
                }
                else if ((Format)HeaderInfo.Format == Format.DXT5_YCbCr)
                {
                    Settings.PixelShader = ToOptimisedColors;
                }

                bitmaps.Add(Kolors.Save(Bitmaps[0].Image, Settings));

                foreach (var mipmap in Bitmaps[0].MipMaps)
                {
                    Settings = new ImageSettings(encoding, Bitmaps[0].Image.Width, Bitmaps[0].Image.Height);

                    //Set possible Swizzles
                    if (HeaderInfo.Version == Version._3DSv1 || HeaderInfo.Version == Version._3DSv2 || HeaderInfo.Version == Version._3DSv3)
                    {
                        Settings.Swizzle = new CTRSwizzle(mipmap.Width, mipmap.Height, CtrTransformation.None, true);
                    }
                    else if (HeaderInfo.Version == Version._Switchv1)
                    {
                        Settings.Swizzle = new SwitchSwizzle(mipmap.Width, mipmap.Height, Settings.Encoding.BitDepth, GetSwitchSwizzleFormat(Settings.Encoding.FormatName), true);    //Switch Swizzle
                    }
                    else if (Settings.Encoding.FormatName.Contains("DXT"))
                    {
                        Settings.Swizzle = new BCSwizzle(mipmap.Width, mipmap.Height);
                    }

                    if ((Format)HeaderInfo.Format == Format.DXT5_B)
                    {
                        Settings.PixelShader = ToNoAlpha;
                    }
                    else if ((Format)HeaderInfo.Format == Format.DXT5_YCbCr)
                    {
                        Settings.PixelShader = ToOptimisedColors;
                    }

                    bitmaps.Add(Kolors.Save(mipmap, Settings));
                }

                if (HeaderInfo.Version == Version._Switchv1)
                {
                    if (SwitchUnknownData != null)
                    {
                        var listOffset = bw.BaseStream.Position;
                        bw.BaseStream.Position += 8 + HeaderInfo.MipMapCount * sizeof(int);

                        var offsets   = new List <int>();
                        var relOffset = bw.BaseStream.Position;
                        foreach (var bitmap in bitmaps)
                        {
                            var data = new byte[(bitmap.Length + 0x1FF) & ~0x1FF];
                            Array.Copy(bitmap, data, bitmap.Length);
                            bw.Write(data);
                            offsets.Add((int)(bw.BaseStream.Position - relOffset));
                        }
                        offsets[offsets.Count - 1] = (offsets.Last() + 0x7FF) & ~0x7FF;
                        bw.BaseStream.Position     = relOffset + offsets.Last();

                        bw.Write(SwitchOverflowingData);

                        var totalSize = bw.BaseStream.Position - 0x84 - HeaderInfo.MipMapCount * sizeof(int);

                        bw.BaseStream.Position = listOffset;
                        bw.Write((int)totalSize);
                        bw.BaseStream.Position += 4;
                        foreach (var offset in offsets)
                        {
                            bw.Write(offset);
                        }
                    }
                    else
                    {
                        bw.BaseStream.Position += 0x4 + HeaderInfo.MipMapCount * sizeof(int);

                        var offsets   = new List <int>();
                        var relOffset = bw.BaseStream.Position;
                        foreach (var bitmap in bitmaps)
                        {
                            offsets.Add((int)(bw.BaseStream.Position - relOffset));
                            var data = new byte[(bitmap.Length + 0x1FF) & ~0x1FF];
                            Array.Copy(bitmap, data, bitmap.Length);
                            bw.Write(data);
                        }
                        var totalSize = bw.BaseStream.Position - (0x10 + 0x4 + HeaderInfo.MipMapCount * sizeof(int));

                        bw.BaseStream.Position = 0x10;
                        bw.Write((int)totalSize);
                        foreach (var offset in offsets)
                        {
                            bw.Write(offset);
                        }
                    }
                }
                else
                // Mipmaps, but not for Version 3DS v1
                if (HeaderInfo.Version != Version._3DSv1)
                {
                    var offset = HeaderInfo.Version == Version._PS3v1 ? HeaderInfo.MipMapCount * sizeof(int) + HeaderLength : 0;
                    foreach (var bitmap in bitmaps)
                    {
                        bw.Write(offset);
                        offset += bitmap.Length;
                    }
                }

                // Bitmaps
                if (SwitchUnknownData == null)
                {
                    foreach (var bitmap in bitmaps)
                    {
                        bw.Write(bitmap);
                    }
                }
            }
        }