Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Stream"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        static public Bitmap LoadAbgr(Stream Stream, int Width, int Height)
        {
            var Data   = Stream.ReadBytes(Width * Height * 4);
            var Bitmap = new Bitmap(Width, Height);

            try
            {
                for (int n = 0; n < Data.Length; n += 4)
                {
                    int X, Y;
                    Swizzling.XGAddress2DTiledXY(n / 4, Width, 4, out X, out Y);
                    byte A = Data[n + 0];
                    byte R = Data[n + 1];
                    byte G = Data[n + 2];
                    byte B = Data[n + 3];
                    Bitmap.SetPixel(X, Y, Color.FromArgb(A, R, G, B));
                }
            }
            catch (Exception Exception)
            {
                Console.Error.WriteLine(Exception);
            }
            //Bitmap.GetChannelsDataInterleaved
            return(Bitmap);
        }
Beispiel #2
0
            private void _GenerateBitmapDecode(Bitmap Bitmap, Func <byte[], int, ARGB_Rev> Decode)
            {
                int BytesPerPixel = BitsPerPixel / 8;

                Bitmap.LockBitsUnlock(PixelFormat.Format32bppArgb, (BitmapData) =>
                {
                    int WidthHeight = Width * Height;
                    var Stream      = SliceStream.Slice();
                    var Bytes       = Stream.ReadBytes(TotalBytes);
                    int m           = 0;
                    bool Tiled      = this.Tiled;

                    var Base = (ARGB_Rev *)BitmapData.Scan0.ToPointer();

                    for (int n = 0; n < WidthHeight; n++)
                    {
                        int X, Y;

                        if (Tiled)
                        {
                            Swizzling.XGAddress2DTiledXY(n, Width, BytesPerPixel, out X, out Y);
                        }
                        else
                        {
                            Swizzling.UnswizzledXY(n, Width, BytesPerPixel, out X, out Y);
                        }

                        if (X >= Width || Y >= Height)
                        {
                            Console.Error.WriteLine("(Warning: Outside! ({0}, {1}) - ({2}x{3}))", X, Y, Width, Height);
                            continue;
                        }

                        Base[Y * Width + X] = Decode(Bytes, m);
                        m += BytesPerPixel;
                    }
                });
            }
Beispiel #3
0
            private void _GenerateBitmapEncode(Bitmap Bitmap, Action <byte[], ARGB_Rev> Encode)
            {
                int TotalBytes    = Bitmap.Width * Bitmap.Height * BitsPerPixel / 8;
                int BytesPerPixel = BitsPerPixel / 8;

                Bitmap.LockBitsUnlock(PixelFormat.Format32bppArgb, (BitmapData) =>
                {
                    int WidthHeight = Width * Height;
                    var Bytes       = new byte[TotalBytes];
                    bool Tiled      = this.Tiled;
                    var PixelBytes  = new byte[BytesPerPixel];

                    var Base = (ARGB_Rev *)BitmapData.Scan0.ToPointer();

                    for (int y = 0; y < Height; y++)
                    {
                        for (int x = 0; x < Width; x++)
                        {
                            int n;

                            if (Tiled)
                            {
                                n = Swizzling.XGAddress2DTiledOffset(x, y, Width, BytesPerPixel);
                            }
                            else
                            {
                                n = Swizzling.UnswizzledOffset(x, y, Width, BytesPerPixel);
                            }

                            Encode(PixelBytes, Base[y * Width + x]);
                            Array.Copy(PixelBytes, 0, Bytes, n * BytesPerPixel, BytesPerPixel);
                        }
                    }

                    SliceStream.Slice().WriteBytes(Bytes).Flush();
                });
            }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Bitmap"></param>
        /// <param name="Stream"></param>
        /// <param name="mode"></param>
        public void SaveSwizzled3D(BitmapList BitmapList, Stream Stream, CompressDXT.CompressionMode mode = CompressDXT.CompressionMode.Normal, bool ShowWarnings = false)
        {
            int Width = BitmapList.Bitmaps[0].Width, Height = BitmapList.Bitmaps[0].Height, Depth = BitmapList.Bitmaps.Length;

            if ((Width % 4) != 0 || (Height % 4) != 0)
            {
                throw (new InvalidDataException());
            }

            BitmapList.LockUnlockBits(PixelFormat.Format32bppArgb, (BitmapDatas) =>
            {
                var Bases = new ARGB_Rev *[Depth];
                for (int n = 0; n < Depth; n++)
                {
                    Bases[n] = (ARGB_Rev *)BitmapDatas[n].Scan0.ToPointer();
                }

                int BlockWidth  = Width / 4;
                int BlockHeight = Height / 4;

                //var BlockCount = BlockWidth * BlockHeight;
                var ExpectedBlockCount = BlockWidth * BlockHeight * Depth;
                int RealUsedBlockCount;

                //RealUsedBlockCount = Swizzling.XGAddress2DTiledExtent(BlockWidth, BlockHeight, BlockSize);
                RealUsedBlockCount = Swizzling.XGAddress3DTiledExtent(BlockWidth, BlockHeight, Depth, BlockSize);
                //Console.WriteLine("{0} - {1}", ExpectedBlockCount, UsedBlockCount);

                var BlockCount = RealUsedBlockCount;

                var CurrentDecodedColors = new ARGB_Rev[4 * 4];
                var Blocks = new TBlock[(uint)BlockCount];

                for (int dxt5_n = 0; dxt5_n < BlockCount; dxt5_n++)
                {
                    int TileX, TileY, TileZ;
                    Swizzling.XGAddress3DTiledXYZ(dxt5_n, BlockWidth, BlockHeight, BlockSize, out TileX, out TileY, out TileZ);

                    int PositionX = TileX * 4;
                    int PositionY = TileY * 4;
                    int PositionZ = TileZ;
                    int n         = 0;

                    if ((PositionX + 3 >= Width) || (PositionY + 3 >= Height) || (PositionZ >= Depth))
                    {
                        if (ShowWarnings)
                        {
                            Console.Error.WriteLine("(Warning! [Write] Position outside ({0}, {1}, {2}) - ({3}x{4}x{5}))", PositionX, PositionY, PositionZ, Width, Height, Depth);
                        }
                        continue;
                    }

                    for (int y = 0; y < 4; y++)
                    {
                        for (int x = 0; x < 4; x++)
                        {
                            CurrentDecodedColors[n] = Bases[TileZ][(PositionY + y) * Width + (PositionX + x)];
                            n++;
                        }
                    }

                    //for (n = 0; n < 16; n++) CurrentDecodedColors[n] = new ARGB_Rev(0xFF, 0xFF, 0, (byte)(n * 16));
                    EncodeBlock(ref Blocks[dxt5_n], ref CurrentDecodedColors, mode);
                }

                //File.WriteAllBytes(@"C:\temp\font\test.txv", StructUtils.StructArrayToBytes(Blocks));
                //Console.WriteLine(Blocks.Length * Marshal.SizeOf(typeof(TBlock)));
                Stream.WriteStructVector(Blocks);
                Stream.Flush();
            });
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="File"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <param name="_Depth"></param>
        /// <param name="Swizzled"></param>
        /// <returns></returns>
        private BitmapList _LoadSwizzled(Stream File, int Width, int Height, int?_Depth, bool Swizzled = true)
        {
            if ((Width % 4) != 0 || (Height % 4) != 0)
            {
                throw (new InvalidDataException(String.Format("Invalid size {0}x{1} must be multiple of 4", Width, Height)));
            }

            int  Depth              = _Depth ?? 1;
            bool Is3D               = _Depth.HasValue;
            var  BitmapList         = new BitmapList(Depth);
            var  BitmapListData     = new BitmapData[Depth];
            var  BitmapListPointers = new ARGB_Rev *[Depth];

            for (int n = 0; n < Depth; n++)
            {
                BitmapList.Bitmaps[n] = new Bitmap(Width, Height);
            }

            for (int n = 0; n < Depth; n++)
            {
                var Bitmap = BitmapList.Bitmaps[n];
                BitmapListData[n]     = Bitmap.LockBits(Bitmap.GetFullRectangle(), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                BitmapListPointers[n] = (ARGB_Rev *)BitmapListData[n].Scan0.ToPointer();
            }

            int BlockWidth           = Width / 4;
            int BlockHeight          = Height / 4;
            var CurrentDecodedColors = new ARGB_Rev[4 * 4];

            var ExpectedBlockCount = BlockWidth * BlockHeight * Depth;
            int RealUsedBlockCount;

            if (Is3D)
            {
                RealUsedBlockCount = Swizzling.XGAddress3DTiledExtent(Width / 4, Height / 4, Depth, BlockSize);
            }
            else
            {
                RealUsedBlockCount = Swizzling.XGAddress2DTiledExtent(Width / 4, Height / 4, BlockSize);
            }
            //Console.WriteLine("{0} - {1}", ExpectedBlockCount, UsedBlockCount);

            var BlockCount = RealUsedBlockCount;

            //var BlockCount = ExpectedBlockCount;

            if (BlockCount * Marshal.SizeOf(typeof(TBlock)) > File.Length)
            {
                Console.Error.WriteLine("File too small");
                //throw(new Exception("File too small"));
                return(new BitmapList(0));
            }

            var Blocks = File.ReadStructVector <TBlock>((uint)BlockCount, -1);

            //Console.WriteLine(Blocks.Length);

            for (int BlockN = 0; BlockN < BlockCount; BlockN++)
            {
                int TileX, TileY, TileZ;

                if (Swizzled)
                {
                    if (Is3D)
                    {
                        Swizzling.XGAddress3DTiledXYZ(BlockN, BlockWidth, BlockHeight, BlockSize, out TileX, out TileY, out TileZ);
                    }
                    else
                    {
                        Swizzling.XGAddress2DTiledXY(BlockN, BlockWidth, BlockSize, out TileX, out TileY);
                        TileZ = 0;
                    }
                }
                else
                {
                    TileX = BlockN % BlockWidth;
                    TileY = BlockN / BlockWidth;
                    TileZ = 0;
                    Console.Error.Write("(Not implemented!)");
                }

                // Skip blocks.
                if (TileX >= BlockWidth || TileY >= BlockHeight)
                {
                    continue;
                }

                DecodeBlock(ref Blocks[BlockN], ref CurrentDecodedColors);

                //Console.WriteLine("{0}", CurrentDecodedColors[0]);

                int PositionX = TileX * 4;
                int PositionY = TileY * 4;

                var BlockBitmap = BitmapList.Bitmaps[TileZ];

                if ((PositionX + 3 >= BlockBitmap.Width) || (PositionY + 3 >= BlockBitmap.Height))
                {
                    Console.Error.WriteLine(
                        "(Warning! [Read] Position outside ({0}, {1}) - ({2}x{3}) ;; ({4}, {5})) - ({6}x{7}) ;; {8}",
                        PositionX, PositionY,
                        Width, Height,
                        TileX, TileY,
                        BlockWidth, BlockHeight,
                        BlockN
                        );
                    continue;
                }

                int n             = 0;
                var BitmapPointer = BitmapListPointers[TileZ];
                for (int y = 0; y < 4; y++)
                {
                    int BaseOffset = (PositionY + y) * Width + (PositionX);
                    for (int x = 0; x < 4; x++)
                    {
                        BitmapPointer[BaseOffset + x] = CurrentDecodedColors[n];
                        n++;
                    }
                }
            }

            for (int n = 0; n < Depth; n++)
            {
                BitmapList.Bitmaps[n].UnlockBits(BitmapListData[n]);
            }

            return(BitmapList);
        }
Beispiel #6
0
        //static private ARGB_Rev FindNearColorInPalette(IEnumerable<ARGB_Rev> Palette, ARGB_Rev Color)
        //{
        //	return Palette.OrderBy(PaletteColor => ARGB_Rev.DistanceRGB(PaletteColor, Color)).First();
        //}
        //
        //static private ARGB_Rev FindFarColorInPalette(IEnumerable<ARGB_Rev> Palette, ARGB_Rev Color)
        //{
        //	return Palette.OrderBy(PaletteColor => ARGB_Rev.DistanceRGB(PaletteColor, Color)).Last();
        //}
        //
        //static private ARGB_Rev AverageColors(IEnumerable<ARGB_Rev> Palette)
        //{
        //	return new ARGB_Rev(
        //		(byte)Palette.Average(Item => Item.A),
        //		(byte)Palette.Average(Item => Item.R),
        //		(byte)Palette.Average(Item => Item.G),
        //		(byte)Palette.Average(Item => Item.B)
        //	);
        //}
        //
        //private void ReduceColors(List<ARGB_Rev> Palette, int ColorCount)
        //{
        //	while (Palette.Count > ColorCount)
        //	{
        //		Palette.Remove(FindNearColorInPalette(Palette, AverageColors(Palette)));
        //	}
        //}
        //
        //private void DoReduceColors(ref ARGB_Rev[] Colors, int ColorCount)
        //{
        //	var ReducedColorsList = Colors.ToList();
        //	ReduceColors(ReducedColorsList, ColorCount);
        //	//Console.WriteLine(String.Join(",", Colors.ToArray()));
        //	//Console.WriteLine(String.Join(",", ReducedColorsList.ToArray()));
        //	for (int n = 0; n < Colors.Length; n++)
        //	{
        //		Colors[n] = FindNearColorInPalette(ReducedColorsList, Colors[n]);
        //	}
        //}

        /// <summary>
        ///
        /// </summary>
        /// <param name="Bitmap"></param>
        /// <param name="File"></param>
        /// <param name="mode"></param>
        public void SaveSwizzled2D(Bitmap Bitmap, Stream File, CompressDXT.CompressionMode mode = CompressDXT.CompressionMode.Normal, int ReduceColors = 16, bool ShowWarnings = false)
        {
            int Width = Bitmap.Width, Height = Bitmap.Height;

            if ((Width % 4) != 0 || (Height % 4) != 0)
            {
                throw (new InvalidDataException());
            }

            Bitmap.LockBitsUnlock(PixelFormat.Format32bppArgb, (BitmapData) =>
            {
                var Base = (ARGB_Rev *)BitmapData.Scan0.ToPointer();

                int BlockWidth  = Width / 4;
                int BlockHeight = Height / 4;

                //var BlockCount = BlockWidth * BlockHeight;
                var ExpectedBlockCount = BlockWidth * BlockHeight;
                int RealUsedBlockCount;

                RealUsedBlockCount = Swizzling.XGAddress2DTiledExtent(Width / 4, Height / 4, BlockSize);
                //Console.WriteLine("{0} - {1}", ExpectedBlockCount, UsedBlockCount);

                var BlockCount = RealUsedBlockCount;

                var CurrentDecodedColors = new ARGB_Rev[4 * 4];
                var Blocks = new TBlock[(uint)BlockCount];

                for (int dxt5_n = 0; dxt5_n < BlockCount; dxt5_n++)
                {
                    int TileX, TileY;
                    Swizzling.XGAddress2DTiledXY(dxt5_n, BlockWidth, BlockSize, out TileX, out TileY);

                    int PositionX = TileX * 4;
                    int PositionY = TileY * 4;
                    int n         = 0;

                    if ((PositionX + 3 >= Width) || (PositionY + 3 >= Height))
                    {
                        if (ShowWarnings)
                        {
                            Console.Error.WriteLine("(Warning! [Write] Position outside ({0}, {1}) - ({2}x{3}))", PositionX, PositionY, Width, Height);
                        }
                        continue;
                    }

                    for (int y = 0; y < 4; y++)
                    {
                        for (int x = 0; x < 4; x++)
                        {
                            CurrentDecodedColors[n] = Base[(PositionY + y) * Width + (PositionX + x)];
                            n++;
                        }
                    }

                    //if (ReduceColors != 16) DoReduceColors(ref CurrentDecodedColors, ReduceColors);

                    EncodeBlock(ref Blocks[dxt5_n], ref CurrentDecodedColors, mode);
                }

                File.WriteStructVector(Blocks);
                File.Flush();
            });
        }