Пример #1
0
        protected override bool TryCopyTo(BitmapContent dstBitmap, Rectangle srcRect, Rectangle dstRect)
        {
            SurfaceFormat format;

            if (!dstBitmap.TryGetFormat(out format) || format != _format)
            {
                return(false);
            }

            var dst = dstBitmap as PixelBitmapContent <T>;

            for (var i = 0; i < dstRect.Height; i++)
            {
                var dy = dstRect.Y + i;
                for (var j = 0; j < dstRect.Width; j++)
                {
                    var dx = dstRect.X + j;

                    var uv = new Vector2()
                    {
                        X = j / (float)dstRect.Width,
                        Y = i / (float)dstRect.Height,
                    };

                    var sx    = MathHelper.Clamp((int)Math.Round(uv.X * srcRect.Width) + srcRect.X, 0, Width - 1);
                    var sy    = MathHelper.Clamp((int)Math.Round(uv.Y * srcRect.Height) + srcRect.Y, 0, Height - 1);
                    var pixel = GetPixel(sx, sy);
                    dst.SetPixel(dx, dy, pixel);
                }
            }

            return(true);
        }
Пример #2
0
        public DxtDataHandler(BitmapContent content)
        {
            _content = content;

            WriteData = new OutputOptions.WriteDataDelegate(WriteDataInternal);
            BeginImage = new OutputOptions.ImageDelegate(BeginImageInternal);
        }
Пример #3
0
        public DxtDataHandler(BitmapContent content)
        {
            _content = content;

            WriteData  = new OutputOptions.WriteDataDelegate(WriteDataInternal);
            BeginImage = new OutputOptions.ImageDelegate(BeginImageInternal);
        }
Пример #4
0
        /// <summary>
        /// Gets the alpha range in a set of pixels.
        /// </summary>
        /// <param name="bitmap">A bitmap of full-colour floating point pixel data in RGBA or BGRA order.</param>
        /// <returns>A member of the AlphaRange enum to describe the range of alpha in the pixel data.</returns>
        static AlphaRange CalculateAlphaRange(BitmapContent bitmap)
        {
            AlphaRange result      = AlphaRange.Opaque;
            var        pixelBitmap = bitmap as PixelBitmapContent <Vector4>;

            if (pixelBitmap != null)
            {
                for (int y = 0; y < pixelBitmap.Height; ++y)
                {
                    var row = pixelBitmap.GetRow(y);
                    foreach (var pixel in row)
                    {
                        if (pixel.W == 0.0)
                        {
                            result = AlphaRange.Cutout;
                        }
                        else if (pixel.W < 1.0)
                        {
                            return(AlphaRange.Full);
                        }
                    }
                }
            }
            return(result);
        }
Пример #5
0
        /// <summary>
        /// Generates a full set of mipmaps for the texture.
        /// </summary>
        /// <param name="overwriteExistingMipmaps">true if the existing mipmap set is replaced with the new set; false otherwise.</param>
        public virtual void GenerateMipmaps(bool overwriteExistingMipmaps)
        {
            // If we already have mipmaps and we're not supposed to overwrite
            // them then return without any generation.
            if (!overwriteExistingMipmaps && faces.Any(f => f.Count > 1))
            {
                return;
            }

            // Generate the mips for each face.
            foreach (var face in faces)
            {
                // Remove any existing mipmaps.
                var faceBitmap = face[0];
                face.Clear();
                face.Add(faceBitmap);
                var faceType = faceBitmap.GetType();
                int width    = faceBitmap.Width;
                int height   = faceBitmap.Height;
                while (width > 1 && height > 1)
                {
                    width  /= 2;
                    height /= 2;

                    var mip = (BitmapContent)Activator.CreateInstance(faceType, new object[] { width, height });
                    BitmapContent.Copy(faceBitmap, mip);
                    face.Add(mip);
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Generates a full set of mipmaps for the texture.
        /// </summary>
        /// <param name="overwriteExistingMipmaps">true if the existing mipmap set is replaced with the new set; false otherwise.</param>
        public virtual void GenerateMipmaps(bool overwriteExistingMipmaps)
        {
            ImageAttributes imageAttr = new ImageAttributes();

            imageAttr.SetWrapMode(WrapMode.TileFlipXY);

            foreach (MipmapChain face in faces)
            {
                BitmapContent faceBitmap = face[0];
                int           width = faceBitmap.Width, height = faceBitmap.Height;
                Bitmap        systemBitmap;
                while (width > 1 && height > 1)
                {
                    systemBitmap = face[face.Count - 1].ToSystemBitmap();
                    width       /= 2;
                    height      /= 2;

                    Bitmap bitmap = new Bitmap(width, height);
                    using (var graphics = System.Drawing.Graphics.FromImage(bitmap))
                    {
                        var destRect = new System.Drawing.Rectangle(0, 0, width, height);
                        graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
                        graphics.DrawImage(systemBitmap, destRect, 0, 0, width * 2, height * 2, GraphicsUnit.Pixel, imageAttr);
                    }

                    face.Add(bitmap.ToXnaBitmap(false)); //we dont want to flip textures twice
                    systemBitmap.Dispose();
                }
            }
        }
Пример #7
0
        protected override bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            throw new NotImplementedException();

            // return BitmapContent.InteropCopy(this, sourceRegion, destinationBitmap, destinationRegion);

        }
Пример #8
0
        // Checks whether an area of a bitmap contains entirely the specified alpha value.
        public static bool IsAlphaEntirely(byte expectedAlpha, BitmapContent bitmap, Rectangle? region = null)
		{
            var bitmapRegion = region.HasValue ? region.Value : new Rectangle(0, 0, bitmap.Width, bitmap.Height);
            // Works with PixelBitmapContent<byte> at this stage
            if (bitmap is PixelBitmapContent<byte>)
            {
                var bmp = bitmap as PixelBitmapContent<byte>;
                for (int y = 0; y < bitmapRegion.Height; y++)
                {
                    for (int x = 0; x < bitmapRegion.Width; x++)
                    {
                        var alpha = bmp.GetPixel(bitmapRegion.X + x, bitmapRegion.Y + y);
                        if (alpha != expectedAlpha)
                            return false;
                    }
                }
                return true;
            }
            else if (bitmap is PixelBitmapContent<Color>)
            {
                var bmp = bitmap as PixelBitmapContent<Color>;
                for (int y = 0; y < bitmapRegion.Height; y++)
                {
                    for (int x = 0; x < bitmapRegion.Width; x++)
                    {
                        var alpha = bmp.GetPixel(bitmapRegion.X + x, bitmapRegion.Y + y).A;
                        if (alpha != expectedAlpha)
                            return false;
                    }
                }
                return true;
            }
            throw new ArgumentException("Expected PixelBitmapContent<byte> or PixelBitmapContent<Color>, got " + bitmap.GetType().Name, "bitmap");
		}
Пример #9
0
        static void Compress(Type targetType, TextureContent content, bool generateMipMaps)
        {
            var wh = new object[2];

            if (generateMipMaps)
            {
                for (int i = 0; i < content.Faces.Count; ++i)
                {
                    // Only generate mipmaps if there are none already
                    if (content.Faces[i].Count == 1)
                    {
                        var src = content.Faces[i][0];
                        var w   = src.Width;
                        var h   = src.Height;

                        content.Faces[i].Clear();
                        wh[0] = w;
                        wh[1] = h;
                        var dest = (BitmapContent)Activator.CreateInstance(targetType, wh);
                        BitmapContent.Copy(src, dest);
                        content.Faces[i].Add(dest);
                        while (w > 1 && h > 1)
                        {
                            if (w > 1)
                            {
                                w = w >> 1;
                            }
                            if (h > 1)
                            {
                                h = h >> 1;
                            }
                            wh[0] = w;
                            wh[1] = h;
                            dest  = (BitmapContent)Activator.CreateInstance(targetType, wh);
                            BitmapContent.Copy(src, dest);
                            content.Faces[i].Add(dest);
                        }
                    }
                    else
                    {
                        // Convert the existing mipmaps
                        var chain = content.Faces[i];
                        for (int j = 0; j < chain.Count; ++j)
                        {
                            var src = chain[j];
                            wh[0] = src.Width;
                            wh[1] = src.Height;
                            var dest = (BitmapContent)Activator.CreateInstance(targetType, wh);
                            BitmapContent.Copy(src, dest);
                            chain[j] = dest;
                        }
                    }
                }
            }
            else
            {
                // Converts all existing faces and mipmaps
                content.ConvertBitmapType(targetType);
            }
        }
Пример #10
0
 /// <summary>
 /// Validates the arguments to the Copy function.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="sourceRegion">Location of sourceBitmap.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
 protected static void ValidateCopyArguments(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     if (sourceBitmap == null)
     {
         throw new ArgumentNullException("sourceBitmap");
     }
     if (destinationBitmap == null)
     {
         throw new ArgumentNullException("destinationBitmap");
     }
     // Make sure regions are within the bounds of the bitmaps
     if (sourceRegion.Left < 0 ||
         sourceRegion.Top < 0 ||
         sourceRegion.Width <= 0 ||
         sourceRegion.Height <= 0 ||
         sourceRegion.Right > sourceBitmap.Width ||
         sourceRegion.Bottom > sourceBitmap.Height)
     {
         throw new ArgumentOutOfRangeException("sourceRegion");
     }
     if (destinationRegion.Left < 0 ||
         destinationRegion.Top < 0 ||
         destinationRegion.Width <= 0 ||
         destinationRegion.Height <= 0 ||
         destinationRegion.Right > destinationBitmap.Width ||
         destinationRegion.Bottom > destinationBitmap.Height)
     {
         throw new ArgumentOutOfRangeException("destinationRegion");
     }
 }
        protected override bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat destinationFormat;

            if (!destinationBitmap.TryGetFormat(out destinationFormat))
            {
                return(false);
            }

            SurfaceFormat format;

            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            var fullRegion = new Rectangle(0, 0, Width, Height);

            if ((format == destinationFormat) && (sourceRegion == fullRegion) && (sourceRegion == destinationRegion))
            {
                destinationBitmap.SetPixelData(GetPixelData());
                return(true);
            }

            // No other support for copying from a DXT texture yet
            return(false);
        }
Пример #12
0
 // Constructor.
 public Glyph(char character, BitmapContent bitmap, Rectangle?subrect = null)
 {
     this.Character = character;
     this.Bitmap    = bitmap;
     this.Subrect   = subrect.GetValueOrDefault(new Rectangle(0, 0, bitmap.Width, bitmap.Height));
     this.Width     = bitmap.Width;
     this.Height    = bitmap.Height;
 }
Пример #13
0
		// Constructor.
        public Glyph(char character, BitmapContent bitmap, Rectangle? subrect = null)
		{
			this.Character = character;
			this.Bitmap = bitmap;
			this.Subrect = subrect.GetValueOrDefault(new Rectangle(0, 0, bitmap.Width, bitmap.Height));
			this.Width = bitmap.Width;
			this.Height = bitmap.Height;
		}
Пример #14
0
 /// <summary>
 /// Copies one bitmap into another.
 /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 public static void Copy(BitmapContent sourceBitmap, BitmapContent destinationBitmap)
 {
     if (sourceBitmap == null)
         throw new ArgumentNullException("sourceBitmap");
     if (destinationBitmap == null)
         throw new ArgumentNullException("destinationBitmap");
     Copy(sourceBitmap, new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), destinationBitmap, new Rectangle(0, 0, destinationBitmap.Width, destinationBitmap.Height));
 }
Пример #15
0
		protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                return false;

            SurfaceFormat format;
            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (format == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return true;
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
                return false;

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent<Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return true;
                }
                catch (InvalidOperationException)
                {
                    return false;
                }
            }

            // Convert to full colour 32-bit format. Floating point would be preferred for processing, but it appears the ATICompressor does not support this
            var colorBitmap = new PixelBitmapContent<Color>(sourceRegion.Width, sourceRegion.Height);
            BitmapContent.Copy(sourceBitmap, sourceRegion, colorBitmap, new Rectangle(0, 0, colorBitmap.Width, colorBitmap.Height));
            sourceBitmap = colorBitmap;

			ATICompressor.CompressionFormat targetFormat;
			switch (format)
            {
				case SurfaceFormat.RgbaAtcExplicitAlpha:
					targetFormat = ATICompressor.CompressionFormat.AtcRgbaExplicitAlpha;
					break;
				case SurfaceFormat.RgbaAtcInterpolatedAlpha:
					targetFormat = ATICompressor.CompressionFormat.AtcRgbaInterpolatedAlpha;
					break;
				default:
					return false;
			}

			var sourceData = sourceBitmap.GetPixelData();
			var compressedData = ATICompressor.Compress(sourceData, Width, Height, targetFormat);
			SetPixelData(compressedData);

			return true;
        }
Пример #16
0
        protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;

            if (!sourceBitmap.TryGetFormat(out sourceFormat))
            {
                return(false);
            }

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (SurfaceFormat.RgbEtc1 == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return(true);
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
            {
                return(false);
            }

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent <Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return(true);
                }
                catch (InvalidOperationException)
                {
                    return(false);
                }
            }

            // Create the texture object in the PVR library
            var sourceData = sourceBitmap.GetPixelData();
            var rgba32F    = (PixelFormat)0x2020202061626772; // static const PixelType PVRStandard32PixelType = PixelType('r', 'g', 'b', 'a', 32, 32, 32, 32);

            using (var pvrTexture = PVRTexture.CreateTexture(sourceData, (uint)sourceBitmap.Width, (uint)sourceBitmap.Height, 1,
                                                             rgba32F, true, VariableType.Float, ColourSpace.lRGB))
            {
                // Resize the bitmap if needed
                if ((sourceBitmap.Width != Width) || (sourceBitmap.Height != Height))
                {
                    pvrTexture.Resize((uint)Width, (uint)Height, 1, ResizeMode.Cubic);
                }
                pvrTexture.Transcode(PixelFormat.ETC1, VariableType.UnsignedByte, ColourSpace.lRGB /*, CompressorQuality.ETCMediumPerceptual, true*/);
                var texDataSize = pvrTexture.GetTextureDataSize(0);
                var texData     = new byte[texDataSize];
                pvrTexture.GetTextureData(texData, texDataSize);
                SetPixelData(texData);
            }
            return(true);
        }
Пример #17
0
 /// <summary>
 /// Copies one bitmap into another.
 /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 public static void Copy(BitmapContent sourceBitmap, BitmapContent destinationBitmap)
 {
     if (sourceBitmap == null)
     {
         throw new ArgumentNullException("sourceBitmap");
     }
     if (destinationBitmap == null)
     {
         throw new ArgumentNullException("destinationBitmap");
     }
     Copy(sourceBitmap, new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height), destinationBitmap, new Rectangle(0, 0, destinationBitmap.Width, destinationBitmap.Height));
 }
Пример #18
0
        /// <summary>
        /// Copies one bitmap into another.
        /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
        /// </summary>
        /// <param name="sourceBitmap">BitmapContent being copied.</param>
        /// <param name="sourceRegion">Region of sourceBitmap.</param>
        /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
        /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
        public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
        {
            ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);

            if (sourceBitmap.TryCopyTo(destinationBitmap, sourceRegion, destinationRegion) ||
                destinationBitmap.TryCopyFrom(sourceBitmap, sourceRegion, destinationRegion))
            {
                return;
            }

            throw new NotImplementedException();
        }
Пример #19
0
        /// <summary>
        /// Copies one bitmap into another.
        /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
        /// </summary>
        /// <param name="sourceBitmap">BitmapContent being copied.</param>
        /// <param name="sourceRegion">Region of sourceBitmap.</param>
        /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
        /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
        public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
        {
            ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);

            SurfaceFormat sourceFormat;

            if (!sourceBitmap.TryGetFormat(out sourceFormat))
            {
                throw new InvalidOperationException("Could not retrieve surface format of source bitmap");
            }
            SurfaceFormat destinationFormat;

            if (!destinationBitmap.TryGetFormat(out destinationFormat))
            {
                throw new InvalidOperationException("Could not retrieve surface format of destination bitmap");
            }

            // If the formats are the same and the regions are the full bounds of the bitmaps and they are the same size, do a simpler copy
            if (sourceFormat == destinationFormat && sourceRegion == destinationRegion &&
                sourceRegion == new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height) &&
                destinationRegion == new Rectangle(0, 0, destinationBitmap.Width, destinationBitmap.Height))
            {
                destinationBitmap.SetPixelData(sourceBitmap.GetPixelData());
                return;
            }

            // The basic process is
            // 1. Copy from source bitmap region to a new PixelBitmapContent<Vector4> using sourceBitmap.TryCopyTo()
            // 2. If source and destination regions are a different size, resize Vector4 version
            // 3. Copy from Vector4 to destination region using destinationBitmap.TryCopyFrom()

            // Copy from the source to the intermediate Vector4 format
            var intermediate       = new PixelBitmapContent <Vector4>(sourceRegion.Width, sourceRegion.Height);
            var intermediateRegion = new Rectangle(0, 0, intermediate.Width, intermediate.Height);

            if (sourceBitmap.TryCopyTo(intermediate, sourceRegion, intermediateRegion))
            {
                // Resize the intermediate if required
                if (intermediate.Width != destinationRegion.Width || intermediate.Height != destinationRegion.Height)
                {
                    intermediate = intermediate.Resize(destinationRegion.Width, destinationRegion.Height) as PixelBitmapContent <Vector4>;
                }
                // Copy from the intermediate to the destination
                if (destinationBitmap.TryCopyFrom(intermediate, new Rectangle(0, 0, intermediate.Width, intermediate.Height), destinationRegion))
                {
                    return;
                }
            }

            // If we got here, one of the above steps didn't work
            throw new InvalidOperationException("Could not copy between " + sourceFormat + " and " + destinationFormat);
        }
Пример #20
0
        public DxtDataHandler(BitmapContent content, OutputOptions outputOptions)
        {
            _content = content;

            WriteData  = new OutputOptions.WriteDataDelegate(WriteDataInternal);
            BeginImage = new OutputOptions.ImageDelegate(BeginImageInternal);

            // Keep the delegate from being re-located or collected by the garbage collector.
            delegateHandleBeginImage = GCHandle.Alloc(BeginImage);
            delegateHandleWriteData  = GCHandle.Alloc(WriteData);

            outputOptions.SetOutputHandler(BeginImage, WriteData);
        }
Пример #21
0
        protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                return false;

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (SurfaceFormat.RgbEtc1 == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return true;
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
                return false;

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent<Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return true;
                }
                catch (InvalidOperationException)
                {
                    return false;
                }
            }

            // Create the texture object in the PVR library
            var sourceData = sourceBitmap.GetPixelData();
            var rgba32F = (PixelFormat)0x2020202061626772; // static const PixelType PVRStandard32PixelType = PixelType('r', 'g', 'b', 'a', 32, 32, 32, 32);
            using (var pvrTexture = PVRTexture.CreateTexture(sourceData, (uint)sourceBitmap.Width, (uint)sourceBitmap.Height, 1,
                rgba32F, true, VariableType.Float, ColourSpace.lRGB))
            {
                // Resize the bitmap if needed
                if ((sourceBitmap.Width != Width) || (sourceBitmap.Height != Height))
                    pvrTexture.Resize((uint)Width, (uint)Height, 1, ResizeMode.Cubic);
                pvrTexture.Transcode(PixelFormat.ETC1, VariableType.UnsignedByte, ColourSpace.lRGB /*, CompressorQuality.ETCMediumPerceptual, true*/);
                var texDataSize = pvrTexture.GetTextureDataSize(0);
                var texData = new byte[texDataSize];
                pvrTexture.GetTextureData(texData, texDataSize);
                SetPixelData(texData);
            }
            return true;
        }
Пример #22
0
        internal static Bitmap ToSystemBitmap(this BitmapContent bitmapContent)
        {
            var srcBmp  = bitmapContent;
            var srcData = srcBmp.GetPixelData();

            var srcDataHandle = GCHandle.Alloc(srcData, GCHandleType.Pinned);
            var srcDataPtr    = (IntPtr)(srcDataHandle.AddrOfPinnedObject().ToInt64());

            // stride must be aligned on a 32 bit boundary or 4 bytes
            int stride = ((srcBmp.Width * 32 + 31) & ~31) >> 3;

            var systemBitmap = new Bitmap(srcBmp.Width, srcBmp.Height, stride, PixelFormat.Format32bppArgb | PixelFormat.Alpha, srcDataPtr);

            srcDataHandle.Free();

            return(systemBitmap);
        }
Пример #23
0
        // Once arranging is complete, copies each glyph to its chosen position in the single larger output bitmap.
        static BitmapContent CopyGlyphsToOutput(List <ArrangedGlyph> glyphs, int width, int height)
        {
            var output = new PixelBitmapContent <Color>(width, height);

            foreach (var glyph in glyphs)
            {
                var sourceGlyph       = glyph.Source;
                var sourceRegion      = sourceGlyph.Subrect;
                var destinationRegion = new Rectangle(glyph.X + 1, glyph.Y + 1, sourceRegion.Width, sourceRegion.Height);

                BitmapContent.Copy(sourceGlyph.Bitmap, sourceRegion, output, destinationRegion);

                sourceGlyph.Bitmap  = output;
                sourceGlyph.Subrect = destinationRegion;
            }

            return(output);
        }
Пример #24
0
        /// <summary>
        /// Converts all bitmaps for this texture to a different format.
        /// </summary>
        /// <param name="newBitmapType">Type being converted to. The new type must be a subclass of BitmapContent, such as PixelBitmapContent or DxtBitmapContent.</param>
        public void ConvertBitmapType(Type newBitmapType)
        {
            if (newBitmapType == null)
            {
                throw new ArgumentNullException("newBitmapType");
            }

            if (!newBitmapType.IsSubclassOf(typeof(BitmapContent)))
            {
                throw new ArgumentException(string.Format("Type '{0}' is not a subclass of BitmapContent.", newBitmapType));
            }

            if (newBitmapType.IsAbstract)
            {
                throw new ArgumentException(string.Format("Type '{0}' is abstract and cannot be allocated.", newBitmapType));
            }

            if (newBitmapType.ContainsGenericParameters)
            {
                throw new ArgumentException(string.Format("Type '{0}' contains generic parameters and cannot be allocated.", newBitmapType));
            }

            if (newBitmapType.GetConstructor(new Type[2] {
                typeof(int), typeof(int)
            }) == null)
            {
                throw new ArgumentException(string.Format("Type '{0} does not have a constructor with signature (int, int) and cannot be allocated.",
                                                          newBitmapType));
            }

            foreach (var mipChain in faces)
            {
                for (var i = 0; i < mipChain.Count; i++)
                {
                    var src = mipChain[i];
                    if (src.GetType() != newBitmapType)
                    {
                        var dst = (BitmapContent)Activator.CreateInstance(newBitmapType, new object[] { src.Width, src.Height });
                        BitmapContent.Copy(src, dst);
                        mipChain[i] = dst;
                    }
                }
            }
        }
Пример #25
0
        // Checks whether an area of a bitmap contains entirely the specified alpha value.
        public static bool IsAlphaEntirely(byte expectedAlpha, BitmapContent bitmap, Rectangle?region = null)
        {
            var bitmapRegion = region.HasValue ? region.Value : new Rectangle(0, 0, bitmap.Width, bitmap.Height);

            // Works with PixelBitmapContent<byte> at this stage
            if (bitmap is PixelBitmapContent <byte> )
            {
                var bmp = bitmap as PixelBitmapContent <byte>;
                for (int y = 0; y < bitmapRegion.Height; y++)
                {
                    for (int x = 0; x < bitmapRegion.Width; x++)
                    {
                        var alpha = bmp.GetPixel(bitmapRegion.X + x, bitmapRegion.Y + y);
                        if (alpha != expectedAlpha)
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }
            else if (bitmap is PixelBitmapContent <Color> )
            {
                var bmp = bitmap as PixelBitmapContent <Color>;
                for (int y = 0; y < bitmapRegion.Height; y++)
                {
                    for (int x = 0; x < bitmapRegion.Width; x++)
                    {
                        var alpha = bmp.GetPixel(bitmapRegion.X + x, bitmapRegion.Y + y).A;
                        if (alpha != expectedAlpha)
                        {
                            return(false);
                        }
                    }
                }
                return(true);
            }
            throw new ArgumentException("Expected PixelBitmapContent<byte> or PixelBitmapContent<Color>, got " + bitmap.GetType().Name, "bitmap");
        }
Пример #26
0
        internal static BitmapContent Resize(this BitmapContent bitmap, int newWidth, int newHeight)
        {
            BitmapContent src = bitmap;
            SurfaceFormat format;

            src.TryGetFormat(out format);
            if (format != SurfaceFormat.Vector4)
            {
                var v4 = new PixelBitmapContent <Vector4>(src.Width, src.Height);
                BitmapContent.Copy(src, v4);
                src = v4;
            }

            // Convert to FreeImage bitmap
            var bytes = src.GetPixelData();
            var fi    = FreeImage.ConvertFromRawBits(bytes, FREE_IMAGE_TYPE.FIT_RGBAF, src.Width, src.Height, SurfaceFormat.Vector4.GetSize() * src.Width, 128, 0, 0, 0, true);

            // Resize
            var newfi = FreeImage.Rescale(fi, newWidth, newHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC);

            FreeImage.UnloadEx(ref fi);

            // Convert back to PixelBitmapContent<Vector4>
            src   = new PixelBitmapContent <Vector4>(newWidth, newHeight);
            bytes = new byte[SurfaceFormat.Vector4.GetSize() * newWidth * newHeight];
            FreeImage.ConvertToRawBits(bytes, newfi, SurfaceFormat.Vector4.GetSize() * newWidth, 128, 0, 0, 0, true);
            src.SetPixelData(bytes);
            FreeImage.UnloadEx(ref newfi);
            // Convert back to source type if required
            if (format != SurfaceFormat.Vector4)
            {
                var s = (BitmapContent)Activator.CreateInstance(bitmap.GetType(), new object[] { newWidth, newHeight });
                BitmapContent.Copy(src, s);
                src = s;
            }

            return(src);
        }
        private MipmapChain CreateFace(BitmapContent bitmapContent, int w, int h, int xOffset)
        {
            PixelBitmapContent<Color> result;

            result = new PixelBitmapContent<Color>(w, h);

            Rectangle sourceRegion = new Rectangle(xOffset, 0, w, h);

            Rectangle destinationRegion = new Rectangle(0, 0, w, h);

            BitmapContent.Copy(bitmapContent, sourceRegion, result, destinationRegion);

            return result;
        }
Пример #28
0
 protected override bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
 {
     throw new NotImplementedException();
 }
Пример #29
0
        /// <summary>
        /// Copies one bitmap into another.
        /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
        /// </summary>
        /// <param name="sourceBitmap">BitmapContent being copied.</param>
        /// <param name="sourceRegion">Region of sourceBitmap.</param>
        /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
        /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
        public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
        {
            ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);

            if (sourceBitmap.TryCopyTo(destinationBitmap, sourceRegion, destinationRegion) ||
                destinationBitmap.TryCopyFrom(sourceBitmap, sourceRegion, destinationRegion))
                return;

            throw new NotImplementedException();
        }
Пример #30
0
 /// <summary>
 /// Attempts to copy a region of the specified bitmap onto another.
 /// </summary>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="sourceRegion">Location of the source bitmap.</param>
 /// <param name="destinationRegion">Region of destination bitmap to be overwritten.</param>
 /// <returns>true if region copy is supported; false otherwise.</returns>
 protected abstract bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion);
Пример #31
0
		protected static void ValidateCopyArguments(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
		{
			throw new NotImplementedException();
		}
Пример #32
0
		public static void Copy(BitmapContent sourceBitmap, BitmapContent destinationBitmap)
		{
			throw new NotImplementedException();
		}
Пример #33
0
        protected override bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat destinationFormat;

            if (!destinationBitmap.TryGetFormat(out destinationFormat))
            {
                return(false);
            }

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (_format == destinationFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                destinationBitmap.SetPixelData(GetPixelData());
                return(true);
            }

            // If the destination is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(destinationBitmap is PixelBitmapContent <Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(this, sourceRegion, destinationBitmap, destinationRegion);
                    return(true);
                }
                catch (InvalidOperationException)
                {
                    return(false);
                }
            }

            // Convert to a Vector4 format
            var dest = destinationBitmap as PixelBitmapContent <Vector4>;

            if (default(T) is IPackedVector)
            {
                Parallel.For(0, sourceRegion.Height, (y) =>
                {
                    var row = GetRow(sourceRegion.Top + y);
                    for (int x = 0; x < sourceRegion.Width; ++x)
                    {
                        dest.SetPixel(destinationRegion.Left + x, destinationRegion.Top + y, ((IPackedVector)row[sourceRegion.Left + x]).ToVector4());
                    }
                });
            }
            else
            {
                var converter = new Vector4Converter() as IVector4Converter <T>;
                // If no converter could be created, converting from this format is not supported
                if (converter == null)
                {
                    return(false);
                }

                Parallel.For(0, sourceRegion.Height, (y) =>
                {
                    var row = GetRow(sourceRegion.Top + y);
                    for (int x = 0; x < sourceRegion.Width; ++x)
                    {
                        dest.SetPixel(destinationRegion.Left + x, destinationRegion.Top + y, converter.ToVector4(row[sourceRegion.Left + x]));
                    }
                });
            }

            return(true);
        }
Пример #34
0
 protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destRegion)
 {
     throw new NotImplementedException();
 }
Пример #35
0
 public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     throw new NotImplementedException();
 }
Пример #36
0
 protected static void ValidateCopyArguments(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     throw new NotImplementedException();
 }
Пример #37
0
 public Texture2DContent(BitmapContent bitmapContent) : base(new MipmapChainCollection(1))
 {
     base.Faces[0] = bitmapContent;
 }
Пример #38
0
 /// <summary>
 /// Copies one bitmap into another.
 /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="sourceRegion">Region of sourceBitmap.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
 public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);
     throw new NotImplementedException();
 }
Пример #39
0
		protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
		{
			throw new NotImplementedException();
		}
Пример #40
0
 protected override bool TryCopyTo(BitmapContent destBitmap, Rectangle sourceRegion, Rectangle destRegion)
 {
     throw new NotImplementedException();
 }
Пример #41
0
 protected override bool TryCopyFrom(BitmapContent srcBitmap, Rectangle srcRect, Rectangle dstRect)
 {
     return(false);
 }
Пример #42
0
 public static void Copy(BitmapContent sourceBitmap, BitmapContent destinationBitmap)
 {
     throw new NotImplementedException();
 }
Пример #43
0
        public static void CompressPngToTexture2DContent(
			ParsedPath pngFileName, 
			string compressionType, 
			out Texture2DContent textureContent)
        {
            PngFile pngFile = PngFileReader.ReadFile(pngFileName);

            SquishMethod? squishMethod = null;
            SurfaceFormat surfaceFormat = SurfaceFormat.Color;

            switch (compressionType.ToLower())
            {
            case "dxt1":
                squishMethod = SquishMethod.Dxt1;
                surfaceFormat = SurfaceFormat.Dxt1;
                break;
            case "dxt3":
                squishMethod = SquishMethod.Dxt3;
                surfaceFormat = SurfaceFormat.Dxt3;
                break;
            case "dxt5":
                squishMethod = SquishMethod.Dxt5;
                surfaceFormat = SurfaceFormat.Dxt5;
                break;
            default:
            case "none":
                surfaceFormat = SurfaceFormat.Color;
                break;
            }

            BitmapContent bitmapContent;

            if (surfaceFormat != SurfaceFormat.Color)
            {
                byte[] rgbaData = Squish.CompressImage(
                    pngFile.RgbaData, pngFile.Width, pngFile.Height,
                    squishMethod.Value, SquishFit.IterativeCluster, SquishMetric.Default, SquishExtra.None);

                bitmapContent = new BitmapContent(surfaceFormat, pngFile.Width, pngFile.Height, rgbaData);
            }
            else
            {
                bitmapContent = new BitmapContent(SurfaceFormat.Color, pngFile.Width, pngFile.Height, pngFile.RgbaData);
            }

            textureContent = new Texture2DContent(bitmapContent);
        }
Пример #44
0
 /// <summary>
 /// Copies one bitmap into another.
 /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="sourceRegion">Region of sourceBitmap.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
 public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);
     throw new NotImplementedException();
 }
Пример #45
0
		public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
		{
			throw new NotImplementedException();
		}
Пример #46
0
        /// <summary>
        /// Gets the alpha range in a set of pixels.
        /// </summary>
        /// <param name="bitmap">A bitmap of full-colour floating point pixel data in RGBA or BGRA order.</param>
        /// <returns>A member of the AlphaRange enum to describe the range of alpha in the pixel data.</returns>
		static AlphaRange CalculateAlphaRange(BitmapContent bitmap)
        {
			AlphaRange result = AlphaRange.Opaque;
			var pixelBitmap = bitmap as PixelBitmapContent<Vector4>;
			if (pixelBitmap != null)
			{
				for (int y = 0; y < pixelBitmap.Height; ++y)
                {
                    var row = pixelBitmap.GetRow(y);
                    foreach (var pixel in row)
                    {
                        if (pixel.W == 0.0)
                            result = AlphaRange.Cutout;
                        else if (pixel.W < 1.0)
                            return AlphaRange.Full;
                    }
				}
			}
            return result;
        }
Пример #47
0
 private static BitmapContent ConvertBitmap(BitmapContent source, Type newType, int width, int height)
 {
     BitmapContent content;
     try
     {
         content = (BitmapContent)Activator.CreateInstance(newType, new object[] {width, height});
     }
     catch (TargetInvocationException exception)
     {
         throw new Exception(exception.InnerException.Message);
     }
     BitmapContent.Copy(source, content);
     return content;
 }
Пример #48
0
        protected override bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat destinationFormat;
            if (!destinationBitmap.TryGetFormat(out destinationFormat))
                return false;

            SurfaceFormat format;
            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            var fullRegion = new Rectangle(0, 0, Width, Height);
            if ((format == destinationFormat) && (sourceRegion == fullRegion) && (sourceRegion == destinationRegion))
            {
                destinationBitmap.SetPixelData(GetPixelData());
                return true;
            }

            // No other support for copying from a DXT texture yet
            return false;
        }
Пример #49
0
 /// <summary>
 /// Validates the arguments to the Copy function.
 /// </summary>
 /// <param name="sourceBitmap">BitmapContent being copied.</param>
 /// <param name="sourceRegion">Location of sourceBitmap.</param>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
 protected static void ValidateCopyArguments(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
 {
     if (sourceBitmap == null)
         throw new ArgumentNullException("sourceBitmap");
     if (destinationBitmap == null)
         throw new ArgumentNullException("destinationBitmap");
     // Make sure regions are within the bounds of the bitmaps
     if (sourceRegion.Left < 0
         || sourceRegion.Top < 0
         || sourceRegion.Width <= 0
         || sourceRegion.Height <= 0
         || sourceRegion.Right > sourceBitmap.Width
         || sourceRegion.Bottom > sourceBitmap.Height)
         throw new ArgumentOutOfRangeException("sourceRegion");
     if (destinationRegion.Left < 0
         || destinationRegion.Top < 0
         || destinationRegion.Width <= 0
         || destinationRegion.Height <= 0
         || destinationRegion.Right > destinationBitmap.Width
         || destinationRegion.Bottom > destinationBitmap.Height)
         throw new ArgumentOutOfRangeException("destinationRegion");
 }
        protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;

            if (!sourceBitmap.TryGetFormat(out sourceFormat))
            {
                return(false);
            }

            SurfaceFormat format;

            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (format == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return(true);
            }

            // TODO: Add a XNA unit test to see what it does
            // my guess is that this is invalid for DXT.
            //
            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
            {
                return(false);
            }

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent <Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return(true);
                }
                catch (InvalidOperationException)
                {
                    return(false);
                }
            }

            // NVTT wants 8bit data in BGRA format.
            var colorBitmap = new PixelBitmapContent <Color>(sourceBitmap.Width, sourceBitmap.Height);

            BitmapContent.Copy(sourceBitmap, colorBitmap);
            var sourceData = colorBitmap.GetPixelData();
            var dataHandle = GCHandle.Alloc(sourceData, GCHandleType.Pinned);

            AlphaMode alphaMode;
            Format    outputFormat;
            var       alphaDither = false;

            switch (format)
            {
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1SRgb:
            {
                bool hasTransparency;
                PrepareNVTT_DXT1(sourceData, out hasTransparency);
                outputFormat = hasTransparency ? Format.DXT1a : Format.DXT1;
                alphaMode    = hasTransparency ? AlphaMode.Transparency : AlphaMode.None;
                alphaDither  = true;
                break;
            }

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt3SRgb:
            {
                PrepareNVTT(sourceData);
                outputFormat = Format.DXT3;
                alphaMode    = AlphaMode.Transparency;
                break;
            }

            case SurfaceFormat.Dxt5:
            case SurfaceFormat.Dxt5SRgb:
            {
                PrepareNVTT(sourceData);
                outputFormat = Format.DXT5;
                alphaMode    = AlphaMode.Transparency;
                break;
            }

            default:
                throw new InvalidOperationException("Invalid DXT surface format!");
            }

            // Do all the calls to the NVTT wrapper within this handler
            // so we properly clean up if things blow up.
            try
            {
                var dataPtr = dataHandle.AddrOfPinnedObject();

                var inputOptions = new InputOptions();
                inputOptions.SetTextureLayout(TextureType.Texture2D, colorBitmap.Width, colorBitmap.Height, 1);
                inputOptions.SetMipmapData(dataPtr, colorBitmap.Width, colorBitmap.Height, 1, 0, 0);
                inputOptions.SetMipmapGeneration(false);
                inputOptions.SetGamma(1.0f, 1.0f);
                inputOptions.SetAlphaMode(alphaMode);

                var compressionOptions = new CompressionOptions();
                compressionOptions.SetFormat(outputFormat);
                compressionOptions.SetQuality(Quality.Normal);

                // TODO: This isn't working which keeps us from getting the
                // same alpha dither behavior on DXT1 as XNA.
                //
                // See https://github.com/MonoGame/MonoGame/issues/6259
                //
                //if (alphaDither)
                //compressionOptions.SetQuantization(false, false, true);

                var outputOptions = new OutputOptions();
                outputOptions.SetOutputHeader(false);
                outputOptions.SetOutputOptionsOutputHandler(NvttBeginImage, NvttWriteImage, NvttEndImage);

                var dxtCompressor = new Compressor();
                dxtCompressor.Compress(inputOptions, compressionOptions, outputOptions);
            }
            finally
            {
                dataHandle.Free();
            }

            return(true);
        }
Пример #51
0
 public Texture2DContent(BitmapContent bitmapContent)
     : base(new MipmapChainCollection(1))
 {
     base.Faces[0] = bitmapContent;
 }
Пример #52
0
        protected override bool TryCopyFrom(BitmapContent sourceBitmap, Rectangle sourceRegion, Rectangle destinationRegion)
        {
            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                return false;

            SurfaceFormat format;
            TryGetFormat(out format);

            // A shortcut for copying the entire bitmap to another bitmap of the same type and format
            if (format == sourceFormat && (sourceRegion == new Rectangle(0, 0, Width, Height)) && sourceRegion == destinationRegion)
            {
                SetPixelData(sourceBitmap.GetPixelData());
                return true;
            }

            // Destination region copy is not yet supported
            if (destinationRegion != new Rectangle(0, 0, Width, Height))
                return false;

            // If the source is not Vector4 or requires resizing, send it through BitmapContent.Copy
            if (!(sourceBitmap is PixelBitmapContent<Vector4>) || sourceRegion.Width != destinationRegion.Width || sourceRegion.Height != destinationRegion.Height)
            {
                try
                {
                    BitmapContent.Copy(sourceBitmap, sourceRegion, this, destinationRegion);
                    return true;
                }
                catch (InvalidOperationException)
                {
                    return false;
                }
            }

            //SquishFlags targetFormat = SquishFlags.ColourClusterFit;
            Format outputFormat = Format.DXT1;
            switch (format)
            {
                case SurfaceFormat.Dxt1:
                    outputFormat = Format.DXT1;
                    break;
                case SurfaceFormat.Dxt1SRgb:
                    outputFormat = Format.DXT1;
                    break;
                case SurfaceFormat.Dxt3:
                    outputFormat = Format.DXT3;
                    break;
                case SurfaceFormat.Dxt3SRgb:
                    outputFormat = Format.DXT3;
                    break;
                case SurfaceFormat.Dxt5:
                    outputFormat = Format.DXT5;
                    break;
                case SurfaceFormat.Dxt5SRgb:
                    outputFormat = Format.DXT5;
                    break;
                default:
                    return false;
            }

            // libsquish requires RGBA8888
            var colorBitmap = new PixelBitmapContent<Color>(sourceBitmap.Width, sourceBitmap.Height);
            BitmapContent.Copy(sourceBitmap, colorBitmap);

            var sourceData = colorBitmap.GetPixelData();
            /*
            var dataSize = Squish.GetStorageRequirements(colorBitmap.Width, colorBitmap.Height, targetFormat);
            var data = new byte[dataSize];
            var metric = new float[] { 1.0f, 1.0f, 1.0f };
            Squish.CompressImage(sourceData, colorBitmap.Width, colorBitmap.Height, data, targetFormat, metric);
            SetPixelData(data);
            */

            var dxtCompressor = new Compressor();
            var inputOptions = new InputOptions();
            if (outputFormat != Format.DXT1)           
                inputOptions.SetAlphaMode(AlphaMode.Premultiplied);
            else
                inputOptions.SetAlphaMode(AlphaMode.None);
            inputOptions.SetTextureLayout(TextureType.Texture2D, colorBitmap.Width, colorBitmap.Height, 1);

            // Small hack here. NVTT wants 8bit data in BGRA. Flip the B and R channels
            // again here.
            GraphicsUtil.BGRAtoRGBA(sourceData);
            var dataHandle = GCHandle.Alloc(sourceData, GCHandleType.Pinned);
            try
            {
                var dataPtr = dataHandle.AddrOfPinnedObject();

                inputOptions.SetMipmapData(dataPtr, colorBitmap.Width, colorBitmap.Height, 1, 0, 0);
                inputOptions.SetMipmapGeneration(false);
                inputOptions.SetGamma(1.0f, 1.0f);

                var outputOptions = new OutputOptions();
                outputOptions.SetOutputHeader(false);

                var handler = new DxtDataHandler(this);
                outputOptions.SetOutputHandler(handler.BeginImage, handler.WriteData);

                var compressionOptions = new CompressionOptions();
                compressionOptions.SetFormat(outputFormat);
                compressionOptions.SetQuality(Quality.Normal);

                dxtCompressor.Compress(inputOptions, compressionOptions, outputOptions);
            }
            finally
            {
                dataHandle.Free ();
            }
            return true;
        }
Пример #53
0
        /// <summary>
        /// Copies one bitmap into another.
        /// The destination bitmap can be in any format and size. If the destination is larger or smaller, the source bitmap is scaled accordingly.
        /// </summary>
        /// <param name="sourceBitmap">BitmapContent being copied.</param>
        /// <param name="sourceRegion">Region of sourceBitmap.</param>
        /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
        /// <param name="destinationRegion">Region of bitmap to be overwritten.</param>
        public static void Copy(BitmapContent sourceBitmap, Rectangle sourceRegion, BitmapContent destinationBitmap, Rectangle destinationRegion)
        {
            ValidateCopyArguments(sourceBitmap, sourceRegion, destinationBitmap, destinationRegion);

            SurfaceFormat sourceFormat;
            if (!sourceBitmap.TryGetFormat(out sourceFormat))
                throw new InvalidOperationException("Could not retrieve surface format of source bitmap");
            SurfaceFormat destinationFormat;
            if (!destinationBitmap.TryGetFormat(out destinationFormat))
                throw new InvalidOperationException("Could not retrieve surface format of destination bitmap");

            // If the formats are the same and the regions are the full bounds of the bitmaps and they are the same size, do a simpler copy
            if (sourceFormat == destinationFormat && sourceRegion == destinationRegion
                && sourceRegion == new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height)
                && destinationRegion == new Rectangle(0, 0, destinationBitmap.Width, destinationBitmap.Height))
            {
                destinationBitmap.SetPixelData(sourceBitmap.GetPixelData());
                return;
            }

            // The basic process is
            // 1. Copy from source bitmap region to a new PixelBitmapContent<Vector4> using sourceBitmap.TryCopyTo()
            // 2. If source and destination regions are a different size, resize Vector4 version
            // 3. Copy from Vector4 to destination region using destinationBitmap.TryCopyFrom()

            // Copy from the source to the intermediate Vector4 format
            var intermediate = new PixelBitmapContent<Vector4>(sourceRegion.Width, sourceRegion.Height);
            var intermediateRegion = new Rectangle(0, 0, intermediate.Width, intermediate.Height);
            if (sourceBitmap.TryCopyTo(intermediate, sourceRegion, intermediateRegion))
            {
                // Resize the intermediate if required
                if (intermediate.Width != destinationRegion.Width || intermediate.Height != destinationRegion.Height)
                    intermediate = intermediate.Resize(destinationRegion.Width, destinationRegion.Height) as PixelBitmapContent<Vector4>;
                // Copy from the intermediate to the destination
                if (destinationBitmap.TryCopyFrom(intermediate, new Rectangle(0, 0, intermediate.Width, intermediate.Height), destinationRegion))
                    return;
            }

            // If we got here, one of the above steps didn't work
            throw new InvalidOperationException("Could not copy between " + sourceFormat + " and " + destinationFormat);
        }
Пример #54
0
 /// <summary>
 /// Attempts to copy a region of the specified bitmap onto another.
 /// </summary>
 /// <param name="destinationBitmap">BitmapContent being overwritten.</param>
 /// <param name="sourceRegion">Location of the source bitmap.</param>
 /// <param name="destinationRegion">Region of destination bitmap to be overwritten.</param>
 /// <returns>true if region copy is supported; false otherwise.</returns>
 protected abstract bool TryCopyTo(BitmapContent destinationBitmap, Rectangle sourceRegion, Rectangle destinationRegion);