using System; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke { /// Functions and types from Gdi32.dll. public static partial class Gdi32 { /// The type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed). Used in . [PInvokeData("Wingdi.h", MSDNShortId = "dd183376")] public enum BitmapCompressionMode : uint { /// An uncompressed format. BI_RGB = 0, /// /// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count /// byte followed by a byte containing a color index. /// BI_RLE8 = 1, /// /// An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two /// word-length color indexes. /// BI_RLE4 = 2, /// /// Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the /// red, green, and blue components, respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps. /// BI_BITFIELDS = 3, /// Indicates that the image is a JPEG image. BI_JPEG = 4, /// Indicates that the image is a PNG image. BI_PNG = 5 } /// The BITMAP structure defines the type, width, height, color format, and bit values of a bitmap. [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd183371")] public struct BITMAP { /// The bitmap type. This member must be zero. public int bmType; /// The width, in pixels, of the bitmap. The width must be greater than zero. public int bmWidth; /// The height, in pixels, of the bitmap. The height must be greater than zero. public int bmHeight; /// /// The number of bytes in each scan line. This value must be divisible by 2, because the system assumes that the bit values of /// a bitmap form an array that is word aligned. /// public int bmWidthBytes; /// The count of color planes. public ushort bmPlanes; /// The number of bits required to indicate the color of a pixel. public ushort bmBitsPixel; /// /// A pointer to the location of the bit values for the bitmap. The bmBits member must be a pointer to an array of character /// (1-byte) values. /// public IntPtr bmBits; } /// The BITMAPCOREHEADER structure contains information about the dimensions and color format of a DIB. /// /// /// The BITMAPCOREINFO structure combines the BITMAPCOREHEADER structure and a color table to provide a complete definition /// of the dimensions and colors of a DIB. For more information about specifying a DIB, see BITMAPCOREINFO. /// /// /// An application should use the information stored in the bcSize member to locate the color table in a BITMAPCOREINFO /// structure, using a method such as the following: /// /// /// pColor = ((LPBYTE) pBitmapCoreInfo + (WORD) (pBitmapCoreInfo -> bcSize)) /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapcoreheader typedef struct tagBITMAPCOREHEADER { DWORD // bcSize; WORD bcWidth; WORD bcHeight; WORD bcPlanes; WORD bcBitCount; } BITMAPCOREHEADER, *LPBITMAPCOREHEADER, *PBITMAPCOREHEADER; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.tagBITMAPCOREHEADER")] [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct BITMAPCOREHEADER { /// The number of bytes required by the structure. public uint bcSize; /// The width of the bitmap, in pixels. public ushort bcWidth; /// The height of the bitmap, in pixels. public ushort bcHeight; /// The number of planes for the target device. This value must be 1. public ushort bcPlanes; /// The number of bits-per-pixel. This value must be 1, 4, 8, or 24. public ushort bcBitCount; } /// The BITMAPCOREINFO structure defines the dimensions and color information for a DIB. /// /// /// A DIB consists of two parts: a BITMAPCOREINFO structure describing the dimensions and colors of the bitmap, and an array /// of bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with /// zeros to end on a LONG boundary. The origin of the bitmap is the lower-left corner. /// /// /// The bcBitCount member of the BITMAPCOREHEADER structure determines the number of bits that define each pixel and the /// maximum number of colors in the bitmap. This member can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// 1 /// /// The bitmap is monochrome, and the bmciColors member contains two entries. Each bit in the bitmap array represents a pixel. If /// the bit is clear, the pixel is displayed with the color of the first entry in the bmciColors table; if the bit is set, the pixel /// has the color of the second entry in the table. /// /// /// /// 4 /// /// The bitmap has a maximum of 16 colors, and the bmciColors member contains up to 16 entries. Each pixel in the bitmap is /// represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte represents two /// pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color in the sixteenth /// table entry. /// /// /// /// 8 /// /// The bitmap has a maximum of 256 colors, and the bmciColors member contains up to 256 entries. In this case, each byte in the /// array represents a single pixel. /// /// /// /// 24 /// /// The bitmap has a maximum of 2 (24) colors, and the bmciColors member is NULL. Each three-byte triplet in the bitmap array /// represents the relative intensities of blue, green, and red, respectively, for a pixel. /// /// /// /// The colors in the bmciColors table should appear in order of importance. /// /// Alternatively, for functions that use DIBs, the bmciColors member can be an array of 16-bit unsigned integers that /// specify indexes into the currently realized logical palette, instead of explicit RGB values. In this case, an application using /// the bitmap must call the DIB functions ( CreateDIBitmap, CreateDIBPatternBrush, and CreateDIBSection ) with the iUsage parameter /// set to DIB_PAL_COLORS. /// /// Note /// /// The bmciColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to /// another application. Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain /// explicit RGB values. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapcoreinfo typedef struct tagBITMAPCOREINFO { // BITMAPCOREHEADER bmciHeader; RGBTRIPLE bmciColors[1]; } BITMAPCOREINFO, *LPBITMAPCOREINFO, *PBITMAPCOREINFO; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.tagBITMAPCOREINFO")] [StructLayout(LayoutKind.Sequential)] public struct BITMAPCOREINFO { /// A BITMAPCOREHEADER structure that contains information about the dimensions and color format of a DIB. public BITMAPCOREHEADER bmciHeader; /// Specifies an array of RGBTRIPLE structures that define the colors in the bitmap. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public RGBTRIPLE[] bmciColors; } /// /// The BITMAPFILEHEADER structure contains information about the type, size, and layout of a file that contains a DIB. /// /// /// A BITMAPINFO or BITMAPCOREINFO structure immediately follows the BITMAPFILEHEADER structure in the DIB file. For more /// information, see Bitmap Storage. /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader typedef struct tagBITMAPFILEHEADER { WORD // bfType; DWORD bfSize; WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; } BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.tagBITMAPFILEHEADER")] [StructLayout(LayoutKind.Sequential)] public struct BITMAPFILEHEADER { /// The file type; must be BM. public ushort bfType; /// The size, in bytes, of the bitmap file. public uint bfSize; /// Reserved; must be zero. public ushort bfReserved1; /// Reserved; must be zero. public ushort bfReserved2; /// The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits. public uint bfOffBits; } /// The BITMAPINFO structure defines the dimensions and color information for a DIB. /// /// A DIB consists of two distinct parts: a BITMAPINFO structure describing the dimensions and colors of the bitmap, and an array of /// bytes defining the pixels of the bitmap. The bits in the array are packed together, but each scan line must be padded with zeros /// to end on a LONG data-type boundary. If the height of the bitmap is positive, the bitmap is a bottom-up DIB and its origin is /// the lower-left corner. If the height is negative, the bitmap is a top-down DIB and its origin is the upper left corner. /// /// A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header. Packed bitmaps are referenced by a single /// pointer. For packed bitmaps, the biClrUsed member must be set to an even number when using the DIB_PAL_COLORS mode so that the /// DIB bitmap array starts on a DWORD boundary. /// /// Note /// /// The bmiColors member should not contain palette indexes if the bitmap is to be stored in a file or transferred to another application. /// /// /// Unless the application has exclusive use and control of the bitmap, the bitmap color table should contain explicit RGB values. /// /// [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd183375")] public struct BITMAPINFO { /// A BITMAPINFOHEADER structure that contains information about the dimensions of color format. public BITMAPINFOHEADER bmiHeader; /// /// The bmiColors member contains one of the following: /// /// /// An array of RGBQUAD. The elements of the array that make up the color table. /// /// /// /// An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of /// bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, /// they must also call the following bitmap /// functions: CreateDIBitmap, CreateDIBPatternBrush, CreateDIBSection (The iUsage parameter of CreateDIBSection must be set to DIB_PAL_COLORS.) /// /// /// /// /// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. /// /// The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public RGBQUAD[] bmiColors; /// Initializes a new instance of the structure. /// The width. /// The height. /// The bit count. public BITMAPINFO(int width, int height, ushort bitCount = 32) : this() { bmiHeader = new BITMAPINFOHEADER(width, height, bitCount); } /// Creates a structure from the information in a bitmap handle. /// The handle to a bitmap. /// /// A structure with all the information the bitmap handle. If the specified bitmap is less than 24bpp, this resulting structure /// must not be used without creating unmanaged memory to hold the structure and BITMAPINFO.bmiHeader.biClrUsed * /// sizeof(RGBQUAD) extra bytes. /// public static BITMAPINFO FromHBITMAP(in HBITMAP hBmp) => new() { bmiHeader = BITMAPINFOHEADER.FromHBITMAP(hBmp) }; } /// /// /// The BITMAPINFOHEADER structure contains information about the dimensions and color format of a device-independent bitmap (DIB). /// /// /// Note This structure is also described in the GDI documentation. However, the semantics for video data are slightly /// different than the semantics used for GDI. If you are using this structure to describe video data, use the information given here. /// /// /// /// Color Tables /// /// The BITMAPINFOHEADER structure may be followed by an array of palette entries or color masks. The rules depend on the /// value of biCompression. /// /// /// /// /// If biCompression equals BI_RGB and the bitmap uses 8 bpp or less, the bitmap has a color table immediatelly /// following the BITMAPINFOHEADER structure. The color table consists of an array of RGBQUAD values. The size of the /// array is given by the biClrUsed member. If biClrUsed is zero, the array contains the maximum number of colors for /// the given bitdepth; that is, 2^ biBitCount colors. /// /// /// /// /// If biCompression equals BI_BITFIELDS, the bitmap uses three DWORD color masks (red, green, and blue, /// respectively), which specify the byte layout of the pixels. The 1 bits in each mask indicate the bits for that color within the pixel. /// /// /// /// /// If biCompression is a video FOURCC, the presence of a color table is implied by the video format. You should not assume /// that a color table exists when the bit depth is 8 bpp or less. However, some legacy components might assume that a color table /// is present. Therefore, if you are allocating a BITMAPINFOHEADER structure, it is recommended to allocate space for a /// color table when the bit depth is 8 bpp or less, even if the color table is not used. /// /// /// /// /// When the BITMAPINFOHEADER is followed by a color table or a set of color masks, you can use the BITMAPINFO structure to /// reference the color table of the color masks. The BITMAPINFO structure is defined as follows: /// /// /// typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; /// /// /// If you cast the BITMAPINFOHEADER to a BITMAPINFO, the bmiHeader member refers to the BITMAPINFOHEADER and /// the bmiColors member refers to the first entry in the color table, or the first color mask. /// /// /// Be aware that if the bitmap uses a color table or color masks, then the size of the entire format structure (the /// BITMAPINFOHEADER plus the color information) is not equal to /// sizeof(BITMAPINFOHEADER) /// or /// sizeof(BITMAPINFO) /// . You must calculate the actual size for each instance. /// /// Calculating Surface Stride /// /// In an uncompressed bitmap, the stride is the number of bytes needed to go from the start of one row of pixels to the start of /// the next row. The image format defines a minimum stride for an image. In addition, the graphics hardware might require a larger /// stride for the surface that contains the image. /// /// /// For uncompressed RGB formats, the minimum stride is always the image width in bytes, rounded up to the nearest DWORD. You /// can use the following formula to calculate the stride: /// /// /// stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3) /// /// /// For YUV formats, there is no general rule for calculating the minimum stride. You must understand the rules for the particular /// YUV format. For a description of the most common YUV formats, see Recommended 8-Bit YUV Formats for Video Rendering. /// /// /// Decoders and video sources should propose formats where biWidth is the width of the image in pixels. If the video renderer /// requires a surface stride that is larger than the default image stride, it modifies the proposed media type by setting the /// following values: /// /// /// /// It sets biWidth equal to the surface stride in pixels. /// /// /// It sets the rcTarget member of the VIDEOINFOHEADER or VIDEOINFOHEADER2 structure equal to the image width, in pixels. /// /// /// /// Then the video renderer proposes the modified format by calling IPin::QueryAccept on the upstream pin. For more information /// about this mechanism, see Dynamic Format Changes. /// /// /// If there is padding in the image buffer, never dereference a pointer into the memory that has been reserved for the padding. If /// the image buffer has been allocated in video memory, the padding might not be readable memory. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader typedef struct tagBITMAPINFOHEADER { DWORD // biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; LONG // biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.tagBITMAPINFOHEADER")] [StructLayout(LayoutKind.Sequential, Pack = 2)] public struct BITMAPINFOHEADER { /// /// Specifies the number of bytes required by the structure. This value does not include the size of the color table or the size /// of the color masks, if they are appended to the end of structure. See Remarks. /// public uint biSize; /// /// Specifies the width of the bitmap, in pixels. For information about calculating the stride of the bitmap, see Remarks. /// public int biWidth; /// /// Specifies the height of the bitmap, in pixels. /// /// /// /// For uncompressed RGB bitmaps, if biHeight is positive, the bitmap is a bottom-up DIB with the origin at the lower /// left corner. If biHeight is negative, the bitmap is a top-down DIB with the origin at the upper left corner. /// /// /// /// /// For YUV bitmaps, the bitmap is always top-down, regardless of the sign of biHeight. Decoders should offer YUV formats /// with postive biHeight, but for backward compatibility they should accept YUV formats with either positive or negative biHeight. /// /// /// /// For compressed formats, biHeight must be positive, regardless of image orientation. /// /// /// public int biHeight; /// Specifies the number of planes for the target device. This value must be set to 1. public ushort biPlanes; /// /// Specifies the number of bits per pixel (bpp). For uncompressed formats, this value is the average number of bits per pixel. /// For compressed formats, this value is the implied bit depth of the uncompressed image, after the image has been decoded. /// public ushort biBitCount; /// /// /// For compressed video and YUV formats, this member is a FOURCC code, specified as a DWORD in little-endian order. For /// example, YUYV video has the FOURCC 'VYUY' or 0x56595559. For more information, see FOURCC Codes. /// /// For uncompressed RGB formats, the following values are possible: /// /// /// Value /// Meaning /// /// /// BI_RGB /// Uncompressed RGB. /// /// /// BI_BITFIELDS /// Uncompressed RGB with color masks. Valid for 16-bpp and 32-bpp bitmaps. /// /// /// See Remarks for more information. Note that BI_JPG and BI_PNG are not valid video formats. /// /// For 16-bpp bitmaps, if biCompression equals BI_RGB, the format is always RGB 555. If biCompression /// equals BI_BITFIELDS, the format is either RGB 555 or RGB 565. Use the subtype GUID in the AM_MEDIA_TYPE structure to /// determine the specific RGB type. /// /// public BitmapCompressionMode biCompression; /// Specifies the size, in bytes, of the image. This can be set to 0 for uncompressed RGB bitmaps. public uint biSizeImage; /// Specifies the horizontal resolution, in pixels per meter, of the target device for the bitmap. public int biXPelsPerMeter; /// Specifies the vertical resolution, in pixels per meter, of the target device for the bitmap. public int biYPelsPerMeter; /// /// Specifies the number of color indices in the color table that are actually used by the bitmap. See Remarks for more information. /// public uint biClrUsed; /// /// Specifies the number of color indices that are considered important for displaying the bitmap. If this value is zero, all /// colors are important. /// public uint biClrImportant; /// Initializes a new instance of the structure. /// The width. /// The height. /// The bit count. public BITMAPINFOHEADER(int width, int height, ushort bitCount = 32) : this() { biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFO)); biWidth = width; biHeight = height; biPlanes = 1; biBitCount = bitCount; biCompression = BitmapCompressionMode.BI_RGB; biSizeImage = 0; // (uint)width * (uint)height * bitCount / 8; } /// Creates a structure from the information in a bitmap handle. /// The handle to a bitmap. /// /// A structure with all the information the bitmap handle. If the specified bitmap is less than 24bpp, the value is set to the number of structures that must be allocated. /// public static BITMAPINFOHEADER FromHBITMAP(in HBITMAP hBmp) { // Retrieve the bitmap color format, width, and height. var bmp = GetObject(hBmp); // Convert the color format to a count of bits. var cClrBits = (ushort)(bmp.bmPlanes * bmp.bmBitsPixel) switch { 1 => 1, <= 4 => 4, <= 8 => 8, <= 16 => 16, <= 24 => 24, _ => 32, }; // Initialize the fields in the BITMAPINFO structure. return new() { biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)), biWidth = bmp.bmWidth, biHeight = bmp.bmHeight, biPlanes = bmp.bmPlanes, biBitCount = bmp.bmBitsPixel, // This value is correct, but there is no memory alllocated to hold these bits biClrUsed = cClrBits < 24 ? 1U << cClrBits : 0, // If the bitmap is not compressed, set the BI_RGB flag. biCompression = BitmapCompressionMode.BI_RGB, // Compute the number of bytes in the array of color indices and store the result in biSizeImage. The width must be uint // aligned unless the bitmap is RLE compressed. biSizeImage = (uint)(((bmp.bmWidth * cClrBits + 31) & ~31) / 8 * bmp.bmHeight), // Set biClrImportant to 0, indicating that all of the device colors are important. biClrImportant = 0 }; } /// Gets the default value for this structure with size fields set appropriately. public static readonly BITMAPINFOHEADER Default = new() { biSize = (uint)Marshal.SizeOf(typeof(BITMAPINFOHEADER)) }; } /// /// /// The BITMAPV4HEADER structure is the bitmap information header file. It is an extended version of the BITMAPINFOHEADER structure. /// /// Applications can use the BITMAPV5HEADER structure for added functionality. /// /// /// The BITMAPV4HEADER structure is extended to allow a JPEG or PNG image to be passed as the source image to StretchDIBits. /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapv4header typedef struct { DWORD bV4Size; LONG bV4Width; // LONG bV4Height; WORD bV4Planes; WORD bV4BitCount; DWORD bV4V4Compression; DWORD bV4SizeImage; LONG bV4XPelsPerMeter; LONG // bV4YPelsPerMeter; DWORD bV4ClrUsed; DWORD bV4ClrImportant; DWORD bV4RedMask; DWORD bV4GreenMask; DWORD bV4BlueMask; DWORD // bV4AlphaMask; DWORD bV4CSType; CIEXYZTRIPLE bV4Endpoints; DWORD bV4GammaRed; DWORD bV4GammaGreen; DWORD bV4GammaBlue; } // BITMAPV4HEADER, *LPBITMAPV4HEADER, *PBITMAPV4HEADER; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.__unnamed_struct_0")] [StructLayout(LayoutKind.Sequential)] public struct BITMAPV4HEADER { /// /// The number of bytes required by the structure. Applications should use this member to determine which bitmap information /// header structure is being used. /// public uint bV4Size; /// /// The width of the bitmap, in pixels. /// If bV4Compression is BI_JPEG or BI_PNG, bV4Width specifies the width of the JPEG or PNG image in pixels. /// public int bV4Width; /// /// /// The height of the bitmap, in pixels. If bV4Height is positive, the bitmap is a bottom-up DIB and its origin is the /// lower-left corner. If bV4Height is negative, the bitmap is a top-down DIB and its origin is the upper-left corner. /// /// /// If bV4Height is negative, indicating a top-down DIB, bV4Compression must be either BI_RGB or BI_BITFIELDS. /// Top-down DIBs cannot be compressed. /// /// If bV4Compression is BI_JPEG or BI_PNG, bV4Height specifies the height of the JPEG or PNG image in pixels. /// public int bV4Height; /// The number of planes for the target device. This value must be set to 1. public ushort bV4Planes; /// /// /// The number of bits-per-pixel. The bV4BitCount member of the BITMAPV4HEADER structure determines the number of /// bits that define each pixel and the maximum number of colors in the bitmap. This member must be one of the following values. /// /// /// /// Value /// Meaning /// /// /// 0 /// The number of bits-per-pixel is specified or is implied by the JPEG or PNG file format. /// /// /// 1 /// /// The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array /// represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors table; if /// the bit is set, the pixel has the color of the second entry in the table. /// /// /// /// 4 /// /// The bitmap has a maximum of 16 colors, and the bmiColors member of BITMAPINFO contains up to 16 entries. Each pixel in the /// bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte /// represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color /// in the sixteenth table entry. /// /// /// /// 8 /// /// The bitmap has a maximum of 256 colors, and the bmiColors member of BITMAPINFO contains up to 256 entries. In this case, /// each byte in the array represents a single pixel. /// /// /// /// 16 /// /// The bitmap has a maximum of 2^16 colors. If the bV4Compression member of the BITMAPV4HEADER structure is BI_RGB, the /// bmiColors member of BITMAPINFO is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of /// red, green, and blue are represented with five bits for each color component. The value for blue is in the least significant /// five bits, followed by five bits each for green and red, respectively. The most significant bit is not used. The bmiColors /// color table is used for optimizing colors used on palette-based devices, and must contain the number of entries specified by /// the bV4ClrUsed member of the BITMAPV4HEADER.If the bV4Compression member of the BITMAPV4HEADER is BI_BITFIELDS, the /// bmiColors member contains three DWORD color masks that specify the red, green, and blue components of each pixel. Each WORD /// in the bitmap array represents a single pixel. /// /// /// /// 24 /// /// The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL. Each 3-byte triplet in the bitmap /// array represents the relative intensities of blue, green, and red for a pixel. The bmiColors color table is used for /// optimizing colors used on palette-based devices, and must contain the number of entries specified by the bV4ClrUsed member /// of the BITMAPV4HEADER. /// /// /// /// 32 /// /// The bitmap has a maximum of 2^32 colors. If the bV4Compression member of the BITMAPV4HEADER is BI_RGB, the bmiColors member /// of BITMAPINFO is NULL. Each DWORD in the bitmap array represents the relative intensities of blue, green, and red for a /// pixel. The value for blue is in the least significant 8 bits, followed by 8 bits each for green and red. The high byte in /// each DWORD is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must /// contain the number of entries specified by the bV4ClrUsed member of the BITMAPV4HEADER.If the bV4Compression member of the /// BITMAPV4HEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue /// components of each pixel. Each DWORD in the bitmap array represents a single pixel. /// /// /// /// public ushort bV4BitCount; /// /// /// The type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be compressed). This member can be one of /// the following values. /// /// /// /// Value /// Description /// /// /// BI_RGB /// An uncompressed format. /// /// /// BI_RLE8 /// /// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a 2-byte format consisting of a count /// byte followed by a byte containing a color index. For more information, see Bitmap Compression. /// /// /// /// BI_RLE4 /// /// An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format consisting of a count byte followed by two /// word-length color indexes. For more information, see Bitmap Compression. /// /// /// /// BI_BITFIELDS /// /// Specifies that the bitmap is not compressed. The members bV4RedMask, bV4GreenMask, and bV4BlueMask specify the red, green, /// and blue components for each pixel. This is valid when used with 16- and 32-bpp bitmaps. /// /// /// /// BI_JPEG /// /// Specifies that the image is compressed using the JPEG file interchange format. JPEG compression trades off compression /// against loss; it can achieve a compression ratio of 20:1 with little noticeable loss. /// /// /// /// BI_PNG /// Specifies that the image is compressed using the PNG file interchange format. /// /// /// public uint bV4V4Compression; /// /// The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. /// If bV4Compression is BI_JPEG or BI_PNG, bV4SizeImage is the size of the JPEG or PNG image buffer. /// public uint bV4SizeImage; /// /// The horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to /// select a bitmap from a resource group that best matches the characteristics of the current device. /// public int bV4XPelsPerMeter; /// The vertical resolution, in pixels-per-meter, of the target device for the bitmap. public int bV4YPelsPerMeter; /// /// /// The number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses /// the maximum number of colors corresponding to the value of the bV4BitCount member for the compression mode specified /// by bV4Compression. /// /// /// If bV4ClrUsed is nonzero and the bV4BitCount member is less than 16, the bV4ClrUsed member specifies /// the actual number of colors the graphics engine or device driver accesses. If bV4BitCount is 16 or greater, the /// bV4ClrUsed member specifies the size of the color table used to optimize performance of the system color palettes. If /// bV4BitCount equals 16 or 32, the optimal color palette starts immediately following the BITMAPV4HEADER. /// /// public uint bV4ClrUsed; /// /// The number of color indexes that are required for displaying the bitmap. If this value is zero, all colors are important. /// public uint bV4ClrImportant; /// Color mask that specifies the red component of each pixel, valid only if bV4Compression is set to BI_BITFIELDS. public uint bV4RedMask; /// Color mask that specifies the green component of each pixel, valid only if bV4Compression is set to BI_BITFIELDS. public uint bV4GreenMask; /// Color mask that specifies the blue component of each pixel, valid only if bV4Compression is set to BI_BITFIELDS. public uint bV4BlueMask; /// Color mask that specifies the alpha component of each pixel. public uint bV4AlphaMask; /// /// The color space of the DIB. The following table lists the value for bV4CSType. /// /// /// Value /// Meaning /// /// /// LCS_CALIBRATED_RGB /// This value indicates that endpoints and gamma values are given in the appropriate fields. /// /// /// See the LOGCOLORSPACE structure for information that defines a logical color space. /// public uint bV4CSType; /// /// /// A CIEXYZTRIPLE structure that specifies the x, y, and z coordinates of the three colors that correspond to the red, green, /// and blue endpoints for the logical color space associated with the bitmap. This member is ignored unless the /// bV4CSType member specifies LCS_CALIBRATED_RGB. /// /// /// Note A color space is a model for representing color numerically in terms of three or more coordinates. For example, /// the RGB color space represents colors in terms of the red, green, and blue coordinates. /// /// public CIEXYZTRIPLE bV4Endpoints; /// /// Tone response curve for red. This member is ignored unless color values are calibrated RGB values and bV4CSType is /// set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 format. The upper 16 bits are the unsigned integer value. The /// lower 16 bits are the fractional part. /// public uint bV4GammaRed; /// /// Tone response curve for green. Used if bV4CSType is set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 /// format. The upper 16 bits are the unsigned integer value. The lower 16 bits are the fractional part. /// public uint bV4GammaGreen; /// /// Tone response curve for blue. Used if bV4CSType is set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 format. /// The upper 16 bits are the unsigned integer value. The lower 16 bits are the fractional part. /// public uint bV4GammaBlue; } /// /// The BITMAPV5HEADER structure is the bitmap information header file. It is an extended version of the BITMAPINFOHEADER structure. /// /// /// /// If bV5Height is negative, indicating a top-down DIB, bV5Compression must be either BI_RGB or BI_BITFIELDS. /// Top-down DIBs cannot be compressed. /// /// /// The Independent Color Management interface (ICM) 2.0 allows International Color Consortium (ICC) color profiles to be linked or /// embedded in DIBs (DIBs). See Using Structures for more information. /// /// /// When a DIB is loaded into memory, the profile data (if present) should follow the color table, and the bV5ProfileData /// should provide the offset of the profile data from the beginning of the BITMAPV5HEADER structure. The value stored in /// bV5ProfileData will be different from the value returned by the sizeof operator given the BITMAPV5HEADER /// argument, because bV5ProfileData is the offset in bytes from the beginning of the BITMAPV5HEADER structure to the /// start of the profile data. (Bitmap bits do not follow the color table in memory). Applications should modify the /// bV5ProfileData member after loading the DIB into memory. /// /// /// For packed DIBs, the profile data should follow the bitmap bits similar to the file format. The bV5ProfileData member /// should still give the offset of the profile data from the beginning of the BITMAPV5HEADER. /// /// /// Applications should access the profile data only when bV5Size equals the size of the BITMAPV5HEADER and /// bV5CSType equals PROFILE_EMBEDDED or PROFILE_LINKED. /// /// /// If a profile is linked, the path of the profile can be any fully qualified name (including a network path) that can be opened /// using the CreateFile function. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapv5header typedef struct { DWORD bV5Size; LONG bV5Width; // LONG bV5Height; WORD bV5Planes; WORD bV5BitCount; DWORD bV5Compression; DWORD bV5SizeImage; LONG bV5XPelsPerMeter; LONG // bV5YPelsPerMeter; DWORD bV5ClrUsed; DWORD bV5ClrImportant; DWORD bV5RedMask; DWORD bV5GreenMask; DWORD bV5BlueMask; DWORD // bV5AlphaMask; DWORD bV5CSType; CIEXYZTRIPLE bV5Endpoints; DWORD bV5GammaRed; DWORD bV5GammaGreen; DWORD bV5GammaBlue; DWORD // bV5Intent; DWORD bV5ProfileData; DWORD bV5ProfileSize; DWORD bV5Reserved; } BITMAPV5HEADER, *LPBITMAPV5HEADER, *PBITMAPV5HEADER; [PInvokeData("wingdi.h", MSDNShortId = "NS:wingdi.__unnamed_struct_1")] [StructLayout(LayoutKind.Sequential)] public struct BITMAPV5HEADER { /// /// The number of bytes required by the structure. Applications should use this member to determine which bitmap information /// header structure is being used. /// public uint bV5Size; /// /// The width of the bitmap, in pixels. /// /// If bV5Compression is BI_JPEG or BI_PNG, the bV5Width member specifies the width of the decompressed JPEG or /// PNG image in pixels. /// /// public int bV5Width; /// /// /// The height of the bitmap, in pixels. If the value of bV5Height is positive, the bitmap is a bottom-up DIB and its /// origin is the lower-left corner. If bV5Height value is negative, the bitmap is a top-down DIB and its origin is the /// upper-left corner. /// /// /// If bV5Height is negative, indicating a top-down DIB, bV5Compression must be either BI_RGB or BI_BITFIELDS. /// Top-down DIBs cannot be compressed. /// /// /// If bV5Compression is BI_JPEG or BI_PNG, the bV5Height member specifies the height of the decompressed JPEG or /// PNG image in pixels. /// /// public int bV5Height; /// The number of planes for the target device. This value must be set to 1. public ushort bV5Planes; /// /// The number of bits that define each pixel and the maximum number of colors in the bitmap. /// This member can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// The number of bits per pixel is specified or is implied by the JPEG or PNG file format. /// /// /// 1 /// /// The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries. Each bit in the bitmap array /// represents a pixel. If the bit is clear, the pixel is displayed with the color of the first entry in the bmiColors color /// table. If the bit is set, the pixel has the color of the second entry in the table. /// /// /// /// 4 /// /// The bitmap has a maximum of 16 colors, and the bmiColors member of BITMAPINFO contains up to 16 entries. Each pixel in the /// bitmap is represented by a 4-bit index into the color table. For example, if the first byte in the bitmap is 0x1F, the byte /// represents two pixels. The first pixel contains the color in the second table entry, and the second pixel contains the color /// in the sixteenth table entry. /// /// /// /// 8 /// /// The bitmap has a maximum of 256 colors, and the bmiColors member of BITMAPINFO contains up to 256 entries. In this case, /// each byte in the array represents a single pixel. /// /// /// /// 16 /// /// The bitmap has a maximum of 2^16 colors. If the bV5Compression member of the BITMAPV5HEADER structure is BI_RGB, the /// bmiColors member of BITMAPINFO is NULL. Each WORD in the bitmap array represents a single pixel. The relative intensities of /// red, green, and blue are represented with five bits for each color component. The value for blue is in the least significant /// five bits, followed by five bits each for green and red. The most significant bit is not used. The bmiColors color table is /// used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the bV5ClrUsed /// member of the BITMAPV5HEADER.If the bV5Compression member of the BITMAPV5HEADER is BI_BITFIELDS, the bmiColors member /// contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each WORD in /// the bitmap array represents a single pixel. When the bV5Compression member is BI_BITFIELDS, bits set in each DWORD mask must /// be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not need to be used. /// /// /// /// 24 /// /// The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL. Each 3-byte triplet in the bitmap /// array represents the relative intensities of blue, green, and red, respectively, for a pixel. The bmiColors color table is /// used for optimizing colors used on palette-based devices, and must contain the number of entries specified by the bV5ClrUsed /// member of the BITMAPV5HEADER structure. /// /// /// /// 32 /// /// The bitmap has a maximum of 2^32 colors. If the bV5Compression member of the BITMAPV5HEADER is BI_RGB, the bmiColors member /// of BITMAPINFO is NULL. Each DWORD in the bitmap array represents the relative intensities of blue, green, and red for a /// pixel. The value for blue is in the least significant 8 bits, followed by 8 bits each for green and red. The high byte in /// each DWORD is not used. The bmiColors color table is used for optimizing colors used on palette-based devices, and must /// contain the number of entries specified by the bV5ClrUsed member of the BITMAPV5HEADER.If the bV5Compression member of the /// BITMAPV5HEADER is BI_BITFIELDS, the bmiColors member contains three DWORD color masks that specify the red, green, and blue /// components of each pixel. Each DWORD in the bitmap array represents a single pixel. /// /// /// /// public ushort bV5BitCount; /// /// /// Specifies that the bitmap is not compressed. The bV5RedMask, bV5GreenMask, and bV5BlueMask members /// specify the red, green, and blue components of each pixel. This is valid when used with 16- and 32-bpp bitmaps. This member /// can be one of the following values. /// /// /// /// Value /// Meaning /// /// /// BI_RGB /// An uncompressed format. /// /// /// BI_RLE8 /// /// A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format is a two-byte format consisting of a count /// byte followed by a byte containing a color index. If bV5Compression is BI_RGB and the bV5BitCount member is 16, 24, or 32, /// the bitmap array specifies the actual intensities of blue, green, and red rather than using color table indexes. For more /// information, see Bitmap Compression. /// /// /// /// BI_RLE4 /// /// An RLE format for bitmaps with 4 bpp. The compression format is a two-byte format consisting of a count byte followed by two /// word-length color indexes. For more information, see Bitmap Compression. /// /// /// /// BI_BITFIELDS /// /// Specifies that the bitmap is not compressed and that the color masks for the red, green, and blue components of each pixel /// are specified in the bV5RedMask, bV5GreenMask, and bV5BlueMask members. This is valid when used with 16- and 32-bpp bitmaps. /// /// /// /// BI_JPEG /// /// Specifies that the image is compressed using the JPEG file Interchange Format. JPEG compression trades off compression /// against loss; it can achieve a compression ratio of 20:1 with little noticeable loss. /// /// /// /// BI_PNG /// Specifies that the image is compressed using the PNG file Interchange Format. /// /// /// public uint bV5Compression; /// /// The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. /// If bV5Compression is BI_JPEG or BI_PNG, bV5SizeImage is the size of the JPEG or PNG image buffer. /// public uint bV5SizeImage; /// /// The horizontal resolution, in pixels-per-meter, of the target device for the bitmap. An application can use this value to /// select a bitmap from a resource group that best matches the characteristics of the current device. /// public int bV5XPelsPerMeter; /// The vertical resolution, in pixels-per-meter, of the target device for the bitmap. public int bV5YPelsPerMeter; /// /// /// The number of color indexes in the color table that are actually used by the bitmap. If this value is zero, the bitmap uses /// the maximum number of colors corresponding to the value of the bV5BitCount member for the compression mode specified /// by bV5Compression. /// /// /// If bV5ClrUsed is nonzero and bV5BitCount is less than 16, the bV5ClrUsed member specifies the actual /// number of colors the graphics engine or device driver accesses. If bV5BitCount is 16 or greater, the /// bV5ClrUsed member specifies the size of the color table used to optimize performance of the system color palettes. If /// bV5BitCount equals 16 or 32, the optimal color palette starts immediately following the BITMAPV5HEADER. If /// bV5ClrUsed is nonzero, the color table is used on palettized devices, and bV5ClrUsed specifies the number of entries. /// /// public uint bV5ClrUsed; /// /// The number of color indexes that are required for displaying the bitmap. If this value is zero, all colors are required. /// public uint bV5ClrImportant; /// Color mask that specifies the red component of each pixel, valid only if bV5Compression is set to BI_BITFIELDS. public uint bV5RedMask; /// Color mask that specifies the green component of each pixel, valid only if bV5Compression is set to BI_BITFIELDS. public uint bV5GreenMask; /// Color mask that specifies the blue component of each pixel, valid only if bV5Compression is set to BI_BITFIELDS. public uint bV5BlueMask; /// Color mask that specifies the alpha component of each pixel. public uint bV5AlphaMask; /// /// The color space of the DIB. /// The following table specifies the values for bV5CSType. /// /// /// Value /// Meaning /// /// /// LCS_CALIBRATED_RGB /// This value implies that endpoints and gamma values are given in the appropriate fields. /// /// /// LCS_sRGB /// Specifies that the bitmap is in sRGB color space. /// /// /// LCS_WINDOWS_COLOR_SPACE /// This value indicates that the bitmap is in the system default color space, sRGB. /// /// /// PROFILE_LINKED /// /// This value indicates that bV5ProfileData points to the file name of the profile to use (gamma and endpoints values are ignored). /// /// /// /// PROFILE_EMBEDDED /// /// This value indicates that bV5ProfileData points to a memory buffer that contains the profile to be used (gamma and endpoints /// values are ignored). /// /// /// /// See the LOGCOLORSPACE structure for information that defines a logical color space. /// public uint bV5CSType; /// /// A CIEXYZTRIPLE structure that specifies the x, y, and z coordinates of the three colors that correspond to the red, green, /// and blue endpoints for the logical color space associated with the bitmap. This member is ignored unless the /// bV5CSType member specifies LCS_CALIBRATED_RGB. /// public CIEXYZTRIPLE bV5Endpoints; /// /// Toned response curve for red. Used if bV5CSType is set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 format. /// The upper 16 bits are the unsigned integer value. The lower 16 bits are the fractional part. /// public uint bV5GammaRed; /// /// Toned response curve for green. Used if bV5CSType is set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 /// format. The upper 16 bits are the unsigned integer value. The lower 16 bits are the fractional part. /// public uint bV5GammaGreen; /// /// Toned response curve for blue. Used if bV5CSType is set to LCS_CALIBRATED_RGB. Specify in unsigned fixed 16.16 /// format. The upper 16 bits are the unsigned integer value. The lower 16 bits are the fractional part. /// public uint bV5GammaBlue; /// /// Rendering intent for bitmap. This can be one of the following values. /// /// /// Value /// Intent /// ICC name /// Meaning /// /// /// LCS_GM_ABS_COLORIMETRIC /// Match /// Absolute Colorimetric /// Maintains the white point. Matches the colors to their nearest color in the destination gamut. /// /// /// LCS_GM_BUSINESS /// Graphic /// Saturation /// Maintains saturation. Used for business charts and other situations in which undithered colors are required. /// /// /// LCS_GM_GRAPHICS /// Proof /// Relative Colorimetric /// Maintains colorimetric match. Used for graphic designs and named colors. /// /// /// LCS_GM_IMAGES /// Picture /// Perceptual /// Maintains contrast. Used for photographs and natural images. /// /// /// public uint bV5Intent; /// /// The offset, in bytes, from the beginning of the BITMAPV5HEADER structure to the start of the profile data. If the /// profile is embedded, profile data is the actual profile, and it is linked. (The profile data is the null-terminated file /// name of the profile.) This cannot be a Unicode string. It must be composed exclusively of characters from the Windows /// character set (code page 1252). These profile members are ignored unless the bV5CSType member specifies /// PROFILE_LINKED or PROFILE_EMBEDDED. /// public uint bV5ProfileData; /// Size, in bytes, of embedded profile data. public uint bV5ProfileSize; /// This member has been reserved. Its value should be set to zero. public uint bV5Reserved; } /// /// The DIBSECTION structure contains information about a DIB created by calling the CreateDIBSection function. A DIBSECTION /// structure includes information about the bitmap's dimensions, color format, color masks, optional file mapping object, and /// optional bit values storage offset. An application can obtain a filled-in DIBSECTION structure for a given DIB by calling the /// GetObject function. /// [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd183567")] public struct DIBSECTION { /// /// A BITMAP data structure that contains information about the DIB: its type, its dimensions, its color capacities, and a /// pointer to its bit values. /// public BITMAP dsBm; /// A BITMAPINFOHEADER structure that contains information about the color format of the DIB. public BITMAPINFOHEADER dsBmih; private uint dsBitField1; private uint dsBitField2; private uint dsBitField3; /// /// The DSH sectionContains a handle to the file mapping object that the CreateDIBSection function used to create the DIB. If /// CreateDIBSection was called with a NULL value for its hSection parameter, causing the system to allocate memory for the /// bitmap, the dshSection member will be NULL. /// public IntPtr dshSection; /// /// The offset to the bitmap's bit values within the file mapping object referenced by dshSection. If dshSection is NULL, the /// dsOffset value has no meaning. /// public uint dsOffset; /// /// Specifies three color masks for the DIB. This field is only valid when the BitCount member of the BITMAPINFOHEADER structure /// has a value greater than 8. Each color mask indicates the bits that are used to encode one of the three color channels (red, /// green, and blue). /// #pragma warning disable IDE1006 // Naming Styles public uint[] dsBitFields #pragma warning restore IDE1006 // Naming Styles { get => new[] { dsBitField1, dsBitField2, dsBitField3 }; set { dsBitField1 = value[0]; dsBitField2 = value[1]; dsBitField3 = value[2]; } } /// Gets the default value for this structure with size fields set appropriately. public static readonly DIBSECTION Default = new() { dsBmih = BITMAPINFOHEADER.Default }; } /// The RGBQUAD structure describes a color consisting of relative intensities of red, green, and blue. [StructLayout(LayoutKind.Sequential)] [PInvokeData("Wingdi.h", MSDNShortId = "dd162938")] public struct RGBQUAD { /// The intensity of blue in the color. public byte rgbBlue; /// The intensity of green in the color. public byte rgbGreen; /// The intensity of red in the color. public byte rgbRed; /// This member is reserved and must be zero. public byte rgbReserved; /// Gets a value indicating whether any transparency is defined. /// if this value is transparent; otherwise, . public bool IsTransparent => rgbReserved == 0; /// Gets or sets the color associated with the structure. /// The color. public COLORREF Color { get => new(rgbRed, rgbGreen, rgbBlue) { A = rgbReserved }; set { rgbReserved = value.A; rgbBlue = value.B; rgbGreen = value.G; rgbRed = value.R; } } /// Performs an implicit conversion from to . /// The c. /// The result of the conversion. public static implicit operator RGBQUAD(COLORREF c) => new() { Color = c }; /// Performs an implicit conversion from to . /// The c. /// The result of the conversion. public static implicit operator COLORREF(RGBQUAD c) => c.Color; } /// Provides a safe handle to a structure. public class SafeBITMAPINFO : SafeCoTaskMemStruct { private const int RGBQUADSZ = 4; /// Initializes a new instance of the class. /// The value. public SafeBITMAPINFO(in BITMAPINFO bmpInfo) : base(BaseStructSize + (bmpInfo.bmiColors?.Length ?? 0) * RGBQUADSZ) { handle.Write(bmpInfo.bmiHeader, 0, Size); bmiColors = bmpInfo.bmiColors; } /// Initializes a new instance of the class. /// The HDR. /// The capacity of the buffer, in bytes. If 0 or , the capacity is calculated. public SafeBITMAPINFO(in BITMAPINFOHEADER hdr, SizeT capacity = default) : base(Math.Max(capacity, BaseStructSize)) { handle.Write(hdr, 0, Size); } /// Initializes a new instance of the class. /// Existing handle. /// if set to true if this class is responsible for freeing the memory on disposal. protected SafeBITMAPINFO(IntPtr ptr, bool ownsHandle = true) : base(ptr, ownsHandle, 0) { } #pragma warning disable IDE1006 // Naming Styles /// /// The bmiColors member contains one of the following: /// /// /// An array of RGBQUAD. The elements of the array that make up the color table. /// /// /// /// An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of /// bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, /// they must also call the following bitmap functions: CreateDIBitmap, CreateDIBPatternBrush, CreateDIBSection (The iUsage /// parameter of CreateDIBSection must be set to DIB_PAL_COLORS.) /// /// /// /// /// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. /// /// The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section. /// public byte[] bmiColorBytes { get => handle.ToArray((Size - BaseStructSize), BaseStructSize, Size); set { var reqSize = BaseStructSize + (value?.Length ?? 0); if (Size < reqSize) Size = reqSize; else handle.Offset(BaseStructSize).FillMemory(0, Size - BaseStructSize); handle.Write(value, BaseStructSize, Size); } } /// /// The bmiColors member contains one of the following: /// /// /// An array of RGBQUAD. The elements of the array that make up the color table. /// /// /// /// An array of 16-bit unsigned integers that specifies indexes into the currently realized logical palette. This use of /// bmiColors is allowed for functions that use DIBs. When bmiColors elements contain indexes to a realized logical palette, /// they must also call the following bitmap functions: CreateDIBitmap, CreateDIBPatternBrush, CreateDIBSection (The iUsage /// parameter of CreateDIBSection must be set to DIB_PAL_COLORS.) /// /// /// /// /// The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure. /// /// The colors in the bmiColors table appear in order of importance. For more information, see the Remarks section. /// public RGBQUAD[] bmiColors { get => handle.ToArray((Size - BaseStructSize) / RGBQUADSZ, BaseStructSize, Size); set { var reqSize = BaseStructSize + (value?.Length ?? 0) * RGBQUADSZ; if (Size < reqSize) Size = reqSize; else handle.Offset(BaseStructSize).FillMemory(0, Size - BaseStructSize); handle.Write(value, BaseStructSize, Size); } } /// A BITMAPINFOHEADER structure that contains information about the dimensions of color format. public BITMAPINFOHEADER bmiHeader { get => Value.bmiHeader; set => handle.Write(value, 0, Size); } #if ALLOWSPAN /// A reference to the BITMAPINFOHEADER structure. public ref BITMAPINFOHEADER bmiHeaderAsRef => ref AsRef().bmiHeader; #endif #pragma warning restore IDE1006 // Naming Styles /// /// Specifies the number of bytes required by the structure. This value does not include the size of the color table or the size /// of the color masks, if they are appended to the end of structure. See Remarks. /// public SizeT HeaderSize { get => handle.ToStructure(); set => handle.Write((uint)value); } /// Represents the equivalent of this class instances. public static new readonly SafeBITMAPINFO Null = new(IntPtr.Zero, false); /// Performs an implicit conversion from to . /// The value. /// The resulting instance from the conversion. public static implicit operator SafeBITMAPINFO(in BITMAPINFO bi) => new(bi); /// Gets a header of the specified type . /// The type of the header to get. /// The requested header structure. public T GetHeader() where T : struct => handle.ToStructure(Size); /// Zero out all allocated memory. public override void Zero() { base.Zero(); HeaderSize = BaseStructSize; } } } }