Esempio n. 1
0
        public static byte[] ConvertNonMultipleBlockSizeBitmap(byte[] data, uint width, uint height, BitmapFormat format)
        {
            // assume block size 4 because that's all we deal with in tag data

            if (!IsCompressedFormat(format))
            {
                return(data);
            }

            uint alignedWidth  = width % 4 != 0 ? width + 4 - width % 4 : width;
            uint alignedHeight = height % 4 != 0 ? height + 4 - height % 4 : height;

            byte[] uncompressedData = BitmapDecoder.DecodeBitmap(data, format, (int)alignedWidth, (int)alignedHeight);
            return(TrimAlignedBitmap(format, BitmapFormat.A8R8G8B8, (int)width, (int)height, uncompressedData));
        }
Esempio n. 2
0
        public static byte[] ConvertXboxFormats(byte[] data, uint width, uint height, BitmapFormat format, bool requireDecompression)
        {
            BitmapFormat destinationFormat = GetEquivalentBitmapFormat(format);

            if (format == BitmapFormat.Dxn)
            {
                // flip x and y channels
                data = BitmapDecoder.SwapXYDxn(data, (int)width, (int)height);
            }

            if (destinationFormat == format && !requireDecompression)
            {
                return(data);
            }

            if (format == BitmapFormat.Ctx1)
            {
                data   = BitmapDecoder.Ctx1ToDxn(data, (int)width, (int)height);
                format = BitmapFormat.Dxn;
            }
            else if (format != destinationFormat)
            {
                byte[] uncompressedData = BitmapDecoder.DecodeBitmap(data, format, (int)width, (int)height);

                uncompressedData = TrimAlignedBitmap(format, destinationFormat, (int)width, (int)height, uncompressedData);

                data   = BitmapDecoder.EncodeBitmap(uncompressedData, destinationFormat, (int)width, (int)height);
                format = destinationFormat;
            }

            if (requireDecompression)
            {
                data = ConvertNonMultipleBlockSizeBitmap(data, width, height, format);
            }


            return(data);
        }
Esempio n. 3
0
        private static bool ConvertImage(BaseBitmap bitmap)
        {
            BitmapFormat targetFormat = bitmap.Format;
            var          data         = bitmap.Data;
            bool         DXTFlip      = false;

            switch (bitmap.Format)
            {
            case BitmapFormat.Dxt5aMono:
            case BitmapFormat.Dxt3aMono:
                targetFormat  = BitmapFormat.Y8;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.Dxt3aAlpha:
            case BitmapFormat.Dxt5aAlpha:
                targetFormat  = BitmapFormat.A8;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.DxnMonoAlpha:
            case BitmapFormat.Dxt5a:
            case BitmapFormat.AY8:
                targetFormat  = BitmapFormat.A8Y8;;
                bitmap.Flags &= ~BitmapFlags.Compressed;
                break;

            case BitmapFormat.A4R4G4B4:
            case BitmapFormat.R5G6B5:
                targetFormat = BitmapFormat.A8R8G8B8;
                break;

            case BitmapFormat.A8Y8:
            case BitmapFormat.Y8:
            case BitmapFormat.A8:
            case BitmapFormat.A8R8G8B8:
            case BitmapFormat.X8R8G8B8:
            case BitmapFormat.A16B16G16R16F:
            case BitmapFormat.A32B32G32R32F:
            case BitmapFormat.V8U8:
                break;

            case BitmapFormat.Dxt1:
            case BitmapFormat.Dxt3:
            case BitmapFormat.Dxt5:
            case BitmapFormat.Dxn:
                if (bitmap.Height != bitmap.NearestHeight || bitmap.Width != bitmap.NearestWidth)
                {
                    targetFormat  = BitmapFormat.A8R8G8B8;
                    bitmap.Flags &= ~BitmapFlags.Compressed;
                    DXTFlip       = true;
                }
                break;

            case BitmapFormat.Ctx1:
                bitmap.UpdateFormat(BitmapFormat.Dxn);
                data         = BitmapDecoder.Ctx1ToDxn(data, bitmap.NearestWidth, bitmap.NearestHeight);
                targetFormat = BitmapFormat.Dxn;
                break;

            default:
                throw new Exception($"Unsupported bitmap format {bitmap.Format}");
            }

            if (targetFormat != bitmap.Format)
            {
                data = BitmapDecoder.DecodeBitmap(data, bitmap.Format, bitmap.NearestWidth, bitmap.NearestHeight);
                data = BitmapDecoder.EncodeBitmap(data, targetFormat, bitmap.NearestWidth, bitmap.NearestHeight);

                bool reformat = false;

                if (bitmap.NearestHeight != bitmap.Height || bitmap.NearestWidth != bitmap.Width)
                {
                    reformat = true;
                }

                if (reformat)
                {
                    var compressionFactor = BitmapFormatUtils.GetCompressionFactor(targetFormat);
                    int fixedSize         = (int)(bitmap.Width * bitmap.Height / compressionFactor);
                    int tilePitch         = (int)(bitmap.NearestWidth / compressionFactor);
                    int pitch             = (int)(bitmap.Width / compressionFactor);

                    byte[] fixedData    = new byte[fixedSize];
                    int    numberOfPass = bitmap.Height;   // encode does not give back block compressed data.
                    for (int i = 0; i < numberOfPass; i++) // may need to compute an offset for special bitmaps
                    {
                        Array.Copy(data, i * tilePitch, fixedData, i * pitch, pitch);
                    }
                    data = fixedData;
                }

                bitmap.UpdateFormat(targetFormat);
                bitmap.Data = data;
            }

            bitmap.Data = data;

            if (DXTFlip)
            {
                return(false);
            }

            return(true);
        }