diff --git a/build/Stride.sln b/build/Stride.sln
index c7060e2b2c..7633b6a11a 100644
--- a/build/Stride.sln
+++ b/build/Stride.sln
@@ -338,6 +338,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.Importer.3D", "..\so
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stride.BepuPhysics.Tests", "..\sources\engine\Stride.BepuPhysics\Stride.BepuPhysics.Tests\Stride.BepuPhysics.Tests.csproj", "{7B70C783-4085-4702-B3C6-6570FD85CB8F}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Stride.FreeImage", "..\sources\tools\Stride.FreeImage\Stride.FreeImage.csproj", "{75CAB5A3-3494-49E6-AB91-91C329160A17}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1523,6 +1525,18 @@ Global
{7B70C783-4085-4702-B3C6-6570FD85CB8F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{7B70C783-4085-4702-B3C6-6570FD85CB8F}.Release|Win32.ActiveCfg = Release|Any CPU
{7B70C783-4085-4702-B3C6-6570FD85CB8F}.Release|Win32.Build.0 = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Debug|Win32.Build.0 = Debug|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Any CPU.Build.0 = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Win32.ActiveCfg = Release|Any CPU
+ {75CAB5A3-3494-49E6-AB91-91C329160A17}.Release|Win32.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1651,6 +1665,7 @@ Global
{7715D094-DF59-4D91-BC9A-9A5118039ECB} = {DE048114-9AE4-467E-A879-188DC0D88A59}
{66EFFDE4-24F0-4E57-9618-0F5577E20A1E} = {6F473FA6-4F8B-4FBA-AE33-EE5AF997D50C}
{7B70C783-4085-4702-B3C6-6570FD85CB8F} = {DE048114-9AE4-467E-A879-188DC0D88A59}
+ {75CAB5A3-3494-49E6-AB91-91C329160A17} = {1AE1AC60-5D2F-4CA7-AE20-888F44551185}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FF877973-604D-4EA7-B5F5-A129961F9EF2}
diff --git a/sources/tools/Stride.FreeImage/Classes/FreeImageBitmap.cs b/sources/tools/Stride.FreeImage/Classes/FreeImageBitmap.cs
new file mode 100644
index 0000000000..ebd383df46
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/FreeImageBitmap.cs
@@ -0,0 +1,4045 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.12 $
+// $Date: 2011/12/22 14:54:22 $
+// $Id: FreeImageBitmap.cs,v 1.12 2011/12/22 14:54:22 drolon Exp $
+// ==========================================================
+
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Collections;
+using System.Collections.Generic;
+using FreeImageAPI.Metadata;
+using System.Diagnostics;
+using System.Drawing.Imaging;
+using System.Drawing;
+
+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 synchronize 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.
+ protected internal 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.
+ ///
+ /// 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 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 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");
+ }
+
+ if (!FreeImage.GetFormatParameters(format, out var type, out var bpp, out var redMask, out var greenMask, out var 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");
+ }
+
+ bool topDown = (stride > 0);
+ stride = (stride > 0) ? stride : (stride * -1);
+
+ if (!FreeImage.GetFormatParameters(format, out var type, out var bpp, out var redMask, out var greenMask, out var 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");
+ }
+
+ bool topDown = (stride > 0);
+ stride = (stride > 0) ? stride : (stride * -1);
+
+ if (!FreeImage.GetFormatParameters(format, out var type, out var bpp, out var redMask, out var greenMask, out var 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");
+ }
+
+ bool topDown = (stride > 0);
+ stride = (stride > 0) ? stride : (stride * -1);
+
+ if (!FreeImage.GetTypeParameters(type, bpp, out var redMask, out var greenMask, out var 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");
+ }
+
+ bool topDown = (stride > 0);
+ stride = (stride > 0) ? stride : (stride * -1);
+
+ if (!FreeImage.GetTypeParameters(type, bpp, out var redMask, out var greenMask, out var 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 is { 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
+
+ ///
+ /// 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 (ReferenceEquals(left, right))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(left, null) || ReferenceEquals(right, null))
+ {
+ return false;
+ }
+
+ 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.");
+ }
+
+ FreeImage.GetBackgroundColor(dib, out var 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 = [];
+ 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 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.
+ ///
+ /// , in the specified unit.
+ public RectangleF GetBounds()
+ {
+ EnsureNotDisposed();
+ return new RectangleF(
+ 0f,
+ 0f,
+ FreeImage.GetWidth(dib),
+ 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;
+ }
+
+ ///
+ /// 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)
+ /// {
+ /// Log.Info(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)
+ /// {
+ /// Log.Info(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();
+ }
+
+ ///
+ /// 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 is 16 or 24 or 32)
+ {
+ if (!FreeImage.GetPixelColor(dib, (uint)x, (uint)y, out var rgbq))
+ {
+ throw new Exception("FreeImage.GetPixelColor() failed");
+ }
+ return rgbq.Color;
+ }
+
+ if (ColorDepth is 1 or 4 or 8)
+ {
+ if (!FreeImage.GetPixelIndex(dib, (uint)x, (uint)y, out var 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 is 16 or 24 or 32)
+ {
+ RGBQUAD rgbq = color;
+ if (!FreeImage.SetPixelColor(dib, (uint)x, (uint)y, ref rgbq))
+ {
+ throw new Exception("FreeImage.SetPixelColor() failed");
+ }
+ return;
+ }
+
+ if (ColorDepth is 1 or 4 or 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);
+ }
+
+ ///
+ /// 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) && 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.
+ ///
+ ///
+ ///
+ ///
+ 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 (pixfmt & PixelFormat.Alpha) != 0;
+ }
+
+ ///
+ /// 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 (pixfmt & PixelFormat.Canonical) != 0;
+ }
+
+ ///
+ /// 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 (pixfmt & PixelFormat.Extended) != 0;
+ }
+
+ ///
+ /// 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 ((int)pixfmt >> 8) & 0xFF;
+ }
+
+ ///
+ /// 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 (!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 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
+}
diff --git a/sources/tools/Stride.FreeImage/Classes/FreeImageEngine.cs b/sources/tools/Stride.FreeImage/Classes/FreeImageEngine.cs
new file mode 100644
index 0000000000..f43c0793f9
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/FreeImageEngine.cs
@@ -0,0 +1,99 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+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
+ // 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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/FreeImagePlugin.cs b/sources/tools/Stride.FreeImage/Classes/FreeImagePlugin.cs
new file mode 100644
index 0000000000..96d30120ba
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/FreeImagePlugin.cs
@@ -0,0 +1,194 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Diagnostics;
+
+namespace FreeImageAPI.Plugins;
+
+///
+/// Class representing a FreeImage format.
+///
+public sealed class FreeImagePlugin
+{
+ ///
+ /// Initializes a new instance of this class.
+ ///
+ /// The FreeImage format to wrap.
+ internal FreeImagePlugin(FREE_IMAGE_FORMAT fif)
+ {
+ this.FIFormat = fif;
+ }
+
+ ///
+ /// Gets the format of this instance.
+ ///
+ public FREE_IMAGE_FORMAT FIFormat { get; }
+
+ ///
+ /// Gets or sets whether this plugin is enabled.
+ ///
+ public bool Enabled
+ {
+ get
+ {
+ return (FreeImage.IsPluginEnabled(FIFormat) == 1);
+ }
+ set
+ {
+ FreeImage.SetPluginEnabled(FIFormat, value);
+ }
+ }
+
+ ///
+ /// Gets a string describing the format.
+ ///
+ public string Format
+ {
+ get
+ {
+ return FreeImage.GetFormatFromFIF(FIFormat);
+ }
+ }
+
+ ///
+ /// 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(FIFormat);
+ }
+ }
+
+ ///
+ /// Gets a descriptive string that describes the bitmap formats
+ /// this plugin can read and/or write.
+ ///
+ public string Description
+ {
+ get
+ {
+ return FreeImage.GetFIFDescription(FIFormat);
+ }
+ }
+
+ ///
+ /// 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(FIFormat);
+ }
+ }
+
+ ///
+ /// Gets whether this plugin can load bitmaps.
+ ///
+ public bool SupportsReading
+ {
+ get
+ {
+ return FreeImage.FIFSupportsReading(FIFormat);
+ }
+ }
+
+ ///
+ /// Gets whether this plugin can save bitmaps.
+ ///
+ public bool SupportsWriting
+ {
+ get
+ {
+ return FreeImage.FIFSupportsWriting(FIFormat);
+ }
+ }
+
+ ///
+ /// 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(FIFormat, 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(FIFormat, bpp);
+ }
+
+ ///
+ /// Gets whether this plugin can load or save an ICC profile.
+ ///
+ public bool SupportsICCProfiles
+ {
+ get
+ {
+ return FreeImage.FIFSupportsICCProfiles(FIFormat);
+ }
+ }
+
+ ///
+ /// 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(FIFormat, 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(FIFormat, 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(FIFormat, 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(FIFormat, 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;
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/FreeImageStreamIO.cs b/sources/tools/Stride.FreeImage/Classes/FreeImageStreamIO.cs
new file mode 100644
index 0000000000..9262aa0b3d
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/FreeImageStreamIO.cs
@@ -0,0 +1,164 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.5 $
+// $Date: 2009/09/15 11:47:46 $
+// $Id: FreeImageStreamIO.cs,v 1.5 2009/09/15 11:47:46 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+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 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)
+ {
+ if (handle.GetObject() is not Stream stream)
+ {
+ return 1;
+ }
+ stream.Seek(offset, origin);
+ return 0;
+ }
+
+ ///
+ /// Returns the streams current position
+ ///
+ static int streamTell(fi_handle handle)
+ {
+ if (handle.GetObject() is not Stream stream)
+ {
+ return -1;
+ }
+ return (int)stream.Position;
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/GifInformation.cs b/sources/tools/Stride.FreeImage/Classes/GifInformation.cs
new file mode 100644
index 0000000000..2ce39593e6
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/GifInformation.cs
@@ -0,0 +1,130 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Diagnostics;
+using System.Drawing;
+
+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.
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/ImageMetadata.cs b/sources/tools/Stride.FreeImage/Classes/ImageMetadata.cs
new file mode 100644
index 0000000000..7c12469cd3
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/ImageMetadata.cs
@@ -0,0 +1,267 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.7 $
+// $Date: 2009/02/27 16:34:59 $
+// $Id: ImageMetadata.cs,v 1.7 2009/02/27 16:34:59 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Diagnostics;
+
+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;
+
+ ///
+ /// 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;
+ }
+
+ 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;
+ }
+
+ return data.Count;
+ }
+ }
+
+ ///
+ /// Gets or sets whether empty
+ /// MetadataModels are hidden.
+ ///
+ public bool HideEmptyModels { get; set; }
+
+ ///
+ /// 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();
+ }
+
+ 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);
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/LocalPlugin.cs b/sources/tools/Stride.FreeImage/Classes/LocalPlugin.cs
new file mode 100644
index 0000000000..e995fcefe9
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/LocalPlugin.cs
@@ -0,0 +1,444 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.9 $
+// $Date: 2009/09/15 11:47:46 $
+// $Id: LocalPlugin.cs,v 1.9 2009/09/15 11:47:46 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using FreeImageAPI.IO;
+using System.Diagnostics;
+
+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;
+
+ ///
+ /// 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);
+ }
+
+ throw new ObjectDisposedException("plugin not registered");
+ }
+ set
+ {
+ if (Registered)
+ {
+ FreeImage.SetPluginEnabled(Format, value);
+ }
+ else
+ {
+ throw new ObjectDisposedException("plugin not registered");
+ }
+ }
+ }
+
+ ///
+ /// When true the plugin was registered successfully else false.
+ /// Gets if the plugin was registered successfully.
+ ///
+ public bool Registered { get; }
+
+ ///
+ /// The format id assiged to the plugin.
+ /// Gets the FreeImage assigned to this plugin.
+ ///
+ public FREE_IMAGE_FORMAT Format { get; protected set; } = FREE_IMAGE_FORMAT.FIF_UNKNOWN;
+
+ ///
+ /// 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);
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/MemoryArray.cs b/sources/tools/Stride.FreeImage/Classes/MemoryArray.cs
new file mode 100644
index 0000000000..faf8ba9604
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/MemoryArray.cs
@@ -0,0 +1,743 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+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 = 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 been pinned, so that its address
+ // can be safely requested and stored for the whole lifetime
+ // of the instance.
+ 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 (ReferenceEquals(left, right))
+ {
+ return true;
+ }
+ if (ReferenceEquals(right, null) ||
+ 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);
+ }
+
+ if (isFourBit)
+ {
+ return (T)(object)(FI4BIT)(((index % 2) == 0) ? (baseAddress[index / 2] >> 4) : (baseAddress[index / 2] & 0x0F));
+ }
+
+ Unsafe.CopyBlockUnaligned(ptr, baseAddress + (index * size), (uint) 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;
+ Unsafe.CopyBlockUnaligned(baseAddress + (index * size), ptr, (uint) 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
+ {
+ ref byte dst = ref Unsafe.As(ref data[0]);
+ ref byte src = ref Unsafe.AsRef(baseAddress + (size * index));
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) (size * length));
+ }
+ 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
+ {
+ ref byte dst = ref Unsafe.AsRef(baseAddress + (index * size));
+ ref byte src = ref Unsafe.As(ref values[0]);
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) (size * length));
+ }
+ }
+
+ ///
+ /// 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.
+ ///
+ 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
+ {
+ ref byte dst = ref Unsafe.As(ref array[destinationIndex]);
+ ref byte src = ref Unsafe.AsRef(baseAddress + (size * sourceIndex));
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) (size * length));
+ }
+ }
+
+ ///
+ /// 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.
+ ///
+ 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
+ {
+ ref byte dst = ref Unsafe.AsRef(baseAddress + (size * destinationIndex));
+ ref byte src = ref Unsafe.As(ref array[sourceIndex]);
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) (size * length));
+ }
+ }
+
+ ///
+ /// 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];
+ }
+
+ ref byte dst = ref result[0];
+ ref byte src = ref Unsafe.AsRef(baseAddress);
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) 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", $"{nameof(Data)} can not be null");
+ }
+ 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;
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/MetadataModel.cs b/sources/tools/Stride.FreeImage/Classes/MetadataModel.cs
new file mode 100644
index 0000000000..75080aa06a
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/MetadataModel.cs
@@ -0,0 +1,908 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.8 $
+// $Date: 2009/02/27 16:34:31 $
+// $Id: MetadataModel.cs,v 1.8 2009/02/27 16:34:31 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Diagnostics;
+
+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");
+ }
+
+ return FreeImage.GetMetadata(Model, dib, key, out MetadataTag 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");
+ }
+
+ return FreeImage.GetMetadata(Model, dib, key, out MetadataTag _);
+ }
+
+ ///
+ /// Returns a list of all metadata tags this instance represents.
+ ///
+ public List List
+ {
+ get
+ {
+ List list = new List((int)FreeImage.GetMetadataCount(Model, dib));
+ FIMETADATA mdHandle = FreeImage.FindFirstMetadata(Model, dib, out MetadataTag 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");
+ }
+
+ int count = 0;
+ FIMETADATA mdHandle = FreeImage.FindFirstMetadata(Model, dib, out MetadataTag 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)
+ {
+ if ((tag.Value is T[] value) && (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[] array)
+ {
+ result = new uint[array.Length];
+ for (int i = 0, j = array.Length; i < j; i++)
+ {
+ result[i] = array[i];
+ }
+ }
+ else if (value is uint[] uints)
+ {
+ result = uints;
+ }
+ }
+ }
+ 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?[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;
+ return s[0] switch
+ {
+ 'T' => DirectionReference.TrueDirection,
+ 'M' => DirectionReference.MagneticDirection,
+ _ => 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)
+ {
+ return type.Value switch
+ {
+ DirectionReference.TrueDirection => "T",
+ DirectionReference.MagneticDirection => "M",
+ _ => "\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;
+ return s[0] switch
+ {
+ 'K' => VelocityUnit.Kilometers,
+ 'M' => VelocityUnit.Miles,
+ 'N' => VelocityUnit.Knots,
+ _ => 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)
+ {
+ return type.Value switch
+ {
+ VelocityUnit.Kilometers => "K",
+ VelocityUnit.Miles => "M",
+ VelocityUnit.Knots => "N",
+ _ => "\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;
+ return s[0] switch
+ {
+ 'E' => LongitudeType.East,
+ 'W' => LongitudeType.West,
+ _ => 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)
+ {
+ return type.Value switch
+ {
+ LongitudeType.East => "E",
+ LongitudeType.West => "W",
+ _ => "\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;
+ return s[0] switch
+ {
+ 'N' => LatitudeType.North,
+ 'S' => LatitudeType.South,
+ _ => 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)
+ {
+ return type.Value switch
+ {
+ LatitudeType.North => "N",
+ LatitudeType.South => "S",
+ _ => "\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", StringComparison.Ordinal))
+ return InteroperabilityMode.R98;
+ if (s.StartsWith("THM", StringComparison.Ordinal))
+ 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)
+ {
+ return type.Value switch
+ {
+ InteroperabilityMode.R98 => "R98",
+ InteroperabilityMode.THM => "THM",
+ _ => "\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();
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/MetadataModels.cs b/sources/tools/Stride.FreeImage/Classes/MetadataModels.cs
new file mode 100644
index 0000000000..9fa60da26f
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/MetadataModels.cs
@@ -0,0 +1,6684 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.6 $
+// $Date: 2009/09/15 11:49:24 $
+// $Id: MetadataModels.cs,v 1.6 2009/09/15 11:49:24 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.Xml;
+using System.IO;
+using System.Text;
+
+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?.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 = 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)
+ {
+ return flag.Value switch
+ {
+ 0 => AltitudeType.AboveSeaLevel,
+ 1 => AltitudeType.BelowSeaLevel,
+ _ => AltitudeType.Undefined
+ };
+ }
+ return null;
+ }
+ set
+ {
+ byte? val = null;
+ if (value.HasValue)
+ {
+ val = value.Value switch
+ {
+ AltitudeType.AboveSeaLevel => 0,
+ AltitudeType.BelowSeaLevel => 1,
+ _ => 2
+ };
+ }
+ 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;
+ }
+
+ 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;
+ }
+
+ date ??= DateTime.MinValue;
+ 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
+/// .
+///
+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(['\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;
+ }
+
+ MemoryStream stream = new MemoryStream();
+ StreamWriter writer = new StreamWriter(stream);
+ writer.Write(xmlString);
+ return XmlReader.Create(stream);
+ }
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/MetadataTag.cs b/sources/tools/Stride.FreeImage/Classes/MetadataTag.cs
new file mode 100644
index 0000000000..dc716001b4
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/MetadataTag.cs
@@ -0,0 +1,760 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.9 $
+// $Date: 2009/02/27 16:35:12 $
+// $Id: MetadataTag.cs,v 1.9 2009/02/27 16:35:12 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+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);
+
+ ref byte dst = ref MemoryMarshal.GetArrayDataReference(array);
+ ref byte src = ref Unsafe.AsRef((void*) FreeImage.GetTagValue(tag));
+ Unsafe.CopyBlockUnaligned(ref dst, ref 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.TryGetValue(type, out var v))
+ {
+ throw new NotSupportedException("The type of value is not supported");
+ }
+ return SetValue(value, v);
+ }
+
+ ///
+ /// 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 not 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)
+ {
+ if (value is not string tempValue)
+ {
+ 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
+ {
+ if (value is not Array array)
+ {
+ throw new ArgumentException(nameof(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];
+
+ ref byte dst = ref data[0];
+ ref byte src = ref MemoryMarshal.GetArrayDataReference(array);
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, 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 PropertyItem GetPropertyItem()
+ {
+ PropertyItem item = FreeImage.CreatePropertyItem();
+ item.Id = ID;
+ item.Len = (int)Length;
+ item.Type = (short)Type;
+ item.Value = new byte[item.Len];
+
+ ref byte dst = ref item.Value[0];
+ ref byte src = ref Unsafe.AsRef((void*) FreeImage.GetTagValue(tag));
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, Length);
+
+ 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);
+
+ return string.IsNullOrEmpty(fiString) ? tag.ToString() : 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.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/Palette.cs b/sources/tools/Stride.FreeImage/Classes/Palette.cs
new file mode 100644
index 0000000000..a59ab6e1cc
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/Palette.cs
@@ -0,0 +1,416 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Drawing;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using FreeImageAPI.Metadata;
+
+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 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 = red / splitSize;
+ double g = green / splitSize;
+ double 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);
+
+ ref byte dst = ref Unsafe.AsRef(baseAddress);
+ ref byte src = ref data[0];
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, (uint) 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);
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/PluginRepository.cs b/sources/tools/Stride.FreeImage/Classes/PluginRepository.cs
new file mode 100644
index 0000000000..7a164479f0
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/PluginRepository.cs
@@ -0,0 +1,450 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Diagnostics;
+
+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.ToLowerInvariant();
+
+ foreach (FreeImagePlugin plugin in plugins)
+ {
+ if (plugin.Format.ToLowerInvariant().Contains(expression) ||
+ plugin.RegExpr.ToLowerInvariant().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]; } }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/Scanline.cs b/sources/tools/Stride.FreeImage/Classes/Scanline.cs
new file mode 100644
index 0000000000..2144155cd5
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/Scanline.cs
@@ -0,0 +1,51 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+
+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");
+ }
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Classes/StreamWrapper.cs b/sources/tools/Stride.FreeImage/Classes/StreamWrapper.cs
new file mode 100644
index 0000000000..0031cae196
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Classes/StreamWrapper.cs
@@ -0,0 +1,302 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.6 $
+// $Date: 2009/02/23 12:28:56 $
+// $Id: StreamWrapper.cs,v 1.6 2009/02/23 12:28:56 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.IO;
+using System.Diagnostics;
+
+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;
+
+ ///
+ /// 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)
+ {
+ memoryStream?.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Indicates if the wrapped stream is disposed or not
+ ///
+ public bool Disposed { get; private set; }
+
+ private void checkDisposed()
+ {
+ if (Disposed) throw new ObjectDisposedException("StreamWrapper");
+ }
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Delegates.cs b/sources/tools/Stride.FreeImage/Delegates.cs
similarity index 100%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Delegates.cs
rename to sources/tools/Stride.FreeImage/Delegates.cs
diff --git a/sources/tools/Stride.FreeImage/Enumerations/DisposalMethodType.cs b/sources/tools/Stride.FreeImage/Enumerations/DisposalMethodType.cs
new file mode 100644
index 0000000000..ec6682b135
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/DisposalMethodType.cs
@@ -0,0 +1,34 @@
+// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
+// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+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,
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs
similarity index 59%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs
index fbf2d3943c..4d3487fa89 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_CHANNEL.cs
@@ -33,52 +33,51 @@
// $Id: FREE_IMAGE_COLOR_CHANNEL.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Color channels. Constants used in color manipulation routines.
+///
+public enum FREE_IMAGE_COLOR_CHANNEL
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_DEPTH.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_DEPTH.cs
new file mode 100644
index 0000000000..bfeae757e3
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_DEPTH.cs
@@ -0,0 +1,104 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.1 $
+// $Date: 2007/11/28 15:33:39 $
+// $Id: FREE_IMAGE_COLOR_DEPTH.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
+// ==========================================================
+
+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
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs
similarity index 63%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs
index 07f357e739..46470d05a5 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_OPTIONS.cs
@@ -33,36 +33,35 @@
// $Id: FREE_IMAGE_COLOR_OPTIONS.cs,v 1.1 2009/09/15 11:44:24 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Constants used in color filling routines.
+///
+public enum FREE_IMAGE_COLOR_OPTIONS
{
- ///
- /// 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,
- }
+ ///
+ /// 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,
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_TYPE.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_TYPE.cs
similarity index 70%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_TYPE.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_TYPE.cs
index 3fbb5aaf7d..87a2f11aac 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COLOR_TYPE.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COLOR_TYPE.cs
@@ -33,36 +33,35 @@
// $Id: FREE_IMAGE_COLOR_TYPE.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Image color types used in FreeImage.
+///
+public enum FREE_IMAGE_COLOR_TYPE
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs
similarity index 72%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs
index 047b0038e8..ca8c50696a 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_COMPARE_FLAGS.cs
@@ -33,33 +33,32 @@
// $Id: FREE_IMAGE_COMPARE_FLAGS.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// List of combinable compare modes.
+///
+[System.Flags]
+public enum FREE_IMAGE_COMPARE_FLAGS
{
- ///
- /// 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)
- }
+ ///
+ /// 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)
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_DITHER.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_DITHER.cs
similarity index 59%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_DITHER.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_DITHER.cs
index 5cf364cda6..5e60d08af3 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_DITHER.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_DITHER.cs
@@ -33,41 +33,40 @@
// $Id: FREE_IMAGE_DITHER.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Dithering algorithms.
+/// Constants used in FreeImage_Dither.
+///
+public enum FREE_IMAGE_DITHER
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_FILTER.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FILTER.cs
similarity index 66%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_FILTER.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FILTER.cs
index 6b283b12ad..13f578ddac 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_FILTER.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FILTER.cs
@@ -33,36 +33,35 @@
// $Id: FREE_IMAGE_FILTER.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Upsampling / downsampling filters. Constants used in FreeImage_Rescale.
+///
+public enum FREE_IMAGE_FILTER
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FORMAT.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FORMAT.cs
new file mode 100644
index 0000000000..777d56229c
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_FORMAT.cs
@@ -0,0 +1,191 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.2 $
+// $Date: 2009/09/15 11:44:42 $
+// $Id: FREE_IMAGE_FORMAT.cs,v 1.2 2009/09/15 11:44:42 cklein05 Exp $
+// ==========================================================
+
+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,
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs
similarity index 61%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs
index d493f55d66..764a7a2660 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_JPEG_OPERATION.cs
@@ -33,44 +33,43 @@
// $Id: FREE_IMAGE_JPEG_OPERATION.cs,v 1.1 2007/11/28 15:33:38 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Lossless JPEG transformations constants used in FreeImage_JPEGTransform.
+///
+public enum FREE_IMAGE_JPEG_OPERATION
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_LOAD_FLAGS.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_LOAD_FLAGS.cs
new file mode 100644
index 0000000000..a7cc9d20d4
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_LOAD_FLAGS.cs
@@ -0,0 +1,114 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.2 $
+// $Date: 2009/09/15 11:45:16 $
+// $Id: FREE_IMAGE_LOAD_FLAGS.cs,v 1.2 2009/09/15 11:45:16 cklein05 Exp $
+// ==========================================================
+
+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,
+ ///
+ /// Load the image header only.
+ ///
+ FIF_LOAD_NOPIXELS = 0x8000,
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_MDMODEL.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDMODEL.cs
similarity index 55%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_MDMODEL.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDMODEL.cs
index 99907aa8ad..968205580e 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_MDMODEL.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDMODEL.cs
@@ -33,60 +33,59 @@
// $Id: FREE_IMAGE_MDMODEL.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Metadata models supported by FreeImage.
+///
+public enum FREE_IMAGE_MDMODEL
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDTYPE.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDTYPE.cs
new file mode 100644
index 0000000000..9e725bfa49
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_MDTYPE.cs
@@ -0,0 +1,104 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.1 $
+// $Date: 2007/11/28 15:33:39 $
+// $Id: FREE_IMAGE_MDTYPE.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
+// ==========================================================
+
+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
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_METADATA_COPY.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_METADATA_COPY.cs
similarity index 76%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_METADATA_COPY.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_METADATA_COPY.cs
index d487ea0ba9..417b18d1ca 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_METADATA_COPY.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_METADATA_COPY.cs
@@ -33,24 +33,23 @@
// $Id: FREE_IMAGE_METADATA_COPY.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Flags for copying data from a bitmap to another.
+///
+public enum FREE_IMAGE_METADATA_COPY
{
- ///
- /// 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
- }
+ ///
+ /// Exisiting metadata will remain unchanged.
+ ///
+ KEEP_EXISITNG = 0x0,
+ ///
+ /// Existing metadata will be cleared.
+ ///
+ CLEAR_EXISTING = 0x1,
+ ///
+ /// Existing metadata will be overwritten.
+ ///
+ REPLACE_EXISTING = 0x2
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_QUANTIZE.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_QUANTIZE.cs
similarity index 79%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_QUANTIZE.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_QUANTIZE.cs
index aa05d7f790..2c9c305825 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_QUANTIZE.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_QUANTIZE.cs
@@ -33,21 +33,20 @@
// $Id: FREE_IMAGE_QUANTIZE.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Color quantization algorithms.
+/// Constants used in FreeImage_ColorQuantize.
+///
+public enum FREE_IMAGE_QUANTIZE
{
- ///
- /// 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
- }
+ ///
+ /// Xiaolin Wu color quantization algorithm
+ ///
+ FIQ_WUQUANT = 0,
+ ///
+ /// NeuQuant neural-net quantization algorithm by Anthony Dekker
+ ///
+ FIQ_NNQUANT = 1
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_SAVE_FLAGS.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_SAVE_FLAGS.cs
new file mode 100644
index 0000000000..2f2312b098
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_SAVE_FLAGS.cs
@@ -0,0 +1,190 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.3 $
+// $Date: 2011/12/22 14:53:28 $
+// $Id: FREE_IMAGE_SAVE_FLAGS.cs,v 1.3 2011/12/22 14:53:28 drolon Exp $
+// ==========================================================
+
+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,
+ ///
+ /// On saving, compute optimal Huffman coding tables (can reduce a few percent of file size).
+ ///
+ JPEG_OPTIMIZE = 0x20000,
+ ///
+ /// save basic JPEG, without metadata or any markers.
+ ///
+ JPEG_BASELINE = 0x40000,
+ ///
+ /// 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
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TMO.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TMO.cs
similarity index 73%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TMO.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TMO.cs
index 36033e4040..423324c9de 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TMO.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TMO.cs
@@ -33,24 +33,23 @@
// $Id: FREE_IMAGE_TMO.cs,v 1.1 2007/11/28 15:33:39 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Tone mapping operators. Constants used in FreeImage_ToneMapping.
+///
+public enum FREE_IMAGE_TMO
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TYPE.cs b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TYPE.cs
similarity index 50%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TYPE.cs
rename to sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TYPE.cs
index a407bca448..9813bde565 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/FREE_IMAGE_TYPE.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/FREE_IMAGE_TYPE.cs
@@ -33,64 +33,63 @@
// $Id: FREE_IMAGE_TYPE.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Image types used in FreeImage.
+///
+public enum FREE_IMAGE_TYPE
{
- ///
- /// 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
- }
+ ///
+ /// 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
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/ICC_FLAGS.cs b/sources/tools/Stride.FreeImage/Enumerations/ICC_FLAGS.cs
similarity index 83%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/ICC_FLAGS.cs
rename to sources/tools/Stride.FreeImage/Enumerations/ICC_FLAGS.cs
index 2e1cdee373..3f875d37a6 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/ICC_FLAGS.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/ICC_FLAGS.cs
@@ -33,21 +33,20 @@
// $Id: ICC_FLAGS.cs,v 1.1 2007/11/28 15:33:38 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// Flags for ICC profiles.
+///
+[System.Flags]
+public enum ICC_FLAGS : ushort
{
- ///
- /// 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
- }
+ ///
+ /// Default value.
+ ///
+ FIICC_DEFAULT = 0x00,
+ ///
+ /// The color is CMYK.
+ ///
+ FIICC_COLOR_IS_CMYK = 0x01
}
\ No newline at end of file
diff --git a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/MD_SEARCH_FLAGS.cs b/sources/tools/Stride.FreeImage/Enumerations/MD_SEARCH_FLAGS.cs
similarity index 78%
rename from sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/MD_SEARCH_FLAGS.cs
rename to sources/tools/Stride.FreeImage/Enumerations/MD_SEARCH_FLAGS.cs
index 923f7e9ecb..7a02266048 100644
--- a/sources/tools/Stride.TextureConverter/Backend/Wrappers/FINetWrapper/Enumerations/MD_SEARCH_FLAGS.cs
+++ b/sources/tools/Stride.FreeImage/Enumerations/MD_SEARCH_FLAGS.cs
@@ -33,25 +33,24 @@
// $Id: MD_SEARCH_FLAGS.cs,v 1.1 2007/11/28 15:33:40 cklein05 Exp $
// ==========================================================
-namespace FreeImageAPI
+namespace FreeImageAPI;
+
+///
+/// List different search modes.
+///
+[System.Flags]
+public enum MD_SEARCH_FLAGS
{
- ///
- /// 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,
- }
+ ///
+ /// The key of the metadata.
+ ///
+ KEY = 0x1,
+ ///
+ /// The description of the metadata
+ ///
+ DESCRIPTION = 0x2,
+ ///
+ /// The ToString value of the metadata
+ ///
+ TOSTRING = 0x4,
}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/FreeImageStaticImports.cs b/sources/tools/Stride.FreeImage/FreeImageStaticImports.cs
new file mode 100644
index 0000000000..6b4c9c95c4
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/FreeImageStaticImports.cs
@@ -0,0 +1,2376 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.9 $
+// $Date: 2009/09/15 11:41:37 $
+// $Id: FreeImageStaticImports.cs,v 1.9 2009/09/15 11:41:37 cklein05 Exp $
+// ==========================================================
+
+using System;
+using System.Runtime.InteropServices;
+using FreeImageAPI.Plugins;
+using FreeImageAPI.IO;
+
+namespace FreeImageAPI;
+
+internal 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 extern unsafe 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.Auto, EntryPoint = "FreeImage_Load")]
+ private static extern FIBITMAP LoadNU(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);
+
+ public static FIBITMAP Load(FREE_IMAGE_FORMAT fif, string filename, FREE_IMAGE_LOAD_FLAGS flags)
+ {
+ return OperatingSystem.IsWindows() ? LoadU(fif, filename, flags) : LoadNU(fif, filename, 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.Auto, EntryPoint = "FreeImage_Save")]
+ private static extern bool SaveNU(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);
+
+ public static bool Save(FREE_IMAGE_FORMAT fif, FIBITMAP dib, string filename, FREE_IMAGE_SAVE_FLAGS flags)
+ {
+ return OperatingSystem.IsWindows() ? SaveU(fif, dib, filename, flags) : SaveNU(fif, dib, filename, 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 with a comma separated list of extensions. f.e: "pl,pl2,pl4"
+ /// A regular expression used to identify the bitmap.
+ /// The format identifier 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.Auto, EntryPoint = "FreeImage_GetFIFFromFilename")]
+ private static extern FREE_IMAGE_FORMAT GetFIFFromFilenameNU(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);
+
+ public static FREE_IMAGE_FORMAT GetFIFFromFilename(string filename)
+ {
+ return OperatingSystem.IsWindows() ? GetFIFFromFilenameU(filename) : GetFIFFromFilenameNU(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.Auto, EntryPoint = "FreeImage_GetFileType")]
+ private static extern FREE_IMAGE_FORMAT GetFileTypeNU(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);
+
+ public static FREE_IMAGE_FORMAT GetFileType(string filename, int size)
+ {
+ return OperatingSystem.IsWindows() ? GetFIFFromFilenameU(filename) : GetFIFFromFilenameNU(filename);
+ }
+
+ ///
+ /// 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
+
+ [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
+}
\ No newline at end of file
diff --git a/sources/tools/Stride.FreeImage/FreeImageWrapper.cs b/sources/tools/Stride.FreeImage/FreeImageWrapper.cs
new file mode 100644
index 0000000000..27500afd18
--- /dev/null
+++ b/sources/tools/Stride.FreeImage/FreeImageWrapper.cs
@@ -0,0 +1,4640 @@
+// ==========================================================
+// 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!
+// ==========================================================
+
+// ==========================================================
+// CVS
+// $Revision: 1.19 $
+// $Date: 2011/10/02 13:00:45 $
+// $Id: FreeImageWrapper.cs,v 1.19 2011/10/02 13:00:45 drolon Exp $
+// ==========================================================
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using FreeImageAPI.IO;
+using FreeImageAPI.Metadata;
+
+namespace FreeImageAPI;
+
+///
+/// Static class importing functions from the FreeImage library
+/// and providing additional functions.
+///
+internal 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))
+ {
+ if (attributes[0] is AssemblyFileVersionAttribute attribute)
+ {
+ 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.Major == wrapperVersion.Major) && (nativeVersion.Minor > wrapperVersion.Minor)) ||
+ ((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 = [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();
+ }
+ }
+
+ 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 (color.HasValue)
+ {
+ if (!CheckColorType(type, color.Value))
+ return FIBITMAP.Zero;
+
+ GCHandle handle = new GCHandle();
+ try
+ {
+ T[] buffer = { 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();
+ }
+ }
+
+ return AllocateExT(type, width, height, bpp, IntPtr.Zero,
+ options, palette, red_mask, green_mask, blue_mask);
+ }
+
+ ///
+ /// 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 redMask,
+ uint greenMask,
+ uint blueMask,
+ bool topdown)
+ {
+ fixed (byte* ptr = bits)
+ {
+ return ConvertFromRawBits(
+ (IntPtr)ptr,
+ type,
+ width,
+ height,
+ pitch,
+ bpp,
+ redMask,
+ greenMask,
+ blueMask,
+ 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 redMask,
+ uint greenMask,
+ uint blueMask,
+ bool topdown)
+ {
+ byte* addr = (byte*)bits;
+ if ((addr == null) || (width <= 0) || (height <= 0))
+ {
+ return FIBITMAP.Zero;
+ }
+
+ FIBITMAP dib = AllocateT(type, width, height, (int)bpp, redMask, greenMask, blueMask);
+ if (dib != FIBITMAP.Zero)
+ {
+ if (topdown)
+ {
+ for (int i = height - 1; i >= 0; --i)
+ {
+ ref byte dst = ref Unsafe.AsRef((byte*) GetScanLine(dib, i));
+ ref byte src = ref Unsafe.AsRef(addr);
+
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, GetLine(dib));
+
+ addr += pitch;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < height; ++i)
+ {
+ ref byte dst = ref Unsafe.AsRef((byte*) GetScanLine(dib, i));
+ ref byte src = ref Unsafe.AsRef(addr);
+
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, GetLine(dib));
+
+ addr += pitch;
+ }
+ }
+ }
+ return dib;
+ }
+
+ ///
+ /// 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 that the file exists
+ if (!File.Exists(filename))
+ {
+ throw new FileNotFoundException(filename + " could not be found.");
+ }
+
+ // try to find the file format by querying FreeImage plugins
+ if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN)
+ {
+ format = GetFileType(filename, 0);
+ }
+ if (format == FREE_IMAGE_FORMAT.FIF_UNKNOWN) // fall-back try to identify the file format using the extension if still unknown
+ {
+ format = GetFileTypeFromExtension(filename);
+ }
+
+ // load the file if the format is supported
+ var dib = new FIBITMAP();
+ if (FIFSupportsReading(format))
+ {
+ dib = Load(format, filename, flags);
+ }
+ return dib;
+ }
+
+ private static FREE_IMAGE_FORMAT GetFileTypeFromExtension(string filename)
+ {
+ if(string.IsNullOrEmpty(filename) || !filename.Contains("."))
+ return FREE_IMAGE_FORMAT.FIF_UNKNOWN;
+
+ var extention = filename.Substring(filename.LastIndexOf('.'));
+ return extention switch
+ {
+ ".tga" => FREE_IMAGE_FORMAT.FIF_TARGA,
+ ".png" => FREE_IMAGE_FORMAT.FIF_PNG,
+ ".bmp" => FREE_IMAGE_FORMAT.FIF_BMP,
+ ".tiff" or ".tif" => FREE_IMAGE_FORMAT.FIF_TIFF,
+ ".jpg" or ".jpeg" => FREE_IMAGE_FORMAT.FIF_JPEG,
+ _ => FREE_IMAGE_FORMAT.FIF_UNKNOWN,// Note: other format met so far seems to be properly handled by "GetFileType".
+ // -> no need to add the extension/format association here.
+ };
+ }
+
+ ///
+ /// 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.IsNull == false)
+ 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))
+ {
+ lock (streamHandles)
+ {
+ if (streamHandles.TryGetValue(bitmap, out var 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, blockSize, 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
+ ref byte dst = ref Unsafe.AsRef((void*) ppvBits);
+ ref byte src = ref Unsafe.AsRef((void*) GetBits(dib));
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, 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 = [];
+ }
+ 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 redMask,
+ out uint greenMask,
+ out uint blueMask)
+ {
+ bool result = false;
+ type = FREE_IMAGE_TYPE.FIT_UNKNOWN;
+ bpp = 0;
+ redMask = 0;
+ greenMask = 0;
+ blueMask = 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;
+ redMask = FI16_565_RED_MASK;
+ greenMask = FI16_565_GREEN_MASK;
+ blueMask = FI16_565_BLUE_MASK;
+ result = true;
+ break;
+ case PixelFormat.Format16bppRgb555:
+ case PixelFormat.Format16bppArgb1555:
+ type = FREE_IMAGE_TYPE.FIT_BITMAP;
+ bpp = 16;
+ redMask = FI16_555_RED_MASK;
+ greenMask = FI16_555_GREEN_MASK;
+ blueMask = FI16_555_BLUE_MASK;
+ result = true;
+ break;
+ case PixelFormat.Format24bppRgb:
+ type = FREE_IMAGE_TYPE.FIT_BITMAP;
+ bpp = 24;
+ redMask = FI_RGBA_RED_MASK;
+ greenMask = FI_RGBA_GREEN_MASK;
+ blueMask = FI_RGBA_BLUE_MASK;
+ result = true;
+ break;
+ case PixelFormat.Format32bppRgb:
+ case PixelFormat.Format32bppArgb:
+ case PixelFormat.Format32bppPArgb:
+ type = FREE_IMAGE_TYPE.FIT_BITMAP;
+ bpp = 32;
+ redMask = FI_RGBA_RED_MASK;
+ greenMask = FI_RGBA_GREEN_MASK;
+ blueMask = 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;
+ }
+
+ ///
+ /// 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];
+
+ ref byte dst = ref result[0];
+ ref byte src = ref Unsafe.AsRef((byte*) GetTransparencyTable(dib));
+ Unsafe.CopyBlockUnaligned(ref dst, ref src, 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 unsafe FIBITMAP ColorQuantizeEx(FIBITMAP dib, FREE_IMAGE_QUANTIZE quantize, int PaletteSize, RGBQUAD[] ReservePalette, int bpp)
+ {
+ FIBITMAP result = FIBITMAP.Zero;
+ FIBITMAP temp = FIBITMAP.Zero;
+ int reservedSize = ReservePalette?.Length ?? 0;
+
+ 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), paletteColors: 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), paletteColors: 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;
+
+ static void CopyMemory(IntPtr dest, IntPtr src, int paletteColors)
+ {
+ ref byte dstMemory = ref Unsafe.AsRef((void*) dest);
+ ref byte srcMemory = ref Unsafe.AsRef((void*) src);
+
+ Unsafe.CopyBlockUnaligned(ref dstMemory, ref srcMemory, (uint) (paletteColors * sizeof(RGBQUAD)));
+ }
+ }
+
+ #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");
+ }
+
+ bool result;
+ if (GetMetadata(model, dib, key, out FITAG _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");
+ }
+
+ FIMETADATA result = FindFirstMetadata(model, dib, out FITAG _tag);
+ if (result.IsNull)
+ {
+ tag = null;
+ return result;
+ }
+ tag = new MetadataTag(_tag, model);
+
+ metaDataSearchHandler[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)
+ {
+ bool result;
+ if (FindNextMetadata(mdhandle, out FITAG _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(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();
+ }
+ }
+
+ 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 xOrg, yOrg;
+ Scanline[] src, dst;
+ var width = (int)GetWidth(dib);
+ var 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 (color.HasValue)
+ {
+ if (!CheckColorType(GetImageType(dib), color.Value))
+ return FIBITMAP.Zero;
+
+ 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();
+ }
+ }
+
+ 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
+ ///