BitmapPalette.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Imaging / BitmapPalette.cs / 1 / BitmapPalette.cs

                            //------------------------------------------------------------------------------ 
//  Microsoft Avalon
//  Copyright (c) Microsoft Corporation, All rights reserved.
//
//  File: BitmapPalette.cs 
//
//----------------------------------------------------------------------------- 
 
using System;
using System.Security; 
using System.Security.Permissions;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel; 
using System.ComponentModel.Design.Serialization;
using System.Reflection; 
using MS.Internal; 
using MS.Win32.PresentationCore;
using MS.Internal.PresentationCore; //SecurityHelper 
using System.Diagnostics;
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Media.Animation; 
using System.Globalization;
using System.Runtime.InteropServices; 
 
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID; 

namespace System.Windows.Media.Imaging
{
    ///  
    /// BitmapPalette class
    ///  
    public sealed class BitmapPalette : DispatcherObject 
    {
        #region Constructors 

        /// 
        /// No public default constructor
        ///  
        private BitmapPalette()
        { 
        } 

        ///  
        /// Create a palette from the list of colors.
        /// 
        public BitmapPalette(IList colors)
        { 
            if (colors == null)
            { 
                throw new ArgumentNullException("colors"); 
            }
 
            int count = colors.Count;

            if (count < 1 || count > 256)
            { 
                throw new InvalidOperationException(SR.Get(SRID.Image_PaletteZeroColors, null));
            } 
 
            Color[] colorArray = new Color[count];
 
            for (int i = 0; i < count; ++i)
            {
                colorArray[i] = colors[i];
            } 

            _colors = new PartialList(colorArray); 
 
            _palette = CreateInternalPalette();
 
            UpdateUnmanaged();
        }

        ///  
        /// Construct BitmapPalette from a BitmapSource.
        /// 
        /// If the BitmapSource is already palettized, the corresponding 
        /// palette is returned. Otherwise, a new palette is constructed from
        /// an analysis of the bitmap. 
        /// 
        /// Bitmap to use for analysis
        /// Maximum number of colors
        ///  
        /// SecurityCritical: Accesses unmanaged resources (_wicSource)
        /// PublicOk: Inputs are verified and _wicSource and the get is Critical 
        ///  
        [SecurityCritical]
        public BitmapPalette(BitmapSource bitmapSource, int maxColorCount) 
        {
            // Note: we will never return a palette from BitmapPalettes.

            if (bitmapSource == null) 
            {
                throw new ArgumentNullException("bitmapSource"); 
            } 

            SafeMILHandle unmanagedBitmap = bitmapSource.WicSourceHandle; 

            _palette = CreateInternalPalette();

            lock (bitmapSource.SyncObject) 
            {
                HRESULT.Check(UnsafeNativeMethods.WICPalette.InitializeFromBitmap( 
                            _palette, 
                            unmanagedBitmap,
                            maxColorCount, 
                            false));
            }

            UpdateManaged(); 
        }
 
        ///  
        /// Constructs a bitmap from a known WICPaletteType (does not perform
        /// caching). 
        ///
        /// Note: It is an error to modify the Color property of the
        /// constructed BitmapPalette.  Indeed, the returned BitmapPalette
        /// should probably be immediately frozen. Additionally, outside users 
        /// will have no knowledge that this is a predefined palette (or which
        /// predefined palette it is). It is thus highly recommended that only 
        /// the BitmapPalettes class use this constructor. 
        /// 
        internal BitmapPalette(WICPaletteType paletteType, 
                bool addtransparentColor)
        {
            switch (paletteType)
            { 
                case WICPaletteType.WICPaletteTypeFixedBW:
                case WICPaletteType.WICPaletteTypeFixedHalftone8: 
                case WICPaletteType.WICPaletteTypeFixedHalftone27: 
                case WICPaletteType.WICPaletteTypeFixedHalftone64:
                case WICPaletteType.WICPaletteTypeFixedHalftone125: 
                case WICPaletteType.WICPaletteTypeFixedHalftone216:
                case WICPaletteType.WICPaletteTypeFixedHalftone252:
                case WICPaletteType.WICPaletteTypeFixedHalftone256:
                case WICPaletteType.WICPaletteTypeFixedGray4: 
                case WICPaletteType.WICPaletteTypeFixedGray16:
                case WICPaletteType.WICPaletteTypeFixedGray256: 
                    break; 

                default: 
                    throw new System.ArgumentException(SR.Get(SRID.Image_PaletteFixedType, paletteType));
            }

            _palette = CreateInternalPalette(); 

            HRESULT.Check(UnsafeNativeMethods.WICPalette.InitializePredefined( 
                        _palette, 
                        paletteType,
                        addtransparentColor)); 

            // Fill in the Colors property.
            UpdateManaged();
        } 

        internal BitmapPalette(SafeMILHandle unmanagedPalette) 
        { 
            _palette = unmanagedPalette;
 
            // Fill in the Colors property.
            UpdateManaged();
        }
 
        #endregion // Constructors
 
        #region Factory Methods 

        ///  
        /// Create a BitmapPalette from an unmanaged BitmapSource. If the
        /// bitmap is not paletteized, we return BitmapPalette.Empty. If the
        /// palette is of a known type, we will use BitmapPalettes.
        ///  
        /// 
        /// Critical - access unmanaged code 
        /// TreatAsSafe - Creating a palette from a Source is OK 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        static internal BitmapPalette CreateFromBitmapSource(BitmapSource source)
        {
            Debug.Assert(source != null);
 
            SafeMILHandle bitmapSource = source.WicSourceHandle;
            Debug.Assert(bitmapSource != null && !bitmapSource.IsInvalid); 
 
            SafeMILHandle unmanagedPalette = CreateInternalPalette();
 
            BitmapPalette palette;

            // Don't throw on the HRESULT from this method.  If it returns failure,
            // that likely means that the source doesn't have a palette. 
            lock (source.SyncObject)
            { 
                int hr = UnsafeNativeMethods.WICBitmapSource.CopyPalette( 
                            bitmapSource,
                            unmanagedPalette); 

                if (hr != HRESULT.S_OK)
                {
                    return null; 
                }
            } 
 
            WICPaletteType paletteType;
            bool hasAlpha; 

            HRESULT.Check(UnsafeNativeMethods.WICPalette.GetType(unmanagedPalette, out paletteType));
            HRESULT.Check(UnsafeNativeMethods.WICPalette.HasAlpha(unmanagedPalette, out hasAlpha));
 
            if (paletteType == WICPaletteType.WICPaletteTypeCustom ||
                paletteType == WICPaletteType.WICPaletteTypeOptimal) 
            { 
                palette = new BitmapPalette(unmanagedPalette);
            } 
            else
            {
                palette = BitmapPalettes.FromMILPaletteType(paletteType, hasAlpha);
                Debug.Assert(palette != null); 
            }
 
            return palette; 
        }
 
        #endregion // Factory Methods

        #region Properties
 
        /// 
        /// The contents of the palette. 
        ///  
        public IList Colors
        { 
            get
            {
                return _colors;
            } 
        }
 
        #endregion // Properties 

        #region Internal Properties 

        internal SafeMILHandle InternalPalette
        {
            get 
            {
                if (_palette == null || SecurityHelper.SafeHandleIsInvalid(_palette)) 
                { 
                    _palette = CreateInternalPalette();
                } 

                return _palette;
            }
        } 

        #endregion // Internal Properties 
 
        #region Static / Private Methods
 
        /// Returns if the Palette has any alpha within its colors
        internal static bool DoesPaletteHaveAlpha(BitmapPalette palette)
        {
            if (palette != null) 
            {
                foreach (Color color in palette.Colors) 
                { 
                    if (color.A != 255)
                    { 
                        return true;
                    }
                }
            } 

            return false; 
        } 

        ///  
        /// Critical - calls unmanaged code
        /// TreatAsSafe - only thing you can do with this is allocate some memory
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        static internal SafeMILHandle CreateInternalPalette()
        { 
            SafeMILHandle palette = null; 

            using (FactoryMaker myFactory = new FactoryMaker()) 
            {
                HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreatePalette(
                            myFactory.ImagingFactoryPtr,
                            out palette)); 
                Debug.Assert(palette != null && !palette.IsInvalid);
            } 
 
            return palette;
        } 

        /// 
        /// Copy Colors down into the IMILPalette.
        ///  
        unsafe private void UpdateUnmanaged()
        { 
            Debug.Assert(_palette != null && !SecurityHelper.SafeHandleIsInvalid(_palette)); 

            int numColors = Math.Min(256, _colors.Count); 

            ImagePaletteColor[] paletteColorArray = new ImagePaletteColor[numColors];

            for (int i = 0; i < numColors; ++i) 
            {
                Color color = _colors[i]; 
                paletteColorArray[i].B = color.B; 
                paletteColorArray[i].G = color.G;
                paletteColorArray[i].R = color.R; 
                paletteColorArray[i].A = color.A;
            }

            fixed(void* paletteColorArrayPinned = paletteColorArray) 
            {
                HRESULT.Check(UnsafeNativeMethods.WICPalette.InitializeCustom( 
                            _palette, 
                            (IntPtr)paletteColorArrayPinned,
                            numColors)); 
            }
        }

        ///  
        /// Copy the colors from IMILBitmapPalette into Colors.
        ///  
        ///  
        /// Critical - access unmanaged code
        /// TreatAsSafe - No inputs are provided and only gets the color count and colors from a palette 
        /// 
        [SecurityCritical, SecurityTreatAsSafe]
        private void UpdateManaged()
        { 
            Debug.Assert(_palette != null && !_palette.IsInvalid);
 
            int numColors = 0; 
            int cActualColors = 0;
            HRESULT.Check(UnsafeNativeMethods.WICPalette.GetColorCount(_palette, 
                        out numColors));

            List colors = new List();
 
            if (numColors < 1 || numColors > 256)
            { 
                throw new InvalidOperationException(SR.Get(SRID.Image_PaletteZeroColors, null)); 
            }
            else 
            {
                ImagePaletteColor[] paletteColorArray = new ImagePaletteColor[numColors];
                unsafe
                { 
                    fixed(void* paletteColorArrayPinned = paletteColorArray)
                    { 
                        HRESULT.Check(UnsafeNativeMethods.WICPalette.GetColors( 
                                    _palette,
                                    numColors, 
                                    (IntPtr)paletteColorArrayPinned,
                                    out cActualColors));

                        Debug.Assert(cActualColors == numColors); 
                    }
                } 
 
                for (int i = 0; i < numColors; ++i)
                { 
                    ImagePaletteColor c = paletteColorArray[i];

                    colors.Add(Color.FromArgb(c.A, c.R, c.G, c.B));
                } 
            }
 
            _colors = new PartialList(colors); 
        }
 
        #endregion // Private Methods

        /// 
        /// ImagePaletteColor structure -- convenience for Interop 
        /// 
        [StructLayout(LayoutKind.Sequential)] 
        private struct ImagePaletteColor 
        {
            ///  
            /// blue channel: 0 - 255
            /// 
            public byte B;
            ///  
            /// green channel: 0 - 255
            ///  
            public byte G; 
            /// 
            /// red channel: 0 - 255 
            /// 
            public byte R;
            /// 
            /// alpha channel: 0 - 255 
            /// 
            public byte A; 
        }; 

        // Note: We have a little trickery going on here. When a new BitmapPalette is 
        // cloned, _palette isn't copied and so is reset to null. This means that the
        // next call to InternalPalette will create a new IMILPalette, which is exactly
        // the behavior that we want.
        private SafeMILHandle _palette = null; // IMILPalette* 

        private IList _colors = new PartialList(new List()); 
    } 
}
 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK