// ========================================================== // FreeImage 3 .NET wrapper // Original FreeImage 3 functions and .NET compatible derived functions // // Design and implementation by // - Jean-Philippe Goerke (jpgoerke@users.sourceforge.net) // - Carsten Klein (cklein05@users.sourceforge.net) // // Contributors: // - David Boland (davidboland@vodafone.ie) // // Main reference : MSDN Knowlede Base // // This file is part of FreeImage 3 // // COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES // THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE // OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED // CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT // THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY // SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL // PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER // THIS DISCLAIMER. // // Use at your own risk! // ========================================================== // ========================================================== // To build the project without VS use the following commandline: // "csc.exe /out:FreeImageNET.dll /target:library /doc:FreeImageNET.XML /debug- /o /unsafe+ /filealign:512 FreeImage.cs" // ========================================================== using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Text; using System.Text.RegularExpressions; using System.Xml; using FreeImageAPI; using FreeImageAPI.IO; using FreeImageAPI.Metadata; using FreeImageAPI.Plugins; ///////////////////////////////////////////////////// // // // FreeImage.h import // // // ///////////////////////////////////////////////////// #region Structs namespace FreeImageAPI { /// /// The BITMAP structure defines the type, width, height, color format, and bit values of a bitmap. /// /// /// The bitmap formats currently used are monochrome and color. The monochrome bitmap uses a one-bit, /// one-plane format. Each scan is a multiple of 32 bits. /// /// Scans are organized as follows for a monochrome bitmap of height n: /// /// /// Scan 0 /// Scan 1 /// . /// . /// . /// Scan n-2 /// Scan n-1 /// /// /// The pixels on a monochrome device are either black or white. If the corresponding bit in the /// bitmap is 1, the pixel is set to the foreground color; if the corresponding bit in the bitmap /// is zero, the pixel is set to the background color. /// /// All devices that have the RC_BITBLT device capability support bitmaps. For more information, /// see GetDeviceCaps. /// /// Each device has a unique color format. To transfer a bitmap from one device to another, /// use the GetDIBits and SetDIBits functions. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct BITMAP { /// /// Specifies the bitmap type. This member must be zero. /// public int bmType; /// /// Specifies the width, in pixels, of the bitmap. The width must be greater than zero. /// public int bmWidth; /// /// Specifies the height, in pixels, of the bitmap. The height must be greater than zero. /// public int bmHeight; /// /// Specifies 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; /// /// Specifies the count of color planes. /// public ushort bmPlanes; /// /// Specifies the number of bits required to indicate the color of a pixel. /// public ushort bmBitsPixel; /// /// Pointer to the location of the bit values for the bitmap. /// The bmBits member must be a long pointer to an array of character (1-byte) values. /// public IntPtr bmBits; } } namespace FreeImageAPI { /// /// This structure contains information about the dimensions and color format /// of a device-independent bitmap (DIB). /// /// /// The structure combines the /// BITMAPINFOHEADER structure and a color table to provide a complete /// definition of the dimensions and colors of a DIB. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct BITMAPINFOHEADER : IEquatable { /// /// Specifies the size of the structure, in bytes. /// public uint biSize; /// /// Specifies the width of the bitmap, in pixels. /// /// Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, /// the biWidth member specifies the width of the decompressed JPEG or PNG image file, /// respectively. /// public int biWidth; /// /// Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap /// is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, /// the bitmap is a top-down DIB and its origin is the upper-left corner. /// /// If biHeight is negative, indicating a top-down DIB, biCompression must be /// either BI_RGB or BI_BITFIELDS. Top-down DIBs cannot be compressed. /// /// Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, /// the biHeight member specifies the height of the decompressed JPEG or PNG image file, /// respectively. /// 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.The biBitCount member of the BITMAPINFOHEADER /// 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 /// /// Windows 98/Me, Windows 2000/XP: The number of bits-per-pixel is specified /// or is implied by the JPEG or PNG format. /// /// /// /// /// 1 /// /// The bitmap is monochrome, and the bmiColors member of /// 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 biCompression member of the /// BITMAPINFOHEADER 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 biClrUsed member of the BITMAPINFOHEADER. /// /// If the biCompression member of the BITMAPINFOHEADER 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. /// /// Windows NT/Windows 2000/XP: When the biCompression 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 have to be used. /// /// Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system /// supports only the following 16bpp color masks: A 5-5-5 16-bit image, where the blue mask is /// 0x001F, the green mask is 0x03E0, and the red mask is 0x7C00; and a 5-6-5 16-bit image, /// where the blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800. /// /// /// /// /// 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 biClrUsed member of the BITMAPINFOHEADER. /// /// /// /// /// 32 /// /// The bitmap has a maximum of 2^32 colors. If the biCompression member of the /// BITMAPINFOHEADER 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, /// respectively, for a pixel. 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 biClrUsed member of the BITMAPINFOHEADER. /// /// If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, /// the bmiColors member contains three DWORD color masks that specify the red, green, /// and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents /// a single pixel. /// /// Windows NT/ 2000: When the biCompression 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. /// /// Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system /// supports only the following 32-bpp color mask: The blue mask is 0x000000FF, the green mask is /// 0x0000FF00, and the red mask is 0x00FF0000. /// /// /// /// public ushort biBitCount; /// /// Specifies the type of compression for a compressed bottom-up bitmap (top-down DIBs cannot be /// compressed). /// /// /// 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 2-byte format consisting of a count byte followed by a byte containing a color index. /// /// /// /// /// 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. /// /// /// /// BI_BITFIELDS /// 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_JPEG /// Windows 98/Me, Windows 2000/XP: Indicates that the image is a JPEG image. /// /// /// /// /// BI_PNG /// Windows 98/Me, Windows 2000/XP: Indicates that the image is a PNG image. /// /// /// /// /// public uint biCompression; /// /// Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps. /// /// Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, /// biSizeImage indicates the size of the JPEG or PNG image buffer, respectively. /// public uint biSizeImage; /// /// Specifies 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 biXPelsPerMeter; /// /// Specifies the vertical resolution, in pixels-per-meter, of the target device for the bitmap. /// public int biYPelsPerMeter; /// /// Specifies 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 biBitCount member for the compression mode specified by biCompression. /// /// If iClrUsed is nonzero and the biBitCount member is less than 16, the biClrUsed /// member specifies the actual number of colors the graphics engine or device driver accesses. /// If biBitCount is 16 or greater, the biClrUsed member specifies the size of the color /// table used to optimize performance of the system color palettes. If biBitCount equals 16 or 32, /// the optimal color palette starts immediately following the three DWORD masks. /// /// When the bitmap array immediately follows the structure, it is a packed bitmap. /// Packed bitmaps are referenced by a single pointer. Packed bitmaps require that the /// biClrUsed member must be either zero or the actual size of the color table. /// public uint biClrUsed; /// /// Specifies the number of color indexes that are required for displaying the bitmap. If this value /// is zero, all colors are required. /// public uint biClrImportant; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(BITMAPINFOHEADER left, BITMAPINFOHEADER right) { return ((left.biSize == right.biSize) && (left.biWidth == right.biWidth) && (left.biHeight == right.biHeight) && (left.biPlanes == right.biPlanes) && (left.biBitCount == right.biBitCount) && (left.biCompression == right.biCompression) && (left.biSizeImage == right.biSizeImage) && (left.biXPelsPerMeter == right.biXPelsPerMeter) && (left.biYPelsPerMeter == right.biYPelsPerMeter) && (left.biClrUsed == right.biClrUsed) && (left.biClrImportant == right.biClrImportant)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(BITMAPINFOHEADER left, BITMAPINFOHEADER right) { return !(left == right); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(BITMAPINFOHEADER other) { return (this == other); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is BITMAPINFOHEADER) && (this == (BITMAPINFOHEADER)obj)); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } } } namespace FreeImageAPI { /// /// 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 zeroes 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. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct BITMAPINFO : IEquatable { /// /// Specifies a structure that contains information /// about the dimensions of color format. /// public BITMAPINFOHEADER bmiHeader; /// /// The bmiColors member contains one of the following: /// /// /// /// /// An array of . 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 structure. /// /// The colors in the bmiColors table appear in order of importance. For more information, /// see the Remarks section. /// public RGBQUAD[] bmiColors; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(BITMAPINFO left, BITMAPINFO right) { if (left.bmiHeader != right.bmiHeader) { return false; } if ((left.bmiColors == null) && (right.bmiColors == null)) { return true; } if ((left.bmiColors == null) || (right.bmiColors == null)) { return false; } if (left.bmiColors.Length != right.bmiColors.Length) { return false; } for (int i = 0; i < left.bmiColors.Length; i++) { if (left.bmiColors[i] != right.bmiColors[i]) { return false; } } return true; } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(BITMAPINFO left, BITMAPINFO right) { return !(left == right); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(BITMAPINFO other) { return (this == other); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is BITMAPINFO) && (this == ((BITMAPINFO)obj))); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { int hash = bmiHeader.GetHashCode(); if (bmiColors != null) { for (int c = 0; c < bmiColors.Length; c++) { hash ^= bmiColors[c].GetHashCode(); hash <<= 1; } hash <<= 1; } else { hash >>= 1; } return hash; } } } namespace FreeImageAPI { /// /// The FIBITMAP structure is a handle to a FreeImage bimtap. /// /// /// The handle represented by a FIBITBAP structure provides /// access to either a singlepage bitmap or exactly one page of /// a multipage bitmap. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIBITMAP : IComparable, IComparable, IEquatable { private IntPtr data; /// /// A read-only field that represents a handle that has been initialized to zero. /// public static readonly FIBITMAP Zero; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIBITMAP left, FIBITMAP right) { return (left.data == right.data); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIBITMAP left, FIBITMAP right) { return (left.data != right.data); } /// /// Gets whether the handle is a null or not. /// /// true if this handle is a null; /// otherwise, false. public bool IsNull { get { return (data == IntPtr.Zero); } } /// /// Sets the handle to null. /// public void SetNull() { data = IntPtr.Zero; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return data.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return data.GetHashCode(); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return ((obj is FIBITMAP) && (this == ((FIBITMAP)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(FIBITMAP other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIBITMAP)) { throw new ArgumentException("obj"); } return CompareTo((FIBITMAP)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIBITMAP other) { return this.data.ToInt64().CompareTo(other.data.ToInt64()); } } } namespace FreeImageAPI { /// /// The FIMULTIBITMAP structure is a handle to a FreeImage multipaged bimtap. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIMULTIBITMAP : IComparable, IComparable, IEquatable { private IntPtr data; /// /// A read-only field that represents a handle that has been initialized to zero. /// public static readonly FIMULTIBITMAP Zero; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIMULTIBITMAP left, FIMULTIBITMAP right) { return (left.data == right.data); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIMULTIBITMAP left, FIMULTIBITMAP right) { return (left.data != right.data); } /// /// Gets whether the handle is a null or not. /// /// true if this handle is a null; /// otherwise, false. public bool IsNull { get { return (data == IntPtr.Zero); } } /// /// Sets the handle to null. /// public void SetNull() { data = IntPtr.Zero; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return data.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return data.GetHashCode(); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return ((obj is FIMULTIBITMAP) && (this == ((FIMULTIBITMAP)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(FIMULTIBITMAP other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIMULTIBITMAP)) { throw new ArgumentException("obj"); } return CompareTo((FIMULTIBITMAP)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIMULTIBITMAP other) { return this.data.ToInt64().CompareTo(other.data.ToInt64()); } } } namespace FreeImageAPI { /// /// The FIMEMORY structure is a handle to an opened memory stream. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIMEMORY : IComparable, IComparable, IEquatable { private IntPtr data; /// /// A read-only field that represents a handle that has been initialized to zero. /// public static readonly FIMEMORY Zero; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIMEMORY left, FIMEMORY right) { return (left.data == right.data); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIMEMORY left, FIMEMORY right) { return (left.data != right.data); } /// /// Gets whether the pointer is a null pointer or not. /// /// true if this is a null pointer; /// otherwise, false. public bool IsNull { get { return (data == IntPtr.Zero); } } /// /// Sets the handle to null. /// public void SetNull() { data = IntPtr.Zero; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return data.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return data.GetHashCode(); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return ((obj is FIMEMORY) && (this == ((FIMEMORY)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(FIMEMORY other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIMEMORY)) { throw new ArgumentException("obj"); } return CompareTo((FIMEMORY)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIMEMORY other) { return this.data.ToInt64().CompareTo(other.data.ToInt64()); } } } namespace FreeImageAPI { /// /// The FIMETADATA structure is an unique search handle for metadata search operations. /// /// /// The FIMETADATA structure is usually returned by the /// /// function and then used on subsequent calls to /// . /// When the FIMETADATA handle is no longer used, it needs to be freed by the /// function. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIMETADATA : IComparable, IComparable, IEquatable { private IntPtr data; /// /// A read-only field that represents a handle that has been initialized to zero. /// public static readonly FIMETADATA Zero; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIMETADATA left, FIMETADATA right) { return (left.data == right.data); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIMETADATA left, FIMETADATA right) { return (left.data != right.data); } /// /// Gets whether the pointer is a null pointer or not. /// /// true if this is a null pointer; /// otherwise, false. public bool IsNull { get { return (data == IntPtr.Zero); } } /// /// Sets the handle to null. /// public void SetNull() { data = IntPtr.Zero; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return data.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return data.GetHashCode(); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return ((obj is FIMETADATA) && (this == ((FIMETADATA)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(FIMETADATA other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIMETADATA)) { throw new ArgumentException("obj"); } return CompareTo((FIMETADATA)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIMETADATA other) { return this.data.ToInt64().CompareTo(other.data.ToInt64()); } } } namespace FreeImageAPI { /// /// The FITAG structure is a handle to a FreeImage metadata tag. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FITAG : IComparable, IComparable, IEquatable { private IntPtr data; /// /// A read-only field that represents a handle that has been initialized to zero. /// public static readonly FITAG Zero; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FITAG left, FITAG right) { return (left.data == right.data); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FITAG left, FITAG right) { return (left.data != right.data); } /// /// Gets whether the pointer is a null pointer or not. /// /// true if this is a null pointer; /// otherwise, false. public bool IsNull { get { return (data == IntPtr.Zero); } } /// /// Sets the handle to null. /// public void SetNull() { data = IntPtr.Zero; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return data.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return data.GetHashCode(); } /// /// Determines whether the specified is equal to the current . /// /// The to compare with the current . /// true if the specified is equal to the current ; otherwise, false. public override bool Equals(object obj) { return ((obj is FITAG) && (this == ((FITAG)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// true if the current object is equal to the other parameter; otherwise, false. public bool Equals(FITAG other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FITAG)) { throw new ArgumentException("obj"); } return CompareTo((FITAG)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FITAG other) { return this.data.ToInt64().CompareTo(other.data.ToInt64()); } } } namespace FreeImageAPI.IO { /// /// Structure for implementing access to custom handles. /// [StructLayout(LayoutKind.Sequential)] public struct FreeImageIO { /// /// Delegate to the C++ function fread. /// public ReadProc readProc; /// /// Delegate to the C++ function fwrite. /// public WriteProc writeProc; /// /// Delegate to the C++ function fseek. /// public SeekProc seekProc; /// /// Delegate to the C++ function ftell. /// public TellProc tellProc; } } namespace FreeImageAPI { /// /// The RGBQUAD structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 8 bits and so, takes values in the range from 0 to 255. /// /// /// /// The RGBQUAD structure provides access to an underlying Win32 RGBQUAD /// structure. To determine the alpha, red, green or blue component of a color, /// use the rgbReserved, rgbRed, rgbGreen or rgbBlue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the RGBQUAD structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the RGBQUAD structure and my be used in all situations which require /// an RGBQUAD type. /// /// /// Each color component rgbReserved, rgbRed, rgbGreen or rgbBlue of RGBQUAD /// is translated into it's corresponding color component A, R, G or B of /// by an one-to-one manner and vice versa. /// /// /// Conversion from System.Drawing.Color to RGBQUAD /// /// RGBQUAD.component = Color.component /// /// Conversion from RGBQUAD to System.Drawing.Color /// /// Color.component = RGBQUAD.component /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// RGBQUAD structure and the structure. /// /// RGBQUAD rgbq; /// // Initialize the structure using a native .NET Color structure. /// rgbq = new RGBQUAD(Color.Indigo); /// // Initialize the structure using the implicit operator. /// rgbq = Color.DarkSeaGreen; /// // Convert the RGBQUAD instance into a native .NET Color /// // using its implicit operator. /// Color color = rgbq; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = rgbq.Color; /// /// [Serializable, StructLayout(LayoutKind.Explicit)] public struct RGBQUAD : IComparable, IComparable, IEquatable { /// /// The blue color component. /// [FieldOffset(0)] public byte rgbBlue; /// /// The green color component. /// [FieldOffset(1)] public byte rgbGreen; /// /// The red color component. /// [FieldOffset(2)] public byte rgbRed; /// /// The alpha color component. /// [FieldOffset(3)] public byte rgbReserved; /// /// The color's value. /// [FieldOffset(0)] public uint uintValue; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public RGBQUAD(Color color) { uintValue = 0u; rgbBlue = color.B; rgbGreen = color.G; rgbRed = color.R; rgbReserved = color.A; } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(RGBQUAD left, RGBQUAD right) { return (left.uintValue == right.uintValue); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(RGBQUAD left, RGBQUAD right) { return (left.uintValue != right.uintValue); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator RGBQUAD(Color value) { return new RGBQUAD(value); } /// /// Converts the value of a structure to a Color structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(RGBQUAD value) { return value.Color; } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator RGBQUAD(uint value) { RGBQUAD result = new RGBQUAD(); result.uintValue = value; return result; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator uint(RGBQUAD value) { return value.uintValue; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( rgbReserved, rgbRed, rgbGreen, rgbBlue); } set { rgbRed = value.R; rgbGreen = value.G; rgbBlue = value.B; rgbReserved = value.A; } } /// /// Converts an array of into an array of /// . /// /// The array to convert. /// An array of . public static RGBQUAD[] ToRGBQUAD(Color[] array) { if (array == null) return null; RGBQUAD[] result = new RGBQUAD[array.Length]; for (int i = 0; i < array.Length; i++) { result[i] = array[i]; } return result; } /// /// Converts an array of into an array of /// . /// /// The array to convert. /// An array of . public static Color[] ToColor(RGBQUAD[] array) { if (array == null) return null; Color[] result = new Color[array.Length]; for (int i = 0; i < array.Length; i++) { result[i] = array[i].Color; } return result; } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is RGBQUAD)) { throw new ArgumentException("obj"); } return CompareTo((RGBQUAD)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(RGBQUAD other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is RGBQUAD) && (this == ((RGBQUAD)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(RGBQUAD other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The RGBTRIPLE structure describes a color consisting of relative /// intensities of red, green and blue value. Each single color component /// consumes 8 bits and so, takes values in the range from 0 to 255. /// /// /// /// The RGBTRIPLE structure provides access to an underlying Win32 RGBTRIPLE /// structure. To determine the red, green or blue component of a color, use the /// rgbtRed, rgbtGreen or rgbtBlue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the RGBTRIPLE structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the RGBTRIPLE structure and my be used in all situations which require /// an RGBTRIPLE type. /// /// /// Each of the color components rgbtRed, rgbtGreen or rgbtBlue of RGBTRIPLE is /// translated into it's corresponding color component R, G or B of /// by an one-to-one manner and vice versa. /// When converting from into RGBTRIPLE, the /// color's alpha value is ignored and assumed to be 255 when converting from /// RGBTRIPLE into , creating a fully /// opaque color. /// /// /// Conversion from System.Drawing.Color to RGBTRIPLE /// /// RGBTRIPLE.component = Color.component /// /// Conversion from RGBTRIPLE to System.Drawing.Color /// /// Color.component = RGBTRIPLE.component /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// RGBTRIPLE structure and the structure. /// /// RGBTRIPLE rgbt; /// // Initialize the structure using a native .NET Color structure. /// rgbt = new RGBTRIPLE(Color.Indigo); /// // Initialize the structure using the implicit operator. /// rgbt = Color.DarkSeaGreen; /// // Convert the RGBTRIPLE instance into a native .NET Color /// // using its implicit operator. /// Color color = rgbt; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = rgbt.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct RGBTRIPLE : IComparable, IComparable, IEquatable { /// /// The blue color component. /// public byte rgbtBlue; /// /// The green color component. /// public byte rgbtGreen; /// /// The red color component. /// public byte rgbtRed; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public RGBTRIPLE(Color color) { rgbtBlue = color.B; rgbtGreen = color.G; rgbtRed = color.R; } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(RGBTRIPLE left, RGBTRIPLE right) { return left.rgbtBlue == right.rgbtBlue && left.rgbtGreen == right.rgbtGreen && left.rgbtRed == right.rgbtRed; } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(RGBTRIPLE left, RGBTRIPLE right) { return !(left == right); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator RGBTRIPLE(Color value) { return new RGBTRIPLE(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(RGBTRIPLE value) { return value.Color; } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator RGBTRIPLE(uint value) { RGBTRIPLE result = new RGBTRIPLE(); result.rgbtBlue = (byte)(value & 0xFF); result.rgbtGreen = (byte)((value >> 8) & 0xFF); result.rgbtRed = (byte)((value >> 16) & 0xFF); return result; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator uint(RGBTRIPLE value) { return (uint)((value.rgbtRed << 16) | (value.rgbtGreen << 8) | (value.rgbtBlue)); } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( rgbtRed, rgbtGreen, rgbtBlue); } set { rgbtBlue = value.B; rgbtGreen = value.G; rgbtRed = value.R; } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is RGBTRIPLE)) { throw new ArgumentException("obj"); } return CompareTo((RGBTRIPLE)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(RGBTRIPLE other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is RGBTRIPLE) && (this == ((RGBTRIPLE)obj))); } /// /// Tests whether the specified structure is equivalent to this /// structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(RGBTRIPLE other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FIRGBA16 structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 16 bits and so, takes values in the range from 0 to 65535. /// /// /// /// The FIRGBA16 structure provides access to an underlying FreeImage FIRGBA16 /// structure. To determine the alpha, red, green or blue component of a color, /// use the alpha, red, green or blue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the FIRGBA16 structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FIRGBA16 structure and my be used in all situations which require /// an FIRGBA16 type. /// /// /// Each color component alpha, red, green or blue of FIRGBA16 /// is translated into it's corresponding color component A, R, G or B of /// by an 8 bit right shift and vice versa. /// /// /// Conversion from System.Drawing.Color to FIRGBA16 /// /// FIRGBA16.component = Color.component << 8 /// /// Conversion from FIRGBA16 to System.Drawing.Color /// /// Color.component = FIRGBA16.component >> 8 /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// FIRGBA16 structure and the structure. /// /// FIRGBA16 firgba16; /// // Initialize the structure using a native .NET Color structure. /// firgba16 = new FIRGBA16(Color.Indigo); /// // Initialize the structure using the implicit operator. /// firgba16 = Color.DarkSeaGreen; /// // Convert the FIRGBA16 instance into a native .NET Color /// // using its implicit operator. /// Color color = firgba16; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = firgba16.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIRGBA16 : IComparable, IComparable, IEquatable { /// /// The red color component. /// public ushort red; /// /// The green color component. /// public ushort green; /// /// The blue color component. /// public ushort blue; /// /// The alpha color component. /// public ushort alpha; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FIRGBA16(Color color) { red = (ushort)(color.R << 8); green = (ushort)(color.G << 8); blue = (ushort)(color.B << 8); alpha = (ushort)(color.A << 8); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIRGBA16 left, FIRGBA16 right) { return ((left.alpha == right.alpha) && (left.blue == right.blue) && (left.green == right.green) && (left.red == right.red)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIRGBA16 left, FIRGBA16 right) { return !(left == right); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRGBA16(Color value) { return new FIRGBA16(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FIRGBA16 value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb((alpha >> 8), (red >> 8), (green >> 8), (blue >> 8)); } set { red = (ushort)(value.R << 8); green = (ushort)(value.G << 8); blue = (ushort)(value.B << 8); alpha = (ushort)(value.A << 8); } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIRGBA16)) { throw new ArgumentException("obj"); } return CompareTo((FIRGBA16)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIRGBA16 other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIRGBA16) && (this == ((FIRGBA16)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIRGBA16 other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FIRGB16 structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 16 bits and so, takes values in the range from 0 to 65535. /// /// /// /// The FIRGB16 structure provides access to an underlying FreeImage FIRGB16 /// structure. To determine the red, green or blue component of a color, /// use the red, green or blue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the FIRGB16 structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FIRGB16 structure and my be used in all situations which require /// an FIRGB16 type. /// /// /// Each color component red, green or blue of FIRGB16 is translated into /// it's corresponding color component R, G or B of /// by right shifting 8 bits and shifting left 8 bits for the reverse conversion. /// When converting from into FIRGB16, the /// color's alpha value is ignored and assumed to be 255 when converting from /// FIRGB16 into , creating a fully /// opaque color. /// /// /// Conversion from System.Drawing.Color to FIRGB16 /// /// FIRGB16.component = Color.component << 8 /// /// Conversion from FIRGB16 to System.Drawing.Color /// /// Color.component = FIRGB16.component >> 8 /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// FIRGB16 structure and the structure. /// /// FIRGB16 firgb16; /// // Initialize the structure using a native .NET Color structure. /// firgb16 = new FIRGBA16(Color.Indigo); /// // Initialize the structure using the implicit operator. /// firgb16 = Color.DarkSeaGreen; /// // Convert the FIRGB16 instance into a native .NET Color /// // using its implicit operator. /// Color color = firgb16; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = firgb16.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIRGB16 : IComparable, IComparable, IEquatable { /// /// The red color component. /// public ushort red; /// /// The green color component. /// public ushort green; /// /// The blue color component. /// public ushort blue; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FIRGB16(Color color) { red = (ushort)(color.R << 8); green = (ushort)(color.G << 8); blue = (ushort)(color.B << 8); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIRGB16 left, FIRGB16 right) { return ((left.blue == right.blue) && (left.green == right.green) && (left.red == right.red)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIRGB16 left, FIRGB16 right) { return !(left == right); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRGB16(Color value) { return new FIRGB16(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FIRGB16 value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb((red >> 8), (green >> 8), (blue >> 8)); } set { red = (ushort)(value.R << 8); green = (ushort)(value.G << 8); blue = (ushort)(value.B << 8); } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIRGB16)) { throw new ArgumentException("obj"); } return CompareTo((FIRGB16)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIRGB16 other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIRGB16) && (this == ((FIRGB16)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIRGB16 other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FIRGBAF structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 32 bits and takes values in the range from 0 to 1. /// /// /// /// The FIRGBAF structure provides access to an underlying FreeImage FIRGBAF /// structure. To determine the alpha, red, green or blue component of a color, /// use the alpha, red, green or blue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the FIRGBAF structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FIRGBAF structure and my be used in all situations which require /// an FIRGBAF type. /// /// /// Each color component alpha, red, green or blue of FIRGBAF is translated /// into it's corresponding color component A, R, G or B of /// by linearly mapping the values of one range /// into the other range and vice versa. /// /// /// Conversion from System.Drawing.Color to FIRGBAF /// /// FIRGBAF.component = (float)Color.component / 255f /// /// Conversion from FIRGBAF to System.Drawing.Color /// /// Color.component = (int)(FIRGBAF.component * 255f) /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// FIRGBAF structure and the structure. /// /// FIRGBAF firgbaf; /// // Initialize the structure using a native .NET Color structure. /// firgbaf = new FIRGBAF(Color.Indigo); /// // Initialize the structure using the implicit operator. /// firgbaf = Color.DarkSeaGreen; /// // Convert the FIRGBAF instance into a native .NET Color /// // using its implicit operator. /// Color color = firgbaf; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = firgbaf.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIRGBAF : IComparable, IComparable, IEquatable { /// /// The red color component. /// public float red; /// /// The green color component. /// public float green; /// /// The blue color component. /// public float blue; /// /// The alpha color component. /// public float alpha; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FIRGBAF(Color color) { red = (float)color.R / 255f; green = (float)color.G / 255f; blue = (float)color.B / 255f; alpha = (float)color.A / 255f; } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIRGBAF left, FIRGBAF right) { return ((left.alpha == right.alpha) && (left.blue == right.blue) && (left.green == right.green) && (left.red == right.red)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIRGBAF left, FIRGBAF right) { return !(left == right); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRGBAF(Color value) { return new FIRGBAF(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FIRGBAF value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( (int)(alpha * 255f), (int)(red * 255f), (int)(green * 255f), (int)(blue * 255f)); } set { red = (float)value.R / 255f; green = (float)value.G / 255f; blue = (float)value.B / 255f; alpha = (float)value.A / 255f; } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIRGBAF)) { throw new ArgumentException("obj"); } return CompareTo((FIRGBAF)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIRGBAF other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIRGBAF) && (this == ((FIRGBAF)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIRGBAF other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FIRGBF structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 32 bits and takes values in the range from 0 to 1. /// /// /// /// The FIRGBF structure provides access to an underlying FreeImage FIRGBF /// structure. To determine the red, green or blue component of a color, use the /// red, green or blue fields, respectively. /// /// For easy integration of the underlying structure into the .NET framework, /// the FIRGBF structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FIRGBF structure and my be used in all situations which require /// an FIRGBF type. /// /// /// Each color component alpha, red, green or blue of FIRGBF is translated /// into it's corresponding color component A, R, G or B of /// by linearly mapping the values of one range /// into the other range and vice versa. /// When converting from into FIRGBF, the /// color's alpha value is ignored and assumed to be 255 when converting from /// FIRGBF into , creating a fully /// opaque color. /// /// /// Conversion from System.Drawing.Color to FIRGBF /// /// FIRGBF.component = (float)Color.component / 255f /// /// Conversion from FIRGBF to System.Drawing.Color /// /// Color.component = (int)(FIRGBF.component * 255f) /// /// The same conversion is also applied when the /// property or the constructor /// is invoked. /// /// /// /// The following code example demonstrates the various conversions between the /// FIRGBF structure and the structure. /// /// FIRGBF firgbf; /// // Initialize the structure using a native .NET Color structure. /// firgbf = new FIRGBF(Color.Indigo); /// // Initialize the structure using the implicit operator. /// firgbf = Color.DarkSeaGreen; /// // Convert the FIRGBF instance into a native .NET Color /// // using its implicit operator. /// Color color = firgbf; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = firgbf.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIRGBF : IComparable, IComparable, IEquatable { /// /// The red color component. /// public float red; /// /// The green color component. /// public float green; /// /// The blue color component. /// public float blue; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FIRGBF(Color color) { red = (float)color.R / 255f; green = (float)color.G / 255f; blue = (float)color.B / 255f; } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FIRGBF left, FIRGBF right) { return ((left.blue == right.blue) && (left.green == right.green) && (left.red == right.red)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FIRGBF left, FIRGBF right) { return !(left == right); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRGBF(Color value) { return new FIRGBF(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FIRGBF value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( (int)(red * 255f), (int)(green * 255f), (int)(blue * 255f)); } set { red = (float)value.R / 255f; green = (float)value.G / 255f; blue = (float)value.B / 255f; } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIRGBF)) { throw new ArgumentException("obj"); } return CompareTo((FIRGBF)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIRGBF other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIRGBF) && (this == ((FIRGBF)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIRGBF other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FICOMPLEX structure describes a color consisting of a real and an imaginary part. /// Each part is using 4 bytes of data. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FICOMPLEX : IComparable, IComparable, IEquatable { /// /// Real part of the color. /// public double real; /// /// Imaginary part of the color. /// public double imag; /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FICOMPLEX left, FICOMPLEX right) { return ((left.real == right.real) && (left.imag == right.imag)); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FICOMPLEX left, FICOMPLEX right) { return ((left.real != right.real) || (left.imag == right.imag)); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FICOMPLEX)) { throw new ArgumentException("obj"); } return CompareTo((FICOMPLEX)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FICOMPLEX other) { return base.GetHashCode(); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FICOMPLEX) && (this == ((FICOMPLEX)obj))); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FICOMPLEX other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } } } namespace FreeImageAPI { /// /// This Structure contains ICC-Profile data. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FIICCPROFILE { private ICC_FLAGS flags; private uint size; private IntPtr data; /// /// Creates a new ICC-Profile for . /// /// Handle to a FreeImage bitmap. /// The ICC-Profile data. /// /// is null. public FIICCPROFILE(FIBITMAP dib, byte[] data) : this(dib, data, (int)data.Length) { } /// /// Creates a new ICC-Profile for . /// /// Handle to a FreeImage bitmap. /// The ICC-Profile data. /// Number of bytes to use from data. /// /// is null. public unsafe FIICCPROFILE(FIBITMAP dib, byte[] data, int size) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } FIICCPROFILE prof; size = Math.Min(size, (int)data.Length); prof = *(FIICCPROFILE*)FreeImage.CreateICCProfile(dib, data, size); this.flags = prof.flags; this.size = prof.size; this.data = prof.data; } /// /// Info flag of the profile. /// public ICC_FLAGS Flags { get { return flags; } } /// /// Profile's size measured in bytes. /// public uint Size { get { return size; } } /// /// Points to a block of contiguous memory containing the profile. /// public IntPtr DataPointer { get { return data; } } /// /// Copy of the ICC-Profiles data. /// public unsafe byte[] Data { get { byte[] result; FreeImage.CopyMemory(result = new byte[size], data.ToPointer(), size); return result; } } /// /// Indicates whether the profile is CMYK. /// public bool IsCMYK { get { return ((flags & ICC_FLAGS.FIICC_COLOR_IS_CMYK) != 0); } } } } namespace FreeImageAPI.Plugins { /// /// The structure contains functionpointers that make up a FreeImage plugin. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct Plugin { /// /// Delegate to a function that returns a string which describes /// the plugins format. /// public FormatProc formatProc; /// /// Delegate to a function that returns a string which contains /// a more detailed description. /// public DescriptionProc descriptionProc; /// /// Delegate to a function that returns a comma seperated list /// of file extensions the plugin can read or write. /// public ExtensionListProc extensionListProc; /// /// Delegate to a function that returns a regular expression that /// can be used to idientify whether a file can be handled by the plugin. /// public RegExprProc regExprProc; /// /// Delegate to a function that opens a file. /// public OpenProc openProc; /// /// Delegate to a function that closes a previosly opened file. /// public CloseProc closeProc; /// /// Delegate to a function that returns the number of pages of a multipage /// bitmap if the plugin is capable of handling multipage bitmaps. /// public PageCountProc pageCountProc; /// /// UNKNOWN /// public PageCapabilityProc pageCapabilityProc; /// /// Delegate to a function that loads and decodes a bitmap into memory. /// public LoadProc loadProc; /// /// Delegate to a function that saves a bitmap. /// public SaveProc saveProc; /// /// Delegate to a function that determines whether the source is a valid image. /// public ValidateProc validateProc; /// /// Delegate to a function that returns a string which contains /// the plugin's mime type. /// public MimeProc mimeProc; /// /// Delegate to a function that returns whether the plugin can handle the /// specified color depth. /// public SupportsExportBPPProc supportsExportBPPProc; /// /// Delegate to a function that returns whether the plugin can handle the /// specified image type. /// public SupportsExportTypeProc supportsExportTypeProc; /// /// Delegate to a function that returns whether the plugin can handle /// ICC-Profiles. /// public SupportsICCProfilesProc supportsICCProfilesProc; } } #endregion #region Enums namespace FreeImageAPI.Metadata { /// /// Specifies how a single frame will be handled after being displayed. /// public enum DisposalMethodType : byte { /// /// Same behavior as but should not be used. /// Unspecified, /// /// The image is left in place and will be overdrawn by the next image. /// Leave, /// /// The area of the image will be blanked out by its background. /// Background, /// /// Restores the the area of the image to the state it was before it /// has been dawn. /// Previous, } } namespace FreeImageAPI { /// /// I/O image format identifiers. /// public enum FREE_IMAGE_FORMAT { /// /// Unknown format (returned value only, never use it as input value) /// FIF_UNKNOWN = -1, /// /// Windows or OS/2 Bitmap File (*.BMP) /// FIF_BMP = 0, /// /// Windows Icon (*.ICO) /// FIF_ICO = 1, /// /// Independent JPEG Group (*.JPG, *.JIF, *.JPEG, *.JPE) /// FIF_JPEG = 2, /// /// JPEG Network Graphics (*.JNG) /// FIF_JNG = 3, /// /// Commodore 64 Koala format (*.KOA) /// FIF_KOALA = 4, /// /// Amiga IFF (*.IFF, *.LBM) /// FIF_LBM = 5, /// /// Amiga IFF (*.IFF, *.LBM) /// FIF_IFF = 5, /// /// Multiple Network Graphics (*.MNG) /// FIF_MNG = 6, /// /// Portable Bitmap (ASCII) (*.PBM) /// FIF_PBM = 7, /// /// Portable Bitmap (BINARY) (*.PBM) /// FIF_PBMRAW = 8, /// /// Kodak PhotoCD (*.PCD) /// FIF_PCD = 9, /// /// Zsoft Paintbrush PCX bitmap format (*.PCX) /// FIF_PCX = 10, /// /// Portable Graymap (ASCII) (*.PGM) /// FIF_PGM = 11, /// /// Portable Graymap (BINARY) (*.PGM) /// FIF_PGMRAW = 12, /// /// Portable Network Graphics (*.PNG) /// FIF_PNG = 13, /// /// Portable Pixelmap (ASCII) (*.PPM) /// FIF_PPM = 14, /// /// Portable Pixelmap (BINARY) (*.PPM) /// FIF_PPMRAW = 15, /// /// Sun Rasterfile (*.RAS) /// FIF_RAS = 16, /// /// truevision Targa files (*.TGA, *.TARGA) /// FIF_TARGA = 17, /// /// Tagged Image File Format (*.TIF, *.TIFF) /// FIF_TIFF = 18, /// /// Wireless Bitmap (*.WBMP) /// FIF_WBMP = 19, /// /// Adobe Photoshop (*.PSD) /// FIF_PSD = 20, /// /// Dr. Halo (*.CUT) /// FIF_CUT = 21, /// /// X11 Bitmap Format (*.XBM) /// FIF_XBM = 22, /// /// X11 Pixmap Format (*.XPM) /// FIF_XPM = 23, /// /// DirectDraw Surface (*.DDS) /// FIF_DDS = 24, /// /// Graphics Interchange Format (*.GIF) /// FIF_GIF = 25, /// /// High Dynamic Range (*.HDR) /// FIF_HDR = 26, /// /// Raw Fax format CCITT G3 (*.G3) /// FIF_FAXG3 = 27, /// /// Silicon Graphics SGI image format (*.SGI) /// FIF_SGI = 28, /// /// OpenEXR format (*.EXR) /// FIF_EXR = 29, /// /// JPEG-2000 format (*.J2K, *.J2C) /// FIF_J2K = 30, /// /// JPEG-2000 format (*.JP2) /// FIF_JP2 = 31, /// /// Portable FloatMap (*.PFM) /// FIF_PFM = 32, /// /// Macintosh PICT (*.PICT) /// FIF_PICT = 33, /// /// RAW camera image (*.*) /// FIF_RAW = 34, } } namespace FreeImageAPI { /// /// Image types used in FreeImage. /// public enum FREE_IMAGE_TYPE { /// /// unknown type /// FIT_UNKNOWN = 0, /// /// standard image : 1-, 4-, 8-, 16-, 24-, 32-bit /// FIT_BITMAP = 1, /// /// array of unsigned short : unsigned 16-bit /// FIT_UINT16 = 2, /// /// array of short : signed 16-bit /// FIT_INT16 = 3, /// /// array of unsigned long : unsigned 32-bit /// FIT_UINT32 = 4, /// /// array of long : signed 32-bit /// FIT_INT32 = 5, /// /// array of float : 32-bit IEEE floating point /// FIT_FLOAT = 6, /// /// array of double : 64-bit IEEE floating point /// FIT_DOUBLE = 7, /// /// array of FICOMPLEX : 2 x 64-bit IEEE floating point /// FIT_COMPLEX = 8, /// /// 48-bit RGB image : 3 x 16-bit /// FIT_RGB16 = 9, /// /// 64-bit RGBA image : 4 x 16-bit /// FIT_RGBA16 = 10, /// /// 96-bit RGB float image : 3 x 32-bit IEEE floating point /// FIT_RGBF = 11, /// /// 128-bit RGBA float image : 4 x 32-bit IEEE floating point /// FIT_RGBAF = 12 } } namespace FreeImageAPI { /// /// Constants used in color filling routines. /// public enum FREE_IMAGE_COLOR_OPTIONS { /// /// Default value. /// FICO_DEFAULT = 0x0, /// /// color is RGB color (contains no valid alpha channel). /// FICO_RGB = 0x0, /// /// color is RGBA color (contains a valid alpha channel). /// FICO_RGBA = 0x1, /// /// Lookup nearest RGB color from palette. /// FICO_NEAREST_COLOR = 0x0, /// /// Lookup equal RGB color from palette. /// FICO_EQUAL_COLOR = 0x2, /// /// contains the palette index to be used. /// FICO_ALPHA_IS_INDEX = 0x4, } } namespace FreeImageAPI { /// /// Image color types used in FreeImage. /// public enum FREE_IMAGE_COLOR_TYPE { /// /// min value is white /// FIC_MINISWHITE = 0, /// /// min value is black /// FIC_MINISBLACK = 1, /// /// RGB color model /// FIC_RGB = 2, /// /// color map indexed /// FIC_PALETTE = 3, /// /// RGB color model with alpha channel /// FIC_RGBALPHA = 4, /// /// CMYK color model /// FIC_CMYK = 5 } } namespace FreeImageAPI { /// /// Color quantization algorithms. /// Constants used in FreeImage_ColorQuantize. /// public enum FREE_IMAGE_QUANTIZE { /// /// Xiaolin Wu color quantization algorithm /// FIQ_WUQUANT = 0, /// /// NeuQuant neural-net quantization algorithm by Anthony Dekker /// FIQ_NNQUANT = 1 } } namespace FreeImageAPI { /// /// Dithering algorithms. /// Constants used in FreeImage_Dither. /// public enum FREE_IMAGE_DITHER { /// /// Floyd and Steinberg error diffusion /// FID_FS = 0, /// /// Bayer ordered dispersed dot dithering (order 2 dithering matrix) /// FID_BAYER4x4 = 1, /// /// Bayer ordered dispersed dot dithering (order 3 dithering matrix) /// FID_BAYER8x8 = 2, /// /// Ordered clustered dot dithering (order 3 - 6x6 matrix) /// FID_CLUSTER6x6 = 3, /// /// Ordered clustered dot dithering (order 4 - 8x8 matrix) /// FID_CLUSTER8x8 = 4, /// /// Ordered clustered dot dithering (order 8 - 16x16 matrix) /// FID_CLUSTER16x16 = 5, /// /// Bayer ordered dispersed dot dithering (order 4 dithering matrix) /// FID_BAYER16x16 = 6 } } namespace FreeImageAPI { /// /// Lossless JPEG transformations constants used in FreeImage_JPEGTransform. /// public enum FREE_IMAGE_JPEG_OPERATION { /// /// no transformation /// FIJPEG_OP_NONE = 0, /// /// horizontal flip /// FIJPEG_OP_FLIP_H = 1, /// /// vertical flip /// FIJPEG_OP_FLIP_V = 2, /// /// transpose across UL-to-LR axis /// FIJPEG_OP_TRANSPOSE = 3, /// /// transpose across UR-to-LL axis /// FIJPEG_OP_TRANSVERSE = 4, /// /// 90-degree clockwise rotation /// FIJPEG_OP_ROTATE_90 = 5, /// /// 180-degree rotation /// FIJPEG_OP_ROTATE_180 = 6, /// /// 270-degree clockwise (or 90 ccw) /// FIJPEG_OP_ROTATE_270 = 7 } } namespace FreeImageAPI { /// /// Tone mapping operators. Constants used in FreeImage_ToneMapping. /// public enum FREE_IMAGE_TMO { /// /// Adaptive logarithmic mapping (F. Drago, 2003) /// FITMO_DRAGO03 = 0, /// /// Dynamic range reduction inspired by photoreceptor physiology (E. Reinhard, 2005) /// FITMO_REINHARD05 = 1, /// /// Gradient domain high dynamic range compression (R. Fattal, 2002) /// FITMO_FATTAL02 } } namespace FreeImageAPI { /// /// Upsampling / downsampling filters. Constants used in FreeImage_Rescale. /// public enum FREE_IMAGE_FILTER { /// /// Box, pulse, Fourier window, 1st order (constant) b-spline /// FILTER_BOX = 0, /// /// Mitchell and Netravali's two-param cubic filter /// FILTER_BICUBIC = 1, /// /// Bilinear filter /// FILTER_BILINEAR = 2, /// /// 4th order (cubic) b-spline /// FILTER_BSPLINE = 3, /// /// Catmull-Rom spline, Overhauser spline /// FILTER_CATMULLROM = 4, /// /// Lanczos3 filter /// FILTER_LANCZOS3 = 5 } } namespace FreeImageAPI { /// /// Color channels. Constants used in color manipulation routines. /// public enum FREE_IMAGE_COLOR_CHANNEL { /// /// Use red, green and blue channels /// FICC_RGB = 0, /// /// Use red channel /// FICC_RED = 1, /// /// Use green channel /// FICC_GREEN = 2, /// /// Use blue channel /// FICC_BLUE = 3, /// /// Use alpha channel /// FICC_ALPHA = 4, /// /// Use black channel /// FICC_BLACK = 5, /// /// Complex images: use real part /// FICC_REAL = 6, /// /// Complex images: use imaginary part /// FICC_IMAG = 7, /// /// Complex images: use magnitude /// FICC_MAG = 8, /// /// Complex images: use phase /// FICC_PHASE = 9 } } namespace FreeImageAPI { /// /// Tag data type information (based on TIFF specifications) /// Note: RATIONALs are the ratio of two 32-bit integer values. /// public enum FREE_IMAGE_MDTYPE { /// /// placeholder /// FIDT_NOTYPE = 0, /// /// 8-bit unsigned integer /// FIDT_BYTE = 1, /// /// 8-bit bytes w/ last byte null /// FIDT_ASCII = 2, /// /// 16-bit unsigned integer /// FIDT_SHORT = 3, /// /// 32-bit unsigned integer /// FIDT_LONG = 4, /// /// 64-bit unsigned fraction /// FIDT_RATIONAL = 5, /// /// 8-bit signed integer /// FIDT_SBYTE = 6, /// /// 8-bit untyped data /// FIDT_UNDEFINED = 7, /// /// 16-bit signed integer /// FIDT_SSHORT = 8, /// /// 32-bit signed integer /// FIDT_SLONG = 9, /// /// 64-bit signed fraction /// FIDT_SRATIONAL = 10, /// /// 32-bit IEEE floating point /// FIDT_FLOAT = 11, /// /// 64-bit IEEE floating point /// FIDT_DOUBLE = 12, /// /// 32-bit unsigned integer (offset) /// FIDT_IFD = 13, /// /// 32-bit RGBQUAD /// FIDT_PALETTE = 14 } } namespace FreeImageAPI { /// /// Metadata models supported by FreeImage. /// public enum FREE_IMAGE_MDMODEL { /// /// No data /// FIMD_NODATA = -1, /// /// single comment or keywords /// FIMD_COMMENTS = 0, /// /// Exif-TIFF metadata /// FIMD_EXIF_MAIN = 1, /// /// Exif-specific metadata /// FIMD_EXIF_EXIF = 2, /// /// Exif GPS metadata /// FIMD_EXIF_GPS = 3, /// /// Exif maker note metadata /// FIMD_EXIF_MAKERNOTE = 4, /// /// Exif interoperability metadata /// FIMD_EXIF_INTEROP = 5, /// /// IPTC/NAA metadata /// FIMD_IPTC = 6, /// /// Abobe XMP metadata /// FIMD_XMP = 7, /// /// GeoTIFF metadata /// FIMD_GEOTIFF = 8, /// /// Animation metadata /// FIMD_ANIMATION = 9, /// /// Used to attach other metadata types to a dib /// FIMD_CUSTOM = 10 } } namespace FreeImageAPI { /// /// Flags used in load functions. /// [System.Flags] public enum FREE_IMAGE_LOAD_FLAGS { /// /// Default option for all types. /// DEFAULT = 0, /// /// Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color. /// GIF_LOAD256 = 1, /// /// 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading. /// GIF_PLAYBACK = 2, /// /// Convert to 32bpp and create an alpha channel from the AND-mask when loading. /// ICO_MAKEALPHA = 1, /// /// Load the file as fast as possible, sacrificing some quality. /// JPEG_FAST = 0x0001, /// /// Load the file with the best quality, sacrificing some speed. /// JPEG_ACCURATE = 0x0002, /// /// Load separated CMYK "as is" (use | to combine with other load flags). /// JPEG_CMYK = 0x0004, /// /// Load and rotate according to Exif 'Orientation' tag if available. /// JPEG_EXIFROTATE = 0x0008, /// /// Load the bitmap sized 768 x 512. /// PCD_BASE = 1, /// /// Load the bitmap sized 384 x 256. /// PCD_BASEDIV4 = 2, /// /// Load the bitmap sized 192 x 128. /// PCD_BASEDIV16 = 3, /// /// Avoid gamma correction. /// PNG_IGNOREGAMMA = 1, /// /// If set the loader converts RGB555 and ARGB8888 -> RGB888. /// TARGA_LOAD_RGB888 = 1, /// /// Reads tags for separated CMYK. /// TIFF_CMYK = 0x0001, /// /// Tries to load the JPEG preview image, embedded in /// Exif Metadata or load the image as RGB 24-bit if no /// preview image is available. /// RAW_PREVIEW = 0x1, /// /// Loads the image as RGB 24-bit. /// RAW_DISPLAY = 0x2, } } namespace FreeImageAPI { /// /// Flags used in save functions. /// [System.Flags] public enum FREE_IMAGE_SAVE_FLAGS { /// /// Default option for all types. /// DEFAULT = 0, /// /// Save with run length encoding. /// BMP_SAVE_RLE = 1, /// /// Save data as float instead of as half (not recommended). /// EXR_FLOAT = 0x0001, /// /// Save with no compression. /// EXR_NONE = 0x0002, /// /// Save with zlib compression, in blocks of 16 scan lines. /// EXR_ZIP = 0x0004, /// /// Save with piz-based wavelet compression. /// EXR_PIZ = 0x0008, /// /// Save with lossy 24-bit float compression. /// EXR_PXR24 = 0x0010, /// /// Save with lossy 44% float compression - goes to 22% when combined with EXR_LC. /// EXR_B44 = 0x0020, /// /// Save images with one luminance and two chroma channels, rather than as RGB (lossy compression). /// EXR_LC = 0x0040, /// /// Save with superb quality (100:1). /// JPEG_QUALITYSUPERB = 0x80, /// /// Save with good quality (75:1). /// JPEG_QUALITYGOOD = 0x0100, /// /// Save with normal quality (50:1). /// JPEG_QUALITYNORMAL = 0x0200, /// /// Save with average quality (25:1). /// JPEG_QUALITYAVERAGE = 0x0400, /// /// Save with bad quality (10:1). /// JPEG_QUALITYBAD = 0x0800, /// /// Save as a progressive-JPEG (use | to combine with other save flags). /// JPEG_PROGRESSIVE = 0x2000, /// /// Save with high 4x1 chroma subsampling (4:1:1). /// JPEG_SUBSAMPLING_411 = 0x1000, /// /// Save with medium 2x2 medium chroma (4:2:0). /// JPEG_SUBSAMPLING_420 = 0x4000, /// /// Save with low 2x1 chroma subsampling (4:2:2). /// JPEG_SUBSAMPLING_422 = 0x8000, /// /// Save with no chroma subsampling (4:4:4). /// JPEG_SUBSAMPLING_444 = 0x10000, /// /// Save using ZLib level 1 compression flag /// (default value is ). /// PNG_Z_BEST_SPEED = 0x0001, /// /// Save using ZLib level 6 compression flag (default recommended value). /// PNG_Z_DEFAULT_COMPRESSION = 0x0006, /// /// save using ZLib level 9 compression flag /// (default value is ). /// PNG_Z_BEST_COMPRESSION = 0x0009, /// /// Save without ZLib compression. /// PNG_Z_NO_COMPRESSION = 0x0100, /// /// Save using Adam7 interlacing (use | to combine with other save flags). /// PNG_INTERLACED = 0x0200, /// /// If set the writer saves in ASCII format (i.e. P1, P2 or P3). /// PNM_SAVE_ASCII = 1, /// /// Stores tags for separated CMYK (use | to combine with compression flags). /// TIFF_CMYK = 0x0001, /// /// Save using PACKBITS compression. /// TIFF_PACKBITS = 0x0100, /// /// Save using DEFLATE compression (a.k.a. ZLIB compression). /// TIFF_DEFLATE = 0x0200, /// /// Save using ADOBE DEFLATE compression. /// TIFF_ADOBE_DEFLATE = 0x0400, /// /// Save without any compression. /// TIFF_NONE = 0x0800, /// /// Save using CCITT Group 3 fax encoding. /// TIFF_CCITTFAX3 = 0x1000, /// /// Save using CCITT Group 4 fax encoding. /// TIFF_CCITTFAX4 = 0x2000, /// /// Save using LZW compression. /// TIFF_LZW = 0x4000, /// /// Save using JPEG compression. /// TIFF_JPEG = 0x8000 } } namespace FreeImageAPI { /// /// Flags for ICC profiles. /// [System.Flags] public enum ICC_FLAGS : ushort { /// /// Default value. /// FIICC_DEFAULT = 0x00, /// /// The color is CMYK. /// FIICC_COLOR_IS_CMYK = 0x01 } } #endregion #region Delegates namespace FreeImageAPI { // Delegates used by the FreeImageIO structure /// /// Delegate for capturing FreeImage error messages. /// /// The format of the image. /// The errormessage. // DLL_API is missing in the definition of the callbackfuntion. [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Ansi, ThrowOnUnmappableChar = false)] public delegate void OutputMessageFunction(FREE_IMAGE_FORMAT fif, string message); } namespace FreeImageAPI.IO { /// /// Delegate to the C++ function fread. /// /// Pointer to read from. /// Item size in bytes. /// Maximum number of items to be read. /// Handle/stream to read from. /// Number of full items actually read, /// which may be less than count if an error occurs or /// if the end of the file is encountered before reaching count. public delegate uint ReadProc(IntPtr buffer, uint size, uint count, fi_handle handle); /// /// Delegate to the C++ function fwrite. /// /// Pointer to data to be written. /// Item size in bytes. /// Maximum number of items to be written. /// Handle/stream to write to. /// Number of full items actually written, /// which may be less than count if an error occurs. /// Also, if an error occurs, the file-position indicator cannot be determined. public delegate uint WriteProc(IntPtr buffer, uint size, uint count, fi_handle handle); /// /// Delegate to the C++ function fseek. /// /// Handle/stream to seek in. /// Number of bytes from origin. /// Initial position. /// If successful 0 is returned; otherwise a nonzero value. public delegate int SeekProc(fi_handle handle, int offset, SeekOrigin origin); /// /// Delegate to the C++ function ftell. /// /// Handle/stream to retrieve its currents position from. /// The current position. public delegate int TellProc(fi_handle handle); // Delegates used by 'Plugin' structure } namespace FreeImageAPI.Plugins { /// /// Delegate to a function that returns a string which describes /// the plugins format. /// public delegate string FormatProc(); /// /// Delegate to a function that returns a string which contains /// a more detailed description. /// public delegate string DescriptionProc(); /// /// Delegate to a function that returns a comma seperated list /// of file extensions the plugin can read or write. /// public delegate string ExtensionListProc(); /// /// Delegate to a function that returns a regular expression that /// can be used to idientify whether a file can be handled by the plugin. /// public delegate string RegExprProc(); /// /// Delegate to a function that opens a file. /// public delegate IntPtr OpenProc(ref FreeImageIO io, fi_handle handle, bool read); /// /// Delegate to a function that closes a previosly opened file. /// public delegate void CloseProc(ref FreeImageIO io, fi_handle handle, IntPtr data); /// /// Delegate to a function that returns the number of pages of a multipage /// bitmap if the plugin is capable of handling multipage bitmaps. /// public delegate int PageCountProc(ref FreeImageIO io, fi_handle handle, IntPtr data); /// /// UNKNOWN /// public delegate int PageCapabilityProc(ref FreeImageIO io, fi_handle handle, IntPtr data); /// /// Delegate to a function that loads and decodes a bitmap into memory. /// public delegate FIBITMAP LoadProc(ref FreeImageIO io, fi_handle handle, int page, int flags, IntPtr data); /// /// Delegate to a function that saves a bitmap. /// public delegate bool SaveProc(ref FreeImageIO io, FIBITMAP dib, fi_handle handle, int page, int flags, IntPtr data); /// /// Delegate to a function that determines whether the source defined /// by and is a valid image. /// public delegate bool ValidateProc(ref FreeImageIO io, fi_handle handle); /// /// Delegate to a function that returns a string which contains /// the plugin's mime type. /// public delegate string MimeProc(); /// /// Delegate to a function that returns whether the plugin can handle the /// specified color depth. /// public delegate bool SupportsExportBPPProc(int bpp); /// /// Delegate to a function that returns whether the plugin can handle the /// specified image type. /// public delegate bool SupportsExportTypeProc(FREE_IMAGE_TYPE type); /// /// Delegate to a function that returns whether the plugin can handle /// ICC-Profiles. /// public delegate bool SupportsICCProfilesProc(); /// /// Callback function used by FreeImage to register plugins. /// public delegate void InitProc(ref Plugin plugin, int format_id); } #endregion namespace FreeImageAPI { public static partial class FreeImage { #region Constants /// /// Filename of the FreeImage library. /// private const string FreeImageLibrary = "FreeImage"; /// /// Number of bytes to shift left within a 4 byte block. /// public const int FI_RGBA_RED = 2; /// /// Number of bytes to shift left within a 4 byte block. /// public const int FI_RGBA_GREEN = 1; /// /// Number of bytes to shift left within a 4 byte block. /// public const int FI_RGBA_BLUE = 0; /// /// Number of bytes to shift left within a 4 byte block. /// public const int FI_RGBA_ALPHA = 3; /// /// Mask indicating the position of the given color. /// public const uint FI_RGBA_RED_MASK = 0x00FF0000; /// /// Mask indicating the position of the given color. /// public const uint FI_RGBA_GREEN_MASK = 0x0000FF00; /// /// Mask indicating the position of the given color. /// public const uint FI_RGBA_BLUE_MASK = 0x000000FF; /// /// Mask indicating the position of the given color. /// public const uint FI_RGBA_ALPHA_MASK = 0xFF000000; /// /// Number of bits to shift left within a 32 bit block. /// public const int FI_RGBA_RED_SHIFT = 16; /// /// Number of bits to shift left within a 32 bit block. /// public const int FI_RGBA_GREEN_SHIFT = 8; /// /// Number of bits to shift left within a 32 bit block. /// public const int FI_RGBA_BLUE_SHIFT = 0; /// /// Number of bits to shift left within a 32 bit block. /// public const int FI_RGBA_ALPHA_SHIFT = 24; /// /// Mask indicating the position of color components of a 32 bit color. /// public const uint FI_RGBA_RGB_MASK = (FI_RGBA_RED_MASK | FI_RGBA_GREEN_MASK | FI_RGBA_BLUE_MASK); /// /// Mask indicating the position of the given color. /// public const int FI16_555_RED_MASK = 0x7C00; /// /// Mask indicating the position of the given color. /// public const int FI16_555_GREEN_MASK = 0x03E0; /// /// Mask indicating the position of the given color. /// public const int FI16_555_BLUE_MASK = 0x001F; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_555_RED_SHIFT = 10; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_555_GREEN_SHIFT = 5; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_555_BLUE_SHIFT = 0; /// /// Mask indicating the position of the given color. /// public const int FI16_565_RED_MASK = 0xF800; /// /// Mask indicating the position of the given color. /// public const int FI16_565_GREEN_MASK = 0x07E0; /// /// Mask indicating the position of the given color. /// public const int FI16_565_BLUE_MASK = 0x001F; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_565_RED_SHIFT = 11; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_565_GREEN_SHIFT = 5; /// /// Number of bits to shift left within a 16 bit block. /// public const int FI16_565_BLUE_SHIFT = 0; #endregion #region General functions /// /// Initialises the library. /// /// /// When the is true, FreeImage won't make use of external plugins. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Initialise")] private static extern void Initialise(bool load_local_plugins_only); /// /// Deinitialises the library. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_DeInitialise")] private static extern void DeInitialise(); /// /// Returns a string containing the current version of the library. /// /// The current version of the library. public static unsafe string GetVersion() { return PtrToStr(GetVersion_()); } [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetVersion")] private static unsafe extern byte* GetVersion_(); /// /// Returns a string containing a standard copyright message. /// /// A standard copyright message. public static unsafe string GetCopyrightMessage() { return PtrToStr(GetCopyrightMessage_()); } [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetCopyrightMessage")] private static unsafe extern byte* GetCopyrightMessage_(); /// /// Calls the set error message function in FreeImage. /// /// Format of the bitmaps. /// The error message. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_OutputMessageProc")] public static extern void OutputMessageProc(FREE_IMAGE_FORMAT fif, string message); /// /// You use the function FreeImage_SetOutputMessage to capture the log string /// so that you can show it to the user of the program. /// The callback is implemented in the event of this class. /// /// The function is private because FreeImage can only have a single /// callback function. To use the callback use the /// event of this class. /// Handler to the callback function. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetOutputMessage")] internal static extern void SetOutputMessage(OutputMessageFunction omf); #endregion #region Bitmap management functions /// /// Creates a new bitmap in memory. /// /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new Bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// Red part of the color layout. /// eg: 0xFF0000 /// Green part of the color layout. /// eg: 0x00FF00 /// Blue part of the color layout. /// eg: 0x0000FF /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Allocate")] public static extern FIBITMAP Allocate(int width, int height, int bpp, uint red_mask, uint green_mask, uint blue_mask); /// /// Creates a new bitmap in memory. /// /// Type of the image. /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new Bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// Red part of the color layout. /// eg: 0xFF0000 /// Green part of the color layout. /// eg: 0x00FF00 /// Blue part of the color layout. /// eg: 0x0000FF /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AllocateT")] public static extern FIBITMAP AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp, uint red_mask, uint green_mask, uint blue_mask); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AllocateEx")] internal static extern FIBITMAP AllocateEx(int width, int height, int bpp, IntPtr color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette, uint red_mask, uint green_mask, uint blue_mask); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AllocateExT")] internal static extern FIBITMAP AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, IntPtr color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette, uint red_mask, uint green_mask, uint blue_mask); /// /// Makes an exact reproduction of an existing bitmap, including metadata and attached profile if any. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Clone")] public static extern FIBITMAP Clone(FIBITMAP dib); /// /// Deletes a previously loaded FIBITMAP from memory. /// /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Unload")] public static extern void Unload(FIBITMAP dib); /// /// Decodes a bitmap, allocates memory for it and returns it as a FIBITMAP. /// /// Type of the bitmap. /// Name of the file to decode. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_LoadU")] public static extern FIBITMAP Load(FREE_IMAGE_FORMAT fif, string filename, FREE_IMAGE_LOAD_FLAGS flags); /// /// Decodes a bitmap, allocates memory for it and returns it as a FIBITMAP. /// The filename supports UNICODE. /// /// Type of the bitmap. /// Name of the file to decode. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_LoadU")] private static extern FIBITMAP LoadU(FREE_IMAGE_FORMAT fif, string filename, FREE_IMAGE_LOAD_FLAGS flags); /// /// Loads a bitmap from an arbitrary source. /// /// Type of the bitmap. /// A FreeImageIO structure with functionpointers to handle the source. /// A handle to the source. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_LoadFromHandle")] public static extern FIBITMAP LoadFromHandle(FREE_IMAGE_FORMAT fif, ref FreeImageIO io, fi_handle handle, FREE_IMAGE_LOAD_FLAGS flags); /// /// Saves a previosly loaded FIBITMAP to a file. /// /// Type of the bitmap. /// Handle to a FreeImage bitmap. /// Name of the file to save to. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_SaveU")] public static extern bool Save(FREE_IMAGE_FORMAT fif, FIBITMAP dib, string filename, FREE_IMAGE_SAVE_FLAGS flags); /// /// Saves a previosly loaded FIBITMAP to a file. /// The filename supports UNICODE. /// /// Type of the bitmap. /// Handle to a FreeImage bitmap. /// Name of the file to save to. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_SaveU")] private static extern bool SaveU(FREE_IMAGE_FORMAT fif, FIBITMAP dib, string filename, FREE_IMAGE_SAVE_FLAGS flags); /// /// Saves a bitmap to an arbitrary source. /// /// Type of the bitmap. /// Handle to a FreeImage bitmap. /// A FreeImageIO structure with functionpointers to handle the source. /// A handle to the source. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SaveToHandle")] public static extern bool SaveToHandle(FREE_IMAGE_FORMAT fif, FIBITMAP dib, ref FreeImageIO io, fi_handle handle, FREE_IMAGE_SAVE_FLAGS flags); #endregion #region Memory I/O streams /// /// Open a memory stream. /// /// Pointer to the data in memory. /// Length of the data in byte. /// Handle to a memory stream. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_OpenMemory")] public static extern FIMEMORY OpenMemory(IntPtr data, uint size_in_bytes); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_OpenMemory")] internal static extern FIMEMORY OpenMemoryEx(byte[] data, uint size_in_bytes); /// /// Close and free a memory stream. /// /// Handle to a memory stream. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CloseMemory")] public static extern void CloseMemory(FIMEMORY stream); /// /// Decodes a bitmap from a stream, allocates memory for it and returns it as a FIBITMAP. /// /// Type of the bitmap. /// Handle to a memory stream. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_LoadFromMemory")] public static extern FIBITMAP LoadFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY stream, FREE_IMAGE_LOAD_FLAGS flags); /// /// Saves a previosly loaded FIBITMAP to a stream. /// /// Type of the bitmap. /// Handle to a FreeImage bitmap. /// Handle to a memory stream. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SaveToMemory")] public static extern bool SaveToMemory(FREE_IMAGE_FORMAT fif, FIBITMAP dib, FIMEMORY stream, FREE_IMAGE_SAVE_FLAGS flags); /// /// Gets the current position of a memory handle. /// /// Handle to a memory stream. /// The current file position if successful, -1 otherwise. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_TellMemory")] public static extern int TellMemory(FIMEMORY stream); /// /// Moves the memory handle to a specified location. /// /// Handle to a memory stream. /// Number of bytes from origin. /// Initial position. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SeekMemory")] public static extern bool SeekMemory(FIMEMORY stream, int offset, System.IO.SeekOrigin origin); /// /// Provides a direct buffer access to a memory stream. /// /// The target memory stream. /// Pointer to the data in memory. /// Size of the data in bytes. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AcquireMemory")] public static extern bool AcquireMemory(FIMEMORY stream, ref IntPtr data, ref uint size_in_bytes); /// /// Reads data from a memory stream. /// /// The buffer to store the data in. /// Size in bytes of the items. /// Number of items to read. /// The stream to read from. /// The memory pointer associated with stream is increased by the number of bytes actually read. /// The number of full items actually read. /// May be less than count on error or stream-end. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ReadMemory")] public static extern uint ReadMemory(byte[] buffer, uint size, uint count, FIMEMORY stream); /// /// Writes data to a memory stream. /// /// The buffer to read the data from. /// Size in bytes of the items. /// Number of items to write. /// The stream to write to. /// The memory pointer associated with stream is increased by the number of bytes actually written. /// The number of full items actually written. /// May be less than count on error or stream-end. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_WriteMemory")] public static extern uint WriteMemory(byte[] buffer, uint size, uint count, FIMEMORY stream); /// /// Open a multi-page bitmap from a memory stream. /// /// Type of the bitmap. /// The stream to decode. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage multi-paged bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_LoadMultiBitmapFromMemory")] public static extern FIMULTIBITMAP LoadMultiBitmapFromMemory(FREE_IMAGE_FORMAT fif, FIMEMORY stream, FREE_IMAGE_LOAD_FLAGS flags); #endregion #region Plugin functions /// /// Registers a new plugin to be used in FreeImage. /// /// Pointer to the function that initialises the plugin. /// A string describing the format of the plugin. /// A string describing the plugin. /// A string witha comma sperated list of extensions. f.e: "pl,pl2,pl4" /// A regular expression used to identify the bitmap. /// The format idientifier assigned by FreeImage. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_RegisterLocalPlugin")] public static extern FREE_IMAGE_FORMAT RegisterLocalPlugin(InitProc proc_address, string format, string description, string extension, string regexpr); /// /// Registers a new plugin to be used in FreeImage. The plugin is residing in a DLL. /// The Init function must be called �Init� and must use the stdcall calling convention. /// /// Complete path to the dll file hosting the plugin. /// A string describing the format of the plugin. /// A string describing the plugin. /// A string witha comma sperated list of extensions. f.e: "pl,pl2,pl4" /// A regular expression used to identify the bitmap. /// The format idientifier assigned by FreeImage. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_RegisterExternalPlugin")] public static extern FREE_IMAGE_FORMAT RegisterExternalPlugin(string path, string format, string description, string extension, string regexpr); /// /// Retrieves the number of FREE_IMAGE_FORMAT identifiers being currently registered. /// /// The number of registered formats. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFIFCount")] public static extern int GetFIFCount(); /// /// Enables or disables a plugin. /// /// The plugin to enable or disable. /// True: enable the plugin. false: disable the plugin. /// The previous state of the plugin. /// 1 - enabled. 0 - disables. -1 plugin does not exist. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetPluginEnabled")] public static extern int SetPluginEnabled(FREE_IMAGE_FORMAT fif, bool enable); /// /// Retrieves the state of a plugin. /// /// The plugin to check. /// 1 - enabled. 0 - disables. -1 plugin does not exist. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_IsPluginEnabled")] public static extern int IsPluginEnabled(FREE_IMAGE_FORMAT fif); /// /// Returns a identifier from the format string that was used to register the FIF. /// /// The string that was used to register the plugin. /// A identifier from the format. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetFIFFromFormat")] public static extern FREE_IMAGE_FORMAT GetFIFFromFormat(string format); /// /// Returns a identifier from a MIME content type string /// (MIME stands for Multipurpose Internet Mail Extension). /// /// A MIME content type. /// A identifier from the MIME. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetFIFFromMime")] public static extern FREE_IMAGE_FORMAT GetFIFFromMime(string mime); /// /// Returns the string that was used to register a plugin from the system assigned . /// /// The assigned . /// The string that was used to register the plugin. public static unsafe string GetFormatFromFIF(FREE_IMAGE_FORMAT fif) { return PtrToStr(GetFormatFromFIF_(fif)); } [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFormatFromFIF")] private static unsafe extern byte* GetFormatFromFIF_(FREE_IMAGE_FORMAT fif); /// /// Returns a comma-delimited file extension list describing the bitmap formats the given plugin can read and/or write. /// /// The desired . /// A comma-delimited file extension list. public static unsafe string GetFIFExtensionList(FREE_IMAGE_FORMAT fif) { return PtrToStr(GetFIFExtensionList_(fif)); } [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFIFExtensionList")] private static unsafe extern byte* GetFIFExtensionList_(FREE_IMAGE_FORMAT fif); /// /// Returns a descriptive string that describes the bitmap formats the given plugin can read and/or write. /// /// The desired . /// A descriptive string that describes the bitmap formats. public static unsafe string GetFIFDescription(FREE_IMAGE_FORMAT fif) { return PtrToStr(GetFIFDescription_(fif)); } [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFIFDescription")] private static unsafe extern byte* GetFIFDescription_(FREE_IMAGE_FORMAT fif); /// /// Returns a regular expression string that can be used by a regular expression engine to identify the bitmap. /// FreeImageQt makes use of this function. /// /// The desired . /// A regular expression string. public static unsafe string GetFIFRegExpr(FREE_IMAGE_FORMAT fif) { return PtrToStr(GetFIFRegExpr_(fif)); } [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFIFRegExpr")] private static unsafe extern byte* GetFIFRegExpr_(FREE_IMAGE_FORMAT fif); /// /// Given a identifier, returns a MIME content type string (MIME stands for Multipurpose Internet Mail Extension). /// /// The desired . /// A MIME content type string. public static unsafe string GetFIFMimeType(FREE_IMAGE_FORMAT fif) { return PtrToStr(GetFIFMimeType_(fif)); } [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFIFMimeType")] private static unsafe extern byte* GetFIFMimeType_(FREE_IMAGE_FORMAT fif); /// /// This function takes a filename or a file-extension and returns the plugin that can /// read/write files with that extension in the form of a identifier. /// /// The filename or -extension. /// The of the plugin. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_GetFIFFromFilenameU")] public static extern FREE_IMAGE_FORMAT GetFIFFromFilename(string filename); /// /// This function takes a filename or a file-extension and returns the plugin that can /// read/write files with that extension in the form of a identifier. /// Supports UNICODE filenames. /// /// The filename or -extension. /// The of the plugin. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_GetFIFFromFilenameU")] private static extern FREE_IMAGE_FORMAT GetFIFFromFilenameU(string filename); /// /// Checks if a plugin can load bitmaps. /// /// The of the plugin. /// True if the plugin can load bitmaps, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FIFSupportsReading")] public static extern bool FIFSupportsReading(FREE_IMAGE_FORMAT fif); /// /// Checks if a plugin can save bitmaps. /// /// The of the plugin. /// True if the plugin can save bitmaps, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FIFSupportsWriting")] public static extern bool FIFSupportsWriting(FREE_IMAGE_FORMAT fif); /// /// Checks if a plugin can save bitmaps in the desired bit depth. /// /// The of the plugin. /// The desired bit depth. /// True if the plugin can save bitmaps in the desired bit depth, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FIFSupportsExportBPP")] public static extern bool FIFSupportsExportBPP(FREE_IMAGE_FORMAT fif, int bpp); /// /// Checks if a plugin can save a bitmap in the desired data type. /// /// The of the plugin. /// The desired image type. /// True if the plugin can save bitmaps as the desired type, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FIFSupportsExportType")] public static extern bool FIFSupportsExportType(FREE_IMAGE_FORMAT fif, FREE_IMAGE_TYPE type); /// /// Checks if a plugin can load or save an ICC profile. /// /// The of the plugin. /// True if the plugin can load or save an ICC profile, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FIFSupportsICCProfiles")] public static extern bool FIFSupportsICCProfiles(FREE_IMAGE_FORMAT fif); #endregion #region Multipage functions /// /// Loads a FreeImage multi-paged bitmap. /// Load flags can be provided by the flags parameter. /// /// Format of the image. /// The complete name of the file to load. /// When true a new bitmap is created. /// When true the bitmap will be loaded read only. /// When true performance is increased at the cost of memory. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage multi-paged bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_OpenMultiBitmap")] public static extern FIMULTIBITMAP OpenMultiBitmap(FREE_IMAGE_FORMAT fif, string filename, bool create_new, bool read_only, bool keep_cache_in_memory, FREE_IMAGE_LOAD_FLAGS flags); /// /// Loads a FreeImage multi-pages bitmap from the specified handle /// using the specified functions. /// Load flags can be provided by the flags parameter. /// /// Format of the image. /// IO functions used to read from the specified handle. /// The handle to load the bitmap from. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage multi-paged bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_OpenMultiBitmapFromHandle")] public static extern FIMULTIBITMAP OpenMultiBitmapFromHandle(FREE_IMAGE_FORMAT fif, ref FreeImageIO io, fi_handle handle, FREE_IMAGE_LOAD_FLAGS flags); /// /// Closes a previously opened multi-page bitmap and, when the bitmap was not opened read-only, applies any changes made to it. /// /// Handle to a FreeImage multi-paged bitmap. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CloseMultiBitmap")] private static extern bool CloseMultiBitmap_(FIMULTIBITMAP bitmap, FREE_IMAGE_SAVE_FLAGS flags); /// /// Returns the number of pages currently available in the multi-paged bitmap. /// /// Handle to a FreeImage multi-paged bitmap. /// Number of pages. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetPageCount")] public static extern int GetPageCount(FIMULTIBITMAP bitmap); /// /// Appends a new page to the end of the bitmap. /// /// Handle to a FreeImage multi-paged bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AppendPage")] public static extern void AppendPage(FIMULTIBITMAP bitmap, FIBITMAP data); /// /// Inserts a new page before the given position in the bitmap. /// /// Handle to a FreeImage multi-paged bitmap. /// Page has to be a number smaller than the current number of pages available in the bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_InsertPage")] public static extern void InsertPage(FIMULTIBITMAP bitmap, int page, FIBITMAP data); /// /// Deletes the page on the given position. /// /// Handle to a FreeImage multi-paged bitmap. /// Number of the page to delete. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_DeletePage")] public static extern void DeletePage(FIMULTIBITMAP bitmap, int page); /// /// Locks a page in memory for editing. /// /// Handle to a FreeImage multi-paged bitmap. /// Number of the page to lock. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_LockPage")] public static extern FIBITMAP LockPage(FIMULTIBITMAP bitmap, int page); /// /// Unlocks a previously locked page and gives it back to the multi-page engine. /// /// Handle to a FreeImage multi-paged bitmap. /// Handle to a FreeImage bitmap. /// If true, the page is applied to the multi-page bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_UnlockPage")] public static extern void UnlockPage(FIMULTIBITMAP bitmap, FIBITMAP data, bool changed); /// /// Moves the source page to the position of the target page. /// /// Handle to a FreeImage multi-paged bitmap. /// New position of the page. /// Old position of the page. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_MovePage")] public static extern bool MovePage(FIMULTIBITMAP bitmap, int target, int source); /// /// Returns an array of page-numbers that are currently locked in memory. /// When the pages parameter is null, the size of the array is returned in the count variable. /// /// /// /// int[] lockedPages = null; /// int count = 0; /// GetLockedPageNumbers(dib, lockedPages, ref count); /// lockedPages = new int[count]; /// GetLockedPageNumbers(dib, lockedPages, ref count); /// /// /// Handle to a FreeImage multi-paged bitmap. /// The list of locked pages in the multi-pages bitmap. /// If set to null, count will contain the number of pages. /// If is set to null count will contain the number of locked pages. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetLockedPageNumbers")] public static extern bool GetLockedPageNumbers(FIMULTIBITMAP bitmap, int[] pages, ref int count); #endregion #region Filetype functions /// /// Orders FreeImage to analyze the bitmap signature. /// /// Name of the file to analyze. /// Reserved parameter - use 0. /// Type of the bitmap. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_GetFileTypeU")] public static extern FREE_IMAGE_FORMAT GetFileType(string filename, int size); /// /// Orders FreeImage to analyze the bitmap signature. /// Supports UNICODE filenames. /// /// Name of the file to analyze. /// Reserved parameter - use 0. /// Type of the bitmap. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_GetFileTypeU")] private static extern FREE_IMAGE_FORMAT GetFileTypeU(string filename, int size); /// /// Uses the structure as described in the topic bitmap management functions /// to identify a bitmap type. /// /// A structure with functionpointers to handle the source. /// A handle to the source. /// Size in bytes of the source. /// Type of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFileTypeFromHandle")] public static extern FREE_IMAGE_FORMAT GetFileTypeFromHandle(ref FreeImageIO io, fi_handle handle, int size); /// /// Uses a memory handle to identify a bitmap type. /// /// Pointer to the stream. /// Size in bytes of the source. /// Type of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetFileTypeFromMemory")] public static extern FREE_IMAGE_FORMAT GetFileTypeFromMemory(FIMEMORY stream, int size); #endregion #region Helper functions /// /// Returns whether the platform is using Little Endian. /// /// Returns true if the platform is using Litte Endian, else false. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_IsLittleEndian")] public static extern bool IsLittleEndian(); /// /// Converts a X11 color name into a corresponding RGB value. /// /// Name of the color to convert. /// Red component. /// Green component. /// Blue component. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_LookupX11Color")] public static extern bool LookupX11Color(string szColor, out byte nRed, out byte nGreen, out byte nBlue); /// /// Converts a SVG color name into a corresponding RGB value. /// /// Name of the color to convert. /// Red component. /// Green component. /// Blue component. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_LookupSVGColor")] public static extern bool LookupSVGColor(string szColor, out byte nRed, out byte nGreen, out byte nBlue); #endregion #region Pixel access functions /// /// Returns a pointer to the data-bits of the bitmap. /// /// Handle to a FreeImage bitmap. /// Pointer to the data-bits. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetBits")] public static extern IntPtr GetBits(FIBITMAP dib); /// /// Returns a pointer to the start of the given scanline in the bitmap's data-bits. /// /// Handle to a FreeImage bitmap. /// Number of the scanline. /// Pointer to the scanline. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetScanLine")] public static extern IntPtr GetScanLine(FIBITMAP dib, int scanline); /// /// Get the pixel index of a palettized image at position (x, y), including range check (slow access). /// /// Handle to a FreeImage bitmap. /// Pixel position in horizontal direction. /// Pixel position in vertical direction. /// The pixel index. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetPixelIndex")] public static extern bool GetPixelIndex(FIBITMAP dib, uint x, uint y, out byte value); /// /// Get the pixel color of a 16-, 24- or 32-bit image at position (x, y), including range check (slow access). /// /// Handle to a FreeImage bitmap. /// Pixel position in horizontal direction. /// Pixel position in vertical direction. /// The pixel color. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetPixelColor")] public static extern bool GetPixelColor(FIBITMAP dib, uint x, uint y, out RGBQUAD value); /// /// Set the pixel index of a palettized image at position (x, y), including range check (slow access). /// /// Handle to a FreeImage bitmap. /// Pixel position in horizontal direction. /// Pixel position in vertical direction. /// The new pixel index. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetPixelIndex")] public static extern bool SetPixelIndex(FIBITMAP dib, uint x, uint y, ref byte value); /// /// Set the pixel color of a 16-, 24- or 32-bit image at position (x, y), including range check (slow access). /// /// Handle to a FreeImage bitmap. /// Pixel position in horizontal direction. /// Pixel position in vertical direction. /// The new pixel color. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetPixelColor")] public static extern bool SetPixelColor(FIBITMAP dib, uint x, uint y, ref RGBQUAD value); #endregion #region Bitmap information functions /// /// Retrieves the type of the bitmap. /// /// Handle to a FreeImage bitmap. /// Type of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetImageType")] public static extern FREE_IMAGE_TYPE GetImageType(FIBITMAP dib); /// /// Returns the number of colors used in a bitmap. /// /// Handle to a FreeImage bitmap. /// Palette-size for palletised bitmaps, and 0 for high-colour bitmaps. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetColorsUsed")] public static extern uint GetColorsUsed(FIBITMAP dib); /// /// Returns the size of one pixel in the bitmap in bits. /// /// Handle to a FreeImage bitmap. /// Size of one pixel in the bitmap in bits. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetBPP")] public static extern uint GetBPP(FIBITMAP dib); /// /// Returns the width of the bitmap in pixel units. /// /// Handle to a FreeImage bitmap. /// With of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetWidth")] public static extern uint GetWidth(FIBITMAP dib); /// /// Returns the height of the bitmap in pixel units. /// /// Handle to a FreeImage bitmap. /// Height of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetHeight")] public static extern uint GetHeight(FIBITMAP dib); /// /// Returns the width of the bitmap in bytes. /// /// Handle to a FreeImage bitmap. /// With of the bitmap in bytes. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetLine")] public static extern uint GetLine(FIBITMAP dib); /// /// Returns the width of the bitmap in bytes, rounded to the next 32-bit boundary, /// also known as pitch or stride or scan width. /// /// Handle to a FreeImage bitmap. /// With of the bitmap in bytes. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetPitch")] public static extern uint GetPitch(FIBITMAP dib); /// /// Returns the size of the DIB-element of a FIBITMAP in memory. /// /// Handle to a FreeImage bitmap. /// Size of the DIB-element [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetDIBSize")] public static extern uint GetDIBSize(FIBITMAP dib); /// /// Returns a pointer to the bitmap's palette. /// /// Handle to a FreeImage bitmap. /// Pointer to the bitmap's palette. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetPalette")] public static extern IntPtr GetPalette(FIBITMAP dib); /// /// Returns the horizontal resolution, in pixels-per-meter, of the target device for the bitmap. /// /// Handle to a FreeImage bitmap. /// The horizontal resolution, in pixels-per-meter. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetDotsPerMeterX")] public static extern uint GetDotsPerMeterX(FIBITMAP dib); /// /// Returns the vertical resolution, in pixels-per-meter, of the target device for the bitmap. /// /// Handle to a FreeImage bitmap. /// The vertical resolution, in pixels-per-meter. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetDotsPerMeterY")] public static extern uint GetDotsPerMeterY(FIBITMAP dib); /// /// Set the horizontal resolution, in pixels-per-meter, of the target device for the bitmap. /// /// Handle to a FreeImage bitmap. /// The new horizontal resolution. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetDotsPerMeterX")] public static extern void SetDotsPerMeterX(FIBITMAP dib, uint res); /// /// Set the vertical resolution, in pixels-per-meter, of the target device for the bitmap. /// /// Handle to a FreeImage bitmap. /// The new vertical resolution. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetDotsPerMeterY")] public static extern void SetDotsPerMeterY(FIBITMAP dib, uint res); /// /// Returns a pointer to the of the DIB-element in a FIBITMAP. /// /// Handle to a FreeImage bitmap. /// Poiter to the header of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetInfoHeader")] public static extern IntPtr GetInfoHeader(FIBITMAP dib); /// /// Alias for FreeImage_GetInfoHeader that returns a pointer to a /// rather than to a . /// /// Handle to a FreeImage bitmap. /// Pointer to the structure for the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetInfo")] public static extern IntPtr GetInfo(FIBITMAP dib); /// /// Investigates the color type of the bitmap by reading the bitmap's pixel bits and analysing them. /// /// Handle to a FreeImage bitmap. /// The color type of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetColorType")] public static extern FREE_IMAGE_COLOR_TYPE GetColorType(FIBITMAP dib); /// /// Returns a bit pattern describing the red color component of a pixel in a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// The bit pattern for RED. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetRedMask")] public static extern uint GetRedMask(FIBITMAP dib); /// /// Returns a bit pattern describing the green color component of a pixel in a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// The bit pattern for green. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetGreenMask")] public static extern uint GetGreenMask(FIBITMAP dib); /// /// Returns a bit pattern describing the blue color component of a pixel in a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// The bit pattern for blue. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetBlueMask")] public static extern uint GetBlueMask(FIBITMAP dib); /// /// Returns the number of transparent colors in a palletised bitmap. /// /// Handle to a FreeImage bitmap. /// The number of transparent colors in a palletised bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTransparencyCount")] public static extern uint GetTransparencyCount(FIBITMAP dib); /// /// Returns a pointer to the bitmap's transparency table. /// /// Handle to a FreeImage bitmap. /// Pointer to the bitmap's transparency table. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTransparencyTable")] public static extern IntPtr GetTransparencyTable(FIBITMAP dib); /// /// Tells FreeImage if it should make use of the transparency table /// or the alpha channel that may accompany a bitmap. /// /// Handle to a FreeImage bitmap. /// True to enable the transparency, false to disable. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTransparent")] public static extern void SetTransparent(FIBITMAP dib, bool enabled); /// /// Set the bitmap's transparency table. Only affects palletised bitmaps. /// /// Handle to a FreeImage bitmap. /// Pointer to the bitmap's new transparency table. /// The number of transparent colors in the new transparency table. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTransparencyTable")] internal static extern void SetTransparencyTable(FIBITMAP dib, byte[] table, int count); /// /// Returns whether the transparency table is enabled. /// /// Handle to a FreeImage bitmap. /// Returns true when the transparency table is enabled (1-, 4- or 8-bit images) /// or when the input dib contains alpha values (32-bit images). Returns false otherwise. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_IsTransparent")] public static extern bool IsTransparent(FIBITMAP dib); /// /// Returns whether the bitmap has a file background color. /// /// Handle to a FreeImage bitmap. /// Returns true when the image has a file background color, false otherwise. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_HasBackgroundColor")] public static extern bool HasBackgroundColor(FIBITMAP dib); /// /// Returns the file background color of an image. /// For 8-bit images, the color index in the palette is returned in the /// rgbReserved member of the bkcolor parameter. /// /// Handle to a FreeImage bitmap. /// The background color. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetBackgroundColor")] public static extern bool GetBackgroundColor(FIBITMAP dib, out RGBQUAD bkcolor); /// /// Set the file background color of an image. /// When saving an image to PNG, this background color is transparently saved to the PNG file. /// /// Handle to a FreeImage bitmap. /// The new background color. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetBackgroundColor")] public static unsafe extern bool SetBackgroundColor(FIBITMAP dib, ref RGBQUAD bkcolor); /// /// Set the file background color of an image. /// When saving an image to PNG, this background color is transparently saved to the PNG file. /// When the bkcolor parameter is null, the background color is removed from the image. /// /// This overloaded version of the function with an array parameter is provided to allow /// passing null in the parameter. This is similar to the /// original C/C++ function. Passing null as parameter will /// unset the dib's previously set background color. /// /// /// Handle to a FreeImage bitmap. /// The new background color. /// The first entry in the array is used. /// Returns true on success, false on failure. /// /// /// // create a RGBQUAD color /// RGBQUAD color = new RGBQUAD(Color.Green); /// /// // set the dib's background color (using the other version of the function) /// FreeImage.SetBackgroundColor(dib, ref color); /// /// // remove it again (this only works due to the array parameter RGBQUAD[]) /// FreeImage.SetBackgroundColor(dib, null); /// /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetBackgroundColor")] public static unsafe extern bool SetBackgroundColor(FIBITMAP dib, RGBQUAD[] bkcolor); /// /// Sets the index of the palette entry to be used as transparent color /// for the image specified. Does nothing on high color images. /// /// Handle to a FreeImage bitmap. /// The index of the palette entry to be set as transparent color. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTransparentIndex")] public static extern void SetTransparentIndex(FIBITMAP dib, int index); /// /// Returns the palette entry used as transparent color for the image specified. /// Works for palletised images only and returns -1 for high color /// images or if the image has no color set to be transparent. /// /// Handle to a FreeImage bitmap. /// the index of the palette entry used as transparent color for /// the image specified or -1 if there is no transparent color found /// (e.g. the image is a high color image). [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTransparentIndex")] public static extern int GetTransparentIndex(FIBITMAP dib); #endregion #region ICC profile functions /// /// Retrieves the data of the bitmap. /// This function can also be called safely, when the original format does not support profiles. /// /// Handle to a FreeImage bitmap. /// The data of the bitmap. public static FIICCPROFILE GetICCProfileEx(FIBITMAP dib) { unsafe { return *(FIICCPROFILE*)FreeImage.GetICCProfile(dib); } } /// /// Retrieves a pointer to the data of the bitmap. /// This function can also be called safely, when the original format does not support profiles. /// /// Handle to a FreeImage bitmap. /// Pointer to the data of the bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetICCProfile")] public static extern IntPtr GetICCProfile(FIBITMAP dib); /// /// Creates a new block from ICC profile data previously read from a file /// or built by a color management system. The profile data is attached to the bitmap. /// /// Handle to a FreeImage bitmap. /// Pointer to the new data. /// Size of the data. /// Pointer to the created structure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CreateICCProfile")] public static extern IntPtr CreateICCProfile(FIBITMAP dib, byte[] data, int size); /// /// This function destroys an previously created by . /// After this call the bitmap will contain no profile information. /// This function should be called to ensure that a stored bitmap will not contain any profile information. /// /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_DestroyICCProfile")] public static extern void DestroyICCProfile(FIBITMAP dib); #endregion #region Conversion functions /// /// Converts a bitmap to 4 bits. /// If the bitmap was a high-color bitmap (16, 24 or 32-bit) or if it was a /// monochrome or greyscale bitmap (1 or 8-bit), the end result will be a /// greyscale bitmap, otherwise (1-bit palletised bitmaps) it will be a palletised bitmap. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo4Bits")] public static extern FIBITMAP ConvertTo4Bits(FIBITMAP dib); /// /// Converts a bitmap to 8 bits. If the bitmap was a high-color bitmap (16, 24 or 32-bit) /// or if it was a monochrome or greyscale bitmap (1 or 4-bit), the end result will be a /// greyscale bitmap, otherwise (1 or 4-bit palletised bitmaps) it will be a palletised bitmap. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo8Bits")] public static extern FIBITMAP ConvertTo8Bits(FIBITMAP dib); /// /// Converts a bitmap to a 8-bit greyscale image with a linear ramp. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToGreyscale")] public static extern FIBITMAP ConvertToGreyscale(FIBITMAP dib); /// /// Converts a bitmap to 16 bits, where each pixel has a color pattern of /// 5 bits red, 5 bits green and 5 bits blue. One bit in each pixel is unused. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo16Bits555")] public static extern FIBITMAP ConvertTo16Bits555(FIBITMAP dib); /// /// Converts a bitmap to 16 bits, where each pixel has a color pattern of /// 5 bits red, 6 bits green and 5 bits blue. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo16Bits565")] public static extern FIBITMAP ConvertTo16Bits565(FIBITMAP dib); /// /// Converts a bitmap to 24 bits. A clone of the input bitmap is returned for 24-bit bitmaps. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo24Bits")] public static extern FIBITMAP ConvertTo24Bits(FIBITMAP dib); /// /// Converts a bitmap to 32 bits. A clone of the input bitmap is returned for 32-bit bitmaps. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertTo32Bits")] public static extern FIBITMAP ConvertTo32Bits(FIBITMAP dib); /// /// Quantizes a high-color 24-bit bitmap to an 8-bit palette color bitmap. /// /// Handle to a FreeImage bitmap. /// Specifies the color reduction algorithm to be used. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ColorQuantize")] public static extern FIBITMAP ColorQuantize(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize); /// /// ColorQuantizeEx is an extension to the method that /// provides additional options used to quantize a 24-bit image to any /// number of colors (up to 256), as well as quantize a 24-bit image using a /// partial or full provided palette. /// /// Handle to a FreeImage bitmap. /// Specifies the color reduction algorithm to be used. /// Size of the desired output palette. /// Size of the provided palette of ReservePalette. /// The provided palette. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ColorQuantizeEx")] public static extern FIBITMAP ColorQuantizeEx(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, int ReserveSize, RGBQUAD[] ReservePalette); /// /// Converts a bitmap to 1-bit monochrome bitmap using a threshold T between [0..255]. /// The function first converts the bitmap to a 8-bit greyscale bitmap. /// Then, any brightness level that is less than T is set to zero, otherwise to 1. /// For 1-bit input bitmaps, the function clones the input bitmap and builds a monochrome palette. /// /// Handle to a FreeImage bitmap. /// The threshold. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Threshold")] public static extern FIBITMAP Threshold(FIBITMAP dib, byte t); /// /// Converts a bitmap to 1-bit monochrome bitmap using a dithering algorithm. /// For 1-bit input bitmaps, the function clones the input bitmap and builds a monochrome palette. /// /// Handle to a FreeImage bitmap. /// The dithering algorithm to use. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Dither")] public static extern FIBITMAP Dither(FIBITMAP dib, FREE_IMAGE_DITHER algorithm); /// /// Converts a raw bitmap to a FreeImage bitmap. /// /// Pointer to the memory block containing the raw bitmap. /// The width in pixels of the raw bitmap. /// The height in pixels of the raw bitmap. /// Defines the total width of a scanline in the raw bitmap, /// including padding bytes. /// The bit depth (bits per pixel) of the raw bitmap. /// The bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap is stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertFromRawBits")] public static extern FIBITMAP ConvertFromRawBits(IntPtr bits, int width, int height, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown); /// /// Converts a raw bitmap to a FreeImage bitmap. /// /// Array of bytes containing the raw bitmap. /// The width in pixels of the raw bitmap. /// The height in pixels of the raw bitmap. /// Defines the total width of a scanline in the raw bitmap, /// including padding bytes. /// The bit depth (bits per pixel) of the raw bitmap. /// The bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap is stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertFromRawBits")] public static extern FIBITMAP ConvertFromRawBits(byte[] bits, int width, int height, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown); /// /// Converts a FreeImage bitmap to a raw bitmap, that is a raw piece of memory. /// /// Pointer to the memory block receiving the raw bitmap. /// Handle to a FreeImage bitmap. /// The desired total width in bytes of a scanline in the raw bitmap, /// including any padding bytes. /// The desired bit depth (bits per pixel) of the raw bitmap. /// The desired bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The desired bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The desired bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap will be stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToRawBits")] public static extern void ConvertToRawBits(IntPtr bits, FIBITMAP dib, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown); /// /// Converts a FreeImage bitmap to a raw bitmap, that is a raw piece of memory. /// /// Array of bytes receiving the raw bitmap. /// Handle to a FreeImage bitmap. /// The desired total width in bytes of a scanline in the raw bitmap, /// including any padding bytes. /// The desired bit depth (bits per pixel) of the raw bitmap. /// The desired bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The desired bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The desired bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap will be stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToRawBits")] public static extern void ConvertToRawBits(byte[] bits, FIBITMAP dib, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown); /// /// Converts a 24- or 32-bit RGB(A) standard image or a 48-bit RGB image to a FIT_RGBF type image. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToRGBF")] public static extern FIBITMAP ConvertToRGBF(FIBITMAP dib); /// /// Converts a non standard image whose color type is FIC_MINISBLACK /// to a standard 8-bit greyscale image. /// /// Handle to a FreeImage bitmap. /// When true the conversion is done by scaling linearly /// each pixel value from [min, max] to an integer value between [0..255], /// where min and max are the minimum and maximum pixel values in the image. /// When false the conversion is done by rounding each pixel value to an integer between [0..255]. /// /// Rounding is done using the following formula: /// /// dst_pixel = (BYTE) MIN(255, MAX(0, q)) where int q = int(src_pixel + 0.5); /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToStandardType")] public static extern FIBITMAP ConvertToStandardType(FIBITMAP src, bool scale_linear); /// /// Converts an image of any type to type dst_type. /// /// Handle to a FreeImage bitmap. /// Destination type. /// True to scale linear, else false. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ConvertToType")] public static extern FIBITMAP ConvertToType(FIBITMAP src, FREE_IMAGE_TYPE dst_type, bool scale_linear); #endregion #region Tone mapping operators /// /// Converts a High Dynamic Range image (48-bit RGB or 96-bit RGBF) to a 24-bit RGB image, suitable for display. /// /// Handle to a FreeImage bitmap. /// The tone mapping operator to be used. /// Parmeter depending on the used algorithm /// Parmeter depending on the used algorithm /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ToneMapping")] public static extern FIBITMAP ToneMapping(FIBITMAP dib, FREE_IMAGE_TMO tmo, double first_param, double second_param); /// /// Converts a High Dynamic Range image to a 24-bit RGB image using a global /// operator based on logarithmic compression of luminance values, imitating the human response to light. /// /// Handle to a FreeImage bitmap. /// A gamma correction that is applied after the tone mapping. /// A value of 1 means no correction. /// Scale factor allowing to adjust the brightness of the output image. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_TmoDrago03")] public static extern FIBITMAP TmoDrago03(FIBITMAP src, double gamma, double exposure); /// /// Converts a High Dynamic Range image to a 24-bit RGB image using a global operator inspired /// by photoreceptor physiology of the human visual system. /// /// Handle to a FreeImage bitmap. /// Controls the overall image intensity in the range [-8, 8]. /// Controls the overall image contrast in the range [0.3, 1.0[. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_TmoReinhard05")] public static extern FIBITMAP TmoReinhard05(FIBITMAP src, double intensity, double contrast); /// /// Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB. /// /// Handle to a FreeImage bitmap. /// Color saturation (s parameter in the paper) in [0.4..0.6] /// Atenuation factor (beta parameter in the paper) in [0.8..0.9] /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_TmoFattal02")] public static extern FIBITMAP TmoFattal02(FIBITMAP src, double color_saturation, double attenuation); #endregion #region Compression functions /// /// Compresses a source buffer into a target buffer, using the ZLib library. /// /// Pointer to the target buffer. /// Size of the target buffer. /// Must be at least 0.1% larger than source_size plus 12 bytes. /// Pointer to the source buffer. /// Size of the source buffer. /// The actual size of the compressed buffer, or 0 if an error occurred. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ZLibCompress")] public static extern uint ZLibCompress(byte[] target, uint target_size, byte[] source, uint source_size); /// /// Decompresses a source buffer into a target buffer, using the ZLib library. /// /// Pointer to the target buffer. /// Size of the target buffer. /// Must have been saved outlide of zlib. /// Pointer to the source buffer. /// Size of the source buffer. /// The actual size of the uncompressed buffer, or 0 if an error occurred. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ZLibUncompress")] public static extern uint ZLibUncompress(byte[] target, uint target_size, byte[] source, uint source_size); /// /// Compresses a source buffer into a target buffer, using the ZLib library. /// /// Pointer to the target buffer. /// Size of the target buffer. /// Must be at least 0.1% larger than source_size plus 24 bytes. /// Pointer to the source buffer. /// Size of the source buffer. /// The actual size of the compressed buffer, or 0 if an error occurred. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ZLibGZip")] public static extern uint ZLibGZip(byte[] target, uint target_size, byte[] source, uint source_size); /// /// Decompresses a source buffer into a target buffer, using the ZLib library. /// /// Pointer to the target buffer. /// Size of the target buffer. /// Must have been saved outlide of zlib. /// Pointer to the source buffer. /// Size of the source buffer. /// The actual size of the uncompressed buffer, or 0 if an error occurred. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ZLibGUnzip")] public static extern uint ZLibGUnzip(byte[] target, uint target_size, byte[] source, uint source_size); /// /// Generates a CRC32 checksum. /// /// The CRC32 checksum to begin with. /// Pointer to the source buffer. /// If the value is 0, the function returns the required initial value for the crc. /// Size of the source buffer. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ZLibCRC32")] public static extern uint ZLibCRC32(uint crc, byte[] source, uint source_size); #endregion #region Tag creation and destruction /// /// Allocates a new object. /// This object must be destroyed with a call to /// when no longer in use. /// /// The new . [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CreateTag")] public static extern FITAG CreateTag(); /// /// Delete a previously allocated object. /// /// The to destroy. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_DeleteTag")] public static extern void DeleteTag(FITAG tag); /// /// Creates and returns a copy of a object. /// /// The to clone. /// The new . [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CloneTag")] public static extern FITAG CloneTag(FITAG tag); #endregion #region Tag accessors /// /// Returns the tag field name (unique inside a metadata model). /// /// The tag field. /// The field name. public static unsafe string GetTagKey(FITAG tag) { return PtrToStr(GetTagKey_(tag)); } [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetTagKey")] private static unsafe extern byte* GetTagKey_(FITAG tag); /// /// Returns the tag description. /// /// The tag field. /// The description or NULL if unavailable. public static unsafe string GetTagDescription(FITAG tag) { return PtrToStr(GetTagDescription_(tag)); } [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetTagDescription")] private static unsafe extern byte* GetTagDescription_(FITAG tag); /// /// Returns the tag ID. /// /// The tag field. /// The ID or 0 if unavailable. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTagID")] public static extern ushort GetTagID(FITAG tag); /// /// Returns the tag data type. /// /// The tag field. /// The tag type. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTagType")] public static extern FREE_IMAGE_MDTYPE GetTagType(FITAG tag); /// /// Returns the number of components in the tag (in tag type units). /// /// The tag field. /// The number of components. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTagCount")] public static extern uint GetTagCount(FITAG tag); /// /// Returns the length of the tag value in bytes. /// /// The tag field. /// The length of the tag value. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTagLength")] public static extern uint GetTagLength(FITAG tag); /// /// Returns the tag value. /// It is up to the programmer to interpret the returned pointer correctly, /// according to the results of GetTagType and GetTagCount. /// /// The tag field. /// Pointer to the value. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetTagValue")] public static extern IntPtr GetTagValue(FITAG tag); /// /// Sets the tag field name. /// /// The tag field. /// The new name. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_SetTagKey")] public static extern bool SetTagKey(FITAG tag, string key); /// /// Sets the tag description. /// /// The tag field. /// The new description. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_SetTagDescription")] public static extern bool SetTagDescription(FITAG tag, string description); /// /// Sets the tag ID. /// /// The tag field. /// The new ID. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTagID")] public static extern bool SetTagID(FITAG tag, ushort id); /// /// Sets the tag data type. /// /// The tag field. /// The new type. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTagType")] public static extern bool SetTagType(FITAG tag, FREE_IMAGE_MDTYPE type); /// /// Sets the number of data in the tag. /// /// The tag field. /// New number of data. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTagCount")] public static extern bool SetTagCount(FITAG tag, uint count); /// /// Sets the length of the tag value in bytes. /// /// The tag field. /// The new length. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTagLength")] public static extern bool SetTagLength(FITAG tag, uint length); /// /// Sets the tag value. /// /// The tag field. /// Pointer to the new value. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetTagValue")] public static extern bool SetTagValue(FITAG tag, byte[] value); #endregion #region Metadata iterator /// /// Provides information about the first instance of a tag that matches the metadata model. /// /// The model to match. /// Handle to a FreeImage bitmap. /// Tag that matches the metadata model. /// Unique search handle that can be used to call FindNextMetadata or FindCloseMetadata. /// Null if the metadata model does not exist. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FindFirstMetadata")] public static extern FIMETADATA FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP dib, out FITAG tag); /// /// Find the next tag, if any, that matches the metadata model argument in a previous call /// to FindFirstMetadata, and then alters the tag object contents accordingly. /// /// Unique search handle provided by FindFirstMetadata. /// Tag that matches the metadata model. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FindNextMetadata")] public static extern bool FindNextMetadata(FIMETADATA mdhandle, out FITAG tag); /// /// Closes the specified metadata search handle and releases associated resources. /// /// The handle to close. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FindCloseMetadata")] private static extern void FindCloseMetadata_(FIMETADATA mdhandle); #endregion #region Metadata setter and getter /// /// Retrieve a metadata attached to a dib. /// /// The metadata model to look for. /// Handle to a FreeImage bitmap. /// The metadata field name. /// A FITAG structure returned by the function. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_GetMetadata")] public static extern bool GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP dib, string key, out FITAG tag); /// /// Attach a new FreeImage tag to a dib. /// /// The metadata model used to store the tag. /// Handle to a FreeImage bitmap. /// The tag field name. /// The FreeImage tag to be attached. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_SetMetadata")] public static extern bool SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP dib, string key, FITAG tag); #endregion #region Metadata helper functions /// /// Returns the number of tags contained in the model metadata model attached to the input dib. /// /// The metadata model. /// Handle to a FreeImage bitmap. /// Number of tags contained in the metadata model. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetMetadataCount")] public static extern uint GetMetadataCount(FREE_IMAGE_MDMODEL model, FIBITMAP dib); /// /// Copies the metadata of FreeImage bitmap to another. /// /// The FreeImage bitmap to copy the metadata to. /// The FreeImage bitmap to copy the metadata from. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_CloneMetadata")] public static extern bool CloneMetadata(FIBITMAP dst, FIBITMAP src); /// /// Converts a FreeImage tag structure to a string that represents the interpreted tag value. /// The function is not thread safe. /// /// The metadata model. /// The interpreted tag value. /// Reserved. /// The representing string. public static unsafe string TagToString(FREE_IMAGE_MDMODEL model, FITAG tag, uint Make) { return PtrToStr(TagToString_(model, tag, Make)); } [DllImport(FreeImageLibrary, CharSet = CharSet.Ansi, EntryPoint = "FreeImage_TagToString")] private static unsafe extern byte* TagToString_(FREE_IMAGE_MDMODEL model, FITAG tag, uint Make); #endregion #region Rotation and flipping /// /// This function rotates a 1-, 8-bit greyscale or a 24-, 32-bit color image by means of 3 shears. /// 1-bit images rotation is limited to integer multiple of 90�. /// null is returned for other values. /// /// Handle to a FreeImage bitmap. /// The angle of rotation. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_RotateClassic")] [Obsolete("RotateClassic is deprecated (use Rotate instead).")] public static extern FIBITMAP RotateClassic(FIBITMAP dib, double angle); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Rotate")] internal static extern FIBITMAP Rotate(FIBITMAP dib, double angle, IntPtr backgroundColor); /// /// This function performs a rotation and / or translation of an 8-bit greyscale, /// 24- or 32-bit image, using a 3rd order (cubic) B-Spline. /// /// Handle to a FreeImage bitmap. /// The angle of rotation. /// Horizontal image translation. /// Vertical image translation. /// Rotation center x-coordinate. /// Rotation center y-coordinate. /// When true the irrelevant part of the image is set to a black color, /// otherwise, a mirroring technique is used to fill irrelevant pixels. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_RotateEx")] public static extern FIBITMAP RotateEx(FIBITMAP dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, bool use_mask); /// /// Flip the input dib horizontally along the vertical axis. /// /// Handle to a FreeImage bitmap. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FlipHorizontal")] public static extern bool FlipHorizontal(FIBITMAP dib); /// /// Flip the input dib vertically along the horizontal axis. /// /// Handle to a FreeImage bitmap. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FlipVertical")] public static extern bool FlipVertical(FIBITMAP dib); /// /// Performs a lossless rotation or flipping on a JPEG file. /// /// Source file. /// Destination file; can be the source file; will be overwritten. /// The operation to apply. /// To avoid lossy transformation, you can set the perfect parameter to true. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_JPEGTransformU")] public static extern bool JPEGTransform(string src_file, string dst_file, FREE_IMAGE_JPEG_OPERATION operation, bool perfect); #endregion #region Upsampling / downsampling /// /// Performs resampling (or scaling, zooming) of a greyscale or RGB(A) image /// to the desired destination width and height. /// /// Handle to a FreeImage bitmap. /// Destination width. /// Destination height. /// The filter to apply. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Rescale")] public static extern FIBITMAP Rescale(FIBITMAP dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter); /// /// Creates a thumbnail from a greyscale or RGB(A) image, keeping aspect ratio. /// /// Handle to a FreeImage bitmap. /// Thumbnail square size. /// When true HDR images are transperantly converted to standard images. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_MakeThumbnail")] public static extern FIBITMAP MakeThumbnail(FIBITMAP dib, int max_pixel_size, bool convert); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_EnlargeCanvas")] internal static extern FIBITMAP EnlargeCanvas(FIBITMAP dib, int left, int top, int right, int bottom, IntPtr color, FREE_IMAGE_COLOR_OPTIONS options); #endregion #region Color manipulation /// /// Perfoms an histogram transformation on a 8-, 24- or 32-bit image. /// /// Handle to a FreeImage bitmap. /// The lookup table. /// It's size is assumed to be 256 in length. /// The color channel to be transformed. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AdjustCurve")] public static extern bool AdjustCurve(FIBITMAP dib, byte[] lookUpTable, FREE_IMAGE_COLOR_CHANNEL channel); /// /// Performs gamma correction on a 8-, 24- or 32-bit image. /// /// Handle to a FreeImage bitmap. /// The parameter represents the gamma value to use (gamma > 0). /// A value of 1.0 leaves the image alone, less than one darkens it, and greater than one lightens it. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AdjustGamma")] public static extern bool AdjustGamma(FIBITMAP dib, double gamma); /// /// Adjusts the brightness of a 8-, 24- or 32-bit image by a certain amount. /// /// Handle to a FreeImage bitmap. /// A value 0 means no change, /// less than 0 will make the image darker and greater than 0 will make the image brighter. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AdjustBrightness")] public static extern bool AdjustBrightness(FIBITMAP dib, double percentage); /// /// Adjusts the contrast of a 8-, 24- or 32-bit image by a certain amount. /// /// Handle to a FreeImage bitmap. /// A value 0 means no change, /// less than 0 will decrease the contrast and greater than 0 will increase the contrast of the image. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AdjustContrast")] public static extern bool AdjustContrast(FIBITMAP dib, double percentage); /// /// Inverts each pixel data. /// /// Handle to a FreeImage bitmap. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Invert")] public static extern bool Invert(FIBITMAP dib); /// /// Computes the image histogram. /// /// Handle to a FreeImage bitmap. /// Array of integers with a size of 256. /// Channel to compute from. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetHistogram")] public static extern bool GetHistogram(FIBITMAP dib, int[] histo, FREE_IMAGE_COLOR_CHANNEL channel); #endregion #region Channel processing /// /// Retrieves the red, green, blue or alpha channel of a 24- or 32-bit image. /// /// Handle to a FreeImage bitmap. /// The color channel to extract. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetChannel")] public static extern FIBITMAP GetChannel(FIBITMAP dib, FREE_IMAGE_COLOR_CHANNEL channel); /// /// Insert a 8-bit dib into a 24- or 32-bit image. /// Both images must have to same width and height. /// /// Handle to a FreeImage bitmap. /// Handle to the bitmap to insert. /// The color channel to replace. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetChannel")] public static extern bool SetChannel(FIBITMAP dib, FIBITMAP dib8, FREE_IMAGE_COLOR_CHANNEL channel); /// /// Retrieves the real part, imaginary part, magnitude or phase of a complex image. /// /// Handle to a FreeImage bitmap. /// The color channel to extract. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetComplexChannel")] public static extern FIBITMAP GetComplexChannel(FIBITMAP src, FREE_IMAGE_COLOR_CHANNEL channel); /// /// Set the real or imaginary part of a complex image. /// Both images must have to same width and height. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. /// The color channel to replace. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SetComplexChannel")] public static extern bool SetComplexChannel(FIBITMAP dst, FIBITMAP src, FREE_IMAGE_COLOR_CHANNEL channel); #endregion #region Copy / Paste / Composite routines /// /// Copy a sub part of the current dib image. /// /// Handle to a FreeImage bitmap. /// Specifies the left position of the cropped rectangle. /// Specifies the top position of the cropped rectangle. /// Specifies the right position of the cropped rectangle. /// Specifies the bottom position of the cropped rectangle. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Copy")] public static extern FIBITMAP Copy(FIBITMAP dib, int left, int top, int right, int bottom); /// /// Alpha blend or combine a sub part image with the current dib image. /// The bit depth of the dst bitmap must be greater than or equal to the bit depth of the src. /// /// Handle to a FreeImage bitmap. /// Handle to a FreeImage bitmap. /// Specifies the left position of the sub image. /// Specifies the top position of the sub image. /// alpha blend factor. /// The source and destination images are alpha blended if alpha=0..255. /// If alpha > 255, then the source image is combined to the destination image. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Paste")] public static extern bool Paste(FIBITMAP dst, FIBITMAP src, int left, int top, int alpha); /// /// This function composite a transparent foreground image against a single background color or /// against a background image. /// /// Handle to a FreeImage bitmap. /// When true the background of fg is used if it contains one. /// The application background is used if useFileBkg is false. /// Image used as background when useFileBkg is false or fg has no background /// and appBkColor is null. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Composite")] public static extern FIBITMAP Composite(FIBITMAP fg, bool useFileBkg, ref RGBQUAD appBkColor, FIBITMAP bg); /// /// This function composite a transparent foreground image against a single background color or /// against a background image. /// /// Handle to a FreeImage bitmap. /// When true the background of fg is used if it contains one. /// The application background is used if useFileBkg is false /// and 'appBkColor' is not null. /// Image used as background when useFileBkg is false or fg has no background /// and appBkColor is null. /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_Composite")] public static extern FIBITMAP Composite(FIBITMAP fg, bool useFileBkg, RGBQUAD[] appBkColor, FIBITMAP bg); /// /// Performs a lossless crop on a JPEG file. /// /// Source filename. /// Destination filename. /// Specifies the left position of the cropped rectangle. /// Specifies the top position of the cropped rectangle. /// Specifies the right position of the cropped rectangle. /// Specifies the bottom position of the cropped rectangle. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, CharSet = CharSet.Unicode, EntryPoint = "FreeImage_JPEGCropU")] public static extern bool JPEGCrop(string src_file, string dst_file, int left, int top, int right, int bottom); /// /// Applies the alpha value of each pixel to its color components. /// The aplha value stays unchanged. /// Only works with 32-bits color depth. /// /// Handle to a FreeImage bitmap. /// Returns true on success, false on failure. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_PreMultiplyWithAlpha")] public static extern bool PreMultiplyWithAlpha(FIBITMAP dib); #endregion #region Miscellaneous algorithms /// /// Solves a Poisson equation, remap result pixels to [0..1] and returns the solution. /// /// Handle to a FreeImage bitmap. /// Number of cycles in the multigrid algorithm (usually 2 or 3) /// Handle to a FreeImage bitmap. [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_MultigridPoissonSolver")] public static extern FIBITMAP MultigridPoissonSolver(FIBITMAP Laplacian, int ncycle); #endregion #region Colors /// /// Creates a lookup table to be used with which may adjusts brightness and /// contrast, correct gamma and invert the image with a single call to . /// /// Output lookup table to be used with . /// The size of 'lookUpTable' is assumed to be 256. /// Percentage brightness value where -100 <= brightness <= 100. /// A value of 0 means no change, less than 0 will make the image darker and greater /// than 0 will make the image brighter. /// Percentage contrast value where -100 <= contrast <= 100. /// A value of 0 means no change, less than 0 will decrease the contrast /// and greater than 0 will increase the contrast of the image. /// Gamma value to be used for gamma correction. /// A value of 1.0 leaves the image alone, less than one darkens it, /// and greater than one lightens it. /// If set to true, the image will be inverted. /// The number of adjustments applied to the resulting lookup table /// compared to a blind lookup table. /// /// This function creates a lookup table to be used with which may adjust /// brightness and contrast, correct gamma and invert the image with a single call to /// . If more than one of these image display properties need to be adjusted, /// using a combined lookup table should be preferred over calling each adjustment function /// separately. That's particularly true for huge images or if performance is an issue. Then, /// the expensive process of iterating over all pixels of an image is performed only once and /// not up to four times. /// /// Furthermore, the lookup table created does not depend on the order, in which each single /// adjustment operation is performed. Due to rounding and byte casting issues, it actually /// matters in which order individual adjustment operations are performed. Both of the following /// snippets most likely produce different results: /// /// /// // snippet 1: contrast, brightness /// AdjustContrast(dib, 15.0); /// AdjustBrightness(dib, 50.0); /// /// /// /// // snippet 2: brightness, contrast /// AdjustBrightness(dib, 50.0); /// AdjustContrast(dib, 15.0); /// /// /// Better and even faster would be snippet 3: /// /// /// // snippet 3: /// byte[] lut = new byte[256]; /// GetAdjustColorsLookupTable(lut, 50.0, 15.0, 1.0, false); /// AdjustCurve(dib, lut, FREE_IMAGE_COLOR_CHANNEL.FICC_RGB); /// /// /// This function is also used internally by , which does not return the /// lookup table, but uses it to call on the passed image. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_GetAdjustColorsLookupTable")] public static extern int GetAdjustColorsLookupTable(byte[] lookUpTable, double brightness, double contrast, double gamma, bool invert); /// /// Adjusts an image's brightness, contrast and gamma as well as it may /// optionally invert the image within a single operation. /// /// Handle to a FreeImage bitmap. /// Percentage brightness value where -100 <= brightness <= 100. /// A value of 0 means no change, less than 0 will make the image darker and greater /// than 0 will make the image brighter. /// Percentage contrast value where -100 <= contrast <= 100. /// A value of 0 means no change, less than 0 will decrease the contrast /// and greater than 0 will increase the contrast of the image. /// Gamma value to be used for gamma correction. /// A value of 1.0 leaves the image alone, less than one darkens it, /// and greater than one lightens it. /// This parameter must not be zero or smaller than zero. /// If so, it will be ignored and no gamma correction will be performed on the image. /// If set to true, the image will be inverted. /// Returns true on success, false on failure. /// /// This function adjusts an image's brightness, contrast and gamma as well as it /// may optionally invert the image within a single operation. If more than one of /// these image display properties need to be adjusted, using this function should /// be preferred over calling each adjustment function separately. That's particularly /// true for huge images or if performance is an issue. /// /// This function relies on , /// which creates a single lookup table, that combines all adjustment operations requested. /// /// Furthermore, the lookup table created by does /// not depend on the order, in which each single adjustment operation is performed. /// Due to rounding and byte casting issues, it actually matters in which order individual /// adjustment operations are performed. Both of the following snippets most likely produce /// different results: /// /// /// // snippet 1: contrast, brightness /// AdjustContrast(dib, 15.0); /// AdjustBrightness(dib, 50.0); /// /// /// /// // snippet 2: brightness, contrast /// AdjustBrightness(dib, 50.0); /// AdjustContrast(dib, 15.0); /// /// /// Better and even faster would be snippet 3: /// /// /// // snippet 3: /// AdjustColors(dib, 50.0, 15.0, 1.0, false); /// /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_AdjustColors")] public static extern bool AdjustColors(FIBITMAP dib, double brightness, double contrast, double gamma, bool invert); /// /// Applies color mapping for one or several colors on a 1-, 4- or 8-bit /// palletized or a 16-, 24- or 32-bit high color image. /// /// Handle to a FreeImage bitmap. /// Array of colors to be used as the mapping source. /// Array of colors to be used as the mapping destination. /// The number of colors to be mapped. This is the size of both /// srccolors and dstcolors. /// If true, 32-bit images and colors are treated as 24-bit. /// If true, source and destination colors are swapped, that is, /// each destination color is also mapped to the corresponding source color. /// The total number of pixels changed. /// /// This function maps up to colors specified in /// to these specified in . /// Thereby, color srccolors[N], if found in the image, will be replaced by color /// dstcolors[N]. If is true, additionally all colors /// specified in are also mapped to these specified /// in . For high color images, the actual image data will be /// modified whereas, for palletized images only the palette will be changed. /// /// The function returns the number of pixels changed or zero, if no pixels were changed. /// /// Both arrays and are assumed /// not to hold less than colors. /// /// For 16-bit images, all colors specified are transparently converted to their /// proper 16-bit representation (either in RGB555 or RGB565 format, which is determined /// by the image's red- green- and blue-mask). /// /// Note, that this behaviour is different from what does, /// which modifies the actual image data on palletized images. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ApplyColorMapping")] public static extern uint ApplyColorMapping(FIBITMAP dib, RGBQUAD[] srccolors, RGBQUAD[] dstcolors, uint count, bool ignore_alpha, bool swap); /// /// Swaps two specified colors on a 1-, 4- or 8-bit palletized /// or a 16-, 24- or 32-bit high color image. /// /// Handle to a FreeImage bitmap. /// One of the two colors to be swapped. /// The other of the two colors to be swapped. /// If true, 32-bit images and colors are treated as 24-bit. /// The total number of pixels changed. /// /// This function swaps the two specified colors and /// on a palletized or high color image. /// For high color images, the actual image data will be modified whereas, for palletized /// images only the palette will be changed. /// /// Note, that this behaviour is different from what does, /// which modifies the actual image data on palletized images. /// /// This is just a thin wrapper for and resolves to: /// /// /// return ApplyColorMapping(dib, color_a, color_b, 1, ignore_alpha, true); /// /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SwapColors")] public static extern uint SwapColors(FIBITMAP dib, ref RGBQUAD color_a, ref RGBQUAD color_b, bool ignore_alpha); /// /// Applies palette index mapping for one or several indices /// on a 1-, 4- or 8-bit palletized image. /// /// Handle to a FreeImage bitmap. /// Array of palette indices to be used as the mapping source. /// Array of palette indices to be used as the mapping destination. /// The number of palette indices to be mapped. This is the size of both /// srcindices and dstindices /// If true, source and destination palette indices are swapped, that is, /// each destination index is also mapped to the corresponding source index. /// The total number of pixels changed. /// /// This function maps up to palette indices specified in /// to these specified in . /// Thereby, index srcindices[N], if present in the image, will be replaced by index /// dstindices[N]. If is true, additionally all indices /// specified in are also mapped to these specified in /// . /// /// The function returns the number of pixels changed or zero, if no pixels were changed. /// Both arrays and are assumed not to /// hold less than indices. /// /// Note, that this behaviour is different from what does, which /// modifies the actual image data on palletized images. /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_ApplyPaletteIndexMapping")] public static extern uint ApplyPaletteIndexMapping(FIBITMAP dib, byte[] srcindices, byte[] dstindices, uint count, bool swap); /// /// Swaps two specified palette indices on a 1-, 4- or 8-bit palletized image. /// /// Handle to a FreeImage bitmap. /// One of the two palette indices to be swapped. /// The other of the two palette indices to be swapped. /// The total number of pixels changed. /// /// This function swaps the two specified palette indices index_a and /// index_b on a palletized image. Therefore, not the palette, but the /// actual image data will be modified. /// /// Note, that this behaviour is different from what does on palletized images, /// which only swaps the colors in the palette. /// /// This is just a thin wrapper for and resolves to: /// /// /// return ApplyPaletteIndexMapping(dib, index_a, index_b, 1, true); /// /// [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_SwapPaletteIndices")] public static extern uint SwapPaletteIndices(FIBITMAP dib, ref byte index_a, ref byte index_b); [DllImport(FreeImageLibrary, EntryPoint = "FreeImage_FillBackground")] internal static extern bool FillBackground(FIBITMAP dib, IntPtr color, FREE_IMAGE_COLOR_OPTIONS options); #endregion } } ///////////////////////////////////////////////////// // // // Wrapper functions // // // ///////////////////////////////////////////////////// #region Structs namespace FreeImageAPI.IO { /// /// Wrapper for a custom handle. /// /// /// The fi_handle of FreeImage in C++ is a simple pointer, but in .NET /// it's not that simple. This wrapper uses fi_handle in two different ways. /// /// We implement a new plugin and FreeImage gives us a handle (pointer) that /// we can simply pass through to the given functions in a 'FreeImageIO' /// structure. /// But when we want to use LoadFromhandle or SaveToHandle we need /// a fi_handle (that we receive again in our own functions). /// This handle is for example a stream (see LoadFromStream / SaveToStream) /// that we want to work with. To know which stream a read/write is meant for /// we could use a hash value that the wrapper itself handles or we can /// go the unmanaged way of using a handle. /// Therefor we use a to receive a unique pointer that we can /// convert back into a .NET object. /// When the fi_handle instance is no longer needed the instance must be disposed /// by the creater manually! It is recommended to use the using statement to /// be sure the instance is always disposed: /// /// /// using (fi_handle handle = new fi_handle(object)) /// { /// callSomeFunctions(handle); /// } /// /// /// What does that mean? /// If we get a fi_handle from unmanaged code we get a pointer to unmanaged /// memory that we do not have to care about, and just pass ist back to FreeImage. /// If we have to create a handle our own we use the standard constructur /// that fills the with an pointer that represents the given object. /// With calling the is used to retrieve the original /// object we passed through the constructor. /// /// This way we can implement a fi_handle that works with managed an unmanaged /// code. /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct fi_handle : IComparable, IComparable, IEquatable, IDisposable { /// /// The handle to wrap. /// public IntPtr handle; /// /// Initializes a new instance wrapping a managed object. /// /// The object to wrap. /// /// is null. public fi_handle(object obj) { if (obj == null) { throw new ArgumentNullException("obj"); } GCHandle gch = GCHandle.Alloc(obj, GCHandleType.Normal); handle = GCHandle.ToIntPtr(gch); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(fi_handle left, fi_handle right) { return (left.handle == right.handle); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(fi_handle left, fi_handle right) { return (left.handle != right.handle); } /// /// Gets whether the pointer is a null pointer. /// public bool IsNull { get { return (handle == IntPtr.Zero); } } /// /// Returns the object assigned to the handle in case this instance /// was created by managed code. /// /// assigned to this handle or null on failure. internal object GetObject() { object result = null; if (handle != IntPtr.Zero) { try { result = GCHandle.FromIntPtr(handle).Target; } catch { } } return result; } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return handle.ToString(); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return handle.GetHashCode(); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is fi_handle) && (this == ((fi_handle)obj))); } /// /// Indicates whether the current object is equal to another object of the same type. /// /// An object to compare with this object. /// True if the current object is equal to the other parameter; otherwise, false. public bool Equals(fi_handle other) { return (this == other); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is fi_handle)) { throw new ArgumentException("obj"); } return CompareTo((fi_handle)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(fi_handle other) { return handle.ToInt64().CompareTo(other.handle.ToInt64()); } /// /// Releases all resources used by the instance. /// public void Dispose() { if (this.handle != IntPtr.Zero) { try { GCHandle.FromIntPtr(handle).Free(); } catch { } finally { this.handle = IntPtr.Zero; } } } } } namespace FreeImageAPI { /// /// The FI1BIT structure represents a single bit. /// It's value can be 0 or 1. /// [DebuggerDisplay("{value}"), Serializable] public struct FI1BIT { /// /// Represents the largest possible value of . This field is constant. /// public const byte MaxValue = 0x01; /// /// Represents the smallest possible value of . This field is constant. /// public const byte MinValue = 0x00; /// /// The value of the structure. /// private byte value; /// /// Initializes a new instance based on the specified value. /// /// The value to initialize with. private FI1BIT(byte value) { this.value = (byte)(value & MaxValue); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator byte(FI1BIT value) { return value.value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FI1BIT(byte value) { return new FI1BIT(value); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return value.ToString(); } } } namespace FreeImageAPI { /// /// The FI4BIT structure represents the half of a . /// It's valuerange is between 0 and 15. /// [DebuggerDisplay("{value}"), Serializable] public struct FI4BIT { /// /// Represents the largest possible value of . This field is constant. /// public const byte MaxValue = 0x0F; /// /// Represents the smallest possible value of . This field is constant. /// public const byte MinValue = 0x00; /// /// The value of the structure. /// private byte value; /// /// Initializes a new instance based on the specified value. /// /// The value to initialize with. private FI4BIT(byte value) { this.value = (byte)(value & MaxValue); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator byte(FI4BIT value) { return value.value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FI4BIT(byte value) { return new FI4BIT(value); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return value.ToString(); } } } namespace FreeImageAPI { /// /// The FI16RGB555 structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 5 bits and so, takes values in the range from 0 to 31. /// /// /// For easy integration of the underlying structure into the .NET framework, /// the FI16RGB555 structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FI16RGB555 structure and my be used in all situations which require /// an FI16RGB555 type. /// /// /// /// The following code example demonstrates the various conversions between the /// FI16RGB555 structure and the structure. /// /// FI16RGB555 fi16rgb; /// // Initialize the structure using a native .NET Color structure. /// fi16rgb = new FI16RGB555(Color.Indigo); /// // Initialize the structure using the implicit operator. /// fi16rgb = Color.DarkSeaGreen; /// // Convert the FI16RGB555 instance into a native .NET Color /// // using its implicit operator. /// Color color = fi16rgb; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = fi16rgb.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FI16RGB555 : IComparable, IComparable, IEquatable { /// /// The value of the color. /// private ushort value; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FI16RGB555(Color color) { value = (ushort)( (((color.R * 31) / 255) << FreeImage.FI16_555_RED_SHIFT) + (((color.G * 31) / 255) << FreeImage.FI16_555_GREEN_SHIFT) + (((color.B * 31) / 255) << FreeImage.FI16_555_BLUE_SHIFT)); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FI16RGB555 left, FI16RGB555 right) { return (left.value == right.value); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FI16RGB555 left, FI16RGB555 right) { return (!(left == right)); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FI16RGB555(Color value) { return new FI16RGB555(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FI16RGB555 value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( ((value & FreeImage.FI16_555_RED_MASK) >> FreeImage.FI16_555_RED_SHIFT) * 255 / 31, ((value & FreeImage.FI16_555_GREEN_MASK) >> FreeImage.FI16_555_GREEN_SHIFT) * 255 / 31, ((value & FreeImage.FI16_555_BLUE_MASK) >> FreeImage.FI16_555_BLUE_SHIFT) * 255 / 31); } set { this.value = (ushort)( (((value.R * 31) / 255) << FreeImage.FI16_555_RED_SHIFT) + (((value.G * 31) / 255) << FreeImage.FI16_555_GREEN_SHIFT) + (((value.B * 31) / 255) << FreeImage.FI16_555_BLUE_SHIFT)); } } /// /// Gets or sets the red color component. /// public byte Red { get { return (byte)(((value & FreeImage.FI16_555_RED_MASK) >> FreeImage.FI16_555_RED_SHIFT) * 255 / 31); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_555_RED_MASK)) | (((value * 31) / 255) << FreeImage.FI16_555_RED_SHIFT)); } } /// /// Gets or sets the green color component. /// public byte Green { get { return (byte)(((value & FreeImage.FI16_555_GREEN_MASK) >> FreeImage.FI16_555_GREEN_SHIFT) * 255 / 31); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_555_GREEN_MASK)) | (((value * 31) / 255) << FreeImage.FI16_555_GREEN_SHIFT)); } } /// /// Gets or sets the blue color component. /// public byte Blue { get { return (byte)(((value & FreeImage.FI16_555_BLUE_MASK) >> FreeImage.FI16_555_BLUE_SHIFT) * 255 / 31); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_555_BLUE_MASK)) | (((value * 31) / 255) << FreeImage.FI16_555_BLUE_SHIFT)); } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FI16RGB555)) { throw new ArgumentException("obj"); } return CompareTo((FI16RGB555)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FI16RGB555 other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return base.Equals(obj); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FI16RGB555 other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FI16RGB565 structure describes a color consisting of relative /// intensities of red, green, blue and alpha value. Each single color /// component consumes 5 bits and so, takes values in the range from 0 to 31. /// /// /// For easy integration of the underlying structure into the .NET framework, /// the FI16RGB565 structure implements implicit conversion operators to /// convert the represented color to and from the /// type. This makes the type a real replacement /// for the FI16RGB565 structure and my be used in all situations which require /// an FI16RGB565 type. /// /// /// /// The following code example demonstrates the various conversions between the /// FI16RGB565 structure and the structure. /// /// FI16RGB565 fi16rgb; /// // Initialize the structure using a native .NET Color structure. /// fi16rgb = new FI16RGB565(Color.Indigo); /// // Initialize the structure using the implicit operator. /// fi16rgb = Color.DarkSeaGreen; /// // Convert the FI16RGB565 instance into a native .NET Color /// // using its implicit operator. /// Color color = fi16rgb; /// // Using the structure's Color property for converting it /// // into a native .NET Color. /// Color another = fi16rgb.Color; /// /// [Serializable, StructLayout(LayoutKind.Sequential)] public struct FI16RGB565 : IComparable, IComparable, IEquatable { /// /// The value of the color. /// private ushort value; /// /// Initializes a new instance based on the specified . /// /// to initialize with. public FI16RGB565(Color color) { value = (ushort)( (((color.R * 31) / 255) << FreeImage.FI16_565_RED_SHIFT) + (((color.G * 63) / 255) << FreeImage.FI16_565_GREEN_SHIFT) + (((color.B * 31) / 255) << FreeImage.FI16_565_BLUE_SHIFT)); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(FI16RGB565 left, FI16RGB565 right) { return (left.value == right.value); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(FI16RGB565 left, FI16RGB565 right) { return (!(left == right)); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FI16RGB565(Color value) { return new FI16RGB565(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator Color(FI16RGB565 value) { return value.Color; } /// /// Gets or sets the of the structure. /// public Color Color { get { return Color.FromArgb( ((value & FreeImage.FI16_565_RED_MASK) >> FreeImage.FI16_565_RED_SHIFT) * 255 / 31, ((value & FreeImage.FI16_565_GREEN_MASK) >> FreeImage.FI16_565_GREEN_SHIFT) * 255 / 63, ((value & FreeImage.FI16_565_BLUE_MASK) >> FreeImage.FI16_565_BLUE_SHIFT) * 255 / 31); } set { this.value = (ushort)( (((value.R * 31) / 255) << FreeImage.FI16_565_RED_SHIFT) + (((value.G * 63) / 255) << FreeImage.FI16_565_GREEN_SHIFT) + (((value.B * 31) / 255) << FreeImage.FI16_565_BLUE_SHIFT)); } } /// /// Gets or sets the red color component. /// public byte Red { get { return (byte)(((value & FreeImage.FI16_565_RED_MASK) >> FreeImage.FI16_565_RED_SHIFT) * 255 / 31); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_565_RED_MASK)) | (((value * 31) / 255) << FreeImage.FI16_565_RED_SHIFT)); } } /// /// Gets or sets the green color component. /// public byte Green { get { return (byte)(((value & FreeImage.FI16_565_GREEN_MASK) >> FreeImage.FI16_565_GREEN_SHIFT) * 255 / 63); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_565_GREEN_MASK)) | (((value * 63) / 255) << FreeImage.FI16_565_GREEN_SHIFT)); } } /// /// Gets or sets the blue color component. /// public byte Blue { get { return (byte)(((value & FreeImage.FI16_565_BLUE_MASK) >> FreeImage.FI16_565_BLUE_SHIFT) * 255 / 31); } set { this.value = (ushort)((this.value & (~FreeImage.FI16_565_BLUE_MASK)) | (((value * 31) / 255) << FreeImage.FI16_565_BLUE_SHIFT)); } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FI16RGB565)) { throw new ArgumentException("obj"); } return CompareTo((FI16RGB565)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FI16RGB565 other) { return this.Color.ToArgb().CompareTo(other.Color.ToArgb()); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return base.Equals(obj); } /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FI16RGB565 other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return FreeImage.ColorToString(Color); } } } namespace FreeImageAPI { /// /// The FIRational structure represents a fraction via two /// instances which are interpreted as numerator and denominator. /// /// /// The structure tries to approximate the value of /// when creating a new instance by using a better algorithm than FreeImage does. /// /// The structure implements the following operators: /// +, -, ++, --, ==, != , >, >==, <, <== and ~ (which switches nominator and denomiator). /// /// The structure can be converted into all .NET standard types either implicit or /// explicit. /// [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)] public struct FIRational : IConvertible, IComparable, IFormattable, IComparable, IEquatable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int numerator; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int denominator; /// /// Represents the largest possible value of . This field is constant. /// public static readonly FIRational MaxValue = new FIRational(Int32.MaxValue, 1); /// /// Represents the smallest possible value of . This field is constant. /// public static readonly FIRational MinValue = new FIRational(Int32.MinValue, 1); /// /// Represents the smallest positive value greater than zero. This field is constant. /// public static readonly FIRational Epsilon = new FIRational(1, Int32.MaxValue); /// /// Initializes a new instance based on the specified parameters. /// /// The numerator. /// The denominator. public FIRational(int n, int d) { numerator = n; denominator = d; Normalize(); } /// /// Initializes a new instance based on the specified parameters. /// /// The tag to read the data from. public unsafe FIRational(FITAG tag) { switch (FreeImage.GetTagType(tag)) { case FREE_IMAGE_MDTYPE.FIDT_SRATIONAL: int* value = (int*)FreeImage.GetTagValue(tag); numerator = (int)value[0]; denominator = (int)value[1]; Normalize(); return; default: throw new ArgumentException("tag"); } } /// /// Initializes a new instance based on the specified parameters. /// /// The value to convert into a fraction. /// /// cannot be converted into a fraction /// represented by two integer values. public FIRational(decimal value) { try { int sign = value < 0 ? -1 : 1; value = Math.Abs(value); try { int[] contFract = CreateContinuedFraction(value); CreateFraction(contFract, out numerator, out denominator); Normalize(); } catch { numerator = 0; denominator = 1; } if (Math.Abs(((decimal)numerator / (decimal)denominator) - value) > 0.0001m) { int maxDen = (Int32.MaxValue / (int)value) - 2; maxDen = maxDen < 10000 ? maxDen : 10000; ApproximateFraction(value, maxDen, out numerator, out denominator); Normalize(); if (Math.Abs(((decimal)numerator / (decimal)denominator) - value) > 0.0001m) { throw new OverflowException("Unable to convert value into a fraction"); } } numerator *= sign; Normalize(); } catch (Exception ex) { throw new OverflowException("Unable to calculate fraction.", ex); } } /// /// The numerator of the fraction. /// public int Numerator { get { return numerator; } } /// /// The denominator of the fraction. /// public int Denominator { get { return denominator; } } /// /// Returns the truncated value of the fraction. /// /// public int Truncate() { return denominator > 0 ? (int)(numerator / denominator) : 0; } /// /// Returns whether the fraction is representing an integer value. /// public bool IsInteger { get { return (denominator == 1 || (denominator != 0 && (numerator % denominator == 0)) || (denominator == 0 && numerator == 0)); } } /// /// Calculated the greatest common divisor of 'a' and 'b'. /// private static long Gcd(long a, long b) { a = Math.Abs(a); b = Math.Abs(b); long r; while (b > 0) { r = a % b; a = b; b = r; } return a; } /// /// Calculated the smallest common multiple of 'a' and 'b'. /// private static long Scm(int n, int m) { return Math.Abs((long)n * (long)m) / Gcd(n, m); } /// /// Normalizes the fraction. /// private void Normalize() { if (denominator == 0) { numerator = 0; denominator = 1; return; } if (numerator != 1 && denominator != 1) { int common = (int)Gcd(numerator, denominator); if (common != 1 && common != 0) { numerator /= common; denominator /= common; } } if (denominator < 0) { numerator *= -1; denominator *= -1; } } /// /// Normalizes a fraction. /// private static void Normalize(ref long numerator, ref long denominator) { if (denominator == 0) { numerator = 0; denominator = 1; } else if (numerator != 1 && denominator != 1) { long common = Gcd(numerator, denominator); if (common != 1) { numerator /= common; denominator /= common; } } if (denominator < 0) { numerator *= -1; denominator *= -1; } } /// /// Returns the digits after the point. /// private static int GetDigits(decimal value) { int result = 0; value -= decimal.Truncate(value); while (value != 0) { value *= 10; value -= decimal.Truncate(value); result++; } return result; } /// /// Creates a continued fraction of a decimal value. /// private static int[] CreateContinuedFraction(decimal value) { int precision = GetDigits(value); decimal epsilon = 0.0000001m; List list = new List(); value = Math.Abs(value); byte b = 0; list.Add((int)value); value -= ((int)value); while (value != 0m) { if (++b == byte.MaxValue || value < epsilon) { break; } value = 1m / value; if (Math.Abs((Math.Round(value, precision - 1) - value)) < epsilon) { value = Math.Round(value, precision - 1); } list.Add((int)value); value -= ((int)value); } return list.ToArray(); } /// /// Creates a fraction from a continued fraction. /// private static void CreateFraction(int[] continuedFraction, out int numerator, out int denominator) { numerator = 1; denominator = 0; int temp; for (int i = continuedFraction.Length - 1; i > -1; i--) { temp = numerator; numerator = continuedFraction[i] * numerator + denominator; denominator = temp; } } /// /// Tries 'brute force' to approximate with a fraction. /// private static void ApproximateFraction(decimal value, int maxDen, out int num, out int den) { num = 0; den = 0; decimal bestDifference = 1m; decimal currentDifference = -1m; int digits = GetDigits(value); if (digits <= 9) { int mul = 1; for (int i = 1; i <= digits; i++) { mul *= 10; } if (mul <= maxDen) { num = (int)(value * mul); den = mul; return; } } for (int i = 1; i <= maxDen; i++) { int numerator = (int)Math.Floor(value * (decimal)i + 0.5m); currentDifference = Math.Abs(value - (decimal)numerator / (decimal)i); if (currentDifference < bestDifference) { num = numerator; den = i; bestDifference = currentDifference; } } } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return ((IConvertible)this).ToDouble(null).ToString(); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIRational) && (this == ((FIRational)obj))); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } #region Operators /// /// Standard implementation of the operator. /// public static FIRational operator +(FIRational r1) { return r1; } /// /// Standard implementation of the operator. /// public static FIRational operator -(FIRational r1) { r1.numerator *= -1; return r1; } /// /// Returns the reciprocal value of this instance. /// public static FIRational operator ~(FIRational r1) { int temp = r1.denominator; r1.denominator = r1.numerator; r1.numerator = temp; r1.Normalize(); return r1; } /// /// Standard implementation of the operator. /// public static FIRational operator ++(FIRational r1) { checked { r1.numerator += r1.denominator; } return r1; } /// /// Standard implementation of the operator. /// public static FIRational operator --(FIRational r1) { checked { r1.numerator -= r1.denominator; } return r1; } /// /// Standard implementation of the operator. /// public static FIRational operator +(FIRational r1, FIRational r2) { long numerator = 0; long denominator = Scm(r1.denominator, r2.denominator); numerator = (r1.numerator * (denominator / r1.denominator)) + (r2.numerator * (denominator / r2.denominator)); Normalize(ref numerator, ref denominator); checked { return new FIRational((int)numerator, (int)denominator); } } /// /// Standard implementation of the operator. /// public static FIRational operator -(FIRational r1, FIRational r2) { return r1 + (-r2); } /// /// Standard implementation of the operator. /// public static FIRational operator *(FIRational r1, FIRational r2) { long numerator = r1.numerator * r2.numerator; long denominator = r1.denominator * r2.denominator; Normalize(ref numerator, ref denominator); checked { return new FIRational((int)numerator, (int)denominator); } } /// /// Standard implementation of the operator. /// public static FIRational operator /(FIRational r1, FIRational r2) { int temp = r2.denominator; r2.denominator = r2.numerator; r2.numerator = temp; return r1 * r2; } /// /// Standard implementation of the operator. /// public static FIRational operator %(FIRational r1, FIRational r2) { r2.Normalize(); if (Math.Abs(r2.numerator) < r2.denominator) return new FIRational(0, 0); int div = (int)(r1 / r2); return r1 - (r2 * div); } /// /// Standard implementation of the operator. /// public static bool operator ==(FIRational r1, FIRational r2) { r1.Normalize(); r2.Normalize(); return (r1.numerator == r2.numerator) && (r1.denominator == r2.denominator); } /// /// Standard implementation of the operator. /// public static bool operator !=(FIRational r1, FIRational r2) { return !(r1 == r2); } /// /// Standard implementation of the operator. /// public static bool operator >(FIRational r1, FIRational r2) { long denominator = Scm(r1.denominator, r2.denominator); return (r1.numerator * (denominator / r1.denominator)) > (r2.numerator * (denominator / r2.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator <(FIRational r1, FIRational r2) { long denominator = Scm(r1.denominator, r2.denominator); return (r1.numerator * (denominator / r1.denominator)) < (r2.numerator * (denominator / r2.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator >=(FIRational r1, FIRational r2) { long denominator = Scm(r1.denominator, r2.denominator); return (r1.numerator * (denominator / r1.denominator)) >= (r2.numerator * (denominator / r2.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator <=(FIRational r1, FIRational r2) { long denominator = Scm(r1.denominator, r2.denominator); return (r1.numerator * (denominator / r1.denominator)) <= (r2.numerator * (denominator / r2.denominator)); } #endregion #region Conversions /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator bool(FIRational value) { return (value.numerator != 0); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator byte(FIRational value) { return (byte)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator char(FIRational value) { return (char)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator decimal(FIRational value) { return value.denominator == 0 ? 0m : (decimal)value.numerator / (decimal)value.denominator; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator double(FIRational value) { return value.denominator == 0 ? 0d : (double)value.numerator / (double)value.denominator; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator short(FIRational value) { return (short)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator int(FIRational value) { return (int)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator long(FIRational value) { return (byte)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator float(FIRational value) { return value.denominator == 0 ? 0f : (float)value.numerator / (float)value.denominator; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator sbyte(FIRational value) { return (sbyte)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator ushort(FIRational value) { return (ushort)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator uint(FIRational value) { return (uint)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator ulong(FIRational value) { return (ulong)(double)value; } // /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIRational(bool value) { return new FIRational(value ? 1 : 0, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRational(byte value) { return new FIRational(value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRational(char value) { return new FIRational(value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIRational(decimal value) { return new FIRational(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIRational(double value) { return new FIRational((decimal)value); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIRational(short value) { return new FIRational(value, 1); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIRational(int value) { return new FIRational(value, 1); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIRational(long value) { return new FIRational((int)value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIRational(sbyte value) { return new FIRational(value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIRational(float value) { return new FIRational((decimal)value); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIRational(ushort value) { return new FIRational(value, 1); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIRational(uint value) { return new FIRational((int)value, 1); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIRational(ulong value) { return new FIRational((int)value, 1); } #endregion #region IConvertible Member TypeCode IConvertible.GetTypeCode() { return TypeCode.Double; } bool IConvertible.ToBoolean(IFormatProvider provider) { return (bool)this; } byte IConvertible.ToByte(IFormatProvider provider) { return (byte)this; } char IConvertible.ToChar(IFormatProvider provider) { return (char)this; } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return Convert.ToDateTime(((IConvertible)this).ToDouble(provider)); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return this; } double IConvertible.ToDouble(IFormatProvider provider) { return this; } short IConvertible.ToInt16(IFormatProvider provider) { return (short)this; } int IConvertible.ToInt32(IFormatProvider provider) { return (int)this; } long IConvertible.ToInt64(IFormatProvider provider) { return (long)this; } sbyte IConvertible.ToSByte(IFormatProvider provider) { return (sbyte)this; } float IConvertible.ToSingle(IFormatProvider provider) { return this; } string IConvertible.ToString(IFormatProvider provider) { return ToString(((double)this).ToString(), provider); } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return Convert.ChangeType(((IConvertible)this).ToDouble(provider), conversionType, provider); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return (ushort)this; } uint IConvertible.ToUInt32(IFormatProvider provider) { return (uint)this; } ulong IConvertible.ToUInt64(IFormatProvider provider) { return (ulong)this; } #endregion #region IComparable Member /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIRational)) { throw new ArgumentException(); } return CompareTo((FIRational)obj); } #endregion #region IFormattable Member /// /// Formats the value of the current instance using the specified format. /// /// The String specifying the format to use. /// The IFormatProvider to use to format the value. /// A String containing the value of the current instance in the specified format. public string ToString(string format, IFormatProvider formatProvider) { if (format == null) { format = ""; } return String.Format(formatProvider, format, ((IConvertible)this).ToDouble(formatProvider)); } #endregion #region IEquatable Member /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIRational other) { return (this == other); } #endregion #region IComparable Member /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIRational other) { FIRational difference = this - other; difference.Normalize(); if (difference.numerator > 0) return 1; if (difference.numerator < 0) return -1; else return 0; } #endregion } } namespace FreeImageAPI { /// /// The FIURational structure represents a fraction via two /// instances which are interpreted as numerator and denominator. /// /// /// The structure tries to approximate the value of /// when creating a new instance by using a better algorithm than FreeImage does. /// /// The structure implements the following operators: /// +, ++, --, ==, != , >, >==, <, <== and ~ (which switches nominator and denomiator). /// /// The structure can be converted into all .NET standard types either implicit or /// explicit. /// [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)] public struct FIURational : IConvertible, IComparable, IFormattable, IComparable, IEquatable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private uint numerator; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private uint denominator; /// /// Represents the largest possible value of . This field is constant. /// public static readonly FIURational MaxValue = new FIURational(UInt32.MaxValue, 1u); /// /// Represents the smallest possible value of . This field is constant. /// public static readonly FIURational MinValue = new FIURational(0u, 1u); /// /// Represents the smallest positive value greater than zero. This field is constant. /// public static readonly FIURational Epsilon = new FIURational(1u, UInt32.MaxValue); /// /// Initializes a new instance based on the specified parameters. /// /// The numerator. /// The denominator. public FIURational(uint n, uint d) { numerator = n; denominator = d; Normalize(); } /// /// Initializes a new instance based on the specified parameters. /// /// The tag to read the data from. public unsafe FIURational(FITAG tag) { switch (FreeImage.GetTagType(tag)) { case FREE_IMAGE_MDTYPE.FIDT_RATIONAL: uint* pvalue = (uint*)FreeImage.GetTagValue(tag); numerator = pvalue[0]; denominator = pvalue[1]; Normalize(); return; default: throw new ArgumentException("tag"); } } /// ///Initializes a new instance based on the specified parameters. /// /// The value to convert into a fraction. /// /// cannot be converted into a fraction /// represented by two unsigned integer values. public FIURational(decimal value) { try { if (value < 0) { throw new OverflowException("value"); } try { int[] contFract = CreateContinuedFraction(value); CreateFraction(contFract, out numerator, out denominator); Normalize(); } catch { numerator = 0; denominator = 1; } if (Math.Abs(((decimal)numerator / (decimal)denominator) - value) > 0.0001m) { int maxDen = (Int32.MaxValue / (int)value) - 2; maxDen = maxDen < 10000 ? maxDen : 10000; ApproximateFraction(value, maxDen, out numerator, out denominator); Normalize(); if (Math.Abs(((decimal)numerator / (decimal)denominator) - value) > 0.0001m) { throw new OverflowException("Unable to convert value into a fraction"); } } Normalize(); } catch (Exception ex) { throw new OverflowException("Unable to calculate fraction.", ex); } } /// /// The numerator of the fraction. /// public uint Numerator { get { return numerator; } } /// /// The denominator of the fraction. /// public uint Denominator { get { return denominator; } } /// /// Returns the truncated value of the fraction. /// /// public int Truncate() { return denominator > 0 ? (int)(numerator / denominator) : 0; } /// /// Returns whether the fraction is representing an integer value. /// public bool IsInteger { get { return (denominator == 1 || (denominator != 0 && (numerator % denominator == 0)) || (denominator == 0 && numerator == 0)); } } /// /// Calculated the greatest common divisor of 'a' and 'b'. /// private static ulong Gcd(ulong a, ulong b) { ulong r; while (b > 0) { r = a % b; a = b; b = r; } return a; } /// /// Calculated the smallest common multiple of 'a' and 'b'. /// private static ulong Scm(uint n, uint m) { return (ulong)n * (ulong)m / Gcd(n, m); } /// /// Normalizes the fraction. /// private void Normalize() { if (denominator == 0) { numerator = 0; denominator = 1; return; } if (numerator != 1 && denominator != 1) { uint common = (uint)Gcd(numerator, denominator); if (common != 1 && common != 0) { numerator /= common; denominator /= common; } } } /// /// Normalizes a fraction. /// private static void Normalize(ref ulong numerator, ref ulong denominator) { if (denominator == 0) { numerator = 0; denominator = 1; } else if (numerator != 1 && denominator != 1) { ulong common = Gcd(numerator, denominator); if (common != 1) { numerator /= common; denominator /= common; } } } /// /// Returns the digits after the point. /// private static int GetDigits(decimal value) { int result = 0; value -= decimal.Truncate(value); while (value != 0) { value *= 10; value -= decimal.Truncate(value); result++; } return result; } /// /// Creates a continued fraction of a decimal value. /// private static int[] CreateContinuedFraction(decimal value) { int precision = GetDigits(value); decimal epsilon = 0.0000001m; List list = new List(); value = Math.Abs(value); byte b = 0; list.Add((int)value); value -= ((int)value); while (value != 0m) { if (++b == byte.MaxValue || value < epsilon) { break; } value = 1m / value; if (Math.Abs((Math.Round(value, precision - 1) - value)) < epsilon) { value = Math.Round(value, precision - 1); } list.Add((int)value); value -= ((int)value); } return list.ToArray(); } /// /// Creates a fraction from a continued fraction. /// private static void CreateFraction(int[] continuedFraction, out uint numerator, out uint denominator) { numerator = 1; denominator = 0; uint temp; for (int i = continuedFraction.Length - 1; i > -1; i--) { temp = numerator; numerator = (uint)(continuedFraction[i] * numerator + denominator); denominator = temp; } } /// /// Tries 'brute force' to approximate with a fraction. /// private static void ApproximateFraction(decimal value, int maxDen, out uint num, out uint den) { num = 0; den = 0; decimal bestDifference = 1m; decimal currentDifference = -1m; int digits = GetDigits(value); if (digits <= 9) { uint mul = 1; for (int i = 1; i <= digits; i++) { mul *= 10; } if (mul <= maxDen) { num = (uint)(value * mul); den = mul; return; } } for (uint u = 1; u <= maxDen; u++) { uint numerator = (uint)Math.Floor(value * (decimal)u + 0.5m); currentDifference = Math.Abs(value - (decimal)numerator / (decimal)u); if (currentDifference < bestDifference) { num = numerator; den = u; bestDifference = currentDifference; } } } /// /// Converts the numeric value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return ((IConvertible)this).ToDouble(null).ToString(); } /// /// Tests whether the specified object is a structure /// and is equivalent to this structure. /// /// The object to test. /// true if is a structure /// equivalent to this structure; otherwise, false. public override bool Equals(object obj) { return ((obj is FIURational) && (this == ((FIURational)obj))); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return base.GetHashCode(); } #region Operators /// /// Standard implementation of the operator. /// public static FIURational operator +(FIURational value) { return value; } /// /// Returns the reciprocal value of this instance. /// public static FIURational operator ~(FIURational value) { uint temp = value.denominator; value.denominator = value.numerator; value.numerator = temp; value.Normalize(); return value; } /// /// Standard implementation of the operator. /// public static FIURational operator ++(FIURational value) { checked { value.numerator += value.denominator; } return value; } /// /// Standard implementation of the operator. /// public static FIURational operator --(FIURational value) { checked { value.numerator -= value.denominator; } return value; } /// /// Standard implementation of the operator. /// public static FIURational operator +(FIURational left, FIURational right) { ulong numerator = 0; ulong denominator = Scm(left.denominator, right.denominator); numerator = (left.numerator * (denominator / left.denominator)) + (right.numerator * (denominator / right.denominator)); Normalize(ref numerator, ref denominator); checked { return new FIURational((uint)numerator, (uint)denominator); } } /// /// Standard implementation of the operator. /// public static FIURational operator -(FIURational left, FIURational right) { checked { if (left.denominator != right.denominator) { uint denom = left.denominator; left.numerator *= right.denominator; left.denominator *= right.denominator; right.numerator *= denom; right.denominator *= denom; } left.numerator -= right.numerator; left.Normalize(); return left; } } /// /// Standard implementation of the operator. /// public static FIURational operator *(FIURational left, FIURational r2) { ulong numerator = left.numerator * r2.numerator; ulong denominator = left.denominator * r2.denominator; Normalize(ref numerator, ref denominator); checked { return new FIURational((uint)numerator, (uint)denominator); } } /// /// Standard implementation of the operator. /// public static FIURational operator /(FIURational left, FIURational right) { uint temp = right.denominator; right.denominator = right.numerator; right.numerator = temp; return left * right; } /// /// Standard implementation of the operator. /// public static FIURational operator %(FIURational left, FIURational right) { right.Normalize(); if (Math.Abs(right.numerator) < right.denominator) return new FIURational(0, 0); int div = (int)(left / right); return left - (right * div); } /// /// Standard implementation of the operator. /// public static bool operator ==(FIURational left, FIURational right) { left.Normalize(); right.Normalize(); return (left.numerator == right.numerator) && (left.denominator == right.denominator); } /// /// Standard implementation of the operator. /// public static bool operator !=(FIURational left, FIURational right) { left.Normalize(); right.Normalize(); return (left.numerator != right.numerator) || (left.denominator != right.denominator); } /// /// Standard implementation of the operator. /// public static bool operator >(FIURational left, FIURational right) { ulong denominator = Scm(left.denominator, right.denominator); return (left.numerator * (denominator / left.denominator)) > (right.numerator * (denominator / right.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator <(FIURational left, FIURational right) { ulong denominator = Scm(left.denominator, right.denominator); return (left.numerator * (denominator / left.denominator)) < (right.numerator * (denominator / right.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator >=(FIURational left, FIURational right) { ulong denominator = Scm(left.denominator, right.denominator); return (left.numerator * (denominator / left.denominator)) >= (right.numerator * (denominator / right.denominator)); } /// /// Standard implementation of the operator. /// public static bool operator <=(FIURational left, FIURational right) { ulong denominator = Scm(left.denominator, right.denominator); return (left.numerator * (denominator / left.denominator)) <= (right.numerator * (denominator / right.denominator)); } #endregion #region Conversions /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator bool(FIURational value) { return (value.numerator != 0); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator byte(FIURational value) { return (byte)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator char(FIURational value) { return (char)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator decimal(FIURational value) { return value.denominator == 0 ? 0m : (decimal)value.numerator / (decimal)value.denominator; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator double(FIURational value) { return value.denominator == 0 ? 0d : (double)value.numerator / (double)value.denominator; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator short(FIURational value) { return (short)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator int(FIURational value) { return (int)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator long(FIURational value) { return (byte)(double)value; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator float(FIURational value) { return value.denominator == 0 ? 0f : (float)value.numerator / (float)value.denominator; } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator sbyte(FIURational value) { return (sbyte)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator ushort(FIURational value) { return (ushort)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator uint(FIURational value) { return (uint)(double)value; } /// /// Converts the value of a structure to an structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator ulong(FIURational value) { return (ulong)(double)value; } // /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIURational(bool value) { return new FIURational(value ? 1u : 0u, 1u); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIURational(byte value) { return new FIURational(value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIURational(char value) { return new FIURational(value, 1); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIURational(decimal value) { return new FIURational(value); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIURational(double value) { return new FIURational((decimal)value); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIURational(short value) { return new FIURational((uint)value, 1u); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIURational(int value) { return new FIURational((uint)value, 1u); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIURational(long value) { return new FIURational((uint)value, 1u); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static implicit operator FIURational(sbyte value) { return new FIURational((uint)value, 1u); } /// /// Converts the value of a structure to a structure. /// /// A structure. /// A new instance of initialized to . public static explicit operator FIURational(float value) { return new FIURational((decimal)value); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static implicit operator FIURational(ushort value) { return new FIURational(value, 1); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIURational(uint value) { return new FIURational(value, 1u); } /// /// Converts the value of an structure to a structure. /// /// An structure. /// A new instance of initialized to . public static explicit operator FIURational(ulong value) { return new FIURational((uint)value, 1u); } #endregion #region IConvertible Member TypeCode IConvertible.GetTypeCode() { return TypeCode.Double; } bool IConvertible.ToBoolean(IFormatProvider provider) { return (bool)this; } byte IConvertible.ToByte(IFormatProvider provider) { return (byte)this; } char IConvertible.ToChar(IFormatProvider provider) { return (char)this; } DateTime IConvertible.ToDateTime(IFormatProvider provider) { return Convert.ToDateTime(((IConvertible)this).ToDouble(provider)); } decimal IConvertible.ToDecimal(IFormatProvider provider) { return this; } double IConvertible.ToDouble(IFormatProvider provider) { return this; } short IConvertible.ToInt16(IFormatProvider provider) { return (short)this; } int IConvertible.ToInt32(IFormatProvider provider) { return (int)this; } long IConvertible.ToInt64(IFormatProvider provider) { return (long)this; } sbyte IConvertible.ToSByte(IFormatProvider provider) { return (sbyte)this; } float IConvertible.ToSingle(IFormatProvider provider) { return this; } string IConvertible.ToString(IFormatProvider provider) { return ToString(((double)this).ToString(), provider); } object IConvertible.ToType(Type conversionType, IFormatProvider provider) { return Convert.ChangeType(((IConvertible)this).ToDouble(provider), conversionType, provider); } ushort IConvertible.ToUInt16(IFormatProvider provider) { return (ushort)this; } uint IConvertible.ToUInt32(IFormatProvider provider) { return (uint)this; } ulong IConvertible.ToUInt64(IFormatProvider provider) { return (ulong)this; } #endregion #region IComparable Member /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is FIURational)) { throw new ArgumentException(); } return CompareTo((FIURational)obj); } #endregion #region IFormattable Member /// /// Formats the value of the current instance using the specified format. /// /// The String specifying the format to use. /// The IFormatProvider to use to format the value. /// A String containing the value of the current instance in the specified format. public string ToString(string format, IFormatProvider formatProvider) { if (format == null) { format = ""; } return String.Format(formatProvider, format, ((IConvertible)this).ToDouble(formatProvider)); } #endregion #region IEquatable Member /// /// Tests whether the specified structure is equivalent to this structure. /// /// A structure to compare to this instance. /// true if is a structure /// equivalent to this structure; otherwise, false. public bool Equals(FIURational other) { return (this == other); } #endregion #region IComparable Member /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(FIURational other) { FIURational difference = this - other; difference.Normalize(); if (difference.numerator > 0) return 1; if (difference.numerator < 0) return -1; else return 0; } #endregion } } #endregion #region Classes namespace FreeImageAPI { /// /// Encapsulates a FreeImage-bitmap. /// [Serializable, Guid("64a4c935-b757-499c-ab8c-6110316a9e51")] public class FreeImageBitmap : MarshalByRefObject, ICloneable, IDisposable, IEnumerable, ISerializable { #region Fields /// /// Indicates whether this instance is disposed. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool disposed; /// /// Tab object. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private object tag; /// /// Object used to syncronize lock methods. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private object lockObject = new object(); /// /// Holds information used by SaveAdd() methods. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private SaveInformation saveInformation = new SaveInformation(); /// /// The stream that this instance was loaded from or /// null if it has been cloned or deserialized. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Stream stream; /// /// True if the stream must be disposed with this /// instance. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool disposeStream; /// /// The number of frames contained by a mutlipage bitmap. /// Default value is 1 and only changed if needed. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int frameCount = 1; /// /// The index of the loaded frame. /// Default value is 0 and only changed if needed. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private int frameIndex = 0; /// /// Format of the sourceimage. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private FREE_IMAGE_FORMAT originalFormat = FREE_IMAGE_FORMAT.FIF_UNKNOWN; /// /// Handle to the encapsulated FreeImage-bitmap. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private FIBITMAP dib; private const string ErrorLoadingBitmap = "Unable to load bitmap."; private const string ErrorLoadingFrame = "Unable to load frame."; private const string ErrorCreatingBitmap = "Unable to create bitmap."; private const string ErrorUnloadBitmap = "Unable to unload bitmap."; #endregion #region Constructors and Destructor /// /// Initializes a new instance of the class. /// protected FreeImageBitmap() { } /// /// Initializes a new instance of the class. /// For internal use only. /// /// The operation failed. internal protected FreeImageBitmap(FIBITMAP dib) { if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } this.dib = dib; AddMemoryPressure(); } /// /// Initializes a new instance of the class /// bases on the specified image. /// /// The original to clone from. /// The operation failed. /// is a null reference. public FreeImageBitmap(FreeImageBitmap original) { if (original == null) { throw new ArgumentNullException("original"); } original.EnsureNotDisposed(); dib = FreeImage.Clone(original.dib); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } originalFormat = original.originalFormat; AddMemoryPressure(); } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// The Size structure that represent the /// size of the new . /// The operation failed. /// is a null reference. /// /// or are less or equal zero. /// public FreeImageBitmap(FreeImageBitmap original, Size newSize) : this(original, newSize.Width, newSize.Height) { } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// Width of the new . /// Height of the new . /// The operation failed. /// is a null reference. /// /// or are less or equal zero. public FreeImageBitmap(FreeImageBitmap original, int width, int height) { if (original == null) { throw new ArgumentNullException("original"); } if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } original.EnsureNotDisposed(); dib = FreeImage.Rescale(original.dib, width, height, FREE_IMAGE_FILTER.FILTER_BICUBIC); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } originalFormat = original.originalFormat; AddMemoryPressure(); } /// /// Initializes a new instance of the class /// bases on the specified image. /// /// The original to clone from. /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. public FreeImageBitmap(Image original) : this(original as Bitmap) { } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// The Size structure that represent the /// size of the new . /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is a null reference. /// /// or are less or equal zero. /// public FreeImageBitmap(Image original, Size newSize) : this(original as Bitmap, newSize.Width, newSize.Height) { } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is a null reference. /// /// or are less or equal zero. public FreeImageBitmap(Image original, int width, int height) : this(original as Bitmap, width, height) { } /// /// Initializes a new instance of the class /// bases on the specified image. /// /// The original to clone from. /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// is a null reference. /// The operation failed. public FreeImageBitmap(Bitmap original) { if (original == null) { throw new ArgumentNullException("original"); } dib = FreeImage.CreateFromBitmap(original, true); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } originalFormat = FreeImage.GetFormat(original.RawFormat); AddMemoryPressure(); } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// The Size structure that represent the /// size of the new . /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is a null reference. /// /// or are less or equal zero. /// public FreeImageBitmap(Bitmap original, Size newSize) : this(original, newSize.Width, newSize.Height) { } /// /// Initializes a new instance of the class /// bases on the specified image with the specified size. /// /// The original to clone from. /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is a null reference. /// /// or are less or equal zero. public FreeImageBitmap(Bitmap original, int width, int height) { if (original == null) { throw new ArgumentNullException("original"); } if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } FIBITMAP temp = FreeImage.CreateFromBitmap(original, true); if (temp.IsNull) { throw new Exception(ErrorLoadingBitmap); } dib = FreeImage.Rescale(temp, width, height, FREE_IMAGE_FILTER.FILTER_BICUBIC); FreeImage.Unload(temp); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } originalFormat = FreeImage.GetFormat(original.RawFormat); AddMemoryPressure(); } /// /// Initializes a new instance of the class /// bases on the specified stream. /// /// Stream to read from. /// Ignored. /// The operation failed. /// is a null reference. /// /// You must keep the stream open for the lifetime of the . /// public FreeImageBitmap(Stream stream, bool useIcm) : this(stream) { } /// /// Initializes a new instance of the class /// bases on the specified stream. /// /// Stream to read from. /// The operation failed. /// is a null reference. /// /// You must keep the stream open for the lifetime of the . /// public FreeImageBitmap(Stream stream) : this(stream, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_LOAD_FLAGS.DEFAULT) { } /// /// Initializes a new instance of the class /// bases on the specified stream in the specified format. /// /// Stream to read from. /// Format of the image. /// The operation failed. /// is a null reference. /// /// You must keep the stream open for the lifetime of the . /// public FreeImageBitmap(Stream stream, FREE_IMAGE_FORMAT format) : this(stream, format, FREE_IMAGE_LOAD_FLAGS.DEFAULT) { } /// /// Initializes a new instance of the class /// bases on the specified stream with the specified loading flags. /// /// Stream to read from. /// Flags to enable or disable plugin-features. /// The operation failed. /// is a null reference. /// /// You must keep the stream open for the lifetime of the . /// public FreeImageBitmap(Stream stream, FREE_IMAGE_LOAD_FLAGS flags) : this(stream, FREE_IMAGE_FORMAT.FIF_UNKNOWN, flags) { } /// /// Initializes a new instance of the class /// bases on the specified stream in the specified format /// with the specified loading flags. /// /// Stream to read from. /// Format of the image. /// Flags to enable or disable plugin-features. /// The operation failed. /// is a null reference. /// /// You must keep the stream open for the lifetime of the . /// public FreeImageBitmap(Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags) { if (stream == null) { throw new ArgumentNullException("stream"); } this.stream = stream; disposeStream = false; LoadFromStream(stream, format, flags); } /// /// Initializes a new instance of the class bases on the specified file. /// /// The complete name of the file to load. /// The operation failed. /// is a null reference. /// does not exist. public FreeImageBitmap(string filename) : this(filename, FREE_IMAGE_LOAD_FLAGS.DEFAULT) { } /// /// Initializes a new instance of the class bases on the specified file. /// /// The complete name of the file to load. /// Ignored. /// The operation failed. /// is a null reference. /// does not exist. public FreeImageBitmap(string filename, bool useIcm) : this(filename) { } /// /// Initializes a new instance of the class bases on the specified file /// with the specified loading flags. /// /// The complete name of the file to load. /// Flags to enable or disable plugin-features. /// The operation failed. /// is a null reference. /// does not exist. public FreeImageBitmap(string filename, FREE_IMAGE_LOAD_FLAGS flags) : this(filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, flags) { } /// /// Initializes a new instance of the class bases on the specified file /// in the specified format. /// /// The complete name of the file to load. /// Format of the image. /// The operation failed. /// is a null reference. /// does not exist. public FreeImageBitmap(string filename, FREE_IMAGE_FORMAT format) : this(filename, format, FREE_IMAGE_LOAD_FLAGS.DEFAULT) { } /// /// Initializes a new instance of the class bases on the specified file /// in the specified format with the specified loading flags. /// /// The complete name of the file to load. /// Format of the image. /// Flags to enable or disable plugin-features. /// The operation failed. /// is a null reference. /// does not exist. public FreeImageBitmap(string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags) { if (filename == null) { throw new ArgumentNullException("filename"); } if (!File.Exists(filename)) { throw new FileNotFoundException("filename"); } saveInformation.filename = filename; stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); disposeStream = true; LoadFromStream(stream, format, flags); } /// /// Initializes a new instance of the class /// bases on the specified size. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// The operation failed. public FreeImageBitmap(int width, int height) { dib = FreeImage.Allocate( width, height, 24, FreeImage.FI_RGBA_RED_MASK, FreeImage.FI_RGBA_GREEN_MASK, FreeImage.FI_RGBA_BLUE_MASK); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified resource. /// /// The class used to extract the resource. /// The name of the resource. /// The operation failed. public FreeImageBitmap(Type type, string resource) : this(type.Module.Assembly.GetManifestResourceStream(type, resource)) { } /// /// Initializes a new instance of the class bases on the specified size /// and with the resolution of the specified object. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// The Graphics object that specifies the resolution for the new . /// The operation failed. /// is a null reference. public FreeImageBitmap(int width, int height, Graphics g) : this(width, height) { FreeImage.SetResolutionX(dib, (uint)g.DpiX); FreeImage.SetResolutionY(dib, (uint)g.DpiY); } /// /// Initializes a new instance of the class bases on the specified size and format. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// The PixelFormat enumeration for the new . /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is invalid. /// /// or are less or equal zero. public FreeImageBitmap(int width, int height, PixelFormat format) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } uint bpp, redMask, greenMask, blueMask; FREE_IMAGE_TYPE type; if (!FreeImage.GetFormatParameters(format, out type, out bpp, out redMask, out greenMask, out blueMask)) { throw new ArgumentException("format is invalid"); } dib = FreeImage.AllocateT(type, width, height, (int)bpp, redMask, greenMask, blueMask); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified size and type. /// Only non standard bitmaps are supported. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// The type of the bitmap. /// The operation failed. /// /// is FIT_BITMAP or FIT_UNKNOWN. /// is invalid. /// /// or are less or equal zero. public FreeImageBitmap(int width, int height, FREE_IMAGE_TYPE type) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } if ((type == FREE_IMAGE_TYPE.FIT_BITMAP) || (type == FREE_IMAGE_TYPE.FIT_UNKNOWN)) { throw new ArgumentException("type is invalid."); } dib = FreeImage.AllocateT(type, width, height, 0, 0u, 0u, 0u); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified size, /// pixel format and pixel data. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// Integer that specifies the byte offset between the beginning /// of one scan line and the next. This is usually (but not necessarily) /// the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) /// multiplied by the width of the bitmap. The value passed to this parameter must /// be a multiple of four.. /// The PixelFormat enumeration for the new . /// Pointer to an array of bytes that contains the pixel data. /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is invalid. /// /// or are less or equal zero. public FreeImageBitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } uint bpp, redMask, greenMask, blueMask; FREE_IMAGE_TYPE type; bool topDown = (stride > 0); stride = (stride > 0) ? stride : (stride * -1); if (!FreeImage.GetFormatParameters(format, out type, out bpp, out redMask, out greenMask, out blueMask)) { throw new ArgumentException("format is invalid."); } dib = FreeImage.ConvertFromRawBits( scan0, type, width, height, stride, bpp, redMask, greenMask, blueMask, topDown); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified size, /// pixel format and pixel data. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// Integer that specifies the byte offset between the beginning /// of one scan line and the next. This is usually (but not necessarily) /// the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) /// multiplied by the width of the bitmap. The value passed to this parameter must /// be a multiple of four.. /// The PixelFormat enumeration for the new . /// Array of bytes containing the bitmap data. /// /// Although this constructor supports creating images in both formats /// /// and , bitmaps /// created in these formats are treated like any normal 32-bit RGBA and 64-bit RGBA /// images respectively. Currently, there is no support for automatic premultiplying images in /// . /// /// The operation failed. /// is invalid. /// /// or are less or equal zero. /// is null public FreeImageBitmap(int width, int height, int stride, PixelFormat format, byte[] bits) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } if (bits == null) { throw new ArgumentNullException("bits"); } uint bpp, redMask, greenMask, blueMask; FREE_IMAGE_TYPE type; bool topDown = (stride > 0); stride = (stride > 0) ? stride : (stride * -1); if (!FreeImage.GetFormatParameters(format, out type, out bpp, out redMask, out greenMask, out blueMask)) { throw new ArgumentException("format is invalid."); } dib = FreeImage.ConvertFromRawBits( bits, type, width, height, stride, bpp, redMask, greenMask, blueMask, topDown); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified size, /// pixel format and pixel data. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// Integer that specifies the byte offset between the beginning /// of one scan line and the next. This is usually (but not necessarily) /// the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) /// multiplied by the width of the bitmap. The value passed to this parameter must /// be a multiple of four.. /// The color depth of the new /// The type for the new . /// Pointer to an array of bytes that contains the pixel data. /// The operation failed. /// is invalid. /// /// or are less or equal zero. public FreeImageBitmap(int width, int height, int stride, int bpp, FREE_IMAGE_TYPE type, IntPtr scan0) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } uint redMask, greenMask, blueMask; bool topDown = (stride > 0); stride = (stride > 0) ? stride : (stride * -1); if (!FreeImage.GetTypeParameters(type, bpp, out redMask, out greenMask, out blueMask)) { throw new ArgumentException("bpp and type are invalid or not supported."); } dib = FreeImage.ConvertFromRawBits( scan0, type, width, height, stride, (uint)bpp, redMask, greenMask, blueMask, topDown); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class bases on the specified size, /// pixel format and pixel data. /// /// The width, in pixels, of the new . /// The height, in pixels, of the new . /// Integer that specifies the byte offset between the beginning /// of one scan line and the next. This is usually (but not necessarily) /// the number of bytes in the pixel format (for example, 2 for 16 bits per pixel) /// multiplied by the width of the bitmap. The value passed to this parameter must /// be a multiple of four.. /// The color depth of the new /// The type for the new . /// Array of bytes containing the bitmap data. /// The operation failed. /// is invalid. /// /// or are less or equal zero. /// is null public FreeImageBitmap(int width, int height, int stride, int bpp, FREE_IMAGE_TYPE type, byte[] bits) { if (width <= 0) { throw new ArgumentOutOfRangeException("width"); } if (height <= 0) { throw new ArgumentOutOfRangeException("height"); } if (bits == null) { throw new ArgumentNullException("bits"); } uint redMask, greenMask, blueMask; bool topDown = (stride > 0); stride = (stride > 0) ? stride : (stride * -1); if (!FreeImage.GetTypeParameters(type, bpp, out redMask, out greenMask, out blueMask)) { throw new ArgumentException("bpp and type are invalid or not supported."); } dib = FreeImage.ConvertFromRawBits( bits, type, width, height, stride, (uint)bpp, redMask, greenMask, blueMask, topDown); if (dib.IsNull) { throw new Exception(ErrorCreatingBitmap); } AddMemoryPressure(); } /// /// Initializes a new instance of the class. /// /// The operation failed. /// The operation failed. public FreeImageBitmap(SerializationInfo info, StreamingContext context) { try { byte[] data = (byte[])info.GetValue("Bitmap Data", typeof(byte[])); if ((data != null) && (data.Length > 0)) { MemoryStream memory = new MemoryStream(data); FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_TIFF; dib = FreeImage.LoadFromStream(memory, ref format); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } AddMemoryPressure(); } } catch (Exception ex) { throw new SerializationException("Deserialization failed.", ex); } } /// /// Frees all managed and unmanaged ressources. /// ~FreeImageBitmap() { Dispose(false); } #endregion #region Operators /// /// Converts a instance to a instance. /// /// A instance. /// A new instance of initialized to . /// /// The explicit conversion from into Bitmap /// allows to create an instance on the fly and use it as if /// was a Bitmap. This way it can be directly used with a /// PixtureBox for example without having to call any /// conversion operations. /// public static explicit operator Bitmap(FreeImageBitmap value) { return value.ToBitmap(); } /// /// Converts a instance to a instance. /// /// A instance. /// A new instance of initialized to . /// /// The explicit conversion from into /// allows to create an instance on the fly to perform /// image processing operations and converting it back. /// public static explicit operator FreeImageBitmap(Bitmap value) { return new FreeImageBitmap(value); } /// /// Determines whether two specified objects have the same value. /// /// A or a null reference (Nothing in Visual Basic). /// A or a null reference (Nothing in Visual Basic). /// /// true if the value of left is the same as the value of right; otherwise, false. /// public static bool operator ==(FreeImageBitmap left, FreeImageBitmap right) { if (object.ReferenceEquals(left, right)) { return true; } else if (object.ReferenceEquals(left, null) || object.ReferenceEquals(right, null)) { return false; } else { left.EnsureNotDisposed(); right.EnsureNotDisposed(); return FreeImage.Compare(left.dib, right.dib, FREE_IMAGE_COMPARE_FLAGS.COMPLETE); } } /// /// Determines whether two specified objects have different values. /// /// A or a null reference (Nothing in Visual Basic). /// A or a null reference (Nothing in Visual Basic). /// /// true if the value of left is different from the value of right; otherwise, false. /// public static bool operator !=(FreeImageBitmap left, FreeImageBitmap right) { return (!(left == right)); } #endregion #region Properties /// /// Type of the bitmap. /// public FREE_IMAGE_TYPE ImageType { get { EnsureNotDisposed(); return FreeImage.GetImageType(dib); } } /// /// Number of palette entries. /// public int ColorsUsed { get { EnsureNotDisposed(); return (int)FreeImage.GetColorsUsed(dib); } } /// /// The number of unique colors actually used by the bitmap. This might be different from /// what ColorsUsed returns, which actually returns the palette size for palletised images. /// Works for FIT_BITMAP type bitmaps only. /// public int UniqueColors { get { EnsureNotDisposed(); return FreeImage.GetUniqueColors(dib); } } /// /// The size of one pixel in the bitmap in bits. /// public int ColorDepth { get { EnsureNotDisposed(); return (int)FreeImage.GetBPP(dib); } } /// /// Width of the bitmap in pixel units. /// public int Width { get { EnsureNotDisposed(); return (int)FreeImage.GetWidth(dib); } } /// /// Height of the bitmap in pixel units. /// public int Height { get { EnsureNotDisposed(); return (int)FreeImage.GetHeight(dib); } } /// /// Returns the width of the bitmap in bytes, rounded to the next 32-bit boundary. /// public int Pitch { get { EnsureNotDisposed(); return (int)FreeImage.GetPitch(dib); } } /// /// Size of the bitmap in memory. /// public int DataSize { get { EnsureNotDisposed(); return (int)FreeImage.GetDIBSize(dib); } } /// /// Returns a structure that represents the palette of a FreeImage bitmap. /// /// is false. public Palette Palette { get { EnsureNotDisposed(); if (HasPalette) { return new Palette(dib); } throw new InvalidOperationException("This bitmap does not have a palette."); } } /// /// Gets whether the bitmap is RGB 555. /// public bool IsRGB555 { get { EnsureNotDisposed(); return FreeImage.IsRGB555(dib); } } /// /// Gets whether the bitmap is RGB 565. /// public bool IsRGB565 { get { EnsureNotDisposed(); return FreeImage.IsRGB565(dib); } } /// /// Gets the horizontal resolution, in pixels per inch, of this . /// public float HorizontalResolution { get { EnsureNotDisposed(); return (float)FreeImage.GetResolutionX(dib); } private set { EnsureNotDisposed(); FreeImage.SetResolutionX(dib, (uint)value); } } /// /// Gets the vertical resolution, in pixels per inch, of this . /// public float VerticalResolution { get { EnsureNotDisposed(); return (float)FreeImage.GetResolutionY(dib); } private set { EnsureNotDisposed(); FreeImage.SetResolutionY(dib, (uint)value); } } /// /// Returns the structure of this . /// public BITMAPINFOHEADER InfoHeader { get { EnsureNotDisposed(); return FreeImage.GetInfoHeaderEx(dib); } } /// /// Returns the structure of a this . /// public BITMAPINFO Info { get { EnsureNotDisposed(); return FreeImage.GetInfoEx(dib); } } /// /// Investigates the color type of this /// by reading the bitmaps pixel bits and analysing them. /// public FREE_IMAGE_COLOR_TYPE ColorType { get { EnsureNotDisposed(); return FreeImage.GetColorType(dib); } } /// /// Bit pattern describing the red color component of a pixel in this . /// public uint RedMask { get { EnsureNotDisposed(); return FreeImage.GetRedMask(dib); } } /// /// Bit pattern describing the green color component of a pixel in this . /// public uint GreenMask { get { EnsureNotDisposed(); return FreeImage.GetGreenMask(dib); } } /// /// Bit pattern describing the blue color component of a pixel in this . /// public uint BlueMask { get { EnsureNotDisposed(); return FreeImage.GetBlueMask(dib); } } /// /// Number of transparent colors in a palletised . /// public int TransparencyCount { get { EnsureNotDisposed(); return (int)FreeImage.GetTransparencyCount(dib); } } /// /// Get or sets transparency table of this . /// public byte[] TransparencyTable { get { EnsureNotDisposed(); return FreeImage.GetTransparencyTableEx(dib); } set { EnsureNotDisposed(); FreeImage.SetTransparencyTable(dib, value); } } /// /// Gets or sets whether this is transparent. /// public bool IsTransparent { get { EnsureNotDisposed(); return FreeImage.IsTransparent(dib); } set { EnsureNotDisposed(); FreeImage.SetTransparent(dib, value); } } /// /// Gets whether this has a file background color. /// public bool HasBackgroundColor { get { EnsureNotDisposed(); return FreeImage.HasBackgroundColor(dib); } } /// /// Gets or sets the background color of this . /// In case the value is null, the background color is removed. /// /// Get: There is no background color available. /// Set: Setting background color failed. public Color? BackgroundColor { get { EnsureNotDisposed(); if (!FreeImage.HasBackgroundColor(dib)) { throw new InvalidOperationException("No background color available."); } RGBQUAD rgbq; FreeImage.GetBackgroundColor(dib, out rgbq); return rgbq.Color; } set { EnsureNotDisposed(); if (!FreeImage.SetBackgroundColor(dib, (value.HasValue ? new RGBQUAD[] { value.Value } : null))) { throw new Exception("Setting background color failed."); } } } /// /// Pointer to the data-bits of this . /// public IntPtr Bits { get { EnsureNotDisposed(); return FreeImage.GetBits(dib); } } /// /// Width, in bytes, of this . /// public int Line { get { EnsureNotDisposed(); return (int)FreeImage.GetLine(dib); } } /// /// Pointer to the scanline of the top most pixel row of this . /// public IntPtr Scan0 { get { EnsureNotDisposed(); return FreeImage.GetScanLine(dib, (int)(FreeImage.GetHeight(dib) - 1)); } } /// /// Width, in bytes, of this . /// In case this is top down Stride will be positive, else negative. /// public int Stride { get { return -Line; } } /// /// Gets attribute flags for the pixel data of this . /// public unsafe int Flags { get { EnsureNotDisposed(); int result = 0; byte alpha; int cd = ColorDepth; if ((cd == 32) || (FreeImage.GetTransparencyCount(dib) != 0)) { result += (int)ImageFlags.HasAlpha; } if (cd == 32) { uint width = FreeImage.GetWidth(dib); uint height = FreeImage.GetHeight(dib); for (int y = 0; y < height; y++) { RGBQUAD* scanline = (RGBQUAD*)FreeImage.GetScanLine(dib, y); for (int x = 0; x < width; x++) { alpha = scanline[x].Color.A; if (alpha != byte.MinValue && alpha != byte.MaxValue) { result += (int)ImageFlags.HasTranslucent; y = (int)height; break; } } } } else if (FreeImage.GetTransparencyCount(dib) != 0) { byte[] transTable = FreeImage.GetTransparencyTableEx(dib); for (int i = 0; i < transTable.Length; i++) { if (transTable[i] != byte.MinValue && transTable[i] != byte.MaxValue) { result += (int)ImageFlags.HasTranslucent; break; } } } if (FreeImage.GetICCProfileEx(dib).IsCMYK) { result += (int)ImageFlags.ColorSpaceCmyk; } else { result += (int)ImageFlags.ColorSpaceRgb; } if (FreeImage.GetColorType(dib) == FREE_IMAGE_COLOR_TYPE.FIC_MINISBLACK || FreeImage.GetColorType(dib) == FREE_IMAGE_COLOR_TYPE.FIC_MINISWHITE) { result += (int)ImageFlags.ColorSpaceGray; } if (originalFormat == FREE_IMAGE_FORMAT.FIF_BMP || originalFormat == FREE_IMAGE_FORMAT.FIF_FAXG3 || originalFormat == FREE_IMAGE_FORMAT.FIF_ICO || originalFormat == FREE_IMAGE_FORMAT.FIF_JPEG || originalFormat == FREE_IMAGE_FORMAT.FIF_PCX || originalFormat == FREE_IMAGE_FORMAT.FIF_PNG || originalFormat == FREE_IMAGE_FORMAT.FIF_PSD || originalFormat == FREE_IMAGE_FORMAT.FIF_TIFF) { result += (int)ImageFlags.HasRealDpi; } return result; } } /// /// Gets the width and height of this . /// public SizeF PhysicalDimension { get { EnsureNotDisposed(); return new SizeF((float)FreeImage.GetWidth(dib), (float)FreeImage.GetHeight(dib)); } } /// /// Gets the pixel format for this . /// public PixelFormat PixelFormat { get { EnsureNotDisposed(); return FreeImage.GetPixelFormat(dib); } } /// /// Gets IDs of the property items stored in this . /// public int[] PropertyIdList { get { EnsureNotDisposed(); List list = new List(); ImageMetadata metaData = new ImageMetadata(dib, true); foreach (MetadataModel metadataModel in metaData) { foreach (MetadataTag metadataTag in metadataModel) { list.Add(metadataTag.ID); } } return list.ToArray(); } } /// /// Gets all the property items (pieces of metadata) stored in this . /// public PropertyItem[] PropertyItems { get { EnsureNotDisposed(); List list = new List(); ImageMetadata metaData = new ImageMetadata(dib, true); foreach (MetadataModel metadataModel in metaData) { foreach (MetadataTag metadataTag in metadataModel) { list.Add(metadataTag.GetPropertyItem()); } } return list.ToArray(); } } /// /// Gets the format of this . /// public ImageFormat RawFormat { get { EnsureNotDisposed(); Attribute guidAttribute = Attribute.GetCustomAttribute( typeof(FreeImageBitmap), typeof(System.Runtime.InteropServices.GuidAttribute) ); return (guidAttribute == null) ? null : new ImageFormat(new Guid(((GuidAttribute)guidAttribute).Value)); } } /// /// Gets the width and height, in pixels, of this . /// public Size Size { get { EnsureNotDisposed(); return new Size(Width, Height); } } /// /// Gets or sets an object that provides additional data about the . /// public Object Tag { get { EnsureNotDisposed(); return tag; } set { EnsureNotDisposed(); tag = value; } } /// /// Gets whether this has been disposed. /// public bool IsDisposed { get { return disposed; } } /// /// Gets a new instance of a metadata representing class. /// public ImageMetadata Metadata { get { EnsureNotDisposed(); return new ImageMetadata(dib, true); } } /// /// Gets or sets the comment of this . /// Supported formats are JPEG, PNG and GIF. /// public string Comment { get { EnsureNotDisposed(); return FreeImage.GetImageComment(dib); } set { EnsureNotDisposed(); FreeImage.SetImageComment(dib, value); } } /// /// Returns whether this has a palette. /// public bool HasPalette { get { EnsureNotDisposed(); return (FreeImage.GetPalette(dib) != IntPtr.Zero); } } /// /// Gets or sets the entry used as transparent color in this . /// Only works for 1-, 4- and 8-bpp. /// public int TransparentIndex { get { EnsureNotDisposed(); return FreeImage.GetTransparentIndex(dib); } set { EnsureNotDisposed(); FreeImage.SetTransparentIndex(dib, value); } } /// /// Gets the number of frames in this . /// public int FrameCount { get { EnsureNotDisposed(); return frameCount; } } /// /// Gets the ICCProfile structure of this . /// public FIICCPROFILE ICCProfile { get { EnsureNotDisposed(); return FreeImage.GetICCProfileEx(dib); } } /// /// Gets the format of the original image in case /// this was loaded from a file or stream. /// public FREE_IMAGE_FORMAT ImageFormat { get { EnsureNotDisposed(); return originalFormat; } } /// /// Gets the encapsulated FIBITMAP. /// internal FIBITMAP Dib { get { EnsureNotDisposed(); return dib; } } #endregion #region Methods /// /// Gets the bounds of this in the specified unit. /// /// One of the values indicating /// the unit of measure for the bounding rectangle. /// The that represents the bounds of this /// , in the specified unit. public RectangleF GetBounds(ref GraphicsUnit pageUnit) { EnsureNotDisposed(); pageUnit = GraphicsUnit.Pixel; return new RectangleF( 0f, 0f, (float)FreeImage.GetWidth(dib), (float)FreeImage.GetHeight(dib)); } /// /// Gets the specified property item from this . /// /// The ID of the property item to get. /// The this method gets. public PropertyItem GetPropertyItem(int propid) { EnsureNotDisposed(); ImageMetadata metadata = new ImageMetadata(dib, true); foreach (MetadataModel metadataModel in metadata) { foreach (MetadataTag tag in metadataModel) { if (tag.ID == propid) { return tag.GetPropertyItem(); } } } return null; } /// /// Returns a thumbnail for this . /// /// The width, in pixels, of the requested thumbnail image. /// The height, in pixels, of the requested thumbnail image. /// Ignored. /// Ignored. /// A that represents the thumbnail. public FreeImageBitmap GetThumbnailImage(int thumbWidth, int thumbHeight, Image.GetThumbnailImageAbort callback, IntPtr callBackData) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.Rescale( dib, thumbWidth, thumbHeight, FREE_IMAGE_FILTER.FILTER_BICUBIC); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Returns a thumbnail for this , keeping aspect ratio. /// defines the maximum width or height /// of the thumbnail. /// /// Thumbnail square size. /// When true HDR images are transperantly /// converted to standard images. /// The thumbnail in a new instance. public FreeImageBitmap GetThumbnailImage(int maxPixelSize, bool convert) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.MakeThumbnail(dib, maxPixelSize, convert); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Converts this instance to a instance. /// /// A new instance of initialized this instance. public Bitmap ToBitmap() { EnsureNotDisposed(); return FreeImage.GetBitmap(dib, true); } /// /// Returns an instance of , representing the scanline /// specified by of this . /// Since FreeImage bitmaps are always bottum up aligned, keep in mind that scanline 0 is the /// bottom-most line of the image. /// /// Number of the scanline to retrieve. /// An instance of representing the /// th scanline. /// /// List of return-types of T: /// /// Color Depth / TypeResult Type /// 1 () /// 4 () /// 8 () /// 16 () /// 16 - 555 () /// 16 - 565 () /// 24 () /// 32 () /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// FreeImageBitmap bitmap = new FreeImageBitmap(@"C:\Pictures\picture.bmp"); /// if (bitmap.ColorDepth == 32) /// { /// Scanline<RGBQUAD> scanline = bitmap.GetScanline<RGBQUAD>(0); /// foreach (RGBQUAD pixel in scanline) /// { /// Console.WriteLine(pixel); /// } /// } /// /// /// /// The bitmap's type or color depth are not supported. /// /// /// is no valid value. /// public Scanline GetScanline(int scanline) where T : struct { EnsureNotDisposed(); return new Scanline(dib, scanline); } /// /// Returns an instance of , representing the scanline /// specified by of this . /// Since FreeImage bitmaps are always bottum up aligned, keep in mind that scanline 0 is the /// bottom-most line of the image. /// /// Number of the scanline to retrieve. /// An instance of representing the /// th scanline. /// /// List of return-types of T: /// /// Color Depth / TypeResult Type /// 1 () /// 4 () /// 8 () /// 16 () /// 16 - 555 () /// 16 - 565 () /// 24 () /// 32 () /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// FreeImageBitmap bitmap = new FreeImageBitmap(@"C:\Pictures\picture.bmp"); /// if (bitmap.ColorDepth == 32) /// { /// Scanline<RGBQUAD> scanline = (Scanline<RGBQUAD>)bitmap.GetScanline(0); /// foreach (RGBQUAD pixel in scanline) /// { /// Console.WriteLine(pixel); /// } /// } /// /// /// /// The type of the bitmap or color depth are not supported. /// /// /// is no valid value. /// public object GetScanline(int scanline) { EnsureNotDisposed(); object result = null; int width = (int)FreeImage.GetWidth(dib); switch (FreeImage.GetImageType(dib)) { case FREE_IMAGE_TYPE.FIT_BITMAP: switch (FreeImage.GetBPP(dib)) { case 1u: result = new Scanline(dib, scanline, width); break; case 4u: result = new Scanline(dib, scanline, width); break; case 8u: result = new Scanline(dib, scanline, width); break; case 16u: if ((RedMask == FreeImage.FI16_555_RED_MASK) && (GreenMask == FreeImage.FI16_555_GREEN_MASK) && (BlueMask == FreeImage.FI16_555_BLUE_MASK)) { result = new Scanline(dib, scanline, width); } else if ((RedMask == FreeImage.FI16_565_RED_MASK) && (GreenMask == FreeImage.FI16_565_GREEN_MASK) && (BlueMask == FreeImage.FI16_565_BLUE_MASK)) { result = new Scanline(dib, scanline, width); } else { result = new Scanline(dib, scanline, width); } break; case 24u: result = new Scanline(dib, scanline, width); break; case 32u: result = new Scanline(dib, scanline, width); break; default: throw new ArgumentException("Color depth is not supported."); } break; case FREE_IMAGE_TYPE.FIT_COMPLEX: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_DOUBLE: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_FLOAT: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_INT16: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_INT32: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_RGB16: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_RGBA16: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_RGBAF: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_RGBF: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_UINT16: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_UINT32: result = new Scanline(dib, scanline, width); break; case FREE_IMAGE_TYPE.FIT_UNKNOWN: default: throw new ArgumentException("Type is not supported."); } return result; } /// /// Returns a pointer to the specified scanline. /// Due to FreeImage bitmaps are bottum up, /// scanline 0 is the most bottom line of the image. /// /// Number of the scanline. /// Pointer to the scanline. public IntPtr GetScanlinePointer(int scanline) { EnsureNotDisposed(); return FreeImage.GetScanLine(dib, scanline); } /// /// Returns a list of structures, representing the scanlines of this . /// Due to FreeImage bitmaps are bottum up, scanline 0 is the /// bottom-most line of the image. /// Each color depth has a different representing structure due to different memory layouts. /// /// /// List of return-types of T: /// /// Color Depth / TypeResult Type of IEnmuerable<Scanline<T>> /// 1 () /// 4 () /// 8 () /// 16 () /// 16 - 555 () /// 16 - 565 () /// 24 () /// 32 () /// /// /// /// /// /// /// /// /// /// /// /// /// public IList GetScanlines() { EnsureNotDisposed(); int height = (int)FreeImage.GetHeight(dib); IList list; switch (FreeImage.GetImageType(dib)) { case FREE_IMAGE_TYPE.FIT_BITMAP: switch (FreeImage.GetBPP(dib)) { case 1u: list = new List>(height); break; case 4u: list = new List>(height); break; case 8u: list = new List>(height); break; case 16u: if (FreeImage.IsRGB555(dib)) { list = new List>(height); } else if (FreeImage.IsRGB565(dib)) { list = new List>(height); } else { list = new List>(height); } break; case 24u: list = new List>(height); break; case 32u: list = new List>(height); break; default: throw new ArgumentException("Color depth is not supported."); } break; case FREE_IMAGE_TYPE.FIT_COMPLEX: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_DOUBLE: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_FLOAT: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_INT16: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_INT32: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_RGB16: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_RGBA16: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_RGBAF: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_RGBF: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_UINT16: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_UINT32: list = new List>(height); break; case FREE_IMAGE_TYPE.FIT_UNKNOWN: default: throw new ArgumentException("Type is not supported."); } for (int i = 0; i < height; i++) { list.Add(GetScanline(i)); } return list; } /// /// Removes the specified property item from this . /// /// The ID of the property item to remove. public void RemovePropertyItem(int propid) { EnsureNotDisposed(); ImageMetadata mdata = new ImageMetadata(dib, true); foreach (MetadataModel model in mdata) { foreach (MetadataTag tag in model) { if (tag.ID == propid) { model.RemoveTag(tag.Key); return; } } } } /// /// This method rotates, flips, or rotates and flips this . /// /// A RotateFlipType member /// that specifies the type of rotation and flip to apply to this . public void RotateFlip(RotateFlipType rotateFlipType) { EnsureNotDisposed(); FIBITMAP newDib = new FIBITMAP(); uint bpp = FreeImage.GetBPP(dib); switch (rotateFlipType) { case RotateFlipType.RotateNoneFlipX: FreeImage.FlipHorizontal(dib); break; case RotateFlipType.RotateNoneFlipY: FreeImage.FlipVertical(dib); break; case RotateFlipType.RotateNoneFlipXY: FreeImage.FlipHorizontal(dib); FreeImage.FlipVertical(dib); break; case RotateFlipType.Rotate90FlipNone: newDib = (bpp == 4u) ? FreeImage.Rotate4bit(dib, 90d) : FreeImage.Rotate(dib, 90d); break; case RotateFlipType.Rotate90FlipX: newDib = (bpp == 4u) ? FreeImage.Rotate4bit(dib, 90d) : FreeImage.Rotate(dib, 90d); FreeImage.FlipHorizontal(newDib); break; case RotateFlipType.Rotate90FlipY: newDib = (bpp == 4u) ? FreeImage.Rotate4bit(dib, 90d) : FreeImage.Rotate(dib, 90d); FreeImage.FlipVertical(newDib); break; case RotateFlipType.Rotate90FlipXY: newDib = (bpp == 4u) ? FreeImage.Rotate4bit(dib, 90d) : FreeImage.Rotate(dib, 90d); FreeImage.FlipHorizontal(newDib); FreeImage.FlipVertical(newDib); break; case RotateFlipType.Rotate180FlipXY: newDib = FreeImage.Clone(dib); break; } ReplaceDib(newDib); } /// /// Copies the metadata from another . /// /// The bitmap to read the metadata from. /// /// is a null reference. /// public void CloneMetadataFrom(FreeImageBitmap bitmap) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } EnsureNotDisposed(); bitmap.EnsureNotDisposed(); FreeImage.CloneMetadata(dib, bitmap.dib); } /// /// Copies the metadata from another using /// the provided options. /// /// The bitmap to read the metadata from. /// Specifies the way the metadata is copied. /// /// is a null reference. /// public void CloneMetadataFrom(FreeImageBitmap bitmap, FREE_IMAGE_METADATA_COPY flags) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } EnsureNotDisposed(); bitmap.EnsureNotDisposed(); FreeImage.CloneMetadataEx(bitmap.dib, dib, flags); } /// /// Saves this to the specified file. /// /// A string that contains the name of the file to which /// to save this . /// is null or empty. /// Saving the image failed. public void Save(string filename) { Save(filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Saves this to the specified file in the specified format. /// /// A string that contains the name of the file to which /// to save this . /// An that specifies the format of the saved image. /// is null or empty. /// Saving the image failed. public void Save(string filename, FREE_IMAGE_FORMAT format) { Save(filename, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Saves this to the specified file in the specified format /// using the specified saving flags. /// /// A string that contains the name of the file to which /// to save this . /// An that specifies the format of the saved image. /// Flags to enable or disable plugin-features. /// is null or empty. /// Saving the image failed. public void Save(string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags) { EnsureNotDisposed(); if (string.IsNullOrEmpty(filename)) { throw new ArgumentException("filename"); } if (!FreeImage.SaveEx(dib, filename, format, flags)) { throw new Exception("Unable to save bitmap"); } saveInformation.filename = filename; saveInformation.format = format; saveInformation.saveFlags = flags; } /// /// Saves this to the specified stream in the specified format. /// /// The stream where this will be saved. /// An that specifies the format of the saved image. /// is a null reference. /// Saving the image failed. public void Save(Stream stream, FREE_IMAGE_FORMAT format) { Save(stream, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Saves this to the specified stream in the specified format /// using the specified saving flags. /// /// The stream where this will be saved. /// An that specifies the format of the saved image. /// Flags to enable or disable plugin-features. /// is a null reference. /// Saving the image failed. public void Save(Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags) { EnsureNotDisposed(); if (stream == null) { throw new ArgumentNullException("stream"); } if (!FreeImage.SaveToStream(dib, stream, format, flags)) { throw new Exception("Unable to save bitmap"); } saveInformation.filename = null; } /// /// Adds a frame to the file specified in a previous call to the /// method. /// /// /// This instance has not been saved to a file using Save(...) before. public void SaveAdd() { SaveAdd(this); } /// /// Adds a frame to the file specified in a previous call to the method. /// /// The position at which the frame should be inserted. /// /// This instance has not yet been saved to a file using the Save(...) method. /// is out of range. public void SaveAdd(int insertPosition) { SaveAdd(this, insertPosition); } /// /// Adds a frame to the file specified in a previous call to the method. /// /// A that contains the frame to add. /// /// This instance has not yet been saved to a file using the Save(...) method. public void SaveAdd(FreeImageBitmap bitmap) { if (saveInformation.filename == null) { throw new InvalidOperationException("This operation requires a previous call of Save()."); } SaveAdd( saveInformation.filename, bitmap, saveInformation.format, saveInformation.loadFlags, saveInformation.saveFlags); } /// /// Adds a frame to the file specified in a previous call to the method. /// /// A that contains the frame to add. /// The position at which the frame should be inserted. /// /// This instance has not yet been saved to a file using the Save(...) method. /// is out of range. public void SaveAdd(FreeImageBitmap bitmap, int insertPosition) { if (saveInformation.filename == null) { throw new InvalidOperationException("This operation requires a previous call of Save()."); } SaveAdd( saveInformation.filename, bitmap, insertPosition, saveInformation.format, saveInformation.loadFlags, saveInformation.saveFlags); } /// /// Adds a frame to the file specified. /// /// File to add this frame to. /// is a null reference. /// does not exist. /// Saving the image has failed. public void SaveAdd(string filename) { SaveAdd( filename, this, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_LOAD_FLAGS.DEFAULT, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Adds a frame to the file specified. /// /// File to add this frame to. /// The position at which the frame should be inserted. /// is a null reference. /// does not exist. /// Saving the image has failed. /// is out of range. public void SaveAdd(string filename, int insertPosition) { SaveAdd( filename, this, insertPosition, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_LOAD_FLAGS.DEFAULT, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Adds a frame to the file specified using the specified parameters. /// /// File to add this frame to. /// Format of the image. /// Flags to enable or disable plugin-features. /// Flags to enable or disable plugin-features. /// is a null reference. /// does not exist. /// Saving the image has failed. public void SaveAdd( string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS loadFlags, FREE_IMAGE_SAVE_FLAGS saveFlags) { SaveAdd( filename, this, format, loadFlags, saveFlags); } /// /// Adds a frame to the file specified using the specified parameters. /// /// File to add this frame to. /// The position at which the frame should be inserted. /// Format of the image. /// Flags to enable or disable plugin-features. /// Flags to enable or disable plugin-features. /// is a null reference. /// does not exist. /// Saving the image has failed. /// is out of range. public void SaveAdd( string filename, int insertPosition, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS loadFlags, FREE_IMAGE_SAVE_FLAGS saveFlags) { SaveAdd( filename, this, insertPosition, format, loadFlags, saveFlags); } /// /// Selects the frame specified by the index. /// /// The index of the active frame. /// /// is out of range. /// The operation failed. /// The source of the bitmap is not available. /// public void SelectActiveFrame(int frameIndex) { EnsureNotDisposed(); if ((frameIndex < 0) || (frameIndex >= frameCount)) { throw new ArgumentOutOfRangeException("frameIndex"); } if (frameIndex != this.frameIndex) { if (stream == null) { throw new InvalidOperationException("No source available."); } FREE_IMAGE_FORMAT format = originalFormat; FIMULTIBITMAP mdib = FreeImage.OpenMultiBitmapFromStream(stream, ref format, saveInformation.loadFlags); if (mdib.IsNull) throw new Exception(ErrorLoadingBitmap); try { if (frameIndex >= FreeImage.GetPageCount(mdib)) { throw new ArgumentOutOfRangeException("frameIndex"); } FIBITMAP newDib = FreeImage.LockPage(mdib, frameIndex); if (newDib.IsNull) { throw new Exception(ErrorLoadingFrame); } try { FIBITMAP clone = FreeImage.Clone(newDib); if (clone.IsNull) { throw new Exception(ErrorCreatingBitmap); } ReplaceDib(clone); } finally { if (!newDib.IsNull) { FreeImage.UnlockPage(mdib, newDib, false); } } } finally { if (!FreeImage.CloseMultiBitmapEx(ref mdib)) { throw new Exception(ErrorUnloadBitmap); } } this.frameIndex = frameIndex; } } /// /// Creates a GDI bitmap object from this . /// /// A handle to the GDI bitmap object that this method creates. public IntPtr GetHbitmap() { EnsureNotDisposed(); return FreeImage.GetHbitmap(dib, IntPtr.Zero, false); } /// /// Creates a GDI bitmap object from this . /// /// A structure that specifies the background color. /// This parameter is ignored if the bitmap is totally opaque. /// A handle to the GDI bitmap object that this method creates. public IntPtr GetHbitmap(Color background) { EnsureNotDisposed(); using (FreeImageBitmap temp = new FreeImageBitmap(this)) { temp.BackgroundColor = background; return temp.GetHbitmap(); } } /// /// Returns the handle to an icon. /// /// A Windows handle to an icon with the same image as this . public IntPtr GetHicon() { EnsureNotDisposed(); using (Bitmap bitmap = FreeImage.GetBitmap(dib, true)) { return bitmap.GetHicon(); } } /// /// Creates a GDI bitmap object from this with the same /// color depth as the primary device. /// /// A handle to the GDI bitmap object that this method creates. public IntPtr GetHbitmapForDevice() { EnsureNotDisposed(); return FreeImage.GetBitmapForDevice(dib, IntPtr.Zero, false); } /// /// Gets the of the specified pixel in this . /// /// The x-coordinate of the pixel to retrieve. /// The y-coordinate of the pixel to retrieve. /// A structure that represents the color of the specified pixel. /// The operation failed. /// The type of this bitmap is not supported. public unsafe Color GetPixel(int x, int y) { EnsureNotDisposed(); if (FreeImage.GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) { if (ColorDepth == 16 || ColorDepth == 24 || ColorDepth == 32) { RGBQUAD rgbq; if (!FreeImage.GetPixelColor(dib, (uint)x, (uint)y, out rgbq)) { throw new Exception("FreeImage.GetPixelColor() failed"); } return rgbq.Color; } else if (ColorDepth == 1 || ColorDepth == 4 || ColorDepth == 8) { byte index; if (!FreeImage.GetPixelIndex(dib, (uint)x, (uint)y, out index)) { throw new Exception("FreeImage.GetPixelIndex() failed"); } RGBQUAD* palette = (RGBQUAD*)FreeImage.GetPalette(dib); return palette[index].Color; } } throw new NotSupportedException("The type of the image is not supported"); } /// /// Makes the default transparent color transparent for this . /// public void MakeTransparent() { EnsureNotDisposed(); MakeTransparent(Color.Transparent); } /// /// Makes the specified color transparent for this . /// /// The structure that represents /// the color to make transparent. /// /// This method is not implemented. public void MakeTransparent(Color transparentColor) { EnsureNotDisposed(); throw new System.NotImplementedException(); } /// /// Sets the of the specified pixel in this . /// /// The x-coordinate of the pixel to set. /// The y-coordinate of the pixel to set. /// A structure that represents the color /// to assign to the specified pixel. /// The operation failed. /// The type of this bitmap is not supported. public unsafe void SetPixel(int x, int y, Color color) { EnsureNotDisposed(); if (FreeImage.GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) { if (ColorDepth == 16 || ColorDepth == 24 || ColorDepth == 32) { RGBQUAD rgbq = color; if (!FreeImage.SetPixelColor(dib, (uint)x, (uint)y, ref rgbq)) { throw new Exception("FreeImage.SetPixelColor() failed"); } return; } else if (ColorDepth == 1 || ColorDepth == 4 || ColorDepth == 8) { uint colorsUsed = FreeImage.GetColorsUsed(dib); RGBQUAD* palette = (RGBQUAD*)FreeImage.GetPalette(dib); for (int i = 0; i < colorsUsed; i++) { if (palette[i].Color == color) { byte index = (byte)i; if (!FreeImage.SetPixelIndex(dib, (uint)x, (uint)y, ref index)) { throw new Exception("FreeImage.SetPixelIndex() failed"); } return; } } throw new ArgumentOutOfRangeException("color"); } } throw new NotSupportedException("The type of the image is not supported"); } /// /// Sets the resolution for this . /// /// The horizontal resolution, in dots per inch, of this . /// The vertical resolution, in dots per inch, of this . public void SetResolution(float xDpi, float yDpi) { EnsureNotDisposed(); FreeImage.SetResolutionX(dib, (uint)xDpi); FreeImage.SetResolutionY(dib, (uint)yDpi); } /// /// This function is not yet implemented. /// /// /// This method is not implemented. public BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format) { throw new NotImplementedException(); } /// /// This function is not yet implemented. /// /// /// This method is not implemented. public BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData) { throw new NotImplementedException(); } /// /// This function is not yet implemented. /// /// /// This method is not implemented. public void UnlockBits(BitmapData bitmapdata) { throw new NotImplementedException(); } /// /// Converts this into a different color depth. /// The parameter specifies color depth, greyscale conversion /// and palette reorder. /// Adding the flag /// will first perform a convesion to greyscale. This can be done with any target /// color depth. /// Adding the flag /// will allow the algorithm to reorder the palette. This operation will not be performed to /// non-greyscale images to prevent data loss by mistake. /// /// A bitfield containing information about the conversion /// to perform. /// Returns true on success, false on failure. public bool ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH bpp) { EnsureNotDisposed(); return ReplaceDib(FreeImage.ConvertColorDepth(dib, bpp, false)); } /// /// Converts this to /// initializing a new instance. /// In case source and destination type are the same, the operation fails. /// An error message can be catched using the 'Message' event. /// /// Destination type. /// True to scale linear, else false. /// Returns true on success, false on failure. public bool ConvertType(FREE_IMAGE_TYPE type, bool scaleLinear) { EnsureNotDisposed(); return (ImageType == type) ? false : ReplaceDib(FreeImage.ConvertToType(dib, type, scaleLinear)); } /// /// Converts this to . /// In case source and destination type are the same, the operation fails. /// An error message can be catched using the 'Message' event. /// /// Destination type. /// True to scale linear, else false. /// The converted instance. public FreeImageBitmap GetTypeConvertedInstance(FREE_IMAGE_TYPE type, bool scaleLinear) { EnsureNotDisposed(); FreeImageBitmap result = null; if (ImageType != type) { FIBITMAP newDib = FreeImage.ConvertToType(dib, type, scaleLinear); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } } return result; } /// /// Converts this into a different color depth initializing /// a new instance. /// The parameter specifies color depth, greyscale conversion /// and palette reorder. /// Adding the flag will /// first perform a convesion to greyscale. This can be done with any target color depth. /// Adding the flag will /// allow the algorithm to reorder the palette. This operation will not be performed to /// non-greyscale images to prevent data loss by mistake. /// /// A bitfield containing information about the conversion /// to perform. /// The converted instance. public FreeImageBitmap GetColorConvertedInstance(FREE_IMAGE_COLOR_DEPTH bpp) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.ConvertColorDepth(dib, bpp, false); if (newDib == dib) { newDib = FreeImage.Clone(dib); } if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Rescales this to the specified size using the /// specified filter. /// /// The Size structure that represent the /// size of the new . /// Filter to use for resizing. /// Returns true on success, false on failure. public bool Rescale(Size newSize, FREE_IMAGE_FILTER filter) { return Rescale(newSize.Width, newSize.Height, filter); } /// /// Rescales this to the specified size using the /// specified filter. /// /// Width of the new . /// Height of the new . /// Filter to use for resizing. /// Returns true on success, false on failure. public bool Rescale(int width, int height, FREE_IMAGE_FILTER filter) { EnsureNotDisposed(); return ReplaceDib(FreeImage.Rescale(dib, width, height, filter)); } /// /// Rescales this to the specified size using the /// specified filter initializing a new instance. /// /// The Size structure that represent the /// size of the new . /// Filter to use for resizing. /// The rescaled instance. public FreeImageBitmap GetScaledInstance(Size newSize, FREE_IMAGE_FILTER filter) { return GetScaledInstance(newSize.Width, newSize.Height, filter); } /// /// Rescales this to the specified size using the /// specified filter initializing a new instance. /// /// Width of the new . /// Height of the new . /// Filter to use for resizing. /// The rescaled instance. public FreeImageBitmap GetScaledInstance(int width, int height, FREE_IMAGE_FILTER filter) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.Rescale(dib, width, height, filter); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Enlarges or shrinks this selectively per side and fills /// newly added areas with the specified background color. /// See for further details. /// /// The type of the specified color. /// The number of pixels, the image should be enlarged on its left side. /// Negative values shrink the image on its left side. /// The number of pixels, the image should be enlarged on its top side. /// Negative values shrink the image on its top side. /// The number of pixels, the image should be enlarged on its right side. /// Negative values shrink the image on its right side. /// The number of pixels, the image should be enlarged on its bottom side. /// Negative values shrink the image on its bottom side. /// The color, the enlarged sides of the image should be filled with. /// true on success, false on failure. public bool EnlargeCanvas(int left, int top, int right, int bottom, T? color) where T : struct { return EnlargeCanvas(left, top, right, bottom, color, FREE_IMAGE_COLOR_OPTIONS.FICO_DEFAULT); } /// /// Enlarges or shrinks this selectively per side and fills /// newly added areas with the specified background color. /// See for further details. /// /// The type of the specified color. /// The number of pixels, the image should be enlarged on its left side. /// Negative values shrink the image on its left side. /// The number of pixels, the image should be enlarged on its top side. /// Negative values shrink the image on its top side. /// The number of pixels, the image should be enlarged on its right side. /// Negative values shrink the image on its right side. /// The number of pixels, the image should be enlarged on its bottom side. /// Negative values shrink the image on its bottom side. /// The color, the enlarged sides of the image should be filled with. /// Options that affect the color search process for palletized images. /// true on success, false on failure. public bool EnlargeCanvas(int left, int top, int right, int bottom, T? color, FREE_IMAGE_COLOR_OPTIONS options) where T : struct { EnsureNotDisposed(); return ReplaceDib(FreeImage.EnlargeCanvas(dib, left, top, right, bottom, color, options)); } /// /// Enlarges or shrinks this selectively per side and fills /// newly added areas with the specified background color returning a new instance. /// See for further details. /// /// The type of the specified color. /// The number of pixels, the image should be enlarged on its left side. /// Negative values shrink the image on its left side. /// The number of pixels, the image should be enlarged on its top side. /// Negative values shrink the image on its top side. /// The number of pixels, the image should be enlarged on its right side. /// Negative values shrink the image on its right side. /// The number of pixels, the image should be enlarged on its bottom side. /// Negative values shrink the image on its bottom side. /// The color, the enlarged sides of the image should be filled with. /// The enlarged instance. public FreeImageBitmap GetEnlargedInstance(int left, int top, int right, int bottom, T? color) where T : struct { return GetEnlargedInstance(left, top, right, bottom, color, FREE_IMAGE_COLOR_OPTIONS.FICO_DEFAULT); } /// /// Enlarges or shrinks this selectively per side and fills /// newly added areas with the specified background color returning a new instance. /// See for further details. /// /// The type of the specified color. /// The number of pixels, the image should be enlarged on its left side. /// Negative values shrink the image on its left side. /// The number of pixels, the image should be enlarged on its top side. /// Negative values shrink the image on its top side. /// The number of pixels, the image should be enlarged on its right side. /// Negative values shrink the image on its right side. /// The number of pixels, the image should be enlarged on its bottom side. /// Negative values shrink the image on its bottom side. /// The color, the enlarged sides of the image should be filled with. /// Options that affect the color search process for palletized images. /// The enlarged instance. public FreeImageBitmap GetEnlargedInstance(int left, int top, int right, int bottom, T? color, FREE_IMAGE_COLOR_OPTIONS options) where T : struct { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.EnlargeCanvas(dib, left, top, right, bottom, color, options); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Quantizes this from 24 bit to 8bit creating a new /// palette with the specified using the specified /// . /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// Returns true on success, false on failure. public bool Quantize(FREE_IMAGE_QUANTIZE algorithm, int paletteSize) { return Quantize(algorithm, paletteSize, 0, (RGBQUAD[])null); } /// /// Quantizes this from 24 bit to 8bit creating a new /// palette with the specified using the specified /// and the specified /// palette up to the /// specified length. /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// The provided palette. /// Returns true on success, false on failure. public bool Quantize(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, Palette reservePalette) { return Quantize(algorithm, paletteSize, reservePalette.Length, reservePalette.Data); } /// /// Quantizes this from 24 bit to 8bit creating a new /// palette with the specified using the specified /// and the specified /// palette up to the /// specified length. /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// Size of the provided palette of ReservePalette. /// The provided palette. /// Returns true on success, false on failure. public bool Quantize(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, int reserveSize, Palette reservePalette) { return Quantize(algorithm, paletteSize, reserveSize, reservePalette.Data); } /// /// Quantizes this from 24 bit to 8bit creating a new /// palette with the specified using the specified /// and the specified /// palette up to the /// specified length. /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// Size of the provided palette of ReservePalette. /// The provided palette. /// Returns true on success, false on failure. public bool Quantize(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, int reserveSize, RGBQUAD[] reservePalette) { EnsureNotDisposed(); return ReplaceDib(FreeImage.ColorQuantizeEx(dib, algorithm, paletteSize, reserveSize, reservePalette)); } /// /// Quantizes this from 24 bit, using the specified /// initializing a new 8 bit instance with the /// specified . /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// The quantized instance. public FreeImageBitmap GetQuantizedInstance(FREE_IMAGE_QUANTIZE algorithm, int paletteSize) { return GetQuantizedInstance(algorithm, paletteSize, 0, (RGBQUAD[])null); } /// /// Quantizes this from 24 bit, using the specified /// and palette /// initializing a new 8 bit instance with the specified . /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// The provided palette. /// The quantized instance. public FreeImageBitmap GetQuantizedInstance(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, Palette reservePalette) { return GetQuantizedInstance(algorithm, paletteSize, reservePalette.Length, reservePalette); } /// /// Quantizes this from 24 bit, using the specified /// and up to /// entries from palette initializing /// a new 8 bit instance with the specified . /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// Size of the provided palette. /// The provided palette. /// The quantized instance. public FreeImageBitmap GetQuantizedInstance(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, int reserveSize, Palette reservePalette) { return GetQuantizedInstance(algorithm, paletteSize, reserveSize, reservePalette.Data); } /// /// Quantizes this from 24 bit, using the specified /// and up to /// entries from palette initializing /// a new 8 bit instance with the specified . /// /// The color reduction algorithm to be used. /// Size of the desired output palette. /// Size of the provided palette. /// The provided palette. /// The quantized instance. public FreeImageBitmap GetQuantizedInstance(FREE_IMAGE_QUANTIZE algorithm, int paletteSize, int reserveSize, RGBQUAD[] reservePalette) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.ColorQuantizeEx(dib, algorithm, paletteSize, reserveSize, reservePalette); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Converts a High Dynamic Range image to a 24-bit RGB image using a global /// operator based on logarithmic compression of luminance values, imitating /// the human response to light. /// /// A gamma correction that is applied after the tone mapping. /// A value of 1 means no correction. /// Scale factor allowing to adjust the brightness of the output image. /// Returns true on success, false on failure. public bool TmoDrago03(double gamma, double exposure) { EnsureNotDisposed(); return ReplaceDib(FreeImage.TmoDrago03(dib, gamma, exposure)); } /// /// Converts a High Dynamic Range image to a 24-bit RGB image using a global operator inspired /// by photoreceptor physiology of the human visual system. /// /// Controls the overall image intensity in the range [-8, 8]. /// Controls the overall image contrast in the range [0.3, 1.0[. /// Returns true on success, false on failure. public bool TmoReinhard05(double intensity, double contrast) { EnsureNotDisposed(); return ReplaceDib(FreeImage.TmoReinhard05(dib, intensity, contrast)); } /// /// Apply the Gradient Domain High Dynamic Range Compression to a RGBF image and convert to 24-bit RGB. /// /// Color saturation (s parameter in the paper) in [0.4..0.6] /// Atenuation factor (beta parameter in the paper) in [0.8..0.9] /// Returns true on success, false on failure. public bool TmoFattal02(double color_saturation, double attenuation) { EnsureNotDisposed(); return ReplaceDib(FreeImage.TmoFattal02(dib, color_saturation, attenuation)); } /// /// This method rotates a 1-, 4-, 8-bit greyscale or a 24-, 32-bit color image by means of 3 shears. /// For 1- and 4-bit images, rotation is limited to angles whose value is an integer /// multiple of 90. /// /// The angle of rotation. /// Returns true on success, false on failure. public bool Rotate(double angle) { EnsureNotDisposed(); bool result = false; if (ColorDepth == 4) { result = ReplaceDib(FreeImage.Rotate4bit(dib, angle)); } else { result = ReplaceDib(FreeImage.Rotate(dib, angle)); } return result; } /// /// This method rotates a 1-, 4-, 8-bit greyscale or a 24-, 32-bit color image by means of 3 shears. /// For 1- and 4-bit images, rotation is limited to angles whose value is an integer /// multiple of 90. /// /// The type of the color to use as background. /// The angle of rotation. /// The color used used to fill the bitmap's background. /// Returns true on success, false on failure. public bool Rotate(double angle, T? backgroundColor) where T : struct { EnsureNotDisposed(); bool result = false; if (ColorDepth == 4) { result = ReplaceDib(FreeImage.Rotate4bit(dib, angle)); } else { result = ReplaceDib(FreeImage.Rotate(dib, angle, backgroundColor)); } return result; } /// /// Rotates this by the specified angle initializing a new instance. /// For 1- and 4-bit images, rotation is limited to angles whose value is an integer /// multiple of 90. /// /// The type of the color to use as background. /// The angle of rotation. /// The color used used to fill the bitmap's background. /// The rotated instance. public FreeImageBitmap GetRotatedInstance(double angle, T? backgroundColor) where T : struct { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib; if (ColorDepth == 4) { newDib = FreeImage.Rotate4bit(dib, angle); } else { newDib = FreeImage.Rotate(dib, angle, backgroundColor); } if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Rotates this by the specified angle initializing a new instance. /// For 1- and 4-bit images, rotation is limited to angles whose value is an integer /// multiple of 90. /// /// The angle of rotation. /// The rotated instance. public FreeImageBitmap GetRotatedInstance(double angle) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib; if (ColorDepth == 4) { newDib = FreeImage.Rotate4bit(dib, angle); } else { newDib = FreeImage.Rotate(dib, angle); } if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// This method performs a rotation and / or translation of an 8-bit greyscale, /// 24- or 32-bit image, using a 3rd order (cubic) B-Spline. /// /// The angle of rotation. /// Horizontal image translation. /// Vertical image translation. /// Rotation center x-coordinate. /// Rotation center y-coordinate. /// When true the irrelevant part of the image is set to a black color, /// otherwise, a mirroring technique is used to fill irrelevant pixels. /// Returns true on success, false on failure. public bool Rotate(double angle, double xShift, double yShift, double xOrigin, double yOrigin, bool useMask) { EnsureNotDisposed(); return ReplaceDib(FreeImage.RotateEx(dib, angle, xShift, yShift, xOrigin, yOrigin, useMask)); } /// /// This method performs a rotation and / or translation of an 8-bit greyscale, /// 24- or 32-bit image, using a 3rd order (cubic) B-Spline initializing a new instance. /// /// The angle of rotation. /// Horizontal image translation. /// Vertical image translation. /// Rotation center x-coordinate. /// Rotation center y-coordinate. /// When true the irrelevant part of the image is set to a black color, /// otherwise, a mirroring technique is used to fill irrelevant pixels. /// The rotated instance. public FreeImageBitmap GetRotatedInstance(double angle, double xShift, double yShift, double xOrigin, double yOrigin, bool useMask) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.RotateEx( dib, angle, xShift, yShift, xOrigin, yOrigin, useMask); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Perfoms an histogram transformation on a 8-, 24- or 32-bit image. /// /// The lookup table (LUT). /// It's size is assumed to be 256 in length. /// The color channel to be transformed. /// Returns true on success, false on failure. public bool AdjustCurve(byte[] lookUpTable, FREE_IMAGE_COLOR_CHANNEL channel) { EnsureNotDisposed(); return FreeImage.AdjustCurve(dib, lookUpTable, channel); } /// /// Performs gamma correction on a 8-, 24- or 32-bit image. /// /// The parameter represents the gamma value to use (gamma > 0). /// A value of 1.0 leaves the image alone, less than one darkens it, and greater than one lightens it. /// Returns true on success, false on failure. public bool AdjustGamma(double gamma) { EnsureNotDisposed(); return FreeImage.AdjustGamma(dib, gamma); } /// /// Adjusts the brightness of a 8-, 24- or 32-bit image by a certain amount. /// /// A value 0 means no change, /// less than 0 will make the image darker and greater than 0 will make the image brighter. /// Returns true on success, false on failure. public bool AdjustBrightness(double percentage) { EnsureNotDisposed(); return FreeImage.AdjustBrightness(dib, percentage); } /// /// Adjusts the contrast of a 8-, 24- or 32-bit image by a certain amount. /// /// A value 0 means no change, /// less than 0 will decrease the contrast and greater than 0 will increase the contrast of the image. /// Returns true on success, false on failure. public bool AdjustContrast(double percentage) { EnsureNotDisposed(); return FreeImage.AdjustContrast(dib, percentage); } /// /// Inverts each pixel data. /// /// Returns true on success, false on failure. public bool Invert() { EnsureNotDisposed(); return FreeImage.Invert(dib); } /// /// Computes the image histogram. /// /// Channel to compute from. /// Array of integers containing the histogram. /// Returns true on success, false on failure. public bool GetHistogram(FREE_IMAGE_COLOR_CHANNEL channel, out int[] histogram) { EnsureNotDisposed(); histogram = new int[256]; return FreeImage.GetHistogram(dib, histogram, channel); } /// /// Retrieves the red, green, blue or alpha channel of a 24- or 32-bit image. /// /// The color channel to extract. /// The color channel in a new instance. public FreeImageBitmap GetChannel(FREE_IMAGE_COLOR_CHANNEL channel) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.GetChannel(dib, channel); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Insert a 8-bit dib into a 24- or 32-bit image. /// Both images must have to same width and height. /// /// The to insert. /// The color channel to replace. /// Returns true on success, false on failure. public bool SetChannel(FreeImageBitmap bitmap, FREE_IMAGE_COLOR_CHANNEL channel) { EnsureNotDisposed(); bitmap.EnsureNotDisposed(); return FreeImage.SetChannel(dib, bitmap.dib, channel); } /// /// Retrieves the real part, imaginary part, magnitude or phase of a complex image. /// /// The color channel to extract. /// The color channel in a new instance. public FreeImageBitmap GetComplexChannel(FREE_IMAGE_COLOR_CHANNEL channel) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.GetComplexChannel(dib, channel); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Set the real or imaginary part of a complex image. /// Both images must have to same width and height. /// /// The to insert. /// The color channel to replace. /// Returns true on success, false on failure. public bool SetComplexChannel(FreeImageBitmap bitmap, FREE_IMAGE_COLOR_CHANNEL channel) { EnsureNotDisposed(); bitmap.EnsureNotDisposed(); return FreeImage.SetComplexChannel(dib, bitmap.dib, channel); } /// /// Copy a sub part of this . /// /// The subpart to copy. /// The sub part in a new instance. public FreeImageBitmap Copy(Rectangle rect) { EnsureNotDisposed(); return Copy(rect.Left, rect.Top, rect.Right, rect.Bottom); } /// /// Copy a sub part of this . /// /// Specifies the left position of the cropped rectangle. /// Specifies the top position of the cropped rectangle. /// Specifies the right position of the cropped rectangle. /// Specifies the bottom position of the cropped rectangle. /// The sub part in a new instance. public FreeImageBitmap Copy(int left, int top, int right, int bottom) { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.Copy(dib, left, top, right, bottom); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Alpha blend or combine a sub part image with this . /// The bit depth of must be greater than or equal to the bit depth this instance. /// /// The to paste into this instance. /// Specifies the left position of the sub image. /// Specifies the top position of the sub image. /// alpha blend factor. /// The source and destination images are alpha blended if alpha=0..255. /// If alpha > 255, then the source image is combined to the destination image. /// Returns true on success, false on failure. public bool Paste(FreeImageBitmap bitmap, int left, int top, int alpha) { EnsureNotDisposed(); bitmap.EnsureNotDisposed(); return FreeImage.Paste(dib, bitmap.dib, left, top, alpha); } /// /// Alpha blend or combine a sub part image with tthis . /// The bit depth of must be greater than or equal to the bit depth this instance. /// /// The to paste into this instance. /// Specifies the position of the sub image. /// alpha blend factor. /// The source and destination images are alpha blended if alpha=0..255. /// If alpha > 255, then the source image is combined to the destination image. /// Returns true on success, false on failure. public bool Paste(FreeImageBitmap bitmap, Point point, int alpha) { EnsureNotDisposed(); return Paste(bitmap, point.X, point.Y, alpha); } /// /// This method composite a transparent foreground image against a single background color or /// against a background image. /// In case is false and /// and /// are null, a checkerboard will be used as background. /// /// When true the background of this instance is used /// if it contains one. /// Backgroundcolor used in case is false /// and is not null. /// Background used in case /// is false and is a null reference. /// Returns true on success, false on failure. public bool Composite(bool useBitmapBackground, Color? applicationBackground, FreeImageBitmap bitmapBackGround) { EnsureNotDisposed(); bitmapBackGround.EnsureNotDisposed(); RGBQUAD? rgb = applicationBackground; return ReplaceDib( FreeImage.Composite( dib, useBitmapBackground, rgb.HasValue ? new RGBQUAD[] { rgb.Value } : null, bitmapBackGround.dib)); } /// /// Applies the alpha value of each pixel to its color components. /// The aplha value stays unchanged. /// Only works with 32-bits color depth. /// /// Returns true on success, false on failure. public bool PreMultiplyWithAlpha() { EnsureNotDisposed(); return FreeImage.PreMultiplyWithAlpha(dib); } /// /// Solves a Poisson equation, remap result pixels to [0..1] and returns the solution. /// /// Number of cycles in the multigrid algorithm (usually 2 or 3) /// Returns true on success, false on failure. public bool MultigridPoissonSolver(int ncycle) { EnsureNotDisposed(); return ReplaceDib(FreeImage.MultigridPoissonSolver(dib, ncycle)); } /// /// Adjusts an image's brightness, contrast and gamma as well as it may /// optionally invert the image within a single operation. /// /// Percentage brightness value where -100 <= brightness <= 100. /// A value of 0 means no change, less than 0 will make the image darker and greater /// than 0 will make the image brighter. /// Percentage contrast value where -100 <= contrast <= 100. /// A value of 0 means no change, less than 0 will decrease the contrast /// and greater than 0 will increase the contrast of the image. /// Gamma value to be used for gamma correction. /// A value of 1.0 leaves the image alone, less than one darkens it, /// and greater than one lightens it. /// This parameter must not be zero or smaller than zero. /// If so, it will be ignored and no gamma correction will be performed on the image. /// If set to true, the image will be inverted. /// Returns true on success, false on failure. public bool AdjustColors(double brightness, double contrast, double gamma, bool invert) { EnsureNotDisposed(); return FreeImage.AdjustColors(dib, brightness, contrast, gamma, invert); } /// /// Applies color mapping for one or several colors on a 1-, 4- or 8-bit /// palletized or a 16-, 24- or 32-bit high color image. /// /// Array of colors to be used as the mapping source. /// Array of colors to be used as the mapping destination. /// If true, 32-bit images and colors are treated as 24-bit. /// If true, source and destination colors are swapped, that is, /// each destination color is also mapped to the corresponding source color. /// The total number of pixels changed. /// /// or is a null reference. /// /// /// has a different length than . /// public uint ApplyColorMapping(RGBQUAD[] srccolors, RGBQUAD[] dstcolors, bool ignore_alpha, bool swap) { EnsureNotDisposed(); if (srccolors == null) { throw new ArgumentNullException("srccolors"); } if (dstcolors == null) { throw new ArgumentNullException("dstcolors"); } if (srccolors.Length != dstcolors.Length) { throw new ArgumentException("srccolors and dstcolors must have the same length."); } return FreeImage.ApplyColorMapping(dib, srccolors, dstcolors, (uint)srccolors.Length, ignore_alpha, swap); } /// /// Swaps two specified colors on a 1-, 4- or 8-bit palletized /// or a 16-, 24- or 32-bit high color image. /// /// One of the two colors to be swapped. /// The other of the two colors to be swapped. /// If true, 32-bit images and colors are treated as 24-bit. /// The total number of pixels changed. public uint SwapColors(RGBQUAD color_a, RGBQUAD color_b, bool ignore_alpha) { EnsureNotDisposed(); return FreeImage.SwapColors(dib, ref color_a, ref color_b, ignore_alpha); } /// /// Applies palette index mapping for one or several indices /// on a 1-, 4- or 8-bit palletized image. /// /// Array of palette indices to be used as the mapping source. /// Array of palette indices to be used as the mapping destination. /// The number of palette indices to be mapped. This is the size of both /// srcindices and dstindices /// If true, source and destination palette indices are swapped, that is, /// each destination index is also mapped to the corresponding source index. /// The total number of pixels changed. /// /// or is a null reference. /// /// /// has a different length than . /// public uint ApplyPaletteIndexMapping(byte[] srcindices, byte[] dstindices, uint count, bool swap) { EnsureNotDisposed(); if (srcindices == null) { throw new ArgumentNullException("srcindices"); } if (dstindices == null) { throw new ArgumentNullException("dstindices"); } if (srcindices.Length != dstindices.Length) { throw new ArgumentException("srcindices and dstindices must have the same length."); } return FreeImage.ApplyPaletteIndexMapping(dib, srcindices, dstindices, (uint)srcindices.Length, swap); } /// /// Swaps two specified palette indices on a 1-, 4- or 8-bit palletized image. /// /// One of the two palette indices to be swapped. /// The other of the two palette indices to be swapped. /// The total number of pixels changed. public uint SwapPaletteIndices(byte index_a, byte index_b) { EnsureNotDisposed(); return FreeImage.SwapPaletteIndices(dib, ref index_a, ref index_b); } /// /// Sets all pixels of this to the specified color. /// See for further details. /// /// The type of the specified color. /// The color to fill this with. /// true on success, false on failure. public bool FillBackground(T color) where T : struct { return FillBackground(color, FREE_IMAGE_COLOR_OPTIONS.FICO_DEFAULT); } /// /// Sets all pixels of this to the specified color. /// See for further details. /// /// The type of the specified color. /// The color to fill this with. /// Options that affect the color search process for palletized images. /// true on success, false on failure. public bool FillBackground(T color, FREE_IMAGE_COLOR_OPTIONS options) where T : struct { EnsureNotDisposed(); return FreeImage.FillBackground(dib, color, options); } /// /// Creates a new ICC-Profile. /// /// The data of the new ICC-Profile. /// The new ICC-Profile of the bitmap. /// is a null reference. public FIICCPROFILE CreateICCProfile(byte[] data) { if (data == null) { throw new ArgumentNullException("data"); } return CreateICCProfile(data, data.Length); } /// /// Creates a new ICC-Profile. /// /// The data of the new ICC-Profile. /// The number of bytes of to use. /// The new ICC-Profile of the bitmap. /// is null. public FIICCPROFILE CreateICCProfile(byte[] data, int size) { EnsureNotDisposed(); if (data == null) { throw new ArgumentNullException("data"); } return FreeImage.CreateICCProfileEx(dib, data, size); } /// /// Determines whether this and the specified instances are the same. /// /// The object to test. /// true if this instance is the same /// or if both are null references; otherwise, false. public override bool Equals(object obj) { return ReferenceEquals(this, obj); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return dib.GetHashCode(); } #endregion #region Static functions /// /// Returns a value that indicates whether the pixel format for this contains alpha information. /// /// The to test. /// true if pixfmt contains alpha information; otherwise, false. public static bool IsAlphaPixelFormat(PixelFormat pixfmt) { return Bitmap.IsAlphaPixelFormat(pixfmt); } /// /// Returns a value that indicates whether the pixel format is 32 bits per pixel. /// /// The to test. /// true if pixfmt is canonical; otherwise, false. public static bool IsCanonicalPixelFormat(PixelFormat pixfmt) { return Bitmap.IsCanonicalPixelFormat(pixfmt); } /// /// Returns a value that indicates whether the pixel format is 64 bits per pixel. /// /// The enumeration to test. /// true if pixfmt is extended; otherwise, false. public static bool IsExtendedPixelFormat(PixelFormat pixfmt) { return Bitmap.IsExtendedPixelFormat(pixfmt); } /// /// Creates a from a Windows handle to an icon. /// /// A handle to an icon. /// The that this method creates. public static FreeImageBitmap FromHicon(IntPtr hicon) { using (Bitmap bitmap = Bitmap.FromHicon(hicon)) { return new FreeImageBitmap(bitmap); } } /// /// Creates a from the specified Windows resource. /// /// A handle to an instance of the executable /// file that contains the resource. /// A string containing the name of the resource bitmap. /// The that this method creates. public static FreeImageBitmap FromResource(IntPtr hinstance, string bitmapName) { using (Bitmap bitmap = Bitmap.FromResource(hinstance, bitmapName)) { return new FreeImageBitmap(bitmap); } } /// /// Creates a from the specified file. /// /// A string that contains the name of the file /// from which to create the . /// The this method creates. public static FreeImageBitmap FromFile(string filename) { return new FreeImageBitmap(filename); } /// /// Creates a from the specified file /// using embedded color management information in that file. /// /// A string that contains the /// name of the file from which to create the . /// Ignored. /// The this method creates. public static FreeImageBitmap FromFile(string filename, bool useEmbeddedColorManagement) { return new FreeImageBitmap(filename); } /// /// Creates a from a handle to a GDI bitmap. /// /// The GDI bitmap handle from which to create the . /// The this method creates. public static FreeImageBitmap FromHbitmap(IntPtr hbitmap) { FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.CreateFromHbitmap(hbitmap, IntPtr.Zero); if (!newDib.IsNull) { result = new FreeImageBitmap(newDib); } return result; } /// /// Creates a from a handle to a GDI bitmap and a handle to a GDI palette. /// /// The GDI bitmap handle from which to create the . /// Ignored. /// The this method creates. public static FreeImageBitmap FromHbitmap(IntPtr hbitmap, IntPtr hpalette) { return FromHbitmap(hbitmap); } /// /// Frees a bitmap handle. /// /// Handle to a bitmap. /// true on success, false on failure. public static bool FreeHbitmap(IntPtr hbitmap) { return FreeImage.FreeHbitmap(hbitmap); } /// /// Creates a from the specified data stream. /// /// A that contains the data for this . /// The this method creates. public static FreeImageBitmap FromStream(Stream stream) { return new FreeImageBitmap(stream); } /// /// Creates a from the specified data stream. /// /// A that contains the data for this . /// Ignored. /// The this method creates. public static FreeImageBitmap FromStream(Stream stream, bool useEmbeddedColorManagement) { return new FreeImageBitmap(stream); } /// /// Creates a from the specified data stream. /// /// A that contains the data for this . /// Ignored. /// Ignored. /// The this method creates. public static FreeImageBitmap FromStream(Stream stream, bool useEmbeddedColorManagement, bool validateImageData) { return new FreeImageBitmap(stream); } /// /// Returns the color depth, in number of bits per pixel, /// of the specified pixel format. /// /// The member that specifies /// the format for which to find the size. /// The color depth of the specified pixel format. public static int GetPixelFormatSize(PixelFormat pixfmt) { return Bitmap.GetPixelFormatSize(pixfmt); } /// /// Performs a lossless rotation or flipping on a JPEG file. /// /// Source file. /// Destination file; can be the source file; will be overwritten. /// The operation to apply. /// To avoid lossy transformation, you can set the perfect parameter to true. /// Returns true on success, false on failure. public static bool JPEGTransform(string source, string destination, FREE_IMAGE_JPEG_OPERATION operation, bool perfect) { return FreeImage.JPEGTransform(source, destination, operation, perfect); } /// /// Performs a lossless crop on a JPEG file. /// /// Source filename. /// Destination filename. /// Specifies the cropped rectangle. /// Returns true on success, false on failure. /// /// or is null. /// /// /// does not exist. /// public static bool JPEGCrop(string source, string destination, Rectangle rect) { if (source == null) { throw new ArgumentNullException("source"); } if (!File.Exists(source)) { throw new FileNotFoundException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } return JPEGCrop(source, destination, rect.Left, rect.Top, rect.Right, rect.Bottom); } /// /// Performs a lossless crop on a JPEG file. /// /// Source filename. /// Destination filename. /// Specifies the left position of the cropped rectangle. /// Specifies the top position of the cropped rectangle. /// Specifies the right position of the cropped rectangle. /// Specifies the bottom position of the cropped rectangle. /// Returns true on success, false on failure. /// /// or is null. /// /// /// does not exist. /// public static bool JPEGCrop(string source, string destination, int left, int top, int right, int bottom) { if (source == null) { throw new ArgumentNullException("source"); } if (!File.Exists(source)) { throw new FileNotFoundException("source"); } if (destination == null) { throw new ArgumentNullException("destination"); } return FreeImage.JPEGCrop(source, destination, left, top, right, bottom); } /// /// Converts a X11 color name into a corresponding RGB value. /// /// Name of the color to convert. /// Red component. /// Green component. /// Blue component. /// Returns true on success, false on failure. /// is null. public static bool LookupX11Color(string color, out byte red, out byte green, out byte blue) { if (color == null) { throw new ArgumentNullException("color"); } return FreeImage.LookupX11Color(color, out red, out green, out blue); } /// /// Converts a SVG color name into a corresponding RGB value. /// /// Name of the color to convert. /// Red component. /// Green component. /// Blue component. /// Returns true on success, false on failure. /// is null. public static bool LookupSVGColor(string color, out byte red, out byte green, out byte blue) { if (color == null) { throw new ArgumentNullException("color"); } return FreeImage.LookupSVGColor(color, out red, out green, out blue); } /// /// Creates a lookup table to be used with AdjustCurve() which /// may adjusts brightness and contrast, correct gamma and invert the image with a /// single call to AdjustCurve(). /// /// Output lookup table to be used with AdjustCurve(). /// The size of is assumed to be 256. /// Percentage brightness value where -100 <= brightness <= 100. /// A value of 0 means no change, less than 0 will make the image darker and greater /// than 0 will make the image brighter. /// Percentage contrast value where -100 <= contrast <= 100. /// A value of 0 means no change, less than 0 will decrease the contrast /// and greater than 0 will increase the contrast of the image. /// Gamma value to be used for gamma correction. /// A value of 1.0 leaves the image alone, less than one darkens it, /// and greater than one lightens it. /// If set to true, the image will be inverted. /// The number of adjustments applied to the resulting lookup table /// compared to a blind lookup table. /// is null. /// is not 256. public static int GetAdjustColorsLookupTable(byte[] lookUpTable, double brightness, double contrast, double gamma, bool invert) { if (lookUpTable == null) { throw new ArgumentNullException("lookUpTable"); } if (lookUpTable.Length != 256) { throw new ArgumentException("lookUpTable"); } return FreeImage.GetAdjustColorsLookupTable(lookUpTable, brightness, contrast, gamma, invert); } /// /// Adds a specified frame to the file specified using the specified parameters. /// Use this method to save selected frames from an to a multiple-frame image. /// /// File to add this frame to. /// A that contains the frame to add. /// Format of the image. /// Flags to enable or disable plugin-features. /// Flags to enable or disable plugin-features. /// /// or is null. /// /// does not exist. /// Saving the image failed. public static void SaveAdd( string filename, FreeImageBitmap bitmap, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS loadFlags, FREE_IMAGE_SAVE_FLAGS saveFlags) { if (filename == null) { throw new ArgumentNullException("filename"); } if (!File.Exists(filename)) { throw new FileNotFoundException("filename"); } if (bitmap == null) { throw new ArgumentNullException("bitmap"); } bitmap.EnsureNotDisposed(); FIBITMAP dib = bitmap.dib; if (dib.IsNull) throw new ArgumentNullException("bitmap"); FIMULTIBITMAP mpBitmap = FreeImage.OpenMultiBitmapEx(filename, ref format, loadFlags, false, false, true); if (mpBitmap.IsNull) throw new Exception(ErrorLoadingBitmap); FreeImage.AppendPage(mpBitmap, bitmap.dib); if (!FreeImage.CloseMultiBitmap(mpBitmap, saveFlags)) throw new Exception(ErrorUnloadBitmap); } /// /// Adds a specified frame to the file specified using the specified parameters. /// Use this method to save selected frames from an image to a multiple-frame image. /// /// File to add this frame to. /// A that contains the frame to add. /// The position of the inserted frame. /// Format of the image. /// Flags to enable or disable plugin-features. /// Flags to enable or disable plugin-features. /// /// or is null. /// /// does not exist. /// Saving the image failed. /// is out of range. public static void SaveAdd( string filename, FreeImageBitmap bitmap, int insertPosition, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS loadFlags, FREE_IMAGE_SAVE_FLAGS saveFlags) { if (filename == null) { throw new ArgumentNullException("filename"); } if (!File.Exists(filename)) { throw new FileNotFoundException("filename"); } if (bitmap == null) { throw new ArgumentNullException("bitmap"); } if (insertPosition < 0) { throw new ArgumentOutOfRangeException("insertPosition"); } bitmap.EnsureNotDisposed(); FIBITMAP dib = bitmap.dib; if (dib.IsNull) throw new ArgumentNullException("bitmap"); FIMULTIBITMAP mpBitmap = FreeImage.OpenMultiBitmapEx(filename, ref format, loadFlags, false, false, true); if (mpBitmap.IsNull) throw new Exception(ErrorLoadingBitmap); int pageCount = FreeImage.GetPageCount(mpBitmap); if (insertPosition > pageCount) throw new ArgumentOutOfRangeException("insertPosition"); if (insertPosition == pageCount) FreeImage.AppendPage(mpBitmap, bitmap.dib); else FreeImage.InsertPage(mpBitmap, insertPosition, bitmap.dib); if (!FreeImage.CloseMultiBitmap(mpBitmap, saveFlags)) throw new Exception(ErrorUnloadBitmap); } /// /// Returns a new instance of the class which /// has no public accessible constructor. /// /// A new instace of . public static PropertyItem CreateNewPropertyItem() { return FreeImage.CreatePropertyItem(); } #endregion #region Helper functions /// /// Throws an exception in case the instance has already been disposed. /// private void EnsureNotDisposed() { lock (lockObject) { if (!this.disposed) { return; } } throw new ObjectDisposedException(ToString()); } /// /// Tries to replace the wrapped with a new one. /// In case the new dib is null or the same as the already /// wrapped one, nothing will be changed and the result will /// be false. /// Otherwise the wrapped will be unloaded and replaced. /// /// The new dib. /// Returns true on success, false on failure. private bool ReplaceDib(FIBITMAP newDib) { bool result = false; if ((dib != newDib) && (!newDib.IsNull)) { UnloadDib(); dib = newDib; AddMemoryPressure(); result = true; } return result; } /// /// Unloads currently wrapped or unlocks the locked page /// in case it came from a multipaged bitmap. /// private void UnloadDib() { if (!dib.IsNull) { long size = FreeImage.GetDIBSize(dib); FreeImage.UnloadEx(ref dib); if (size > 0L) GC.RemoveMemoryPressure(size); } } /// /// Informs the runtime about unmanaged allocoted memory. /// private void AddMemoryPressure() { long dataSize; if ((dataSize = DataSize) > 0L) GC.AddMemoryPressure(dataSize); } /// /// Opens the stream and reads the number of available pages. /// Then loads the first page to this instance. /// private void LoadFromStream(Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags) { FIMULTIBITMAP mdib = FreeImage.OpenMultiBitmapFromStream(stream, ref format, flags); if (mdib.IsNull) { throw new Exception(ErrorLoadingBitmap); } try { frameCount = FreeImage.GetPageCount(mdib); } finally { if (!FreeImage.CloseMultiBitmapEx(ref mdib)) { throw new Exception(ErrorUnloadBitmap); } } dib = FreeImage.LoadFromStream(stream, flags, ref format); if (dib.IsNull) { throw new Exception(ErrorLoadingBitmap); } saveInformation.loadFlags = flags; originalFormat = format; AddMemoryPressure(); } #endregion #region Interfaces /// /// Helper class to store informations for . /// private sealed class SaveInformation : ICloneable { public string filename; public FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; public FREE_IMAGE_LOAD_FLAGS loadFlags = FREE_IMAGE_LOAD_FLAGS.DEFAULT; public FREE_IMAGE_SAVE_FLAGS saveFlags = FREE_IMAGE_SAVE_FLAGS.DEFAULT; public object Clone() { return base.MemberwiseClone(); } } /// /// Creates a deep copy of this . /// /// A deep copy of this . public object Clone() { EnsureNotDisposed(); FreeImageBitmap result = null; FIBITMAP newDib = FreeImage.Clone(dib); if (!dib.IsNull) { result = new FreeImageBitmap(newDib); result.saveInformation = (SaveInformation)saveInformation.Clone(); result.tag = tag; result.originalFormat = originalFormat; } return result; } /// /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Performs application-defined tasks associated with freeing, /// releasing, or resetting unmanaged resources. /// /// If true managed ressources are released. protected virtual void Dispose(bool disposing) { // Only clean up once lock (lockObject) { if (disposed) { return; } disposed = true; } // Clean up managed resources if (disposing) { if (stream != null) { if (disposeStream) { stream.Dispose(); } stream = null; } } tag = null; saveInformation = null; // Clean up unmanaged resources UnloadDib(); } /// /// Retrieves an object that can iterate through the individual scanlines in this . /// /// An for the . /// The bitmaps's type is not supported. IEnumerator IEnumerable.GetEnumerator() { return GetScanlines().GetEnumerator(); } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { EnsureNotDisposed(); using (MemoryStream memory = new MemoryStream(DataSize)) { if (!FreeImage.SaveToStream(dib, memory, FREE_IMAGE_FORMAT.FIF_TIFF, FREE_IMAGE_SAVE_FLAGS.TIFF_LZW)) { throw new SerializationException(); } memory.Capacity = (int)memory.Length; info.AddValue("Bitmap Data", memory.GetBuffer()); } } #endregion } } namespace FreeImageAPI { /// /// Class handling non-bitmap related functions. /// public static class FreeImageEngine { #region Callback // Callback delegate [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly OutputMessageFunction outputMessageFunction; static FreeImageEngine() { // Check if FreeImage.dll is present and cancel setting the callbackfuntion if not if (!IsAvailable) { return; } // Create a delegate (function pointer) to 'OnMessage' outputMessageFunction = new OutputMessageFunction(OnMessage); // Set the callback FreeImage.SetOutputMessage(outputMessageFunction); } /// /// Internal callback /// private static void OnMessage(FREE_IMAGE_FORMAT fif, string message) { // Get a local copy of the multicast-delegate OutputMessageFunction m = Message; // Check the local copy instead of the static instance // to prevent a second thread from setting the delegate // to null, which would cause a nullreference exception if (m != null) { // Invoke the multicast-delegate m.Invoke(fif, message); } } /// /// Gets a value indicating if the FreeImage DLL is available or not. /// public static bool IsAvailable { get { return FreeImage.IsAvailable(); } } /// /// Internal errors in FreeImage generate a logstring that can be /// captured by this event. /// public static event OutputMessageFunction Message; #endregion /// /// Gets a string containing the current version of the library. /// public static string Version { get { return FreeImage.GetVersion(); } } /// /// Gets a string containing a standard copyright message. /// public static string CopyrightMessage { get { return FreeImage.GetCopyrightMessage(); } } /// /// Gets whether the platform is using Little Endian. /// public static bool IsLittleEndian { get { return FreeImage.IsLittleEndian(); } } } } namespace FreeImageAPI.Plugins { /// /// Class representing a FreeImage format. /// public sealed class FreeImagePlugin { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly FREE_IMAGE_FORMAT fif; /// /// Initializes a new instance of this class. /// /// The FreeImage format to wrap. internal FreeImagePlugin(FREE_IMAGE_FORMAT fif) { this.fif = fif; } /// /// Gets the format of this instance. /// public FREE_IMAGE_FORMAT FIFormat { get { return fif; } } /// /// Gets or sets whether this plugin is enabled. /// public bool Enabled { get { return (FreeImage.IsPluginEnabled(fif) == 1); } set { FreeImage.SetPluginEnabled(fif, value); } } /// /// Gets a string describing the format. /// public string Format { get { return FreeImage.GetFormatFromFIF(fif); } } /// /// Gets a comma-delimited file extension list describing the bitmap formats /// this plugin can read and/or write. /// public string ExtentsionList { get { return FreeImage.GetFIFExtensionList(fif); } } /// /// Gets a descriptive string that describes the bitmap formats /// this plugin can read and/or write. /// public string Description { get { return FreeImage.GetFIFDescription(fif); } } /// /// Returns a regular expression string that can be used by /// a regular expression engine to identify the bitmap. /// FreeImageQt makes use of this function. /// public string RegExpr { get { return FreeImage.GetFIFRegExpr(fif); } } /// /// Gets whether this plugin can load bitmaps. /// public bool SupportsReading { get { return FreeImage.FIFSupportsReading(fif); } } /// /// Gets whether this plugin can save bitmaps. /// public bool SupportsWriting { get { return FreeImage.FIFSupportsWriting(fif); } } /// /// Checks whether this plugin can save a bitmap in the desired data type. /// /// The desired image type. /// True if this plugin can save bitmaps as the desired type, else false. public bool SupportsExportType(FREE_IMAGE_TYPE type) { return FreeImage.FIFSupportsExportType(fif, type); } /// /// Checks whether this plugin can save bitmaps in the desired bit depth. /// /// The desired bit depth. /// True if this plugin can save bitmaps in the desired bit depth, else false. public bool SupportsExportBPP(int bpp) { return FreeImage.FIFSupportsExportBPP(fif, bpp); } /// /// Gets whether this plugin can load or save an ICC profile. /// public bool SupportsICCProfiles { get { return FreeImage.FIFSupportsICCProfiles(fif); } } /// /// Checks whether an extension is valid for this format. /// /// The desired extension. /// True if the extension is valid for this format, false otherwise. public bool ValidExtension(string extension) { return FreeImage.IsExtensionValidForFIF(fif, extension); } /// /// Checks whether an extension is valid for this format. /// /// The desired extension. /// The string comparison type. /// True if the extension is valid for this format, false otherwise. public bool ValidExtension(string extension, StringComparison comparisonType) { return FreeImage.IsExtensionValidForFIF(fif, extension, comparisonType); } /// /// Checks whether a filename is valid for this format. /// /// The desired filename. /// True if the filename is valid for this format, false otherwise. public bool ValidFilename(string filename) { return FreeImage.IsFilenameValidForFIF(fif, filename); } /// /// Checks whether a filename is valid for this format. /// /// The desired filename. /// The string comparison type. /// True if the filename is valid for this format, false otherwise. public bool ValidFilename(string filename, StringComparison comparisonType) { return FreeImage.IsFilenameValidForFIF(fif, filename, comparisonType); } /// /// Gets a descriptive string that describes the bitmap formats /// this plugin can read and/or write. /// /// A descriptive string that describes the bitmap formats. public override string ToString() { return Description; } } } namespace FreeImageAPI.IO { /// /// Internal class wrapping stream io functions. /// /// /// FreeImage can read files from a disk or a network drive but also allows the user to /// implement their own loading or saving functions to load them directly from an ftp or web /// server for example. /// /// In .NET streams are a common way to handle data. The FreeImageStreamIO class handles /// the loading and saving from and to streams. It implements the funtions FreeImage needs /// to load data from an an arbitrary source. /// /// The class is for internal use only. /// internal static class FreeImageStreamIO { /// /// structure that can be used to read from streams via /// . /// public static readonly FreeImageIO io; /// /// Initializes a new instances which can be used to /// create a FreeImage compatible structure. /// static FreeImageStreamIO() { io.readProc = new ReadProc(streamRead); io.writeProc = new WriteProc(streamWrite); io.seekProc = new SeekProc(streamSeek); io.tellProc = new TellProc(streamTell); } /// /// Reads the requested data from the stream and writes it to the given address. /// static unsafe uint streamRead(IntPtr buffer, uint size, uint count, fi_handle handle) { Stream stream = handle.GetObject() as Stream; if ((stream == null) || (!stream.CanRead)) { return 0; } uint readCount = 0; byte* ptr = (byte*)buffer; byte[] bufferTemp = new byte[size]; int read; while (readCount < count) { read = stream.Read(bufferTemp, 0, (int)size); if (read != (int)size) { stream.Seek(-read, SeekOrigin.Current); break; } for (int i = 0; i < read; i++, ptr++) { *ptr = bufferTemp[i]; } readCount++; } return (uint)readCount; } /// /// Reads the given data and writes it into the stream. /// static unsafe uint streamWrite(IntPtr buffer, uint size, uint count, fi_handle handle) { Stream stream = handle.GetObject() as Stream; if ((stream == null) || (!stream.CanWrite)) { return 0; } uint writeCount = 0; byte[] bufferTemp = new byte[size]; byte* ptr = (byte*)buffer; while (writeCount < count) { for (int i = 0; i < size; i++, ptr++) { bufferTemp[i] = *ptr; } try { stream.Write(bufferTemp, 0, bufferTemp.Length); } catch { return writeCount; } writeCount++; } return writeCount; } /// /// Moves the streams position. /// static int streamSeek(fi_handle handle, int offset, SeekOrigin origin) { Stream stream = handle.GetObject() as Stream; if (stream == null) { return 1; } stream.Seek((long)offset, origin); return 0; } /// /// Returns the streams current position /// static int streamTell(fi_handle handle) { Stream stream = handle.GetObject() as Stream; if (stream == null) { return -1; } return (int)stream.Position; } } } namespace FreeImageAPI.Metadata { /// /// Provides additional information specific for GIF files. This class cannot be inherited. /// public class GifInformation : MDM_ANIMATION { /// /// Initializes a new instance of the class /// with the specified . /// /// A reference to a instance. public GifInformation(FreeImageBitmap bitmap) : base(bitmap.Dib) { } /// /// Gets or sets a value indicating whether this frame uses the /// GIF image's global palette. If set to false, this /// frame uses its local palette. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? UseGlobalPalette { get { byte? useGlobalPalette = GetTagValue("NoLocalPalette"); return useGlobalPalette.HasValue ? (useGlobalPalette.Value != 0) : default(bool?); } set { byte? val = null; if (value.HasValue) { val = (byte)(value.Value ? 1 : 0); } SetTagValue("NoLocalPalette", val); } } /// /// Creates a global palette for the GIF image, intialized with all entries of the /// current local palette. /// The property will be set to true when /// invoking this method. This effectively enables the newly created global palette. /// /// /// The image does not have a palette. /// public void CreateGlobalPalette() { CreateGlobalPalette(new Palette(dib)); } /// /// Creates a global palette for the GIF image with the specified size, intialized /// with the first entries of the current local palette. /// The property will be set to true when /// invoking this method. This effectively enables the newly created global palette. /// /// The size of the newly created global palette. /// /// is a null reference. public void CreateGlobalPalette(int size) { CreateGlobalPalette(new Palette(dib), size); } /// /// Creates a global palette for the GIF image, intialized with the entries /// of the specified palette. /// The property will be set to true when /// invoking this method. This effectively enables the newly created global palette. /// /// The palette that contains the initial values for /// the newly created global palette. /// /// is a null reference. public void CreateGlobalPalette(Palette palette) { if (palette == null) { throw new ArgumentNullException("palette"); } GlobalPalette = palette; UseGlobalPalette = true; } /// /// Creates a global palette for the GIF image with the specified size, intialized /// with the first entries of the specified palette. /// The property will be set to true when /// invoking this method. This effectively enables the newly created global palette. /// /// The palette that contains the initial values for /// the newly created global palette. /// The size of the newly created global palette. /// /// is a null reference. public void CreateGlobalPalette(Palette palette, int size) { if (palette == null) { throw new ArgumentNullException("palette"); } if (size <= 0) { throw new ArgumentOutOfRangeException("size"); } Palette pal = new Palette(size); pal.CopyFrom(palette); GlobalPalette = palette; UseGlobalPalette = true; } } } namespace FreeImageAPI.Metadata { /// /// Class handling metadata of a FreeImage bitmap. /// public class ImageMetadata : IEnumerable, IComparable, IComparable { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly List data; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly FIBITMAP dib; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool hideEmptyModels; /// /// Initializes a new instance based on the specified , /// showing all known models. /// /// Handle to a FreeImage bitmap. public ImageMetadata(FIBITMAP dib) : this(dib, false) { } /// /// Initializes a new instance based on the specified , /// showing or hiding empry models. /// /// Handle to a FreeImage bitmap. /// When true, empty metadata models /// will be hidden until a tag to this model is added. public ImageMetadata(FIBITMAP dib, bool hideEmptyModels) { if (dib.IsNull) throw new ArgumentNullException("dib"); data = new List(FreeImage.FREE_IMAGE_MDMODELS.Length); this.dib = dib; this.hideEmptyModels = hideEmptyModels; data.Add(new MDM_ANIMATION(dib)); data.Add(new MDM_COMMENTS(dib)); data.Add(new MDM_CUSTOM(dib)); data.Add(new MDM_EXIF_EXIF(dib)); data.Add(new MDM_EXIF_GPS(dib)); data.Add(new MDM_INTEROP(dib)); data.Add(new MDM_EXIF_MAIN(dib)); data.Add(new MDM_MAKERNOTE(dib)); data.Add(new MDM_GEOTIFF(dib)); data.Add(new MDM_IPTC(dib)); data.Add(new MDM_NODATA(dib)); data.Add(new MDM_XMP(dib)); } /// /// Gets or sets the of the specified type. /// In case the getter returns null the model is not contained /// by the list. /// null can be used calling the setter to destroy the model. /// /// Type of the model. /// The object of the specified type. public MetadataModel this[FREE_IMAGE_MDMODEL model] { get { for (int i = 0; i < data.Count; i++) { if (data[i].Model == model) { if (!data[i].Exists && hideEmptyModels) { return null; } return data[i]; } } return null; } } /// /// Gets or sets the at the specified index. /// In case the getter returns null the model is not contained /// by the list. /// null can be used calling the setter to destroy the model. /// /// Index of the within /// this instance. /// The /// object at the specified index. public MetadataModel this[int index] { get { if (index < 0 || index >= data.Count) { throw new ArgumentOutOfRangeException("index"); } return (hideEmptyModels && !data[index].Exists) ? null : data[index]; } } /// /// Returns a list of all visible /// MetadataModels. /// public List List { get { if (hideEmptyModels) { List result = new List(); for (int i = 0; i < data.Count; i++) { if (data[i].Exists) { result.Add(data[i]); } } return result; } else { return data; } } } /// /// Adds new tag to the bitmap or updates its value in case it already exists. /// will be used as key. /// /// The tag to add or update. /// Returns true on success, false on failure. /// /// is null. public bool AddTag(MetadataTag tag) { for (int i = 0; i < data.Count; i++) { if (tag.Model == data[i].Model) { return data[i].AddTag(tag); } } return false; } /// /// Returns the number of visible /// MetadataModels. /// public int Count { get { if (hideEmptyModels) { int count = 0; for (int i = 0; i < data.Count; i++) { if (data[i].Exists) { count++; } } return count; } else { return data.Count; } } } /// /// Gets or sets whether empty /// MetadataModels are hidden. /// public bool HideEmptyModels { get { return hideEmptyModels; } set { hideEmptyModels = value; } } /// /// Retrieves an object that can iterate through the individual /// MetadataModels /// in this . /// /// An for this . public IEnumerator GetEnumerator() { if (hideEmptyModels) { List tempList = new List(data.Count); for (int i = 0; i < data.Count; i++) { if (data[i].Exists) { tempList.Add(data[i]); } } return tempList.GetEnumerator(); } else { return data.GetEnumerator(); } } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is ImageMetadata)) { throw new ArgumentException("obj"); } return CompareTo((ImageMetadata)obj); } /// /// Compares this instance with a specified object. /// /// A to compare. /// A signed number indicating the relative values of this instance /// and . public int CompareTo(ImageMetadata other) { return this.dib.CompareTo(other.dib); } } } namespace FreeImageAPI.Plugins { /// /// Class representing own FreeImage-Plugins. /// /// /// FreeImages itself is plugin based. Each supported format is integrated by a seperat plugin, /// that handles loading, saving, descriptions, identifing ect. /// And of course the user can create own plugins and use them in FreeImage. /// To do that the above mentioned predefined methodes need to be implemented. /// /// The class below handles the creation of such a plugin. The class itself is abstract /// as well as some core functions that need to be implemented. /// The class can be used to enable or disable the plugin in FreeImage after regististration or /// retrieve the formatid, assigned by FreeImage. /// The class handles the callback functions, garbage collector and pointer operation to make /// the implementation as user friendly as possible. /// /// How to: /// There are two functions that need to be implemented: /// and /// . /// is used by the constructor /// of the abstract class. FreeImage wants a list of the implemented functions. Each function is /// represented by a function pointer (a .NET ). In case a function /// is not implemented FreeImage receives an empty delegate). To tell the constructor /// which functions have been implemented the information is represented by a disjunction of /// . /// /// For example: /// return MethodFlags.LoadProc | MethodFlags.SaveProc; /// /// The above statement means that LoadProc and SaveProc have been implemented by the user. /// Keep in mind, that each function has a standard implementation that has static return /// values that may cause errors if listed in /// without a real implementation. /// /// is used by some checks of FreeImage and /// must be implemented. for example can be /// implemented if the plugin supports reading, but it doesn't have to, the plugin could only /// be used to save an already loaded bitmap in a special format. /// public abstract class LocalPlugin { /// /// Struct containing function pointers. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Plugin plugin; /// /// Delegate for register callback by FreeImage. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private InitProc initProc; /// /// The format id assiged to the plugin. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; /// /// When true the plugin was registered successfully else false. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected readonly bool registered = false; /// /// A copy of the functions used to register. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected readonly MethodFlags implementedMethods; /// /// MethodFlags defines values to fill a bitfield telling which /// functions have been implemented by a plugin. /// [Flags] protected enum MethodFlags { /// /// No mothods implemented. /// None = 0x0, /// /// DescriptionProc has been implemented. /// DescriptionProc = 0x1, /// /// ExtensionListProc has been implemented. /// ExtensionListProc = 0x2, /// /// RegExprProc has been implemented. /// RegExprProc = 0x4, /// /// OpenProc has been implemented. /// OpenProc = 0x8, /// /// CloseProc has been implemented. /// CloseProc = 0x10, /// /// PageCountProc has been implemented. /// PageCountProc = 0x20, /// /// PageCapabilityProc has been implemented. /// PageCapabilityProc = 0x40, /// /// LoadProc has been implemented. /// LoadProc = 0x80, /// /// SaveProc has been implemented. /// SaveProc = 0x100, /// /// ValidateProc has been implemented. /// ValidateProc = 0x200, /// /// MimeProc has been implemented. /// MimeProc = 0x400, /// /// SupportsExportBPPProc has been implemented. /// SupportsExportBPPProc = 0x800, /// /// SupportsExportTypeProc has been implemented. /// SupportsExportTypeProc = 0x1000, /// /// SupportsICCProfilesProc has been implemented. /// SupportsICCProfilesProc = 0x2000 } // Functions that must be implemented. /// /// Function that returns a bitfield containing the /// implemented methods. /// /// Bitfield of the implemented methods. protected abstract MethodFlags GetImplementedMethods(); /// /// Implementation of FormatProc /// /// A string containing the plugins format. protected abstract string FormatProc(); // Functions that can be implemented. /// /// Function that can be implemented. /// protected virtual string DescriptionProc() { return ""; } /// /// Function that can be implemented. /// protected virtual string ExtensionListProc() { return ""; } /// /// Function that can be implemented. /// protected virtual string RegExprProc() { return ""; } /// /// Function that can be implemented. /// protected virtual IntPtr OpenProc(ref FreeImageIO io, fi_handle handle, bool read) { return IntPtr.Zero; } /// /// Function that can be implemented. /// protected virtual void CloseProc(ref FreeImageIO io, fi_handle handle, IntPtr data) { } /// /// Function that can be implemented. /// protected virtual int PageCountProc(ref FreeImageIO io, fi_handle handle, IntPtr data) { return 0; } /// /// Function that can be implemented. /// protected virtual int PageCapabilityProc(ref FreeImageIO io, fi_handle handle, IntPtr data) { return 0; } /// /// Function that can be implemented. /// protected virtual FIBITMAP LoadProc(ref FreeImageIO io, fi_handle handle, int page, int flags, IntPtr data) { return FIBITMAP.Zero; } /// /// Function that can be implemented. /// protected virtual bool SaveProc(ref FreeImageIO io, FIBITMAP dib, fi_handle handle, int page, int flags, IntPtr data) { return false; } /// /// Function that can be implemented. /// protected virtual bool ValidateProc(ref FreeImageIO io, fi_handle handle) { return false; } /// /// Function that can be implemented. /// protected virtual string MimeProc() { return ""; } /// /// Function that can be implemented. /// protected virtual bool SupportsExportBPPProc(int bpp) { return false; } /// /// Function that can be implemented. /// protected virtual bool SupportsExportTypeProc(FREE_IMAGE_TYPE type) { return false; } /// /// Function that can be implemented. /// protected virtual bool SupportsICCProfilesProc() { return false; } /// /// The constructor automatically registeres the plugin in FreeImage. /// To do this it prepares a FreeImage defined structure with function pointers /// to the implemented functions or null if not implemented. /// Before registing the functions they are pinned in memory so the garbage collector /// can't move them around in memory after we passed there addresses to FreeImage. /// public LocalPlugin() { implementedMethods = GetImplementedMethods(); if ((implementedMethods & MethodFlags.DescriptionProc) != 0) { plugin.descriptionProc = new DescriptionProc(DescriptionProc); } if ((implementedMethods & MethodFlags.ExtensionListProc) != 0) { plugin.extensionListProc = new ExtensionListProc(ExtensionListProc); } if ((implementedMethods & MethodFlags.RegExprProc) != 0) { plugin.regExprProc = new RegExprProc(RegExprProc); } if ((implementedMethods & MethodFlags.OpenProc) != 0) { plugin.openProc = new OpenProc(OpenProc); } if ((implementedMethods & MethodFlags.CloseProc) != 0) { plugin.closeProc = new CloseProc(CloseProc); } if ((implementedMethods & MethodFlags.PageCountProc) != 0) { plugin.pageCountProc = new PageCountProc(PageCountProc); } if ((implementedMethods & MethodFlags.PageCapabilityProc) != 0) { plugin.pageCapabilityProc = new PageCapabilityProc(PageCapabilityProc); } if ((implementedMethods & MethodFlags.LoadProc) != 0) { plugin.loadProc = new LoadProc(LoadProc); } if ((implementedMethods & MethodFlags.SaveProc) != 0) { plugin.saveProc = new SaveProc(SaveProc); } if ((implementedMethods & MethodFlags.ValidateProc) != 0) { plugin.validateProc = new ValidateProc(ValidateProc); } if ((implementedMethods & MethodFlags.MimeProc) != 0) { plugin.mimeProc = new MimeProc(MimeProc); } if ((implementedMethods & MethodFlags.SupportsExportBPPProc) != 0) { plugin.supportsExportBPPProc = new SupportsExportBPPProc(SupportsExportBPPProc); } if ((implementedMethods & MethodFlags.SupportsExportTypeProc) != 0) { plugin.supportsExportTypeProc = new SupportsExportTypeProc(SupportsExportTypeProc); } if ((implementedMethods & MethodFlags.SupportsICCProfilesProc) != 0) { plugin.supportsICCProfilesProc = new SupportsICCProfilesProc(SupportsICCProfilesProc); } // FormatProc is always implemented plugin.formatProc = new FormatProc(FormatProc); // InitProc is the register call back. initProc = new InitProc(RegisterProc); // Register the plugin. The result will be saved and can be accessed later. registered = FreeImage.RegisterLocalPlugin(initProc, null, null, null, null) != FREE_IMAGE_FORMAT.FIF_UNKNOWN; if (registered) { PluginRepository.RegisterLocalPlugin(this); } } private void RegisterProc(ref Plugin plugin, int format_id) { // Copy the function pointers plugin = this.plugin; // Retrieve the format if assigned to this plugin by FreeImage. format = (FREE_IMAGE_FORMAT)format_id; } /// /// Gets or sets if the plugin is enabled. /// public bool Enabled { get { if (registered) { return (FreeImage.IsPluginEnabled(format) > 0); } else { throw new ObjectDisposedException("plugin not registered"); } } set { if (registered) { FreeImage.SetPluginEnabled(format, value); } else { throw new ObjectDisposedException("plugin not registered"); } } } /// /// Gets if the plugin was registered successfully. /// public bool Registered { get { return registered; } } /// /// Gets the FreeImage assigned to this plugin. /// public FREE_IMAGE_FORMAT Format { get { return format; } } /// /// Reads from an unmanaged stream. /// protected unsafe int Read(FreeImageIO io, fi_handle handle, uint size, uint count, ref byte[] buffer) { fixed (byte* ptr = buffer) { return (int)io.readProc(new IntPtr(ptr), size, count, handle); } } /// /// Reads a single byte from an unmanaged stream. /// protected unsafe int ReadByte(FreeImageIO io, fi_handle handle) { byte buffer = 0; return (int)io.readProc(new IntPtr(&buffer), 1, 1, handle) > 0 ? buffer : -1; } /// /// Writes to an unmanaged stream. /// protected unsafe int Write(FreeImageIO io, fi_handle handle, uint size, uint count, ref byte[] buffer) { fixed (byte* ptr = buffer) { return (int)io.writeProc(new IntPtr(ptr), size, count, handle); } } /// /// Writes a single byte to an unmanaged stream. /// protected unsafe int WriteByte(FreeImageIO io, fi_handle handle, byte value) { return (int)io.writeProc(new IntPtr(&value), 1, 1, handle); } /// /// Seeks in an unmanaged stream. /// protected int Seek(FreeImageIO io, fi_handle handle, int offset, SeekOrigin origin) { return io.seekProc(handle, offset, origin); } /// /// Retrieves the position of an unmanaged stream. /// protected int Tell(FreeImageIO io, fi_handle handle) { return io.tellProc(handle); } } } namespace FreeImageAPI { /// /// Represents unmanaged memory, containing an array of a given structure. /// /// Structuretype represented by the instance. /// /// and can not be marshalled. /// /// Use instead of and /// instead of . /// public unsafe class MemoryArray : IDisposable, ICloneable, ICollection, IEnumerable, IEquatable> where T : struct { /// /// Baseaddress of the wrapped memory. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected byte* baseAddress; /// /// Number of elements being wrapped. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected int length; /// /// Size, in bytes, of each element. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly int size; /// /// Array of T containing a single element. /// The array is used as a workaround, because there are no pointer for generic types. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected T[] buffer; /// /// Pointer to the element of buffer. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected byte* ptr; /// /// Handle for pinning buffer. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected GCHandle handle; /// /// Indicates whether the wrapped memory is handled like a bitfield. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected readonly bool isOneBit; /// /// Indicates whther the wrapped memory is handles like 4-bit blocks. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected readonly bool isFourBit; /// /// An object that can be used to synchronize access to the . /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected object syncRoot = null; static MemoryArray() { T[] dummy = new T[2]; long marshalledSize = Marshal.SizeOf(typeof(T)); long structureSize = Marshal.UnsafeAddrOfPinnedArrayElement(dummy, 1).ToInt64() - Marshal.UnsafeAddrOfPinnedArrayElement(dummy, 0).ToInt64(); if (marshalledSize != structureSize) { throw new NotSupportedException( "The desired type can not be handled, " + "because its managed and unmanaged size in bytes are different."); } size = (int)marshalledSize; } /// /// Initializes a new instance. /// protected MemoryArray() { } /// /// Initializes a new instance of the class. /// /// Address of the memory block. /// Length of the array. /// /// is null. /// /// is less or equal zero. /// /// The type is not supported. public MemoryArray(IntPtr baseAddress, int length) : this(baseAddress.ToPointer(), length) { } /// /// Initializes a new instance of the class. /// /// Address of the memory block. /// Length of the array. /// /// is null. /// /// is less or equal zero. /// /// The type is not supported. public MemoryArray(void* baseAddress, int length) { if (typeof(T) == typeof(FI1BIT)) { isOneBit = true; } else if (typeof(T) == typeof(FI4BIT)) { isFourBit = true; } if (baseAddress == null) { throw new ArgumentNullException("baseAddress"); } if (length < 1) { throw new ArgumentOutOfRangeException("length"); } this.baseAddress = (byte*)baseAddress; this.length = (int)length; if (!isOneBit && !isFourBit) { // Create an array containing a single element. // Due to the fact, that it's not possible to create pointers // of generic types, an array is used to obtain the memory // address of an element of T. this.buffer = new T[1]; // The array is pinned immediately to prevent the GC from // moving it to a different position in memory. this.handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); // The array and its content have beed pinned, so that its address // can be safely requested and stored for the whole lifetime // of the instace. this.ptr = (byte*)handle.AddrOfPinnedObject(); } } /// /// Frees the allocated . /// ~MemoryArray() { Dispose(false); } /// /// Tests whether two specified structures are equivalent. /// /// The that is to the left of the equality operator. /// The that is to the right of the equality operator. /// /// true if the two structures are equal; otherwise, false. /// public static bool operator ==(MemoryArray left, MemoryArray right) { if (object.ReferenceEquals(left, right)) { return true; } if (object.ReferenceEquals(right, null) || object.ReferenceEquals(left, null) || (left.length != right.length)) { return false; } if (left.baseAddress == right.baseAddress) { return true; } return FreeImage.CompareMemory(left.baseAddress, right.baseAddress, (uint)left.length); } /// /// Tests whether two specified structures are different. /// /// The that is to the left of the inequality operator. /// The that is to the right of the inequality operator. /// /// true if the two structures are different; otherwise, false. /// public static bool operator !=(MemoryArray left, MemoryArray right) { return (!(left == right)); } /// /// Gets the value at the specified position. /// /// A 32-bit integer that represents the position /// of the array element to get. /// The value at the specified position. /// /// is outside the range of valid indexes /// for the unmanaged array. public T GetValue(int index) { if ((index >= this.length) || (index < 0)) { throw new ArgumentOutOfRangeException("index"); } return GetValueInternal(index); } private T GetValueInternal(int index) { EnsureNotDisposed(); if (isOneBit) { return (T)(object)(FI1BIT)(((baseAddress[index / 8] & ((1 << (7 - (index % 8))))) == 0) ? 0 : 1); } else if (isFourBit) { return (T)(object)(FI4BIT)(((index % 2) == 0) ? (baseAddress[index / 2] >> 4) : (baseAddress[index / 2] & 0x0F)); } else { CopyMemory(ptr, baseAddress + (index * size), size); return buffer[0]; } } /// /// Sets a value to the element at the specified position. /// /// The new value for the specified element. /// A 32-bit integer that represents the /// position of the array element to set. /// /// is outside the range of valid indexes /// for the unmanaged array. public void SetValue(T value, int index) { if ((index >= this.length) || (index < 0)) { throw new ArgumentOutOfRangeException("index"); } SetValueInternal(value, index); } private void SetValueInternal(T value, int index) { EnsureNotDisposed(); if (isOneBit) { if ((FI1BIT)(object)value != 0) { baseAddress[index / 8] |= (byte)(1 << (7 - (index % 8))); } else { baseAddress[index / 8] &= (byte)(~(1 << (7 - (index % 8)))); } } else if (isFourBit) { if ((index % 2) == 0) { baseAddress[index / 2] = (byte)((baseAddress[index / 2] & 0x0F) | ((FI4BIT)(object)value << 4)); } else { baseAddress[index / 2] = (byte)((baseAddress[index / 2] & 0xF0) | ((FI4BIT)(object)value & 0x0F)); } } else { buffer[0] = value; CopyMemory(baseAddress + (index * size), ptr, size); } } /// /// Gets the values at the specified position and length. /// /// A 32-bit integer that represents the position /// of the array elements to get. /// A 32-bit integer that represents the length /// of the array elements to get. /// The values at the specified position and length. /// /// is outside the range of valid indexes /// for the unmanaged array or is greater than the number of elements /// from to the end of the unmanaged array. public T[] GetValues(int index, int length) { EnsureNotDisposed(); if ((index >= this.length) || (index < 0)) { throw new ArgumentOutOfRangeException("index"); } if (((index + length) > this.length) || (length < 1)) { throw new ArgumentOutOfRangeException("length"); } T[] data = new T[length]; if (isOneBit || isFourBit) { for (int i = 0; i < length; i++) { data[i] = GetValueInternal(i); } } else { GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); byte* dst = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(data, 0); CopyMemory(dst, baseAddress + (size * index), size * length); handle.Free(); } return data; } /// /// Sets the values at the specified position. /// /// An array containing the new values for the specified elements. /// A 32-bit integer that represents the position /// of the array elements to set. /// /// is a null reference (Nothing in Visual Basic). /// /// is outside the range of valid indexes /// for the unmanaged array or is greater than the number of elements /// from to the end of the array. public void SetValues(T[] values, int index) { EnsureNotDisposed(); if (values == null) { throw new ArgumentNullException("values"); } if ((index >= this.length) || (index < 0)) { throw new ArgumentOutOfRangeException("index"); } if ((index + values.Length) > this.length) { throw new ArgumentOutOfRangeException("values.Length"); } if (isOneBit || isFourBit) { for (int i = 0; i != values.Length; ) { SetValueInternal(values[i++], index++); } } else { GCHandle handle = GCHandle.Alloc(values, GCHandleType.Pinned); byte* src = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(values, 0); CopyMemory(baseAddress + (index * size), src, size * length); handle.Free(); } } /// /// Copies the entire array to a compatible one-dimensional , /// starting at the specified index of the target array. /// /// The one-dimensional that is the destination /// of the elements copied from . /// The must have zero-based indexing. /// The zero-based index in /// at which copying begins. public void CopyTo(Array array, int index) { EnsureNotDisposed(); if (!(array is T[])) { throw new InvalidCastException("array"); } try { CopyTo((T[])array, 0, index, length); } catch (ArgumentOutOfRangeException ex) { throw new ArgumentException(ex.Message, ex); } } /// /// Copies a range of elements from the unmanaged array starting at the specified /// and pastes them to /// starting at the specified . /// The length and the indexes are specified as 32-bit integers. /// /// The array that receives the data. /// A 32-bit integer that represents the index /// in the unmanaged array at which copying begins. /// A 32-bit integer that represents the index in /// the destination array at which storing begins. /// A 32-bit integer that represents the number of elements to copy. /// /// is a null reference (Nothing in Visual Basic). /// /// is outside the range of valid indexes /// for the unmanaged array or is greater than the number of elements /// from to the end of the unmanaged array /// -or- /// is outside the range of valid indexes /// for the array or is greater than the number of elements /// from to the end of the array. /// public void CopyTo(T[] array, int sourceIndex, int destinationIndex, int length) { EnsureNotDisposed(); if (array == null) { throw new ArgumentNullException("array"); } if ((sourceIndex >= this.length) || (sourceIndex < 0)) { throw new ArgumentOutOfRangeException("sourceIndex"); } if ((destinationIndex >= array.Length) || (destinationIndex < 0)) { throw new ArgumentOutOfRangeException("destinationIndex"); } if ((sourceIndex + length > this.length) || (destinationIndex + length > array.Length) || (length < 1)) { throw new ArgumentOutOfRangeException("length"); } if (isOneBit || isFourBit) { for (int i = 0; i != length; i++) { array[destinationIndex++] = GetValueInternal(sourceIndex++); } } else { GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); byte* dst = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(array, destinationIndex); CopyMemory(dst, baseAddress + (size * sourceIndex), size * length); handle.Free(); } } /// /// Copies a range of elements from the array starting at the specified /// and pastes them to the unmanaged array /// starting at the specified . /// The length and the indexes are specified as 32-bit integers. /// /// The array that holds the data. /// A 32-bit integer that represents the index /// in the array at which copying begins. /// A 32-bit integer that represents the index in /// the unmanaged array at which storing begins. /// A 32-bit integer that represents the number of elements to copy. /// /// is a null reference (Nothing in Visual Basic). /// /// is outside the range of valid indexes /// for the array or is greater than the number of elements /// from to the end of the array /// -or- /// is outside the range of valid indexes /// for the unmanaged array or is greater than the number of elements /// from to the end of the unmanaged array. /// public void CopyFrom(T[] array, int sourceIndex, int destinationIndex, int length) { EnsureNotDisposed(); if (array == null) { throw new ArgumentNullException("array"); } if ((destinationIndex >= this.length) || (destinationIndex < 0)) { throw new ArgumentOutOfRangeException("destinationIndex"); } if ((sourceIndex >= array.Length) || (sourceIndex < 0)) { throw new ArgumentOutOfRangeException("sourceIndex"); } if ((destinationIndex + length > this.length) || (sourceIndex + length > array.Length) || (length < 1)) { throw new ArgumentOutOfRangeException("length"); } if (isOneBit || isFourBit) { for (int i = 0; i != length; i++) { SetValueInternal(array[sourceIndex++], destinationIndex++); } } else { GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned); byte* src = (byte*)Marshal.UnsafeAddrOfPinnedArrayElement(array, sourceIndex); CopyMemory(baseAddress + (size * destinationIndex), src, size * length); handle.Free(); } } /// /// Returns the represented block of memory as an array of . /// /// The represented block of memory. public byte[] ToByteArray() { EnsureNotDisposed(); byte[] result; if (isOneBit) { result = new byte[(length + 7) / 8]; } else if (isFourBit) { result = new byte[(length + 3) / 4]; } else { result = new byte[size * length]; } fixed (byte* dst = result) { CopyMemory(dst, baseAddress, result.Length); } return result; } /// /// Gets or sets the value at the specified position in the array. /// /// A 32-bit integer that represents the position /// of the array element to get. /// The value at the specified position in the array. /// /// is outside the range of valid indexes /// for the unmanaged array. public T this[int index] { get { return GetValue(index); } set { SetValue(value, index); } } /// /// Gets or sets the values of the unmanaged array. /// public T[] Data { get { return GetValues(0, length); } set { if (value == null) { throw new ArgumentNullException("value"); } if (value.Length != length) { throw new ArgumentOutOfRangeException("value.Lengt"); } SetValues(value, 0); } } /// /// Gets the length of the unmanaged array. /// public int Length { get { EnsureNotDisposed(); return length; } } /// /// Gets the base address of the represented memory block. /// public IntPtr BaseAddress { get { EnsureNotDisposed(); return new IntPtr(baseAddress); } } /// /// Creates a shallow copy of the . /// /// A shallow copy of the . public object Clone() { EnsureNotDisposed(); return new MemoryArray(baseAddress, length); } /// /// Gets a 32-bit integer that represents the total number of elements /// in the . /// public int Count { get { EnsureNotDisposed(); return length; } } /// /// Gets a value indicating whether access to the /// is synchronized (thread safe). /// public bool IsSynchronized { get { EnsureNotDisposed(); return false; } } /// /// Gets an object that can be used to synchronize access to the . /// public object SyncRoot { get { EnsureNotDisposed(); if (syncRoot == null) { System.Threading.Interlocked.CompareExchange(ref syncRoot, new object(), null); } return syncRoot; } } /// /// Retrieves an object that can iterate through the individual /// elements in this . /// /// An for the . public IEnumerator GetEnumerator() { EnsureNotDisposed(); T[] values = GetValues(0, length); for (int i = 0; i != values.Length; i++) { yield return values[i]; } } /// /// Retrieves an object that can iterate through the individual /// elements in this . /// /// An for the . IEnumerator IEnumerable.GetEnumerator() { EnsureNotDisposed(); T[] values = GetValues(0, length); for (int i = 0; i != values.Length; i++) { yield return values[i]; } } /// /// Releases all ressources. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// Releases allocated handles associated with this instance. /// /// true to release managed resources. protected virtual void Dispose(bool disposing) { if (baseAddress != null) { if (handle.IsAllocated) handle.Free(); baseAddress = null; buffer = null; length = 0; syncRoot = null; } } /// /// Throws an if /// this instance is disposed. /// protected virtual void EnsureNotDisposed() { if (baseAddress == null) throw new ObjectDisposedException("This instance is disposed."); } /// /// Tests whether the specified structure is equivalent to this /// structure. /// /// The structure to test. /// true if is a /// instance equivalent to this structure; otherwise, /// false. public override bool Equals(object obj) { EnsureNotDisposed(); return ((obj is MemoryArray) && Equals((MemoryArray)obj)); } /// /// Tests whether the specified structure is equivalent to this /// structure. /// /// The structure to test. /// true if is equivalent to this /// structure; otherwise, /// false. public bool Equals(MemoryArray other) { EnsureNotDisposed(); return ((this.baseAddress == other.baseAddress) && (this.length == other.length)); } /// /// Serves as a hash function for a particular type. /// /// A hash code for the current . public override int GetHashCode() { EnsureNotDisposed(); return (int)baseAddress ^ length; } /// /// Copies a block of memory from one location to another. /// /// Pointer to the starting address of the copy destination. /// Pointer to the starting address of the block of memory to be copied. /// Size of the block of memory to copy, in bytes. protected static unsafe void CopyMemory(byte* dest, byte* src, int len) { if (len >= 0x10) { do { *((int*)dest) = *((int*)src); *((int*)(dest + 4)) = *((int*)(src + 4)); *((int*)(dest + 8)) = *((int*)(src + 8)); *((int*)(dest + 12)) = *((int*)(src + 12)); dest += 0x10; src += 0x10; } while ((len -= 0x10) >= 0x10); } if (len > 0) { if ((len & 8) != 0) { *((int*)dest) = *((int*)src); *((int*)(dest + 4)) = *((int*)(src + 4)); dest += 8; src += 8; } if ((len & 4) != 0) { *((int*)dest) = *((int*)src); dest += 4; src += 4; } if ((len & 2) != 0) { *((short*)dest) = *((short*)src); dest += 2; src += 2; } if ((len & 1) != 0) { *dest = *src; } } } } } namespace FreeImageAPI.Metadata { /// /// Base class that represents a collection of all tags contained in a metadata model. /// /// /// The MetedataModel class is an abstract base class, which is inherited by /// several derived classes, one for each existing metadata model. /// public abstract class MetadataModel : IEnumerable { /// /// Handle to the encapsulated FreeImage-bitmap. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] protected readonly FIBITMAP dib; /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. /// /// is null. protected MetadataModel(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } this.dib = dib; } /// /// Retrieves the datamodel that this instance represents. /// public abstract FREE_IMAGE_MDMODEL Model { get; } /// /// Adds new tag to the bitmap or updates its value in case it already exists. /// will be used as key. /// /// The tag to add or update. /// Returns true on success, false on failure. /// /// is null. /// /// The tags model differs from this instances model. public bool AddTag(MetadataTag tag) { if (tag == null) { throw new ArgumentNullException("tag"); } if (tag.Model != Model) { throw new ArgumentException("tag.Model"); } return tag.AddToImage(dib); } /// /// Adds a list of tags to the bitmap or updates their values in case they already exist. /// will be used as key. /// /// A list of tags to add or update. /// Returns the number of successfully added tags. /// /// is null. public int AddTag(IEnumerable list) { if (list == null) { throw new ArgumentNullException("list"); } int count = 0; foreach (MetadataTag tag in list) { if (tag.Model == Model && tag.AddToImage(dib)) { count++; } } return count; } /// /// Removes the specified tag from the bitmap. /// /// The key of the tag. /// Returns true on success, false on failure. /// /// is null. public bool RemoveTag(string key) { if (key == null) { throw new ArgumentNullException("key"); } return FreeImage.SetMetadata(Model, dib, key, FITAG.Zero); } /// /// Destroys the metadata model /// which will remove all tags of this model from the bitmap. /// /// Returns true on success, false on failure. public bool DestoryModel() { return FreeImage.SetMetadata(Model, dib, null, FITAG.Zero); } /// /// Returns the specified metadata tag. /// /// The key of the tag. /// The metadata tag. /// /// is null. public MetadataTag GetTag(string key) { if (key == null) { throw new ArgumentNullException("key"); } MetadataTag tag; return FreeImage.GetMetadata(Model, dib, key, out tag) ? tag : null; } /// /// Returns whether the specified tag exists. /// /// The key of the tag. /// True in case the tag exists, else false. /// /// is null. public bool TagExists(string key) { if (key == null) { throw new ArgumentNullException("key"); } MetadataTag tag; return FreeImage.GetMetadata(Model, dib, key, out tag); } /// /// Returns a list of all metadata tags this instance represents. /// public List List { get { List list = new List((int)FreeImage.GetMetadataCount(Model, dib)); MetadataTag tag; FIMETADATA mdHandle = FreeImage.FindFirstMetadata(Model, dib, out tag); if (!mdHandle.IsNull) { do { list.Add(tag); } while (FreeImage.FindNextMetadata(mdHandle, out tag)); FreeImage.FindCloseMetadata(mdHandle); } return list; } } /// /// Returns the tag at the given index. /// /// Index of the tag to return. /// The tag at the given index. protected MetadataTag GetTagFromIndex(int index) { if (index >= Count || index < 0) { throw new ArgumentOutOfRangeException("index"); } MetadataTag tag; int count = 0; FIMETADATA mdHandle = FreeImage.FindFirstMetadata(Model, dib, out tag); if (!mdHandle.IsNull) { try { do { if (count++ == index) { break; } } while (FreeImage.FindNextMetadata(mdHandle, out tag)); } finally { FreeImage.FindCloseMetadata(mdHandle); } } return tag; } /// /// Returns the metadata tag at the given index. This operation is slow when accessing all tags. /// /// Index of the tag. /// The metadata tag. /// /// is greater or equal Count /// or index is less than zero. public MetadataTag this[int index] { get { return GetTagFromIndex(index); } } /// /// Retrieves an object that can iterate through the individual MetadataTags in this MetadataModel. /// /// An for the /// . public IEnumerator GetEnumerator() { return List.GetEnumerator(); } /// /// Returns the number of metadata tags this instance represents. /// public int Count { get { return (int)FreeImage.GetMetadataCount(Model, dib); } } /// /// Returns whether this model exists in the bitmaps metadata structure. /// public bool Exists { get { return Count > 0; } } /// /// Searches for a pattern in each metadata tag and returns the result as a list. /// /// The regular expression to use for the search. /// A bitfield that controls which fields should be searched in. /// A list containing all found metadata tags. /// /// is null. /// /// is empty. public List RegexSearch(string searchPattern, MD_SEARCH_FLAGS flags) { if (searchPattern == null) { throw new ArgumentNullException("searchString"); } if (searchPattern.Length == 0) { throw new ArgumentException("searchString is empty"); } List result = new List(Count); Regex regex = new Regex(searchPattern); List list = List; foreach (MetadataTag tag in list) { if (((flags & MD_SEARCH_FLAGS.KEY) > 0) && regex.Match(tag.Key).Success) { result.Add(tag); continue; } if (((flags & MD_SEARCH_FLAGS.DESCRIPTION) > 0) && regex.Match(tag.Description).Success) { result.Add(tag); continue; } if (((flags & MD_SEARCH_FLAGS.TOSTRING) > 0) && regex.Match(tag.ToString()).Success) { result.Add(tag); continue; } } result.Capacity = result.Count; return result; } /// /// Returns the value of the specified tag. /// /// Type of the tag's data. /// The key of the tag. /// The value of the specified tag. protected T? GetTagValue(string key) where T : struct { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } MetadataTag tag = GetTag(key); if (tag != null) { T[] value = tag.Value as T[]; if ((value != null) && (value.Length != 0)) { return value[0]; } } return null; } /// /// Returns an array containing the data of the specified tag. /// /// The type of the tag's data. /// The key of the tag. /// An array containing the data of the specified tag. protected T[] GetTagArray(string key) where T : struct { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } MetadataTag tag = GetTag(key); return (tag == null) ? null : tag.Value as T[]; } /// /// Returns the string contained by the specified tag. /// /// The key of the tag. /// The string contained by the specified tag. protected string GetTagText(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } MetadataTag tag = GetTag(key); return (tag == null) ? null : tag.Value as string; } /// /// Returns an array containg the data of the specified tag /// as unsigned 32bit integer. /// /// The key of the tag. /// An array containg the data of the specified tag /// as unsigned 32bit integer. protected uint[] GetUInt32Array(string key) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } uint[] result = null; MetadataTag tag = GetTag(key); if (tag != null) { object value = tag.Value; if (value != null) { if (value is ushort[]) { ushort[] array = (ushort[])value; result = new uint[array.Length]; for (int i = 0, j = array.Length; i < j; i++) { result[i] = (uint)array[i]; } } else if (value is uint[]) { result = (uint[])value; } } } return result; } /// /// Returns the value of the tag as unsigned 32bit integer. /// /// The key of the tag. /// The value of the tag as unsigned 32bit integer. protected uint? GetUInt32Value(string key) { uint[] value = GetUInt32Array(key); return value == null ? default(uint?) : value[0]; } /// /// Sets the value of the specified tag. /// /// The type of the tag's data. /// The key of the tag. /// The new value of the specified tag or null. protected void SetTagValue(string key, T? value) where T : struct { SetTagValue(key, value.HasValue ? new T[] { value.Value } : null); } /// /// Sets the value of the specified tag. /// /// The key of the tag. /// The new value of the specified tag or null. protected void SetTagValue(string key, object value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (value == null) { RemoveTag(key); } else { MetadataTag tag = GetTag(key); if (tag == null) { tag = new MetadataTag(Model); tag.Key = key; tag.Value = value; AddTag(tag); } else { tag.Value = value; } } } /// /// Sets the value of the specified tag as undefined. /// /// The key of the tag. /// The new value of the specified tag or null. protected void SetTagValueUndefined(string key, byte[] value) { if (string.IsNullOrEmpty(key)) { throw new ArgumentNullException("key"); } if (value == null) { RemoveTag(key); } else { MetadataTag tag = GetTag(key); if (tag == null) { tag = new MetadataTag(Model); tag.Key = key; tag.SetValue(value, FREE_IMAGE_MDTYPE.FIDT_UNDEFINED); AddTag(tag); } else { tag.Value = value; } } } /// /// Returns the equivalent for the /// specified . /// /// The string containing the . /// The equivalent for the /// specified . protected static DirectionReference? ToDirectionType(string s) { if (string.IsNullOrEmpty(s)) return null; switch (s[0]) { case 'T': return DirectionReference.TrueDirection; case 'M': return DirectionReference.MagneticDirection; default: return DirectionReference.Undefined; } } /// /// Returns the equivalent for the /// specified . /// /// The to convert. /// The equivalent for the /// specified . protected static string ToString(DirectionReference? type) { if (type.HasValue) { switch (type.Value) { case DirectionReference.TrueDirection: return "T"; case DirectionReference.MagneticDirection: return "M"; default: return "\0"; } } return null; } /// /// Returns the equivalent for the /// specified . /// /// The string containing the . /// The equivalent for the /// specified . protected static VelocityUnit? ToUnitType(string s) { if (string.IsNullOrEmpty(s)) return null; switch (s[0]) { case 'K': return VelocityUnit.Kilometers; case 'M': return VelocityUnit.Miles; case 'N': return VelocityUnit.Knots; default: return VelocityUnit.Undefinied; } } /// /// Returns the equivalent for the /// specified . /// /// The to convert. /// The equivalent for the /// specified . protected static string ToString(VelocityUnit? type) { if (type.HasValue) { switch (type.Value) { case VelocityUnit.Kilometers: return "K"; case VelocityUnit.Miles: return "M"; case VelocityUnit.Knots: return "N"; default: return "\0"; } } return null; } /// /// Returns the equivalent for the /// specified . /// /// The string containing the . /// The equivalent for the /// specified . protected static LongitudeType? ToLongitudeType(string s) { if (string.IsNullOrEmpty(s)) return null; switch (s[0]) { case 'E': return LongitudeType.East; case 'W': return LongitudeType.West; default: return LongitudeType.Undefined; } } /// /// Returns the equivalent for the /// specified . /// /// The to convert. /// The equivalent for the /// specified . protected static string ToString(LongitudeType? type) { if (type.HasValue) { switch (type.Value) { case LongitudeType.East: return "E"; case LongitudeType.West: return "W"; default: return "\0"; } } return null; } /// /// Returns the equivalent for the /// specified . /// /// The string containing the . /// The equivalent for the /// specified . protected static LatitudeType? ToLatitudeType(string s) { if (string.IsNullOrEmpty(s)) return null; switch (s[0]) { case 'N': return LatitudeType.North; case 'S': return LatitudeType.South; default: return LatitudeType.Undefined; } } /// /// Returns the equivalent for the /// specified . /// /// The to convert. /// The equivalent for the /// specified . protected static string ToString(LatitudeType? type) { if (type.HasValue) { switch (type.Value) { case LatitudeType.North: return "N"; case LatitudeType.South: return "S"; default: return "\0"; } } return null; } /// /// Returns the equivalent for the /// specified . /// /// The string containing the . /// The equivalent for the /// specified . protected static InteroperabilityMode? ToInteroperabilityType(string s) { if (string.IsNullOrEmpty(s)) return null; if (s.StartsWith("R98")) return InteroperabilityMode.R98; if (s.StartsWith("THM")) return InteroperabilityMode.THM; return InteroperabilityMode.Undefined; } /// /// Returns the equivalent for the /// specified . /// /// The to convert. /// The equivalent for the /// specified . protected static string ToString(InteroperabilityMode? type) { if (type.HasValue) { switch (type.Value) { case InteroperabilityMode.R98: return "R98"; case InteroperabilityMode.THM: return "THM"; default: return "\0\0\0"; } } return null; } /// /// Specified different unit types. /// public enum VelocityUnit { /// /// No or unknown type. /// Undefinied, /// /// Kilometers per hour. /// Kilometers, /// /// Miles per hour. /// Miles, /// /// Knots. /// Knots, } /// /// Specifies different direction types. /// public enum DirectionReference { /// /// No or unknown direction type. /// Undefined, /// /// True direction. /// TrueDirection, /// /// Magnatic direction. /// MagneticDirection, } /// /// Specifies the type of a latitude value. /// public enum LatitudeType { /// /// No or unknown type. /// Undefined, /// /// North. /// North, /// /// South. /// South, } /// /// Specifies the type of a longitude value. /// public enum LongitudeType { /// /// No or unknown type. /// Undefined, /// /// East. /// East, /// /// West. /// West, } /// /// Specifies different altitude types. /// public enum AltitudeType { /// /// No or unknown type. /// Undefined, /// /// East. /// AboveSeaLevel, /// /// West. /// BelowSeaLevel, } /// /// Specifies interoperability types. /// public enum InteroperabilityMode { /// /// No or unknown type. /// Undefined, /// /// Indicates a file conforming to R98 file specification of Recommended /// Exif Interoperability Rules (ExifR98) or to DCF basic file stipulated /// by Design Rule for Camera File System. /// R98, /// /// Indicates a file conforming to DCF thumbnail file stipulated by Design /// rule for Camera File System. /// THM, } /// /// Specifies orientation of images. /// public enum ExifImageOrientation : ushort { /// /// Undefinied orientation. /// Undefined, /// /// TopLeft. /// TopLeft = 1, /// /// TopRight. /// TopRight, /// /// BottomRight. /// BottomRight, /// /// BottomLeft. /// BottomLeft, /// /// LeftTop. /// LeftTop, /// /// RightTop. /// RightTop, /// /// RightBottom. /// RightBottom, /// /// LeftBottom. /// LeftBottom, } /// /// Converts the model of the MetadataModel object to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { return Model.ToString(); } } } #region Metadata Models namespace FreeImageAPI.Metadata { /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_ANIMATION : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_ANIMATION(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_ANIMATION; } } /// /// Gets or sets the width of the entire canvas area, that each page is displayed in. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? LogicalWidth { get { return GetTagValue("LogicalWidth"); } set { SetTagValue("LogicalWidth", value); } } /// /// Gets or sets the height of the entire canvas area, that each page is displayed in. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? LogicalHeight { get { return GetTagValue("LogicalHeight"); } set { SetTagValue("LogicalHeight", value); } } /// /// Gets or sets the global palette of the GIF image. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public Palette GlobalPalette { get { MetadataTag mdtag = GetTag("GlobalPalette"); return (mdtag == null) ? null : new Palette(mdtag); } set { SetTagValue("GlobalPalette", (value != null) ? null : value.Data); } } /// /// Gets or sets the number of replays for the animation. /// Use 0 (zero) to specify an infinte number of replays. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? LoopCount { get { return GetTagValue("Loop"); } set { SetTagValue("Loop", value); } } /// /// Gets or sets the horizontal offset within the logical canvas area, this frame is to be displayed at. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? FrameLeft { get { return GetTagValue("FrameLeft"); } set { SetTagValue("FrameLeft", value); } } /// /// Gets or sets the vertical offset within the logical canvas area, this frame is to be displayed at. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? FrameTop { get { return GetTagValue("FrameTop"); } set { SetTagValue("FrameTop", value); } } /// /// Gets or sets a flag to supress saving the dib's attached palette /// (making it use the global palette). The local palette is the palette used by a page. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? NoLocalPalette { get { byte? useGlobalPalette = GetTagValue("NoLocalPalette"); return useGlobalPalette.HasValue ? (useGlobalPalette.Value != 0) : default(bool?); } set { byte? val = null; if (value.HasValue) { val = (byte)(value.Value ? 1 : 0); } SetTagValue("NoLocalPalette", val); } } /// /// Gets or sets a value indicating whether the image is interlaced. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? Interlaced { get { byte? useGlobalPalette = GetTagValue("Interlaced"); return useGlobalPalette.HasValue ? (useGlobalPalette.Value != 0) : default(bool?); } set { byte? val = null; if (value.HasValue) { val = (byte)(value.Value ? 1 : 0); } SetTagValue("Interlaced", val); } } /// /// Gets or sets the amout of time in milliseconds this frame is to be displayed. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? FrameTime { get { return GetTagValue("FrameTime"); } set { SetTagValue("FrameTime", value); } } /// /// Gets or sets this frame's disposal method. Generally, this method defines, how to /// remove or replace a frame when the next frame has to be drawn. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public DisposalMethodType? DisposalMethod { get { return GetTagValue("DisposalMethod"); } set { SetTagValue("DisposalMethod", value); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_COMMENTS : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_COMMENTS(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_COMMENTS; } } /// /// Gets or sets the comment of the image. /// Supported formats are JPEG, PNG and GIF. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Comment { get { return GetTagText("Comment"); } set { SetTagValue("Comment", value); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_CUSTOM : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_CUSTOM(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_CUSTOM; } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_EXIF_EXIF : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_EXIF_EXIF(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_EXIF_EXIF; } } /// /// Gets or sets the version of this standard supported. /// Constant length or 4. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] ExifVersion { get { return GetTagArray("ExifVersion"); } set { FreeImage.Resize(ref value, 4); SetTagValueUndefined("ExifVersion", value); } } /// /// Gets or sets the Flashpix format version supported by a FPXR file. /// Constant length or 4. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] FlashpixVersion { get { return GetTagArray("FlashpixVersion"); } set { FreeImage.Resize(ref value, 4); SetTagValueUndefined("FlashpixVersion", value); } } /// /// Gets or sets the color space information tag. /// See remarks for further information. /// /// /// The following values are defined: /// /// /// ID /// Description /// /// /// 1 /// sRGB (default) /// /// /// 0xFFFF /// uncalibrated /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? ColorSpace { get { return GetTagValue("ColorSpace"); } set { SetTagValue("ColorSpace", value); } } /// /// Gets or sets the valid width of a compressed image. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? PixelXDimension { get { return GetUInt32Value("PixelXDimension"); } set { RemoveTag("PixelXDimension"); if (value.HasValue) { SetTagValue("PixelXDimension", value.Value); } } } /// /// Gets or sets the valid height of a compressed image. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? PixelYDimension { get { return GetUInt32Value("PixelYDimension"); } set { RemoveTag("PixelYDimension"); if (value.HasValue) { SetTagValue("PixelYDimension", value.Value); } } } /// /// Gets or sets components configuration. See remarks for further information. /// Constant length of 4. /// /// /// The channels of each component are arranged in order from the 1st component to the 4th. /// For uncompressed data the data arrangement is given in the PhotometricInterpretation tag. /// However, since PhotometricInterpretation can only express the order of Y,Cb and Cr, /// this tag is provided for cases when compressed data uses components other than Y, Cb, /// and Cr and to enable support of other sequences. /// Default = 4 5 6 0 (if RGB uncompressed) /// The following values are defined: /// /// /// ID /// Description /// /// /// 0 /// does not exist /// /// /// 1 /// Y /// /// /// 2 /// Cb /// /// /// 3 /// Cr /// /// /// 4 /// R /// /// /// 5 /// R /// /// /// 6 /// R /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public byte[] ComponentsConfiguration { get { return GetTagArray("ComponentsConfiguration"); } set { FreeImage.Resize(ref value, 4); SetTagValueUndefined("ComponentsConfiguration", value); } } /// /// Gets or sets compression mode used for a compressed image is indicated /// in unit bits per pixel. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? CompressedBitsPerPixel { get { return GetTagValue("CompressedBitsPerPixel"); } set { SetTagValue("CompressedBitsPerPixel", value); } } /// /// Gets or sets a tag for manufacturers of Exif writers to record any desired information. /// The contents are up to the manufacturer, but this tag should not be used for any other /// than its intended purpose. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] MakerNote { get { return GetTagArray("FlashpixVersion"); } set { SetTagValueUndefined("FlashpixVersion", value); } } /// /// Gets or sets a tag for Exif users to write keywords or comments on the image besides /// those in ImageDescription, and without the character code limitations of the ImageDescription tag. /// Minimum length of 8. See remarks for further information. /// /// /// The character code used in the UserComment tag is identified based on an ID code in a fixed 8-byte /// area at the start of the tag data area. The unused portion of the area is padded with NULL. /// The ID code for the UserComment area may be a Defined code such as JIS or ASCII, or may be Undefined. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public byte[] UserComment { get { return GetTagArray("UserComment"); } set { FreeImage.Resize(ref value, 8, int.MaxValue); SetTagValueUndefined("UserComment", value); } } /// /// Gets or sets the name of an audio file related to the image data. /// The format is 8.3. /// Constant length of 12 /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string RelatedSoundFile { get { string text = GetTagText("RelatedSoundFile"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { FreeImage.Resize(ref value, 12); value += '\0'; } SetTagValue("RelatedSoundFile", value); } } /// /// Gets or sets the date and time when the original image data was generated. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public DateTime? DateTimeOriginal { get { DateTime? result = null; string text = GetTagText("DateTimeOriginal"); if (text != null) { try { result = System.DateTime.ParseExact(text, "yyyy:MM:dd HH:mm:ss\0", null); } catch { } } return result; } set { string val = null; if (value.HasValue) { try { val = value.Value.ToString("yyyy:MM:dd HH:mm:ss\0"); } catch { } } SetTagValue("DateTimeOriginal", val); } } /// /// Gets or sets the date and time when the image was stored as digital data. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public DateTime? DateTimeDigitized { get { DateTime? result = null; string text = GetTagText("DateTimeDigitized"); if (text != null) { try { result = System.DateTime.ParseExact(text, "yyyy:MM:dd HH:mm:ss\0", null); } catch { } } return result; } set { string val = null; if (value.HasValue) { try { val = value.Value.ToString("yyyy:MM:dd HH:mm:ss\0"); } catch { } } SetTagValue("DateTimeDigitized", val); } } /// /// Gets or sets a tag used to record fractions of seconds for the DateTime tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SubsecTime { get { string text = GetTagText("SubsecTime"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { value += '\0'; } SetTagValue("SubsecTime", value); } } /// /// Gets or sets a tag used to record fractions of seconds for the DateTimeOriginal tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SubsecTimeOriginal { get { string text = GetTagText("SubsecTimeOriginal"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { value += '\0'; } SetTagValue("SubsecTimeOriginal", value); } } /// /// Gets or sets a tag used to record fractions of seconds for the DateTimeDigitized tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SubsecTimeDigitized { get { string text = GetTagText("SubsecTimeDigitized"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { value += '\0'; } SetTagValue("SubsecTimeDigitized", value); } } /// /// Gets or the exposure time, given in seconds (sec). /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? ExposureTime { get { return GetTagValue("ExposureTime"); } set { SetTagValue("ExposureTime", value); } } /// /// Gets or the F number. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? FNumber { get { return GetTagValue("FNumber"); } set { SetTagValue("FNumber", value); } } /// /// Gets or sets the class of the program used by the camera to set exposure when the /// picture is taken. /// See remarks for further information. /// /// /// The following values are defined: /// /// /// ID /// Description /// /// /// 0 /// not defined /// /// /// 1 /// manual /// /// /// 2 /// normal program /// /// /// 3 /// aperture priority /// /// /// 4 /// shutter priority /// /// /// 5 /// create program /// /// /// 6 /// action program /// /// /// 7 /// portrait mode /// /// /// 8 /// landscape mode /// /// /// others /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? ExposureProgram { get { return GetTagValue("ExposureProgram"); } set { SetTagValue("ExposureProgram", value); } } /// /// Gets or sets the spectral sensitivity of each channel of the camera used. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SpectralSensitivity { get { string text = GetTagText("SpectralSensitivity"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { value += '\0'; } SetTagValue("SpectralSensitivity", value); } } /// /// Gets or sets the the ISO Speed and ISO Latitude of the camera or input device as /// specified in ISO 12232. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort[] ISOSpeedRatings { get { return GetTagArray("ISOSpeedRatings"); } set { SetTagValue("ISOSpeedRatings", value); } } /// /// Gets or sets the Opto-Electric Conversion Function (OECF) specified in ISO 14524. /// OECF is the relationship between the camera optical input and the image values. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] OECF { get { return GetTagArray("OECF"); } set { SetTagValueUndefined("OECF", value); } } /// /// Gets or sets the shutter speed. The unit is the APEX (Additive System of Photographic Exposure). /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIRational? ShutterSpeedValue { get { return GetTagValue("ShutterSpeedValue"); } set { SetTagValue("ShutterSpeedValue", value); } } /// /// Gets or sets the lens aperture. The unit is the APEX value. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? ApertureValue { get { return GetTagValue("ApertureValue"); } set { SetTagValue("ApertureValue", value); } } /// /// Gets or sets the value of brightness. The unit is the APEX value. /// Ordinarily it is given in the range of -99.99 to 99.99. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIRational? BrightnessValue { get { return GetTagValue("BrightnessValue"); } set { SetTagValue("BrightnessValue", value); } } /// /// Gets or sets the exposure bias. The unit is the APEX value. /// Ordinarily it is given in the range of �99.99 to 99.99. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIRational? ExposureBiasValue { get { return GetTagValue("ExposureBiasValue"); } set { SetTagValue("ExposureBiasValue", value); } } /// /// Gets or sets the smallest F number of the lens. The unit is the APEX value. /// Ordinarily it is given in the range of 00.00 to 99.99, /// but it is not limited to this range. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? MaxApertureValue { get { return GetTagValue("MaxApertureValue"); } set { SetTagValue("MaxApertureValue", value); } } /// /// Gets or sets distance to the subject, given in meters. /// Note that if the numerator of the recorded value is FFFFFFFF, infinity shall be indicated; /// and if the numerator is 0, distance unknown shall be indicated. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? SubjectDistance { get { return GetTagValue("SubjectDistance"); } set { SetTagValue("SubjectDistance", value); } } /// /// Gets or sets the metering mode. See remarks for further information. /// /// /// The following values are defined: /// /// /// ID /// Description /// /// /// 0 /// unknown /// /// /// 1 /// average /// /// /// 2 /// center-weighted-average /// /// /// 3 /// spot /// /// /// 4 /// multi-spot /// /// /// 5 /// pattern /// /// /// 6 /// partial /// /// /// other /// reserved /// /// /// 255 /// other /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? MeteringMode { get { return GetTagValue("MeteringMode"); } set { SetTagValue("MeteringMode", value); } } /// /// Gets or sets the kind of light source. /// See remarks for further information. /// /// /// The following values are defined: /// /// /// ID /// Description /// /// /// 0 /// unknown /// /// /// 1 /// daylight /// /// /// 2 /// fluorescent /// /// /// 3 /// tungsten /// /// /// 4 /// flash /// /// /// 9 /// fine weather /// /// /// 10 /// cloudy weather /// /// /// 11 /// shade /// /// /// 12 /// daylight fluorecent (D 5700 - 7100K) /// /// /// 13 /// day white fluorescent (N 4600 - 5400K) /// /// /// 14 /// cool white fluorescent (W 3900 - 4500K) /// /// /// 15 /// white fluorescent (WW 3200 - 3700K) /// /// /// 17 /// standard light A /// /// /// 18 /// standard light B /// /// /// 19 /// standard light C /// /// /// 20 /// D55 /// /// /// 21 /// D65 /// /// /// 22 /// D75 /// /// /// 23 /// D50 /// /// /// 24 /// ISO studio tungsten /// /// /// 255 /// other light source /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? LightSource { get { return GetTagValue("LightSource"); } set { SetTagValue("LightSource", value); } } /// /// Gets or sets a value indicating the status of flash when the image was shot. /// Bit 0 indicates the flash firing status, bits 1 and 2 indicate the flash return /// status, bits 3 and 4 indicate the flash mode, bit 5 indicates whether the flash /// function is present, and bit 6 indicates "red eye" mode. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? Flash { get { return GetTagValue("Flash"); } set { SetTagValue("Flash", value); } } /// /// Gets or sets a value indicating the location and area of the main subject in /// the overall scene. Variable length between 2 and 4. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort[] SubjectArea { get { return GetTagArray("SubjectArea"); } set { FreeImage.Resize(ref value, 2, 4); SetTagValue("SubjectArea", value); } } /// /// Gets or sets the actual focal length of the lens, in mm. /// Conversion is not made to the focal length of a 35 mm film camera. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? FocalLength { get { return GetTagValue("FocalLength"); } set { SetTagValue("FocalLength", value); } } /// /// Gets or sets the strobe energy at the time the image is captured, /// as measured in Beam Candle Power Seconds (BCPS). /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? FlashEnergy { get { return GetTagValue("FlashEnergy"); } set { SetTagValue("FlashEnergy", value); } } /// /// Gets or sets the camera or input device spatial frequency table and SFR values /// in the direction of image width, image height, and diagonal direction, /// as specified in ISO 12233. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] SpatialFrequencyResponse { get { return GetTagArray("SpatialFrequencyResponse"); } set { SetTagValueUndefined("SpatialFrequencyResponse", value); } } /// /// Gets or sets the number of pixels in the image width (X) direction per /// FocalPlaneResolutionUnit on the camera focal plane. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? FocalPlaneXResolution { get { return GetTagValue("FocalPlaneXResolution"); } set { SetTagValue("FocalPlaneXResolution", value); } } /// /// Gets or sets the number of pixels in the image height (Y) direction per /// FocalPlaneResolutionUnit on the camera focal plane. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? FocalPlaneYResolution { get { return GetTagValue("FocalPlaneYResolution"); } set { SetTagValue("FocalPlaneYResolution", value); } } /// /// Gets or sets the unit for measuring FocalPlaneXResolution and FocalPlaneYResolution. /// This value is the same as the ResolutionUnit. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? FocalPlaneResolutionUnit { get { return GetTagValue("FocalPlaneResolutionUnit"); } set { SetTagValue("FocalPlaneResolutionUnit", value); } } /// /// Gets or sets the location of the main subject in the scene. /// The value of this tag represents the pixel at the center of the main subject /// relative to the left edge, prior to rotation processing as per the Rotation tag. /// The first value indicates the X column number and second indicates the Y row number. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? SubjectLocation { get { return GetTagValue("SubjectLocation"); } set { SetTagValue("SubjectLocation", value); } } /// /// Gets or sets the exposure index selected on the camera or input device at the /// time the image was captured. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? ExposureIndex { get { return GetTagValue("ExposureIndex"); } set { SetTagValue("ExposureIndex", value); } } /// /// Gets or sets the image sensor type on the camera or input device. /// See remarks for further information. /// /// /// The following values are defined: /// /// /// ID /// Description /// /// /// 1 /// not defined /// /// /// 2 /// one-chip color area sensor /// /// /// 3 /// two-chip color area sensor /// /// /// 4 /// three-chip color area sensor /// /// /// 5 /// color sequential area sensor /// /// /// 7 /// trilinear sensor /// /// /// 8 /// color sequential linear sensor /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? SensingMethod { get { return GetTagValue("SensingMethod"); } set { SetTagValue("SensingMethod", value); } } /// /// Gets or sets the image source. If a DSC recorded the image, this tag value of this /// tag always be set to 3, indicating that the image was recorded on a DSC. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte? FileSource { get { return GetTagValue("FileSource"); } set { SetTagValueUndefined("FileSource", value.HasValue ? new byte[] { value.Value } : null); } } /// /// Gets or sets the type of scene. If a DSC recorded the image, this tag value shall /// always be set to 1, indicating that the image was directly photographed. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte? SceneType { get { return GetTagValue("SceneType"); } set { SetTagValueUndefined("SceneType", value.HasValue ? new byte[] { value.Value } : null); } } /// /// Gets or sets the color filter array (CFA) geometric pattern of the image sensor /// when a one-chip color area sensor is used. It does not apply to all sensing methods. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] CFAPattern { get { return GetTagArray("CFAPattern"); } set { SetTagValueUndefined("CFAPattern", value); } } /// /// Gets or sets the use of special processing on image data, such as rendering geared to output. /// When special processing is performed, the reader is expected to disable or minimize any /// further processing. See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// normal process /// /// /// 1 /// custom process /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? CustomRendered { get { return GetTagValue("CustomRendered"); } set { SetTagValue("CustomRendered", value); } } /// /// Gets or sets the exposure mode set when the image was shot. /// In auto-bracketing mode, the camera shoots a series of frames of the same scene /// at different exposure settings. See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// auto exposure /// /// /// 1 /// manual exposure /// /// /// 2 /// auto bracket /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? ExposureMode { get { return GetTagValue("ExposureMode"); } set { SetTagValue("ExposureMode", value); } } /// /// Gets or sets the white balance mode set when the image was shot. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// auto white balance /// /// /// 1 /// manual white balance /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? WhiteBalance { get { return GetTagValue("WhiteBalance"); } set { SetTagValue("WhiteBalance", value); } } /// /// Gets or sets the digital zoom ratio when the image was shot. /// If the numerator of the recorded value is 0, this indicates that digital zoom was not used. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? DigitalZoomRatio { get { return GetTagValue("DigitalZoomRatio"); } set { SetTagValue("DigitalZoomRatio", value); } } /// /// Gets or sets the equivalent focal length assuming a 35mm film camera, in mm. /// A value of 0 means the focal length is unknown. Note that this tag differs /// from the FocalLength tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? FocalLengthIn35mmFilm { get { return GetTagValue("DigitalZoomRatio"); } set { SetTagValue("DigitalZoomRatio", value); } } /// /// Gets or sets the type of scene that was shot. /// It can also be used to record the mode in which the image was shot. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// standard /// /// /// 1 /// landscape /// /// /// 2 /// portrait /// /// /// 3 /// night scene /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? SceneCaptureType { get { return GetTagValue("SceneCaptureType"); } set { SetTagValue("SceneCaptureType", value); } } /// /// Gets or sets the degree of overall image gain adjustment. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// none /// /// /// 1 /// low gain up /// /// /// 2 /// high gain up /// /// /// 3 /// low gain down /// /// /// 4 /// high gain down /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? GainControl { get { return GetTagValue("GainControl"); } set { SetTagValue("GainControl", value); } } /// /// Gets or sets the direction of contrast processing applied by the camera /// when the image was shot. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// normal /// /// /// 1 /// soft /// /// /// 2 /// hard /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? Contrast { get { return GetTagValue("Contrast"); } set { SetTagValue("Contrast", value); } } /// /// Gets or sets the direction of saturation processing applied by the camera /// when the image was shot. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// normal /// /// /// 1 /// low saturation /// /// /// 2 /// high saturation /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? Saturation { get { return GetTagValue("Saturation"); } set { SetTagValue("Saturation", value); } } /// /// Gets or sets the direction of sharpness processing applied by the camera /// when the image was shot. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// normal /// /// /// 1 /// soft /// /// /// 2 /// hard /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? Sharpness { get { return GetTagValue("Sharpness"); } set { SetTagValue("Sharpness", value); } } /// /// Gets or sets information on the picture-taking conditions of a particular camera model. /// The tag is used only to indicate the picture-taking conditions in the reader. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] DeviceSettingDescription { get { return GetTagArray("DeviceSettingDescription"); } set { SetTagValueUndefined("DeviceSettingDescription", value); } } /// /// Gets or sets the distance to the subject. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 0 /// unknown /// /// /// 1 /// macro /// /// /// 2 /// close view /// /// /// 3 /// distant view /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? SubjectDistanceRange { get { return GetTagValue("SubjectDistanceRange"); } set { SetTagValue("SubjectDistanceRange", value); } } /// /// Gets or sets an identifier assigned uniquely to each image. /// It is recorded as an ASCII string equivalent to hexadecimal notation and 128-bit fixed length. /// Constant length of 32. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ImageUniqueID { get { string text = GetTagText("ImageUniqueID"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { FreeImage.Resize(ref value, 32); value += '\0'; } SetTagValue("ImageUniqueID", value); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_EXIF_GPS : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_EXIF_GPS(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_EXIF_GPS; } } /// /// Gets or sets the GPS version ID. Constant length of 4. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] VersionID { get { return GetTagArray("GPSVersionID"); } set { FreeImage.Resize(ref value, 4); SetTagValue("GPSVersionID", value); } } /// /// Gets or sets a value indicating whether the /// is north or south latitude. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public LatitudeType? LatitudeDirection { get { return ToLatitudeType(GetTagText("GPSLatitudeRef")); } set { SetTagValue("GPSLatitudeRef", ToString(value) + '\0'); } } /// /// Gets or sets the latitude of the image. The latitude is expressed as three rational /// values giving the degrees, minutes, and seconds, respectively. Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational[] Latitude { get { return GetTagArray("GPSLatitude"); } set { FreeImage.Resize(ref value, 3); SetTagValue("GPSLatitude", value); } } /// /// Gets or sets a value indicating whether /// is east or west longitude. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public LongitudeType? LongitudeDirection { get { return ToLongitudeType(GetTagText("GPSLongitudeRef")); } set { SetTagValue("GPSLongitudeRef", ToString(value) + '\0'); } } /// /// Gets or sets the longitude of the image. The longitude is expressed as three rational /// values giving the degrees, minutes, and seconds, respectively. Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational[] Longitude { get { return GetTagArray("GPSLongitude"); } set { FreeImage.Resize(ref value, 3); SetTagValue("GPSLongitude", value); } } /// /// Gets a value indicating whether is sea level and the altitude /// is above sea level. If the altitude is below sea level is /// indicated as an absolute value. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public AltitudeType? AltitudeDirection { get { byte? flag = GetTagValue("GPSAltitudeRef"); if (flag.HasValue) { switch (flag.Value) { case 0: return AltitudeType.AboveSeaLevel; case 1: return AltitudeType.BelowSeaLevel; default: return AltitudeType.Undefined; } } return null; } set { byte? val = null; if (value.HasValue) { switch (value.Value) { case AltitudeType.AboveSeaLevel: val = 0; break; case AltitudeType.BelowSeaLevel: val = 1; break; default: val = 2; break; } } SetTagValue("GPSAltitudeRef", val); } } /// /// Gets or sets the altitude based on the reference in . /// Altitude is expressed as one rational value. The reference unit is meters. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? Altitude { get { return GetTagValue("GPSAltitude"); } set { SetTagValue("GPSAltitude", value); } } /// /// Gets or sets the sign of the . /// /// /// This is a derived property. There is no metadata tag directly associated /// with this property value. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public int? AltitudeSign { get { AltitudeType? seaLevel = AltitudeDirection; if (seaLevel.HasValue) { return (seaLevel.Value == AltitudeType.BelowSeaLevel) ? -1 : 1; } return null; } set { if (value.HasValue) { AltitudeDirection = value.Value >= 0 ? AltitudeType.AboveSeaLevel : AltitudeType.BelowSeaLevel; } else { AltitudeDirection = null; } } } /// /// Gets or sets the signed altitude. /// Altitude is expressed as one rational value. The reference unit is meters. /// /// /// Altitude is too large to fit into a FIRational. /// /// /// This is a derived property. There is no metadata tag directly associated /// with this property value. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public FIRational? SignedAltitude { get { FIRational? result = null; FIURational? altitude = Altitude; if (altitude.HasValue) { int sign = AltitudeSign ?? 1; if (((int)altitude.Value.Numerator < 0) || ((int)altitude.Value.Denominator < 0)) throw new OverflowException(); result = new FIRational((int)altitude.Value.Numerator * sign, (int)altitude.Value.Denominator); } return result; } set { FIURational? val = null; if (value.HasValue) { if (value.Value < 0) { AltitudeSign = -1; value = -value.Value; } else { AltitudeSign = 1; } val = new FIURational((uint)value.Value.Numerator, (uint)value.Value.Denominator); } Altitude = val; } } /// /// Gets or sets the time as UTC (Coordinated Universal Time). Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public TimeSpan? TimeStamp { get { FIURational[] stamp = GetTagArray("GPSTimeStamp"); if ((stamp == null) || stamp.Length != 3) { return null; } else { return new TimeSpan((int)stamp[0], (int)stamp[1], (int)stamp[2]); } } set { FIURational[] stamp = null; if (value.HasValue) { TimeSpan span = value.Value; stamp = new FIURational[3]; stamp[0] = span.Hours; stamp[1] = span.Minutes; stamp[2] = span.Seconds; } SetTagValue("GPSTimeStamp", stamp); } } /// /// Gets or sets the GPS satellites used for measurements. This tag can be used to describe /// the number of satellites, their ID number, angle of elevation, azimuth, SNR and other /// information in ASCII notation. The format is not specified. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Satellites { get { string result = GetTagText("GPSSatellites"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("GPSTimeStamp", value); } } /// /// Gets or sets a value indicating the status of the GPS receiver when the image was recorded. /// true indicates measurement was in progress; /// false indicates measurement was Interoperability. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? Status { get { string text = GetTagText("GPSStatus"); return string.IsNullOrEmpty(text) ? default(bool?) : text[0] == 'A'; } set { SetTagValue("GPSStatus", value.HasValue ? (value.Value ? "A\0" : "V\0") : null); } } /// /// Gets or sets a value indicating the GPS measurement mode. /// true indicates three-dimensional measurement; /// false indicated two-dimensional measurement was in progress. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? MeasureMode3D { get { string text = GetTagText("GPSMeasureMode"); return string.IsNullOrEmpty(text) ? default(bool?) : text[0] == '3'; } set { SetTagValue("GPSMeasureMode", value.HasValue ? (value.Value ? "3\0" : "2\0") : null); } } /// /// Gets or sets the GPS DOP (data degree of precision). An HDOP value is written during /// two-dimensional measurement, and PDOP during three-dimensional measurement. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? DOP { get { return GetTagValue("GPSDOP"); } set { SetTagValue("GPSDOP", value); } } /// /// Gets or sets the unit used to express the GPS receiver of movement. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public VelocityUnit? SpeedUnit { get { return ToUnitType(GetTagText("GPSSpeedRef")); } set { SetTagValue("GPSSpeedRef", ToString(value) + '\0'); } } /// /// Gets or sets the speed of GPS receiver movement. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational? Speed { get { return GetTagValue("GPSSpeed"); } set { SetTagValue("GPSSpeed", value); } } /// /// Gets or sets the reference for giving the direction of GPS receiver movement. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public DirectionReference? TrackDirectionReference { get { return ToDirectionType(GetTagText("GPSTrackRef")); } set { SetTagValue("GPSTrackRef", ToString(value) + '\0'); } } /// /// Gets or sets the direction of GPS receiver movement. /// The range of values is from 0.00 to 359.99. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational? Track { get { return GetTagValue("GPSTrack"); } set { SetTagValue("GPSTrack", value); } } /// /// Gets or sets the reference for giving the direction of GPS receiver movement. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public DirectionReference? ImageDirectionReference { get { return ToDirectionType(GetTagText("GPSImgDirectionRef")); } set { SetTagValue("GPSImgDirectionRef", ToString(value) + '\0'); } } /// /// Gets or sets the direction of the image when it was captured. /// The range of values is from 0.00 to 359.99. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational? ImageDirection { get { return GetTagValue("GPSImgDirection"); } set { SetTagValue("GPSImgDirection", value); } } /// /// Gets or sets the geodetic survey data used by the GPS receiver. If the survey data /// is restricted to Japan, the value of this tag is 'TOKYO' or 'WGS-84'. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string MapDatum { get { string result = GetTagText("GPSMapDatum"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { SetTagValue("GPSMapDatum", value + '\0'); } } /// /// Gets or sets a value indicating whether the destination point /// is north or south latitude. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public LatitudeType? DestinationLatitudeDirection { get { return ToLatitudeType(GetTagText("GPSDestLatitudeRef")); } set { SetTagValue("GPSDestLatitudeRef", ToString(value) + '\0'); } } /// /// Gets or sets the latitude of the destination point. The latitude is expressed as three rational /// values giving the degrees, minutes, and seconds, respectively. Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational[] DestinationLatitude { get { return GetTagArray("GPSDestLatitude"); } set { FreeImage.Resize(ref value, 3); SetTagValue("GPSDestLatitude", value); } } /// /// Gets or sets a value indicating whether the destination point /// is east or west longitude. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public LongitudeType? DestinationLongitudeDirection { get { return ToLongitudeType(GetTagText("GPSDestLongitudeRef")); } set { SetTagValue("GPSDestLongitudeRef", ToString(value) + '\0'); } } /// /// Gets or sets the longitude of the destination point. The longitude is expressed as three rational /// values giving the degrees, minutes, and seconds, respectively. Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational[] DestinationLongitude { get { return GetTagArray("GPSDestLongitude"); } set { FreeImage.Resize(ref value, 3); SetTagValue("GPSDestLongitude", value); } } /// /// Gets or sets the reference used for giving the bearing to the destination point. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public DirectionReference? DestinationDirectionReference { get { return ToDirectionType(GetTagText("GPSDestBearingRef")); } set { SetTagValue("GPSDestBearingRef", ToString(value) + '\0'); } } /// /// Gets or sets the bearing to the destination point. /// The range of values is from 0.00 to 359.99. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public FIURational? DestinationBearing { get { return GetTagValue("GPSDestBearing"); } set { SetTagValue("GPSDestBearing", value); } } /// /// Gets or sets the unit used to express the distance to the destination point. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public VelocityUnit? DestinationUnit { get { return ToUnitType(GetTagText("GPSDestDistanceRef")); } set { SetTagValue("GPSDestDistanceRef", ToString(value) + '\0'); } } /// /// Gets or sets a character string recording the name of the method used /// for location finding. The first byte indicates the character code used, /// and this is followed by the name of the method. Since the Type is not ASCII, /// NULL termination is not necessary. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] ProcessingMethod { get { return GetTagArray("GPSProcessingMethod"); } set { SetTagValue("GPSProcessingMethod", value); } } /// /// Gets or sets a character string recording the name of the GPS area. /// The first byte indicates the character code used, and this is followed by /// the name of the GPS area. Since the Type is not ASCII, NULL termination is /// not necessary. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public byte[] AreaInformation { get { return GetTagArray("GPSAreaInformation"); } set { SetTagValue("GPSAreaInformation", value); } } /// /// Gets or sets date and time information relative to UTC (Coordinated Universal Time). /// /// /// This is a derived property. There is no metadata tag directly associated /// with this property value. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public DateTime? DateTimeStamp { get { DateTime? date = DateStamp; TimeSpan? time = TimeStamp; if ((date == null) && (time == null)) { return null; } else { if (date == null) { date = DateTime.MinValue; } if (time == null) { time = TimeSpan.MinValue; } return date.Value.Add(time.Value); } } set { if (value.HasValue) { DateStamp = value.Value.Date; TimeStamp = value.Value.TimeOfDay; } else { DateStamp = null; TimeStamp = null; } } } /// /// Gets or sets date information relative to UTC (Coordinated Universal Time). /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public DateTime? DateStamp { get { string stamp = GetTagText("GPSDateStamp"); if (stamp != null) { try { return DateTime.ParseExact(stamp, "yyyy:MM:dd\0", null); } catch { } } return null; } set { string val = null; if (value.HasValue) { try { val = value.Value.ToString("yyyy:MM:dd\0"); } catch { } } SetTagValue("GPSDateStamp", val); } } /// /// Gets or sets a value indicating whether differential correction was applied to /// the GPS receiver. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public bool? IsDifferential { get { ushort? value = GetTagValue("GPSDifferential"); return value.HasValue ? (value != 0) : (default(bool?)); } set { SetTagValue("GPSDifferential", value.HasValue ? (object)(value.Value ? (ushort)1 : (ushort)0) : (null)); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_INTEROP : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_INTEROP(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_EXIF_INTEROP; } } /// /// Gets or sets the identification of the Interoperability rule. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public InteroperabilityMode? Identification { get { return ToInteroperabilityType(GetTagText("InteroperabilityIndex")); } set { SetTagValue("InteroperabilityIndex", ToString(value) + '\0'); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// /// This class is obsolete. Use class instead. /// [Obsolete("To be removed in future releases. Use MDM_EXIF_MAIN instead.")] public class MDM_MAIN : MDM_EXIF_MAIN { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_MAIN(FIBITMAP dib) : base(dib) { } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_EXIF_MAIN : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_EXIF_MAIN(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_EXIF_MAIN; } } /// /// Gets or sets the number of columns of image data, equal to the number /// of pixels per row. In JPEG compressed data a JPEG marker is used /// instead of this tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? ImageWidth { get { return GetUInt32Value("ImageWidth"); } set { RemoveTag("ImageWidth"); if (value.HasValue) { SetTagValue("ImageWidth", value); } } } /// /// Gets or sets number of rows of image data. In JPEG compressed data a JPEG marker /// is used instead of this tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? ImageHeight { get { return GetUInt32Value("ImageLength"); } set { RemoveTag("ImageLength"); if (value.HasValue) { SetTagValue("ImageLength", value); } } } /// /// Gets or sets number of bits per image component. In this standard /// each component of the image is 8 bits, so the value for this tag is 8. /// Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort[] BitsPerSample { get { return GetTagArray("BitsPerSample"); } set { FreeImage.Resize(ref value, 3); SetTagValue("BitsPerSample", value); } } /// /// Gets or sets compression scheme used for the image data. When a primary image /// is JPEG compressed, this designation is not necessary and is omitted. /// When thumbnails use JPEG compression, this tag value is set to 6. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? Compression { get { return GetTagValue("Compression"); } set { SetTagValue("Compression", value); } } /// /// Gets or sets pixel composition. In JPEG compressed data a JPEG marker is /// used instead of this tag. See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 2 /// RGB /// /// /// 6 /// YCbCr /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? PhotometricInterpretation { get { return GetTagValue("PhotometricInterpretation"); } set { SetTagValue("PhotometricInterpretation", value); } } /// /// Gets or sets the image orientation viewed in terms of rows and columns. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ExifImageOrientation? Orientation { get { return (ExifImageOrientation?)GetTagValue("Orientation"); } set { SetTagValue("Orientation", (ushort?)value); } } /// /// Gets or sets the number of components per pixel. Since this standard applies /// to RGB and YCbCr images, the value set for this tag is 3. In JPEG compressed /// data a JPEG marker is used instead of this tag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort? SamplesPerPixel { get { return GetTagValue("SamplesPerPixel"); } set { SetTagValue("SamplesPerPixel", value); } } /// /// Gets or sets a value that indicates whether pixel components are recorded in /// chunky or planar format. In JPEG compressed files a JPEG marker is used instead /// of this tag. If this field does not exist, the TIFF default of 1 (chunky) is assumed. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 1 /// chunky format /// /// /// 2 /// planar format /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? PlanarConfiguration { get { return GetTagValue("PlanarConfiguration"); } set { SetTagValue("PlanarConfiguration", value); } } /// /// Gets or sets the sampling ratio of chrominance components in relation to /// the luminance component. In JPEG compressed dat a JPEG marker is used /// instead of this tag. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// [2,1] /// YCbCr4:2:2 /// /// /// [2,2] /// YCbCr4:2:0 /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort[] YCbCrSubSampling { get { return GetTagArray("YCbCrSubSampling"); } set { FreeImage.Resize(ref value, 2); SetTagValue("YCbCrSubSampling", value); } } /// /// Gets or sets position of chrominance components in relation to the luminance component. /// See remarks for further information. /// /// /// This field is designated only for JPEG compressed data or uncompressed YCbCr data. /// The TIFF default is 1 (centered); but when Y:Cb:Cr = 4:2:2 it is recommended in /// this standard that 2 (co-sited) be used to record data, in order to improve the /// image quality when viewed on TV systems. /// /// When this field does not exist, the reader shall assume the TIFF default. /// In the case of Y:Cb:Cr = 4:2:0, the TIFF default (centered) is recommended. /// If the reader does not have the capability of supporting both kinds of YCbCrPositioning, /// it shall follow the TIFF default regardless of the value in this field. /// It is preferable that readers be able to support both centered and co-sited positioning. /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 1 /// centered /// /// /// 2 /// co-sited /// /// /// other /// reserved /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? YCbCrPositioning { get { return GetTagValue("YCbCrPositioning"); } set { SetTagValue("YCbCrPositioning", value); } } /// /// Gets or sets the number of pixels per /// in the direction. When the image resolution is unknown, /// 72 [dpi] is designated. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? XResolution { get { return GetTagValue("XResolution"); } set { SetTagValue("XResolution", value); } } /// /// Gets or sets the number of pixels per /// in the direction. When the image resolution is unknown, /// 72 [dpi] is designated. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational? YResolution { get { return GetTagValue("YResolution"); } set { SetTagValue("YResolution", value); } } /// /// Gets or sets the unit for measuring and . /// The same unit is used for both and . /// If the image resolution in unknown, 2 (inches) is designated. /// See remarks for further information. /// /// /// The following values are definied: /// /// /// ID /// Description /// /// /// 2 /// inches /// /// /// 3 /// YCbCr4:2:0 /// /// /// other /// centimeters /// /// /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort? ResolutionUnit { get { return GetTagValue("ResolutionUnit"); } set { SetTagValue("ResolutionUnit", value); } } /// /// Gets or sets the byte offset of that strip. /// It is recommended that this be selected so the number of strip bytes /// does not exceed 64 Kbytes. /// With JPEG compressed data this designation is not needed and is omitted. /// Constant length of * StripsPerImage. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// /// public uint[] StripOffsets { get { return GetUInt32Array("StripOffsets"); } set { RemoveTag("StripOffsets"); if (value != null) { SetTagValue("StripOffsets", value); } } } /// /// Gets or sets number of rows per strip. This is the number of rows in the image of /// one strip when an image is divided into strips. With JPEG compressed data this /// designation is not needed and is omitted. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// /// public uint? RowsPerStrip { get { return GetUInt32Value("RowsPerStrip"); } set { RemoveTag("RowsPerStrip"); if (value.HasValue) { SetTagValue("RowsPerStrip", value); } } } /// /// Gets or sets the total number of bytes in each strip. /// With JPEG compressed data this designation is not needed and is omitted. /// Constant length of * StripsPerImage. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint[] StripByteCounts { get { return GetUInt32Array("StripByteCounts"); } set { RemoveTag("StripByteCounts"); if (value != null) { SetTagValue("StripByteCounts", value); } } } /// /// Gets or sets the offset to the start byte (SOI) of JPEG compressed thumbnail data. /// This is not used for primary image JPEG data. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? JPEGInterchangeFormat { get { return GetTagValue("JPEGInterchangeFormat"); } set { SetTagValue("JPEGInterchangeFormat", value); } } /// /// Gets or sets the number of bytes of JPEG compressed thumbnail data. /// /// /// This is not used for primary image JPEG data. /// JPEG thumbnails are not divided but are recorded as a continuous /// JPEG bitstream from SOI to EOI. APPn and COM markers should not be recorded. /// Compressed thumbnails shall be recorded in no more than 64 Kbytes, /// including all other data to be recorded in APP1. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public uint? JPEGInterchangeFormatLength { get { return GetTagValue("JPEGInterchangeFormatLength"); } set { SetTagValue("JPEGInterchangeFormatLength", value); } } /// /// Gets or sets a transfer function for the image, described in tabular style. /// Constant length of 3 * 256. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public ushort[] TransferFunction { get { return GetTagArray("TransferFunction"); } set { FreeImage.Resize(ref value, 3 * 256); SetTagValue("TransferFunction", value); } } /// /// Gets or sets the chromaticity of the white point of the image. /// Constant length of 2. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational[] WhitePoint { get { return GetTagArray("WhitePoint"); } set { FreeImage.Resize(ref value, 2); SetTagValue("WhitePoint", value); } } /// /// Gets or sets the chromaticity of the three primary colors of the image. /// Constant length of 6. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational[] PrimaryChromaticities { get { return GetTagArray("PrimaryChromaticities"); } set { FreeImage.Resize(ref value, 6); SetTagValue("PrimaryChromaticities", value); } } /// /// Gets or sets the matrix coefficients for transformation from RGB to YCbCr image data. /// Constant length of 3. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational[] YCbCrCoefficients { get { return GetTagArray("YCbCrCoefficients"); } set { FreeImage.Resize(ref value, 3); SetTagValue("PrimaryChromaticities", value); } } /// /// Gets or sets the reference black point value and reference white point value. /// Constant length of 6. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public FIURational[] ReferenceBlackWhite { get { return GetTagArray("ReferenceBlackWhite"); } set { FreeImage.Resize(ref value, 6); SetTagValue("ReferenceBlackWhite", value); } } /// /// Gets or sets the date and time of image creation. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public DateTime? DateTime { get { DateTime? result = null; string text = GetTagText("DateTime"); if (text != null) { try { result = System.DateTime.ParseExact(text, "yyyy:MM:dd HH:mm:ss\0", null); } catch { } } return result; } set { string val = null; if (value.HasValue) { try { val = value.Value.ToString("yyyy:MM:dd HH:mm:ss\0"); } catch { } } SetTagValue("DateTime", val); } } /// /// Gets or sets a string giving the title of the image. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ImageDescription { get { string result = GetTagText("ImageDescription"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("ImageDescription", value); } } /// /// Gets or sets the manufacturer of the recording equipment. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Make { get { string result = GetTagText("Make"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("Make", value); } } /// /// Gets or sets the model name or model number of the equipment. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string EquipmentModel { get { string result = GetTagText("Model"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("Model", value); } } /// /// Gets or sets the name and version of the software or firmware of the camera /// or image input device used to generate the image. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Software { get { string result = GetTagText("Software"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("Software", value); } } /// /// Gets or sets the name of the camera owner, photographer or image creator. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Artist { get { string result = GetTagText("Artist"); if (!string.IsNullOrEmpty(result)) { result = result.Substring(0, result.Length - 1); } return result; } set { if (value != null) { value += '\0'; } SetTagValue("Artist", value); } } /// /// Gets or sets the photographer and editor copyrights. /// Constant length of 1-2. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string[] Copyright { get { string[] result = null; string text = GetTagText("Copyright"); if (!string.IsNullOrEmpty(text)) { result = text.Split(new char[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); } return result; } set { string val = null; if (value != null) { if (value.Length == 1) { if (value[0] != null) { val = value[0] + '\0'; } } else if (value.Length == 2) { if ((value[0] != null) && (value[1] != null)) { val = value[0] + '\0' + value[1] + '\0'; } } } SetTagValue("Copyright", val); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_MAKERNOTE : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_MAKERNOTE(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_EXIF_MAKERNOTE; } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_GEOTIFF : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_GEOTIFF(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_GEOTIFF; } } /// /// Gets or sets the value of the GeoTIFF GeoASCIIParamsTag. /// /// /// The GeoASCIIParamsTag is used to store all of the valued /// GeoKeys, referenced by the property. Since keys /// defined in the GeoKeyDirectoryTag use offsets into this tag, any special /// comments may be placed at the beginning of this tag. /// For the most part, the only keys that are valued are /// Citation keys, giving documentation and references for obscure /// projections, datums, etc. /// /// Special handling is required for -valued keys. While it /// is true that TIFF 6.0 permits multiple NULL-delimited strings within a single /// ASCII tag, the secondary strings might not appear in the output of naive /// tiffdump programs. For this reason, the NULL delimiter of each ASCII key /// value shall be converted to a "|" (pipe) character before being installed /// back into the holding tag, so that a dump of the tag /// will look like this. /// /// AsciiTag="first_value|second_value|etc...last_value|" /// /// A baseline GeoTIFF-reader must check for and convert the final "|" pipe /// character of a key back into a NULL before returning it to the client /// software. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public string GeoASCIIParams { get { string text = GetTagText("GeoASCIIParams"); if (!string.IsNullOrEmpty(text)) { text = text.Substring(0, text.Length - 1); } return text; } set { if (value != null) { value += '\0'; } SetTagValue("GeoASCIIParams", value); } } /// /// Gets or sets the value of the GeoTIFF GeoDoubleParamsTag. /// /// /// The GeoDoubleParamsTag is used to store all of the valued /// GeoKeys, referenced by the property. The meaning of /// any value of this double array is determined from the GeoKeyDirectoryTag reference /// pointing to it. values should first be converted to /// and stored here. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public double[] GeoDoubleParams { get { return GetTagArray("GeoDoubleParams"); } set { SetTagValue("GeoDoubleParams", value); } } /// /// Gets or sets the value of the GeoTIFF GeoKeyDirectoryTag. /// /// /// The GeoKeyDirectoryTag may be used to store the GeoKey Directory, which defines and /// references the GeoKeys. /// /// The tag is an array of unsigned values, which are primarily /// grouped into blocks of 4. The first 4 values are special, and contain GeoKey directory /// header information. The header values consist of the following information, in order: /// /// Header={KeyDirectoryVersion, KeyRevision, MinorRevision, NumberOfKeys} /// /// where /// /// KeyDirectoryVersion indicates the current version of Key implementation, and will /// only change if this Tag's Key structure is changed. (Similar to the TIFFVersion (42)). /// The current DirectoryVersion number is 1. This value will most likely never change, /// and may be used to ensure that this is a valid Key-implementation. /// /// KeyRevision indicates what revision of Key-Sets are used. /// /// MinorRevision indicates what set of Key-Codes are used. The complete revision number /// is denoted <KeyRevision>.<MinorRevision>. /// /// NumberOfKeys indicates how many Keys are defined by the rest of this Tag. /// /// This header is immediately followed by a collection of <NumberOfKeys> KeyEntry /// sets, each of which is also 4- long. Each KeyEntry is modeled on the /// TIFFEntry format of the TIFF directory header, and is of the form: /// /// KeyEntry = { KeyID, TIFFTagLocation, Count, Value_Offset } /// /// where /// /// KeyID gives the Key-ID value of the Key (identical in function to TIFF tag ID, /// but completely independent of TIFF tag-space), /// /// TIFFTagLocation indicates which TIFF tag contains the value(s) of the Key: if /// TIFFTagLocation is 0, then the value is , and is contained in the /// Value_Offset entry. Otherwise, the type (format) of the value is implied by the /// TIFF-Type of the tag containing the value. /// /// Count indicates the number of values in this key. /// /// Value_Offset Value_Offset indicates the index-offset into the TagArray indicated /// by TIFFTagLocation, if it is nonzero. If TIFFTagLocation is 0 (zero) , then Value_Offset /// contains the actual () value of the Key, and Count=1 is implied. /// Note that the offset is not a byte-offset, but rather an index based on the natural data /// type of the specified tag array. /// /// Following the KeyEntry definitions, the KeyDirectory tag may also contain additional /// values. For example, if a key requires multiple values, they shall /// be placed at the end of this tag, and the KeyEntry will set /// TIFFTagLocation=GeoKeyDirectoryTag, with the Value_Offset pointing to the location of the /// value(s). /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public ushort[] GeoKeyDirectory { get { return GetTagArray("GeoKeyDirectory"); } set { SetTagValue("GeoKeyDirectory", value); } } /// /// Gets or sets the value of the GeoTIFF ModelPixelScaleTag. /// /// /// The ModelPixelScaleTag tag may be used to specify the size of raster pixel spacing /// in the model space units, when the raster space can be embedded in the model space /// coordinate system without rotation, and consists of the following 3 values: /// /// ModelPixelScaleTag = (ScaleX, ScaleY, ScaleZ) /// /// where ScaleX and ScaleY give the horizontal and vertical spacing of /// raster pixels. The ScaleZ is primarily used to map the pixel value of a /// digital elevation model into the correct Z-scale, and so for most other purposes /// this value should be zero (since most model spaces are 2-D, with Z=0). /// /// A single tiepoint in the tag, together with this tag, /// completely determine the relationship between raster and model space; thus they /// comprise the two tags which Baseline GeoTIFF files most often will use to place a /// raster image into a "standard position" in model space. /// /// Like the tag, this tag information is independent of the /// XPosition, YPosition, Resolution and Orientation tags of the standard TIFF 6.0 spec. /// However, simple reversals of orientation between raster and model space /// (e.g. horizontal or vertical flips) may be indicated by reversal of sign in the /// corresponding component of the ModelPixelScaleTag. GeoTIFF compliant readers must /// honor this signreversal convention. /// /// This tag must not be used if the raster image requires rotation or shearing to place /// it into the standard model space. In such cases the transformation shall be defined /// with the more general . /// ///
Naming differences /// In the native FreeImage library and thus, in the FreeImage API documentation, this /// property's key is named GeoPixelScale. Since the GeoTIFF specification /// as well as Java's EXIFTIFFTagSet class call this tag /// , this property was renamed accordingly. /// However, when accessing this property's tag by its object, /// the native FreeImage tag key GeoPixelScale must be used. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public double[] ModelPixelScale { get { return GetTagArray("GeoPixelScale"); } set { SetTagValue("GeoPixelScale", value); } } /// /// Gets or sets the value of the GeoTIFF GeoTiePointsTag. /// /// /// The GeoTiePointsTag stores raster -> model tiepoint pairs in the order /// /// ModelTiePoints = (...,I,J,K, X,Y,Z...), /// /// where (I,J,K) is the point at location (I,J) in raster space with /// pixel-value K, and (X,Y,Z) is a vector in model space. In most cases /// the model space is only two-dimensional, in which case both K and Z should be set /// to zero; this third dimension is provided in anticipation of future support for 3D /// digital elevation models and vertical coordinate systems. /// /// A raster image may be georeferenced simply by specifying its location, size and /// orientation in the model coordinate space M. This may be done by specifying the /// location of three of the four bounding corner points. However, tiepoints are only /// to be considered exact at the points specified; thus defining such a set of /// bounding tiepoints does not imply that the model space locations of the interior /// of the image may be exactly computed by a linear interpolation of these tiepoints. /// /// However, since the relationship between the Raster space and the model space will /// often be an exact, affine transformation, this relationship can be defined using /// one set of tiepoints and the , described below, which /// gives the vertical and horizontal raster grid cell size, specified in model units. /// /// If possible, the first tiepoint placed in this tag shall be the one establishing /// the location of the point (0,0) in raster space. However, if this is not possible /// (for example, if (0,0) is goes to a part of model space in which the projection is /// ill-defined), then there is no particular order in which the tiepoints need be /// listed. /// /// For orthorectification or mosaicking applications a large number of tiepoints may /// be specified on a mesh over the raster image. However, the definition of associated /// grid interpolation methods is not in the scope of the current GeoTIFF spec. /// ///
Naming differences /// In the native FreeImage library and thus, in the FreeImage API documentation, this /// property's key is named GeoTiePoints. Since the GeoTIFF specification /// as well as Java's EXIFTIFFTagSet class call this tag /// , this property was renamed accordingly. /// However, when accessing this property's tag by its object, /// the native FreeImage tag key GeoTiePoints must be used. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public double[] ModelTiePoints { get { return GetTagArray("GeoTiePoints"); } set { SetTagValue("GeoTiePoints", value); } } /// /// Gets or sets the value of the GeoTIFF ModelTransformationMatrixTag. /// /// /// This tag may be used to specify the transformation matrix between the raster space /// (and its dependent pixel-value space) and the (possibly 3D) model space. /// ///
Naming differences /// In the native FreeImage library and thus, in the FreeImage API documentation, this /// property's key is named GeoTransformationMatrix. Since the GeoTIFF specification /// as well as Java's EXIFTIFFTagSet class call this tag /// , this property was renamed accordingly. /// However, when accessing this property's tag by its object, /// the native FreeImage tag key GeoTransformationMatrix must be used. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public double[] ModelTransformationMatrix { get { return GetTagArray("GeoTransformationMatrix"); } set { SetTagValue("GeoTransformationMatrix", value); } } /// /// Gets or sets the value of the GeoTIFF IntergraphTransformationMatrixTag. /// /// /// The IntergraphTransformationMatrixTag conflicts with an internal software implementation /// at Intergraph, and so its use is no longer encouraged. A GeoTIFF reader should look first /// for the new tag, and only if it is not found should it check for this older tag. If found, /// it should only consider it to be contain valid GeoTIFF matrix information if the tag-count /// is 16; the Intergraph version uses 17 values. /// ///
Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. ///
public double[] IntergraphTransformationMatrix { get { return GetTagArray("Intergraph TransformationMatrix"); } set { SetTagValue("Intergraph TransformationMatrix", value); } } /// /// Gets or sets the value of the GeoTIFF JPLCartoIFDOffsetTag. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public uint? JPLCartoIFDOffset { get { return GetTagValue("JPL Carto IFD offset"); } set { SetTagValue("JPL Carto IFD offset", value); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_IPTC : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_IPTC(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_IPTC; } } /// /// Gets the Application Record Version. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public short? ApplicationRecordVersion { get { return GetTagValue("ApplicationRecordVersion"); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Type Reference. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectTypeReference { get { return GetTagText("ObjectTypeReference"); } set { SetTagValue("ObjectTypeReference", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Attribute Reference. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectAttributeReference { get { return GetTagText("ObjectAttributeReference"); } set { SetTagValue("ObjectAttributeReference", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Name. /// This is also referred to as Title. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectName { get { return GetTagText("ObjectName"); } set { SetTagValue("ObjectName", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Edit Status. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string EditStatus { get { return GetTagText("EditStatus"); } set { SetTagValue("EditStatus", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Editorial Update. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string EditorialUpdate { get { return GetTagText("EditorialUpdate"); } set { SetTagValue("EditorialUpdate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Urgency. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Urgency { get { return GetTagText("Urgency"); } set { SetTagValue("Urgency", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Subject Reference. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SubjectReference { get { return GetTagText("SubjectReference"); } set { SetTagValue("SubjectReference", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Category. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Category { get { return GetTagText("Category"); } set { SetTagValue("Category", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Supplemental Categories. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SupplementalCategories { get { return GetTagText("SupplementalCategories"); } set { SetTagValue("SupplementalCategories", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Fixture Identifier. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string FixtureIdentifier { get { return GetTagText("FixtureIdentifier"); } set { SetTagValue("FixtureIdentifier", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Keywords. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Keywords { get { return GetTagText("Keywords"); } set { SetTagValue("Keywords", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Content Location Code. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ContentLocationCode { get { return GetTagText("ContentLocationCode"); } set { SetTagValue("ContentLocationCode", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Content Location Name. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ContentLocationName { get { return GetTagText("ContentLocationName"); } set { SetTagValue("ContentLocationName", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Release Date. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ReleaseDate { get { return GetTagText("ReleaseDate"); } set { SetTagValue("ReleaseDate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Release Time. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ReleaseTime { get { return GetTagText("ReleaseTime"); } set { SetTagValue("ReleaseTime", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Expiration Date. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ExpirationDate { get { return GetTagText("ExpirationDate"); } set { SetTagValue("ExpirationDate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Expiration Time. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ExpirationTime { get { return GetTagText("ExpirationTime"); } set { SetTagValue("ExpirationTime", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Special Instructions. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SpecialInstructions { get { return GetTagText("SpecialInstructions"); } set { SetTagValue("SpecialInstructions", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Action Advised. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ActionAdvised { get { return GetTagText("ActionAdvised"); } set { SetTagValue("ActionAdvised", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Reference Service. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ReferenceService { get { return GetTagText("ReferenceService"); } set { SetTagValue("ReferenceService", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Reference Date. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ReferenceDate { get { return GetTagText("ReferenceDate"); } set { SetTagValue("ReferenceDate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Reference Number. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ReferenceNumber { get { return GetTagText("ReferenceNumber"); } set { SetTagValue("ReferenceNumber", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Date Created. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string DateCreated { get { return GetTagText("DateCreated"); } set { SetTagValue("DateCreated", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Time Created. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string TimeCreated { get { return GetTagText("TimeCreated"); } set { SetTagValue("TimeCreated", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Digital Creation Date. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string DigitalCreationDate { get { return GetTagText("DigitalCreationDate"); } set { SetTagValue("DigitalCreationDate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Digital Creation Time. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string DigitalCreationTime { get { return GetTagText("DigitalCreationTime"); } set { SetTagValue("DigitalCreationTime", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Originating Program. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string OriginatingProgram { get { return GetTagText("OriginatingProgram"); } set { SetTagValue("OriginatingProgram", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Program Version. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ProgramVersion { get { return GetTagText("ProgramVersion"); } set { SetTagValue("ProgramVersion", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Cycle. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectCycle { get { return GetTagText("ObjectCycle"); } set { SetTagValue("ObjectCycle", value); } } /// /// Gets or sets the value of the IPTC/NAA tag By Line. /// This is the author's name. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ByLine { get { return GetTagText("By-line"); } set { SetTagValue("By-line", value); } } /// /// Gets or sets the value of the IPTC/NAA tag By Line Title. /// This is the author's position. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ByLineTitle { get { return GetTagText("By-lineTitle"); } set { SetTagValue("By-lineTitle", value); } } /// /// Gets or sets the value of the IPTC/NAA tag City. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string City { get { return GetTagText("City"); } set { SetTagValue("City", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Sub Location. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SubLocation { get { return GetTagText("SubLocation"); } set { SetTagValue("SubLocation", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Province State. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ProvinceState { get { return GetTagText("ProvinceState"); } set { SetTagValue("ProvinceState", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Country Primary Location Code. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string CountryPrimaryLocationCode { get { return GetTagText("Country-PrimaryLocationCode"); } set { SetTagValue("Country-PrimaryLocationCode", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Country Primary Location Name. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string CountryPrimaryLocationName { get { return GetTagText("Country-PrimaryLocationName"); } set { SetTagValue("Country-PrimaryLocationName", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Original Transmission Reference. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string OriginalTransmissionReference { get { return GetTagText("OriginalTransmissionReference"); } set { SetTagValue("OriginalTransmissionReference", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Headline. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Headline { get { return GetTagText("Headline"); } set { SetTagValue("Headline", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Credit. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Credit { get { return GetTagText("Credit"); } set { SetTagValue("Credit", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Source. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Source { get { return GetTagText("Source"); } set { SetTagValue("Source", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Copyright Notice. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string CopyrightNotice { get { return GetTagText("CopyrightNotice"); } set { SetTagValue("CopyrightNotice", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Contact. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Contact { get { return GetTagText("Contact"); } set { SetTagValue("Contact", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Caption Abstract. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string CaptionAbstract { get { return GetTagText("CaptionAbstract"); } set { SetTagValue("CaptionAbstract", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Writer Editor. /// This is also referred to as Caption Writer. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string WriterEditor { get { return GetTagText("WriterEditor"); } set { SetTagValue("WriterEditor", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Rasterized Caption. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string RasterizedCaption { get { return GetTagText("RasterizedCaption"); } set { SetTagValue("RasterizedCaption", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Image Type. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ImageType { get { return GetTagText("ImageType"); } set { SetTagValue("ImageType", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Image Orientation. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ImageOrientation { get { return GetTagText("ImageOrientation"); } set { SetTagValue("ImageOrientation", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Language Identifier. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string LanguageIdentifier { get { return GetTagText("LanguageIdentifier"); } set { SetTagValue("LanguageIdentifier", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Audio Type. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string AudioType { get { return GetTagText("AudioType"); } set { SetTagValue("AudioType", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Audio Sampling Rate. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string AudioSamplingRate { get { return GetTagText("AudioSamplingRate"); } set { SetTagValue("AudioSamplingRate", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Audio Sampling Resolution. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string AudioSamplingResolution { get { return GetTagText("AudioSamplingResolution"); } set { SetTagValue("AudioSamplingResolution", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Audio Duration. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string AudioDuration { get { return GetTagText("AudioDuration"); } set { SetTagValue("AudioDuration", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Audio Outcue. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string AudioOutcue { get { return GetTagText("AudioOutcue"); } set { SetTagValue("AudioOutcue", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Job I D. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string JobID { get { return GetTagText("JobID"); } set { SetTagValue("JobID", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Master Document I D. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string MasterDocumentID { get { return GetTagText("MasterDocumentID"); } set { SetTagValue("MasterDocumentID", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Short Document I D. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ShortDocumentID { get { return GetTagText("ShortDocumentID"); } set { SetTagValue("ShortDocumentID", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Unique Document I D. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string UniqueDocumentID { get { return GetTagText("UniqueDocumentID"); } set { SetTagValue("UniqueDocumentID", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Owner I D. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string OwnerID { get { return GetTagText("OwnerID"); } set { SetTagValue("OwnerID", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Preview File Format. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectPreviewFileFormat { get { return GetTagText("ObjectPreviewFileFormat"); } set { SetTagValue("ObjectPreviewFileFormat", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Preview File Version. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectPreviewFileVersion { get { return GetTagText("ObjectPreviewFileVersion"); } set { SetTagValue("ObjectPreviewFileVersion", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Object Preview Data. /// This is also referred to as Audio Outcue. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ObjectPreviewData { get { return GetTagText("ObjectPreviewData"); } set { SetTagValue("ObjectPreviewData", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Prefs. /// This is also referred to as photo-mechanic preferences. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Prefs { get { return GetTagText("Prefs"); } set { SetTagValue("Prefs", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Classify State. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ClassifyState { get { return GetTagText("ClassifyState"); } set { SetTagValue("ClassifyState", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Similarity Index. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string SimilarityIndex { get { return GetTagText("SimilarityIndex"); } set { SetTagValue("SimilarityIndex", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Document Notes. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string DocumentNotes { get { return GetTagText("DocumentNotes"); } set { SetTagValue("DocumentNotes", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Document History. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string DocumentHistory { get { return GetTagText("DocumentHistory"); } set { SetTagValue("DocumentHistory", value); } } /// /// Gets or sets the value of the IPTC/NAA tag Exif Camera Info. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string ExifCameraInfo { get { return GetTagText("ExifCameraInfo"); } set { SetTagValue("ExifCameraInfo", value); } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_NODATA : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_NODATA(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_NODATA; } } } /// /// Represents a collection of all tags contained in the metadata model /// . /// public class MDM_XMP : MetadataModel { /// /// Initializes a new instance of this class. /// /// Handle to a FreeImage bitmap. public MDM_XMP(FIBITMAP dib) : base(dib) { } /// /// Retrieves the datamodel that this instance represents. /// public override FREE_IMAGE_MDMODEL Model { get { return FREE_IMAGE_MDMODEL.FIMD_XMP; } } /// /// Gets or sets the XMP XML content. /// /// /// Handling of null values /// A null value indicates, that the corresponding metadata tag is not /// present in the metadata model. /// Setting this property's value to a non-null reference creates the /// metadata tag if necessary. /// Setting this property's value to a null reference deletes the /// metadata tag from the metadata model. /// public string Xml { get { return GetTagText("XMLPacket"); } set { SetTagValue("XMLPacket", value); } } /// /// Gets an initialized to read the XMP XML content. /// Returns null, if the metadata tag XMLPacket is not present in /// this model. /// public XmlReader XmlReader { get { string xmlString = Xml; if (xmlString == null) { return null; } else { MemoryStream stream = new MemoryStream(); StreamWriter writer = new StreamWriter(stream); writer.Write(xmlString); return XmlReader.Create(stream); } } } } } #endregion namespace FreeImageAPI.Metadata { /// /// Manages metadata objects and operations. /// public sealed class MetadataTag : IComparable, IComparable, ICloneable, IEquatable, IDisposable { /// /// The encapsulated FreeImage-tag. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] internal FITAG tag; /// /// The metadata model of . /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private FREE_IMAGE_MDMODEL model; /// /// Indicates whether this instance has already been disposed. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool disposed = false; /// /// Indicates whether this instance was created by FreeImage or /// by the user. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool selfCreated; /// /// List linking metadata-model and Type. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly Dictionary idList; /// /// List linking Type and metadata-model. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly Dictionary typeList; /// /// Initializes a new instance of this class. /// private MetadataTag() { } /// /// Initializes a new instance of this class. /// /// The new model the tag should be of. public MetadataTag(FREE_IMAGE_MDMODEL model) { this.model = model; tag = FreeImage.CreateTag(); selfCreated = true; if (model == FREE_IMAGE_MDMODEL.FIMD_XMP) { Key = "XMLPacket"; } } /// /// Initializes a new instance of this class. /// /// The to represent. /// The bitmap was extracted from. public MetadataTag(FITAG tag, FIBITMAP dib) { if (tag.IsNull) { throw new ArgumentNullException("tag"); } if (dib.IsNull) { throw new ArgumentNullException("dib"); } this.tag = tag; model = GetModel(dib, tag); selfCreated = false; if (model == FREE_IMAGE_MDMODEL.FIMD_XMP) { Key = "XMLPacket"; } } /// /// Initializes a new instance of this class. /// /// The to represent. /// The model of . public MetadataTag(FITAG tag, FREE_IMAGE_MDMODEL model) { if (tag.IsNull) { throw new ArgumentNullException("tag"); } this.tag = tag; this.model = model; selfCreated = false; if (model == FREE_IMAGE_MDMODEL.FIMD_XMP) { Key = "XMLPacket"; } } static MetadataTag() { idList = new Dictionary(); idList.Add(FREE_IMAGE_MDTYPE.FIDT_BYTE, typeof(byte)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_SHORT, typeof(ushort)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_LONG, typeof(uint)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_RATIONAL, typeof(FIURational)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_SBYTE, typeof(sbyte)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_UNDEFINED, typeof(byte)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_SSHORT, typeof(short)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_SLONG, typeof(int)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_SRATIONAL, typeof(FIRational)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_FLOAT, typeof(float)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_DOUBLE, typeof(double)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_IFD, typeof(uint)); idList.Add(FREE_IMAGE_MDTYPE.FIDT_PALETTE, typeof(RGBQUAD)); typeList = new Dictionary(); typeList.Add(typeof(ushort), FREE_IMAGE_MDTYPE.FIDT_SHORT); typeList.Add(typeof(ushort[]), FREE_IMAGE_MDTYPE.FIDT_SHORT); typeList.Add(typeof(string), FREE_IMAGE_MDTYPE.FIDT_ASCII); typeList.Add(typeof(uint), FREE_IMAGE_MDTYPE.FIDT_LONG); typeList.Add(typeof(uint[]), FREE_IMAGE_MDTYPE.FIDT_LONG); typeList.Add(typeof(FIURational), FREE_IMAGE_MDTYPE.FIDT_RATIONAL); typeList.Add(typeof(FIURational[]), FREE_IMAGE_MDTYPE.FIDT_RATIONAL); typeList.Add(typeof(sbyte), FREE_IMAGE_MDTYPE.FIDT_SBYTE); typeList.Add(typeof(sbyte[]), FREE_IMAGE_MDTYPE.FIDT_SBYTE); typeList.Add(typeof(byte), FREE_IMAGE_MDTYPE.FIDT_BYTE); typeList.Add(typeof(byte[]), FREE_IMAGE_MDTYPE.FIDT_BYTE); typeList.Add(typeof(short), FREE_IMAGE_MDTYPE.FIDT_SSHORT); typeList.Add(typeof(short[]), FREE_IMAGE_MDTYPE.FIDT_SSHORT); typeList.Add(typeof(int), FREE_IMAGE_MDTYPE.FIDT_SLONG); typeList.Add(typeof(int[]), FREE_IMAGE_MDTYPE.FIDT_SLONG); typeList.Add(typeof(FIRational), FREE_IMAGE_MDTYPE.FIDT_SRATIONAL); typeList.Add(typeof(FIRational[]), FREE_IMAGE_MDTYPE.FIDT_SRATIONAL); typeList.Add(typeof(float), FREE_IMAGE_MDTYPE.FIDT_FLOAT); typeList.Add(typeof(float[]), FREE_IMAGE_MDTYPE.FIDT_FLOAT); typeList.Add(typeof(double), FREE_IMAGE_MDTYPE.FIDT_DOUBLE); typeList.Add(typeof(double[]), FREE_IMAGE_MDTYPE.FIDT_DOUBLE); typeList.Add(typeof(RGBQUAD), FREE_IMAGE_MDTYPE.FIDT_PALETTE); typeList.Add(typeof(RGBQUAD[]), FREE_IMAGE_MDTYPE.FIDT_PALETTE); } /// /// Releases all resources used by the instance. /// ~MetadataTag() { Dispose(); } /// /// Determines whether two specified objects have the same value. /// /// A or a null reference (Nothing in Visual Basic). /// A or a null reference (Nothing in Visual Basic). /// /// true if the value of left is the same as the value of right; otherwise, false. /// public static bool operator ==(MetadataTag left, MetadataTag right) { // Check whether both are null if ((object)left == (object)right) { return true; } else if ((object)left == null || (object)right == null) { return false; } left.CheckDisposed(); right.CheckDisposed(); // Check all properties if ((left.Key != right.Key) || (left.ID != right.ID) || (left.Description != right.Description) || (left.Count != right.Count) || (left.Length != right.Length) || (left.Model != right.Model) || (left.Type != right.Type)) { return false; } if (left.Length == 0) { return true; } IntPtr ptr1 = FreeImage.GetTagValue(left.tag); IntPtr ptr2 = FreeImage.GetTagValue(right.tag); return FreeImage.CompareMemory(ptr1, ptr2, left.Length); } /// /// Determines whether two specified objects have different values. /// /// A or a null reference (Nothing in Visual Basic). /// A or a null reference (Nothing in Visual Basic). /// /// true if the value of left is different from the value of right; otherwise, false. /// public static bool operator !=(MetadataTag left, MetadataTag right) { return !(left == right); } /// /// Extracts the value of a instance to a handle. /// /// A instance. /// A new instance of initialized to . public static implicit operator FITAG(MetadataTag value) { return value.tag; } private static FREE_IMAGE_MDMODEL GetModel(FIBITMAP dib, FITAG tag) { FITAG value; foreach (FREE_IMAGE_MDMODEL model in FreeImage.FREE_IMAGE_MDMODELS) { FIMETADATA mData = FreeImage.FindFirstMetadata(model, dib, out value); if (mData.IsNull) { continue; } try { do { if (value == tag) { return model; } } while (FreeImage.FindNextMetadata(mData, out value)); } finally { if (!mData.IsNull) { FreeImage.FindCloseMetadata(mData); } } } throw new ArgumentException("'tag' is no metadata object of 'dib'"); } /// /// Gets the model of the metadata. /// public FREE_IMAGE_MDMODEL Model { get { CheckDisposed(); return model; } } /// /// Gets or sets the key of the metadata. /// public string Key { get { CheckDisposed(); return FreeImage.GetTagKey(tag); } set { CheckDisposed(); if ((model != FREE_IMAGE_MDMODEL.FIMD_XMP) || (value == "XMLPacket")) { FreeImage.SetTagKey(tag, value); } } } /// /// Gets or sets the description of the metadata. /// public string Description { get { CheckDisposed(); return FreeImage.GetTagDescription(tag); } set { CheckDisposed(); FreeImage.SetTagDescription(tag, value); } } /// /// Gets or sets the ID of the metadata. /// public ushort ID { get { CheckDisposed(); return FreeImage.GetTagID(tag); } set { CheckDisposed(); FreeImage.SetTagID(tag, value); } } /// /// Gets the type of the metadata. /// public FREE_IMAGE_MDTYPE Type { get { CheckDisposed(); return FreeImage.GetTagType(tag); } internal set { FreeImage.SetTagType(tag, value); } } /// /// Gets the number of elements the metadata object contains. /// public uint Count { get { CheckDisposed(); return FreeImage.GetTagCount(tag); } private set { FreeImage.SetTagCount(tag, value); } } /// /// Gets the length of the value in bytes. /// public uint Length { get { CheckDisposed(); return FreeImage.GetTagLength(tag); } private set { FreeImage.SetTagLength(tag, value); } } private unsafe byte[] GetData() { uint length = Length; byte[] value = new byte[length]; byte* ptr = (byte*)FreeImage.GetTagValue(tag); for (int i = 0; i < length; i++) { value[i] = ptr[i]; } return value; } /// /// Gets or sets the value of the metadata. /// public object Value { get { unsafe { CheckDisposed(); int cnt = (int)Count; if (Type == FREE_IMAGE_MDTYPE.FIDT_ASCII) { byte* value = (byte*)FreeImage.GetTagValue(tag); StringBuilder sb = new StringBuilder(); for (int i = 0; i < cnt; i++) { sb.Append(Convert.ToChar(value[i])); } return sb.ToString(); } else if (Type == FREE_IMAGE_MDTYPE.FIDT_NOTYPE) { return null; } Array array = Array.CreateInstance(idList[Type], Count); void* src = (void*)FreeImage.GetTagValue(tag); FreeImage.CopyMemory(array, src, Length); return array; } } set { SetValue(value); } } /// /// Sets the value of the metadata. /// In case value is of byte or byte[] is assumed. /// In case value is of uint or uint[] is assumed. /// /// New data of the metadata. /// True on success, false on failure. /// /// The data format is not supported. /// /// is null. public bool SetValue(object value) { Type type = value.GetType(); if (!typeList.ContainsKey(type)) { throw new NotSupportedException("The type of value is not supported"); } return SetValue(value, typeList[type]); } /// /// Sets the value of the metadata. /// /// New data of the metadata. /// Type of the data. /// True on success, false on failure. /// /// The data type is not supported. /// /// is null. /// /// and to not fit. public bool SetValue(object value, FREE_IMAGE_MDTYPE type) { CheckDisposed(); if ((!value.GetType().IsArray) && (!(value is string))) { Array array = Array.CreateInstance(value.GetType(), 1); array.SetValue(value, 0); return SetArrayValue(array, type); } return SetArrayValue(value, type); } /// /// Sets the value of this tag to the value of /// using the given type. /// /// New value of the tag. /// Data-type of the tag. /// /// /// is a null reference. /// /// /// is FIDT_ASCII and /// is not String. /// is not FIDT_ASCII and /// is not Array. /// /// is FIDT_NOTYPE. private unsafe bool SetArrayValue(object value, FREE_IMAGE_MDTYPE type) { if (value == null) { throw new ArgumentNullException("value"); } byte[] data = null; if (type == FREE_IMAGE_MDTYPE.FIDT_ASCII) { string tempValue = value as string; if (tempValue == null) { throw new ArgumentException("value"); } Type = type; Length = Count = (uint)tempValue.Length; data = new byte[Length]; for (int i = 0; i < tempValue.Length; i++) { data[i] = (byte)tempValue[i]; } } else if (type == FREE_IMAGE_MDTYPE.FIDT_NOTYPE) { throw new NotSupportedException("type is not supported."); } else { Array array = value as Array; if (array == null) { throw new ArgumentException("value"); } if (array.Length != 0) if (!CheckType(array.GetValue(0).GetType(), type)) throw new ArgumentException("The type of value is incorrect."); Type = type; Count = (uint)array.Length; Length = (uint)(array.Length * Marshal.SizeOf(idList[type])); data = new byte[Length]; FreeImage.CopyMemory(data, array, Length); } return FreeImage.SetTagValue(tag, data); } private static bool CheckType(Type dataType, FREE_IMAGE_MDTYPE type) { if (dataType != null) switch (type) { case FREE_IMAGE_MDTYPE.FIDT_ASCII: return dataType == typeof(string); case FREE_IMAGE_MDTYPE.FIDT_BYTE: return dataType == typeof(byte); case FREE_IMAGE_MDTYPE.FIDT_DOUBLE: return dataType == typeof(double); case FREE_IMAGE_MDTYPE.FIDT_FLOAT: return dataType == typeof(float); case FREE_IMAGE_MDTYPE.FIDT_IFD: return dataType == typeof(uint); case FREE_IMAGE_MDTYPE.FIDT_LONG: return dataType == typeof(uint); case FREE_IMAGE_MDTYPE.FIDT_NOTYPE: return false; case FREE_IMAGE_MDTYPE.FIDT_PALETTE: return dataType == typeof(RGBQUAD); case FREE_IMAGE_MDTYPE.FIDT_RATIONAL: return dataType == typeof(FIURational); case FREE_IMAGE_MDTYPE.FIDT_SBYTE: return dataType == typeof(sbyte); case FREE_IMAGE_MDTYPE.FIDT_SHORT: return dataType == typeof(ushort); case FREE_IMAGE_MDTYPE.FIDT_SLONG: return dataType == typeof(int); case FREE_IMAGE_MDTYPE.FIDT_SRATIONAL: return dataType == typeof(FIRational); case FREE_IMAGE_MDTYPE.FIDT_SSHORT: return dataType == typeof(short); case FREE_IMAGE_MDTYPE.FIDT_UNDEFINED: return dataType == typeof(byte); } return false; } /// /// Add this metadata to an image. /// /// Handle to a FreeImage bitmap. /// True on success, false on failure. public bool AddToImage(FIBITMAP dib) { CheckDisposed(); if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (Key == null) { throw new ArgumentNullException("Key"); } if (!selfCreated) { tag = FreeImage.CloneTag(tag); if (tag.IsNull) { throw new Exception("FreeImage.CloneTag() failed."); } selfCreated = true; } if (!FreeImage.SetMetadata(Model, dib, Key, tag)) { return false; } FREE_IMAGE_MDMODEL _model = Model; string _key = Key; selfCreated = false; FreeImage.DeleteTag(tag); return FreeImage.GetMetadata(_model, dib, _key, out tag); } /// /// Gets a .NET PropertyItem for this metadata tag. /// /// The .NET PropertyItem. public unsafe System.Drawing.Imaging.PropertyItem GetPropertyItem() { System.Drawing.Imaging.PropertyItem item = FreeImage.CreatePropertyItem(); item.Id = ID; item.Len = (int)Length; item.Type = (short)Type; FreeImage.CopyMemory(item.Value = new byte[item.Len], FreeImage.GetTagValue(tag), item.Len); return item; } /// /// Converts the value of the object /// to its equivalent string representation. /// /// The string representation of the value of this instance. public override string ToString() { CheckDisposed(); string fiString = FreeImage.TagToString(model, tag, 0); if (String.IsNullOrEmpty(fiString)) { return tag.ToString(); } else { return fiString; } } /// /// Creates a deep copy of this . /// /// A deep copy of this . public object Clone() { CheckDisposed(); MetadataTag clone = new MetadataTag(); clone.model = model; clone.tag = FreeImage.CloneTag(tag); clone.selfCreated = true; return clone; } /// /// Tests whether the specified object is a instance /// and is equivalent to this instance. /// /// The object to test. /// true if is a instance /// equivalent to this instance; otherwise, false. public override bool Equals(object obj) { return ((obj is MetadataTag) && (Equals((MetadataTag)obj))); } /// /// Tests whether the specified instance is equivalent to this instance. /// /// A instance to compare to this instance. /// true if equivalent to this instance; /// otherwise, false. public bool Equals(MetadataTag other) { return (this == other); } /// /// Returns a hash code for this structure. /// /// An integer value that specifies the hash code for this . public override int GetHashCode() { return tag.GetHashCode(); } /// /// Compares this instance with a specified . /// /// An object to compare with this instance. /// A 32-bit signed integer indicating the lexical relationship between the two comparands. /// is not a . public int CompareTo(object obj) { if (obj == null) { return 1; } if (!(obj is MetadataTag)) { throw new ArgumentException("obj"); } return CompareTo((MetadataTag)obj); } /// /// Compares the current instance with another object of the same type. /// /// An object to compare with this instance. /// A 32-bit signed integer that indicates the relative order of the objects being compared. public int CompareTo(MetadataTag other) { CheckDisposed(); other.CheckDisposed(); return tag.CompareTo(other.tag); } /// /// Releases all resources used by the instance. /// public void Dispose() { if (!disposed) { disposed = true; if (selfCreated) { FreeImage.DeleteTag(tag); tag = FITAG.Zero; } } } /// /// Gets whether this instance has already been disposed. /// public bool Disposed { get { return disposed; } } /// /// Throwns an in case /// this instance has already been disposed. /// private void CheckDisposed() { if (disposed) { throw new ObjectDisposedException("The object has already been disposed."); } } } } namespace FreeImageAPI { /// /// Provides methods for working with the standard bitmap palette. /// public sealed class Palette : MemoryArray { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private GCHandle paletteHandle; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private RGBQUAD[] array; /// /// Initializes a new instance for the given FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// is null. /// is not /// -or- /// has more than 8bpp. public Palette(FIBITMAP dib) : base(FreeImage.GetPalette(dib), (int)FreeImage.GetColorsUsed(dib)) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (FreeImage.GetImageType(dib) != FREE_IMAGE_TYPE.FIT_BITMAP) { throw new ArgumentException("dib"); } if (FreeImage.GetBPP(dib) > 8u) { throw new ArgumentException("dib"); } } /// /// Initializes a new instance for the given FITAG that contains /// a palette. /// /// The tag containing the palette. /// is null. /// is not /// . public Palette(FITAG tag) : base(FreeImage.GetTagValue(tag), (int)FreeImage.GetTagCount(tag)) { if (FreeImage.GetTagType(tag) != FREE_IMAGE_MDTYPE.FIDT_PALETTE) { throw new ArgumentException("tag"); } } /// /// Initializes a new instance for the given MetadataTag that contains /// a palette. /// /// The tag containing the palette. /// is null. /// is not /// . public Palette(MetadataTag tag) : base(FreeImage.GetTagValue(tag.tag), (int)tag.Count) { if (FreeImage.GetTagType(tag) != FREE_IMAGE_MDTYPE.FIDT_PALETTE) { throw new ArgumentException("tag"); } } /// /// Initializes a new instance for the given array of that contains /// a palette. /// /// A RGBQUAD array containing the palette data to initialize this instance. public Palette(RGBQUAD[] palette) { unsafe { this.array = (RGBQUAD[])palette.Clone(); this.paletteHandle = GCHandle.Alloc(array, GCHandleType.Pinned); base.baseAddress = (byte*)this.paletteHandle.AddrOfPinnedObject(); base.length = (int)this.array.Length; // Create an array containing a single element. // Due to the fact, that it's not possible to create pointers // of generic types, an array is used to obtain the memory // address of an element of T. base.buffer = new RGBQUAD[1]; // The array is pinned immediately to prevent the GC from // moving it to a different position in memory. base.handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); // The array and its content have beed pinned, so that its address // can be safely requested and stored for the whole lifetime // of the instace. base.ptr = (byte*)base.handle.AddrOfPinnedObject(); } } /// /// Initializes a new instance for the given array of that contains /// a palette. /// /// A Color array containing the palette data to initialize this instance. public Palette(Color[] palette) : this(RGBQUAD.ToRGBQUAD(palette)) { } /// /// Initializes a new instance with the specified size. /// /// The size of the palette. public Palette(int size) : this(new RGBQUAD[size]) { } /// /// Gets or sets the palette through an array of . /// public RGBQUAD[] AsArray { get { return Data; } set { Data = value; } } /// /// Get an array of that the block of memory represents. /// This property is used for internal palette operations. /// internal unsafe Color[] ColorData { get { EnsureNotDisposed(); Color[] data = new Color[length]; for (int i = 0; i < length; i++) { data[i] = Color.FromArgb((int)(((uint*)baseAddress)[i] | 0xFF000000)); } return data; } } /// /// Returns the palette as an array of . /// /// The palette as an array of . public RGBQUAD[] ToArray() { return Data; } /// /// Creates a linear palette based on the provided . /// /// The used to colorize the palette. /// /// Only call this method on linear palettes. /// public void Colorize(Color color) { Colorize(color, 0.5d); } /// /// Creates a linear palette based on the provided . /// /// The used to colorize the palette. /// The position of the color within the new palette. /// 0 < < 1. /// /// Only call this method on linear palettes. /// public void Colorize(Color color, double splitSize) { Colorize(color, (int)(length * splitSize)); } /// /// Creates a linear palette based on the provided . /// /// The used to colorize the palette. /// The position of the color within the new palette. /// 0 < < . /// /// Only call this method on linear palettes. /// public void Colorize(Color color, int splitSize) { EnsureNotDisposed(); if (splitSize < 1 || splitSize >= length) { throw new ArgumentOutOfRangeException("splitSize"); } RGBQUAD[] pal = new RGBQUAD[length]; double red = color.R; double green = color.G; double blue = color.B; int i = 0; double r, g, b; r = red / splitSize; g = green / splitSize; b = blue / splitSize; for (; i <= splitSize; i++) { pal[i].rgbRed = (byte)(i * r); pal[i].rgbGreen = (byte)(i * g); pal[i].rgbBlue = (byte)(i * b); } r = (255 - red) / (length - splitSize); g = (255 - green) / (length - splitSize); b = (255 - blue) / (length - splitSize); for (; i < length; i++) { pal[i].rgbRed = (byte)(red + ((i - splitSize) * r)); pal[i].rgbGreen = (byte)(green + ((i - splitSize) * g)); pal[i].rgbBlue = (byte)(blue + ((i - splitSize) * b)); } Data = pal; } /// /// Creates a linear grayscale palette. /// public void CreateGrayscalePalette() { Colorize(Color.White, length - 1); } /// /// Creates a linear grayscale palette. /// /// true to create an inverse grayscale palette. public void CreateGrayscalePalette(bool inverse) { Colorize(Color.White, inverse ? 0 : length - 1); } /// /// Creates a linear palette with the specified . /// /// /// A linear grayscale palette contains all shades of colors from /// black to white. This method creates a similar palette with the white /// color being replaced by the specified color. /// /// The used to create the palette. /// true to create an inverse palette. public void CreateGrayscalePalette(Color color, bool inverse) { Colorize(color, inverse ? 0 : length - 1); } /// /// Reverses the palette. /// public void Reverse() { EnsureNotDisposed(); if (array != null) { Array.Reverse(array); } else { RGBQUAD[] localArray = Data; Array.Reverse(localArray); Data = localArray; } } /// /// Copies the values from the specified to this instance. /// /// The palette to copy from. /// /// is a null reference. public void CopyFrom(Palette palette) { EnsureNotDisposed(); if (palette == null) { throw new ArgumentNullException("palette"); } CopyFrom(palette.Data, 0, 0, Math.Min(palette.Length, this.Length)); } /// /// Copies the values from the specified to this instance, /// starting at the specified . /// /// The palette to copy from. /// The position in this instance where the values /// will be copied to. /// /// is a null reference. /// /// is outside the range of valid indexes. public void CopyFrom(Palette palette, int offset) { EnsureNotDisposed(); CopyFrom(palette.Data, 0, offset, Math.Min(palette.Length, this.Length - offset)); } /// /// Saves this to the specified file. /// /// /// A string that contains the name of the file to which to save this . /// public void Save(string filename) { using (Stream stream = new FileStream(filename, FileMode.Create, FileAccess.Write)) { Save(stream); } } /// /// Saves this to the specified stream. /// /// /// The where the image will be saved. /// public void Save(Stream stream) { Save(new BinaryWriter(stream)); } /// /// Saves this using the specified writer. /// /// /// The used to save the image. /// public void Save(BinaryWriter writer) { EnsureNotDisposed(); writer.Write(ToByteArray()); } /// /// Loads a palette from the specified file. /// /// The name of the palette file. public void Load(string filename) { using (Stream stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { Load(stream); } } /// /// Loads a palette from the specified stream. /// /// The stream to load the palette from. public void Load(Stream stream) { Load(new BinaryReader(stream)); } /// /// Loads a palette from the reader. /// /// The reader to load the palette from. public void Load(BinaryReader reader) { EnsureNotDisposed(); unsafe { int size = length * sizeof(RGBQUAD); byte[] data = reader.ReadBytes(size); fixed (byte* src = data) { CopyMemory(baseAddress, src, data.Length); } } } /// /// Releases allocated handles associated with this instance. /// /// true to release managed resources. protected override void Dispose(bool disposing) { if (paletteHandle.IsAllocated) paletteHandle.Free(); array = null; base.Dispose(disposing); } } } namespace FreeImageAPI.Plugins { /// /// Class representing all registered in FreeImage. /// public static class PluginRepository { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly List plugins = null; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private static readonly List localPlugins = null; static PluginRepository() { plugins = new List(FreeImage.GetFIFCount()); localPlugins = new List(0); for (int i = 0; i < plugins.Capacity; i++) { plugins.Add(new FreeImagePlugin((FREE_IMAGE_FORMAT)i)); } } /// /// Adds local plugin to this class. /// /// The registered plugin. internal static void RegisterLocalPlugin(LocalPlugin localPlugin) { FreeImagePlugin plugin = new FreeImagePlugin(localPlugin.Format); plugins.Add(plugin); localPlugins.Add(plugin); } /// /// Returns an instance of , representing the given format. /// /// The representing format. /// An instance of . public static FreeImagePlugin Plugin(FREE_IMAGE_FORMAT fif) { return Plugin((int)fif); } /// /// Returns an instance of , /// representing the format at the given index. /// /// The index of the representing format. /// An instance of . public static FreeImagePlugin Plugin(int index) { return (index >= 0) ? plugins[index] : null; } /// /// Returns an instance of . /// is searched in: /// Format, RegExpr, /// ValidExtension and ValidFilename. /// /// The expression to search for. /// An instance of . public static FreeImagePlugin Plugin(string expression) { FreeImagePlugin result = null; expression = expression.ToLower(); foreach (FreeImagePlugin plugin in plugins) { if (plugin.Format.ToLower().Contains(expression) || plugin.RegExpr.ToLower().Contains(expression) || plugin.ValidExtension(expression, StringComparison.CurrentCultureIgnoreCase) || plugin.ValidFilename(expression, StringComparison.CurrentCultureIgnoreCase)) { result = plugin; break; } } return result; } /// /// Returns an instance of for the given format. /// /// The format of the Plugin. /// An instance of . public static FreeImagePlugin PluginFromFormat(string format) { return Plugin(FreeImage.GetFIFFromFormat(format)); } /// /// Returns an instance of for the given filename. /// /// The valid filename for the plugin. /// An instance of . public static FreeImagePlugin PluginFromFilename(string filename) { return Plugin(FreeImage.GetFIFFromFilename(filename)); } /// /// Returns an instance of for the given mime. /// /// The valid mime for the plugin. /// An instance of . public static FreeImagePlugin PluginFromMime(string mime) { return Plugin(FreeImage.GetFIFFromMime(mime)); } /// /// Gets the number of registered plugins. /// public static int FIFCount { get { return FreeImage.GetFIFCount(); } } /// /// Gets a readonly collection of all plugins. /// public static ReadOnlyCollection PluginList { get { return plugins.AsReadOnly(); } } /// /// Gets a list of plugins that are only able to /// read but not to write. /// public static List ReadOnlyPlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (p.SupportsReading && !p.SupportsWriting) { list.Add(p); } } return list; } } /// /// Gets a list of plugins that are only able to /// write but not to read. /// public static List WriteOnlyPlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (!p.SupportsReading && p.SupportsWriting) { list.Add(p); } } return list; } } /// /// Gets a list of plugins that are not able to /// read or write. /// public static List StupidPlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (!p.SupportsReading && !p.SupportsWriting) { list.Add(p); } } return list; } } /// /// Gets a list of plugins that are able to read. /// public static List ReadablePlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (p.SupportsReading) { list.Add(p); } } return list; } } /// /// Gets a list of plugins that are able to write. /// public static List WriteablePlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (p.SupportsWriting) { list.Add(p); } } return list; } } /// /// Gets a list of local plugins. /// public static ReadOnlyCollection LocalPlugins { get { return localPlugins.AsReadOnly(); } } /// /// Gets a list of built-in plugins. /// public static List BuiltInPlugins { get { List list = new List(); foreach (FreeImagePlugin p in plugins) { if (!localPlugins.Contains(p)) { list.Add(p); } } return list; } } /// /// Windows or OS/2 Bitmap File (*.BMP) /// public static FreeImagePlugin BMP { get { return plugins[0]; } } /// /// Independent JPEG Group (*.JPG, *.JIF, *.JPEG, *.JPE) /// public static FreeImagePlugin ICO { get { return plugins[1]; } } /// /// Independent JPEG Group (*.JPG, *.JIF, *.JPEG, *.JPE) /// public static FreeImagePlugin JPEG { get { return plugins[2]; } } /// /// JPEG Network Graphics (*.JNG) /// public static FreeImagePlugin JNG { get { return plugins[3]; } } /// /// Commodore 64 Koala format (*.KOA) /// public static FreeImagePlugin KOALA { get { return plugins[4]; } } /// /// Amiga IFF (*.IFF, *.LBM) /// public static FreeImagePlugin LBM { get { return plugins[5]; } } /// /// Amiga IFF (*.IFF, *.LBM) /// public static FreeImagePlugin IFF { get { return plugins[5]; } } /// /// Multiple Network Graphics (*.MNG) /// public static FreeImagePlugin MNG { get { return plugins[6]; } } /// /// Portable Bitmap (ASCII) (*.PBM) /// public static FreeImagePlugin PBM { get { return plugins[7]; } } /// /// Portable Bitmap (BINARY) (*.PBM) /// public static FreeImagePlugin PBMRAW { get { return plugins[8]; } } /// /// Kodak PhotoCD (*.PCD) /// public static FreeImagePlugin PCD { get { return plugins[9]; } } /// /// Zsoft Paintbrush PCX bitmap format (*.PCX) /// public static FreeImagePlugin PCX { get { return plugins[10]; } } /// /// Portable Graymap (ASCII) (*.PGM) /// public static FreeImagePlugin PGM { get { return plugins[11]; } } /// /// Portable Graymap (BINARY) (*.PGM) /// public static FreeImagePlugin PGMRAW { get { return plugins[12]; } } /// /// Portable Network Graphics (*.PNG) /// public static FreeImagePlugin PNG { get { return plugins[13]; } } /// /// Portable Pixelmap (ASCII) (*.PPM) /// public static FreeImagePlugin PPM { get { return plugins[14]; } } /// /// Portable Pixelmap (BINARY) (*.PPM) /// public static FreeImagePlugin PPMRAW { get { return plugins[15]; } } /// /// Sun Rasterfile (*.RAS) /// public static FreeImagePlugin RAS { get { return plugins[16]; } } /// /// truevision Targa files (*.TGA, *.TARGA) /// public static FreeImagePlugin TARGA { get { return plugins[17]; } } /// /// Tagged Image File Format (*.TIF, *.TIFF) /// public static FreeImagePlugin TIFF { get { return plugins[18]; } } /// /// Wireless Bitmap (*.WBMP) /// public static FreeImagePlugin WBMP { get { return plugins[19]; } } /// /// Adobe Photoshop (*.PSD) /// public static FreeImagePlugin PSD { get { return plugins[20]; } } /// /// Dr. Halo (*.CUT) /// public static FreeImagePlugin CUT { get { return plugins[21]; } } /// /// X11 Bitmap Format (*.XBM) /// public static FreeImagePlugin XBM { get { return plugins[22]; } } /// /// X11 Pixmap Format (*.XPM) /// public static FreeImagePlugin XPM { get { return plugins[23]; } } /// /// DirectDraw Surface (*.DDS) /// public static FreeImagePlugin DDS { get { return plugins[24]; } } /// /// Graphics Interchange Format (*.GIF) /// public static FreeImagePlugin GIF { get { return plugins[25]; } } /// /// High Dynamic Range (*.HDR) /// public static FreeImagePlugin HDR { get { return plugins[26]; } } /// /// Raw Fax format CCITT G3 (*.G3) /// public static FreeImagePlugin FAXG3 { get { return plugins[27]; } } /// /// Silicon Graphics SGI image format (*.SGI) /// public static FreeImagePlugin SGI { get { return plugins[28]; } } /// /// OpenEXR format (*.EXR) /// public static FreeImagePlugin EXR { get { return plugins[29]; } } /// /// JPEG-2000 format (*.J2K, *.J2C) /// public static FreeImagePlugin J2K { get { return plugins[30]; } } /// /// JPEG-2000 format (*.JP2) /// public static FreeImagePlugin JP2 { get { return plugins[31]; } } /// /// Portable FloatMap (*.PFM) /// public static FreeImagePlugin PFM { get { return plugins[32]; } } /// /// Macintosh PICT (*.PICT) /// public static FreeImagePlugin PICT { get { return plugins[33]; } } /// /// RAW camera image (*.*) /// public static FreeImagePlugin RAW { get { return plugins[34]; } } } } namespace FreeImageAPI { /// /// Provides methods for working with generic bitmap scanlines. /// /// Type of the bitmaps' scanlines. public sealed class Scanline : MemoryArray where T : struct { /// /// Initializes a new instance based on the specified FreeImage bitmap. /// /// Handle to a FreeImage bitmap. public Scanline(FIBITMAP dib) : this(dib, 0) { } /// /// Initializes a new instance based on the specified FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// Index of the zero based scanline. public Scanline(FIBITMAP dib, int scanline) : this(dib, scanline, (int)(typeof(T) == typeof(FI1BIT) ? FreeImage.GetBPP(dib) * FreeImage.GetWidth(dib) : typeof(T) == typeof(FI4BIT) ? FreeImage.GetBPP(dib) * FreeImage.GetWidth(dib) / 4 : (FreeImage.GetBPP(dib) * FreeImage.GetWidth(dib)) / (Marshal.SizeOf(typeof(T)) * 8))) { } internal Scanline(FIBITMAP dib, int scanline, int length) : base(FreeImage.GetScanLine(dib, scanline), length) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if ((scanline < 0) || (scanline >= FreeImage.GetHeight(dib))) { throw new ArgumentOutOfRangeException("scanline"); } } } } namespace FreeImageAPI.IO { /// /// Class wrapping streams, implementing a buffer for read data, /// so that seek operations can be made. /// /// /// FreeImage can load bitmaps from arbitrary sources. /// .NET works with different streams like File- or NetConnection-strams. /// NetConnection streams, which are used to load files from web servers, /// for example cannot seek. /// But FreeImage frequently uses the seek operation when loading bitmaps. /// StreamWrapper wrapps a stream and makes it seekable by caching all read /// data into an internal MemoryStream to jump back- and forward. /// StreamWapper is for internal use and only for loading from streams. /// internal class StreamWrapper : Stream { /// /// The stream to wrap /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly Stream stream; /// /// The caching stream /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private MemoryStream memoryStream = new MemoryStream(); /// /// Indicates if the wrapped stream reached its end /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool eos = false; /// /// Tells the wrapper to block readings or not /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool blocking = false; /// /// Indicates if the wrapped stream is disposed or not /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] private bool disposed = false; /// /// Initializes a new instance based on the specified . /// /// The stream to wrap. /// When true the wrapper always tries to read the requested /// amount of data from the wrapped stream. public StreamWrapper(Stream stream, bool blocking) { if (!stream.CanRead) { throw new ArgumentException("stream is not capable of reading."); } this.stream = stream; this.blocking = blocking; } /// /// Releases all resources used by the instance. /// ~StreamWrapper() { Dispose(false); } // The wrapper only accepts readable streams public override bool CanRead { get { checkDisposed(); return true; } } // We implement that feature public override bool CanSeek { get { checkDisposed(); return true; } } // The wrapper is readonly public override bool CanWrite { get { checkDisposed(); return false; } } // Just forward it public override void Flush() { checkDisposed(); stream.Flush(); } // Calling this property will cause the wrapper to read the stream // to its end and cache it completely. public override long Length { get { checkDisposed(); if (!eos) { Fill(); } return memoryStream.Length; } } // Gets or sets the current position public override long Position { get { checkDisposed(); return memoryStream.Position; } set { checkDisposed(); Seek(value, SeekOrigin.Begin); } } // Implements the reading feature public override int Read(byte[] buffer, int offset, int count) { checkDisposed(); // total bytes read from memory-stream int memoryBytes = 0; // total bytes read from the original stream int streamBytes = 0; memoryBytes = memoryStream.Read(buffer, offset, count); if ((count > memoryBytes) && (!eos)) { // read the rest from the original stream (can be 0 bytes) do { int read = stream.Read( buffer, offset + memoryBytes + streamBytes, count - memoryBytes - streamBytes); streamBytes += read; if (read == 0) { eos = true; break; } if (!blocking) { break; } } while ((memoryBytes + streamBytes) < count); // copy the bytes from the original stream into the memory stream // if 0 bytes were read we write 0 so the memory-stream is not changed memoryStream.Write(buffer, offset + memoryBytes, streamBytes); } return memoryBytes + streamBytes; } // Implements the seeking feature public override long Seek(long offset, SeekOrigin origin) { checkDisposed(); long newPosition = 0L; // get new position switch (origin) { case SeekOrigin.Begin: newPosition = offset; break; case SeekOrigin.Current: newPosition = memoryStream.Position + offset; break; case SeekOrigin.End: // to seek from the end have have to read to the end first if (!eos) { Fill(); } newPosition = memoryStream.Length + offset; break; default: throw new ArgumentOutOfRangeException("origin"); } // in case the new position is beyond the memory-streams end // and the original streams end hasn't been reached // the original stream is read until either the stream ends or // enough bytes have been read if ((newPosition > memoryStream.Length) && (!eos)) { memoryStream.Position = memoryStream.Length; int bytesToRead = (int)(newPosition - memoryStream.Length); byte[] buffer = new byte[1024]; do { bytesToRead -= Read(buffer, 0, (bytesToRead >= buffer.Length) ? buffer.Length : bytesToRead); } while ((bytesToRead > 0) && (!eos)); } memoryStream.Position = (newPosition <= memoryStream.Length) ? newPosition : memoryStream.Length; return 0; } // No write-support public override void SetLength(long value) { throw new Exception("The method or operation is not implemented."); } // No write-support public override void Write(byte[] buffer, int offset, int count) { throw new Exception("The method or operation is not implemented."); } public void Reset() { checkDisposed(); Position = 0; } // Reads the wrapped stream until its end. private void Fill() { if (!eos) { memoryStream.Position = memoryStream.Length; int bytesRead = 0; byte[] buffer = new byte[1024]; do { bytesRead = stream.Read(buffer, 0, buffer.Length); memoryStream.Write(buffer, 0, bytesRead); } while (bytesRead != 0); eos = true; } } public new void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private new void Dispose(bool disposing) { if (!disposed) { disposed = true; if (disposing) { if (memoryStream != null) { memoryStream.Dispose(); } } } } public bool Disposed { get { return disposed; } } private void checkDisposed() { if (disposed) throw new ObjectDisposedException("StreamWrapper"); } } } #endregion #region Enums namespace FreeImageAPI { /// /// Enumeration used for color conversions. /// FREE_IMAGE_COLOR_DEPTH contains several colors to convert to. /// The default value 'FICD_AUTO'. /// [System.Flags] public enum FREE_IMAGE_COLOR_DEPTH { /// /// Unknown. /// FICD_UNKNOWN = 0, /// /// Auto selected by the used algorithm. /// FICD_AUTO = FICD_UNKNOWN, /// /// 1-bit. /// FICD_01_BPP = 1, /// /// 1-bit using dithering. /// FICD_01_BPP_DITHER = FICD_01_BPP, /// /// 1-bit using threshold. /// FICD_01_BPP_THRESHOLD = FICD_01_BPP | 2, /// /// 4-bit. /// FICD_04_BPP = 4, /// /// 8-bit. /// FICD_08_BPP = 8, /// /// 16-bit 555 (1 bit remains unused). /// FICD_16_BPP_555 = FICD_16_BPP | 2, /// /// 16-bit 565 (all bits are used). /// FICD_16_BPP = 16, /// /// 24-bit. /// FICD_24_BPP = 24, /// /// 32-bit. /// FICD_32_BPP = 32, /// /// Reorder palette (make it linear). Only affects 1-, 4- and 8-bit images. /// The palette is only reordered in case the image is greyscale /// (all palette entries have the same red, green and blue value). /// FICD_REORDER_PALETTE = 1024, /// /// Converts the image to greyscale. /// FICD_FORCE_GREYSCALE = 2048, /// /// Flag to mask out all non color depth flags. /// FICD_COLOR_MASK = FICD_01_BPP | FICD_04_BPP | FICD_08_BPP | FICD_16_BPP | FICD_24_BPP | FICD_32_BPP } } namespace FreeImageAPI { /// /// List of combinable compare modes. /// [System.Flags] public enum FREE_IMAGE_COMPARE_FLAGS { /// /// Compare headers. /// HEADER = 0x1, /// /// Compare palettes. /// PALETTE = 0x2, /// /// Compare pixel data. /// DATA = 0x4, /// /// Compare meta data. /// METADATA = 0x8, /// /// Compare everything. /// COMPLETE = (HEADER | PALETTE | DATA | METADATA) } } namespace FreeImageAPI { /// /// Flags for copying data from a bitmap to another. /// public enum FREE_IMAGE_METADATA_COPY { /// /// Exisiting metadata will remain unchanged. /// KEEP_EXISITNG = 0x0, /// /// Existing metadata will be cleared. /// CLEAR_EXISTING = 0x1, /// /// Existing metadata will be overwritten. /// REPLACE_EXISTING = 0x2 } } namespace FreeImageAPI { /// /// List different search modes. /// [System.Flags] public enum MD_SEARCH_FLAGS { /// /// The key of the metadata. /// KEY = 0x1, /// /// The description of the metadata /// DESCRIPTION = 0x2, /// /// The ToString value of the metadata /// TOSTRING = 0x4, } } #endregion namespace FreeImageAPI { /// /// Static class importing functions from the FreeImage library /// and providing additional functions. /// public static partial class FreeImage { #region Constants /// /// Array containing all 'FREE_IMAGE_MDMODEL's. /// public static readonly FREE_IMAGE_MDMODEL[] FREE_IMAGE_MDMODELS = (FREE_IMAGE_MDMODEL[])Enum.GetValues(typeof(FREE_IMAGE_MDMODEL)); /// /// Stores handles used to read from streams. /// private static Dictionary streamHandles = new Dictionary(); /// /// Version of the wrapper library. /// private static Version WrapperVersion; private const int DIB_RGB_COLORS = 0; private const int DIB_PAL_COLORS = 1; private const int CBM_INIT = 0x4; /// /// An uncompressed format. /// public const int 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. /// public const int 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. /// public const int 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. /// public const int BI_BITFIELDS = 3; /// /// Windows 98/Me, Windows 2000/XP: Indicates that the image is a JPEG image. /// public const int BI_JPEG = 4; /// /// Windows 98/Me, Windows 2000/XP: Indicates that the image is a PNG image. /// public const int BI_PNG = 5; #endregion #region General functions /// /// Returns the internal version of this FreeImage .NET wrapper. /// /// The internal version of this FreeImage .NET wrapper. public static Version GetWrapperVersion() { if (WrapperVersion == null) { try { object[] attributes = Assembly.GetAssembly(typeof(FreeImage)) .GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false); if ((attributes != null) && (attributes.Length != 0)) { AssemblyFileVersionAttribute attribute = attributes[0] as AssemblyFileVersionAttribute; if ((attribute != null) && (attribute.Version != null)) { return (WrapperVersion = new Version(attribute.Version)); } } } catch { } WrapperVersion = new Version(); } return WrapperVersion; } /// /// Returns the version of the native FreeImage library. /// /// The version of the native FreeImage library. public static Version GetNativeVersion() { return new Version(GetVersion()); } /// /// Returns a value indicating if the FreeImage library is available or not. /// See remarks for further details. /// /// false if the file is not available or out of date; /// true, otherwise. /// /// The FreeImage.NET library is a wrapper for the native C++ library /// (FreeImage.dll ... dont mix ist up with this library FreeImageNet.dll). /// The native library must be either in the same folder as the program's /// executable or in a folder contained in the envirent variable PATH /// (for example %WINDIR%\System32). /// Further more must both libraries, including the program itself, /// be the same architecture (x86 or x64). /// public static bool IsAvailable() { try { // Call a static fast executing function Version nativeVersion = new Version(GetVersion()); Version wrapperVersion = GetWrapperVersion(); // No exception thrown, the library seems to be present return (nativeVersion.Major >= wrapperVersion.Major) && (nativeVersion.Minor >= wrapperVersion.Minor) && (nativeVersion.Build >= wrapperVersion.Build); } catch (DllNotFoundException) { return false; } catch (EntryPointNotFoundException) { return false; } catch (BadImageFormatException) { return false; } } #endregion #region Bitmap management functions /// /// Creates a new bitmap in memory. /// /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new Bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// Handle to a FreeImage bitmap. public static FIBITMAP Allocate(int width, int height, int bpp) { return Allocate(width, height, bpp, 0, 0, 0); } /// /// Creates a new bitmap in memory. /// /// Type of the image. /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new Bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// Handle to a FreeImage bitmap. public static FIBITMAP AllocateT(FREE_IMAGE_TYPE type, int width, int height, int bpp) { return AllocateT(type, width, height, bpp, 0, 0, 0); } /// /// Allocates a new image of the specified width, height and bit depth and optionally /// fills it with the specified color. See remarks for further details. /// /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmaps. /// The color to fill the bitmap with or null. /// Options to enable or disable function-features. /// The palette of the bitmap or null. /// Handle to a FreeImage bitmap. /// /// This function is an extension to , which additionally supports /// specifying a palette to be set for the newly create image, as well as specifying a /// background color, the newly created image should initially be filled with. /// /// Basically, this function internally relies on function , followed by a /// call to . This is why both parameters /// and behave the same as it is /// documented for function . /// So, please refer to the documentation of to /// learn more about parameters and . /// /// The palette specified through parameter is only copied to the /// newly created image, if the desired bit depth is smaller than or equal to 8 bits per pixel. /// In other words, the parameter is only taken into account for /// palletized images. So, for an 8-bit image, the length is 256, for an 4-bit image it is 16 /// and it is 2 for a 1-bit image. In other words, this function does not support partial palettes. /// /// However, specifying a palette is not necesarily needed, even for palletized images. This /// function is capable of implicitly creating a palette, if is null. /// If the specified background color is a greyscale value (red = green = blue) or if option /// is specified, a greyscale palette /// is created. For a 1-bit image, only if the specified background color is either black or white, /// a monochrome palette, consisting of black and white only is created. In any case, the darker /// colors are stored at the smaller palette indices. /// /// If the specified background color is not a greyscale value, or is neither black nor white /// for a 1-bit image, solely this specified color is injected into the otherwise black-initialized /// palette. For this operation, option /// is implicit, so the specified is applied to the palette entry, /// specified by the background color's field. /// The image is then filled with this palette index. /// /// This function returns a newly created image as function does, if both /// parameters and are null. /// If only is null, the palette pointed to by /// parameter is initially set for the new image, if a palletized /// image of type is created. /// However, in the latter case, this function returns an image, whose /// pixels are all initialized with zeros so, the image will be filled with the color of the /// first palette entry. /// public static FIBITMAP AllocateEx(int width, int height, int bpp, RGBQUAD? color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette) { return AllocateEx(width, height, bpp, color, options, palette, 0, 0, 0); } /// /// Allocates a new image of the specified width, height and bit depth and optionally /// fills it with the specified color. See remarks for further details. /// /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmaps. /// The color to fill the bitmap with or null. /// Options to enable or disable function-features. /// The palette of the bitmap or null. /// Red part of the color layout. /// eg: 0xFF0000 /// Green part of the color layout. /// eg: 0x00FF00 /// Blue part of the color layout. /// eg: 0x0000FF /// Handle to a FreeImage bitmap. /// /// This function is an extension to , which additionally supports /// specifying a palette to be set for the newly create image, as well as specifying a /// background color, the newly created image should initially be filled with. /// /// Basically, this function internally relies on function , followed by a /// call to . This is why both parameters /// and behave the same as it is /// documented for function . /// So, please refer to the documentation of to /// learn more about parameters and . /// /// The palette specified through parameter is only copied to the /// newly created image, if the desired bit depth is smaller than or equal to 8 bits per pixel. /// In other words, the parameter is only taken into account for /// palletized images. So, for an 8-bit image, the length is 256, for an 4-bit image it is 16 /// and it is 2 for a 1-bit image. In other words, this function does not support partial palettes. /// /// However, specifying a palette is not necesarily needed, even for palletized images. This /// function is capable of implicitly creating a palette, if is null. /// If the specified background color is a greyscale value (red = green = blue) or if option /// is specified, a greyscale palette /// is created. For a 1-bit image, only if the specified background color is either black or white, /// a monochrome palette, consisting of black and white only is created. In any case, the darker /// colors are stored at the smaller palette indices. /// /// If the specified background color is not a greyscale value, or is neither black nor white /// for a 1-bit image, solely this specified color is injected into the otherwise black-initialized /// palette. For this operation, option /// is implicit, so the specified is applied to the palette entry, /// specified by the background color's field. /// The image is then filled with this palette index. /// /// This function returns a newly created image as function does, if both /// parameters and are null. /// If only is null, the palette pointed to by /// parameter is initially set for the new image, if a palletized /// image of type is created. /// However, in the latter case, this function returns an image, whose /// pixels are all initialized with zeros so, the image will be filled with the color of the /// first palette entry. /// public static FIBITMAP AllocateEx(int width, int height, int bpp, RGBQUAD? color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette, uint red_mask, uint green_mask, uint blue_mask) { if ((palette != null) && (bpp <= 8) && (palette.Length < (1 << bpp))) return FIBITMAP.Zero; if (color.HasValue) { GCHandle handle = new GCHandle(); try { RGBQUAD[] buffer = new RGBQUAD[] { color.Value }; handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return AllocateEx(width, height, bpp, handle.AddrOfPinnedObject(), options, palette, red_mask, green_mask, blue_mask); } finally { if (handle.IsAllocated) handle.Free(); } } else { return AllocateEx(width, height, bpp, IntPtr.Zero, options, palette, red_mask, green_mask, blue_mask); } } /// /// Allocates a new image of the specified type, width, height and bit depth and optionally /// fills it with the specified color. See remarks for further details. /// /// The type of the specified color. /// Type of the image. /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// The color to fill the bitmap with or null. /// Options to enable or disable function-features. /// The palette of the bitmap or null. /// Handle to a FreeImage bitmap. /// /// This function is an extension to , which additionally supports /// specifying a palette to be set for the newly create image, as well as specifying a /// background color, the newly created image should initially be filled with. /// /// Basically, this function internally relies on function , followed by a /// call to . This is why both parameters /// and behave the same as it is /// documented for function . So, please refer to the /// documentation of to learn more about parameters color and options. /// /// The palette specified through parameter palette is only copied to the newly created /// image, if its image type is and the desired bit /// depth is smaller than or equal to 8 bits per pixel. In other words, the /// palette is only taken into account for palletized images. However, if the preceding conditions /// match and if is not null, the palette is assumed to be at /// least as large as the size of a fully populated palette for the desired bit depth. /// So, for an 8-bit image, this length is 256, for an 4-bit image it is 16 and it is /// 2 for a 1-bit image. In other words, this function does not support partial palettes. /// /// However, specifying a palette is not necesarily needed, even for palletized images. This /// function is capable of implicitly creating a palette, if is null. /// If the specified background color is a greyscale value (red = green = blue) or if option /// is specified, a greyscale palette /// is created. For a 1-bit image, only if the specified background color is either black or white, /// a monochrome palette, consisting of black and white only is created. In any case, the darker /// colors are stored at the smaller palette indices. /// /// If the specified background color is not a greyscale value, or is neither black nor white /// for a 1-bit image, solely this specified color is injected into the otherwise black-initialized /// palette. For this operation, option /// is implicit, so the specified color is applied to the palette entry, specified by the /// background color's field. The image is then filled with /// this palette index. /// /// This function returns a newly created image as function does, if both /// parameters and are null. /// If only is null, the palette pointed to by /// parameter is initially set for the new image, if a palletized /// image of type is created. /// However, in the latter case, this function returns an image, whose /// pixels are all initialized with zeros so, the image will be filled with the color of the /// first palette entry. /// public static FIBITMAP AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, T? color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette) where T : struct { return AllocateExT(type, width, height, bpp, color, options, palette, 0, 0, 0); } /// /// Allocates a new image of the specified type, width, height and bit depth and optionally /// fills it with the specified color. See remarks for further details. /// /// The type of the specified color. /// Type of the image. /// Width of the new bitmap. /// Height of the new bitmap. /// Bit depth of the new bitmap. /// Supported pixel depth: 1-, 4-, 8-, 16-, 24-, 32-bit per pixel for standard bitmap /// The color to fill the bitmap with or null. /// Options to enable or disable function-features. /// The palette of the bitmap or null. /// Red part of the color layout. /// eg: 0xFF0000 /// Green part of the color layout. /// eg: 0x00FF00 /// Blue part of the color layout. /// eg: 0x0000FF /// Handle to a FreeImage bitmap. /// /// This function is an extension to , which additionally supports /// specifying a palette to be set for the newly create image, as well as specifying a /// background color, the newly created image should initially be filled with. /// /// Basically, this function internally relies on function , followed by a /// call to . This is why both parameters /// and behave the same as it is /// documented for function . So, please refer to the /// documentation of to learn more about parameters color and options. /// /// The palette specified through parameter palette is only copied to the newly created /// image, if its image type is and the desired bit /// depth is smaller than or equal to 8 bits per pixel. In other words, the /// palette is only taken into account for palletized images. However, if the preceding conditions /// match and if is not null, the palette is assumed to be at /// least as large as the size of a fully populated palette for the desired bit depth. /// So, for an 8-bit image, this length is 256, for an 4-bit image it is 16 and it is /// 2 for a 1-bit image. In other words, this function does not support partial palettes. /// /// However, specifying a palette is not necesarily needed, even for palletized images. This /// function is capable of implicitly creating a palette, if is null. /// If the specified background color is a greyscale value (red = green = blue) or if option /// is specified, a greyscale palette /// is created. For a 1-bit image, only if the specified background color is either black or white, /// a monochrome palette, consisting of black and white only is created. In any case, the darker /// colors are stored at the smaller palette indices. /// /// If the specified background color is not a greyscale value, or is neither black nor white /// for a 1-bit image, solely this specified color is injected into the otherwise black-initialized /// palette. For this operation, option /// is implicit, so the specified color is applied to the palette entry, specified by the /// background color's field. The image is then filled with /// this palette index. /// /// This function returns a newly created image as function does, if both /// parameters and are null. /// If only is null, the palette pointed to by /// parameter is initially set for the new image, if a palletized /// image of type is created. /// However, in the latter case, this function returns an image, whose /// pixels are all initialized with zeros so, the image will be filled with the color of the /// first palette entry. /// public static FIBITMAP AllocateExT(FREE_IMAGE_TYPE type, int width, int height, int bpp, T? color, FREE_IMAGE_COLOR_OPTIONS options, RGBQUAD[] palette, uint red_mask, uint green_mask, uint blue_mask) where T : struct { if ((palette != null) && (bpp <= 8) && (palette.Length < (1 << bpp))) return FIBITMAP.Zero; if (!CheckColorType(type, color)) return FIBITMAP.Zero; if (color.HasValue) { GCHandle handle = new GCHandle(); try { T[] buffer = new T[] { color.Value }; handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return AllocateExT(type, width, height, bpp, handle.AddrOfPinnedObject(), options, palette, red_mask, green_mask, blue_mask); } finally { if (handle.IsAllocated) handle.Free(); } } else { return AllocateExT(type, width, height, bpp, IntPtr.Zero, options, palette, red_mask, green_mask, blue_mask); } } /// /// Converts a FreeImage bitmap to a .NET . /// /// Handle to a FreeImage bitmap. /// The converted .NET . /// Copying metadata has been disabled until a proper way /// of reading and storing metadata in a .NET bitmap is found. /// /// is null. /// /// The image type of is not FIT_BITMAP. public static Bitmap GetBitmap(FIBITMAP dib) { return GetBitmap(dib, true); } /// /// Converts a FreeImage bitmap to a .NET . /// /// Handle to a FreeImage bitmap. /// When true existing metadata will be copied. /// The converted .NET . /// Copying metadata has been disabled until a proper way /// of reading and storing metadata in a .NET bitmap is found. /// /// is null. /// /// The image type of is not FIT_BITMAP. internal static Bitmap GetBitmap(FIBITMAP dib, bool copyMetadata) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (GetImageType(dib) != FREE_IMAGE_TYPE.FIT_BITMAP) { throw new ArgumentException("Only bitmaps with type of FIT_BITMAP can be converted."); } PixelFormat format = GetPixelFormat(dib); if ((format == PixelFormat.Undefined) && (GetBPP(dib) == 16u)) { throw new ArgumentException("Only 16bit 555 and 565 are supported."); } int height = (int)GetHeight(dib); int width = (int)GetWidth(dib); int pitch = (int)GetPitch(dib); Bitmap result = new Bitmap(width, height, format); BitmapData data; // Locking the complete bitmap in writeonly mode data = result.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, format); // Writing the bitmap data directly into the new created .NET bitmap. ConvertToRawBits(data.Scan0, dib, pitch, GetBPP(dib), GetRedMask(dib), GetGreenMask(dib), GetBlueMask(dib), true); // Unlock the bitmap result.UnlockBits(data); // Apply the bitmaps resolution result.SetResolution(GetResolutionX(dib), GetResolutionY(dib)); // Check whether the bitmap has a palette if (GetPalette(dib) != IntPtr.Zero) { // Get the bitmaps palette to apply changes ColorPalette palette = result.Palette; // Get the orgininal palette Color[] colorPalette = new Palette(dib).ColorData; // Get the maximum number of palette entries to copy int entriesToCopy = Math.Min(colorPalette.Length, palette.Entries.Length); // Check whether the bitmap is transparent if (IsTransparent(dib)) { byte[] transTable = GetTransparencyTableEx(dib); int i = 0; int maxEntriesWithTrans = Math.Min(entriesToCopy, transTable.Length); // Copy palette entries and include transparency for (; i < maxEntriesWithTrans; i++) { palette.Entries[i] = Color.FromArgb(transTable[i], colorPalette[i]); } // Copy palette entries and that have no transparancy for (; i < entriesToCopy; i++) { palette.Entries[i] = Color.FromArgb(0xFF, colorPalette[i]); } } else { for (int i = 0; i < entriesToCopy; i++) { palette.Entries[i] = colorPalette[i]; } } // Set the bitmaps palette result.Palette = palette; } // Copy metadata if (copyMetadata) { try { List list = new List(); // Get a list of all types FITAG tag; FIMETADATA mData; foreach (FREE_IMAGE_MDMODEL model in FREE_IMAGE_MDMODELS) { // Get a unique search handle mData = FindFirstMetadata(model, dib, out tag); // Check if metadata exists for this type if (mData.IsNull) continue; do { PropertyItem propItem = CreatePropertyItem(); propItem.Len = (int)GetTagLength(tag); propItem.Id = (int)GetTagID(tag); propItem.Type = (short)GetTagType(tag); byte[] buffer = new byte[propItem.Len]; unsafe { byte* src = (byte*)GetTagValue(tag); fixed (byte* dst = buffer) { CopyMemory(dst, src, (uint)propItem.Len); } } propItem.Value = buffer; list.Add(propItem); } while (FindNextMetadata(mData, out tag)); FindCloseMetadata(mData); } foreach (PropertyItem propItem in list) { result.SetPropertyItem(propItem); } } catch { } } return result; } /// /// Converts an .NET into a FreeImage bitmap. /// /// The to convert. /// Handle to a FreeImage bitmap. /// Copying metadata has been disabled until a proper way /// of reading and storing metadata in a .NET bitmap is found. /// /// is null. /// /// The bitmaps pixelformat is invalid. public static FIBITMAP CreateFromBitmap(Bitmap bitmap) { return CreateFromBitmap(bitmap, false); } /// /// Converts an .NET into a FreeImage bitmap. /// /// The to convert. /// When true existing metadata will be copied. /// Handle to a FreeImage bitmap. /// Copying metadata has been disabled until a proper way /// of reading and storing metadata in a .NET bitmap is found. /// /// is null. /// /// The bitmaps pixelformat is invalid. internal static FIBITMAP CreateFromBitmap(Bitmap bitmap, bool copyMetadata) { if (bitmap == null) { throw new ArgumentNullException("bitmap"); } uint bpp, red_mask, green_mask, blue_mask; FREE_IMAGE_TYPE type; if (!GetFormatParameters(bitmap.PixelFormat, out type, out bpp, out red_mask, out green_mask, out blue_mask)) { throw new ArgumentException("The bitmaps pixelformat is invalid."); } // Locking the complete bitmap in readonly mode BitmapData data = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); // Copying the bitmap data directly from the .NET bitmap FIBITMAP result = ConvertFromRawBits( data.Scan0, type, data.Width, data.Height, data.Stride, bpp, red_mask, green_mask, blue_mask, true); bitmap.UnlockBits(data); // Handle palette if (GetPalette(result) != IntPtr.Zero) { Palette palette = new Palette(result); Color[] colors = bitmap.Palette.Entries; // Only copy available palette entries int entriesToCopy = Math.Min(palette.Length, colors.Length); byte[] transTable = new byte[entriesToCopy]; for (int i = 0; i < entriesToCopy; i++) { RGBQUAD color = (RGBQUAD)colors[i]; color.rgbReserved = 0x00; palette[i] = color; transTable[i] = colors[i].A; } if ((bitmap.Flags & (int)ImageFlags.HasAlpha) != 0) { FreeImage.SetTransparencyTable(result, transTable); } } // Handle meta data // Disabled //if (copyMetadata) //{ // foreach (PropertyItem propItem in bitmap.PropertyItems) // { // FITAG tag = CreateTag(); // SetTagLength(tag, (uint)propItem.Len); // SetTagID(tag, (ushort)propItem.Id); // SetTagType(tag, (FREE_IMAGE_MDTYPE)propItem.Type); // SetTagValue(tag, propItem.Value); // SetMetadata(FREE_IMAGE_MDMODEL.FIMD_EXIF_EXIF, result, "", tag); // } //} return result; } /// /// Converts a raw bitmap to a FreeImage bitmap. /// /// Array of bytes containing the raw bitmap. /// The type of the raw bitmap. /// The width in pixels of the raw bitmap. /// The height in pixels of the raw bitmap. /// Defines the total width of a scanline in the raw bitmap, /// including padding bytes. /// The bit depth (bits per pixel) of the raw bitmap. /// The bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap is stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. /// Handle to a FreeImage bitmap. public static unsafe FIBITMAP ConvertFromRawBits( byte[] bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown) { fixed (byte* ptr = bits) { return ConvertFromRawBits( (IntPtr)ptr, type, width, height, pitch, bpp, red_mask, green_mask, blue_mask, topdown); } } /// /// Converts a raw bitmap to a FreeImage bitmap. /// /// Pointer to the memory block containing the raw bitmap. /// The type of the raw bitmap. /// The width in pixels of the raw bitmap. /// The height in pixels of the raw bitmap. /// Defines the total width of a scanline in the raw bitmap, /// including padding bytes. /// The bit depth (bits per pixel) of the raw bitmap. /// The bit mask describing the bits used to store a single /// pixel's red component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's green component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// The bit mask describing the bits used to store a single /// pixel's blue component in the raw bitmap. This is only applied to 16-bpp raw bitmaps. /// If true, the raw bitmap is stored in top-down order (top-left pixel first) /// and in bottom-up order (bottom-left pixel first) otherwise. /// Handle to a FreeImage bitmap. public static unsafe FIBITMAP ConvertFromRawBits( IntPtr bits, FREE_IMAGE_TYPE type, int width, int height, int pitch, uint bpp, uint red_mask, uint green_mask, uint blue_mask, bool topdown) { byte* addr = (byte*)bits; if ((addr == null) || (width <= 0) || (height <= 0)) { return FIBITMAP.Zero; } FIBITMAP dib = AllocateT(type, width, height, (int)bpp, red_mask, green_mask, blue_mask); if (dib != FIBITMAP.Zero) { if (topdown) { for (int i = height - 1; i >= 0; --i) { CopyMemory((byte*)GetScanLine(dib, i), addr, (int)GetLine(dib)); addr += pitch; } } else { for (int i = 0; i < height; ++i) { CopyMemory((byte*)GetScanLine(dib, i), addr, (int)GetLine(dib)); addr += pitch; } } } return dib; } /// /// Saves a .NET to a file. /// /// The .NET to save. /// Name of the file to save to. /// Returns true on success, false on failure. /// /// or is null. /// /// The bitmaps pixelformat is invalid. public static bool SaveBitmap(Bitmap bitmap, string filename) { return SaveBitmap( bitmap, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Saves a .NET to a file. /// /// The .NET to save. /// Name of the file to save to. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. /// /// or is null. /// /// The bitmaps pixelformat is invalid. public static bool SaveBitmap(Bitmap bitmap, string filename, FREE_IMAGE_SAVE_FLAGS flags) { return SaveBitmap( bitmap, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, flags); } /// /// Saves a .NET to a file. /// /// The .NET to save. /// Name of the file to save to. /// Format of the bitmap. If the format should be taken from the /// filename use . /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. /// /// or is null. /// /// The bitmaps pixelformat is invalid. public static bool SaveBitmap( Bitmap bitmap, string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags) { FIBITMAP dib = CreateFromBitmap(bitmap); bool result = SaveEx(dib, filename, format, flags); Unload(dib); return result; } /// /// Loads a FreeImage bitmap. /// The file will be loaded with default loading flags. /// /// The complete name of the file to load. /// Handle to a FreeImage bitmap. /// /// does not exists. public static FIBITMAP LoadEx(string filename) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return LoadEx(filename, FREE_IMAGE_LOAD_FLAGS.DEFAULT, ref format); } /// /// Loads a FreeImage bitmap. /// Load flags can be provided by the flags parameter. /// /// The complete name of the file to load. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. /// /// does not exists. public static FIBITMAP LoadEx(string filename, FREE_IMAGE_LOAD_FLAGS flags) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return LoadEx(filename, flags, ref format); } /// /// Loads a FreeImage bitmap. /// In case the loading format is the files /// real format is being analysed. If no plugin can read the file, format remains /// and 0 is returned. /// The file will be loaded with default loading flags. /// /// The complete name of the file to load. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadEx it will be returned in format. /// Handle to a FreeImage bitmap. /// /// does not exists. public static FIBITMAP LoadEx(string filename, ref FREE_IMAGE_FORMAT format) { return LoadEx(filename, FREE_IMAGE_LOAD_FLAGS.DEFAULT, ref format); } /// /// Loads a FreeImage bitmap. /// In case the loading format is the files /// real format is being analysed. If no plugin can read the file, format remains /// and 0 is returned. /// Load flags can be provided by the flags parameter. /// /// The complete name of the file to load. /// Flags to enable or disable plugin-features. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadEx it will be returned in format. /// /// Handle to a FreeImage bitmap. /// /// does not exists. public static FIBITMAP LoadEx(string filename, FREE_IMAGE_LOAD_FLAGS flags, ref FREE_IMAGE_FORMAT format) { // check if file exists if (!File.Exists(filename)) { throw new FileNotFoundException(filename + " could not be found."); } FIBITMAP dib = new FIBITMAP(); if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { // query all plugins to see if one can read the file format = GetFileType(filename, 0); } // check if the plugin is capable of loading files if (FIFSupportsReading(format)) { dib = Load(format, filename, flags); } return dib; } /// /// Loads a .NET from a file. /// /// Name of the file to be loaded. /// Format of the image. If the format should be taken from the /// filename use . /// Flags to enable or disable plugin-features. /// The loaded .NET . /// /// does not exists. /// /// The image type of the image is not . public static Bitmap LoadBitmap(string filename, FREE_IMAGE_LOAD_FLAGS flags, ref FREE_IMAGE_FORMAT format) { FIBITMAP dib = LoadEx(filename, flags, ref format); Bitmap result = GetBitmap(dib, true); Unload(dib); return result; } /// /// Deletes a previously loaded FreeImage bitmap from memory and resets the handle to 0. /// /// Handle to a FreeImage bitmap. public static void UnloadEx(ref FIBITMAP dib) { if (!dib.IsNull) { Unload(dib); dib.SetNull(); } } /// /// Saves a previously loaded FreeImage bitmap to a file. /// The format is taken off the filename. /// If no suitable format was found false will be returned. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx(FIBITMAP dib, string filename) { return SaveEx( ref dib, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// In case the loading format is /// the format is taken off the filename. /// If no suitable format was found false will be returned. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Format of the image. If the format should be taken from the /// filename use . /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( FIBITMAP dib, string filename, FREE_IMAGE_FORMAT format) { return SaveEx( ref dib, filename, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// The format is taken off the filename. /// If no suitable format was found false will be returned. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// When true the structure will be unloaded on success. /// If the function failed and returned false, the bitmap was not unloaded. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( ref FIBITMAP dib, string filename, bool unloadSource) { return SaveEx( ref dib, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, unloadSource); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// The format is taken off the filename. /// If no suitable format was found false will be returned. /// Save flags can be provided by the flags parameter. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( FIBITMAP dib, string filename, FREE_IMAGE_SAVE_FLAGS flags) { return SaveEx( ref dib, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, flags, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// The format is taken off the filename. /// If no suitable format was found false will be returned. /// Save flags can be provided by the flags parameter. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Flags to enable or disable plugin-features. /// When true the structure will be unloaded on success. /// If the function failed and returned false, the bitmap was not unloaded. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( ref FIBITMAP dib, string filename, FREE_IMAGE_SAVE_FLAGS flags, bool unloadSource) { return SaveEx( ref dib, filename, FREE_IMAGE_FORMAT.FIF_UNKNOWN, flags, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, unloadSource); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// In case the loading format is /// the format is taken off the filename. /// If no suitable format was found false will be returned. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Format of the image. If the format should be taken from the /// filename use . /// When true the structure will be unloaded on success. /// If the function failed and returned false, the bitmap was not unloaded. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( ref FIBITMAP dib, string filename, FREE_IMAGE_FORMAT format, bool unloadSource) { return SaveEx( ref dib, filename, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, unloadSource); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// In case the loading format is /// the format is taken off the filename. /// If no suitable format was found false will be returned. /// Save flags can be provided by the flags parameter. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Format of the image. If the format should be taken from the /// filename use . /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. /// /// or is null. public static bool SaveEx( FIBITMAP dib, string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags) { return SaveEx( ref dib, filename, format, flags, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a file. /// In case the loading format is /// the format is taken off the filename. /// If no suitable format was found false will be returned. /// Save flags can be provided by the flags parameter. /// The bitmaps color depth can be set by 'colorDepth'. /// If set to a suitable color depth /// will be taken if available. /// /// Handle to a FreeImage bitmap. /// The complete name of the file to save to. /// The extension will be corrected if it is no valid extension for the /// selected format or if no extension was specified. /// Format of the image. If the format should be taken from the /// filename use . /// Flags to enable or disable plugin-features. /// The new color depth of the bitmap. /// Set to if Save should take the /// best suitable color depth. /// If a color depth is selected that the provided format cannot write an /// error-message will be thrown. /// When true the structure will be unloaded on success. /// If the function failed and returned false, the bitmap was not unloaded. /// Returns true on success, false on failure. /// /// A direct color conversion failed. /// /// or is null. public static bool SaveEx( ref FIBITMAP dib, string filename, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags, FREE_IMAGE_COLOR_DEPTH colorDepth, bool unloadSource) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (filename == null) { throw new ArgumentNullException("filename"); } bool result = false; // Gets format from filename if the format is unknown if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { format = GetFIFFromFilename(filename); } if (format != FREE_IMAGE_FORMAT.FIF_UNKNOWN) { // Checks writing support if (FIFSupportsWriting(format) && FIFSupportsExportType(format, GetImageType(dib))) { // Check valid filename and correct it if needed if (!IsFilenameValidForFIF(format, filename)) { string extension = GetPrimaryExtensionFromFIF(format); filename = Path.ChangeExtension(filename, extension); } FIBITMAP dibToSave = PrepareBitmapColorDepth(dib, format, colorDepth); try { result = Save(format, dibToSave, filename, flags); } finally { // Always unload a temporary created bitmap. if (dibToSave != dib) { UnloadEx(ref dibToSave); } // On success unload the bitmap if (result && unloadSource) { UnloadEx(ref dib); } } } } return result; } /// /// Loads a FreeImage bitmap. /// The stream must be set to the correct position before calling LoadFromStream. /// /// The stream to read from. /// Handle to a FreeImage bitmap. /// /// is null. /// /// is not capable of reading. public static FIBITMAP LoadFromStream(Stream stream) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return LoadFromStream(stream, FREE_IMAGE_LOAD_FLAGS.DEFAULT, ref format); } /// /// Loads a FreeImage bitmap. /// The stream must be set to the correct position before calling LoadFromStream. /// /// The stream to read from. /// Flags to enable or disable plugin-features. /// Handle to a FreeImage bitmap. /// /// is null. /// /// is not capable of reading. public static FIBITMAP LoadFromStream(Stream stream, FREE_IMAGE_LOAD_FLAGS flags) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return LoadFromStream(stream, flags, ref format); } /// /// Loads a FreeImage bitmap. /// In case the loading format is the /// bitmaps real format is being analysed. /// The stream must be set to the correct position before calling LoadFromStream. /// /// The stream to read from. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadFromStream it will be returned in format. /// Handle to a FreeImage bitmap. /// /// is null. /// /// is not capable of reading. public static FIBITMAP LoadFromStream(Stream stream, ref FREE_IMAGE_FORMAT format) { return LoadFromStream(stream, FREE_IMAGE_LOAD_FLAGS.DEFAULT, ref format); } /// /// Loads a FreeImage bitmap. /// In case the loading format is /// the bitmaps real format is being analysed. /// The stream must be set to the correct position before calling LoadFromStream. /// /// The stream to read from. /// Flags to enable or disable plugin-features. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadFromStream it will be returned in format. /// Handle to a FreeImage bitmap. /// /// is null. /// /// is not capable of reading. public static FIBITMAP LoadFromStream( Stream stream, FREE_IMAGE_LOAD_FLAGS flags, ref FREE_IMAGE_FORMAT format) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("stream is not capable of reading."); } // Wrap the source stream if it is unable to seek (which is required by FreeImage) stream = (stream.CanSeek) ? stream : new StreamWrapper(stream, true); stream.Position = 0L; if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { // Get the format of the bitmap format = GetFileTypeFromStream(stream); // Restore the streams position stream.Position = 0L; } if (!FIFSupportsReading(format)) { return FIBITMAP.Zero; } // Create a 'FreeImageIO' structure for calling 'LoadFromHandle' // using the internal structure 'FreeImageStreamIO'. FreeImageIO io = FreeImageStreamIO.io; using (fi_handle handle = new fi_handle(stream)) { return LoadFromHandle(format, ref io, handle, flags); } } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format) { return SaveToStream( ref dib, stream, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// When true the structure will be unloaded on success. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( ref FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format, bool unloadSource) { return SaveToStream( ref dib, stream, format, FREE_IMAGE_SAVE_FLAGS.DEFAULT, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, unloadSource); } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags) { return SaveToStream( ref dib, stream, format, flags, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, false); } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// Flags to enable or disable plugin-features. /// When true the structure will be unloaded on success. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( ref FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags, bool unloadSource) { return SaveToStream( ref dib, stream, format, flags, FREE_IMAGE_COLOR_DEPTH.FICD_AUTO, unloadSource); } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// Flags to enable or disable plugin-features. /// The new color depth of the bitmap. /// Set to if SaveToStream should /// take the best suitable color depth. /// If a color depth is selected that the provided format cannot write an /// error-message will be thrown. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags, FREE_IMAGE_COLOR_DEPTH colorDepth) { return SaveToStream( ref dib, stream, format, flags, colorDepth, false); } /// /// Saves a previously loaded FreeImage bitmap to a stream. /// The stream must be set to the correct position before calling SaveToStream. /// /// Handle to a FreeImage bitmap. /// The stream to write to. /// Format of the image. /// Flags to enable or disable plugin-features. /// The new color depth of the bitmap. /// Set to if SaveToStream should /// take the best suitable color depth. /// If a color depth is selected that the provided format cannot write an /// error-message will be thrown. /// When true the structure will be unloaded on success. /// Returns true on success, false on failure. /// /// or is null. /// /// cannot write. public static bool SaveToStream( ref FIBITMAP dib, Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_SAVE_FLAGS flags, FREE_IMAGE_COLOR_DEPTH colorDepth, bool unloadSource) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanWrite) { throw new ArgumentException("stream is not capable of writing."); } if ((!FIFSupportsWriting(format)) || (!FIFSupportsExportType(format, GetImageType(dib)))) { return false; } FIBITMAP dibToSave = PrepareBitmapColorDepth(dib, format, colorDepth); bool result = false; try { // Create a 'FreeImageIO' structure for calling 'SaveToHandle' FreeImageIO io = FreeImageStreamIO.io; using (fi_handle handle = new fi_handle(stream)) { result = SaveToHandle(format, dibToSave, ref io, handle, flags); } } finally { // Always unload a temporary created bitmap. if (dibToSave != dib) { UnloadEx(ref dibToSave); } // On success unload the bitmap if (result && unloadSource) { UnloadEx(ref dib); } } return result; } #endregion #region Plugin functions /// /// Checks if an extension is valid for a certain format. /// /// The desired format. /// The desired extension. /// True if the extension is valid for the given format, false otherwise. /// /// is null. public static bool IsExtensionValidForFIF(FREE_IMAGE_FORMAT fif, string extension) { return IsExtensionValidForFIF(fif, extension, StringComparison.CurrentCultureIgnoreCase); } /// /// Checks if an extension is valid for a certain format. /// /// The desired format. /// The desired extension. /// The string comparison type. /// True if the extension is valid for the given format, false otherwise. /// /// is null. public static bool IsExtensionValidForFIF(FREE_IMAGE_FORMAT fif, string extension, StringComparison comparisonType) { if (extension == null) { throw new ArgumentNullException("extension"); } bool result = false; // Split up the string and compare each with the given extension string tempList = GetFIFExtensionList(fif); if (tempList != null) { string[] extensionList = tempList.Split(','); foreach (string ext in extensionList) { if (extension.Equals(ext, comparisonType)) { result = true; break; } } } return result; } /// /// Checks if a filename is valid for a certain format. /// /// The desired format. /// The desired filename. /// True if the filename is valid for the given format, false otherwise. /// /// is null. public static bool IsFilenameValidForFIF(FREE_IMAGE_FORMAT fif, string filename) { return IsFilenameValidForFIF(fif, filename, StringComparison.CurrentCultureIgnoreCase); } /// /// Checks if a filename is valid for a certain format. /// /// The desired format. /// The desired filename. /// The string comparison type. /// True if the filename is valid for the given format, false otherwise. /// /// is null. public static bool IsFilenameValidForFIF(FREE_IMAGE_FORMAT fif, string filename, StringComparison comparisonType) { if (filename == null) { throw new ArgumentNullException("filename"); } bool result = false; // Extract the filenames extension if it exists string extension = Path.GetExtension(filename); if (extension.Length != 0) { extension = extension.Remove(0, 1); result = IsExtensionValidForFIF(fif, extension, comparisonType); } return result; } /// /// This function returns the primary (main or most commonly used?) extension of a certain /// image format (fif). This is done by returning the first of all possible extensions /// returned by GetFIFExtensionList(). /// That assumes, that the plugin returns the extensions in ordered form. /// The image format to obtain the primary extension for. /// The primary extension of the specified image format. public static string GetPrimaryExtensionFromFIF(FREE_IMAGE_FORMAT fif) { string result = null; string extensions = GetFIFExtensionList(fif); if (extensions != null) { int position = extensions.IndexOf(','); if (position < 0) { result = extensions; } else { result = extensions.Substring(0, position); } } return result; } #endregion #region Multipage functions /// /// Loads a FreeImage multi-paged bitmap. /// /// The complete name of the file to load. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx(string filename) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return OpenMultiBitmapEx( filename, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT, false, false, false); } /// /// Loads a FreeImage multi-paged bitmap. /// /// The complete name of the file to load. /// When true performance is increased at the cost of memory. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx(string filename, bool keep_cache_in_memory) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return OpenMultiBitmapEx( filename, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT, false, false, keep_cache_in_memory); } /// /// Loads a FreeImage multi-paged bitmap. /// /// The complete name of the file to load. /// When true the bitmap will be loaded read only. /// When true performance is increased at the cost of memory. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx( string filename, bool read_only, bool keep_cache_in_memory) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return OpenMultiBitmapEx( filename, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT, false, read_only, keep_cache_in_memory); } /// /// Loads a FreeImage multi-paged bitmap. /// /// The complete name of the file to load. /// When true a new bitmap is created. /// When true the bitmap will be loaded read only. /// When true performance is increased at the cost of memory. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx( string filename, bool create_new, bool read_only, bool keep_cache_in_memory) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return OpenMultiBitmapEx( filename, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT, create_new, read_only, keep_cache_in_memory); } /// /// Loads a FreeImage multi-paged bitmap. /// In case the loading format is the files real /// format is being analysed. If no plugin can read the file, format remains /// and 0 is returned. /// /// The complete name of the file to load. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadEx it will be returned in format. /// When true a new bitmap is created. /// When true the bitmap will be loaded read only. /// When true performance is increased at the cost of memory. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx( string filename, ref FREE_IMAGE_FORMAT format, bool create_new, bool read_only, bool keep_cache_in_memory) { return OpenMultiBitmapEx( filename, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT, create_new, read_only, keep_cache_in_memory); } /// /// Loads a FreeImage multi-paged bitmap. /// In case the loading format is the files /// real format is being analysed. If no plugin can read the file, format remains /// and 0 is returned. /// Load flags can be provided by the flags parameter. /// /// The complete name of the file to load. /// Format of the image. If the format is unknown use /// . /// In case a suitable format was found by LoadEx it will be returned in format. /// Flags to enable or disable plugin-features. /// When true a new bitmap is created. /// When true the bitmap will be loaded read only. /// When true performance is increased at the cost of memory. /// Handle to a FreeImage multi-paged bitmap. /// /// does not exists while opening. public static FIMULTIBITMAP OpenMultiBitmapEx( string filename, ref FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags, bool create_new, bool read_only, bool keep_cache_in_memory) { if (!File.Exists(filename) && !create_new) { throw new FileNotFoundException(filename + " could not be found."); } if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { // Check if a plugin can read the data format = GetFileType(filename, 0); } FIMULTIBITMAP dib = new FIMULTIBITMAP(); if (FIFSupportsReading(format)) { dib = OpenMultiBitmap(format, filename, create_new, read_only, keep_cache_in_memory, flags); } return dib; } /// /// Loads a FreeImage multi-paged bitmap. /// /// The stream to load the bitmap from. /// Handle to a FreeImage multi-paged bitmap. public static FIMULTIBITMAP OpenMultiBitmapFromStream(Stream stream) { FREE_IMAGE_FORMAT format = FREE_IMAGE_FORMAT.FIF_UNKNOWN; return OpenMultiBitmapFromStream(stream, ref format, FREE_IMAGE_LOAD_FLAGS.DEFAULT); } /// /// Loads a FreeImage multi-paged bitmap. /// In case the loading format is the files /// real format is being analysed. If no plugin can read the file, format remains /// and 0 is returned. /// Load flags can be provided by the flags parameter. /// /// The stream to load the bitmap from. /// Format of the image. If the format is unknown use /// . /// Flags to enable or disable plugin-features. /// Handle to a FreeImage multi-paged bitmap. public static FIMULTIBITMAP OpenMultiBitmapFromStream(Stream stream, ref FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags) { if (stream == null) return FIMULTIBITMAP.Zero; if (!stream.CanSeek) stream = new StreamWrapper(stream, true); FIMULTIBITMAP mdib = FIMULTIBITMAP.Zero; FreeImageIO io = FreeImageStreamIO.io; fi_handle handle = new fi_handle(stream); try { if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) { format = GetFileTypeFromHandle(ref io, handle, checked((int)stream.Length)); } mdib = OpenMultiBitmapFromHandle(format, ref io, handle, flags); if (mdib.IsNull) { handle.Dispose(); } else { lock (streamHandles) { streamHandles.Add(mdib, handle); } } return mdib; } catch { if (!mdib.IsNull) CloseMultiBitmap(mdib, FREE_IMAGE_SAVE_FLAGS.DEFAULT); if (handle != null) handle.Dispose(); throw; } } /// /// Closes a previously opened multi-page bitmap and, when the bitmap was not opened read-only, applies any changes made to it. /// /// Handle to a FreeImage multi-paged bitmap. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. public static bool CloseMultiBitmap(FIMULTIBITMAP bitmap, FREE_IMAGE_SAVE_FLAGS flags) { if (CloseMultiBitmap_(bitmap, flags)) { fi_handle handle; lock (streamHandles) { if (streamHandles.TryGetValue(bitmap, out handle)) { streamHandles.Remove(bitmap); handle.Dispose(); } } return true; } return false; } /// /// Closes a previously opened multi-page bitmap and, when the bitmap was not opened read-only, /// applies any changes made to it. /// On success the handle will be reset to null. /// /// Handle to a FreeImage multi-paged bitmap. /// Returns true on success, false on failure. public static bool CloseMultiBitmapEx(ref FIMULTIBITMAP bitmap) { return CloseMultiBitmapEx(ref bitmap, FREE_IMAGE_SAVE_FLAGS.DEFAULT); } /// /// Closes a previously opened multi-page bitmap and, when the bitmap was not opened read-only, /// applies any changes made to it. /// On success the handle will be reset to null. /// /// Handle to a FreeImage multi-paged bitmap. /// Flags to enable or disable plugin-features. /// Returns true on success, false on failure. public static bool CloseMultiBitmapEx(ref FIMULTIBITMAP bitmap, FREE_IMAGE_SAVE_FLAGS flags) { bool result = false; if (!bitmap.IsNull) { if (CloseMultiBitmap(bitmap, flags)) { bitmap.SetNull(); result = true; } } return result; } /// /// Retrieves the number of pages that are locked in a multi-paged bitmap. /// /// Handle to a FreeImage multi-paged bitmap. /// Number of locked pages. /// /// is null. public static int GetLockedPageCount(FIMULTIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } int result = 0; GetLockedPageNumbers(dib, null, ref result); return result; } /// /// Retrieves a list locked pages of a multi-paged bitmap. /// /// Handle to a FreeImage multi-paged bitmap. /// List containing the indexes of the locked pages. /// /// is null. public static int[] GetLockedPages(FIMULTIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } // Get the number of pages and create an array to save the information int count = 0; int[] result = null; // Get count if (GetLockedPageNumbers(dib, result, ref count)) { result = new int[count]; // Fill array if (!GetLockedPageNumbers(dib, result, ref count)) { result = null; } } return result; } /// /// Loads a FreeImage multi-paged bitmap from a stream and returns the /// FreeImage memory stream used as temporary buffer. /// The bitmap can not be modified by calling /// , /// , /// or /// . /// /// The stream to read from. /// Format of the image. /// Flags to enable or disable plugin-features. /// The temporary memory buffer used to load the bitmap. /// Handle to a FreeImage multi-paged bitmap. /// /// is null. /// /// can not read. public static FIMULTIBITMAP LoadMultiBitmapFromStream( Stream stream, FREE_IMAGE_FORMAT format, FREE_IMAGE_LOAD_FLAGS flags, out FIMEMORY memory) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("stream"); } const int blockSize = 1024; int bytesRead; byte[] buffer = new byte[blockSize]; stream = stream.CanSeek ? stream : new StreamWrapper(stream, true); memory = OpenMemory(IntPtr.Zero, 0); do { bytesRead = stream.Read(buffer, 0, blockSize); WriteMemory(buffer, (uint)blockSize, (uint)1, memory); } while (bytesRead == blockSize); return LoadMultiBitmapFromMemory(format, memory, flags); } #endregion #region Filetype functions /// /// Orders FreeImage to analyze the bitmap signature. /// In case the stream is not seekable, the stream will have been used /// and must be recreated for loading. /// /// Name of the stream to analyze. /// Type of the bitmap. /// /// is null. /// /// can not read. public static FREE_IMAGE_FORMAT GetFileTypeFromStream(Stream stream) { if (stream == null) { throw new ArgumentNullException("stream"); } if (!stream.CanRead) { throw new ArgumentException("stream is not capable of reading."); } // Wrap the stream if it cannot seek stream = (stream.CanSeek) ? stream : new StreamWrapper(stream, true); // Create a 'FreeImageIO' structure for the stream FreeImageIO io = FreeImageStreamIO.io; using (fi_handle handle = new fi_handle(stream)) { return GetFileTypeFromHandle(ref io, handle, 0); } } #endregion #region Pixel access functions /// /// Retrieves an hBitmap for a FreeImage bitmap. /// Call FreeHbitmap(IntPtr) to free the handle. /// /// Handle to a FreeImage bitmap. /// A reference device context. /// Use IntPtr.Zero if no reference is available. /// When true dib will be unloaded if the function succeeded. /// The hBitmap for the FreeImage bitmap. /// /// is null. public static unsafe IntPtr GetHbitmap(FIBITMAP dib, IntPtr hdc, bool unload) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } IntPtr hBitmap = IntPtr.Zero; bool release = false; IntPtr ppvBits = IntPtr.Zero; // Check if we have destination if (release = (hdc == IntPtr.Zero)) { // We don't so request dc hdc = GetDC(IntPtr.Zero); } if (hdc != IntPtr.Zero) { // Get pointer to the infoheader of the bitmap IntPtr info = GetInfo(dib); // Create a bitmap in the dc hBitmap = CreateDIBSection(hdc, info, DIB_RGB_COLORS, out ppvBits, IntPtr.Zero, 0); if (hBitmap != IntPtr.Zero && ppvBits != IntPtr.Zero) { // Copy the data into the dc CopyMemory(ppvBits, GetBits(dib), (GetHeight(dib) * GetPitch(dib))); // Success: we unload the bitmap if (unload) { Unload(dib); } } // We have to release the dc if (release) { ReleaseDC(IntPtr.Zero, hdc); } } return hBitmap; } /// /// Returns an HBITMAP created by the CreateDIBitmap() function which in turn /// has always the same color depth as the reference DC, which may be provided /// through . The desktop DC will be used, /// if IntPtr.Zero DC is specified. /// Call to free the handle. /// /// Handle to a FreeImage bitmap. /// Handle to a device context. /// When true the structure will be unloaded on success. /// If the function failed and returned false, the bitmap was not unloaded. /// If the function succeeds, the return value is a handle to the /// compatible bitmap. If the function fails, the return value is . /// /// is null. public static IntPtr GetBitmapForDevice(FIBITMAP dib, IntPtr hdc, bool unload) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } IntPtr hbitmap = IntPtr.Zero; bool release = false; if (release = (hdc == IntPtr.Zero)) { hdc = GetDC(IntPtr.Zero); } if (hdc != IntPtr.Zero) { hbitmap = CreateDIBitmap( hdc, GetInfoHeader(dib), CBM_INIT, GetBits(dib), GetInfo(dib), DIB_RGB_COLORS); if (unload) { Unload(dib); } if (release) { ReleaseDC(IntPtr.Zero, hdc); } } return hbitmap; } /// /// Creates a FreeImage DIB from a Device Context/Compatible Bitmap. /// /// Handle to the bitmap. /// Handle to a device context. /// Handle to a FreeImage bitmap. /// /// is null. public unsafe static FIBITMAP CreateFromHbitmap(IntPtr hbitmap, IntPtr hdc) { if (hbitmap == IntPtr.Zero) { throw new ArgumentNullException("hbitmap"); } FIBITMAP dib = new FIBITMAP(); BITMAP bm; uint colors; bool release; if (GetObject(hbitmap, sizeof(BITMAP), (IntPtr)(&bm)) != 0) { dib = Allocate(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel, 0, 0, 0); if (!dib.IsNull) { colors = GetColorsUsed(dib); if (release = (hdc == IntPtr.Zero)) { hdc = GetDC(IntPtr.Zero); } if (GetDIBits( hdc, hbitmap, 0, (uint)bm.bmHeight, GetBits(dib), GetInfo(dib), DIB_RGB_COLORS) != 0) { if (colors != 0) { BITMAPINFOHEADER* bmih = (BITMAPINFOHEADER*)GetInfo(dib); bmih[0].biClrImportant = bmih[0].biClrUsed = colors; } } else { UnloadEx(ref dib); } if (release) { ReleaseDC(IntPtr.Zero, hdc); } } } return dib; } /// /// Frees a bitmap handle. /// /// Handle to a bitmap. /// True on success, false on failure. public static bool FreeHbitmap(IntPtr hbitmap) { return DeleteObject(hbitmap); } #endregion #region Bitmap information functions /// /// Retrieves a DIB's resolution in X-direction measured in 'dots per inch' (DPI) and not in /// 'dots per meter'. /// /// Handle to a FreeImage bitmap. /// The resolution in 'dots per inch'. /// /// is null. public static uint GetResolutionX(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } return (uint)(0.5d + 0.0254d * GetDotsPerMeterX(dib)); } /// /// Retrieves a DIB's resolution in Y-direction measured in 'dots per inch' (DPI) and not in /// 'dots per meter'. /// /// Handle to a FreeImage bitmap. /// The resolution in 'dots per inch'. /// /// is null. public static uint GetResolutionY(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } return (uint)(0.5d + 0.0254d * GetDotsPerMeterY(dib)); } /// /// Sets a DIB's resolution in X-direction measured in 'dots per inch' (DPI) and not in /// 'dots per meter'. /// /// Handle to a FreeImage bitmap. /// The new resolution in 'dots per inch'. /// /// is null. public static void SetResolutionX(FIBITMAP dib, uint res) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } SetDotsPerMeterX(dib, (uint)((double)res / 0.0254d + 0.5d)); } /// /// Sets a DIB's resolution in Y-direction measured in 'dots per inch' (DPI) and not in /// 'dots per meter'. /// /// Handle to a FreeImage bitmap. /// The new resolution in 'dots per inch'. /// /// is null. public static void SetResolutionY(FIBITMAP dib, uint res) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } SetDotsPerMeterY(dib, (uint)((double)res / 0.0254d + 0.5d)); } /// /// Returns whether the image is a greyscale image or not. /// The function scans all colors in the bitmaps palette for entries where /// red, green and blue are not all the same (not a grey color). /// Supports 1-, 4- and 8-bit bitmaps. /// /// Handle to a FreeImage bitmap. /// True if the image is a greyscale image, else false. /// /// is null. public static unsafe bool IsGreyscaleImage(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } bool result = true; uint bpp = GetBPP(dib); switch (bpp) { case 1: case 4: case 8: RGBQUAD* palette = (RGBQUAD*)GetPalette(dib); uint paletteLength = GetColorsUsed(dib); for (int i = 0; i < paletteLength; i++) { if (palette[i].rgbRed != palette[i].rgbGreen || palette[i].rgbRed != palette[i].rgbBlue) { result = false; break; } } break; default: result = false; break; } return result; } /// /// Returns a structure that represents the palette of a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// A structure representing the bitmaps palette. /// /// is null. public static Palette GetPaletteEx(FIBITMAP dib) { return new Palette(dib); } /// /// Returns the structure of a FreeImage bitmap. /// The structure is a copy, so changes will have no effect on /// the bitmap itself. /// /// Handle to a FreeImage bitmap. /// structure of the bitmap. /// /// is null. public static unsafe BITMAPINFOHEADER GetInfoHeaderEx(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } return *(BITMAPINFOHEADER*)GetInfoHeader(dib); } /// /// Returns the structure of a FreeImage bitmap. /// The structure is a copy, so changes will have no effect on /// the bitmap itself. /// /// Handle to a FreeImage bitmap. /// structure of the bitmap. /// /// is null. public static BITMAPINFO GetInfoEx(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } BITMAPINFO result = new BITMAPINFO(); result.bmiHeader = GetInfoHeaderEx(dib); IntPtr ptr = GetPalette(dib); if (ptr == IntPtr.Zero) { result.bmiColors = new RGBQUAD[0]; } else { result.bmiColors = new MemoryArray(ptr, (int)result.bmiHeader.biClrUsed).Data; } return result; } /// /// Returns the pixelformat of the bitmap. /// /// Handle to a FreeImage bitmap. /// of the bitmap. /// /// is null. public static PixelFormat GetPixelFormat(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } PixelFormat result = PixelFormat.Undefined; if (GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) { switch (GetBPP(dib)) { case 1: result = PixelFormat.Format1bppIndexed; break; case 4: result = PixelFormat.Format4bppIndexed; break; case 8: result = PixelFormat.Format8bppIndexed; break; case 16: if ((GetBlueMask(dib) == FI16_565_BLUE_MASK) && (GetGreenMask(dib) == FI16_565_GREEN_MASK) && (GetRedMask(dib) == FI16_565_RED_MASK)) { result = PixelFormat.Format16bppRgb565; } if ((GetBlueMask(dib) == FI16_555_BLUE_MASK) && (GetGreenMask(dib) == FI16_555_GREEN_MASK) && (GetRedMask(dib) == FI16_555_RED_MASK)) { result = PixelFormat.Format16bppRgb555; } break; case 24: result = PixelFormat.Format24bppRgb; break; case 32: result = PixelFormat.Format32bppArgb; break; } } return result; } /// /// Retrieves all parameters needed to create a new FreeImage bitmap from /// the format of a .NET . /// /// The /// of the .NET . /// Returns the type used for the new bitmap. /// Returns the color depth for the new bitmap. /// Returns the red_mask for the new bitmap. /// Returns the green_mask for the new bitmap. /// Returns the blue_mask for the new bitmap. /// True in case a matching conversion exists; else false. /// public static bool GetFormatParameters( PixelFormat format, out FREE_IMAGE_TYPE type, out uint bpp, out uint red_mask, out uint green_mask, out uint blue_mask) { bool result = false; type = FREE_IMAGE_TYPE.FIT_UNKNOWN; bpp = 0; red_mask = 0; green_mask = 0; blue_mask = 0; switch (format) { case PixelFormat.Format1bppIndexed: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 1; result = true; break; case PixelFormat.Format4bppIndexed: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 4; result = true; break; case PixelFormat.Format8bppIndexed: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 8; result = true; break; case PixelFormat.Format16bppRgb565: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 16; red_mask = FI16_565_RED_MASK; green_mask = FI16_565_GREEN_MASK; blue_mask = FI16_565_BLUE_MASK; result = true; break; case PixelFormat.Format16bppRgb555: case PixelFormat.Format16bppArgb1555: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 16; red_mask = FI16_555_RED_MASK; green_mask = FI16_555_GREEN_MASK; blue_mask = FI16_555_BLUE_MASK; result = true; break; case PixelFormat.Format24bppRgb: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 24; red_mask = FI_RGBA_RED_MASK; green_mask = FI_RGBA_GREEN_MASK; blue_mask = FI_RGBA_BLUE_MASK; result = true; break; case PixelFormat.Format32bppRgb: case PixelFormat.Format32bppArgb: case PixelFormat.Format32bppPArgb: type = FREE_IMAGE_TYPE.FIT_BITMAP; bpp = 32; red_mask = FI_RGBA_RED_MASK; green_mask = FI_RGBA_GREEN_MASK; blue_mask = FI_RGBA_BLUE_MASK; result = true; break; case PixelFormat.Format16bppGrayScale: type = FREE_IMAGE_TYPE.FIT_UINT16; bpp = 16; result = true; break; case PixelFormat.Format48bppRgb: type = FREE_IMAGE_TYPE.FIT_RGB16; bpp = 48; result = true; break; case PixelFormat.Format64bppArgb: case PixelFormat.Format64bppPArgb: type = FREE_IMAGE_TYPE.FIT_RGBA16; bpp = 64; result = true; break; } return result; } /// /// Returns the for the specified /// . /// /// The /// for which to return the corresponding . /// The for the specified /// public static FREE_IMAGE_FORMAT GetFormat(ImageFormat imageFormat) { if (imageFormat != null) { if (imageFormat.Equals(ImageFormat.Bmp)) return FREE_IMAGE_FORMAT.FIF_BMP; if (imageFormat.Equals(ImageFormat.Gif)) return FREE_IMAGE_FORMAT.FIF_GIF; if (imageFormat.Equals(ImageFormat.Icon)) return FREE_IMAGE_FORMAT.FIF_ICO; if (imageFormat.Equals(ImageFormat.Jpeg)) return FREE_IMAGE_FORMAT.FIF_JPEG; if (imageFormat.Equals(ImageFormat.Png)) return FREE_IMAGE_FORMAT.FIF_PNG; if (imageFormat.Equals(ImageFormat.Tiff)) return FREE_IMAGE_FORMAT.FIF_TIFF; } return FREE_IMAGE_FORMAT.FIF_UNKNOWN; } /// /// Retrieves all parameters needed to create a new FreeImage bitmap from /// raw bits . /// /// The /// of the data in memory. /// The color depth for the data. /// Returns the red_mask for the data. /// Returns the green_mask for the data. /// Returns the blue_mask for the data. /// True in case a matching conversion exists; else false. /// public static bool GetTypeParameters( FREE_IMAGE_TYPE type, int bpp, out uint red_mask, out uint green_mask, out uint blue_mask) { bool result = false; red_mask = 0; green_mask = 0; blue_mask = 0; switch (type) { case FREE_IMAGE_TYPE.FIT_BITMAP: switch (bpp) { case 1: case 4: case 8: result = true; break; case 16: result = true; red_mask = FI16_555_RED_MASK; green_mask = FI16_555_GREEN_MASK; blue_mask = FI16_555_BLUE_MASK; break; case 24: case 32: result = true; red_mask = FI_RGBA_RED_MASK; green_mask = FI_RGBA_GREEN_MASK; blue_mask = FI_RGBA_BLUE_MASK; break; } break; case FREE_IMAGE_TYPE.FIT_UNKNOWN: break; default: result = true; break; } return result; } /// /// Compares two FreeImage bitmaps. /// /// The first bitmap to compare. /// The second bitmap to compare. /// Determines which components of the bitmaps will be compared. /// True in case both bitmaps match the compare conditions, false otherwise. public static bool Compare(FIBITMAP dib1, FIBITMAP dib2, FREE_IMAGE_COMPARE_FLAGS flags) { // Check whether one bitmap is null if (dib1.IsNull ^ dib2.IsNull) { return false; } // Check whether both pointers are the same if (dib1 == dib2) { return true; } if (((flags & FREE_IMAGE_COMPARE_FLAGS.HEADER) > 0) && (!CompareHeader(dib1, dib2))) { return false; } if (((flags & FREE_IMAGE_COMPARE_FLAGS.PALETTE) > 0) && (!ComparePalette(dib1, dib2))) { return false; } if (((flags & FREE_IMAGE_COMPARE_FLAGS.DATA) > 0) && (!CompareData(dib1, dib2))) { return false; } if (((flags & FREE_IMAGE_COMPARE_FLAGS.METADATA) > 0) && (!CompareMetadata(dib1, dib2))) { return false; } return true; } private static unsafe bool CompareHeader(FIBITMAP dib1, FIBITMAP dib2) { IntPtr i1 = GetInfoHeader(dib1); IntPtr i2 = GetInfoHeader(dib2); return CompareMemory((void*)i1, (void*)i2, sizeof(BITMAPINFOHEADER)); } private static unsafe bool ComparePalette(FIBITMAP dib1, FIBITMAP dib2) { IntPtr pal1 = GetPalette(dib1), pal2 = GetPalette(dib2); bool hasPalette1 = pal1 != IntPtr.Zero; bool hasPalette2 = pal2 != IntPtr.Zero; if (hasPalette1 ^ hasPalette2) { return false; } if (!hasPalette1) { return true; } uint colors = GetColorsUsed(dib1); if (colors != GetColorsUsed(dib2)) { return false; } return CompareMemory((void*)pal1, (void*)pal2, sizeof(RGBQUAD) * colors); } private static unsafe bool CompareData(FIBITMAP dib1, FIBITMAP dib2) { uint width = GetWidth(dib1); if (width != GetWidth(dib2)) { return false; } uint height = GetHeight(dib1); if (height != GetHeight(dib2)) { return false; } uint bpp = GetBPP(dib1); if (bpp != GetBPP(dib2)) { return false; } if (GetColorType(dib1) != GetColorType(dib2)) { return false; } FREE_IMAGE_TYPE type = GetImageType(dib1); if (type != GetImageType(dib2)) { return false; } if (GetRedMask(dib1) != GetRedMask(dib2)) { return false; } if (GetGreenMask(dib1) != GetGreenMask(dib2)) { return false; } if (GetBlueMask(dib1) != GetBlueMask(dib2)) { return false; } byte* ptr1, ptr2; int fullBytes; int shift; uint line = GetLine(dib1); if (type == FREE_IMAGE_TYPE.FIT_BITMAP) { switch (bpp) { case 32: for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (!CompareMemory(ptr1, ptr2, line)) { return false; } } break; case 24: for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (!CompareMemory(ptr1, ptr2, line)) { return false; } } break; case 16: short* sPtr1, sPtr2; short mask = (short)(GetRedMask(dib1) | GetGreenMask(dib1) | GetBlueMask(dib1)); if (mask == -1) { for (int i = 0; i < height; i++) { sPtr1 = (short*)GetScanLine(dib1, i); sPtr2 = (short*)GetScanLine(dib2, i); if (!CompareMemory(sPtr1, sPtr1, line)) { return false; } } } else { for (int i = 0; i < height; i++) { sPtr1 = (short*)GetScanLine(dib1, i); sPtr2 = (short*)GetScanLine(dib2, i); for (int x = 0; x < width; x++) { if ((sPtr1[x] & mask) != (sPtr2[x] & mask)) { return false; } } } } break; case 8: for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (!CompareMemory(ptr1, ptr2, line)) { return false; } } break; case 4: fullBytes = (int)width / 2; shift = (width % 2) == 0 ? 8 : 4; for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (fullBytes != 0) { if (!CompareMemory(ptr1, ptr2, fullBytes)) { return false; } ptr1 += fullBytes; ptr2 += fullBytes; } if (shift != 8) { if ((ptr1[0] >> shift) != (ptr2[0] >> shift)) { return false; } } } break; case 1: fullBytes = (int)width / 8; shift = 8 - ((int)width % 8); for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (fullBytes != 0) { if (!CompareMemory(ptr1, ptr2, fullBytes)) { return false; } ptr1 += fullBytes; ptr2 += fullBytes; } if (shift != 8) { if ((ptr1[0] >> shift) != (ptr2[0] >> shift)) { return false; } } } break; default: throw new NotSupportedException("Only 1, 4, 8, 16, 24 and 32 bpp bitmaps are supported."); } } else { for (int i = 0; i < height; i++) { ptr1 = (byte*)GetScanLine(dib1, i); ptr2 = (byte*)GetScanLine(dib2, i); if (!CompareMemory(ptr1, ptr2, line)) { return false; } } } return true; } private static bool CompareMetadata(FIBITMAP dib1, FIBITMAP dib2) { MetadataTag tag1, tag2; foreach (FREE_IMAGE_MDMODEL metadataModel in FREE_IMAGE_MDMODELS) { if (GetMetadataCount(metadataModel, dib1) != GetMetadataCount(metadataModel, dib2)) { return false; } if (GetMetadataCount(metadataModel, dib1) == 0) { continue; } FIMETADATA mdHandle = FindFirstMetadata(metadataModel, dib1, out tag1); if (mdHandle.IsNull) { continue; } do { if ((!GetMetadata(metadataModel, dib2, tag1.Key, out tag2)) || (tag1 != tag2)) { FindCloseMetadata(mdHandle); return false; } } while (FindNextMetadata(mdHandle, out tag1)); FindCloseMetadata(mdHandle); } return true; } /// /// Returns the FreeImage bitmap's transparency table. /// The array is empty in case the bitmap has no transparency table. /// /// Handle to a FreeImage bitmap. /// The FreeImage bitmap's transparency table. /// /// is null. public static unsafe byte[] GetTransparencyTableEx(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } uint count = GetTransparencyCount(dib); byte[] result = new byte[count]; byte* ptr = (byte*)GetTransparencyTable(dib); fixed (byte* dst = result) { CopyMemory(dst, ptr, count); } return result; } /// /// Set the FreeImage bitmap's transparency table. Only affects palletised bitmaps. /// /// Handle to a FreeImage bitmap. /// The FreeImage bitmap's new transparency table. /// /// or is null. public static void SetTransparencyTable(FIBITMAP dib, byte[] table) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } if (table == null) { throw new ArgumentNullException("table"); } SetTransparencyTable(dib, table, table.Length); } /// /// This function returns the number of unique colors actually used by the /// specified 1-, 4-, 8-, 16-, 24- or 32-bit image. This might be different from /// what function FreeImage_GetColorsUsed() returns, which actually returns the /// palette size for palletised images. Works for /// type images only. /// /// Handle to a FreeImage bitmap. /// Returns the number of unique colors used by the image specified or /// zero, if the image type cannot be handled. /// /// is null. public static unsafe int GetUniqueColors(FIBITMAP dib) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } int result = 0; if (GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) { BitArray bitArray; int uniquePalEnts; int hashcode; byte[] lut; int width = (int)GetWidth(dib); int height = (int)GetHeight(dib); switch (GetBPP(dib)) { case 1: result = 1; lut = CreateShrunkenPaletteLUT(dib, out uniquePalEnts); if (uniquePalEnts == 1) { break; } if ((*(byte*)GetScanLine(dib, 0) & 0x80) == 0) { for (int y = 0; y < height; y++) { byte* scanline = (byte*)GetScanLine(dib, y); int mask = 0x80; for (int x = 0; x < width; x++) { if ((scanline[x / 8] & mask) > 0) { return 2; } mask = (mask == 0x1) ? 0x80 : (mask >> 1); } } } else { for (int y = 0; y < height; y++) { byte* scanline = (byte*)GetScanLine(dib, y); int mask = 0x80; for (int x = 0; x < width; x++) { if ((scanline[x / 8] & mask) == 0) { return 2; } mask = (mask == 0x1) ? 0x80 : (mask >> 1); } } } break; case 4: bitArray = new BitArray(0x10); lut = CreateShrunkenPaletteLUT(dib, out uniquePalEnts); if (uniquePalEnts == 1) { result = 1; break; } for (int y = 0; (y < height) && (result < uniquePalEnts); y++) { byte* scanline = (byte*)GetScanLine(dib, y); bool top = true; for (int x = 0; (x < width) && (result < uniquePalEnts); x++) { if (top) { hashcode = lut[scanline[x / 2] >> 4]; } else { hashcode = lut[scanline[x / 2] & 0xF]; } top = !top; if (!bitArray[hashcode]) { bitArray[hashcode] = true; result++; } } } break; case 8: bitArray = new BitArray(0x100); lut = CreateShrunkenPaletteLUT(dib, out uniquePalEnts); if (uniquePalEnts == 1) { result = 1; break; } for (int y = 0; (y < height) && (result < uniquePalEnts); y++) { byte* scanline = (byte*)GetScanLine(dib, y); for (int x = 0; (x < width) && (result < uniquePalEnts); x++) { hashcode = lut[scanline[x]]; if (!bitArray[hashcode]) { bitArray[hashcode] = true; result++; } } } break; case 16: bitArray = new BitArray(0x10000); for (int y = 0; y < height; y++) { short* scanline = (short*)GetScanLine(dib, y); for (int x = 0; x < width; x++, scanline++) { hashcode = *scanline; if (!bitArray[hashcode]) { bitArray[hashcode] = true; result++; } } } break; case 24: bitArray = new BitArray(0x1000000); for (int y = 0; y < height; y++) { byte* scanline = (byte*)GetScanLine(dib, y); for (int x = 0; x < width; x++, scanline += 3) { hashcode = *((int*)scanline) & 0x00FFFFFF; if (!bitArray[hashcode]) { bitArray[hashcode] = true; result++; } } } break; case 32: bitArray = new BitArray(0x1000000); for (int y = 0; y < height; y++) { int* scanline = (int*)GetScanLine(dib, y); for (int x = 0; x < width; x++, scanline++) { hashcode = *scanline & 0x00FFFFFF; if (!bitArray[hashcode]) { bitArray[hashcode] = true; result++; } } } break; } } return result; } /// /// Verifies whether the FreeImage bitmap is 16bit 555. /// /// The FreeImage bitmap to verify. /// true if the bitmap is RGB16-555; otherwise false. public static bool IsRGB555(FIBITMAP dib) { return ((GetRedMask(dib) == FI16_555_RED_MASK) && (GetGreenMask(dib) == FI16_555_GREEN_MASK) && (GetBlueMask(dib) == FI16_555_BLUE_MASK)); } /// /// Verifies whether the FreeImage bitmap is 16bit 565. /// /// The FreeImage bitmap to verify. /// true if the bitmap is RGB16-565; otherwise false. public static bool IsRGB565(FIBITMAP dib) { return ((GetRedMask(dib) == FI16_565_RED_MASK) && (GetGreenMask(dib) == FI16_565_GREEN_MASK) && (GetBlueMask(dib) == FI16_565_BLUE_MASK)); } #endregion #region ICC profile functions /// /// Creates a new ICC-Profile for a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// The data of the new ICC-Profile. /// The new ICC-Profile of the bitmap. /// /// is null. public static FIICCPROFILE CreateICCProfileEx(FIBITMAP dib, byte[] data) { return new FIICCPROFILE(dib, data); } /// /// Creates a new ICC-Profile for a FreeImage bitmap. /// /// Handle to a FreeImage bitmap. /// The data of the new ICC-Profile. /// The number of bytes of to use. /// The new ICC-Profile of the FreeImage bitmap. /// /// is null. public static FIICCPROFILE CreateICCProfileEx(FIBITMAP dib, byte[] data, int size) { return new FIICCPROFILE(dib, data, size); } #endregion #region Conversion functions /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion) { return ConvertColorDepth( dib, conversion, 128, FREE_IMAGE_DITHER.FID_FS, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, false); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// When true the structure will be unloaded on success. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, bool unloadSource) { return ConvertColorDepth( dib, conversion, 128, FREE_IMAGE_DITHER.FID_FS, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, unloadSource); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Threshold value when converting with /// . /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, byte threshold) { return ConvertColorDepth( dib, conversion, threshold, FREE_IMAGE_DITHER.FID_FS, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, false); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Dither algorithm when converting /// with . /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, FREE_IMAGE_DITHER ditherMethod) { return ConvertColorDepth( dib, conversion, 128, ditherMethod, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, false); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// The quantization algorithm for conversion to 8-bit color depth. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, FREE_IMAGE_QUANTIZE quantizationMethod) { return ConvertColorDepth( dib, conversion, 128, FREE_IMAGE_DITHER.FID_FS, quantizationMethod, false); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Threshold value when converting with /// . /// When true the structure will be unloaded on success. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, byte threshold, bool unloadSource) { return ConvertColorDepth( dib, conversion, threshold, FREE_IMAGE_DITHER.FID_FS, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, unloadSource); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Dither algorithm when converting with /// . /// When true the structure will be unloaded on success. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, FREE_IMAGE_DITHER ditherMethod, bool unloadSource) { return ConvertColorDepth( dib, conversion, 128, ditherMethod, FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, unloadSource); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// The quantization algorithm for conversion to 8-bit color depth. /// When true the structure will be unloaded on success. /// Handle to a FreeImage bitmap. /// /// is null. public static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, FREE_IMAGE_QUANTIZE quantizationMethod, bool unloadSource) { return ConvertColorDepth( dib, conversion, 128, FREE_IMAGE_DITHER.FID_FS, quantizationMethod, unloadSource); } /// /// Converts a FreeImage bitmap from one color depth to another. /// If the conversion fails the original FreeImage bitmap is returned. /// /// Handle to a FreeImage bitmap. /// The desired output format. /// Threshold value when converting with /// . /// Dither algorithm when converting with /// . /// The quantization algorithm for conversion to 8-bit color depth. /// When true the structure will be unloaded on success. /// Handle to a FreeImage bitmap. /// /// is null. internal static FIBITMAP ConvertColorDepth( FIBITMAP dib, FREE_IMAGE_COLOR_DEPTH conversion, byte threshold, FREE_IMAGE_DITHER ditherMethod, FREE_IMAGE_QUANTIZE quantizationMethod, bool unloadSource) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } FIBITMAP result = new FIBITMAP(); FIBITMAP dibTemp = new FIBITMAP(); uint bpp = GetBPP(dib); bool reorderPalette = ((conversion & FREE_IMAGE_COLOR_DEPTH.FICD_REORDER_PALETTE) > 0); bool forceGreyscale = ((conversion & FREE_IMAGE_COLOR_DEPTH.FICD_FORCE_GREYSCALE) > 0); if (GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) { switch (conversion & (FREE_IMAGE_COLOR_DEPTH)0xFF) { case FREE_IMAGE_COLOR_DEPTH.FICD_01_BPP_THRESHOLD: if (bpp != 1) { if (forceGreyscale) { result = Threshold(dib, threshold); } else { dibTemp = ConvertTo24Bits(dib); result = ColorQuantizeEx(dibTemp, quantizationMethod, 2, null, 1); Unload(dibTemp); } } else { bool isGreyscale = IsGreyscaleImage(dib); if ((forceGreyscale && (!isGreyscale)) || (reorderPalette && isGreyscale)) { result = Threshold(dib, threshold); } } break; case FREE_IMAGE_COLOR_DEPTH.FICD_01_BPP_DITHER: if (bpp != 1) { if (forceGreyscale) { result = Dither(dib, ditherMethod); } else { dibTemp = ConvertTo24Bits(dib); result = ColorQuantizeEx(dibTemp, quantizationMethod, 2, null, 1); Unload(dibTemp); } } else { bool isGreyscale = IsGreyscaleImage(dib); if ((forceGreyscale && (!isGreyscale)) || (reorderPalette && isGreyscale)) { result = Dither(dib, ditherMethod); } } break; case FREE_IMAGE_COLOR_DEPTH.FICD_04_BPP: if (bpp != 4) { // Special case when 1bpp and FIC_PALETTE if (forceGreyscale || ((bpp == 1) && (GetColorType(dib) == FREE_IMAGE_COLOR_TYPE.FIC_PALETTE))) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo4Bits(dibTemp); Unload(dibTemp); } else { dibTemp = ConvertTo24Bits(dib); result = ColorQuantizeEx(dibTemp, quantizationMethod, 16, null, 4); Unload(dibTemp); } } else { bool isGreyscale = IsGreyscaleImage(dib); if ((forceGreyscale && (!isGreyscale)) || (reorderPalette && isGreyscale)) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo4Bits(dibTemp); Unload(dibTemp); } } break; case FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP: if (bpp != 8) { if (forceGreyscale) { result = ConvertToGreyscale(dib); } else { dibTemp = ConvertTo24Bits(dib); result = ColorQuantize(dibTemp, quantizationMethod); Unload(dibTemp); } } else { bool isGreyscale = IsGreyscaleImage(dib); if ((forceGreyscale && (!isGreyscale)) || (reorderPalette && isGreyscale)) { result = ConvertToGreyscale(dib); } } break; case FREE_IMAGE_COLOR_DEPTH.FICD_16_BPP_555: if (forceGreyscale) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo16Bits555(dibTemp); Unload(dibTemp); } else if (bpp != 16 || GetRedMask(dib) != FI16_555_RED_MASK || GetGreenMask(dib) != FI16_555_GREEN_MASK || GetBlueMask(dib) != FI16_555_BLUE_MASK) { result = ConvertTo16Bits555(dib); } break; case FREE_IMAGE_COLOR_DEPTH.FICD_16_BPP: if (forceGreyscale) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo16Bits565(dibTemp); Unload(dibTemp); } else if (bpp != 16 || GetRedMask(dib) != FI16_565_RED_MASK || GetGreenMask(dib) != FI16_565_GREEN_MASK || GetBlueMask(dib) != FI16_565_BLUE_MASK) { result = ConvertTo16Bits565(dib); } break; case FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP: if (forceGreyscale) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo24Bits(dibTemp); Unload(dibTemp); } else if (bpp != 24) { result = ConvertTo24Bits(dib); } break; case FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP: if (forceGreyscale) { dibTemp = ConvertToGreyscale(dib); result = ConvertTo32Bits(dibTemp); Unload(dibTemp); } else if (bpp != 32) { result = ConvertTo32Bits(dib); } break; } } if (result.IsNull) { return dib; } if (unloadSource) { Unload(dib); } return result; } /// /// ColorQuantizeEx is an extension to the /// method that provides additional options used to quantize a 24-bit image to any /// number of colors (up to 256), as well as quantize a 24-bit image using a /// provided palette. /// /// Handle to a FreeImage bitmap. /// Specifies the color reduction algorithm to be used. /// Size of the desired output palette. /// The provided palette. /// true to create a bitmap with the smallest possible /// color depth for the specified . /// Handle to a FreeImage bitmap. public static FIBITMAP ColorQuantizeEx(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, RGBQUAD[] ReservePalette, bool minColorDepth) { FIBITMAP result; if (minColorDepth) { int bpp; if (PaletteSize >= 256) bpp = 8; else if (PaletteSize > 2) bpp = 4; else bpp = 1; result = ColorQuantizeEx(dib, quantize, PaletteSize, ReservePalette, bpp); } else { result = ColorQuantizeEx(dib, quantize, PaletteSize, ReservePalette, 8); } return result; } /// /// ColorQuantizeEx is an extension to the /// method that provides additional options used to quantize a 24-bit image to any /// number of colors (up to 256), as well as quantize a 24-bit image using a /// partial or full provided palette. /// /// Handle to a FreeImage bitmap. /// Specifies the color reduction algorithm to be used. /// Size of the desired output palette. /// The provided palette. /// The desired color depth of the created image. /// Handle to a FreeImage bitmap. public static FIBITMAP ColorQuantizeEx(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, RGBQUAD[] ReservePalette, int bpp) { unsafe { FIBITMAP result = FIBITMAP.Zero; FIBITMAP temp = FIBITMAP.Zero; int reservedSize = (ReservePalette == null) ? 0 : ReservePalette.Length; if (bpp == 8) { result = ColorQuantizeEx(dib, quantize, PaletteSize, reservedSize, ReservePalette); } else if (bpp == 4) { temp = ColorQuantizeEx(dib, quantize, Math.Min(16, PaletteSize), reservedSize, ReservePalette); if (!temp.IsNull) { result = Allocate((int)GetWidth(temp), (int)GetHeight(temp), 4, 0, 0, 0); CloneMetadata(result, temp); CopyMemory(GetPalette(result), GetPalette(temp), sizeof(RGBQUAD) * 16); for (int y = (int)GetHeight(temp) - 1; y >= 0; y--) { Scanline srcScanline = new Scanline(temp, y); Scanline dstScanline = new Scanline(result, y); for (int x = (int)GetWidth(temp) - 1; x >= 0; x--) { dstScanline[x] = srcScanline[x]; } } } } else if (bpp == 1) { temp = ColorQuantizeEx(dib, quantize, 2, reservedSize, ReservePalette); if (!temp.IsNull) { result = Allocate((int)GetWidth(temp), (int)GetHeight(temp), 1, 0, 0, 0); CloneMetadata(result, temp); CopyMemory(GetPalette(result), GetPalette(temp), sizeof(RGBQUAD) * 2); for (int y = (int)GetHeight(temp) - 1; y >= 0; y--) { Scanline srcScanline = new Scanline(temp, y); Scanline dstScanline = new Scanline(result, y); for (int x = (int)GetWidth(temp) - 1; x >= 0; x--) { dstScanline[x] = srcScanline[x]; } } } } UnloadEx(ref temp); return result; } } #endregion #region Metadata /// /// Copies metadata from one FreeImage bitmap to another. /// /// Source FreeImage bitmap containing the metadata. /// FreeImage bitmap to copy the metadata to. /// Flags to switch different copy modes. /// Returns -1 on failure else the number of copied tags. /// /// or is null. public static int CloneMetadataEx(FIBITMAP src, FIBITMAP dst, FREE_IMAGE_METADATA_COPY flags) { if (src.IsNull) { throw new ArgumentNullException("src"); } if (dst.IsNull) { throw new ArgumentNullException("dst"); } FITAG tag = new FITAG(), tag2 = new FITAG(); int copied = 0; // Clear all existing metadata if ((flags & FREE_IMAGE_METADATA_COPY.CLEAR_EXISTING) > 0) { foreach (FREE_IMAGE_MDMODEL model in FREE_IMAGE_MDMODELS) { if (!SetMetadata(model, dst, null, tag)) { return -1; } } } bool keep = !((flags & FREE_IMAGE_METADATA_COPY.REPLACE_EXISTING) > 0); foreach (FREE_IMAGE_MDMODEL model in FREE_IMAGE_MDMODELS) { FIMETADATA mData = FindFirstMetadata(model, src, out tag); if (mData.IsNull) continue; do { string key = GetTagKey(tag); if (!(keep && GetMetadata(model, dst, key, out tag2))) { if (SetMetadata(model, dst, key, tag)) { copied++; } } } while (FindNextMetadata(mData, out tag)); FindCloseMetadata(mData); } return copied; } /// /// Returns the comment of a JPEG, PNG or GIF image. /// /// Handle to a FreeImage bitmap. /// Comment of the FreeImage bitmp, or null in case no comment exists. /// /// is null. public static string GetImageComment(FIBITMAP dib) { string result = null; if (dib.IsNull) { throw new ArgumentNullException("dib"); } FITAG tag; if (GetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, dib, "Comment", out tag)) { MetadataTag metadataTag = new MetadataTag(tag, FREE_IMAGE_MDMODEL.FIMD_COMMENTS); result = metadataTag.Value as string; } return result; } /// /// Sets the comment of a JPEG, PNG or GIF image. /// /// Handle to a FreeImage bitmap. /// New comment of the FreeImage bitmap. /// Use null to remove the comment. /// Returns true on success, false on failure. /// /// is null. public static bool SetImageComment(FIBITMAP dib, string comment) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } bool result; if (comment != null) { FITAG tag = CreateTag(); MetadataTag metadataTag = new MetadataTag(tag, FREE_IMAGE_MDMODEL.FIMD_COMMENTS); metadataTag.Value = comment; result = SetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, dib, "Comment", tag); DeleteTag(tag); } else { result = SetMetadata(FREE_IMAGE_MDMODEL.FIMD_COMMENTS, dib, "Comment", FITAG.Zero); } return result; } /// /// Retrieve a metadata attached to a FreeImage bitmap. /// /// The metadata model to look for. /// Handle to a FreeImage bitmap. /// The metadata field name. /// A structure returned by the function. /// Returns true on success, false on failure. /// /// is null. public static bool GetMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP dib, string key, out MetadataTag tag) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } FITAG _tag; bool result; if (GetMetadata(model, dib, key, out _tag)) { tag = new MetadataTag(_tag, model); result = true; } else { tag = null; result = false; } return result; } /// /// Attach a new metadata tag to a FreeImage bitmap. /// /// The metadata model used to store the tag. /// Handle to a FreeImage bitmap. /// The tag field name. /// The to be attached. /// Returns true on success, false on failure. /// /// is null. public static bool SetMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP dib, string key, MetadataTag tag) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } return SetMetadata(model, dib, key, tag.tag); } /// /// Provides information about the first instance of a tag that matches the metadata model. /// /// The model to match. /// Handle to a FreeImage bitmap. /// Tag that matches the metadata model. /// Unique search handle that can be used to call FindNextMetadata or FindCloseMetadata. /// Null if the metadata model does not exist. /// /// is null. public static FIMETADATA FindFirstMetadata( FREE_IMAGE_MDMODEL model, FIBITMAP dib, out MetadataTag tag) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } FITAG _tag; FIMETADATA result = FindFirstMetadata(model, dib, out _tag); if (result.IsNull) { tag = null; return result; } tag = new MetadataTag(_tag, model); if (metaDataSearchHandler.ContainsKey(result)) { metaDataSearchHandler[result] = model; } else { metaDataSearchHandler.Add(result, model); } return result; } /// /// Find the next tag, if any, that matches the metadata model argument in a previous call /// to FindFirstMetadata, and then alters the tag object contents accordingly. /// /// Unique search handle provided by FindFirstMetadata. /// Tag that matches the metadata model. /// Returns true on success, false on failure. public static bool FindNextMetadata(FIMETADATA mdhandle, out MetadataTag tag) { FITAG _tag; bool result; if (FindNextMetadata(mdhandle, out _tag)) { tag = new MetadataTag(_tag, metaDataSearchHandler[mdhandle]); result = true; } else { tag = null; result = false; } return result; } /// /// Closes the specified metadata search handle and releases associated resources. /// /// The handle to close. public static void FindCloseMetadata(FIMETADATA mdhandle) { if (metaDataSearchHandler.ContainsKey(mdhandle)) { metaDataSearchHandler.Remove(mdhandle); } FindCloseMetadata_(mdhandle); } /// /// This dictionary links FIMETADATA handles and FREE_IMAGE_MDMODEL models. /// private static Dictionary metaDataSearchHandler = new Dictionary(1); #endregion #region Rotation and Flipping /// /// This function rotates a 1-, 8-bit greyscale or a 24-, 32-bit color image by means of 3 shears. /// 1-bit images rotation is limited to integer multiple of 90�. /// null is returned for other values. /// /// Handle to a FreeImage bitmap. /// The angle of rotation. /// Handle to a FreeImage bitmap. public static FIBITMAP Rotate(FIBITMAP dib, double angle) { return Rotate(dib, angle, IntPtr.Zero); } /// /// This function rotates a 1-, 8-bit greyscale or a 24-, 32-bit color image by means of 3 shears. /// 1-bit images rotation is limited to integer multiple of 90�. /// null is returned for other values. /// /// The type of the color to use as background. /// Handle to a FreeImage bitmap. /// The angle of rotation. /// The color used used to fill the bitmap's background. /// Handle to a FreeImage bitmap. public static FIBITMAP Rotate(FIBITMAP dib, double angle, T? backgroundColor) where T : struct { if (backgroundColor.HasValue) { GCHandle handle = new GCHandle(); try { T[] buffer = new T[] { backgroundColor.Value }; handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return Rotate(dib, angle, handle.AddrOfPinnedObject()); } finally { if (handle.IsAllocated) handle.Free(); } } else { return Rotate(dib, angle, IntPtr.Zero); } } /// /// Rotates a 4-bit color FreeImage bitmap. /// Allowed values for are 90, 180 and 270. /// In case is 0 or 360 a clone is returned. /// 0 is returned for other values or in case the rotation fails. /// /// Handle to a FreeImage bitmap. /// The angle of rotation. /// Handle to a FreeImage bitmap. /// /// This function is kind of temporary due to FreeImage's lack of /// rotating 4-bit images. It's particularly used by 's /// method RotateFlip. This function will be removed as soon as FreeImage /// supports rotating 4-bit images. /// /// /// is null. public static unsafe FIBITMAP Rotate4bit(FIBITMAP dib, double angle) { if (dib.IsNull) { throw new ArgumentNullException("dib"); } FIBITMAP result = new FIBITMAP(); int ang = (int)angle; if ((GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) && (GetBPP(dib) == 4) && ((ang % 90) == 0)) { int width, height, xOrg, yOrg; Scanline[] src, dst; width = (int)GetWidth(dib); height = (int)GetHeight(dib); byte index = 0; switch (ang) { case 90: result = Allocate(height, width, 4, 0, 0, 0); if (result.IsNull) { break; } CopyPalette(dib, result); src = Get04BitScanlines(dib); dst = Get04BitScanlines(result); for (int y = 0; y < width; y++) { yOrg = height - 1; for (int x = 0; x < height; x++, yOrg--) { index = src[yOrg][y]; dst[y][x] = index; } } break; case 180: result = Allocate(width, height, 4, 0, 0, 0); if (result.IsNull) { break; } CopyPalette(dib, result); src = Get04BitScanlines(dib); dst = Get04BitScanlines(result); yOrg = height - 1; for (int y = 0; y < height; y++, yOrg--) { xOrg = width - 1; for (int x = 0; x < width; x++, xOrg--) { index = src[yOrg][xOrg]; dst[y][x] = index; } } break; case 270: result = Allocate(height, width, 4, 0, 0, 0); if (result.IsNull) { break; } CopyPalette(dib, result); src = Get04BitScanlines(dib); dst = Get04BitScanlines(result); xOrg = width - 1; for (int y = 0; y < width; y++, xOrg--) { for (int x = 0; x < height; x++) { index = src[x][xOrg]; dst[y][x] = index; } } break; case 0: case 360: result = Clone(dib); break; } } return result; } #endregion #region Upsampling / downsampling /// /// Enlarges or shrinks the FreeImage bitmap selectively per side and fills newly added areas /// with the specified background color. See remarks for further details. /// /// The type of the specified color. /// Handle to a FreeImage bitmap. /// The number of pixels, the image should be enlarged on its left side. /// Negative values shrink the image on its left side. /// The number of pixels, the image should be enlarged on its top side. /// Negative values shrink the image on its top side. /// The number of pixels, the image should be enlarged on its right side. /// Negative values shrink the image on its right side. /// The number of pixels, the image should be enlarged on its bottom side. /// Negative values shrink the image on its bottom side. /// The color, the enlarged sides of the image should be filled with. /// Options that affect the color search process for palletized images. /// Handle to a FreeImage bitmap. /// /// This function enlarges or shrinks an image selectively per side. /// The main purpose of this function is to add borders to an image. /// To add a border to any of the image's sides, a positive integer value must be passed in /// any of the parameters , , /// or . This value represents the border's /// width in pixels. Newly created parts of the image (the border areas) are filled with the /// specified . /// Specifying a negative integer value for a certain side, will shrink or crop the image on /// this side. Consequently, specifying zero for a certain side will not change the image's /// extension on that side. /// /// So, calling this function with all parameters , , /// and set to zero, is /// effectively the same as calling function ; setting all parameters /// , , and /// to value equal to or smaller than zero, my easily be substituted /// by a call to function . Both these cases produce a new image, which is /// guaranteed not to be larger than the input image. Thus, since the specified /// is not needed in these cases, /// may be null. /// /// Both parameters and work according to /// function . So, please refer to the documentation of /// to learn more about parameters /// and . For palletized images, the palette of the input image is /// transparently copied to the newly created enlarged or shrunken image, so any color look-ups /// are performed on this palette. /// /// /// // create a white color
/// RGBQUAD c;
/// c.rgbRed = 0xFF;
/// c.rgbGreen = 0xFF;
/// c.rgbBlue = 0xFF;
/// c.rgbReserved = 0x00;
///
/// // add a white, symmetric 10 pixel wide border to the image
/// dib2 = FreeImage_EnlargeCanvas(dib, 10, 10, 10, 10, c, FREE_IMAGE_COLOR_OPTIONS.FICO_RGB);
///
/// // add white, 20 pixel wide stripes to the top and bottom side of the image
/// dib3 = FreeImage_EnlargeCanvas(dib, 0, 20, 0, 20, c, FREE_IMAGE_COLOR_OPTIONS.FICO_RGB);
///
/// // add white, 30 pixel wide stripes to the right side of the image and
/// // cut off the 40 leftmost pixel columns
/// dib3 = FreeImage_EnlargeCanvas(dib, -40, 0, 30, 0, c, FREE_IMAGE_COLOR_OPTIONS.FICO_RGB);
///
public static FIBITMAP EnlargeCanvas(FIBITMAP dib, int left, int top, int right, int bottom, T? color, FREE_IMAGE_COLOR_OPTIONS options) where T : struct { if (dib.IsNull) return FIBITMAP.Zero; if (!CheckColorType(GetImageType(dib), color)) return FIBITMAP.Zero; if (color.HasValue) { GCHandle handle = new GCHandle(); try { T[] buffer = new T[] { color.Value }; handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return EnlargeCanvas(dib, left, top, right, bottom, handle.AddrOfPinnedObject(), options); } finally { if (handle.IsAllocated) handle.Free(); } } else { return EnlargeCanvas(dib, left, top, right, bottom, IntPtr.Zero, options); } } #endregion #region Color /// /// Sets all pixels of the specified image to the color provided through the /// parameter. See remarks for further details. /// /// The type of the specified color. /// Handle to a FreeImage bitmap. /// The color to fill the bitmap with. See remarks for further details. /// Options that affect the color search process for palletized images. /// true on success, false on failure. /// /// This function sets all pixels of an image to the color provided through /// the parameter. is used for standard type images. /// For non standard type images the underlaying structure is used. /// /// So, must be of type , if the image to be filled is of type /// and must be a structure if the /// image is of type and so on. /// /// However, the fill color is always specified through a structure /// for all images of type . /// So, for 32- and 24-bit images, the red, green and blue members of the /// structure are directly used for the image's red, green and blue channel respectively. /// Although alpha transparent colors are /// supported, the alpha channel of a 32-bit image never gets modified by this function. /// A fill color with an alpha value smaller than 255 gets blended with the image's actual /// background color, which is determined from the image's bottom-left pixel. /// So, currently using alpha enabled colors, assumes the image to be unicolor before the /// fill operation. However, the field is only taken into account, /// if option has been specified. /// /// For 16-bit images, the red-, green- and blue components of the specified color are /// transparently translated into either the 16-bit 555 or 565 representation. This depends /// on the image's actual red- green- and blue masks. /// /// Special attention must be payed for palletized images. Generally, the RGB color specified /// is looked up in the image's palette. The found palette index is then used to fill the image. /// There are some option flags, that affect this lookup process: /// /// /// Value /// Meaning /// /// /// /// /// Uses the color, that is nearest to the specified color. /// This is the default behavior and should always find a /// color in the palette. However, the visual result may /// far from what was expected and mainly depends on the /// image's palette. /// /// /// /// /// /// Searches the image's palette for the specified color /// but only uses the returned palette index, if the specified /// color exactly matches the palette entry. Of course, /// depending on the image's actual palette entries, this /// operation may fail. In this case, the function falls back /// to option /// and uses the RGBQUAD's rgbReserved member (or its low nibble for 4-bit images /// or its least significant bit (LSB) for 1-bit images) as /// the palette index used for the fill operation. /// /// /// /// /// /// Does not perform any color lookup from the palette, but /// uses the RGBQUAD's alpha channel member rgbReserved as /// the palette index to be used for the fill operation. /// However, for 4-bit images, only the low nibble of the /// rgbReserved member are used and for 1-bit images, only /// the least significant bit (LSB) is used. /// /// /// /// public static bool FillBackground(FIBITMAP dib, T color, FREE_IMAGE_COLOR_OPTIONS options) where T : struct { if (dib.IsNull) return false; if (!CheckColorType(GetImageType(dib), color)) return false; GCHandle handle = new GCHandle(); try { T[] buffer = new T[] { color }; handle = GCHandle.Alloc(buffer, GCHandleType.Pinned); return FillBackground(dib, handle.AddrOfPinnedObject(), options); } finally { if (handle.IsAllocated) handle.Free(); } } #endregion #region Wrapper functions /// /// Returns the next higher possible color depth. /// /// Color depth to increase. /// The next higher color depth or 0 if there is no valid color depth. internal static int GetNextColorDepth(int bpp) { int result = 0; switch (bpp) { case 1: result = 4; break; case 4: result = 8; break; case 8: result = 16; break; case 16: result = 24; break; case 24: result = 32; break; } return result; } /// /// Returns the next lower possible color depth. /// /// Color depth to decrease. /// The next lower color depth or 0 if there is no valid color depth. internal static int GetPrevousColorDepth(int bpp) { int result = 0; switch (bpp) { case 32: result = 24; break; case 24: result = 16; break; case 16: result = 8; break; case 8: result = 4; break; case 4: result = 1; break; } return result; } /// /// Reads a null-terminated c-string. /// /// Pointer to the first char of the string. /// The converted string. internal static unsafe string PtrToStr(byte* ptr) { string result = null; if (ptr != null) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); while (*ptr != 0) { sb.Append((char)(*(ptr++))); } result = sb.ToString(); } return result; } internal static unsafe byte[] CreateShrunkenPaletteLUT(FIBITMAP dib, out int uniqueColors) { byte[] result = null; uniqueColors = 0; if ((!dib.IsNull) && (GetImageType(dib) == FREE_IMAGE_TYPE.FIT_BITMAP) && (GetBPP(dib) <= 8)) { int size = (int)GetColorsUsed(dib); List newPalette = new List(size); List lut = new List(size); RGBQUAD* palette = (RGBQUAD*)GetPalette(dib); RGBQUAD color; int index; for (int i = 0; i < size; i++) { color = palette[i]; color.rgbReserved = 255; // ignore alpha index = newPalette.IndexOf(color); if (index < 0) { newPalette.Add(color); lut.Add((byte)(newPalette.Count - 1)); } else { lut.Add((byte)index); } } result = lut.ToArray(); uniqueColors = newPalette.Count; } return result; } internal static PropertyItem CreatePropertyItem() { return (PropertyItem)Activator.CreateInstance(typeof(PropertyItem), true); } private static unsafe void CopyPalette(FIBITMAP src, FIBITMAP dst) { RGBQUAD* orgPal = (RGBQUAD*)GetPalette(src); RGBQUAD* newPal = (RGBQUAD*)GetPalette(dst); uint size = (uint)(sizeof(RGBQUAD) * GetColorsUsed(src)); CopyMemory(newPal, orgPal, size); } private static unsafe Scanline[] Get04BitScanlines(FIBITMAP dib) { int height = (int)GetHeight(dib); Scanline[] array = new Scanline[height]; for (int i = 0; i < height; i++) { array[i] = new Scanline(dib, i); } return array; } /// /// Changes a bitmaps color depth. /// Used by SaveEx and SaveToStream. /// private static FIBITMAP PrepareBitmapColorDepth(FIBITMAP dibToSave, FREE_IMAGE_FORMAT format, FREE_IMAGE_COLOR_DEPTH colorDepth) { FREE_IMAGE_TYPE type = GetImageType(dibToSave); if (type == FREE_IMAGE_TYPE.FIT_BITMAP) { int bpp = (int)GetBPP(dibToSave); int targetBpp = (int)(colorDepth & FREE_IMAGE_COLOR_DEPTH.FICD_COLOR_MASK); if (colorDepth != FREE_IMAGE_COLOR_DEPTH.FICD_AUTO) { // A fix colordepth was chosen if (FIFSupportsExportBPP(format, targetBpp)) { dibToSave = ConvertColorDepth(dibToSave, colorDepth, false); } else { throw new ArgumentException("FreeImage\n\nFreeImage Library plugin " + GetFormatFromFIF(format) + " is unable to write images with a color depth of " + targetBpp + " bpp."); } } else { // Auto selection was chosen if (!FIFSupportsExportBPP(format, bpp)) { // The color depth is not supported int bppUpper = bpp; int bppLower = bpp; // Check from the bitmaps current color depth in both directions do { bppUpper = GetNextColorDepth(bppUpper); if (FIFSupportsExportBPP(format, bppUpper)) { dibToSave = ConvertColorDepth(dibToSave, (FREE_IMAGE_COLOR_DEPTH)bppUpper, false); break; } bppLower = GetPrevousColorDepth(bppLower); if (FIFSupportsExportBPP(format, bppLower)) { dibToSave = ConvertColorDepth(dibToSave, (FREE_IMAGE_COLOR_DEPTH)bppLower, false); break; } } while (!((bppLower == 0) && (bppUpper == 0))); } } } return dibToSave; } /// /// Compares blocks of memory. /// /// A pointer to a block of memory to compare. /// A pointer to a block of memory to compare. /// Specifies the number of bytes to be compared. /// true, if all bytes compare as equal, false otherwise. public static unsafe bool CompareMemory(void* buf1, void* buf2, uint length) { return (length == RtlCompareMemory(buf1, buf2, length)); } /// /// Compares blocks of memory. /// /// A pointer to a block of memory to compare. /// A pointer to a block of memory to compare. /// Specifies the number of bytes to be compared. /// true, if all bytes compare as equal, false otherwise. public static unsafe bool CompareMemory(void* buf1, void* buf2, long length) { return (length == RtlCompareMemory(buf1, buf2, checked((uint)length))); } /// /// Compares blocks of memory. /// /// A pointer to a block of memory to compare. /// A pointer to a block of memory to compare. /// Specifies the number of bytes to be compared. /// true, if all bytes compare as equal, false otherwise. public static unsafe bool CompareMemory(IntPtr buf1, IntPtr buf2, uint length) { return (length == RtlCompareMemory(buf1.ToPointer(), buf2.ToPointer(), length)); } /// /// Compares blocks of memory. /// /// A pointer to a block of memory to compare. /// A pointer to a block of memory to compare. /// Specifies the number of bytes to be compared. /// true, if all bytes compare as equal, false otherwise. public static unsafe bool CompareMemory(IntPtr buf1, IntPtr buf2, long length) { return (length == RtlCompareMemory(buf1.ToPointer(), buf2.ToPointer(), checked((uint)length))); } /// /// Moves a block of memory from one location to another. /// /// A pointer to the starting address of the move destination. /// A pointer to the starting address of the block of memory to be moved. /// The size of the block of memory to move, in bytes. public static unsafe void MoveMemory(void* dst, void* src, long size) { MoveMemory(dst, src, checked((uint)size)); } /// /// Moves a block of memory from one location to another. /// /// A pointer to the starting address of the move destination. /// A pointer to the starting address of the block of memory to be moved. /// The size of the block of memory to move, in bytes. public static unsafe void MoveMemory(IntPtr dst, IntPtr src, uint size) { MoveMemory(dst.ToPointer(), src.ToPointer(), size); } /// /// Moves a block of memory from one location to another. /// /// A pointer to the starting address of the move destination. /// A pointer to the starting address of the block of memory to be moved. /// The size of the block of memory to move, in bytes. public static unsafe void MoveMemory(IntPtr dst, IntPtr src, long size) { MoveMemory(dst.ToPointer(), src.ToPointer(), checked((uint)size)); } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(byte* dest, byte* src, int len) { if (len >= 0x10) { do { *((int*)dest) = *((int*)src); *((int*)(dest + 4)) = *((int*)(src + 4)); *((int*)(dest + 8)) = *((int*)(src + 8)); *((int*)(dest + 12)) = *((int*)(src + 12)); dest += 0x10; src += 0x10; } while ((len -= 0x10) >= 0x10); } if (len > 0) { if ((len & 8) != 0) { *((int*)dest) = *((int*)src); *((int*)(dest + 4)) = *((int*)(src + 4)); dest += 8; src += 8; } if ((len & 4) != 0) { *((int*)dest) = *((int*)src); dest += 4; src += 4; } if ((len & 2) != 0) { *((short*)dest) = *((short*)src); dest += 2; src += 2; } if ((len & 1) != 0) { *dest = *src; } } } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(byte* dest, byte* src, long len) { CopyMemory(dest, src, checked((int)len)); } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(void* dest, void* src, long len) { CopyMemory((byte*)dest, (byte*)src, checked((int)len)); } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(void* dest, void* src, int len) { CopyMemory((byte*)dest, (byte*)src, len); } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(IntPtr dest, IntPtr src, int len) { CopyMemory((byte*)dest, (byte*)src, len); } /// /// Copies a block of memory from one location to another. /// /// A pointer to the starting address of the copied block's destination. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. /// /// CopyMemory runs faster than . /// However, if both blocks overlap the result is undefined. /// public static unsafe void CopyMemory(IntPtr dest, IntPtr src, long len) { CopyMemory((byte*)dest, (byte*)src, checked((int)len)); } /// /// Copies a block of memory into an array. /// /// An array used as the destination of the copy process. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(Array dest, void* src, int len) { GCHandle handle = GCHandle.Alloc(dest, GCHandleType.Pinned); try { CopyMemory((byte*)handle.AddrOfPinnedObject(), (byte*)src, len); } finally { handle.Free(); } } /// /// Copies a block of memory into an array. /// /// An array used as the destination of the copy process. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(Array dest, void* src, long len) { CopyMemory(dest, (byte*)src, checked((int)len)); } /// /// Copies a block of memory into an array. /// /// An array used as the destination of the copy process. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(Array dest, IntPtr src, int len) { CopyMemory(dest, (byte*)src, len); } /// /// Copies a block of memory into an array. /// /// An array used as the destination of the copy process. /// A pointer to the starting address of the block of memory to copy. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(Array dest, IntPtr src, long len) { CopyMemory(dest, (byte*)src, checked((int)len)); } /// /// Copies the content of an array to a memory location. /// /// A pointer to the starting address of the copied block's destination. /// An array used as the source of the copy process. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(void* dest, Array src, int len) { GCHandle handle = GCHandle.Alloc(src, GCHandleType.Pinned); try { CopyMemory((byte*)dest, (byte*)handle.AddrOfPinnedObject(), len); } finally { handle.Free(); } } /// /// Copies the content of an array to a memory location. /// /// A pointer to the starting address of the copied block's destination. /// An array used as the source of the copy process. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(void* dest, Array src, long len) { CopyMemory((byte*)dest, src, checked((int)len)); } /// /// Copies the content of an array to a memory location. /// /// A pointer to the starting address of the copied block's destination. /// An array used as the source of the copy process. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(IntPtr dest, Array src, int len) { CopyMemory((byte*)dest, src, len); } /// /// Copies the content of an array to a memory location. /// /// A pointer to the starting address of the copied block's destination. /// An array used as the source of the copy process. /// The size of the block of memory to copy, in bytes. public static unsafe void CopyMemory(IntPtr dest, Array src, long len) { CopyMemory((byte*)dest, src, checked((int)len)); } /// /// Copies the content of one array into another array. /// /// An array used as the destination of the copy process. /// An array used as the source of the copy process. /// The size of the content to copy, in bytes. public static unsafe void CopyMemory(Array dest, Array src, int len) { GCHandle dHandle = GCHandle.Alloc(dest, GCHandleType.Pinned); try { GCHandle sHandle = GCHandle.Alloc(src, GCHandleType.Pinned); try { CopyMemory((byte*)dHandle.AddrOfPinnedObject(), (byte*)sHandle.AddrOfPinnedObject(), len); } finally { sHandle.Free(); } } finally { dHandle.Free(); } } /// /// Copies the content of one array into another array. /// /// An array used as the destination of the copy process. /// An array used as the source of the copy process. /// The size of the content to copy, in bytes. public static unsafe void CopyMemory(Array dest, Array src, long len) { CopyMemory(dest, src, checked((int)len)); } internal static string ColorToString(Color color) { return string.Format( System.Globalization.CultureInfo.CurrentCulture, "{{Name={0}, ARGB=({1}, {2}, {3}, {4})}}", new object[] { color.Name, color.A, color.R, color.G, color.B }); } internal static void Resize(ref string str, int length) { if ((str != null) && (length >= 0) && (str.Length != length)) { char[] chars = str.ToCharArray(); Array.Resize(ref chars, length); str = new string(chars); } } internal static void Resize(ref string str, int min, int max) { if ((str != null) && (min >= 0) && (max >= 0) && (min <= max)) { if (str.Length < min) { char[] chars = str.ToCharArray(); Array.Resize(ref chars, min); str = new string(chars); } else if (str.Length > max) { char[] chars = str.ToCharArray(); Array.Resize(ref chars, max); str = new string(chars); } } } internal static void Resize(ref T[] array, int length) { if ((array != null) && (length >= 0) && (array.Length != length)) { Array.Resize(ref array, length); } } internal static void Resize(ref T[] array, int min, int max) { if ((array != null) && (min >= 0) && (max >= 0) && (min <= max)) { if (array.Length < min) { Array.Resize(ref array, min); } else if (array.Length > max) { Array.Resize(ref array, max); } } } internal static bool CheckColorType(FREE_IMAGE_TYPE imageType, T color) { Type type = typeof(T); bool result; switch (imageType) { case FREE_IMAGE_TYPE.FIT_BITMAP: result = (type == typeof(RGBQUAD)); break; case FREE_IMAGE_TYPE.FIT_COMPLEX: result = (type == typeof(FICOMPLEX)); break; case FREE_IMAGE_TYPE.FIT_DOUBLE: result = (type == typeof(double)); break; case FREE_IMAGE_TYPE.FIT_FLOAT: result = (type == typeof(float)); break; case FREE_IMAGE_TYPE.FIT_INT16: result = (type == typeof(Int16)); break; case FREE_IMAGE_TYPE.FIT_INT32: result = (type == typeof(Int32)); break; case FREE_IMAGE_TYPE.FIT_RGB16: result = (type == typeof(FIRGB16)); break; case FREE_IMAGE_TYPE.FIT_RGBA16: result = (type == typeof(FIRGBA16)); break; case FREE_IMAGE_TYPE.FIT_RGBAF: result = (type == typeof(FIRGBAF)); break; case FREE_IMAGE_TYPE.FIT_RGBF: result = (type == typeof(FIRGBF)); break; case FREE_IMAGE_TYPE.FIT_UINT16: result = (type == typeof(UInt16)); break; case FREE_IMAGE_TYPE.FIT_UINT32: result = (type == typeof(UInt32)); break; default: result = false; break; } return result; } #endregion #region Dll-Imports /// /// Retrieves a handle to a display device context (DC) for the client area of a specified window /// or for the entire screen. You can use the returned handle in subsequent GDI functions to draw in the DC. /// /// Handle to the window whose DC is to be retrieved. /// If this value is IntPtr.Zero, GetDC retrieves the DC for the entire screen. /// If the function succeeds, the return value is a handle to the DC for the specified window's client area. /// If the function fails, the return value is NULL. [DllImport("user32.dll")] private static extern IntPtr GetDC(IntPtr hWnd); /// /// Releases a device context (DC), freeing it for use by other applications. /// The effect of the ReleaseDC function depends on the type of DC. It frees only common and window DCs. /// It has no effect on class or private DCs. /// /// Handle to the window whose DC is to be released. /// Handle to the DC to be released. /// Returns true on success, false on failure. [DllImport("user32.dll")] private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); /// /// Creates a DIB that applications can write to directly. /// The function gives you a pointer to the location of the bitmap bit values. /// You can supply a handle to a file-mapping object that the function will use to create the bitmap, /// or you can let the system allocate the memory for the bitmap. /// /// Handle to a device context. /// Pointer to a BITMAPINFO structure that specifies various attributes of the DIB, /// including the bitmap dimensions and colors. /// Specifies the type of data contained in the bmiColors array member of the BITMAPINFO structure /// pointed to by pbmi (either logical palette indexes or literal RGB values). /// Pointer to a variable that receives a pointer to the location of the DIB bit values. /// Handle to a file-mapping object that the function will use to create the DIB. /// This parameter can be NULL. /// Specifies the offset from the beginning of the file-mapping object referenced by hSection /// where storage for the bitmap bit values is to begin. This value is ignored if hSection is NULL. /// If the function succeeds, the return value is a handle to the newly created DIB, /// and *ppvBits points to the bitmap bit values. If the function fails, the return value is NULL, and *ppvBits is NULL. [DllImport("gdi32.dll")] private static extern IntPtr CreateDIBSection( IntPtr hdc, [In] IntPtr pbmi, uint iUsage, out IntPtr ppvBits, IntPtr hSection, uint dwOffset); /// /// Deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. /// After the object is deleted, the specified handle is no longer valid. /// /// Handle to a logical pen, brush, font, bitmap, region, or palette. /// Returns true on success, false on failure. [DllImport("gdi32.dll")] private static extern bool DeleteObject(IntPtr hObject); /// /// Creates a compatible bitmap (DDB) from a DIB and, optionally, sets the bitmap bits. /// /// Handle to a device context. /// Pointer to a bitmap information header structure. /// Specifies how the system initializes the bitmap bits - (use 4). /// Pointer to an array of bytes containing the initial bitmap data. /// Pointer to a BITMAPINFO structure that describes the dimensions /// and color format of the array pointed to by the lpbInit parameter. /// Specifies whether the bmiColors member of the BITMAPINFO structure /// was initialized - (use 0). /// Handle to a DIB or null on failure. [DllImport("gdi32.dll")] private static extern IntPtr CreateDIBitmap( IntPtr hdc, IntPtr lpbmih, uint fdwInit, IntPtr lpbInit, IntPtr lpbmi, uint fuUsage); /// /// Retrieves information for the specified graphics object. /// /// Handle to the graphics object of interest. /// Specifies the number of bytes of information to /// be written to the buffer. /// Pointer to a buffer that receives the information /// about the specified graphics object. /// 0 on failure. [DllImport("gdi32.dll")] private static extern int GetObject(IntPtr hgdiobj, int cbBuffer, IntPtr lpvObject); /// /// Retrieves the bits of the specified compatible bitmap and copies them into a buffer /// as a DIB using the specified format. /// /// Handle to the device context. /// Handle to the bitmap. This must be a compatible bitmap (DDB). /// Specifies the first scan line to retrieve. /// Specifies the number of scan lines to retrieve. /// Pointer to a buffer to receive the bitmap data. /// Pointer to a BITMAPINFO structure that specifies the desired /// format for the DIB data. /// Specifies the format of the bmiColors member of the /// BITMAPINFO structure - (use 0). /// 0 on failure. [DllImport("gdi32.dll")] private static extern unsafe int GetDIBits( IntPtr hdc, IntPtr hbmp, uint uStartScan, uint cScanLines, IntPtr lpvBits, IntPtr lpbmi, uint uUsage); /// /// Moves a block of memory from one location to another. /// /// Pointer to the starting address of the move destination. /// Pointer to the starting address of the block of memory to be moved. /// Size of the block of memory to move, in bytes. [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)] public static unsafe extern void MoveMemory(void* dst, void* src, uint size); /// /// The RtlCompareMemory routine compares blocks of memory /// and returns the number of bytes that are equivalent. /// /// A pointer to a block of memory to compare. /// A pointer to a block of memory to compare. /// Specifies the number of bytes to be compared. /// RtlCompareMemory returns the number of bytes that compare as equal. /// If all bytes compare as equal, the input Length is returned. [DllImport("ntdll.dll", EntryPoint = "RtlCompareMemory", SetLastError = false)] internal static unsafe extern uint RtlCompareMemory(void* buf1, void* buf2, uint count); #endregion } }