summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/im.h282
-rw-r--r--include/im_attrib.h116
-rw-r--r--include/im_attrib_flat.h39
-rw-r--r--include/im_binfile.h214
-rw-r--r--include/im_capture.h365
-rw-r--r--include/im_color.h465
-rw-r--r--include/im_colorhsi.h61
-rw-r--r--include/im_complex.h160
-rw-r--r--include/im_convert.h127
-rw-r--r--include/im_counter.h69
-rw-r--r--include/im_dib.h195
-rw-r--r--include/im_file.h111
-rw-r--r--include/im_format.h79
-rw-r--r--include/im_format_all.h576
-rw-r--r--include/im_format_avi.h87
-rw-r--r--include/im_format_ecw.h93
-rw-r--r--include/im_format_jp2.h78
-rw-r--r--include/im_format_raw.h64
-rw-r--r--include/im_format_wmv.h100
-rw-r--r--include/im_image.h403
-rw-r--r--include/im_kernel.h315
-rw-r--r--include/im_lib.h191
-rw-r--r--include/im_math.h368
-rw-r--r--include/im_math_op.h219
-rw-r--r--include/im_palette.h172
-rw-r--r--include/im_plus.h73
-rw-r--r--include/im_process.h35
-rw-r--r--include/im_process_ana.h221
-rw-r--r--include/im_process_glo.h170
-rw-r--r--include/im_process_loc.h577
-rw-r--r--include/im_process_pon.h712
-rw-r--r--include/im_raw.h34
-rw-r--r--include/im_util.h277
-rw-r--r--include/imlua.h83
-rw-r--r--include/old_im.h59
35 files changed, 7190 insertions, 0 deletions
diff --git a/include/im.h b/include/im.h
new file mode 100644
index 0000000..8091e77
--- /dev/null
+++ b/include/im.h
@@ -0,0 +1,282 @@
+/** \file
+ * \brief Main API
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_H
+#define __IM_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** Image data type descriptors. \n
+ * See also \ref datatypeutl.
+ * \ingroup imagerep */
+enum imDataType
+{
+ IM_BYTE, /**< "unsigned char". 1 byte from 0 to 255. */
+ IM_USHORT, /**< "unsigned short". 2 bytes from 0 to 65,535. */
+ IM_INT, /**< "int". 4 bytes from -2,147,483,648 to 2,147,483,647. */
+ IM_FLOAT, /**< "float". 4 bytes single precision IEEE floating point. */
+ IM_CFLOAT /**< complex "float". 2 float values in sequence, real and imaginary parts. */
+};
+
+/** Image color mode color space descriptors (first byte). \n
+ * See also \ref colormodeutl.
+ * \ingroup imagerep */
+enum imColorSpace
+{
+ IM_RGB, /**< Red, Green and Blue (nonlinear). */
+ IM_MAP, /**< Indexed by RGB color map (data_type=IM_BYTE). */
+ IM_GRAY, /**< Shades of gray, luma (nonlinear Luminance), or an intensity value that is not related to color. */
+ IM_BINARY, /**< Indexed by 2 colors: black (0) and white (1) (data_type=IM_BYTE). */
+ IM_CMYK, /**< Cian, Magenta, Yellow and Black (nonlinear). */
+ IM_YCBCR, /**< ITU-R 601 Y'CbCr. Y' is luma (nonlinear Luminance). */
+ IM_LAB, /**< CIE L*a*b*. L* is Lightness (nonlinear Luminance, nearly perceptually uniform). */
+ IM_LUV, /**< CIE L*u*v*. L* is Lightness (nonlinear Luminance, nearly perceptually uniform). */
+ IM_XYZ /**< CIE XYZ. Linear Light Tristimulus, Y is linear Luminance. */
+};
+
+/** Image color mode configuration/extra descriptors (1 bit each in the second byte). \n
+ * See also \ref colormodeutl.
+ * \ingroup imagerep */
+enum imColorModeConfig
+{
+ IM_ALPHA = 0x100, /**< adds an Alpha channel */
+ IM_PACKED = 0x200, /**< packed components (rgbrgbrgb...) */
+ IM_TOPDOWN = 0x400 /**< orientation from top down to bottom */
+};
+
+
+
+/** File Access Error Codes
+ * \ingroup file */
+enum imErrorCodes
+{
+ IM_ERR_NONE, /**< No error. */
+ IM_ERR_OPEN, /**< Error while opening the file (read or write). */
+ IM_ERR_ACCESS, /**< Error while accessing the file (read or write). */
+ IM_ERR_FORMAT, /**< Invalid or unrecognized file format. */
+ IM_ERR_DATA, /**< Invalid or unsupported data. */
+ IM_ERR_COMPRESS, /**< Invalid or unsupported compression. */
+ IM_ERR_MEM, /**< Insuficient memory */
+ IM_ERR_COUNTER /**< Interrupted by the counter */
+};
+
+/* Internal Image File Structure. */
+typedef struct _imFile imFile;
+
+/** Opens the file for reading. It must exists. Also reads file header.
+ * It will try to identify the file format.
+ * See also \ref imErrorCodes. \n
+ * In Lua the IM file metatable name is "imFile".
+ * When converted to a string will return "imFile(%p)" where %p is replaced by the userdata address.
+ * If the file is already closed by im.FileClose, then it will return also the suffix "-closed".
+ *
+ * \verbatim im.FileOpen(file_name: string) -> ifile: imFile, error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+imFile* imFileOpen(const char* file_name, int *error);
+
+/** Opens the file for reading using a specific format. It must exists. Also reads file header.
+ * See also \ref imErrorCodes and \ref format.
+ *
+ * \verbatim im.FileOpenAs(file_name, format: string) -> ifile: imFile, error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+imFile* imFileOpenAs(const char* file_name, const char* format, int *error);
+
+/** Creates a new file for writing using a specific format. If the file exists will be replaced. \n
+ * It will only initialize the format driver and create the file, no data is actually written.
+ * See also \ref imErrorCodes and \ref format.
+ *
+ * \verbatim im.FileNew(file_name: string, format: string) -> ifile: imFile, error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+imFile* imFileNew(const char* file_name, const char* format, int *error);
+
+/** Closes the file. \n
+ * In Lua if this function is not called, the file is closed by the garbage collector.
+ *
+ * \verbatim im.FileClose(ifile: imFile) [in Lua 5] \endverbatim
+ * \verbatim ifile:Close() [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileClose(imFile* ifile);
+
+/** Returns an internal handle.
+ * index=0 returns always an imBinFile* handle,
+ * but for some formats returns NULL because they do not use imBinFile (like AVI and WMV).
+ * index=1 return an internal structure used by the format, usually is a handle
+ * to a third party library structure. This is file format dependent.
+ *
+ * \verbatim ifile:Handle() -> handle: userdata [in Lua 5] \endverbatim
+ * \ingroup file */
+void* imFileHandle(imFile* ifile, int index);
+
+/** Returns file information.
+ * image_count is the number of images in a stack or
+ * the number of frames in a video/animation or the depth of a volume data. \n
+ * compression and image_count can be NULL.
+ * See also \ref format.
+ *
+ * \verbatim ifile:GetInfo() -> format: string, compression: string, image_count: number [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileGetInfo(imFile* ifile, char* format, char* compression, int *image_count);
+
+/** Changes the write compression method. \n
+ * If the compression is not supported will return an error code when writting. \n
+ * Use NULL to set the default compression. You can use the imFileGetInfo to retrieve the actual compression
+ * but only after \ref imFileWriteImageInfo. Only a few formats allow you to change the compression between frames.
+ *
+ * \verbatim ifile:SetInfo(compression: string) [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileSetInfo(imFile* ifile, const char* compression);
+
+/** Changes an extended attribute. \n
+ * The data will be internally duplicated. \n
+ * If data is NULL the attribute is removed.
+ * See also \ref imDataType.
+ *
+ * \verbatim ifile:SetAttribute(attrib: string, data_type: number, data: table of numbers or string) [in Lua 5] \endverbatim
+ * If data_type is IM_BYTE, as_string can be used as data.
+ * \ingroup file */
+void imFileSetAttribute(imFile* ifile, const char* attrib, int data_type, int count, const void* data);
+
+/** Returns an extended attribute. \n
+ * Returns NULL if not found. data_type and count can be NULL.
+ * See also \ref imDataType.
+ *
+ * \verbatim ifile:GetAttribute(attrib: string, [as_string: boolean]) -> data: table of numbers or string, data_type: number [in Lua 5] \endverbatim
+ * If data_type is IM_BYTE, as_string can be used to return a string instead of a table.
+ * \ingroup file */
+const void* imFileGetAttribute(imFile* ifile, const char* attrib, int *data_type, int *count);
+
+/** Returns a list of the attribute names. \n
+ * "attrib" must contain room enough for "attrib_count" names. Use "attrib=NULL" to return only the count.
+ *
+ * \verbatim ifile:GetAttributeList() -> data: table of strings [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileGetAttributeList(imFile* ifile, char** attrib, int *attrib_count);
+
+/** Returns the pallete if any. \n
+ * "palette" must be a 256 colors alocated array. \n
+ * Returns zero in "palette_count" if there is no palette. "palette_count" is >0 and <=256.
+ *
+ * \verbatim ifile:GetPalette() -> palette: imPalette [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileGetPalette(imFile* ifile, long* palette, int *palette_count);
+
+/** Changes the pallete. \n
+ * "palette_count" is >0 and <=256.
+ *
+ * \verbatim ifile:SetPalette(palette: imPalette) [in Lua 5] \endverbatim
+ * \ingroup file */
+void imFileSetPalette(imFile* ifile, long* palette, int palette_count);
+
+/** Reads the image header if any and returns image information. \n
+ * Reads also the extended image attributes, so other image attributes will be available only after calling this function. \n
+ * Returns an error code.
+ * index specifies the image number between 0 and image_count-1. \n
+ * Some drivers reads only in sequence, so "index" can be ignored by the format driver. \n
+ * Any parameters can be NULL. This function must be called at least once, check each format documentation.
+ * See also \ref imErrorCodes, \ref imDataType, \ref imColorSpace and \ref imColorModeConfig.
+ *
+ * \verbatim ifile:ReadImageInfo([index: number]) -> error: number, width: number, height: number, file_color_mode: number, file_data_type: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup file */
+int imFileReadImageInfo(imFile* ifile, int index, int *width, int *height, int *file_color_mode, int *file_data_type);
+
+/** Writes the image header. Writes the file header at the first time it is called.
+ * Writes also the extended image attributes. \n
+ * Must call imFileSetPalette and set other attributes before calling this function. \n
+ * In some formats the color space will be converted to match file format specification. \n
+ * Returns an error code. This function must be called at least once, check each format documentation.
+ * See also \ref imErrorCodes, \ref imDataType, \ref imColorSpace and \ref imColorModeConfig.
+ *
+ * \verbatim ifile:WriteImageInfo(width: number, height: number, user_color_mode: number, user_data_type: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+int imFileWriteImageInfo(imFile* ifile, int width, int height, int user_color_mode, int user_data_type);
+
+/** Reads the image data with or without conversion. \n
+ * The data can be converted to bitmap when reading.
+ * Data type conversion to byte will always scan for min-max then scale to 0-255,
+ * except integer values that min-max are already between 0-255. Complex to real conversions will use the magnitude. \n
+ * Color mode flags contains packed, alpha and top-botttom information.
+ * If flag is 0 means unpacked, no alpha and bottom up. If flag is -1 the file original flags are used. \n
+ * Returns an error code.
+ * See also \ref imErrorCodes, \ref imDataType, \ref imColorSpace and \ref imColorModeConfig.
+ *
+ * \verbatim ifile:ReadImageData(data: userdata, convert2bitmap: bool, color_mode_flags: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+int imFileReadImageData(imFile* ifile, void* data, int convert2bitmap, int color_mode_flags);
+
+/** Writes the image data. \n
+ * Returns an error code.
+ *
+ * \verbatim ifile:WriteImageData(data: userdata) -> error: number [in Lua 5] \endverbatim
+ * \ingroup file */
+int imFileWriteImageData(imFile* ifile, void* data);
+
+
+
+
+/** Registers all the internal formats. \n
+ * It is automatically called internally when a format is accessed,
+ * but can be called to force the internal formats to be registered before other formats.
+ * Notice that additional formats when registered will be registered before the internal formats
+ * if imFormatRegisterInternal is not called yet. \n
+ * To control the register order is usefull when two format drivers handle the same format.
+ * The first registered format will always be used first.
+ * \ingroup format */
+void imFormatRegisterInternal(void);
+
+/** Remove all registered formats.
+ * \ingroup format */
+void imFormatRemoveAll(void);
+
+/** Returns a list of the registered formats. \n
+ * format_list is an array of format identifiers.
+ * Each format identifier is 10 chars max, maximum of 50 formats.
+ * You can use "char* format_list[50]".
+ *
+ * \verbatim im.FormatList() -> format_list: table of strings [in Lua 5] \endverbatim
+ * \ingroup format */
+void imFormatList(char** format_list, int *format_count);
+
+/** Returns the format description. \n
+ * Format description is 50 chars max. \n
+ * Extensions are separated like "*.tif;*.tiff;", 50 chars max. \n
+ * Returns an error code. The parameters can be NULL, except format.
+ * See also \ref format.
+ *
+ * \verbatim im.FormatInfo(format: string) -> error: number, desc: string, ext: string, can_sequence: boolean [in Lua 5] \endverbatim
+ * \ingroup format */
+int imFormatInfo(const char* format, char* desc, char* ext, int *can_sequence);
+
+/** Returns the format compressions. \n
+ * Compressions are 20 chars max each, maximum of 50 compressions. You can use "char* comp[50]". \n
+ * color_mode and data_type are optional, use -1 to ignore them. \n
+ * If you use them they will select only the allowed compressions checked like in \ref imFormatCanWriteImage. \n
+ * Returns an error code.
+ * See also \ref format, \ref imErrorCodes, \ref imDataType, \ref imColorSpace and \ref imColorModeConfig.
+ *
+ * \verbatim im.FormatCompressions(format: string, [color_mode: number], [data_type: number]) -> error: number, comp: table of strings [in Lua 5] \endverbatim
+ * \ingroup format */
+int imFormatCompressions(const char* format, char** comp, int *comp_count, int color_mode, int data_type);
+
+/** Checks if the format suport the given image class at the given compression. \n
+ * Returns an error code.
+ * See also \ref format, \ref imErrorCodes, \ref imDataType, \ref imColorSpace and \ref imColorModeConfig.
+ *
+ * \verbatim im.FormatCanWriteImage(format: string, compression: string, color_mode: number, data_type: number) -> can_write: boolean [in Lua 5] \endverbatim
+ * \ingroup format */
+int imFormatCanWriteImage(const char* format, const char* compression, int color_mode, int data_type);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#include "old_im.h"
+
+#endif
diff --git a/include/im_attrib.h b/include/im_attrib.h
new file mode 100644
index 0000000..2a7cfb6
--- /dev/null
+++ b/include/im_attrib.h
@@ -0,0 +1,116 @@
+/** \file
+ * \brief Attributes Table.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_ATTRIB_H_
+#define __IM_ATTRIB_H_
+
+#include "im_attrib_flat.h"
+
+/** \brief Attributes Table.
+ *
+ * \par
+ * All the attributes have a name, a type, a count and the data.\n
+ * Names are usually strings with less that 30 chars.
+ * \par
+ * Attributes are stored in a hash table for fast access. \n
+ * We use the hash function described in "The Pratice of Programming" of Kernighan & Pike.
+ * \ingroup util */
+class imAttribTable
+{
+ imAttribTablePrivate* ptable;
+public:
+
+ /** Creates an empty table.
+ * If size is zero the default size of 101 is used. Size must be a prime number.
+ * Other common values are 67, 599 and 1499.*/
+ imAttribTable(int hash_size)
+ { ptable = imAttribTableCreate(hash_size); }
+
+ /** Destroys the table and all the attributes. */
+ ~imAttribTable()
+ { imAttribTableDestroy(ptable); ptable = 0; }
+
+ /** Returns the number of elements in the table. */
+ int Count() const
+ { return imAttribTableCount(ptable); }
+
+ /** Removes all the attributes in the table */
+ void RemoveAll()
+ { imAttribTableRemoveAll(ptable); }
+
+ /** Copies the contents of the given table into this table. */
+ void CopyFrom(const imAttribTable& table)
+ { imAttribTableCopyFrom(ptable, table.ptable); }
+
+ /** Inserts an attribute into the table. \n
+ * Data is duplicated if not NULL, else data is initialized with zeros.
+ * See also \ref imDataType. */
+ void Set(const char* name, int data_type, int count, const void* data)
+ { imAttribTableSet(ptable, name, data_type, count, data); }
+
+ /** Removes an attribute from the table given its name. */
+ void UnSet(const char *name)
+ { imAttribTableUnSet(ptable, name); }
+
+ /** Finds an attribute in the table.
+ * Returns the attribute if found, NULL otherwise.
+ * See also \ref imDataType. */
+ const void* Get(const char *name, int *data_type = 0, int *count = 0) const
+ { return imAttribTableGet(ptable, name, data_type, count); }
+
+ /** For each attribute calls the user callback. If the callback returns 0 the function returns. */
+ void ForEach(void* user_data, imAttribTableCallback attrib_func) const
+ { imAttribTableForEach(ptable, user_data, attrib_func); }
+};
+
+/** \brief Attributes Table.
+ *
+ * \par
+ * Same as \ref imAttribTable, but uses an array of fixed size.
+ * \ingroup util */
+class imAttribArray
+{
+ imAttribTablePrivate* ptable;
+public:
+
+ /** Creates an empty array. */
+ imAttribArray(int count)
+ { ptable = imAttribArrayCreate(count); }
+
+ /** Destroys the array and all the attributes. */
+ ~imAttribArray()
+ { imAttribTableDestroy(ptable); ptable = 0; }
+
+ /** Returns the number of elements in the array. */
+ int Count() const
+ { return imAttribTableCount(ptable); }
+
+ /** Removes all the attributes in the array */
+ void RemoveAll()
+ { imAttribTableRemoveAll(ptable); }
+
+ /** Copies the contents of the given table into this table. */
+ void CopyFrom(const imAttribArray& table)
+ { imAttribArrayCopyFrom(ptable, table.ptable); }
+
+ /** Inserts an attribute into the array. \n
+ * Data is duplicated if not NULL, else data is initialized with zeros.
+ * See also \ref imDataType. */
+ void Set(int index, const char* name, int data_type, int count, const void* data)
+ { imAttribArraySet(ptable, index, name, data_type, count, data); }
+
+ /** Finds an attribute in the array.
+ * Returns the attribute if found, NULL otherwise.
+ * See also \ref imDataType. */
+ const void* Get(int index, char *name = 0, int *data_type = 0, int *count = 0) const
+ { return imAttribArrayGet(ptable, index, name, data_type, count); }
+
+ /** For each attribute calls the user callback. If the callback returns 0 the function returns. */
+ void ForEach(void* user_data, imAttribTableCallback attrib_func) const
+ { imAttribTableForEach(ptable, user_data, attrib_func); }
+};
+
+#endif
diff --git a/include/im_attrib_flat.h b/include/im_attrib_flat.h
new file mode 100644
index 0000000..db6c2d8
--- /dev/null
+++ b/include/im_attrib_flat.h
@@ -0,0 +1,39 @@
+/** \file
+ * \brief Attributes Table Flat API.
+ * This will simplify the DLL export, and can be used for C aplications.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_ATTRIB_FLAT_H_
+#define __IM_ATTRIB_FLAT_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct imAttribTablePrivate;
+
+/** Definition of the callback used in ForEach function. */
+typedef int (*imAttribTableCallback)(void* user_data, int index, const char* name, int data_type, int count, const void* data);
+
+imAttribTablePrivate* imAttribTableCreate(int hash_size);
+void imAttribTableDestroy(imAttribTablePrivate* ptable);
+int imAttribTableCount(imAttribTablePrivate* ptable);
+void imAttribTableRemoveAll(imAttribTablePrivate* ptable);
+const void* imAttribTableGet(const imAttribTablePrivate* ptable, const char *name, int *data_type, int *count);
+void imAttribTableSet(imAttribTablePrivate* ptable, const char* name, int data_type, int count, const void* data);
+void imAttribTableUnSet(imAttribTablePrivate* ptable, const char *name);
+void imAttribTableCopyFrom(imAttribTablePrivate* ptable_dst, const imAttribTablePrivate* ptable_src);
+void imAttribTableForEach(const imAttribTablePrivate* ptable, void* user_data, imAttribTableCallback attrib_func);
+
+imAttribTablePrivate* imAttribArrayCreate(int hash_size);
+const void* imAttribArrayGet(const imAttribTablePrivate* ptable, int index, char *name, int *data_type, int *count);
+void imAttribArraySet(imAttribTablePrivate* ptable, int index, const char* name, int data_type, int count, const void* data);
+void imAttribArrayCopyFrom(imAttribTablePrivate* ptable_dst, const imAttribTablePrivate* ptable_src);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_binfile.h b/include/im_binfile.h
new file mode 100644
index 0000000..6bac31e
--- /dev/null
+++ b/include/im_binfile.h
@@ -0,0 +1,214 @@
+/** \file
+ * \brief Binary File Access.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#include "im_util.h"
+
+#ifndef __IM_BINFILE_H
+#define __IM_BINFILE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup binfile Binary File Access
+ *
+ * \par
+ * These functions are very usefull for reading/writing binary files
+ * that have headers or data that have to be converted depending on
+ * the current CPU byte order. It can invert 2, 4 or 8 bytes numbers to/from little/big-endian orders.
+ * \par
+ * It will process the data only if the file format is diferent from the current CPU.
+ * \par
+ * Can read from disk or memory. In case of a memory buffer, the file name must be the \ref imBinMemoryFileName structure.
+ * \par
+ * See \ref im_binfile.h
+ * \ingroup util */
+
+typedef struct _imBinFile imBinFile;
+
+/** Opens an existant binary file for reading.
+ * The default file byte order is the CPU byte order.
+ * Returns NULL if failed.
+ * \ingroup binfile */
+imBinFile* imBinFileOpen(const char* pFileName);
+
+/** Creates a new binary file for writing.
+ * The default file byte order is the CPU byte order.
+ * Returns NULL if failed.
+ * \ingroup binfile */
+imBinFile* imBinFileNew(const char* pFileName);
+
+/** Closes the file.
+ * \ingroup binfile */
+void imBinFileClose(imBinFile* bfile);
+
+/** Indicates that was an error on the last operation.
+ * \ingroup binfile */
+int imBinFileError(imBinFile* bfile);
+
+/** Returns the file size in bytes.
+ * \ingroup binfile */
+unsigned long imBinFileSize(imBinFile* bfile);
+
+/** Changes the file byte order. Returns the old one.
+ * \ingroup binfile */
+int imBinFileByteOrder(imBinFile* bfile, int pByteOrder);
+
+/** Reads an array of count values with byte sizes: 1, 2, 4, or 8. And invert the byte order if necessary after read.
+ * \ingroup binfile */
+unsigned long imBinFileRead(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
+
+/** Writes an array of values with sizes: 1, 2, 4, or 8. And invert the byte order if necessary before write.\n
+ * <b>ATENTION</b>: The function will not make a temporary copy of the values to invert the byte order.\n
+ * So after the call the values will be invalid, if the file byte order is diferent from the CPU byte order.
+ * \ingroup binfile */
+unsigned long imBinFileWrite(imBinFile* bfile, void* pValues, unsigned long pCount, int pSizeOf);
+
+/** Writes a string without the NULL terminator. The function uses sprintf to compose the string. \n
+ * The internal buffer is fixed at 4096 bytes.
+ * \ingroup binfile */
+unsigned long imBinFilePrintf(imBinFile* bfile, char *format, ...);
+
+/** Moves the file pointer from the begining of the file.\n
+ * When writing to a file seeking can go beyond the end of the file.
+ * \ingroup binfile */
+void imBinFileSeekTo(imBinFile* bfile, unsigned long pOffset);
+
+/** Moves the file pointer from current position.\n
+ * If the offset is a negative value the pointer moves backwards.
+ * \ingroup binfile */
+void imBinFileSeekOffset(imBinFile* bfile, long pOffset);
+
+/** Moves the file pointer from the end of the file.\n
+ * The offset is usually a negative value.
+ * \ingroup binfile */
+void imBinFileSeekFrom(imBinFile* bfile, long pOffset);
+
+/** Returns the current offset position.
+ * \ingroup binfile */
+unsigned long imBinFileTell(imBinFile* bfile);
+
+/** Indicates that the file pointer is at the end of the file.
+ * \ingroup binfile */
+int imBinFileEndOfFile(imBinFile* bfile);
+
+/** Predefined I/O Modules.
+ * \ingroup binfile */
+enum imBinFileModule
+{
+ IM_RAWFILE, /**< System dependent file I/O Rotines. */
+ IM_STREAM, /**< Standard Ansi C Stream I/O Rotines. */
+ IM_MEMFILE, /**< Uses a memory buffer (see \ref imBinMemoryFileName). */
+ IM_SUBFILE, /**< It is a sub file. FileName is a imBinFile* pointer from any other module. */
+ IM_FILEHANDLE,/**< System dependent file I/O Rotines, but FileName is a system file handle ("int" in UNIX and "HANDLE" in Windows). */
+ IM_IOCUSTOM0 /**< Other registered modules starts from here. */
+};
+
+/** Sets the current I/O module.
+ * \returns the previous function set, or -1 if failed.
+ * See also \ref imBinFileModule.
+ * \ingroup binfile */
+int imBinFileSetCurrentModule(int pModule);
+
+/** \brief Memory File I/O Filename
+ *
+ * \par
+ * Fake file name for the memory I/O module.
+ * \ingroup binfile */
+typedef struct _imBinMemoryFileName
+{
+ unsigned char *buffer; /**< The memory buffer. If you are reading the buffer must exists.
+ * If you are writing the buffer can be internally allocated to the given size. The buffer is never free.
+ * The buffer is allocated using "malloc", and reallocated using "realloc". Use "free" to release it.
+ * To avoid RTL conflicts use the function imBinMemoryRelease. */
+ int size; /**< Size of the buffer. */
+ float reallocate; /**< Reallocate factor for the memory buffer when writing (size += reallocate*size).
+ * Set reallocate to 0 to disable reallocation, in this case buffer must not be NULL. */
+}imBinMemoryFileName;
+
+/** Release the internal memory allocated when writing a Memory File (see \ref imBinMemoryFileName).
+ * \ingroup binfile */
+void imBinMemoryRelease(unsigned char *buffer);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#if defined(__cplusplus)
+
+/** Base class to help the creation of new modules.\n
+ * It handles the read/write operations with byte order correction if necessary.
+ * \ingroup binfile */
+class imBinFileBase
+{
+ friend class imBinSubFile;
+
+protected:
+ int IsNew,
+ FileByteOrder,
+ DoByteOrder; // to speed up byte order checking
+
+ // These will actually read/write the data
+ virtual unsigned long ReadBuf(void* pValues, unsigned long pSize) = 0;
+ virtual unsigned long WriteBuf(void* pValues, unsigned long pSize) = 0;
+
+public:
+
+ int InitByteOrder(int ByteOrder)
+ {
+ int old_byte_order = this->FileByteOrder;
+ this->FileByteOrder = ByteOrder;
+
+ if (ByteOrder != imBinCPUByteOrder())
+ this->DoByteOrder = 1;
+ else
+ this->DoByteOrder = 0;
+ return old_byte_order;
+ }
+
+ // These will take care of byte swap if needed.
+
+ unsigned long Read(void* pValues, unsigned long pCount, int pSizeOf)
+ {
+ unsigned long rSize = ReadBuf(pValues, pCount * pSizeOf);
+ if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
+ return rSize/pSizeOf;
+ }
+
+ unsigned long Write(void* pValues, unsigned long pCount, int pSizeOf)
+ {
+ if (pSizeOf != 1 && DoByteOrder) imBinSwapBytes(pValues, pCount, pSizeOf);
+ return WriteBuf(pValues, pCount * pSizeOf)/pSizeOf;
+ }
+
+ virtual void Open(const char* pFileName) = 0;
+ virtual void New(const char* pFileName) = 0;
+ virtual void Close() = 0;
+ virtual unsigned long FileSize() = 0;
+ virtual int HasError() const = 0;
+ virtual void SeekTo(unsigned long pOffset) = 0;
+ virtual void SeekOffset(long pOffset) = 0;
+ virtual void SeekFrom(long pOffset) = 0;
+ virtual unsigned long Tell() const = 0;
+ virtual int EndOfFile() const = 0;
+};
+
+/** File I/O module creation callback.
+ * \ingroup binfile */
+typedef imBinFileBase* (*imBinFileNewFunc)();
+
+/** Register a user I/O module.\n
+ * Returns the new function set id.\n
+ * Accepts up to 10 modules.
+ * \ingroup binfile */
+int imBinFileRegisterModule(imBinFileNewFunc pNewFunc);
+
+#endif
+
+#endif
diff --git a/include/im_capture.h b/include/im_capture.h
new file mode 100644
index 0000000..7c130a3
--- /dev/null
+++ b/include/im_capture.h
@@ -0,0 +1,365 @@
+/** \file
+ * \brief Video Capture
+ *
+ * See Copyright Notice in im.h
+ */
+
+#ifndef __IM_CAPTURE_H
+#define __IM_CAPTURE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* declarations to create an export library for Watcom. */
+#if ! defined (IM_DECL)
+ #if defined (__WATCOMC__)
+ #define IM_DECL __cdecl
+ #elif defined(__WATCOM_CPLUSPLUS__)
+ #define IM_DECL __cdecl
+ #else
+ #define IM_DECL
+ #endif
+#endif
+
+/** \defgroup capture Image Capture
+ * \par
+ * Functions to capture images from live video devices.
+ * \par
+ * See \ref im_capture.h
+ */
+
+typedef struct _imVideoCapture imVideoCapture;
+
+/** Returns the number of available devices.
+ *
+ * \verbatim im.VideoCaptureDeviceCount() -> count: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureDeviceCount(void);
+
+/** Returns the device description. Returns NULL only if it is an invalid device.
+ *
+ * \verbatim im.VideoCaptureDeviceDesc(device: number) -> desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char* IM_DECL imVideoCaptureDeviceDesc(int device);
+
+/** Returns the extendend device description. May return NULL.
+ *
+ * \verbatim im.VideoCaptureDeviceExDesc(device: number) -> desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char* imVideoCaptureDeviceExDesc(int device);
+
+/** Returns the device path configuration. This is a unique string.
+ *
+ * \verbatim im.VideoCaptureDevicePath(device: number) -> desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char* imVideoCaptureDevicePath(int device);
+
+/** Returns the vendor information. May return NULL.
+ *
+ * \verbatim im.VideoCaptureDeviceVendorInfo(device: number) -> desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char* imVideoCaptureDeviceVendorInfo(int device);
+
+/** Reload the device list. The devices can be dynamically removed or added to the system.
+ * Returns the number of available devices.
+ *
+ * \verbatim im.imVideoCaptureReloadDevices() -> count: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureReloadDevices(void);
+
+/** Creates a new imVideoCapture object. \n
+ * Returns NULL if there is no capture device available. \n
+ * In Windows returns NULL if DirectX version is older than 8. \n
+ * In Lua the IM videocapture metatable name is "imVideoCapture".
+ * When converted to a string will return "imVideoCapture(%p)" where %p is replaced by the userdata address.
+ * If the videocapture is already destroyed by im.VideoCaptureDestroy, then it will return also the suffix "-destroyed".
+ *
+ * \verbatim im.VideoCaptureCreate() -> vc: imVideoCapture [in Lua 5] \endverbatim
+ * \ingroup capture */
+imVideoCapture* IM_DECL imVideoCaptureCreate(void);
+
+/** Destroys a imVideoCapture object. \n
+ * In Lua if this function is not called, the videocapture is destroyed by the garbage collector.
+ *
+ * \verbatim im.VideoCaptureDestroy(vc: imVideoCapture) [in Lua 5] \endverbatim
+ * \verbatim vc:Destroy() [in Lua 5] \endverbatim
+ * \ingroup capture */
+void IM_DECL imVideoCaptureDestroy(imVideoCapture* vc);
+
+/** Connects to a capture device.
+ * More than one imVideoCapture object can be created
+ * but they must be connected to different devices. \n
+ * If the object is conected it will disconnect first. \n
+ * Use -1 to return the current connected device,
+ * in this case returns -1 if not connected. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:Connect([device: number]) -> ret: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureConnect(imVideoCapture* vc, int device);
+
+/** Disconnect from a capture device.
+ *
+ * \verbatim vc:Disconnect() [in Lua 5] \endverbatim
+ * \ingroup capture */
+void IM_DECL imVideoCaptureDisconnect(imVideoCapture* vc);
+
+/** Returns the number of available configuration dialogs.
+ *
+ * \verbatim vc:DialogCount() -> count: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureDialogCount(imVideoCapture* vc);
+
+/** Displays a configuration modal dialog of the connected device. \n
+ * In Windows, the capturing will be stopped in some cases. \n
+ * In Windows parent is a HWND of a parent window, it can be NULL. \n
+ * dialog can be from 0 to \ref imVideoCaptureDialogCount. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:ShowDialog(dialog: number, parent: userdata) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureShowDialog(imVideoCapture* vc, int dialog, void* parent);
+
+/** Allows to control the input and output of devices that have multiple input and outputs.
+ * cross controls in which stage the input/output will be set. Usually use 1, but some capture boards
+ * has a second stage. In Direct X it controls the crossbars.
+ *
+ * \verbatim vc:SetInOut(input, output, cross: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int imVideoCaptureSetInOut(imVideoCapture* vc, int input, int output, int cross);
+
+/** Returns the description of a configuration dialog.
+ * dialog can be from 0 to \ref imVideoCaptureDialogCount. \n
+ *
+ * \verbatim vc:DialogDesc(dialog: number) -> desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char* IM_DECL imVideoCaptureDialogDesc(imVideoCapture* vc, int dialog);
+
+/** Returns the number of available video formats. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:FormatCount() -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureFormatCount(imVideoCapture* vc);
+
+/** Returns information about the video format. \n
+ * format can be from 0 to \ref imVideoCaptureFormatCount. \n
+ * desc should be of size 10. \n
+ * The image size is usually the maximum size for that format.
+ * Other sizes can be available using \ref imVideoCaptureSetImageSize. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:GetFormat(format: number) -> error: number, width: number, height: number, desc: string [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureGetFormat(imVideoCapture* vc, int format, int *width, int *height, char* desc);
+
+/** Changes the video format of the connected device. \n
+ * Should NOT work for DV devices. Use \ref imVideoCaptureSetImageSize only. \n
+ * Use -1 to return the current format, in this case returns -1 if failed. \n
+ * When the format is changed in the dialog, for some formats
+ * the returned format is the preferred format, not the current format. \n
+ * This will not affect color_mode of the capture image. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:SetFormat(format: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureSetFormat(imVideoCapture* vc, int format);
+
+/** Returns the current image size of the connected device. \n
+ * width and height returns 0 if not connected.
+ *
+ * \verbatim vc:GetImageSize() -> width: number, height: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+void IM_DECL imVideoCaptureGetImageSize(imVideoCapture* vc, int *width, int *height);
+
+/** Changes the image size of the connected device. \n
+ * Similar to \ref imVideoCaptureSetFormat, but changes only the size. \n
+ * Valid sizes can be obtained with \ref imVideoCaptureGetFormat. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:SetImageSize(width: number, height: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureSetImageSize(imVideoCapture* vc, int width, int height);
+
+/** Returns a new captured frame. Use -1 for infinite timeout. \n
+ * Color space can be IM_RGB or IM_GRAY, and mode can be packed (IM_PACKED) or not. \n
+ * Data type is always IM_BYTE. \n
+ * It can not have an alpha channel and orientation is always bottom up. \n
+ * Returns zero if failed or timeout expired, the buffer is not changed.
+ *
+ * \verbatim vc:Frame(image: imImage, timeout: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureFrame(imVideoCapture* vc, unsigned char* data, int color_mode, int timeout);
+
+/** Start capturing, returns the new captured frame and stop capturing. \n
+ * This is more usefull if you are switching between devices. \n
+ * Data format is the same as imVideoCaptureFrame. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:OneFrame(image: imImage) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureOneFrame(imVideoCapture* vc, unsigned char* data, int color_mode);
+
+/** Start capturing. \n
+ * Use -1 to return the current state. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:Live(live: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureLive(imVideoCapture* vc, int live);
+
+/** Resets a camera or video attribute to the default value or
+ * to the automatic setting. \n
+ * Not all attributes support automatic modes. \n
+ * Returns zero if failed.
+ *
+ * \verbatim vc:ResetAttribute(attrib: string, fauto: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureResetAttribute(imVideoCapture* vc, const char* attrib, int fauto);
+
+/** Returns a camera or video attribute in percentage of the valid range value. \n
+ * Returns zero if failed or attribute not supported.
+ *
+ * \verbatim vc:GetAttribute(attrib: string) -> error: number, percent: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureGetAttribute(imVideoCapture* vc, const char* attrib, float *percent);
+
+/** Changes a camera or video attribute in percentage of the valid range value. \n
+ * Returns zero if failed or attribute not supported.
+ *
+ * \verbatim vc:SetAttribute(attrib: string, percent: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup capture */
+int IM_DECL imVideoCaptureSetAttribute(imVideoCapture* vc, const char* attrib, float percent);
+
+/** Returns a list of the description of the valid attributes for the device class. \n
+ * But each device may still not support some of the returned attributes. \n
+ * Use the return value of \ref imVideoCaptureGetAttribute to check if the attribute is supported.
+ *
+ * \verbatim vc:GetAttributeList() -> attrib_list: table of strings [in Lua 5] \endverbatim
+ * \ingroup capture */
+const char** IM_DECL imVideoCaptureGetAttributeList(imVideoCapture* vc, int *num_attrib);
+
+
+/** \defgroup winattrib Windows Attributes Names
+ * Not all attributes are supported by each device.
+ * Use the return value of \ref imVideoCaptureGetAttribute to check if the attribute is supported.
+\verbatim
+ VideoBrightness - Specifies the brightness, also called the black level.
+ VideoContrast - Specifies the contrast, expressed as gain factor.
+ VideoHue - Specifies the hue angle.
+ VideoSaturation - Specifies the saturation.
+ VideoSharpness - Specifies the sharpness.
+ VideoGamma - Specifies the gamma.
+ VideoColorEnable - Specifies the color enable setting. (0/100)
+ VideoWhiteBalance - Specifies the white balance, as a color temperature in degrees Kelvin.
+ VideoBacklightCompensation - Specifies the backlight compensation setting. (0/100)
+ VideoGain - Specifies the gain adjustment.
+ CameraPanAngle - Specifies the camera's pan angle. To 100 rotate right, To 0 rotate left (view from above).
+ CameraTiltAngle - Specifies the camera's tilt angle. To 100 rotate up, To 0 rotate down.
+ CameraRollAngle - Specifies the camera's roll angle. To 100 rotate right, To 0 rotate left.
+ CameraLensZoom - Specifies the camera's zoom setting.
+ CameraExposure - Specifies the exposure setting.
+ CameraIris - Specifies the camera's iris setting.
+ CameraFocus - Specifies the camera's focus setting, as the distance to the optimally focused target.
+ FlipHorizontal - Specifies the video will be flipped in the horizontal direction.
+ FlipVertical - Specifies the video will be flipped in the vertical direction.
+ AnalogFormat - Specifies the video format standard NTSC, PAL, etc. Valid values:
+ NTSC_M = 0
+ NTSC_M_J = 1
+ NTSC_433 = 2
+ PAL_B = 3
+ PAL_D = 4
+ PAL_H = 5
+ PAL_I = 6
+ PAL_M = 7
+ PAL_N = 8
+ PAL_60 = 9
+ SECAM_B = 10
+ SECAM_D = 11
+ SECAM_G = 12
+ SECAM_H = 13
+ SECAM_K = 14
+ SECAM_K1 = 15
+ SECAM_L = 16
+ SECAM_L1 = 17
+ PAL_N_COMBO = 18
+\endverbatim
+ * \ingroup capture */
+
+
+#if defined(__cplusplus)
+}
+
+/** A C++ Wrapper for the imVideoCapture structure functions.
+ * \ingroup capture */
+class imCapture
+{
+public:
+ imCapture()
+ { vc = imVideoCaptureCreate(); }
+
+ ~imCapture()
+ { if (vc) imVideoCaptureDestroy(vc); }
+
+ int Failed()
+ { if (!vc) return 0; else return 1; }
+
+ int Connect(int device)
+ { return imVideoCaptureConnect(vc, device); }
+
+ void Disconnect()
+ { imVideoCaptureDisconnect(vc); }
+
+ int DialogCount()
+ { return imVideoCaptureDialogCount(vc); }
+
+ int ShowDialog(int dialog, void* parent)
+ { return imVideoCaptureShowDialog(vc, dialog, parent); }
+
+ const char* DialogDescription(int dialog)
+ { return imVideoCaptureDialogDesc(vc, dialog); }
+
+ int FormatCount()
+ { return imVideoCaptureFormatCount(vc); }
+
+ int GetFormat(int format, int *width, int *height, char* desc)
+ { return imVideoCaptureGetFormat(vc, format, width, height, desc); }
+
+ int SetFormat(int format)
+ { return imVideoCaptureSetFormat(vc, format); }
+
+ void GetImageSize(int *width, int *height)
+ { imVideoCaptureGetImageSize(vc, width, height); }
+
+ int SetImageSize(int width, int height)
+ { return imVideoCaptureSetImageSize(vc, width, height); }
+
+ int GetFrame(unsigned char* data, int color_mode, int timeout)
+ { return imVideoCaptureFrame(vc, data, color_mode, timeout); }
+
+ int GetOneFrame(unsigned char* data, int color_mode)
+ { return imVideoCaptureOneFrame(vc, data, color_mode); }
+
+ int Live(int live)
+ { return imVideoCaptureLive(vc, live); }
+
+ int ResetAttribute(const char* attrib, int fauto)
+ { return imVideoCaptureResetAttribute(vc, attrib, fauto); }
+
+ int GetAttribute(const char* attrib, float *percent)
+ { return imVideoCaptureGetAttribute(vc, attrib, percent); }
+
+ int SetAttribute(const char* attrib, float percent)
+ { return imVideoCaptureSetAttribute(vc, attrib, percent); }
+
+ const char** GetAttributeList(int *num_attrib)
+ { return imVideoCaptureGetAttributeList(vc, num_attrib); }
+
+protected:
+ imVideoCapture* vc;
+};
+
+#endif
+
+#endif
diff --git a/include/im_color.h b/include/im_color.h
new file mode 100644
index 0000000..b38b22c
--- /dev/null
+++ b/include/im_color.h
@@ -0,0 +1,465 @@
+/** \file
+ * \brief Color Manipulation
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_COLOR_H
+#define __IM_COLOR_H
+
+#include "im_math.h"
+
+/** \defgroup color Color Manipulation
+ *
+ * \par
+ * Functions to convert from one color space to another,
+ * and color gammut utilities.
+ * \par
+ * See \ref im_color.h
+ *
+ * \section s1 Some Color Science
+ * \par
+ * Y is luminance, a linear-light quantity.
+ * It is directly proportional to physical intensity
+ * weighted by the spectral sensitivity of human vision.
+ * \par
+ * L* is lightness, a nonlinear luminance
+ * that aproximates the perception of brightness.
+ * It is nearly perceptual uniform.
+ * It has a range of 0 to 100.
+ * \par
+ * Y' is luma, a nonlinear luminance that aproximates lightness.
+ * \par
+ * Brightness is a visual sensation according to which an area
+ * apears to exhibit more or less light.
+ * It is a subjective quantity and can not be measured.
+ * \par
+ * One unit of euclidian distante in CIE L*u*v* or CIE L*a*b* corresponds
+ * roughly to a just-noticeable difference (JND) of color.
+ * \par
+\verbatim
+ ChromaUV = sqrt(u*u + v*v)
+ HueUV = atan2(v, u)
+ SaturationUV = ChromaUV / L (called psychometric saturation)
+ (the same can be calculated for Lab)
+\endverbatim
+ * \par
+ * IEC 61966-2.1 Default RGB colour space - sRGB
+ * \li ITU-R Recommendation BT.709 (D65 white point).
+ * \li D65 White Point (X,Y,Z) = (0.9505 1.0000 1.0890)
+ * \par
+ * Documentation extracted from Charles Poynton - Digital Video and HDTV - Morgan Kaufmann - 2003.
+ *
+ * \section Links
+ * \li www.color.org - ICC
+ * \li www.srgb.com - sRGB
+ * \li www.poynton.com - Charles Poynton
+ * \li www.littlecms.com - A free Color Management System (use this if you need precise color conversions)
+ *
+ * \section cci Color Component Intervals
+ * \par
+ * All the color components are stored in the 0-max interval, even the signed ones. \n
+ * Here are the pre-defined intervals for each data type. These values are used for standard color conversion.
+ * You should normalize data before converting betwwen color spaces.
+ * \par
+\verbatim
+ byte [0,255] or [-128,+127] (1 byte)
+ ushort [0,65535] or [-32768,+32767] (2 bytes)
+ int [0,16777215] or [-8388608,+8388607] (3 bytes)
+ float [0,1] or [-0.5,+0.5] (4 bytes)
+\endverbatim
+ * \ingroup util */
+
+/** Returns the zero value for color conversion porpouses. \n
+ * This is a value to be compensated when the data_type is unsigned and component is signed. \n
+ * \ingroup color */
+inline float imColorZero(int data_type)
+{
+ float zero[] = {128.0f, 32768.0f, 8388608.0f, 0.5f};
+ return zero[data_type];
+}
+
+/** Returns the maximum value for color conversion porpouses. \n
+ * \ingroup color */
+inline int imColorMax(int data_type)
+{
+ int max[] = {255, 65535, 16777215, 1};
+ return max[data_type];
+}
+
+/** Quantize r=0-1 values into q=0-max.
+ * max is the maximum value.
+ * max and the returned value are usually integers,
+ * but the dummy quantizer uses real values.
+ * See also \ref math.
+ * \ingroup color */
+template <class T>
+inline T imColorQuantize(const float& value, const T& max)
+{
+ if (max == 1) return (T)value; // to allow a dummy quantizer
+ if (value >= 1) return max;
+ if (value <= 0) return 0;
+ /* return (T)imRound(value*(max + 1) - 0.5f); not necessary since all values are positive */
+ return (T)(value*(max + 1));
+}
+
+/** Reconstruct 0-max values into 0-1. \n
+ * max is the maximum value.
+ * max and the given value are usually integers,
+ * but the dummy reconstructor uses real values.
+ * See also \ref math.
+ * \ingroup color */
+template <class T>
+inline float imColorReconstruct(const T& value, const T& max)
+{
+ if (max == 1) return (float)value; // to allow a dummy reconstructor
+ if (value <= 0) return 0;
+ if (value >= max) return 1;
+ return (((float)value + 0.5f)/((float)max + 1.0f));
+}
+
+/** Converts Y'CbCr to R'G'B' (all nonlinear). \n
+ * ITU-R Recommendation 601-1 with no headroom/footroom.
+\verbatim
+ 0 <= Y <= 1 ; -0.5 <= CbCr <= 0.5 ; 0 <= RGB <= 1
+
+ R'= Y' + 0.000 *Cb + 1.402 *Cr
+ G'= Y' - 0.344 *Cb - 0.714 *Cr
+ B'= Y' + 1.772 *Cb + 0.000 *Cr
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline void imColorYCbCr2RGB(const T Y, const T Cb, const T Cr,
+ T& R, T& G, T& B,
+ const T& zero, const T& max)
+{
+ float r = float(Y + 1.402f * (Cr - zero));
+ float g = float(Y - 0.344f * (Cb - zero) - 0.714f * (Cr - zero));
+ float b = float(Y + 1.772f * (Cb - zero));
+
+ // now we should enforce 0<= rgb <= max
+
+ R = (T)IM_CROPMAX(r, max);
+ G = (T)IM_CROPMAX(g, max);
+ B = (T)IM_CROPMAX(b, max);
+}
+
+/** Converts R'G'B' to Y'CbCr (all nonlinear). \n
+ * ITU-R Recommendation 601-1 with no headroom/footroom.
+\verbatim
+ 0 <= Y <= 1 ; -0.5 <= CbCr <= 0.5 ; 0 <= RGB <= 1
+
+ Y' = 0.299 *R' + 0.587 *G' + 0.114 *B'
+ Cb = -0.169 *R' - 0.331 *G' + 0.500 *B'
+ Cr = 0.500 *R' - 0.419 *G' - 0.081 *B'
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline void imColorRGB2YCbCr(const T R, const T G, const T B,
+ T& Y, T& Cb, T& Cr,
+ const T& zero)
+{
+ Y = (T)( 0.299f *R + 0.587f *G + 0.114f *B);
+ Cb = (T)(-0.169f *R - 0.331f *G + 0.500f *B + (float)zero);
+ Cr = (T)( 0.500f *R - 0.419f *G - 0.081f *B + (float)zero);
+
+ // there is no need for cropping here, YCrCr is already at the limits
+}
+
+/** Converts C'M'Y'K' to R'G'B' (all nonlinear). \n
+ * This is a poor conversion that works for a simple visualization.
+\verbatim
+ 0 <= CMYK <= 1 ; 0 <= RGB <= 1
+
+ R = (1 - K) * (1 - C)
+ G = (1 - K) * (1 - M)
+ B = (1 - K) * (1 - Y)
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline void imColorCMYK2RGB(const T C, const T M, const T Y, const T K,
+ T& R, T& G, T& B, const T& max)
+{
+ T W = max - K;
+ R = (T)((W * (max - C)) / max);
+ G = (T)((W * (max - M)) / max);
+ B = (T)((W * (max - Y)) / max);
+
+ // there is no need for cropping here, RGB is already at the limits
+}
+
+/** Converts CIE XYZ to Rec 709 RGB (all linear). \n
+ * ITU-R Recommendation BT.709 (D65 white point). \n
+\verbatim
+ 0 <= XYZ <= 1 ; 0 <= RGB <= 1
+
+ R = 3.2406 *X - 1.5372 *Y - 0.4986 *Z
+ G = -0.9689 *X + 1.8758 *Y + 0.0415 *Z
+ B = 0.0557 *X - 0.2040 *Y + 1.0570 *Z
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline void imColorXYZ2RGB(const T X, const T Y, const T Z,
+ T& R, T& G, T& B, const T& max)
+{
+ float r = 3.2406f *X - 1.5372f *Y - 0.4986f *Z;
+ float g = -0.9689f *X + 1.8758f *Y + 0.0415f *Z;
+ float b = 0.0557f *X - 0.2040f *Y + 1.0570f *Z;
+
+ // we need to crop because not all XYZ colors are visible
+
+ R = (T)IM_CROPMAX(r, max);
+ G = (T)IM_CROPMAX(g, max);
+ B = (T)IM_CROPMAX(b, max);
+}
+
+/** Converts Rec 709 RGB to CIE XYZ (all linear). \n
+ * ITU-R Recommendation BT.709 (D65 white point). \n
+\verbatim
+ 0 <= XYZ <= 1 ; 0 <= RGB <= 1
+
+ X = 0.4124 *R + 0.3576 *G + 0.1805 *B
+ Y = 0.2126 *R + 0.7152 *G + 0.0722 *B
+ Z = 0.0193 *R + 0.1192 *G + 0.9505 *B
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline void imColorRGB2XYZ(const T R, const T G, const T B,
+ T& X, T& Y, T& Z)
+{
+ X = (T)(0.4124f *R + 0.3576f *G + 0.1805f *B);
+ Y = (T)(0.2126f *R + 0.7152f *G + 0.0722f *B);
+ Z = (T)(0.0193f *R + 0.1192f *G + 0.9505f *B);
+
+ // there is no need for cropping here, XYZ is already at the limits
+}
+
+#define IM_FWLAB(_w) (_w > 0.008856f? \
+ powf(_w, 1.0f/3.0f): \
+ 7.787f * _w + 0.16f/1.16f)
+
+/** Converts CIE XYZ (linear) to CIE L*a*b* (nonlinear). \n
+ * The white point is D65. \n
+\verbatim
+ 0 <= L <= 1 ; -0.5 <= ab <= +0.5 ; 0 <= XYZ <= 1
+
+ if (t > 0.008856)
+ f(t) = pow(t, 1/3)
+ else
+ f(t) = 7.787*t + 16/116
+
+ fX = f(X / Xn) fY = f(Y / Yn) fZ = f(Z / Zn)
+
+ L = 1.16 * fY - 0.16
+ a = 2.5 * (fX - fY)
+ b = (fY - fZ)
+
+\endverbatim
+ * \ingroup color */
+inline void imColorXYZ2Lab(const float X, const float Y, const float Z,
+ float& L, float& a, float& b)
+{
+ float fX = X / 0.9505f; // white point D65
+ float fY = Y / 1.0f;
+ float fZ = Z / 1.0890f;
+
+ fX = IM_FWLAB(fX);
+ fY = IM_FWLAB(fY);
+ fZ = IM_FWLAB(fZ);
+
+ L = 1.16f * fY - 0.16f;
+ a = 2.5f * (fX - fY);
+ b = (fY - fZ);
+}
+
+#define IM_GWLAB(_w) (_w > 0.20689f? \
+ powf(_w, 3.0f): \
+ 0.1284f * (_w - 0.16f/1.16f))
+
+/** Converts CIE L*a*b* (nonlinear) to CIE XYZ (linear). \n
+ * The white point is D65. \n
+ * 0 <= L <= 1 ; -0.5 <= ab <= +0.5 ; 0 <= XYZ <= 1
+ * \ingroup color */
+inline void imColorLab2XYZ(const float L, const float a, const float b,
+ float& X, float& Y, float& Z)
+
+{
+ float fY = (L + 0.16f) / 1.16f;
+ float gY = IM_GWLAB(fY);
+
+ float fgY = IM_FWLAB(gY);
+ float gX = fgY + a / 2.5f;
+ float gZ = fgY - b;
+ gX = IM_GWLAB(gX);
+ gZ = IM_GWLAB(gZ);
+
+ X = gX * 0.9505f; // white point D65
+ Y = gY * 1.0f;
+ Z = gZ * 1.0890f;
+}
+
+/** Converts CIE XYZ (linear) to CIE L*u*v* (nonlinear). \n
+ * The white point is D65. \n
+\verbatim
+ 0 <= L <= 1 ; -1 <= uv <= +1 ; 0 <= XYZ <= 1
+
+ Y = Y / 1.0 (for D65)
+ if (Y > 0.008856)
+ fY = pow(Y, 1/3)
+ else
+ fY = 7.787 * Y + 0.16/1.16
+ L = 1.16 * fY - 0.16
+
+ U(x, y, z) = (4 * x)/(x + 15 * y + 3 * z)
+ V(x, y, z) = (9 * x)/(x + 15 * y + 3 * z)
+ un = U(Xn, Yn, Zn) = 0.1978 (for D65)
+ vn = V(Xn, Yn, Zn) = 0.4683 (for D65)
+ fu = U(X, Y, Z)
+ fv = V(X, Y, Z)
+
+ u = 13 * L * (fu - un)
+ v = 13 * L * (fv - vn)
+\endverbatim
+ * \ingroup color */
+inline void imColorXYZ2Luv(const float X, const float Y, const float Z,
+ float& L, float& u, float& v)
+{
+ float XYZ = (float)(X + 15 * Y + 3 * Z);
+ float fY = Y / 1.0f;
+
+ if (XYZ != 0)
+ {
+ L = 1.16f * IM_FWLAB(fY) - 0.16f;
+ u = 6.5f * L * ((4 * X)/XYZ - 0.1978f);
+ v = 6.5f * L * ((9 * Y)/XYZ - 0.4683f);
+ }
+ else
+ {
+ L = u = v = 0;
+ }
+}
+
+/** Converts CIE L*u*v* (nonlinear) to CIE XYZ (linear). \n
+ * The white point is D65.
+ * 0 <= L <= 1 ; -0.5 <= uv <= +0.5 ; 0 <= XYZ <= 1 \n
+ * \ingroup color */
+inline void imColorLuv2XYZ(const float L, const float u, const float v,
+ float& X, float& Y, float& Z)
+
+{
+ float fY = (L + 0.16f) / 1.16f;
+ Y = IM_GWLAB(fY) * 1.0f;
+
+ float ul = 0.1978f, vl = 0.4683f;
+ if (L != 0)
+ {
+ ul = u / (6.5f * L) + 0.1978f;
+ vl = v / (6.5f * L) + 0.4683f;
+ }
+
+ X = ((9 * ul) / (4 * vl)) * Y;
+ Z = ((12 - 3 * ul - 20 * vl) / (4 * vl)) * Y;
+}
+
+/** Converts nonlinear values to linear values. \n
+ * We use the sRGB transfer function. sRGB uses ITU-R 709 primaries and D65 white point. \n
+\verbatim
+ 0 <= l <= 1 ; 0 <= v <= 1
+
+ if (v < 0.03928)
+ l = v / 12.92
+ else
+ l = pow((v + 0.055) / 1.055, 2.4)
+\endverbatim
+ * \ingroup color */
+inline float imColorTransfer2Linear(const float& nonlinear_value)
+{
+ if (nonlinear_value < 0.03928f)
+ return nonlinear_value / 12.92f;
+ else
+ return powf((nonlinear_value + 0.055f) / 1.055f, 2.4f);
+}
+
+/** Converts linear values to nonlinear values. \n
+ * We use the sRGB transfer function. sRGB uses ITU-R 709 primaries and D65 white point. \n
+\verbatim
+ 0 <= l <= 1 ; 0 <= v <= 1
+
+ if (l < 0.0031308)
+ v = 12.92 * l
+ else
+ v = 1.055 * pow(l, 1/2.4) - 0.055
+\endverbatim
+ * \ingroup color */
+inline float imColorTransfer2Nonlinear(const float& value)
+{
+ if (value < 0.0031308f)
+ return 12.92f * value;
+ else
+ return 1.055f * powf(value, 1.0f/2.4f) - 0.055f;
+}
+
+/** Converts RGB (linear) to R'G'B' (nonlinear).
+ * \ingroup color */
+inline void imColorRGB2RGBNonlinear(const float RL, const float GL, const float BL,
+ float& R, float& G, float& B)
+{
+ R = imColorTransfer2Nonlinear(RL);
+ G = imColorTransfer2Nonlinear(GL);
+ B = imColorTransfer2Nonlinear(BL);
+}
+
+/** Converts R'G'B' to Y' (all nonlinear). \n
+\verbatim
+ Y' = 0.299 *R' + 0.587 *G' + 0.114 *B'
+\endverbatim
+ * \ingroup color */
+template <class T>
+inline T imColorRGB2Luma(const T R, const T G, const T B)
+{
+ return (T)((299 * R + 587 * G + 114 * B) / 1000);
+}
+
+/** Converts Luminance (CIE Y) to Lightness (CIE L*) (all linear). \n
+ * The white point is D65.
+\verbatim
+ 0 <= Y <= 1 ; 0 <= L* <= 1
+
+ Y = Y / 1.0 (for D65)
+ if (Y > 0.008856)
+ fY = pow(Y, 1/3)
+ else
+ fY = 7.787 * Y + 0.16/1.16
+ L = 1.16 * fY - 0.16
+\endverbatim
+ * \ingroup color */
+inline float imColorLuminance2Lightness(const float& Y)
+{
+ return 1.16f * IM_FWLAB(Y) - 0.16f;
+}
+
+/** Converts Lightness (CIE L*) to Luminance (CIE Y) (all linear). \n
+ * The white point is D65.
+\verbatim
+ 0 <= Y <= 1 ; 0 <= L* <= 1
+
+ fY = (L + 0.16)/1.16
+ if (fY > 0.20689)
+ Y = pow(fY, 3)
+ else
+ Y = 0.1284 * (fY - 0.16/1.16)
+ Y = Y * 1.0 (for D65)
+\endverbatim
+ * \ingroup color */
+inline float imColorLightness2Luminance(const float& L)
+{
+ float fY = (L + 0.16f) / 1.16f;
+ return IM_GWLAB(fY);
+}
+
+#undef IM_FWLAB
+#undef IM_GWLAB
+#undef IM_CROPL
+#undef IM_CROPC
+
+#endif
diff --git a/include/im_colorhsi.h b/include/im_colorhsi.h
new file mode 100644
index 0000000..effb62a
--- /dev/null
+++ b/include/im_colorhsi.h
@@ -0,0 +1,61 @@
+/** \file
+ * \brief HSI Color Manipulation
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_COLORHSI_H
+#define __IM_COLORHSI_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup hsi HSI Color Coordinate System Conversions
+ *
+ * \par
+ * HSI is just the RGB color space written in a different coordinate system.
+ * \par
+ * "I" is defined along the cube diagonal. It ranges from 0 (black) to 1 (white). \n
+ * HS are the polar coordinates of a plane normal to "I". \n
+ * "S" is the normal distance from the diagonal of the RGB cube. It ranges from 0 to Smax. \n
+ * "H" is the angle starting from the red vector, given in degrees.
+ * \par
+ * This is not a new color space, this is exactly the same gammut as RGB. \n
+ * Since it is still a cube, Smax depends on H.
+ * \par
+ * See \ref im_colorhsi.h
+ * \ingroup color */
+
+
+/** Returns the maximum S for H (here in radians) and I.
+ * \ingroup hsi */
+float imColorHSI_Smax(float h, double cosh, double sinh, float i);
+
+/** Returns I where S is maximum given H (here in radians).
+ * \ingroup hsi */
+float imColorHSI_ImaxS(float h, double cosh, double sinh);
+
+/** Converts from RGB to HSI.
+ * \ingroup hsi */
+void imColorRGB2HSI(float r, float g, float b, float *h, float *s, float *i);
+
+/** Converts from RGB (byte) to HSI.
+ * \ingroup hsi */
+void imColorRGB2HSIbyte(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i);
+
+/** Converts from HSI to RGB.
+ * \ingroup hsi */
+void imColorHSI2RGB(float h, float s, float i, float *r, float *g, float *b);
+
+/** Converts from HSI to RGB (byte).
+ * \ingroup hsi */
+void imColorHSI2RGBbyte(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_complex.h b/include/im_complex.h
new file mode 100644
index 0000000..2ac4d92
--- /dev/null
+++ b/include/im_complex.h
@@ -0,0 +1,160 @@
+/** \file
+ * \brief Complex Data Type.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_COMPLEX_H
+#define __IM_COMPLEX_H
+
+#include "im_math.h"
+
+/** \defgroup cpx Complex Numbers
+ * \par
+ * See \ref im_complex.h
+ * \ingroup util
+ */
+
+/** \brief Complex Float Data Type
+ *
+ * \par
+ * Complex class using two floats, one for real part, one for the imaginary part.
+ * \par
+ * It is not a complete complex class, we just implement constructors inside the class.
+ * All the other operators and functions are external to the class.
+ * \ingroup cpx */
+class imcfloat
+{
+public:
+ float real; ///< Real part.
+ float imag; ///< Imaginary part.
+
+ /// Default Constructor (0,0).
+ imcfloat():real(0), imag(0) {}
+
+ /// Constructor from (real, imag)
+ imcfloat(const float& r, const float& i):real(r),imag(i) {}
+
+ /// Constructor from (real)
+ imcfloat(const float& r):real(r),imag(0) {}
+};
+
+/** \addtogroup cpx
+ * Complex numbers operators.
+ * @{
+ */
+
+inline int operator <= (const imcfloat& C1, const imcfloat& C2)
+{
+ return ((C1.real <= C2.real) && (C1.imag <= C2.imag));
+}
+
+inline int operator <= (const imcfloat& C, const float& F)
+{
+ return ((F <= C.real) && (0 <= C.imag));
+}
+
+inline imcfloat operator + (const imcfloat& C1, const imcfloat& C2)
+{
+ return imcfloat(C1.real + C2.real, C1.imag + C2.imag);
+}
+
+inline imcfloat operator += (const imcfloat& C1, const imcfloat& C2)
+{
+ return imcfloat(C1.real + C2.real, C1.imag + C2.imag);
+}
+
+inline imcfloat operator - (const imcfloat& C1, const imcfloat& C2)
+{
+ return imcfloat(C1.real - C2.real, C1.imag - C2.imag);
+}
+
+inline imcfloat operator * (const imcfloat& C1, const imcfloat& C2)
+{
+ return imcfloat(C1.real * C2.real - C1.imag * C2.imag,
+ C1.imag * C2.real + C1.real * C2.imag);
+}
+
+inline imcfloat operator / (const imcfloat& C1, const imcfloat& C2)
+{
+ float den = C2.real * C2.real - C2.imag * C2.imag;
+ return imcfloat((C1.real * C2.real + C1.imag * C2.imag) / den,
+ (C1.imag * C2.real - C1.real * C2.imag) / den);
+}
+
+inline imcfloat operator / (const imcfloat& C, const float& R)
+{
+ return imcfloat(C.real / R, C.imag / R);
+}
+
+inline imcfloat operator /= (const imcfloat& C, const float& R)
+{
+ return imcfloat(C.real / R, C.imag / R);
+}
+
+inline imcfloat operator * (const imcfloat& C, const float& R)
+{
+ return imcfloat(C.real * R, C.imag * R);
+}
+
+inline int operator == (const imcfloat& C1, const imcfloat& C2)
+{
+ return ((C1.real == C2.real) && (C1.imag == C2.imag));
+}
+
+inline float cpxreal(const imcfloat& C)
+{
+ return C.real;
+}
+
+inline float cpximag(const imcfloat& C)
+{
+ return C.imag;
+}
+
+inline float cpxmag(const imcfloat& C)
+{
+ return sqrtf(C.real*C.real + C.imag*C.imag);
+}
+
+inline float cpxphase(const imcfloat& C)
+{
+ return atan2f(C.real, C.imag);
+}
+
+inline imcfloat cpxconj(const imcfloat& C)
+{
+ return imcfloat(C.real, -C.imag);
+}
+
+inline imcfloat log(const imcfloat& C)
+{
+ return imcfloat(logf(cpxmag(C)), atan2f(C.real, C.imag));
+}
+
+inline imcfloat exp(const imcfloat& C)
+{
+ float mag = expf(C.real);
+ return imcfloat(mag * cosf(C.imag), mag * sinf(C.imag));
+}
+
+inline imcfloat pow(const imcfloat& C1, const imcfloat& C2)
+{
+ return exp(C1 * log(C2));
+}
+
+inline imcfloat sqrt(const imcfloat& C)
+{
+ float mag = sqrtf(sqrtf(C.real*C.real + C.imag*C.imag));
+ float phase = atan2f(C.real, C.imag) / 2;
+ return imcfloat(mag * cosf(phase), mag * sinf(phase));
+}
+
+inline imcfloat cpxpolar(const float& mag, const float& phase)
+{
+ return imcfloat(mag * cosf(phase), mag * sinf(phase));
+}
+
+/** @} */
+
+#endif
diff --git a/include/im_convert.h b/include/im_convert.h
new file mode 100644
index 0000000..47950ea
--- /dev/null
+++ b/include/im_convert.h
@@ -0,0 +1,127 @@
+/** \file
+ * \brief Image Conversion
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_CONVERT_H
+#define __IM_CONVERT_H
+
+#include "im_image.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup convert Image Conversion
+ * \par
+ * Converts one type of image into another. Can convert between color modes
+ * and between data types.
+ * \par
+ * See \ref im_convert.h
+ * \ingroup imgclass */
+
+
+/** Complex to real conversions
+ * \ingroup convert */
+enum imComplex2Real
+{
+ IM_CPX_REAL,
+ IM_CPX_IMAG,
+ IM_CPX_MAG,
+ IM_CPX_PHASE
+};
+
+/** Predefined Gamma factors. Gamma can be any real number.
+ * When gamma<0 use logarithmic, when gamma>0 use exponential.
+ * gamma(x,g) = ((e^(g*x))-1)/(exp(g)-1)
+ * gamma(x,g) = (log((g*x)+1))/(log(g+1))
+ * \ingroup convert */
+enum imGammaFactor
+{
+ IM_GAMMA_LINEAR = 0,
+ IM_GAMMA_LOGLITE = -10,
+ IM_GAMMA_LOGHEAVY = -1000,
+ IM_GAMMA_EXPLITE = 2,
+ IM_GAMMA_EXPHEAVY = 7
+};
+
+/** Predefined Cast Modes
+ * \ingroup convert */
+enum imCastMode
+{
+ IM_CAST_MINMAX, /**< scan for min and max values */
+ IM_CAST_FIXED, /**< use predefied 0-max values, see \ref color Color Manipulation. */
+ IM_CAST_DIRECT /**< direct type cast the value. Only byte and ushort will be cropped. */
+};
+
+/** Changes the image data type, using a complex2real conversion,
+ * a gamma factor, and an abssolute mode (modulus). \n
+ * When demoting the data type the function will scan for min/max values or use fixed values (cast_mode)
+ * to scale the result according to the destiny range. \n
+ * Except complex to real that will use only the complex2real conversion. \n
+ * Images must be of the same size and color mode. \n
+ * Returns IM_ERR_NONE, IM_ERR_DATA or IM_ERR_COUNTER, see also \ref imErrorCodes.
+ * See also \ref imComplex2Real, \ref imGammaFactor and \ref imCastMode.
+ *
+ * \verbatim im.ConvertDataType(src_image: imImage, dst_image: imImage, cpx2real: number, gamma: number, abssolute: bool, cast_mode: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup convert */
+int imConvertDataType(const imImage* src_image, imImage* dst_image, int cpx2real, float gamma, int abssolute, int cast_mode);
+
+/** Converts one color space to another. Images must be of the same size and data type. \n
+ * CMYK can be converted to RGB only, and it is a very simple conversion. \n
+ * All colors can be converted to Binary, the non zero gray values are converted to 1. \n
+ * RGB to Map uses the median cut implementation from the free IJG JPEG software, copyright Thomas G. Lane. \n
+ * All other color space conversions assume sRGB and CIE definitions. \n
+ * Returns IM_ERR_NONE, IM_ERR_DATA or IM_ERR_COUNTER, see also \ref imErrorCodes.
+ *
+ * \verbatim im.ConvertColorSpace(src_image: imImage, dst_image: imImage) -> error: number [in Lua 5] \endverbatim
+ * \ingroup convert */
+int imConvertColorSpace(const imImage* src_image, imImage* dst_image);
+
+/** Converts the image to its bitmap equivalent,
+ * uses \ref imConvertColorSpace and \ref imConvertDataType. \n
+ * Returns IM_ERR_NONE, IM_ERR_DATA or IM_ERR_COUNTER, see also \ref imErrorCodes.
+ * See also \ref imComplex2Real, \ref imGammaFactor and \ref imCastMode.
+ *
+ * \verbatim im.ConvertToBitmap(src_image: imImage, dst_image: imImage, cpx2real: number, gamma: number, abssolute: bool, cast_mode: number) -> error: number [in Lua 5] \endverbatim
+ * \ingroup convert */
+int imConvertToBitmap(const imImage* src_image, imImage* dst_image, int cpx2real, float gamma, int abssolute, int cast_mode);
+
+
+
+/** \defgroup cnvutil Raw Data Conversion Utilities
+ * \par
+ * Utilities for raw data buffers.
+ * \par
+ * See \ref im_convert.h
+ * \ingroup imagerep */
+
+
+/** Changes the packing of the data buffer.
+ * \ingroup cnvutil */
+void imConvertPacking(const void* src_data, void* dst_data, int width, int height, int depth, int data_type, int src_is_packed);
+
+/** Changes in-place a MAP data into a RGB data. The data must have room for the RGB image. \n
+ * depth can be 3 or 4. count=width*height. \n
+ * Very usefull for OpenGL applications.
+ * \ingroup cnvutil */
+void imConvertMapToRGB(unsigned char* data, int count, int depth, int packed, long* palette, int palette_count);
+
+
+
+/* Converts a RGB bitmap into a map bitmap using the median cut algorithm.
+ * Used only "im_convertcolor.cpp" implemented in "im_rgb2map.cpp".
+ * Internal function kept here because of the compatibility module.
+ * Will not be at the documentation. */
+int imConvertRGB2Map(int width, int height,
+ unsigned char *red, unsigned char *green, unsigned char *blue,
+ unsigned char *map, long *palette, int *palette_count);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_counter.h b/include/im_counter.h
new file mode 100644
index 0000000..82714f5
--- /dev/null
+++ b/include/im_counter.h
@@ -0,0 +1,69 @@
+/** \file
+ * \brief Processing Counter
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_COUNTER_H
+#define __IM_COUNTER_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup counter Counter
+ * \par
+ * Used to notify the application that a step in the loading, saving or processing operation has been performed.
+ * \par
+ * See \ref im_counter.h
+ * \ingroup util */
+
+/** Counter callback, informs the progress of the operation to the client. \n
+ * Text contains a constant string that is NULL during normal counting, a title in the begining of a sequence
+ * and a message in the begining of a count.
+ * Counter id identifies diferrent counters. \n
+ * Progress in a count reports a value from 0 to 1000. If -1 indicates the start of a sequence of operations, 1001 ends the sequence. \n
+ * If returns 0 the client should abort the operation. \n
+ * If the counter is aborted, the callback will be called one last time at 1001.
+ * \ingroup counter */
+typedef int (*imCounterCallback)(int counter, void* user_data, const char* text, int progress);
+
+/** Changes the counter callback. Returns old callback. \n
+ * User data is changed only if not NULL.
+ * \ingroup counter */
+imCounterCallback imCounterSetCallback(void* user_data, imCounterCallback counter_func);
+
+/** Begins a new count, or a partial-count in a sequence. \n
+ * Calls the callback with "-1" and text=title, if it is at the top level. \n
+ * This is to be used by the operations. Returns a counter Id.
+ * \ingroup counter */
+int imCounterBegin(const char* title);
+
+/** Ends a count, or a partial-count in a sequence. \n
+ * Calls the callback with "1001", text=null, and releases the counter if it is at top level count. \n
+ * \ingroup counter */
+void imCounterEnd(int counter);
+
+/** Increments a count. Must set the total first. \n
+ * Calls the callback, text=message if it is the first increment for the count. \n
+ * Returns 0 if the callback aborted, 1 if returns normally.
+ * \ingroup counter */
+int imCounterInc(int counter);
+
+/** Set a specific count. Must set the total first. \n
+ * Calls the callback, text=message if it is the first increment for the count. \n
+ * Returns 0 if the callback aborted, 1 if returns normally.
+ * \ingroup counter */
+int imCounterIncTo(int counter, int count);
+
+/** Sets the total increments of a count.
+ * \ingroup counter */
+void imCounterTotal(int counter, int total, const char* message);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_dib.h b/include/im_dib.h
new file mode 100644
index 0000000..49077b8
--- /dev/null
+++ b/include/im_dib.h
@@ -0,0 +1,195 @@
+/** \file
+ * \brief Windows DIB (Device Independent Bitmap)
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_DIB_H
+#define __IM_DIB_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup dib Windows DIB
+ *
+ * \par
+ * Windows DIBs in memory are handled just like a BMP file without the file header. \n
+ * These functions will work only in Windows. They are usefull for interchanging data
+ * with the clipboard, with capture drivers, with the AVI and WMF file formats and others.
+ * \par
+ * Supported DIB aspects:
+ * \li bpp must be 1, 4, 8, 16, 24, or 32.
+ * \li BITMAPV4HEADER or BITMAPV5HEADER are handled but ignored. \n
+ * \li BITMAPCOREHEADER is not handled .
+ * \li BI_JPEG and BI_PNG compressions are not handled.
+ * \li biHeight can be negative, compression can be RLE only if created
+ * from imDibCreateReference, imDibPasteClipboard, imDibLoadFile.
+ * \li can not encode/decode Images to/from RLE compressed Dibs.
+ * \li if working with RLE Dibs bits_size is greatter than used.
+ * \li the resolution of a new Dib is taken from the screen.
+ * \li SetDIBitsToDevice(start_scan is 0, scan_lines is dib->bmih->biHeight).
+ * \li StretchDIBits(use always DIB_RGB_COLORS).
+ * \li CreateDIBPatternBrushPt(packed_dib is dib->dib).
+ * \par
+ * Must include <windows.h> before using these functions. \n
+ * Check <wingdi.h> for structures and definitions.
+ * \par
+ * See \ref im_dib.h
+ * \ingroup util */
+
+
+/** \brief Windows DIB Structure
+ *
+ * \par
+ * Handles a DIB in memory. \n
+ * The DIB is stored in only one buffer.
+ * The secondary members are pointers to the main buffer.
+ * \ingroup dib */
+typedef struct _imDib
+{
+ HGLOBAL handle; /**< The windows memory handle */
+ BYTE* dib; /**< The DIB as it is defined in memory */
+ int size; /**< Full size in memory */
+
+ BITMAPINFO* bmi; /**< Bitmap Info = Bitmap Info Header + Palette */
+ BITMAPINFOHEADER* bmih; /**< Bitmap Info Header */
+ RGBQUAD* bmic; /**< Bitmap Info Colors = Palette */
+ BYTE* bits; /**< Bitmap Bits */
+
+ int palette_count; /**< number of colors in the palette */
+ int bits_size; /**< size in bytes of the Bitmap Bits */
+ int line_size; /**< size in bytes of one line, includes padding */
+ int pad_size; /**< number of bytes remaining in the line, lines are in a word boundary */
+
+ int is_reference; /**< only a reference, do not free pointer */
+} imDib;
+
+/** Creates a new DIB. \n
+ * use bpp=-16/-32 to allocate space for BITFLIEDS.
+ * \ingroup dib */
+imDib* imDibCreate(int width, int height, int bpp);
+
+/** Duplicates the DIB contents in a new DIB.
+ * \ingroup dib */
+imDib* imDibCreateCopy(const imDib* dib);
+
+/** Creates a DIB using an already allocated memory. \n
+ * "bmi" must be a pointer to BITMAPINFOHEADER. \n
+ * "bits" can be NULL if it is inside "bmi" after the palette.
+ * \ingroup dib */
+imDib* imDibCreateReference(BYTE* bmi, BYTE* bits);
+
+/** Creates a DIB section for drawing porposes. \n
+ * Returns the image handle also created.
+ * \ingroup dib */
+imDib* imDibCreateSection(HDC hDC, HBITMAP *image, int width, int height, int bpp);
+
+/** Destroy the DIB
+ * \ingroup dib */
+void imDibDestroy(imDib* dib);
+
+/** DIB GetPixel function definition. \n
+ * the DWORD is a raw copy of the bits, use (unsigned char*)&pixel
+ * \ingroup dib */
+typedef unsigned int (*imDibLineGetPixel)(unsigned char* line, int col);
+
+/** Returns a function to read pixels from a DIB line.
+ * \ingroup dib */
+imDibLineGetPixel imDibLineGetPixelFunc(int bpp);
+
+/** DIB SetPixel function definition
+ * \ingroup dib */
+typedef void (*imDibLineSetPixel)(unsigned char* line, int col, unsigned int pixel);
+
+/** Returns a function to write pixels into a DIB line.
+ * \ingroup dib */
+imDibLineSetPixel imDibLineSetPixelFunc(int bpp);
+
+/** Creates a DIB from a image handle and a palette handle.
+ * \ingroup dib */
+imDib* imDibFromHBitmap(const HBITMAP image, const HPALETTE hPalette);
+
+/** Creates a image handle from a DIB.
+ * \ingroup dib */
+HBITMAP imDibToHBitmap(const imDib* dib);
+
+/** Returns a Logical palette from the DIB palette. \n
+ * DIB bpp must be <=8.
+ * \ingroup dib */
+HPALETTE imDibLogicalPalette(const imDib* dib);
+
+/** Captures the screen into a DIB.
+ * \ingroup dib */
+imDib* imDibCaptureScreen(int x, int y, int width, int height);
+
+/** Transfer the DIB to the clipboard. \n
+ * "dib" pointer can not be used after, or use imDibCopyClipboard(imDibCreateCopy(dib)).
+ * Warning: Clipboard functions in C++ can fail with Visual C++ /EHsc (Enable C++ Exceptions)
+* \ingroup dib */
+void imDibCopyClipboard(imDib* dib);
+
+/** Creates a reference for the DIB in the clipboard if any. Returns NULL otherwise.
+ * Warning: Clipboard functions in C++ can fail with Visual C++ /EHsc (Enable C++ Exceptions)
+ * \ingroup dib */
+imDib* imDibPasteClipboard(void);
+
+/** Checks if there is a dib at the clipboard.
+ * \ingroup dib */
+int imDibIsClipboardAvailable(void);
+
+/** Saves the DIB into a file ".bmp".
+ * \ingroup dib */
+int imDibSaveFile(const imDib* dib, const char* filename);
+
+/** Creates a DIB from a file ".bmp".
+ * \ingroup dib */
+imDib* imDibLoadFile(const char* filename);
+
+/** Converts a DIB into an RGBA image. alpha is optional. bpp must be >8. \n
+ * alpha is used only when bpp=32.
+ * \ingroup dib */
+void imDibDecodeToRGBA(const imDib* dib, unsigned char* red, unsigned char* green, unsigned char* blue, unsigned char* alpha);
+
+/** Converts a DIB into an indexed image. bpp must be <=8. colors must have room for at least 256 colors.
+ * colors is rgb packed (RGBRGBRGB...)
+ * \ingroup dib */
+void imDibDecodeToMap(const imDib* dib, unsigned char* map, long* palette);
+
+/** Converts an RGBA image into a DIB. alpha is optional. bpp must be >8. \n
+ * alpha is used only when bpp=32.
+ * \ingroup dib */
+void imDibEncodeFromRGBA(imDib* dib, const unsigned char* red, const unsigned char* green, const unsigned char* blue, const unsigned char* alpha);
+
+/** Converts an indexed image into a DIB. bpp must be <=8. \n
+ * colors is rgb packed (RGBRGBRGB...)
+ * \ingroup dib */
+void imDibEncodeFromMap(imDib* dib, const unsigned char* map, const long* palette, int palette_count);
+
+/** Converts a IM_RGB packed image, with or without alpha, into a DIB.
+ * \ingroup dib */
+void imDibEncodeFromBitmap(imDib* dib, const unsigned char* data);
+
+/** Converts a DIB into IM_RGB packed image, with or without alpha.
+ * \ingroup dib */
+void imDibDecodeToBitmap(const imDib* dib, unsigned char* data);
+
+#ifdef __IM_IMAGE_H
+/* You must include "im_image.h" before this header to enable these declarations. */
+
+/** Creates a imImage from the dib data.
+ * \ingroup dib */
+imImage* imDibToImage(const imDib* dib);
+
+/** Creates a Dib from the image. It must be a bitmap image.
+ * \ingroup dib */
+imDib* imDibFromImage(const imImage* image);
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_file.h b/include/im_file.h
new file mode 100644
index 0000000..a35c82a
--- /dev/null
+++ b/include/im_file.h
@@ -0,0 +1,111 @@
+/** \file
+ * \brief File Access
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FILE_H
+#define __IM_FILE_H
+
+#include "im.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup filesdk File Format SDK
+ * \par
+ * All the file formats are based on theses structures. Use them to create new file formats. \n
+ * The LineBuffer functions will help transfer image from format buffer to application buffer and vice-versa.
+ * \par
+ * See \ref im_file.h
+ * \ingroup file */
+
+
+/** \brief Image File Format Base (SDK Use Only)
+ *
+ * \par
+ * Base container to hold format independent state variables.
+ * \ingroup filesdk */
+struct _imFile
+{
+ int is_new;
+ void* attrib_table; /**< in fact is a imAttribTable, but we hide this here */
+
+ void* line_buffer; /**< used for line convertion, contains all components if packed, or only one if not */
+ int line_buffer_size;
+ int line_buffer_extra; /**< extra bytes to be allocated */
+ int line_buffer_alloc; /**< total allocated so far */
+ int counter;
+
+ int convert_bpp; /**< number of bpp to unpack/pack to/from 1 byte.
+ When reading converts n packed bits to 1 byte (unpack). If n>1 will also expand to 0-255.
+ When writing converts 1 byte to 1 bit (pack).
+ If negative will only expand to 0-255 (no unpack or pack). */
+ int switch_type; /**< flag to switch the original data type: char-byte, short-ushort, uint-int, double-float */
+
+ long palette[256];
+ int palette_count;
+
+ int user_color_mode,
+ user_data_type,
+ file_color_mode, /* these two must be filled by te driver always. */
+ file_data_type;
+
+ /* these must be filled by the driver when reading,
+ and given by the user when writing. */
+
+ char compression[10];
+ int image_count,
+ image_index,
+ width,
+ height;
+};
+
+
+/* Internal Use only */
+
+/* Initializes the imFile structure.
+ * Used by the special format RAW. */
+void imFileClear(imFile* ifile);
+
+/* Initializes the line buffer.
+ * Used by "im_file.cpp" only. */
+void imFileLineBufferInit(imFile* ifile);
+
+/* Check if the conversion is valid.
+ * Used by "im_file.cpp" only. */
+int imFileCheckConversion(imFile* ifile);
+
+
+
+/* File Format SDK */
+
+/** Number of lines to be accessed.
+ * \ingroup filesdk */
+int imFileLineBufferCount(imFile* ifile);
+
+/** Increments the row and plane counters.
+ * \ingroup filesdk */
+void imFileLineBufferInc(imFile* ifile, int *row, int *plane);
+
+/** Converts from FILE color mode to USER color mode.
+ * \ingroup filesdk */
+void imFileLineBufferRead(imFile* ifile, void* data, int line, int plane);
+
+/** Converts from USER color mode to FILE color mode.
+ * \ingroup filesdk */
+void imFileLineBufferWrite(imFile* ifile, const void* data, int line, int plane);
+
+/** Utility to calculate the line size in byte with a specified alignment. \n
+ * "align" can be 1, 2 or 4.
+ * \ingroup filesdk */
+int imFileLineSizeAligned(int width, int bpp, int align);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format.h b/include/im_format.h
new file mode 100644
index 0000000..9120676
--- /dev/null
+++ b/include/im_format.h
@@ -0,0 +1,79 @@
+/** \file
+ * \brief File Format Access
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#include "im_file.h"
+#include "im_attrib.h"
+
+#ifndef __IM_FORMAT_H
+#define __IM_FORMAT_H
+
+
+/** \brief Image File Format Driver (SDK Use Only)
+ *
+ * \par
+ * Virtual Base class for file formats. All file formats inherit from this class.
+ * \ingroup filesdk */
+class imFormat: public _imFile
+{
+public:
+ const char* format;
+ const char* desc;
+ const char* ext;
+ const char** comp;
+ int comp_count,
+ can_sequence;
+
+ imFormat(const char* _format, const char* _desc, const char* _ext,
+ const char** _comp, int _comp_count, int _can_sequence)
+ :format(_format), desc(_desc), ext(_ext), comp(_comp),
+ comp_count(_comp_count), can_sequence(_can_sequence)
+ {}
+ virtual ~imFormat() {}
+
+ imAttribTable* AttribTable() {return (imAttribTable*)this->attrib_table;}
+
+ /* Pure Virtual Methods. Every driver must implement all the following methods. */
+
+ virtual int Open(const char* file_name) = 0; // Must initialize compression and image_count
+ virtual int New(const char* file_name) = 0;
+ virtual void Close() = 0;
+ virtual void* Handle(int index) = 0;
+ virtual int ReadImageInfo(int index) = 0; // Should update compression
+ virtual int ReadImageData(void* data) = 0;
+ virtual int WriteImageInfo() = 0; // Should update compression
+ virtual int WriteImageData(void* data) = 0; // Must update image_count
+ virtual int CanWrite(const char* compression, int color_mode, int data_type) const = 0;
+};
+
+extern "C"
+{
+
+/* Internal Use only */
+
+/* Opens a file with the respective format driver
+ * Uses the file extension to speed up the search for the format driver.
+ * Used by "im_file.cpp" only. */
+imFormat* imFormatOpen(const char* file_name, int *error);
+
+/* Opens a file with the given format
+ * Used by "im_file.cpp" only. */
+imFormat* imFormatOpenAs(const char* file_name, const char* format, int *error);
+
+/* Creates a file using the given format driver.
+ * Used by "im_file.cpp" only. */
+imFormat* imFormatNew(const char* file_name, const char* format, int *error);
+
+
+/* File Format SDK */
+
+/** Register a format driver.
+ * \ingroup filesdk */
+void imFormatRegister(imFormat* iformat);
+
+
+}
+
+#endif
diff --git a/include/im_format_all.h b/include/im_format_all.h
new file mode 100644
index 0000000..3c38452
--- /dev/null
+++ b/include/im_format_all.h
@@ -0,0 +1,576 @@
+/** \file
+ * \brief All the Internal File Formats.
+ * They are all automatically registered by the library.
+ * The signatures are in C, but the functions are C++.
+ * Header for internal use only.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_ALL_H
+#define __IM_FORMAT_ALL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/** \defgroup tiff TIFF - Tagged Image File Format
+ * \section Description
+ *
+ * \par
+ * Copyright (c) 1986-1988, 1992 by Adobe Systems Incorporated. \n
+ * Originally created by a group of companies,
+ * the Aldus Corporation keeped the copyright until Aldus was aquired by Adobe. \n
+ * TIFF Revision 6.0 Final — June 3, 1992 \n
+ * http://www.adobe.com/Support/TechNotes.html
+ * \par
+ * Access to the TIFF file format uses libTIFF version 3.8.2 \n
+ * http://www.remotesensing.org/libtiff/ \n
+ * Copyright (c) 1988-1997 Sam Leffler \n
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc. \n
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: <all>
+ Color Spaces: Gray, RGB, CMYK, YCbCr, Lab, XYZ, Map and Binary.
+ Compressions:
+ NONE - no compression [default for IEEE Floating Point Data]
+ CCITTRLE - CCITT modified Huffman RLE (binary only) [default for Binary]
+ CCITTFAX3 - CCITT Group 3 fax (binary only)
+ CCITTFAX4 - CCITT Group 4 fax (binary only)
+ LZW - Lempel-Ziv & Welch [default]
+ JPEG - ISO JPEG [default for YCBCR]
+ NEXT - NeXT 2-bit RLE (2 bpp only)
+ CCITTRLEW - CCITT modified Huffman RLE with word alignment (binary only)
+ RLE - Packbits (Macintosh RLE) [default for MAP]
+ THUNDERSCAN - ThunderScan 4-bit RLE (only for 2 or 4 bpp)
+ PIXARLOG - Pixar companded 11-bit ZIP (only byte, ushort and float)
+ DEFLATE - LZ77 variation (ZIP)
+ ADOBE_DEFLATE - Adobe LZ77 variation
+ SGILOG - SGI Log Luminance RLE for L and Luv (only byte, ushort and float) [default for XYZ]
+ SGILOG24 - SGI Log 24-bit packed for Luv (only byte, ushort and float)
+ Can have more than one image.
+ Can have an alpha channel.
+ Components can be packed or not.
+ Lines arranged from top down to bottom or bottom up to top.
+ Handle(1) returns a TIFF* libTIFF structure.
+
+ Attributes:
+ Photometric IM_USHORT (1) (when writing this will complement the color_mode information, for Mask, MinIsWhite, ITULab and ICCLab)
+ ExtraSampleInfo IM_USHORT (1) (description of alpha channel: 0- uknown, 1- pre-multiplied, 2-normal)
+ JPEGQuality IM_INT (1) [0-100, default 75] (write only)
+ ZIPQuality IM_INT (1) [1-9, default 6] (write only)
+ ResolutionUnit (string) ["DPC", "DPI"]
+ XResolution, YResolution IM_FLOAT (1)
+ Description, Author, Copyright, DateTime, DocumentName,
+ PageName, TargetPrinter, Make, Model, Software, HostComputer (string)
+ InkNames (strings separated by '0's)
+ InkSet IM_USHORT (1)
+ NumberOfInks IM_USHORT (1)
+ DotRange IM_USHORT (2)
+ TransferFunction0, TransferFunction1, TransferFunction3 IM_USHORT [gray=0, rgb=012]
+ ReferenceBlackWhite IMFLOAT (6)
+ WhitePoint IMFLOAT (2)
+ PrimaryChromaticities IMFLOAT (6)
+ YCbCrCoefficients IM_FLOAT (3)
+ YCbCrSubSampling IM_USHORT (2)
+ YCbCrPositioning IM_USHORT (1)
+ PageNumber IM_USHORT (2)
+ StoNits IM_FLOAT (1)
+ XPosition, YPosition IM_FLOAT (1)
+ SMinSampleValue, SMaxSampleValue IM_FLOAT (1)
+ HalftoneHints IM_USHORT (2)
+ SubfileType IM_INT (1)
+ ICCProfile IM_BYTE (N)
+ MultiBandCount IM_USHORT (1) [Number of bands in a multiband gray image.]
+ MultiBandSelect IM_USHORT (1) [Band number to read one band of a multiband gray image. Must be set before reading image info.]
+ and other TIFF tags as they are described in the TIFF documentation.
+ GeoTIFF tags:
+ GeoTiePoints, GeoTransMatrix, IntergraphMatrix, GeoPixelScale, GeoDoubleParams IM_FLOAT (N)
+ GeoASCIIParams (string)
+ Read-only support for EXIF tags as they are described in the EXIF 2.2 documentation. See http://www.exif.org/
+ DNG tags as they are described in the DNG documentation. See http://www.adobe.com/br/products/dng/
+ Tags BlackLevel, DefaultCropOrigin and DefaultCropSize are incorrectly interpreted by libTIFF so they are ignored.
+ Raw image is loaded in place of the thumbnail image in the main IFD.
+ SubIFDCount IM_USHORT (1) [Number of subifds of the current image.]
+ SubIFDSelect IM_USHORT (1) [Subifd number to be readed. Must be set before reading image info.]
+ (other attributes can be obtained by using libTIFF directly using the Handle(1) function)
+
+ Comments:
+ LogLuv is in fact Y'+CIE(u,v), so we choose to always convert it to XYZ.
+ SubIFD is handled only for DNG.
+ Since LZW patent expired, LZW compression is enabled. LZW Copyright Unisys.
+ libGeoTIFF can be used without XTIFF initialization. Use Handle(1) to obtain a TIFF*.
+
+ Changes:
+ "tiff_jpeg.c" - commented "downsampled_output = TRUE" in 2 places.
+ New file "tif_config.h" to match our needs.
+ New file "tiff_binfile.c" that implement I/O rotines using imBinFile.
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterTIFF(void);
+
+/** \defgroup jpeg JPEG - JPEG File Interchange Format
+ * \section Description
+ *
+ * \par
+ * ISO/IEC 10918 (1994, 1995, 1997, 1999)\n
+ * http://www.jpeg.org/
+ * \par
+ * Access to the JPEG file format uses libJPEG version 6b. \n
+ * http://www.ijg.org \n
+ * Copyright (C) 1991-1998, Thomas G. Lane \n
+ * from the Independent JPEG Group.
+ * \par
+ * Access to the EXIF attributes uses libEXIF version 0.6.12. \n
+ * http://sourceforge.net/projects/libexif \n
+ * Copyright (C) 2001-2003, Lutz Müller
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: Gray, RGB, CMYK and YCbCr (Binary Saved as Gray)
+ Compressions:
+ JPEG - ISO JPEG [default]
+ Only one image.
+ No alpha channel.
+ Internally the components are always packed.
+ Internally the lines are arranged from top down to bottom.
+ Handle(1) returns jpeg_decompress_struct* when reading, and
+ jpeg_compress_struct* when writing (libJPEG structures).
+
+ Attributes:
+ AutoYCbCr IM_INT (1) (controls YCbCr auto conversion) default 1
+ JPEGQuality IM_INT (1) [0-100, default 75] (write only)
+ ResolutionUnit (string) ["DPC", "DPI"]
+ XResolution, YResolution IM_FLOAT (1)
+ Interlaced (same as Progressive) IM_INT (1 | 0) default 0
+ Description (string)
+ (lots of Exif tags)
+
+ Changes to libJPEG:
+ jdatadst.c - fflush and ferror replaced by macros JFFLUSH and JFERROR.
+ jinclude.h - standard JFFLUSH and JFERROR definitions, and new macro HAVE_JFIO.
+ jmorecfg.h - changed definition of INT32 to JINT32 for better compatibility.
+ jdhuf.c - added support for OJPEG_SUPPORT in libTIFF.
+ new file created: jconfig.h
+
+ Changes to libEXIF:
+ new file config.h
+ changed "exif-tag.c" to add new function
+ changed "exif-entry.c" to improve exif_entry_initialize
+ fixed small bug in "mnote-pentax-tag.h".
+
+ Comments:
+ Other APPx markers are ignored.
+ No thumbnail support.
+ RGB images are automatically converted to YCbCr when saved.
+ Also YcbCr are converted to RGB when loaded. Use AutoYCbCr=0 to disable this behavior.
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterJPEG(void);
+
+/** \defgroup png PNG - Portable Network Graphic Format
+ * \section Description
+ *
+ * \par
+ * Access to the PNG file format uses libPNG version 1.2.22. \n
+ * http://www.libpng.org \n
+ * Copyright (C) 1998-2007 Glenn Randers-Pehrson
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte and UShort
+ Color Spaces: Gray, RGB, MAP and Binary
+ Compressions:
+ DEFLATE - LZ77 variation (ZIP) [default]
+ Only one image.
+ Can have an alpha channel.
+ Internally the components are always packed.
+ Internally the lines are arranged from top down to bottom.
+ Handle(1) returns png_structp libPNG structure.
+
+ Attributes:
+ ZIPQuality IM_INT (1) [1-9, default 6] (write only)
+ ResolutionUnit (string) ["DPC", "DPI"]
+ XResolution, YResolution IM_FLOAT (1)
+ Interlaced (same as Progressive) IM_INT (1 | 0) default 0
+ Gamma IM_FLOAT (1)
+ WhitePoint IMFLOAT (2)
+ PrimaryChromaticities IMFLOAT (6)
+ XPosition, YPosition IM_FLOAT (1)
+ sRGBIntent IM_INT (1) [0: Perceptual, 1: Relative colorimetric, 2: Saturation, 3: Absolute colorimetric]
+ TransparencyIndex IM_BYTE (1 or N)
+ TransparentColor IM_BYTE (3)
+ CalibrationName, CalibrationUnits (string)
+ CalibrationLimits IM_INT (2)
+ CalibrationEquation IM_BYTE (1) [0-Linear,1-Exponential,2-Arbitrary,3-HyperbolicSine)]
+ CalibrationParam (string) [params separated by '\\n']
+ Title, Author, Description, Copyright, DateTime (string)
+ Software, Disclaimer, Warning, Source, Comment, ... (string)
+ DateTimeModified (string) [when writing uses the current system time]
+ ICCProfile IM_BYTE (N)
+ ScaleUnit (string) ["meters", "radians"]
+ XScale, YScale IM_FLOAT (1)
+
+ Comments:
+ Attributes after the image are ignored.
+ Define PNG_NO_CONSOLE_IO to avoid printfs.
+ We define PNG_TIME_RFC1123_SUPPORTED.
+ Add the following files to the makefile to optimize the library:
+ pngvcrd.c - PNG_USE_PNGVCRD
+ For Intel x86 CPU and Microsoft Visual C++ compiler
+ pnggccrd.c - PNG_USE_PNGGCCRD
+ For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler.
+ Changed pngconf.h to use int instead of long in png_uint_32 and png_int_32.
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterPNG(void);
+
+/** \defgroup gif GIF - Graphics Interchange Format
+ * \section Description
+ *
+ * \par
+ * Copyright (c) 1987,1988,1989,1990 CompuServe Incorporated. \n
+ * GIF is a Service Mark property of CompuServe Incorporated. \n
+ * Graphics Interchange Format Programming Reference, 1990. \n
+ * LZW Copyright Unisys.
+ * \par
+ * Patial Internal Implementation. \n
+ * Decoding and encoding code were extracted from GIFLib 1.0. \n
+ * Copyright (c) 1989 Gershon Elber.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: MAP only, (Gray and Binary saved as MAP)
+ Compressions:
+ LZW - Lempel-Ziv & Welch [default]
+ Can have more than one image.
+ No alpha channel.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ ScreenHeight, ScreenWidth IM_USHORT (1) screen size [default to the first image size]
+ Interlaced IM_INT (1 | 0) default 0
+ Description (string)
+ TransparencyIndex IM_BYTE (1)
+ XScreen, YScreen IM_USHORT (1) screen position
+ UserInput IM_BYTE (1) [1, 0]
+ Disposal (string) [UNDEF, LEAVE, RBACK, RPREV]
+ Delay IM_USHORT (1)
+ Iterations IM_USHORT (1) (NETSCAPE2.0 Application Extension)
+
+ Comments:
+ Attributes after the last image are ignored.
+ Reads GIF87 and GIF89, but writes GIF89 always.
+ Ignored attributes: Background Color Index, Pixel Aspect Ratio,
+ Plain Text Extensions, Application Extensions...
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterGIF(void);
+
+/** \defgroup bmp BMP - Windows Device Independent Bitmap
+ * \section Description
+ *
+ * \par
+ * Windows Copyright Microsoft Corporation.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: RGB, MAP and Binary (Gray saved as MAP)
+ Compressions:
+ NONE - no compression [default]
+ RLE - Run Lenght Encoding (only for MAP and Gray)
+ Only one image.
+ Can have an alpha channel (only for RGB)
+ Internally the components are always packed.
+ Lines arranged from top down to bottom or bottom up to top. But are saved always as bottom up.
+
+ Attributes:
+ ResolutionUnit (string) ["DPC", "DPI"]
+ XResolution, YResolution IM_FLOAT (1)
+
+ Comments:
+ Reads OS2 1.x and Windows 3, but writes Windows 3 always.
+ Version 4 and 5 BMPs are not supported.
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterBMP(void);
+
+/** \defgroup ras RAS - Sun Raster File
+ * \section Description
+ *
+ * \par
+ * Copyright Sun Corporation.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: Gray, RGB, MAP and Binary
+ Compressions:
+ NONE - no compression [default]
+ RLE - Run Lenght Encoding
+ Only one image.
+ Can have an alpha channel (only for IM_RGB)
+ Internally the components are always packed.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ none
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterRAS(void);
+
+/** \defgroup led LED - IUP image in LED
+ * \section Description
+ *
+ * \par
+ * Copyright Tecgraf/PUC-Rio and PETROBRAS/CENPES.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: MAP only (Gray and Binary saved as MAP)
+ Compressions:
+ NONE - no compression [default]
+ Only one image.
+ No alpha channel.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ none
+
+ Comments:
+ LED file must start with "LEDImage = IMAGE[".
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterLED(void);
+
+/** \defgroup sgi SGI - Silicon Graphics Image File Format
+ * \section Description
+ *
+ * \par
+ * SGI is a trademark of Silicon Graphics, Inc.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte and UShort
+ Color Spaces: Gray and RGB (Binary saved as Gray, MAP with fixed palette when reading only)
+ Compressions:
+ NONE - no compression [default]
+ RLE - Run Lenght Encoding
+ Only one image.
+ Can have an alpha channel (only for IM_RGB)
+ Internally the components are always packed.
+ Internally the lines are arranged from bottom up to top.
+
+ Attributes:
+ Description (string)
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterSGI(void);
+
+/** \defgroup pcx PCX - ZSoft Picture
+ * \section Description
+ *
+ * \par
+ * Copyright ZSoft Corporation. \n
+ * ZSoft (1988) PCX Technical Reference Manual.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: RGB, MAP and Binary (Gray saved as MAP)
+ Compressions:
+ NONE - no compression
+ RLE - Run Lenght Encoding [default - since uncompressed PCX is not well supported]
+ Only one image.
+ No alpha channel.
+ Internally the components are always packed.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ ResolutionUnit (string) ["DPC", "DPI"]
+ XResolution, YResolution IM_FLOAT (1)
+ XScreen, YScreen IM_USHORT (1) screen position
+
+ Comments:
+ Reads Versions 0-5, but writes Version 5 always.
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterPCX(void);
+
+/** \defgroup tga TGA - Truevision Graphics Adapter File
+ * \section Description
+ *
+ * \par
+ * Truevision TGA File Format Specification Version 2.0 \n
+ * Technical Manual Version 2.2 January, 1991 \n
+ * Copyright 1989, 1990, 1991 Truevision, Inc.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Supports 8 bits per component only. Data type is always Byte.
+ Color Spaces: Gray, RGB and MAP (Binary saved as Gray)
+ Compressions:
+ NONE - no compression [default]
+ RLE - Run Lenght Encoding
+ Only one image.
+ No alpha channel.
+ Internally the components are always packed.
+ Internally the lines are arranged from bottom up to top or from top down to bottom.
+
+ Attributes:
+ XScreen, YScreen IM_USHORT (1) screen position
+ Title, Author, Description, JobName, Software (string)
+ SoftwareVersion (read only) (string)
+ DateTimeModified (string) [when writing uses the current system time]
+ Gamma IM_FLOAT (1)
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterTGA(void);
+
+/** \defgroup pnm PNM - Netpbm Portable Image Map
+ * \section Description
+ *
+ * \par
+ * PNM formats Copyright Jef Poskanzer
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte and UShort
+ Color Spaces: Gray, RGB and Binary
+ Compressions:
+ NONE - no compression [default]
+ ASCII (textual data)
+ Can have more than one image, but sequencial access only.
+ No alpha channel.
+ Internally the components are always packed.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ Description (string)
+
+ Comments:
+ In fact ASCII is an expansion...
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterPNM(void);
+
+/** \defgroup ico ICO - Windows Icon
+ * \section Description
+ *
+ * \par
+ * Windows Copyright Microsoft Corporation.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: RGB, MAP and Binary (Gray saved as MAP)
+ Compressions:
+ NONE - no compression [default]
+ Can have more than one image. But writing is limited to 5 images,
+ and all images must have different sizes and bpp.
+ Can have an alpha channel (only for RGB)
+ Internally the components are always packed.
+ Internally the lines are arranged from bottom up to top.
+
+ Attributes:
+ TransparencyIndex IM_BYTE (1 or N)
+
+ Comments:
+ If the user specifies an alpha channel, the AND mask is loaded as alpha if
+ the file color mode does not contain the IM_ALPHA flag.
+ For MAP imagens, if the user does not specifies an alpha channel
+ the TransparencyIndex is used to initialize the AND mask when writing,
+ and if the user does specifies an alpha channel
+ the most repeated index with transparency will be the transparent index.
+ Although any size and common bpp can be used is recomended to use the typical configurations:
+ 16x16, 32x32, 48x48, 64x64 or 96x96
+ 2 colors, 16 colors, 256 colors, 24bpp or 32bpp
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterICO(void);
+
+/** \defgroup krn KRN - IM Kernel File Format
+ * \section Description
+ *
+ * \par
+ * Textual format to provied a simple way to create kernel convolution images.
+ * \par
+ * Internal Implementation.
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte, Int
+ Color Spaces: Gray
+ Compressions:
+ NONE - no compression [default]
+ Only one image.
+ No alpha channel.
+ Internally the lines are arranged from top down to bottom.
+
+ Attributes:
+ Description (string)
+
+ Comments:
+ The format is very simple, inspired by PNM.
+ It was developed because PNM does not have support for INT and FLOAT.
+ Remeber that usually convolution operations use kernel size an odd number.
+
+ Format Model:
+ IMKERNEL
+ Description up to 512 characters
+ width height
+ type (0 - IM_INT, 1 - IM_FLOAT)
+ data...
+
+ Example:
+ IMKERNEL
+ Gradian
+ 3 3
+ 0
+ 0 -1 0
+ 0 1 0
+ 0 0 0
+\endverbatim
+ * \ingroup format */
+void imFormatRegisterKRN(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format_avi.h b/include/im_format_avi.h
new file mode 100644
index 0000000..32eb7fa
--- /dev/null
+++ b/include/im_format_avi.h
@@ -0,0 +1,87 @@
+/** \file
+ * \brief Register the AVI Format
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_AVI_H
+#define __IM_FORMAT_AVI_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/** \defgroup avi AVI - Windows Audio-Video Interleaved RIFF
+ * \section Description
+ *
+ * \par
+ * Windows Copyright Microsoft Corporation.
+ * \par
+ * Access to the AVI format uses Windows AVIFile library. Available in Windows Only. \n
+ * When writing a new file you must use an ".avi" extension, or the Windows API will fail. \n
+ * You must link the application with "im_avi.lib"
+ * and you must call the function \ref imFormatRegisterAVI once
+ * to register the format into the IM core library. \n
+ * Depends also on the VFW library (vfw32.lib).
+ * When using the "im_avi.dll" this extra library is not necessary. \n
+ * If using Cygwin or MingW must link with "-lvfw32".
+ * Old versions of Cygwin and MingW use the "-lvfw_ms32" and "-lvfw_avi32".
+ * \par
+ * See \ref im_format_avi.h
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: RGB, MAP and Binary (Gray saved as MAP)
+ Compressions (installed in Windows XP by default):
+ NONE - no compression [default]
+ RLE - Microsoft RLE (8bpp only)
+ CINEPACK - Cinepak Codec by Radius
+ MSVC - Microsoft Video 1 (old)
+ M261 - Microsoft H.261 Video Codec
+ M263 - Microsoft H.263 Video Codec
+ I420 - Intel 4:2:0 Video Codec (same as M263)
+ IV32 - Intel Indeo Video Codec 3.2 (old)
+ IV41 - Intel Indeo Video Codec 4.5 (old)
+ IV50 - Intel Indeo Video 5.1
+ IYUV - Intel IYUV Codec
+ MPG4 - Microsoft MPEG-4 Video Codec V1 (not MPEG-4 compliant) (old)
+ MP42 - Microsoft MPEG-4 Video Codec V2 (not MPEG-4 compliant)
+ CUSTOM - (show compression dialog)
+ DIVX - DivX 5.0.4 Codec (DivX must be installed)
+ (others, must be the 4 charaters of the fourfcc code)
+ Can have more than one image.
+ Can have an alpha channel (only for RGB)
+ Internally the components are always packed.
+ Lines arranged from top down to bottom or bottom up to top. But are saved always as bottom up.
+ Handle(0) returns NULL. imBinFile is not supported.
+ Handle(1) returns PAVIFILE.
+ Handle(2) returns PAVISTREAM.
+
+ Attributes:
+ FPS IM_FLOAT (1) (should set when writing, default 15)
+ AVIQuality IM_INT (1) [1-10000, default -1] (write only)
+ KeyFrameRate IM_INT (1) (write only) [key frame frequency, if 0 not using key frames, default 15]
+ DataRate IM_INT (1) (write only) [kilobits/second, default 2400]
+
+ Comments:
+ Reads only the first video stream. Other streams are ignored.
+ All the images have the same size, you must call imFileReadImageInfo/imFileWriteImageInfo
+ at least once.
+ For codecs comparsion and download go to:
+ http://graphics.lcs.mit.edu/~tbuehler/video/codecs/
+ http://www.fourcc.org
+\endverbatim
+ * \ingroup format */
+
+/** Register the AVI Format. \n
+ * In Lua, when using require"imlua_avi" this function will be automatically called.
+ * \ingroup avi */
+void imFormatRegisterAVI(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format_ecw.h b/include/im_format_ecw.h
new file mode 100644
index 0000000..701bac3
--- /dev/null
+++ b/include/im_format_ecw.h
@@ -0,0 +1,93 @@
+/** \file
+ * \brief Register the ECW Format
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_ECW_H
+#define __IM_FORMAT_ECW_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/** \defgroup ecw ECW - ECW JPEG 2000
+ * \section Description
+ *
+ * \par
+ * ECW JPEG 2000 Copyright 1998 Earth Resource Mapping Ltd.
+ * Two formats are supported with this module. The ECW (Enhanced Compression Wavelet) format and the ISO JPEG 2000 format.
+ * \par
+ * Access to the ECW format uses the ECW JPEG 2000 SDK version 3.3.
+ * Available in Windows, Linux and Solaris Only. But source code is also available. \n
+ * You must link the application with "im_ecw.lib"
+ * and you must call the function \ref imFormatRegisterECW once
+ * to register the format into the IM core library. \n
+ * Depends also on the ECW JPEG 2000 SDK libraries (NCSEcw.lib).
+ * \par
+ * When using other JPEG 2000 libraries the first registered library will be used to guess the file format.
+ * Use the extension *.ecw to shortcut to this implementation of the JPEG 2000 format.
+ * \par
+ * See \ref im_format_ecw.h
+ * \par
+ * \par
+ * http://www.ermapper.com/ecw/ \n
+ * The three types of licenses available for the ECW JPEG 2000 SDK are as follows:
+\verbatim
+ - ECW JPEG 2000 SDK Free Use License Agreement - This license governs the free use of
+ the ECW JPEG 2000 SDK with Unlimited Decompression and Limited Compression (Less
+ than 500MB).
+ - ECW JPEG 2000 SDK Public Use License Agreement - This license governs the use of the
+ ECW SDK with Unlimited Decompression and Unlimited Compression for applications
+ licensed under a GNU General Public style license.
+ - ECW JPEG 2000 SDK Commercial Use License Agreement - This license governs the use
+ of the ECW JPEG 2000 SDK with Unlimited Decompression and Unlimited Compression
+ for commercial applications.
+\endverbatim
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte, UShort, Float
+ Color Spaces: BINARY, GRAY, RGB, YCBCR
+ Compressions:
+ ECW - Enhanced Compression Wavelet
+ JPEG-2000 - ISO JPEG 2000
+ Only one image.
+ Can have an alpha channel
+ Internally the components are always packed.
+ Lines arranged from top down to bottom.
+ Handle() returns NCSFileView* when reading, NCSEcwCompressClient* when writing.
+
+ Attributes:
+ CompressionRatio IM_FLOAT (1) [example: Ratio=7 just like 7:1]
+ OriginX, OriginY IM_FLOAT (1)
+ Rotation IM_FLOAT (1)
+ CellIncrementX, CellIncrementY IM_FLOAT (1)
+ CellUnits (string)
+ Datum (string)
+ Projection (string)
+ ViewWidth, ViewHeight IM_INT (1) [view zoom]
+ ViewXmin, ViewYmin, ViewXmax, ViewYmax IM_INT (1) [view limits]
+ MultiBandCount IM_USHORT (1) [Number of bands in a multiband gray image.]
+ MultiBandSelect IM_USHORT (1) [Band number to read one band of a multiband gray image. Must be set before reading image info.]
+
+ Comments:
+ Only read support is implemented.
+ To read a region of the image you must set the View* attributes before reading the image data.
+ After reading a partial image the width and height returned in ReadImageInfo is the view size.
+ The view limits define the region to be readed.
+ The view size is the actual size of the image, so the result can be zoomed.
+\endverbatim
+ * \ingroup format */
+
+/** Register the ECW Format
+ * \ingroup ecw */
+void imFormatRegisterECW(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format_jp2.h b/include/im_format_jp2.h
new file mode 100644
index 0000000..96c1c0a
--- /dev/null
+++ b/include/im_format_jp2.h
@@ -0,0 +1,78 @@
+/** \file
+ * \brief Register the JP2 Format
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_JP2_H
+#define __IM_FORMAT_JP2_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup jp2 JP2 - JPEG-2000 JP2 File Format
+ * \section Description
+ *
+ * \par
+ * ISO/IEC 15444 (2000, 2003)\n
+ * http://www.jpeg.org/
+ * \par
+ * You must link the application with "im_jp2.lib"
+ * and you must call the function \ref imFormatRegisterJP2 once
+ * to register the format into the IM core library. \n
+ * \par
+ * Access to the JPEG2000 file format uses libJasper version 1.900.1 \n
+ * http://www.ece.uvic.ca/~mdadams/jasper \n
+ * Copyright (c) 2001-2006 Michael David Adams. \n
+ * and GeoJasPer 1.4.0 \n
+ * Copyright (c) 2003-2007 Dmitry V. Fedorov. \n
+ * http://www.dimin.net/software/geojasper/ \n
+ *
+ * \par
+ * See \ref im_format_jp2.h
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte and UShort
+ Color Spaces: Binary, Gray, RGB, YCbCr, Lab and XYZ
+ Compressions:
+ JPEG-2000 - ISO JPEG 2000 [default]
+ Only one image.
+ Can have an alpha channel.
+ Internally the components are always unpacked.
+ Internally the lines are arranged from top down to bottom.
+ Handle(1) returns jas_image_t*
+ Handle(2) returns jas_stream_t*
+
+ Attributes:
+ CompressionRatio IM_FLOAT (1) [write only, example: Ratio=7 just like 7:1]
+ GeoTIFFBox IM_BYTE (n)
+ XMLPacket IM_BYTE (n)
+
+ Comments:
+ We read code stream syntax and JP2, but we write always as JP2.
+ Used definitions EXCLUDE_JPG_SUPPORT,EXCLUDE_MIF_SUPPORT,
+ EXCLUDE_PNM_SUPPORT,EXCLUDE_RAS_SUPPORT,
+ EXCLUDE_BMP_SUPPORT,EXCLUDE_PGX_SUPPORT
+ Changed jas_config.h to match our needs.
+ New file jas_binfile.c
+ Changed base/jas_stream.c to export jas_stream_create and jas_stream_initbuf.
+ Changed jp2/jp2_dec.c and jpc/jpc_cs.c to remove "uint" and "ulong" usage.
+ The counter is restarted many times, because it has many phases.
+\endverbatim
+ * \ingroup format */
+
+/** Register the JP2 Format. \n
+ * In Lua, when using require"imlua_jp2" this function will be automatically called.
+ * \ingroup jp2 */
+void imFormatRegisterJP2(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format_raw.h b/include/im_format_raw.h
new file mode 100644
index 0000000..8027f82
--- /dev/null
+++ b/include/im_format_raw.h
@@ -0,0 +1,64 @@
+/** \file
+ * \brief Initialize the RAW Format Driver
+ * Header for internal use only.
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_RAW_H
+#define __IM_FORMAT_RAW_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/** \defgroup raw RAW - RAW File
+ *
+ * \par
+ * The file must be open/created with the functions \ref imFileOpenRaw and \ref imFileNewRaw.
+ *
+ * \section Description
+ *
+ * \par
+ * Internal Implementation.
+ * \par
+ * Supports RAW binary images. You must know image parameters a priori. \n
+ * You must set the IM_INT attributes "Width", "Height", "ColorMode", "DataType" before the imFileReadImageInfo/imFileWriteImageInfo functions.
+ * \par
+ * The data must be in binary form, but can start in an arbitrary offset from the begining of the file, use attribute "StartOffset".
+ * The default is at 0 offset.
+ * \par
+ * Integer sign and double precision can be converted using attribute "SwitchType". \n
+ * The conversions will be BYTE<->CHAR, USHORT<->SHORT, INT<->UINT, FLOAT<->DOUBLE.
+ * \par
+ * Byte Order can be Little Endian (Intel=1) or Big Endian (Motorola=0), use the attribute "ByteOrder", the default is the current CPU.
+ * \par
+ * The lines can be aligned to a BYTE (1), WORD (2) or DWORD (4) boundaries, ue attribute "Padding" with the respective value.
+ * \par
+ * See \ref im_raw.h
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: <all>
+ Color Spaces: all, except MAP.
+ Compressions:
+ NONE - no compression
+ Can have more than one image, depends on "StartOffset" attribute.
+ Can have an alpha channel.
+ Components can be packed or not.
+ Lines arranged from top down to bottom or bottom up to top.
+
+ Attributes:
+ Width, Height, ColorMode, DataType IM_INT (1)
+ StartOffset, SwitchType, ByteOrder, Padding IM_INT (1)
+\endverbatim
+ * \ingroup format */
+imFormat* imFormatInitRAW(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_format_wmv.h b/include/im_format_wmv.h
new file mode 100644
index 0000000..10007b8
--- /dev/null
+++ b/include/im_format_wmv.h
@@ -0,0 +1,100 @@
+/** \file
+ * \brief Register the WMF Format
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_FORMAT_WMV_H
+#define __IM_FORMAT_WMV_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/** \defgroup wmv WMV - Windows Media Video Format
+ * \section Description
+ *
+ * \par
+ * Advanced Systems Format (ASF) \n
+ * Windows Copyright Microsoft Corporation.
+ * \par
+ * Access to the WMV format uses Windows Media SDK. Available in Windows Only. \n
+ * You must link the application with "im_wmv.lib"
+ * and you must call the function \ref imFormatRegisterWMV once
+ * to register the format into the IM core library. \n
+ * Depends also on the WMF SDK (wmvcore.lib).
+ * When using the "im_wmv.dll" this extra library is not necessary.
+ * \par
+ * The application users should have the WMV codec 9 installed:
+ * http://www.microsoft.com/windows/windowsmedia/format/codecdownload.aspx
+ * \par
+ * You must agree with the WMF SDK EULA to use the SDK. \n
+ * http://wmlicense.smdisp.net/v9sdk/
+ * \par
+ * For more information: \n
+ * http://www.microsoft.com/windows/windowsmedia/9series/sdk.aspx \n
+ * http://msdn.microsoft.com/library/en-us/wmform/htm/introducingwindowsmediaformat.asp
+ * \par
+ * See \ref im_format_wmv.h
+ *
+ * \section Features
+ *
+\verbatim
+ Data Types: Byte
+ Color Spaces: RGB and MAP (Gray and Binary saved as MAP)
+ Compressions (installed in Windows XP by default):
+ NONE - no compression
+ MPEG-4v3 - Windows Media MPEG-4 Video V3
+ MPEG-4v1 - ISO MPEG-4 Video V1
+ WMV7 - Windows Media Video V7
+ WMV7Screen - Windows Media Screen V7
+ WMV8 - Windows Media Video V8
+ WMV9Screen - Windows Media Video 9 Screen
+ WMV9 - Windows Media Video 9 [default]
+ Unknown - Others
+ Can have more than one image.
+ Can have an alpha channel (only for RGB) ?
+ Internally the components are always packed.
+ Lines arranged from top down to bottom or bottom up to top.
+ Handle(0) return NULL. imBinFile is not supported.
+ Handle(1) returns IWMSyncReader* when reading, IWMWriter* when writing.
+
+ Attributes:
+ FPS IM_FLOAT (1) (should set when writing, default 15)
+ WMFQuality IM_INT (1) [0-100, default 50] (write only)
+ MaxKeyFrameTime IM_INT (1) (write only) [maximum key frame interval in miliseconds, default 5 seconds]
+ DataRate IM_INT (1) (write only) [kilobits/second, default 2400]
+ VBR IM_INT (1) [0, 1] (write only) [0 - Constant Bit Rate (default), 1 - Variable Bit Rate (Quality-Based)]
+ (and several others from the file-level attributes) For ex:
+ Title, Author, Copyright, Description (string)
+ Duration IM_INT [100-nanosecond units]
+ Seekable, HasAudio, HasVideo, Is_Protected, Is_Trusted, IsVBR IM_INT (1) [0, 1]
+ NumberOfFrames IM_INT (1)
+
+ Comments:
+ IMPORTANT - The "image_count" and the "FPS" attribute may not be available from the file,
+ we try to estimate from the duration and from the average time between frames, or using the default value.
+ We do not handle DRM protected files (Digital Rights Management).
+ Reads only the first video stream. Other streams are ignored.
+ All the images have the same size, you must call imFileReadImageInfo/imFileWriteImageInfo
+ at least once.
+ For optimal random reading, the file should be indexed previously.
+ If not indexed by frame, random positioning may not be precise.
+ Sequencial reading will always be precise.
+ When writing we use a custom profile and time indexing only.
+ We do not support multipass encoding.
+ Since the driver uses COM, CoInitialize(NULL) and CoUninitialize() are called every Open/Close.
+\endverbatim
+ * \ingroup format */
+
+/** Register the WMF Format. \n
+ * In Lua, when using require"imlua_wmv" this function will be automatically called.
+ * \ingroup wmv */
+void imFormatRegisterWMV(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_image.h b/include/im_image.h
new file mode 100644
index 0000000..fca3212
--- /dev/null
+++ b/include/im_image.h
@@ -0,0 +1,403 @@
+/** \file
+ * \brief Image Manipulation
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_IMAGE_H
+#define __IM_IMAGE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup imgclass imImage
+ *
+ * \par
+ * Base definitions and functions for image representation. \n
+ * Only the image processing operations depends on these definitions,
+ * Image Storage and Image Capture are completely independent.
+ * \par
+ * You can also initialize a structure with your own memory buffer, see \ref imImageInit.
+ * To release the structure without releasing the buffer,
+ * set "data[0]" to NULL before calling imImageDestroy.
+ * \par
+ * See \ref im_image.h
+ * \ingroup imagerep */
+
+
+
+/** \brief imImage Structure Definition.
+ *
+ * \par
+ * An image representation than supports all the color spaces,
+ * but planes are always unpacked and the orientation is always bottom up.
+ * \ingroup imgclass */
+typedef struct _imImage
+{
+ /* main parameters */
+ int width; /**< Number of columns. image:Width() -> width: number [in Lua 5]. */
+ int height; /**< Number of lines. image:Height() -> height: number [in Lua 5]. */
+ int color_space; /**< Color space descriptor. See also \ref imColorSpace. image:ColorSpace() -> color_space: number [in Lua 5]. */
+ int data_type; /**< Data type descriptor. See also \ref imDataType. image:DataType() -> data_type: number [in Lua 5]. */
+ int has_alpha; /**< Indicates that there is an extra channel with alpha. image:HasAlpha() -> has_alpha: number [in Lua 5]. \n
+ It will not affect the secondary parameters, i.e. the number of planes will be in fact depth+1. \n
+ It is always 0 unless imImageAddAlpha is called, this is done in image load functions. */
+
+ /* secondary parameters */
+ int depth; /**< Number of planes (ColorSpaceDepth) */
+ int line_size; /**< Number of bytes per line in one plane (width * DataTypeSize) */
+ int plane_size; /**< Number of bytes per plane. (line_size * height) */
+ int size; /**< Number of bytes occupied by the image (plane_size * depth) */
+ int count; /**< Number of pixels (width * height) */
+
+ /* image data */
+ void** data; /**< Image data organized as a 2D matrix with several planes. \n
+ But plane 0 is also a pointer to the full data. \n
+ The remaining planes are: data[i] = data[0] + i*plane_size \n
+ In Lua, data indexing is possible using: image[plane][row][column] */
+
+ /* image attributes */
+ long *palette; /**< Color palette. image:GetPalette() -> palette: imPalette [in Lua 5]. \n
+ Used when depth=1. Otherwise is NULL. */
+ int palette_count; /**< The palette is always 256 colors allocated, but can have less colors used. */
+
+ void* attrib_table; /**< in fact is an imAttribTable, but we hide this here */
+} imImage;
+
+
+/** Creates a new image.
+ * See also \ref imDataType and \ref imColorSpace. \n
+ * In Lua the IM image metatable name is "imImage".
+ * When converted to a string will return "imImage(%p) [width=%d,height=%d,color_space=%s,data_type=%s,depth=%d]" where %p is replaced by the userdata address,
+ * and other values are replaced by the respective attributes.
+ * If the image is already destroyed by im.ImageDestroy, then it will return also the suffix "-destroyed".
+ *
+ * \verbatim im.ImageCreate(width: number, height: number, color_space: number, data_type: number) -> image: imImage [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+imImage* imImageCreate(int width, int height, int color_space, int data_type);
+
+/** Initializes the image structure but does not allocates image data.
+ * See also \ref imDataType and \ref imColorSpace.
+ * \ingroup imgclass */
+imImage* imImageInit(int width, int height, int color_space, int data_type, void* data_buffer, long* palette, int palette_count);
+
+/** Creates a new image based on an existing one. \n
+ * If the addicional parameters are -1, the given image parameters are used. \n
+ * The image atributes always are copied.
+ * See also \ref imDataType and \ref imColorSpace.
+ *
+ * \verbatim im.ImageCreateBased(image: imImage, [width: number], [height: number], [color_space: number], [data_type: number]) -> image: imImage [in Lua 5] \endverbatim
+ * The addicional parameters in Lua can be nil,
+ * and they can also be functions with the based image as a parameter to return the respective value.
+ * \ingroup imgclass */
+imImage* imImageCreateBased(const imImage* image, int width, int height, int color_space, int data_type);
+
+/** Destroys the image and frees the memory used.
+ * image data is destroyed only if its data[0] is not NULL. \n
+ * In Lua if this function is not called, the image is destroyed by the garbage collector.
+ *
+ * \verbatim im.ImageDestroy(image: imImage) [in Lua 5] \endverbatim
+ * \verbatim image:Destroy() [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageDestroy(imImage* image);
+
+/** Adds an alpha channel plane.
+ *
+ * \verbatim image:AddAlpha() [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageAddAlpha(imImage* image);
+
+/** Changes the buffer size. Reallocate internal buffers if the new size is larger than the original.
+ *
+ * \verbatim image:Reshape(width: number, height: number) [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageReshape(imImage* image, int width, int height);
+
+/** Copy image data and attributes from one image to another. \n
+ * Images must have the same size and type.
+ *
+ * \verbatim image:Copy(dst_image: imImage) [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageCopy(const imImage* src_image, imImage* dst_image);
+
+/** Copy image data only fom one image to another. \n
+ * Images must have the same size and type.
+ *
+ * \verbatim image:CopyData(dst_image: imImage) [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageCopyData(const imImage* src_image, imImage* dst_image);
+
+/** Creates a copy of the image.
+ *
+ * \verbatim image:Duplicate() -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+imImage* imImageDuplicate(const imImage* image);
+
+/** Creates a clone of the image. i.e. same attributes but ignore contents.
+ *
+ * \verbatim image:Clone() -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+imImage* imImageClone(const imImage* image);
+
+/** Changes an extended attribute. \n
+ * The data will be internally duplicated. \n
+ * If data is NULL the attribute is removed. \n
+ * If count is -1 and data_type is IM_BYTE then data is zero terminated.
+ * See also \ref imDataType.
+ *
+ * \verbatim image:SetAttribute(attrib: string, data_type: number, data: table of numbers or string) [in Lua 5] \endverbatim
+ * If data_type is IM_BYTE, as_string can be used as data.
+ * \ingroup imgclass */
+void imImageSetAttribute(imImage* image, const char* attrib, int data_type, int count, const void* data);
+
+/** Returns an extended attribute. \n
+ * Returns NULL if not found.
+ * See also \ref imDataType.
+ *
+ * \verbatim image:GetAttribute(attrib: string, [as_string: boolean]) -> data: table of numbers or string, data_type: number [in Lua 5] \endverbatim
+ * If data_type is IM_BYTE, as_string can be used to return a string instead of a table.
+ * \ingroup imgclass */
+const void* imImageGetAttribute(const imImage* image, const char* attrib, int *data_type, int *count);
+
+/** Returns a list of the attribute names. \n
+ * "attrib" must contain room enough for "attrib_count" names. Use "attrib=NULL" to return only the count.
+ *
+ * \verbatim image:GetAttributeList() -> data: table of strings [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageGetAttributeList(const imImage* image, char** attrib, int *attrib_count);
+
+/** Sets all image data to zero.
+ *
+ * \verbatim image:Clear() [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageClear(imImage* image);
+
+/** Indicates that the image can be viewed in common graphic devices.
+ * Data type must be IM_BYTE. Color mode can be IM_RGB, IM_MAP, IM_GRAY or IM_BINARY.
+ *
+ * \verbatim image:IsBitmap() -> is_bitmap: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageIsBitmap(const imImage* image);
+
+/** Changes the image palette.
+ * This will destroy the existing palette and replace it with the given palette buffer.
+ *
+ * \verbatim image:SetPalette(palette: imPalette) [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageSetPalette(imImage* image, long* palette, int palette_count);
+
+/** Copies the image attributes from src to dst.
+ *
+ * \verbatim image:CopyAttributes(dst_image: imImage) [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageCopyAttributes(const imImage* src_image, imImage* dst_image);
+
+/** Returns 1 if the images match width and height. Returns 0 otherwise.
+ *
+ * \verbatim image:MatchSize(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageMatchSize(const imImage* image1, const imImage* image2);
+
+/** Returns 1 if the images match color mode and data type. Returns 0 otherwise.
+ *
+ * \verbatim image:MatchColor(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageMatchColor(const imImage* image1, const imImage* image2);
+
+/** Returns 1 if the images match width, height and data type. Returns 0 otherwise.
+ *
+ * \verbatim image:MatchDataType(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageMatchDataType(const imImage* image1, const imImage* image2);
+
+/** Returns 1 if the images match width, height and color space. Returns 0 otherwise.
+ *
+ * \verbatim image:MatchColorSpace(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageMatchColorSpace(const imImage* image1, const imImage* image2);
+
+/** Returns 1 if the images match in width, height, data type and color space. Returns 0 otherwise.
+ *
+ * \verbatim image:Match(image2: imImage) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+int imImageMatch(const imImage* image1, const imImage* image2);
+
+/** Changes the image space from gray to binary by just changing color_space and the palette.
+ *
+ * \verbatim image:SetBinary() [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageSetBinary(imImage* image);
+
+/** Changes a gray data into a binary data, done in-place.
+ *
+ * \verbatim image:MakeBinary() [in Lua 5] \endverbatim
+ * \ingroup imgclass */
+void imImageMakeBinary(imImage *image);
+
+
+
+/** \defgroup imgfile imImage Storage
+ *
+ * \par
+ * Functions to simplify the process of reading and writting imImage structures.
+ * Will also load and save the alpha planes when possible.
+ * \par
+ * See \ref im_image.h
+ * \ingroup file */
+
+
+/** Loads an image from an already open file. Returns NULL if failed. \n
+ * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * The returned image will be of the same color_space and data_type of the image in the file. \n
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim ifile:LoadImage([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileLoadImage(imFile* ifile, int index, int *error);
+
+/** Loads an image from an already open file. Returns NULL if failed. \n
+ * This function assumes that the image in the file has the same parameters as the given image. \n
+ * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * The returned image will be of the same color_space and data_type of the image in the file. \n
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim ifile:LoadImageFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+void imFileLoadImageFrame(imFile* ifile, int index, imImage* image, int *error);
+
+/** Loads an image from an already open file, but forces the image to be a bitmap.\n
+ * The returned imagem will be always a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * Returns NULL if failed.
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim ifile:LoadBitmap([index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileLoadBitmap(imFile* ifile, int index, int *error);
+
+/** Loads an image region from an already open file. Returns NULL if failed. \n
+ * This will call \ref imFileReadImageInfo and \ref imFileReadImageData. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * The returned image will be of the same color_space and data_type of the image in the file,
+ * or will be a Bitmap image. \n
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes. \n
+ * For now works only for ECW file format.
+ *
+ * \verbatim ifile:LoadRegion(index, bitmap, xmin, xmax, ymin, ymax, width, height: number) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileLoadImageRegion(imFile* ifile, int index, int bitmap, int *error,
+ int xmin, int xmax, int ymin, int ymax, int width, int height);
+
+/** Loads an image from an already open file, but forces the image to be a bitmap.\n
+ * This function assumes that the image in the file has the same parameters as the given image. \n
+ * The imagem must be a Bitmap image, with color_space RGB, MAP, GRAY or BINARY, and data_type IM_BYTE. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * Returns NULL if failed.
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim ifile:LoadBitmapFrame(index: number, image: imImage) -> error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+void imFileLoadBitmapFrame(imFile* ifile, int index, imImage* image, int *error);
+
+/** Saves the image to an already open file. \n
+ * This will call \ref imFileWriteImageInfo and \ref imFileWriteImageData. \n
+ * Attributes from the image will be stored at the file.
+ * Returns error code.
+ *
+ * \verbatim ifile:SaveImage(image: imImage) -> error: number [in Lua 5] \endverbatim
+ * \ingroup imgfile */
+int imFileSaveImage(imFile* ifile, const imImage* image);
+
+/** Loads an image from file. Open, loads and closes the file. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * Returns NULL if failed.
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim im.FileImageLoad(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileImageLoad(const char* file_name, int index, int *error);
+
+/** Loads an image from file, but forces the image to be a bitmap. Open, loads and closes the file. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * Returns NULL if failed.
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim im.FileImageLoadBitmap(file_name: string, [index: number]) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileImageLoadBitmap(const char* file_name, int index, int *error);
+
+/** Loads an image region from file. Open, loads and closes the file. \n
+ * index specifies the image number between 0 and image_count-1. \n
+ * Returns NULL if failed.
+ * Attributes from the file will be stored at the image.
+ * See also \ref imErrorCodes. \n
+ * For now works only for ECW file format.
+ *
+ * \verbatim im.FileImageLoadRegion(file_name: string, index, bitmap, xmin, xmax, ymin, ymax, width, height: number, ) -> image: imImage, error: number [in Lua 5] \endverbatim
+ * Default index is 0.
+ * \ingroup imgfile */
+imImage* imFileImageLoadRegion(const char* file_name, int index, int bitmap, int *error,
+ int xmin, int xmax, int ymin, int ymax, int width, int height);
+
+/** Saves the image to file. Open, saves and closes the file. \n
+ * Returns error code. \n
+ * Attributes from the image will be stored at the file.
+ *
+ * \verbatim im.FileImageSave(file_name: string, format: string, image: imImage) -> error: number [in Lua 5] \endverbatim
+ * \verbatim image:Save(file_name: string, format: string) -> error: number [in Lua 5] \endverbatim
+ * \ingroup imgfile */
+int imFileImageSave(const char* file_name, const char* format, const imImage* image);
+
+
+
+/** Utility macro to draw the image in a CD library canvas.
+ * Works only for data_type IM_BYTE, and color spaces: IM_RGB, IM_MAP, IMGRAY and IM_BINARY.
+ * \ingroup imgclass */
+#define imcdCanvasPutImage(_canvas, _image, _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax) \
+ { \
+ if (_image->color_space == IM_RGB) \
+ { \
+ if (_image->has_alpha) \
+ cdCanvasPutImageRectRGBA(_canvas, _image->width, _image->height, \
+ (unsigned char*)_image->data[0], \
+ (unsigned char*)_image->data[1], \
+ (unsigned char*)_image->data[2], \
+ (unsigned char*)_image->data[3], \
+ _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax); \
+ else \
+ cdCanvasPutImageRectRGB(_canvas, _image->width, _image->height, \
+ (unsigned char*)_image->data[0], \
+ (unsigned char*)_image->data[1], \
+ (unsigned char*)_image->data[2], \
+ _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax); \
+ } \
+ else \
+ cdCanvasPutImageRectMap(_canvas, _image->width, _image->height, \
+ (unsigned char*)_image->data[0], _image->palette, \
+ _x, _y, _w, _h, _xmin, _xmax, _ymin, _ymax); \
+ }
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_kernel.h b/include/im_kernel.h
new file mode 100644
index 0000000..db066d8
--- /dev/null
+++ b/include/im_kernel.h
@@ -0,0 +1,315 @@
+/** \file
+ * \brief Kernel Generators
+ * Creates several known kernels
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_KERNEL_H
+#define __IM_KERNEL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup kernel Kernel Generators
+ * \par
+ * Creates several known kernels
+ * \par
+ * See \ref im_kernel.h
+ * \ingroup convolve */
+
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 2 1
+ 0 0 0
+ -1 -2 -1
+\endverbatim
+ *
+ * \verbatim im.KernelSobel() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelSobel(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 1 1
+ 0 0 0
+ -1 -1 -1
+\endverbatim
+ *
+ * \verbatim im.KernelPrewitt() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelPrewitt(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 5 5 5
+ -3 0 -3
+ -3 -3 -3
+\endverbatim
+ *
+ * \verbatim im.KernelKirsh() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelKirsh(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 0
+ -1 4 -1
+ 0 -1 0
+\endverbatim
+ *
+ * \verbatim im.KernelLaplacian4() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelLaplacian4(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ -1 -1 -1
+ -1 8 -1
+ -1 -1 -1
+\endverbatim
+ *
+ * \verbatim im.KernelLaplacian8() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelLaplacian8(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 -1 -1 0
+ -1 0 1 0 -1
+ -1 1 8 1 -1
+ -1 0 1 0 -1
+ 0 -1 -1 -1 0
+\endverbatim
+ *
+ * \verbatim im.KernelLaplacian5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelLaplacian5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ -1 -1 -1 -1 -1 -1 -1
+ -1 -1 -1 -1 -1 -1 -1
+ -1 -1 -1 -1 -1 -1 -1
+ -1 -1 -1 48 -1 -1 -1
+ -1 -1 -1 -1 -1 -1 -1
+ -1 -1 -1 -1 -1 -1 -1
+ -1 -1 -1 -1 -1 -1 -1
+\endverbatim
+ *
+ * \verbatim im.KernelLaplacian7x7() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelLaplacian7x7(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 0
+ 0 1 0
+ 0 0 0
+\endverbatim
+ *
+ * \verbatim im.KernelGradian3x3() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelGradian3x3(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 -1 0 1 1 0
+ -1 -2 -2 0 2 2 1
+ -1 -2 -3 0 3 2 1
+ -1 -2 -3 0 3 2 1
+ -1 -2 -3 0 3 2 1
+ -1 -2 -2 0 2 2 1
+ 0 -1 -1 0 1 1 0
+\endverbatim
+ *
+ * \verbatim im.KernelGradian7x7() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelGradian7x7(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ -1 0 0
+ 0 0 0
+ 0 0 1
+\endverbatim
+ *
+ * \verbatim im.KernelSculpt() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelSculpt(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 1 1
+ 1 1 1
+ 1 1 1
+\endverbatim
+ *
+ * \verbatim im.KernelMean3x3() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelMean3x3(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 1 1 1 1
+ 1 1 1 1 1
+ 1 1 1 1 1
+ 1 1 1 1 1
+ 1 1 1 1 1
+\endverbatim
+ *
+ * \verbatim im.KernelMean5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelMean5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 1 1 1 0
+ 1 1 1 1 1
+ 1 1 1 1 1
+ 1 1 1 1 1
+ 0 1 1 1 0
+\endverbatim
+ *
+ * \verbatim im.KernelMean5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelCircularMean5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+\endverbatim
+ *
+ * \verbatim im.KernelMean7x7() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelMean7x7(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 0 1 1 1 0 0
+ 0 1 1 1 1 1 0
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 1 1 1 1 1 1 1
+ 0 1 1 1 1 1 0
+ 0 0 1 1 1 0 0
+\endverbatim
+ *
+ * \verbatim im.KernelCircularMean7x7() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelCircularMean7x7(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 2 1
+ 2 4 2
+ 1 2 1
+\endverbatim
+ *
+ * \verbatim im.KernelGaussian3x3() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelGaussian3x3(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 4 6 4 1
+ 4 16 24 16 4
+ 6 24 36 24 6
+ 4 16 24 16 4
+ 1 4 6 4 1
+\endverbatim
+ *
+ * \verbatim im.KernelGaussian5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelGaussian5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 1 2 3 2 1
+ 2 4 6 4 2
+ 3 6 9 6 3
+ 2 4 6 4 2
+ 1 2 3 2 1
+\endverbatim
+ *
+ * \verbatim im.KernelBarlett5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelBarlett5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 -1 -1 0
+ -1 -1 3 -1 -1
+ -1 3 4 3 -1
+ -1 -1 3 -1 -1
+ 0 -1 -1 -1 0
+\endverbatim
+ *
+ * \verbatim im.KernelTopHat5x5() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelTopHat5x5(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 0 -1 -1 -1 0 0
+ 0 -1 -1 -1 -1 -1 0
+ -1 -1 3 3 3 -1 -1
+ -1 -1 3 4 3 -1 -1
+ -1 -1 3 3 3 -1 -1
+ 0 -1 -1 -1 -1 -1 0
+ 0 0 -1 -1 -1 0 0
+\endverbatim
+ *
+ * \verbatim im.KernelTopHat7x7() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelTopHat7x7(void);
+
+/** Creates a kernel with the following values:
+ *
+\verbatim
+ 0 -1 -2 -1 0
+ -1 -4 0 -4 -1
+ -2 0 40 0 -2
+ -1 -4 0 -4 -1
+ 0 -1 -2 -1 0
+\endverbatim
+ *
+ * \verbatim im.KernelEnhance() -> kernel: imImage [in Lua 5] \endverbatim
+ * \ingroup kernel */
+imImage* imKernelEnhance(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/include/im_lib.h b/include/im_lib.h
new file mode 100644
index 0000000..80330cc
--- /dev/null
+++ b/include/im_lib.h
@@ -0,0 +1,191 @@
+/** \file
+ * \brief Library Management and Main Documentation
+ *
+ * See Copyright Notice in this file.
+ */
+
+#ifndef __IM_LIB_H
+#define __IM_LIB_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup lib Library Management
+ * \ingroup util
+ * \par
+ * Usefull definitions for about dialogs and
+ * for comparing the compiled version with the linked version of the library.
+ * \par
+ * \verbatim im._AUTHOR [in Lua 5] \endverbatim
+ * \verbatim im._COPYRIGHT [in Lua 5] \endverbatim
+ * \verbatim im._VERSION [in Lua 5] \endverbatim
+ * \verbatim im._VERSION_DATE [in Lua 5] \endverbatim
+ * \verbatim im._VERSION_NUMBER [in Lua 5] \endverbatim
+ * \verbatim im._DESCRIPTION [in Lua 5] \endverbatim
+ * \verbatim im._NAME [in Lua 5] \endverbatim
+ * \par
+ * See \ref im_lib.h
+ * @{
+ */
+#define IM_AUTHOR "Antonio Scuri"
+#define IM_COPYRIGHT "Copyright (C) 1994-2008 Tecgraf, PUC-Rio."
+#define IM_VERSION "3.4.0"
+#define IM_VERSION_NUMBER 304000
+#define IM_VERSION_DATE "2008/10/14"
+#define IM_DESCRIPTION "Image Representation, Storage, Capture and Processing"
+#define IM_NAME "IM - An Imaging Toolkit"
+/** @} */
+
+
+/** Returns the library current version. Returns the definition IM_VERSION.
+ *
+ * \verbatim im.Version() -> version: string [in Lua 5] \endverbatim
+ * \ingroup lib */
+const char* imVersion(void);
+
+/** Returns the library current version release date. Returns the definition IM_VERSION_DATE.
+ *
+ * \verbatim im.VersionDate() -> date: string [in Lua 5] \endverbatim
+ * \ingroup lib */
+const char* imVersionDate(void);
+
+/** Returns the library current version number. Returns the definition IM_VERSION_NUMBER. \n
+ * Can be compared in run time with IM_VERSION_NUMBER to compare compiled and linked versions of the library.
+ *
+ * \verbatim im.VersionNumber() -> version: number [in Lua 5] \endverbatim
+ * \ingroup lib */
+int imVersionNumber(void);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+/*! \mainpage IM
+ * <CENTER>
+ * <H3> Image Representation, Storage, Capture and Processing </H3>
+ * Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil \n
+ * http://www.tecgraf.puc-rio.br/im \n
+ * mailto:im@tecgraf.puc-rio.br
+ * </CENTER>
+ *
+ * \section over Overview
+ * \par
+ * IM is a toolkit for Digital Imaging.
+ * \par
+ * It provides support for image capture, several image file formats and many image processing operations.
+ * \par
+ * Image representation includes scientific data types (like IEEE floating point data)
+ * and attributes (or metadata like GeoTIFF and Exif tags).
+ * Animation, video and volumes are supported as image sequences,
+ * but there is no digital audio support.
+ * \par
+ * The main goal of the library is to provide a simple API and abstraction
+ * of images for scientific applications.
+ * \par
+ * The toolkit API is written in C.
+ * The core library source code is implemented in C++ and it is very portable,
+ * it can be compiled in Windows and UNIX with no modifications.
+ * New image processing operations can be implemented in C or in C++.
+ * \par
+ * IM is free software, can be used for public and commercial applications.
+ * \par
+ * This work was developed at Tecgraf/PUC-Rio
+ * by means of the partnership with PETROBRAS/CENPES.
+ *
+ * \section author Author
+ * \par
+ * Basic Software Group @ Tecgraf/PUC-Rio
+ * - Antonio Scuri scuri@tecgraf.puc-rio.br
+ *
+ * \section copyright Copyright Notice
+\verbatim
+
+****************************************************************************
+Copyright (C) 1994-2008 Tecgraf, PUC-Rio.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+****************************************************************************
+\endverbatim
+ */
+
+
+/** \defgroup imagerep Image Representation
+ * \par
+ * See \ref im.h
+ */
+
+
+/** \defgroup file Image Storage
+ * \par
+ * See \ref im.h
+ */
+
+
+/** \defgroup format File Formats
+ * \par
+ * See \ref im.h
+ *
+ * Internal Predefined File Formats:
+ * \li "BMP" - Windows Device Independent Bitmap
+ * \li "PCX" - ZSoft Picture
+ * \li "GIF" - Graphics Interchange Format
+ * \li "TIFF" - Tagged Image File Format
+ * \li "RAS" - Sun Raster File
+ * \li "SGI" - Silicon Graphics Image File Format
+ * \li "JPEG" - JPEG File Interchange Format
+ * \li "LED" - IUP image in LED
+ * \li "TGA" - Truevision Targa
+ * \li "RAW" - RAW File
+ * \li "PNM" - Netpbm Portable Image Map
+ * \li "ICO" - Windows Icon
+ * \li "PNG" - Portable Network Graphic Format
+ *
+ * Other Supported File Formats:
+ * \li "JP2" - JPEG-2000 JP2 File Format
+ * \li "AVI" - Windows Audio-Video Interleaved RIFF
+ * \li "WMV" - Windows Media Video Format
+ *
+ * Some Known Compressions:
+ * \li "NONE" - No Compression.
+ * \li "RLE" - Run Lenght Encoding.
+ * \li "LZW" - Lempel, Ziff and Welsh.
+ * \li "JPEG" - Join Photographics Experts Group.
+ * \li "DEFLATE" - LZ77 variation (ZIP)
+ *
+ * \ingroup file */
+
+
+/* Library Names Convention
+ *
+ * Global Functions and Types - "im[Object][Action]" using first capitals (imFileOpen)
+ * Local Functions and Types - "i[Object][Action]" using first capitals (iTIFFGetCompIndex)
+ * Local Static Variables - same as local functions and types (iFormatCount)
+ * Local Static Tables - same as local functions and types with "Table" suffix (iTIFFCompTable)
+ * Variables and Members - no prefix, all lower case (width)
+ * Defines and Enumerations - all capitals (IM_ERR_NONE)
+ *
+ */
+
+
+#endif
diff --git a/include/im_math.h b/include/im_math.h
new file mode 100644
index 0000000..8e9b3dd
--- /dev/null
+++ b/include/im_math.h
@@ -0,0 +1,368 @@
+/** \file
+ * \brief Math Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_MATH_H
+#define __IM_MATH_H
+
+#include <math.h>
+#include "im_util.h"
+
+#ifdef IM_DEFMATHFLOAT
+inline float acosf(float _X) {return ((float)acos((double)_X)); }
+inline float asinf(float _X) {return ((float)asin((double)_X)); }
+inline float atanf(float _X) {return ((float)atan((double)_X)); }
+inline float atan2f(float _X, float _Y) {return ((float)atan2((double)_X, (double)_Y)); }
+inline float ceilf(float _X) {return ((float)ceil((double)_X)); }
+inline float cosf(float _X) {return ((float)cos((double)_X)); }
+inline float coshf(float _X) {return ((float)cosh((double)_X)); }
+inline float expf(float _X) {return ((float)exp((double)_X)); }
+inline float fabsf(float _X) {return ((float)fabs((double)_X)); }
+inline float floorf(float _X) {return ((float)floor((double)_X)); }
+inline float fmodf(float _X, float _Y) {return ((float)fmod((double)_X, (double)_Y)); }
+inline float logf(float _X) {return ((float)log((double)_X)); }
+inline float log10f(float _X) {return ((float)log10((double)_X)); }
+inline float powf(float _X, float _Y) {return ((float)pow((double)_X, (double)_Y)); }
+inline float sinf(float _X) {return ((float)sin((double)_X)); }
+inline float sinhf(float _X) {return ((float)sinh((double)_X)); }
+inline float sqrtf(float _X) {return ((float)sqrt((double)_X)); }
+inline float tanf(float _X) {return ((float)tan((double)_X)); }
+inline float tanhf(float _X) {return ((float)tanh((double)_X)); }
+#endif
+
+/** \defgroup math Math Utilities
+ * \par
+ * When converting between continuous and discrete use: \n
+ * Continuous = Discrete + 0.5 [Reconstruction/Interpolation] \n
+ * Discrete = Round(Continuous - 0.5) [Sampling/Quantization] \n
+ * \par
+ * Notice that must check 0-max limits when converting from Continuous to Discrete.
+ * \par
+ * When converting between discrete and discrete use: \n
+ * integer src_size, dst_len, src_i, dst_i \n
+ * real factor = (real)(dst_size)/(real)(src_size) \n
+ * dst_i = Round(factor*(src_i + 0.5) - 0.5)
+ * \par
+ * See \ref im_math.h
+ * \ingroup util */
+
+
+/** Round a real to the nearest integer.
+ * \ingroup math */
+inline int imRound(float x)
+{
+ return (int)(x < 0? x-0.5f: x+0.5f);
+}
+inline int imRound(double x)
+{
+ return (int)(x < 0? x-0.5: x+0.5);
+}
+
+/** Converts between two discrete grids.
+ * factor is "dst_size/src_size".
+ * \ingroup math */
+inline int imResample(int x, float factor)
+{
+ float xr = factor*(x + 0.5f) - 0.5f;
+ return (int)(xr < 0? xr-0.5f: xr+0.5f); /* Round */
+}
+
+/** Does Zero Order Decimation (Mean).
+ * \ingroup math */
+template <class T, class TU>
+inline T imZeroOrderDecimation(int width, int height, T *map, float xl, float yl, float box_width, float box_height, TU Dummy)
+{
+ int x0,x1,y0,y1;
+ (void)Dummy;
+
+ x0 = (int)floor(xl - box_width/2.0 - 0.5) + 1;
+ y0 = (int)floor(yl - box_height/2.0 - 0.5) + 1;
+ x1 = (int)floor(xl + box_width/2.0 - 0.5);
+ y1 = (int)floor(yl + box_height/2.0 - 0.5);
+
+ if (x0 == x1) x1++;
+ if (y0 == y1) y1++;
+
+ x0 = x0<0? 0: x0>width-1? width-1: x0;
+ y0 = y0<0? 0: y0>height-1? height-1: y0;
+ x1 = x1<0? 0: x1>width-1? width-1: x1;
+ y1 = y1<0? 0: y1>height-1? height-1: y1;
+
+ TU Value;
+ int Count = 0;
+
+ Value = 0;
+
+ for (int y = y0; y <= y1; y++)
+ {
+ for (int x = x0; x <= x1; x++)
+ {
+ Value += map[y*width+x];
+ Count++;
+ }
+ }
+
+ if (Count == 0)
+ {
+ Value = 0;
+ return (T)Value;
+ }
+
+ return (T)(Value/(float)Count);
+}
+
+/** Does Bilinear Decimation.
+ * \ingroup math */
+template <class T, class TU>
+inline T imBilinearDecimation(int width, int height, T *map, float xl, float yl, float box_width, float box_height, TU Dummy)
+{
+ int x0,x1,y0,y1;
+ (void)Dummy;
+
+ x0 = (int)floor(xl - box_width/2.0 - 0.5) + 1;
+ y0 = (int)floor(yl - box_height/2.0 - 0.5) + 1;
+ x1 = (int)floor(xl + box_width/2.0 - 0.5);
+ y1 = (int)floor(yl + box_height/2.0 - 0.5);
+
+ if (x0 == x1) x1++;
+ if (y0 == y1) y1++;
+
+ x0 = x0<0? 0: x0>width-1? width-1: x0;
+ y0 = y0<0? 0: y0>height-1? height-1: y0;
+ x1 = x1<0? 0: x1>width-1? width-1: x1;
+ y1 = y1<0? 0: y1>height-1? height-1: y1;
+
+ TU Value, LineValue;
+ float LineNorm, Norm, dxr, dyr;
+
+ Value = 0;
+ Norm = 0;
+
+ for (int y = y0; y <= y1; y++)
+ {
+ dyr = yl - (y+0.5f);
+ if (dyr < 0) dyr *= -1;
+
+ LineValue = 0;
+ LineNorm = 0;
+
+ for (int x = x0; x <= x1; x++)
+ {
+ dxr = xl - (x+0.5f);
+ if (dxr < 0) dxr *= -1;
+
+ LineValue += map[y*width+x] * dxr;
+ LineNorm += dxr;
+ }
+
+ Value += LineValue * dyr;
+ Norm += dyr * LineNorm;
+ }
+
+ if (Norm == 0)
+ {
+ Value = 0;
+ return (T)Value;
+ }
+
+ return (T)(Value/Norm);
+}
+
+/** Does Zero Order Interpolation (Nearest Neighborhood).
+ * \ingroup math */
+template <class T>
+inline T imZeroOrderInterpolation(int width, int height, T *map, float xl, float yl)
+{
+ int x0 = imRound(xl-0.5f);
+ int y0 = imRound(yl-0.5f);
+ x0 = x0<0? 0: x0>width-1? width-1: x0;
+ y0 = y0<0? 0: y0>height-1? height-1: y0;
+ return map[y0*width + x0];
+}
+
+/** Does Bilinear Interpolation.
+ * \ingroup math */
+template <class T>
+inline T imBilinearInterpolation(int width, int height, T *map, float xl, float yl)
+{
+ int x0, y0, x1, y1;
+ float t, u;
+
+ if (xl < 0.5)
+ {
+ x1 = x0 = 0;
+ t = 0;
+ }
+ else if (xl > width-0.5)
+ {
+ x1 = x0 = width-1;
+ t = 0;
+ }
+ else
+ {
+ x0 = (int)(xl-0.5f);
+ x1 = x0+1;
+ t = xl - (x0+0.5f);
+ }
+
+ if (yl < 0.5)
+ {
+ y1 = y0 = 0;
+ u = 0;
+ }
+ else if (yl > height-0.5)
+ {
+ y1 = y0 = height-1;
+ u = 0;
+ }
+ else
+ {
+ y0 = (int)(yl-0.5f);
+ y1 = y0+1;
+ u = yl - (y0+0.5f);
+ }
+
+ T fll = map[y0*width + x0];
+ T fhl = map[y0*width + x1];
+ T flh = map[y1*width + x0];
+ T fhh = map[y1*width + x1];
+
+ return (T)((fhh - flh - fhl + fll) * u * t +
+ (fhl - fll) * t +
+ (flh - fll) * u +
+ fll);
+}
+
+/** Does Bicubic Interpolation.
+ * \ingroup math */
+template <class T, class TU>
+inline T imBicubicInterpolation(int width, int height, T *map, float xl, float yl, TU Dummy)
+{
+ int X[4], Y[4];
+ float t, u;
+ (void)Dummy;
+
+ if (xl > width-0.5)
+ {
+ X[3] = X[2] = X[1] = width-1;
+ X[0] = X[1]-1;
+ t = 0;
+ }
+ else
+ {
+ X[1] = (int)(xl-0.5f);
+ if (X[1] < 0) X[1] = 0;
+
+ X[0] = X[1]-1;
+ X[2] = X[1]+1;
+ X[3] = X[1]+2;
+
+ if (X[0] < 0) X[0] = 0;
+ if (X[3] > width-1) X[3] = width-1;
+
+ t = xl - (X[1]+0.5f);
+ }
+
+ if (yl > height-0.5)
+ {
+ Y[3] = Y[2] = Y[1] = height-1;
+ Y[0] = Y[1]-1;
+ u = 0;
+ }
+ else
+ {
+ Y[1] = (int)(yl-0.5f);
+ if (Y[1] < 0) Y[1] = 0;
+
+ Y[0] = Y[1]-1;
+ Y[2] = Y[1]+1;
+ Y[3] = Y[1]+2;
+
+ if (Y[0] < 0) Y[0] = 0;
+ if (Y[3] > height-1) Y[3] = height-1;
+
+ u = yl - (Y[1]+0.5f);
+ }
+
+ float CX[4], CY[4];
+
+ // Optimize calculations
+ {
+ float c, c2, c3;
+
+#define C0 (-c3 + 2.0f*c2 - c)
+#define C1 ( c3 - 2.0f*c2 + 1.0f)
+#define C2 (-c3 + c2 + c)
+#define C3 ( c3 - c2)
+
+ c = t;
+ c2 = c*c; c3 = c2*c;
+ CX[0] = C0; CX[1] = C1; CX[2] = C2; CX[3] = C3;
+
+ c = u;
+ c2 = c*c; c3 = c2*c;
+ CY[0] = C0; CY[1] = C1; CY[2] = C2; CY[3] = C3;
+
+#undef C0
+#undef C1
+#undef C2
+#undef C3
+ }
+
+ TU LineValue, Value;
+ float LineNorm, Norm;
+
+ Value = 0;
+ Norm = 0;
+
+ for (int y = 0; y < 4; y++)
+ {
+ LineValue = 0;
+ LineNorm = 0;
+
+ for (int x = 0; x < 4; x++)
+ {
+ LineValue += map[Y[y]*width+X[x]] * CX[x];
+ LineNorm += CX[x];
+ }
+
+ Value += LineValue * CY[y];
+ Norm += CY[y] * LineNorm;
+ }
+
+ if (Norm == 0)
+ {
+ Value = 0;
+ return (T)Value;
+ }
+
+ Value = (Value/Norm);
+
+ int size = sizeof(T);
+ if (size == 1)
+ return (T)(Value<=(TU)0? (TU)0: Value<=(TU)255? Value: (TU)255);
+ else
+ return (T)(Value);
+}
+
+/** Calculates minimum and maximum values.
+ * \ingroup math */
+template <class T>
+inline void imMinMax(const T *map, int count, T& min, T& max)
+{
+ min = *map++;
+ max = min;
+ for (int i = 1; i < count; i++)
+ {
+ T value = *map++;
+
+ if (value > max)
+ max = value;
+ else if (value < min)
+ min = value;
+ }
+}
+
+#endif
diff --git a/include/im_math_op.h b/include/im_math_op.h
new file mode 100644
index 0000000..f410c62
--- /dev/null
+++ b/include/im_math_op.h
@@ -0,0 +1,219 @@
+/** \file
+ * \brief Math Operations
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_MATH_OP_H
+#define __IM_MATH_OP_H
+
+#include "im_complex.h"
+
+//#define IM_NEARZERO 0.0000001f
+//#define IM_NEARINF 10000000
+
+/// Crop value to Byte limit
+template <class T>
+inline T crop_byte(const T& v)
+{
+ return v <= 0? 0: v <= 255? v: 255;
+}
+
+/// Generic Addition with 2 template types
+template <class T1, class T2>
+inline T1 add_op(const T1& v1, const T2& v2)
+{
+ return v2 + v1;
+}
+
+/// Generic Subtraction with 2 template types
+template <class T1, class T2>
+inline T1 sub_op(const T1& v1, const T2& v2)
+{
+ return v2 - v1;
+}
+
+/// Generic Multiplication with 2 template types
+template <class T1, class T2>
+inline T1 mul_op(const T1& v1, const T2& v2)
+{
+ return v2 * v1;
+}
+
+/// Generic Division with 2 template types
+template <class T1, class T2>
+inline T1 div_op(const T1& v1, const T2& v2)
+{
+// if (v2 == 0) return (T1)IM_NEARINF;
+ return v1 / v2;
+}
+
+/// Generic Invert
+template <class T>
+inline T inv_op(const T& v)
+{
+// if (v == 0) return (T)IM_NEARINF;
+ return 1/v;
+}
+
+/// Generic Difference with 2 template types
+template <class T1, class T2>
+inline T1 diff_op(const T1& v1, const T2& v2)
+{
+ if (v1 <= v2)
+ return v2 - v1;
+ return v1 - v2;
+}
+
+/// Generic Minimum with 2 template types
+template <class T1, class T2>
+inline T1 min_op(const T1& v1, const T2& v2)
+{
+ if (v1 <= v2)
+ return v1;
+ return v2;
+}
+
+/// Generic Maximum with 2 template types
+template <class T1, class T2>
+inline T1 max_op(const T1& v1, const T2& v2)
+{
+ if (v1 <= v2)
+ return v2;
+ return v1;
+}
+
+inline imbyte pow_op(const imbyte& v1, const imbyte& v2)
+{
+ return (imbyte)pow((float)v1, v2);
+}
+
+inline imushort pow_op(const imushort& v1, const imushort& v2)
+{
+ return (imushort)pow((float)v1, v2);
+}
+
+inline int pow_op(const int& v1, const int& v2)
+{
+ return (int)pow((float)v1, v2);
+}
+
+/// Generic Power with 2 template types
+template <class T1, class T2>
+inline T1 pow_op(const T1& v1, const T2& v2)
+{
+ return (T1)pow(v1, v2);
+}
+
+/// Generic Abssolute
+template <class T>
+inline T abs_op(const T& v)
+{
+ if (v <= 0)
+ return -1*v;
+ return v;
+}
+
+/// Generic Less
+template <class T>
+inline T less_op(const T& v)
+{
+ return -1*v;
+}
+
+/// Generic Square
+template <class T>
+inline T sqr_op(const T& v)
+{
+ return v*v;
+}
+
+inline int sqrt(const int& C)
+{
+ return (int)sqrt(float(C));
+}
+
+/// Generic Square Root
+template <class T>
+inline T sqrt_op(const T& v)
+{
+ return (T)sqrt(v);
+}
+
+inline int exp(const int& v)
+{
+ return (int)exp((float)v);
+}
+
+/// Generic Exponential
+template <class T>
+inline T exp_op(const T& v)
+{
+ return (T)exp(v);
+}
+
+inline int log(const int& v)
+{
+ return (int)log((float)v);
+}
+
+/// Generic Logarithm
+template <class T>
+inline T log_op(const T& v)
+{
+// if (v <= 0) return (T)IM_NEARINF;
+ return (T)log(v);
+}
+
+// Dummy sin
+inline imcfloat sin(const imcfloat& v)
+{
+ return (v);
+}
+
+inline int sin(const int& v)
+{
+ return (int)sin((float)v);
+}
+
+/// Generic Sine
+template <class T>
+inline T sin_op(const T& v)
+{
+ return (T)sin(v);
+}
+
+inline int cos(const int& v)
+{
+ return (int)cos((float)v);
+}
+
+// Dummy cos
+inline imcfloat cos(const imcfloat& v)
+{
+ return (v);
+}
+
+/// Generic Cosine
+template <class T>
+inline T cos_op(const T& v)
+{
+ return (T)cos(v);
+}
+
+/// Sets a bit in an array
+inline void imDataBitSet(imbyte* data, int index, int bit)
+{
+ if (bit)
+ data[index / 8] |= (0x01 << (7 - (index % 8)));
+ else
+ data[index / 8] &= ~(0x01 << (7 - (index % 8)));
+}
+
+/// Gets a bit from an array
+inline int imDataBitGet(imbyte* data, int index)
+{
+ return (data[index / 8] >> (7 - (index % 8))) & 0x01;
+}
+
+#endif
diff --git a/include/im_palette.h b/include/im_palette.h
new file mode 100644
index 0000000..c7ed88c
--- /dev/null
+++ b/include/im_palette.h
@@ -0,0 +1,172 @@
+/** \file
+ * \brief Palette Generators
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PALETTE_H
+#define __IM_PALETTE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup palette Palette Generators
+ * \par
+ * Creates several standard palettes. The palette is just an array of encoded color values.
+ * See also \ref colorutl.
+ * \par
+ * In Lua, to create a palette you can call im.PaletteCreate.
+ * \verbatim im.PaletteCreate([count: number]) -> pal: imPalette [in Lua 5] \endverbatim
+ * Default count is 256.
+ * IMLua and CDLua palettes are 100% compatible. The IM palette metatable name is "imPalette". \n
+ * When converted to a string will return "imPalete(%p)" where %p is replaced by the userdata address.
+ * If the palette is already destroyed by im.PaletteDestroy, then it will return also the suffix "-destroyed".
+ * \par
+ * In Lua, to destroy a palette you can call im.PaletteDestroy.
+ * If this function is not called, the palette is destroyed by the garbage collector.
+ * \verbatim im.PaletteDestroy(pal: imPalette) [in Lua 5] \endverbatim
+ * \par
+ * In Lua, array access is enabled so you can do:.
+ * \verbatim color = pal[index] \endverbatim
+ * \verbatim pal[index] = color \endverbatim
+ * \verbatim count = #pal \endverbatim
+ * \par
+ * See \ref im_palette.h
+ * \ingroup util */
+
+
+/** Searches for the nearest color on the table and returns the color index if successful.
+ * It looks in all palette entries and finds the minimum euclidian square distance.
+ * If the color matches the given color it returns immediately.
+ * See also \ref colorutl.
+ *
+ * \verbatim im.PaletteFindNearest(pal: imPalette, color: lightuserdata) -> index: number [in Lua 5] \endverbatim
+ * \ingroup palette */
+int imPaletteFindNearest(const long *palette, int palette_count, long color);
+
+/** Searches for the color on the table and returns the color index if successful.
+ * If the tolerance is 0 search for the exact match in the palette else search for the
+ * first color that fits in the tolerance range.
+ * See also \ref colorutl.
+ *
+ * \verbatim im.PaletteFindColor(pal: imPalette, color: lightuserdata, tol: number) -> index: number [in Lua 5] \endverbatim
+ * \ingroup palette */
+int imPaletteFindColor(const long *palette, int palette_count, long color, unsigned char tol);
+
+/** Creates a palette of gray scale values.
+ * The colors are arranged from black to white.
+ *
+ * \verbatim im.PaletteGray() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteGray(void);
+
+/** Creates a palette of a gradient of red colors.
+ * The colors are arranged from black to pure red.
+ *
+ * \verbatim im.PaletteRed() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteRed(void);
+
+/** Creates a palette of a gradient of green colors.
+ * The colors are arranged from black to pure green.
+ *
+ * \verbatim im.PaletteGreen() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteGreen(void);
+
+/** Creates a palette of a gradient of blue colors.
+ * The colors are arranged from black to pure blue.
+ *
+ * \verbatim im.PaletteBlue() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteBlue(void);
+
+/** Creates a palette of a gradient of yellow colors.
+ * The colors are arranged from black to pure yellow.
+ *
+ * \verbatim im.PaletteYellow() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteYellow(void);
+
+/** Creates a palette of a gradient of magenta colors.
+ * The colors are arranged from black to pure magenta.
+ *
+ * \verbatim im.PaletteMagenta() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteMagenta(void);
+
+/** Creates a palette of a gradient of cian colors.
+ * The colors are arranged from black to pure cian.
+ *
+ * \verbatim im.PaletteCian() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteCian(void);
+
+/** Creates a palette of rainbow colors.
+ * The colors are arranged in the light wave length spectrum order (starting from purple).
+ *
+ * \verbatim im.PaletteRainbow() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteRainbow(void);
+
+/** Creates a palette of hues with maximum saturation.
+ *
+ * \verbatim im.PaletteHues() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteHues(void);
+
+/** Creates a palette of a gradient of blue colors.
+ * The colors are arranged from pure blue to white.
+ *
+ * \verbatim im.PaletteBlueIce() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteBlueIce(void);
+
+/** Creates a palette of a gradient from black to white passing trough red and orange.
+ *
+ * \verbatim im.PaletteHotIron() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteHotIron(void);
+
+/** Creates a palette of a gradient from black to white passing trough red and yellow.
+ *
+ * \verbatim im.PaletteBlackBody() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteBlackBody(void);
+
+/** Creates a palette with high contrast colors.
+ *
+ * \verbatim im.PaletteHighContrast() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteHighContrast(void);
+
+/** Creates a palette of an uniform range of colors from black to white.
+ * This is a 2^(2.6) bits per pixel palette.
+ *
+ * \verbatim im.PaletteUniform() -> pal: imPalette [in Lua 5] \endverbatim
+ * \ingroup palette */
+long* imPaletteUniform(void);
+
+/** Returns the index of the correspondent RGB color of an uniform palette.
+ *
+ * \verbatim im.PaletteUniformIndex(color: lightuserdata) -> index: number [in Lua 5] \endverbatim
+ * \ingroup palette */
+int imPaletteUniformIndex(long color);
+
+/** Returns the index of the correspondent RGB color of an uniform palette.
+ * Uses an 8x8 ordered dither to lookup the index in a halftone matrix.
+ * The spatial position used by the halftone method.
+ *
+ * \verbatim im.PaletteUniformIndexHalftoned(color: lightuserdata, x: number, y: number) -> index: number [in Lua 5] \endverbatim
+ * \ingroup palette */
+int imPaletteUniformIndexHalftoned(long color, int x, int y);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/include/im_plus.h b/include/im_plus.h
new file mode 100644
index 0000000..0aabd1f
--- /dev/null
+++ b/include/im_plus.h
@@ -0,0 +1,73 @@
+/** \file
+ * \brief C++ Wrapper for File Access
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PLUS_H
+#define __IM_PLUS_H
+
+
+/** \brief C++ Wrapper for the Image File Structure
+ *
+ * \par
+ * Usage is just like the C API. Open and New are replaced by equivalent constructors. \n
+ * Close is replaced by the destructor. Error checking is done by the Error() member. \n
+ * Open and New errors are cheked using the Failed() member.
+ * \ingroup file */
+class imImageFile
+{
+ imFile* ifile;
+ int error;
+
+ imImageFile() {};
+
+public:
+
+ imImageFile(const char* file_name)
+ { this->ifile = imFileOpen(file_name, &this->error); }
+
+ imImageFile(const char* file_name, const char* format)
+ { this->ifile = imFileNew(file_name, format, &this->error); }
+
+ ~imImageFile()
+ { if (this->ifile) imFileClose(this->ifile); }
+
+ int Failed()
+ { return this->ifile == 0; }
+
+ int Error()
+ { return this->error; }
+
+ void SetAttribute(const char* attrib, int data_type, int count, const void* data)
+ { imFileSetAttribute(this->ifile, attrib, data_type, count, data); }
+
+ const void* GetAttribute(const char* attrib, int *data_type, int *count)
+ { return imFileGetAttribute(this->ifile, attrib, data_type, count); }
+
+ void GetInfo(char* format, char* compression, int *image_count)
+ { imFileGetInfo(this->ifile, format, compression, image_count); }
+
+ void ReadImageInfo(int index, int *width, int *height, int *color_mode, int *data_type)
+ { this->error = imFileReadImageInfo(this->ifile, index, width, height, color_mode, data_type); }
+
+ void GetPalette(long* palette, int *palette_count)
+ { imFileGetPalette(this->ifile, palette, palette_count); }
+
+ void ReadImageData(void* data, int convert2bitmap, int color_mode_flags)
+ { this->error = imFileReadImageData(this->ifile, data, convert2bitmap, color_mode_flags); }
+
+ void SetInfo(const char* compression)
+ { imFileSetInfo(this->ifile, compression); }
+
+ void SetPalette(long* palette, int palette_count)
+ { imFileSetPalette(this->ifile, palette, palette_count); }
+
+ void WriteImageInfo(int width, int height, int color_mode, int data_type)
+ { this->error = imFileWriteImageInfo(this->ifile, width, height, color_mode, data_type); }
+
+ void WriteImageData(void* data)
+ { this->error = imFileWriteImageData(this->ifile, data); }
+};
+
+#endif
diff --git a/include/im_process.h b/include/im_process.h
new file mode 100644
index 0000000..e0d3d6c
--- /dev/null
+++ b/include/im_process.h
@@ -0,0 +1,35 @@
+/** \file
+ * \brief Image Processing
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PROCESS_H
+#define __IM_PROCESS_H
+
+#include "im_process_pon.h"
+#include "im_process_loc.h"
+#include "im_process_glo.h"
+#include "im_process_ana.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup process Image Processing
+ * \par
+ * Several image processing functions based on the \ref imImage structure.
+ * \par
+ * You must link the application with "im_process.lib/.a/.so". \n
+ * Some complex operations use the \ref counter.\n
+ * There is no check on the input/output image properties,
+ * check each function documentation before using it.
+ */
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_process_ana.h b/include/im_process_ana.h
new file mode 100644
index 0000000..2458be3
--- /dev/null
+++ b/include/im_process_ana.h
@@ -0,0 +1,221 @@
+/** \file
+ * \brief Image Statistics and Analysis
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PROC_ANA_H
+#define __IM_PROC_ANA_H
+
+#include "im_image.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** \defgroup stats Image Statistics Calculations
+ * \par
+ * Operations to calculate some statistics over images.
+ * \par
+ * See \ref im_process_ana.h
+ * \ingroup process */
+
+/** Calculates the RMS error between two images (Root Mean Square Error).
+ *
+ * \verbatim im.CalcRMSError(image1: imImage, image2: imImage) -> rms: number [in Lua 5] \endverbatim
+ * \ingroup stats */
+float imCalcRMSError(const imImage* image1, const imImage* image2);
+
+/** Calculates the SNR of an image and its noise (Signal Noise Ratio).
+ *
+ * \verbatim im.CalcSNR(src_image: imImage, noise_image: imImage) -> snr: number [in Lua 5] \endverbatim
+ * \ingroup stats */
+float imCalcSNR(const imImage* src_image, const imImage* noise_image);
+
+/** Count the number of different colors in an image. \n
+ * Image must be IM_BYTE, but all color spaces except IM_CMYK.
+ *
+ * \verbatim im.CalcCountColors(image: imImage) -> count: number [in Lua 5] \endverbatim
+ * \ingroup stats */
+unsigned long imCalcCountColors(const imImage* image);
+
+/** Calculates the histogram of a IM_BYTE data. \n
+ * Histogram is always 256 positions long. \n
+ * When cumulative is different from zero it calculates the cumulative histogram.
+ *
+ * \verbatim im.CalcHistogram(image: imImage, plane: number, cumulative: number) -> histo: table of numbers [in Lua 5] \endverbatim
+ * Where plane is the depth plane to calculate the histogram. \n
+ * The returned table is zero indexed. image can be IM_USHORT or IM_BYTE.
+ * \ingroup stats */
+void imCalcHistogram(const unsigned char* data, int count, unsigned long* histo, int cumulative);
+
+/** Calculates the histogram of a IM_USHORT data. \n
+ * Histogram is always 65535 positions long. \n
+ * When cumulative is different from zero it calculates the cumulative histogram. \n
+ * Use \ref imCalcHistogram in Lua.
+ * \ingroup stats */
+void imCalcUShortHistogram(const unsigned short* data, int count, unsigned long* histo, int cumulative);
+
+/** Calculates the gray histogram of an image. \n
+ * Image must be IM_BYTE/(IM_RGB, IM_GRAY, IM_BINARY or IM_MAP). \n
+ * If the image is IM_RGB then the histogram of the luma component is calculated. \n
+ * Histogram is always 256 positions long. \n
+ * When cumulative is different from zero it calculates the cumulative histogram.
+ *
+ * \verbatim im.CalcGrayHistogram(image: imImage, cumulative: number) -> histo: table of numbers [in Lua 5] \endverbatim
+ * \ingroup stats */
+void imCalcGrayHistogram(const imImage* image, unsigned long* histo, int cumulative);
+
+/** Numerical Statistics Structure
+ * \ingroup stats */
+typedef struct _imStats
+{
+ float max; /**< Maximum value */
+ float min; /**< Minimum value */
+ unsigned long positive; /**< Number of Positive Values */
+ unsigned long negative; /**< Number of Negative Values */
+ unsigned long zeros; /**< Number of Zeros */
+ float mean; /**< Mean */
+ float stddev; /**< Standard Deviation */
+} imStats;
+
+/** Calculates the statistics about the image data. \n
+ * There is one stats for each depth plane. For ex: stats[0]=red stats, stats[0]=green stats, ... \n
+ * Supports all data types except IM_CFLOAT. \n
+ *
+ * \verbatim im.CalcImageStatistics(image: imImage) -> stats: table [in Lua 5] \endverbatim
+ * Table contains the following fields: max, min, positive, negative, zeros, mean, stddev.
+ * The same as the \ref imStats structure.
+ * \ingroup stats */
+void imCalcImageStatistics(const imImage* image, imStats* stats);
+
+/** Calculates the statistics about the image histogram data.\n
+ * There is one stats for each depth plane. For ex: stats[0]=red stats, stats[0]=green stats, ... \n
+ * Only IM_BYTE images are supported.
+ *
+ * \verbatim im.CalcHistogramStatistics(image: imImage) -> stats: table [in Lua 5] \endverbatim
+ * \ingroup stats */
+void imCalcHistogramStatistics(const imImage* image, imStats* stats);
+
+/** Calculates some extra statistics about the image histogram data.\n
+ * There is one stats for each depth plane. \n
+ * Only IM_BYTE images are supported. \n
+ * mode will be -1 if more than one max is found.
+ *
+ * \verbatim im.CalcHistoImageStatistics(image: imImage) -> median: number, mode: number [in Lua 5] \endverbatim
+ * \ingroup stats */
+void imCalcHistoImageStatistics(const imImage* image, int* median, int* mode);
+
+
+
+/** \defgroup analyze Image Analysis
+ * \par
+ * See \ref im_process_ana.h
+ * \ingroup process */
+
+/** Find white regions in binary image. \n
+ * Result is IM_GRAY/IM_USHORT type. Regions can be 4 connected or 8 connected. \n
+ * Returns the number of regions found. Background is marked as 0. \n
+ * Regions touching the border are considered only if touch_border=1.
+ *
+ * \verbatim im.AnalyzeFindRegions(src_image: imImage, dst_image: imImage, connect: number, touch_border: number) -> count: number [in Lua 5] \endverbatim
+ * \verbatim im.AnalyzeFindRegionsNew(image: imImage, connect: number, touch_border: number) -> count: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup analyze */
+int imAnalyzeFindRegions(const imImage* src_image, imImage* dst_image, int connect, int touch_border);
+
+/** Measure the actual area of all regions. Holes are not included. \n
+ * This is the number of pixels of each region. \n
+ * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
+ * area has size the number of regions.
+ *
+ * \verbatim im.AnalyzeMeasureArea(image: imImage, [region_count: number]) -> area: table of numbers [in Lua 5] \endverbatim
+ * The returned table is zero indexed.
+ * \ingroup analyze */
+void imAnalyzeMeasureArea(const imImage* image, int* area, int region_count);
+
+/** Measure the polygonal area limited by the perimeter line of all regions. Holes are not included. \n
+ * Notice that some regions may have polygonal area zero. \n
+ * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
+ * perimarea has size the number of regions.
+ *
+ * \verbatim im.AnalyzeMeasurePerimArea(image: imImage, [region_count: number]) -> perimarea: table of numbers [in Lua 5] \endverbatim
+ * The returned table is zero indexed.
+ * \ingroup analyze */
+void imAnalyzeMeasurePerimArea(const imImage* image, float* perimarea);
+
+/** Calculate the centroid position of all regions. Holes are not included. \n
+ * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
+ * area, cx and cy have size the number of regions. If area is NULL will be internally calculated.
+ *
+ * \verbatim im.AnalyzeMeasureCentroid(image: imImage, [area: table of numbers], [region_count: number]) -> cx: table of numbers, cy: table of numbers [in Lua 5] \endverbatim
+ * The returned tables are zero indexed.
+ * \ingroup analyze */
+void imAnalyzeMeasureCentroid(const imImage* image, const int* area, int region_count, float* cx, float* cy);
+
+/** Calculate the principal major axis slope of all regions. \n
+ * Source image is IM_GRAY/IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
+ * data has size the number of regions. If area or centroid are NULL will be internally calculated. \n
+ * Principal (major and minor) axes are defined to be those axes that pass through the
+ * centroid, about which the moment of inertia of the region is, respectively maximal or minimal.
+ *
+ * \verbatim im.AnalyzeMeasurePrincipalAxis(image: imImage, [area: table of numbers], [cx: table of numbers], [cy: table of numbers], [region_count: number])
+ -> major_slope: table of numbers, major_length: table of numbers, minor_slope: table of numbers, minor_length: table of numbers [in Lua 5] \endverbatim
+ * The returned tables are zero indexed.
+ * \ingroup analyze */
+void imAnalyzeMeasurePrincipalAxis(const imImage* image, const int* area, const float* cx, const float* cy,
+ const int region_count, float* major_slope, float* major_length,
+ float* minor_slope, float* minor_length);
+
+/** Measure the number and area of holes of all regions. \n
+ * Source image is IM_USHORT type (the result of \ref imAnalyzeFindRegions). \n
+ * area and perim has size the number of regions, if some is NULL it will be not calculated.
+ *
+ * \verbatim im.AnalyzeMeasureHoles(image: imImage, connect: number, [region_count: number]) -> holes_count: number, area: table of numbers, perim: table of numbers [in Lua 5] \endverbatim
+ * The returned tables are zero indexed.
+ * \ingroup analyze */
+void imAnalyzeMeasureHoles(const imImage* image, int connect, int *holes_count, int* area, float* perim);
+
+/** Measure the total perimeter of all regions (external and internal). \n
+ * Source image is IM_GRAY/IM_USHORT type (the result of imAnalyzeFindRegions). \n
+ * It uses a half-pixel inter distance for 8 neighboors in a perimeter of a 4 connected region. \n
+ * This function can also be used to measure line lenght. \n
+ * perim has size the number of regions.
+ *
+ * \verbatim im.AnalyzeMeasurePerimeter(image: imImage) -> perim: table of numbers [in Lua 5] \endverbatim
+ * \ingroup analyze */
+void imAnalyzeMeasurePerimeter(const imImage* image, float* perim, int region_count);
+
+/** Isolates the perimeter line of gray integer images. Background is defined as being black (0). \n
+ * It just checks if at least one of the 4 connected neighboors is non zero. Image borders are extended with zeros.
+ *
+ * \verbatim im.ProcessPerimeterLine(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPerimeterLineNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup analyze */
+void imProcessPerimeterLine(const imImage* src_image, imImage* dst_image);
+
+/** Eliminates regions that have size outside the given interval. \n
+ * Source and destiny are a binary images. Regions can be 4 connected or 8 connected. \n
+ * Can be done in-place. end_size can be zero to ignore big objects.
+ *
+ * \verbatim im.ProcessPrune(src_image: imImage, dst_image: imImage, connect: number, start_size: number, end_size: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPruneNew(image: imImage, connect: number, start_size: number, end_size: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup analyze */
+void imProcessPrune(const imImage* src_image, imImage* dst_image, int connect, int start_size, int end_size);
+
+/** Fill holes inside white regions. \n
+ * Source and destiny are a binary images. Regions can be 4 connected or 8 connected. \n
+ * Can be done in-place.
+ *
+ * \verbatim im.ProcessFillHoles(src_image: imImage, dst_image: imImage, connect: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessFillHolesNew(image: imImage, connect: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup analyze */
+void imProcessFillHoles(const imImage* src_image, imImage* dst_image, int connect);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_process_glo.h b/include/im_process_glo.h
new file mode 100644
index 0000000..fc6dba8
--- /dev/null
+++ b/include/im_process_glo.h
@@ -0,0 +1,170 @@
+/** \file
+ * \brief Image Processing - Global Operations
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PROCESS_GLO_H
+#define __IM_PROCESS_GLO_H
+
+#include "im_image.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** \defgroup transform Other Domain Transform Operations
+ * \par
+ * Hough, Distance.
+ *
+ * See \ref im_process_glo.h
+ * \ingroup process */
+
+/** Hough Lines Transform. \n
+ * It will detect white lines in a black background. So the source image must be a IM_BINARY image
+ * with the white lines of interest enhanced. The better the threshold with the white lines the better
+ * the line detection. \n
+ * The destiny image must have IM_GRAY, IM_INT, hg_width=180, hg_height=2*rmax+1,
+ * where rmax is the image diagonal/2 (rmax = srqrt(width*width + height*height)). \n
+ * The hough transform defines "cos(theta) * X + sin(theta) * Y = rho" and the parameters are in the interval: \n
+ * theta = "0 .. 179", rho = "-hg_height/2 .. hg_height/2" .\n
+ * Where rho is the perpendicular distance from the center of the image and theta the angle with the normal.
+ * So do not confuse theta with the line angle, they are perpendicular. \n
+ * Returns zero if the counter aborted. \n
+ * Inspired from ideas in XITE, Copyright 1991, Blab, UiO \n
+ * http://www.ifi.uio.no/~blab/Software/Xite/
+ *
+ * \verbatim im.ProcessHoughLines(src_image: imImage, dst_image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessHoughLinesNew(image: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+int imProcessHoughLines(const imImage* src_image, imImage* dst_image);
+
+/** Draw detected hough lines. \n
+ * The source image must be IM_GRAY and IM_BYTE. The destiny image can be a clone of the source image or
+ * it can be the source image for in place processing. \n
+ * If the hough transform is not NULL, then the hough points are filtered to include only lines
+ * that are significally different from each other. \n
+ * The hough image is the hough transform image, but it is optional and can be NULL.
+ * If not NULL then it will be used to filter lines that are very similar. \n
+ * The hough points image is a hough transform image that was thresholded to a IM_BINARY image,
+ * usually using a Local Max threshold operation (see \ref imProcessLocalMaxThreshold). Again the better the threshold the better the results. \n
+ * The destiny image will be set to IM_MAP, and the detected lines will be drawn using a red color. \n
+ * Returns the number of detected lines.
+ *
+ * \verbatim im.ProcessHoughLinesDraw(src_image: imImage, hough: imImage, hough_points: imImage, dst_image: imImage) -> lines: number [in Lua 5] \endverbatim
+ * \verbatim im.ProcessHoughLinesDrawNew(image: imImage, hough: imImage, hough_points: imImage) -> lines: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+int imProcessHoughLinesDraw(const imImage* src_image, const imImage* hough, const imImage* hough_points, imImage* dst_image);
+
+/** Calculates the Cross Correlation in the frequency domain. \n
+ * CrossCorr(a,b) = IFFT(Conj(FFT(a))*FFT(b)) \n
+ * Images must be of the same size and only destiny image must be of type complex.
+ *
+ * \verbatim im.ProcessCrossCorrelation(src_image1: imImage, src_image2: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessCrossCorrelationNew(image1: imImage, image2: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+void imProcessCrossCorrelation(const imImage* src_image1, const imImage* src_image2, imImage* dst_image);
+
+/** Calculates the Auto Correlation in the frequency domain. \n
+ * Uses the cross correlation.
+ * Images must be of the same size and only destiny image must be of type complex.
+ *
+ * \verbatim im.ProcessAutoCorrelation(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessAutoCorrelationNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+void imProcessAutoCorrelation(const imImage* src_image, imImage* dst_image);
+
+/** Calculates the Distance Transform of a binary image
+ * using an aproximation of the euclidian distance.\n
+ * Each white pixel in the binary image is
+ * assigned a value equal to its distance from the nearest
+ * black pixel. \n
+ * Uses a two-pass algorithm incrementally calculating the distance. \n
+ * Source image must be IM_BINARY, destiny must be IM_FLOAT.
+ *
+ * \verbatim im.ProcessDistanceTransform(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessDistanceTransformNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+void imProcessDistanceTransform(const imImage* src_image, imImage* dst_image);
+
+/** Marks all the regional maximum of the distance transform. \n
+ * source is IMGRAY/IM_FLOAT destiny in IM_BINARY. \n
+ * We consider maximum all connected pixel values that have smaller pixel values around it.
+ *
+ * \verbatim im.ProcessRegionalMaximum(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRegionalMaximumNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup transform */
+void imProcessRegionalMaximum(const imImage* src_image, imImage* dst_image);
+
+
+
+/** \defgroup fourier Fourier Transform Operations
+ * \par
+ * All Fourier transforms use FFTW library version 2.1.5. \n
+ * Although there are newer versions, we build binaries only to version 2
+ * because it is small and as fast as newer versions.
+ * Source code to use FFTW version 3 is available.
+ * \par
+ * FFTW Copyright Matteo Frigo, Steven G. Johnson and the MIT. \n
+ * http://www.fftw.org \n
+ * See "fftw.h"
+ * \par
+ * Must link with "im_fftw" library. \n
+ * \par
+ * The FFTW lib has a GPL license. The license of the "im_fftw" library is automatically the GPL.
+ * So you cannot use it for commercial applications without contacting the authors.
+ * \par
+ * See \ref im_process_glo.h
+ * \ingroup process */
+
+/** Forward FFT. \n
+ * The result has its lowest frequency at the center of the image. \n
+ * This is an unnormalized fft. \n
+ * Images must be of the same size. Destiny image must be of type complex.
+ *
+ * \verbatim im.ProcessFFT(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessFFTNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup fourier */
+void imProcessFFT(const imImage* src_image, imImage* dst_image);
+
+/** Inverse FFT. \n
+ * The image has its lowest frequency restored to the origin before the transform. \n
+ * The result is normalized by (width*height). \n
+ * Images must be of the same size and both must be of type complex.
+ *
+ * \verbatim im.ProcessIFFT(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessIFFTNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup fourier */
+void imProcessIFFT(const imImage* src_image, imImage* dst_image);
+
+/** Raw in-place FFT (forward or inverse). \n
+ * The lowest frequency can be centered after forward, or
+ * can be restored to the origin before inverse. \n
+ * The result can be normalized after the transform by sqrt(w*h) [1] or by (w*h) [2],
+ * or left unnormalized [0]. \n
+ * Images must be of the same size and both must be of type complex.
+ *
+ * \verbatim im.ProcessFFTraw(image: imImage, inverse: number, center: number, normalize: number) [in Lua 5] \endverbatim
+ * \ingroup fourier */
+void imProcessFFTraw(imImage* image, int inverse, int center, int normalize);
+
+/** Auxiliary function for the raw FFT. \n
+ * This is the function used internally to change the lowest frequency position in the image. \n
+ * If the image size has even dimensions the flag "center2origin" is useless. But if it is odd,
+ * you must specify if its from center to origin (usually used before inverse) or
+ * from origin to center (usually used after forward). \n
+ * Notice that this function is used for images in the the frequency domain. \n
+ * Image type must be complex.
+ *
+ * \verbatim im.ProcessSwapQuadrants(image: imImage, center2origin: number) [in Lua 5] \endverbatim
+ * \ingroup fourier */
+void imProcessSwapQuadrants(imImage* image, int center2origin);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_process_loc.h b/include/im_process_loc.h
new file mode 100644
index 0000000..9c0531b
--- /dev/null
+++ b/include/im_process_loc.h
@@ -0,0 +1,577 @@
+/** \file
+ * \brief Image Processing - Local Operations
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PROCESS_LOC_H
+#define __IM_PROCESS_LOC_H
+
+#include "im_image.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** \defgroup resize Image Resize
+ * \par
+ * Operations to change the image size.
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Only reduze the image size using the given decimation order. \n
+ * Supported decimation orders:
+ * \li 0 - zero order (mean)
+ * \li 1 - first order (bilinear decimation)
+ * Images must be of the same type. If image type is IM_MAP or IM_BINARY, must use order=0. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessReduce(src_image: imImage, dst_image: imImage, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessReduceNew(image: imImage, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+int imProcessReduce(const imImage* src_image, imImage* dst_image, int order);
+
+/** Change the image size using the given interpolation order. \n
+ * Supported interpolation orders:
+ * \li 0 - zero order (near neighborhood)
+ * \li 1 - first order (bilinear interpolation)
+ * \li 3 - third order (bicubic interpolation)
+ * Images must be of the same type. If image type is IM_MAP or IM_BINARY, must use order=0. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessResize(src_image: imImage, dst_image: imImage, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessResizeNew(image: imImage, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+int imProcessResize(const imImage* src_image, imImage* dst_image, int order);
+
+/** Reduze the image area by 4 (w/2,h/2). \n
+ * Images must be of the same type. Destiny image size must be source image width/2, height/2.
+ * Can not operate on IM_MAP nor IM_BINARY images.
+ *
+ * \verbatim im.ProcessReduceBy4(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessReduceBy4New(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+void imProcessReduceBy4(const imImage* src_image, imImage* dst_image);
+
+/** Extract a rectangular region from an image. \n
+ * Images must be of the same type. Destiny image size must be smaller than source image width-xmin, height-ymin. \n
+ * ymin and xmin must be >0 and <size.
+ *
+ * \verbatim im.ProcessCrop(src_image: imImage, dst_image: imImage, xmin: number, ymin: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessCropNew(image: imImage, xmin: number, xmax: number, ymin: number, ymax: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+void imProcessCrop(const imImage* src_image, imImage* dst_image, int xmin, int ymin);
+
+/** Insert a rectangular region in an image. \n
+ * Images must be of the same type. Region image size can be larger than source image. \n
+ * ymin and xmin must be >0 and <size. \n
+ * Source and destiny must be of the same size. Can be done in place.
+ *
+ * \verbatim im.ProcessInsert(src_image: imImage, region_image: imImage, dst_image: imImage, xmin: number, ymin: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessInsertNew(image: imImage, region_image: imImage, xmin: number, ymin: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+void imProcessInsert(const imImage* src_image, const imImage* region_image, imImage* dst_image, int xmin, int ymin);
+
+/** Increase the image size by adding pixels with zero value. \n
+ * Images must be of the same type. Destiny image size must be greatter than source image width+xmin, height+ymin.
+ *
+ * \verbatim im.ProcessAddMargins(src_image: imImage, dst_image: imImage, xmin: number, ymin: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessAddMarginsNew(image: imImage, xmin: number, xmax: number, ymin: number, ymax: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup resize */
+void imProcessAddMargins(const imImage* src_image, imImage* dst_image, int xmin, int ymin);
+
+
+
+/** \defgroup geom Geometric Operations
+ * \par
+ * Operations to change the shape of the image.
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Calculates the size of the new image after rotation.
+ *
+ * \verbatim im.ProcessCalcRotateSize(width: number, height: number, cos0: number, sin0: number) [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessCalcRotateSize(int width, int height, int *new_width, int *new_height, double cos0, double sin0);
+
+/** Rotates the image using the given interpolation order (see \ref imProcessResize). \n
+ * Images must be of the same type. The destiny size can be calculated using \ref imProcessCalcRotateSize to fit the new image size,
+ * or can be any size, including the original size. The rotation is relative to the center of the image. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRotate(src_image: imImage, dst_image: imImage, cos0: number, sin0: number, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRotateNew(image: imImage, cos0: number, sin0: number, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+int imProcessRotate(const imImage* src_image, imImage* dst_image, double cos0, double sin0, int order);
+
+/** Rotates the image using the given interpolation order (see \ref imProcessResize). \n
+ * Images must be of the same type. Destiny can have any size, including the original size. \n
+ * The rotation is relative to the reference point. But the result can be shifted to the origin. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRotateRef(src_image: imImage, dst_image: imImage, cos0: number, sin0: number, x: number, y: number, to_origin: boolean, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRotateRefNew(image: imImage, cos0: number, sin0: number, x: number, y: number, to_origin: boolean, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+int imProcessRotateRef(const imImage* src_image, imImage* dst_image, double cos0, double sin0, int x, int y, int to_origin, int order);
+
+/** Rotates the image in 90 degrees counterclockwise or clockwise. Swap columns by lines. \n
+ * Images must be of the same type. Destiny width and height must be source height and width. \n
+ * Direction can be clockwise (1) or counter clockwise (-1).
+ *
+ * \verbatim im.ProcessRotate90(src_image: imImage, dst_image: imImage, dir_clockwise: boolean) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRotate90New(image: imImage, dir_clockwise: boolean) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessRotate90(const imImage* src_image, imImage* dst_image, int dir_clockwise);
+
+/** Rotates the image in 180 degrees. Swap columns and swap lines. \n
+ * Images must be of the same type and size.
+ *
+ * \verbatim im.ProcessRotate180(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRotate180New(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessRotate180(const imImage* src_image, imImage* dst_image);
+
+/** Mirror the image in a horizontal flip. Swap columns. \n
+ * Images must be of the same type and size.
+ * Can be done in-place.
+ *
+ * \verbatim im.ProcessMirror(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMirrorNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessMirror(const imImage* src_image, imImage* dst_image);
+
+/** Apply a vertical flip. Swap lines. \n
+ * Images must be of the same type and size.
+ * Can be done in-place.
+ *
+ * \verbatim im.ProcessFlip(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessFlipNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessFlip(const imImage* src_image, imImage* dst_image);
+
+/** Apply a radial distortion using the given interpolation order (see imProcessResize). \n
+ * Images must be of the same type and size. Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRadial(src_image: imImage, dst_image: imImage, k1: number, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRadialNew(image: imImage, k1: number, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+int imProcessRadial(const imImage* src_image, imImage* dst_image, float k1, int order);
+
+/** Apply a swirl distortion using the given interpolation order (see imProcessResize). \n
+ * Images must be of the same type and size. Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessSwirl(src_image: imImage, dst_image: imImage, k: number, order: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSwirlNew(image: imImage, k: number, order: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+int imProcessSwirl(const imImage* src_image, imImage* dst_image, float k1, int order);
+
+/** Split the image in two images, one containing the odd lines and other containing the even lines. \n
+ * Images must be of the same type. Height of the output images must be half the height of the input image.
+ * If the height of the input image is odd then the first image must have height equals to half+1.
+ *
+ * \verbatim im.ProcessInterlaceSplit(src_image: imImage, dst_image1: imImage, dst_image2: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessInterlaceSplitNew(image: imImage) -> new_image1: imImage, new_image2: imImage [in Lua 5] \endverbatim
+ * \ingroup geom */
+void imProcessInterlaceSplit(const imImage* src_image, imImage* dst_image1, imImage* dst_image2);
+
+
+
+/** \defgroup morphgray Morphology Operations for Gray Images
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Base gray morphology convolution. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images. \n
+ * Kernel is always IM_INT. Use kernel size odd for better results. \n
+ * Use -1 for don't care positions in kernel. Kernel values are added to image values, then \n
+ * you can use the maximum or the minimum within the kernel area. \n
+ * No border extensions are used.
+ * All the gray morphology operations use this function. \n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessGrayMorphConvolve(src_image: imImage, dst_image: imImage, kernel: imImage, ismax: boolean) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphConvolveNew(image: imImage, kernel: imImage, ismax: boolean) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphConvolve(const imImage* src_image, imImage* dst_image, const imImage* kernel, int ismax);
+
+/** Gray morphology convolution with a kernel full of "0"s and use minimum value.
+ *
+ * \verbatim im.ProcessGrayMorphErode(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphErodeNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphErode(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Gray morphology convolution with a kernel full of "0"s and use maximum value.
+ *
+ * \verbatim im.ProcessGrayMorphDilate(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphDilateNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphDilate(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Erode+Dilate.
+ *
+ * \verbatim im.ProcessGrayMorphOpen(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphOpenNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphOpen(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Dilate+Erode.
+ *
+ * \verbatim im.ProcessGrayMorphClose(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphCloseNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphClose(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Open+Difference.
+ *
+ * \verbatim im.ProcessGrayMorphTopHat(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphTopHatNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphTopHat(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Close+Difference.
+ *
+ * \verbatim im.ProcessGrayMorphWell(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphWellNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphWell(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Difference(Erode, Dilate).
+ *
+ * \verbatim im.ProcessGrayMorphGradient(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGrayMorphGradientNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphgray */
+int imProcessGrayMorphGradient(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+
+
+/** \defgroup morphbin Morphology Operations for Binary Images
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Base binary morphology convolution. \n
+ * Images are all IM_BINARY. Kernel is IM_INT, but values can be only 1, 0 or -1. Use kernel size odd for better results. \n
+ * Hit white means hit=1 and miss=0, or else hit=0 and miss=1. \n
+ * Use -1 for don't care positions in kernel. Kernel values are simply compared with image values. \n
+ * The operation can be repeated by a number of iterations.
+ * The border is zero extended. \n
+ * Almost all the binary morphology operations use this function.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessBinMorphConvolve(src_image: imImage, dst_image: imImage, kernel: imImage, hit_white: boolean, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphConvolveNew(image: imImage, kernel: imImage, hit_white: boolean, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphConvolve(const imImage* src_image, imImage* dst_image, const imImage* kernel, int hit_white, int iter);
+
+/** Binary morphology convolution with a kernel full of "1"s and hit white.
+ *
+ * \verbatim im.ProcessBinMorphErode(src_image: imImage, dst_image: imImage, kernel_size: number, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphErodeNew(image: imImage, kernel_size: number, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphErode(const imImage* src_image, imImage* dst_image, int kernel_size, int iter);
+
+/** Binary morphology convolution with a kernel full of "0"s and hit black.
+ *
+ * \verbatim im.ProcessBinMorphDilate(src_image: imImage, dst_image: imImage, kernel_size: number, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphDilateNew(image: imImage, kernel_size: number, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphDilate(const imImage* src_image, imImage* dst_image, int kernel_size, int iter);
+
+/** Erode+Dilate.
+ * When iteration is more than one it means Erode+Erode+Erode+...+Dilate+Dilate+Dilate+...
+ *
+ * \verbatim im.ProcessBinMorphOpen(src_image: imImage, dst_image: imImage, kernel_size: number, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphOpenNew(image: imImage, kernel_size: number, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphOpen(const imImage* src_image, imImage* dst_image, int kernel_size, int iter);
+
+/** Dilate+Erode.
+ *
+ * \verbatim im.ProcessBinMorphClose(src_image: imImage, dst_image: imImage, kernel_size: number, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphCloseNew(image: imImage, kernel_size: number, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphClose(const imImage* src_image, imImage* dst_image, int kernel_size, int iter);
+
+/** Erode+Difference. \n
+ * The difference from the source image is applied only once.
+ *
+ * \verbatim im.ProcessBinMorphOutline(src_image: imImage, dst_image: imImage, kernel_size: number, iter: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphOutlineNew(image: imImage, kernel_size: number, iter: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+int imProcessBinMorphOutline(const imImage* src_image, imImage* dst_image, int kernel_size, int iter);
+
+/** Thins the supplied binary image using Rosenfeld's parallel thinning algorithm. \n
+ * Reference: \n
+ * "Efficient Binary Image Thinning using Neighborhood Maps" \n
+ * by Joseph M. Cychosz, 3ksnn64@ecn.purdue.edu \n
+ * in "Graphics Gems IV", Academic Press, 1994
+ *
+ * \verbatim im.ProcessBinMorphThin(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBinMorphThinNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup morphbin */
+void imProcessBinMorphThin(const imImage* src_image, imImage* dst_image);
+
+
+
+/** \defgroup rank Rank Convolution Operations
+ * \par
+ * All the rank convolution use the same base function. Near the border the base function
+ * includes only the real image pixels in the rank. No border extensions are used.
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Rank convolution using the median value. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images.
+ *
+ * \verbatim im.ProcessMedianConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMedianConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup rank */
+int imProcessMedianConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Rank convolution using (maximum-minimum) value. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images.
+ *
+ * \verbatim im.ProcessRangeConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRangeConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup rank */
+int imProcessRangeConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Rank convolution using the closest maximum or minimum value. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images.
+ *
+ * \verbatim im.ProcessRankClosestConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRankClosestConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup rank */
+int imProcessRankClosestConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Rank convolution using the maximum value. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images.
+ *
+ * \verbatim im.ProcessRankMaxConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRankMaxConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup rank */
+int imProcessRankMaxConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Rank convolution using the minimum value. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all data types except IM_CFLOAT. Can be applied on color images.
+ *
+ * \verbatim im.ProcessRankMinConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRankMinConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup rank */
+int imProcessRankMinConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Threshold using a rank convolution with a range contrast function. \n
+ * Supports all integer IM_GRAY images as source, and IM_BINARY as destiny. \n
+ * Local variable threshold by the method of Bernsen. \n
+ * Extracted from XITE, Copyright 1991, Blab, UiO \n
+ * http://www.ifi.uio.no/~blab/Software/Xite/
+\verbatim
+ Reference:
+ Bernsen, J: "Dynamic thresholding of grey-level images"
+ Proc. of the 8th ICPR, Paris, Oct 1986, 1251-1255.
+ Author: Oivind Due Trier
+\endverbatim
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRangeContrastThreshold(src_image: imImage, dst_image: imImage, kernel_size: number, min_range: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRangeContrastThresholdNew(image: imImage, kernel_size: number, min_range: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessRangeContrastThreshold(const imImage* src_image, imImage* dst_image, int kernel_size, int min_range);
+
+/** Threshold using a rank convolution with a local max function. \n
+ * Returns zero if the counter aborted. \n
+ * Supports all integer IM_GRAY images as source, and IM_BINARY as destiny.
+ *
+ * \verbatim im.ProcessLocalMaxThreshold(src_image: imImage, dst_image: imImage, kernel_size: number, min_level: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessLocalMaxThresholdNew(image: imImage, kernel_size: number, min_level: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessLocalMaxThreshold(const imImage* src_image, imImage* dst_image, int kernel_size, int min_level);
+
+
+
+/** \defgroup convolve Convolution Operations
+ * \par
+ * See \ref im_process_loc.h
+ * \ingroup process */
+
+/** Base Convolution with a kernel. \n
+ * Kernel can be IM_INT or IM_FLOAT, but always IM_GRAY. Use kernel size odd for better results. \n
+ * Supports all data types. The border is mirrored. \n
+ * Returns zero if the counter aborted. Most of the convolutions use this function.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessConvolve(src_image: imImage, dst_image: imImage, kernel: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessConvolveNew(image: imImage, kernel: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessConvolve(const imImage* src_image, imImage* dst_image, const imImage* kernel);
+
+/** Base convolution when the kernel is separable. Only the first line and the first column will be used. \n
+ * Returns zero if the counter aborted.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessConvolveSep(src_image: imImage, dst_image: imImage, kernel: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessConvolveSepNew(image: imImage, kernel: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessConvolveSep(const imImage* src_image, imImage* dst_image, const imImage* kernel);
+
+/** Base Convolution with two kernels. The result is the magnitude of the result of each convolution. \n
+ * Kernel can be IM_INT or IM_FLOAT, but always IM_GRAY. Use kernel size odd for better results. \n
+ * Supports all data types. The border is mirrored. \n
+ * Returns zero if the counter aborted. Most of the convolutions use this function.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessConvolveDual(src_image: imImage, dst_image: imImage, kernel1, kernel2: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessConvolveDualNew(image: imImage, kernel1, kernel2: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessConvolveDual(const imImage* src_image, imImage* dst_image, const imImage *kernel1, const imImage *kernel2);
+
+/** Repeats the convolution a number of times. \n
+ * Returns zero if the counter aborted.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessConvolveRep(src_image: imImage, dst_image: imImage, kernel: imImage, count: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessConvolveRepNew(image: imImage, kernel: imImage, count: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessConvolveRep(const imImage* src_image, imImage* dst_image, const imImage* kernel, int count);
+
+/** Convolve with a kernel rotating it 8 times and getting the absolute maximum value. \n
+ * Kernel must be square. \n
+ * The rotation is implemented only for kernel sizes 3x3, 5x5 and 7x7. \n
+ * Supports all data types except IM_CFLOAT.
+ * Returns zero if the counter aborted.\n
+ * If the kernel image attribute "Description" exists it is used by the counter.
+ *
+ * \verbatim im.ProcessCompassConvolve(src_image: imImage, dst_image: imImage, kernel: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessCompassConvolveNew(image: imImage, kernel: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessCompassConvolve(const imImage* src_image, imImage* dst_image, imImage* kernel);
+
+/** Utility function to rotate a kernel one time.
+ *
+ * \verbatim im.ProcessRotateKernel(kernel: imImage) [in Lua 5] \endverbatim
+ * \ingroup convolve */
+void imProcessRotateKernel(imImage* kernel);
+
+/** Difference(Gaussian1, Gaussian2). \n
+ * Supports all data types,
+ * but if source is IM_BYTE or IM_USHORT destiny image must be of type IM_INT.
+ *
+ * \verbatim im.ProcessDiffOfGaussianConvolve(src_image: imImage, dst_image: imImage, stddev1: number, stddev2: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessDiffOfGaussianConvolveNew(image: imImage, stddev1: number, stddev2: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessDiffOfGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev1, float stddev2);
+
+/** Convolution with a laplacian of a gaussian kernel. \n
+ * Supports all data types,
+ * but if source is IM_BYTE or IM_USHORT destiny image must be of type IM_INT.
+ *
+ * \verbatim im.ProcessLapOfGaussianConvolve(src_image: imImage, dst_image: imImage, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessLapOfGaussianConvolveNew(image: imImage, stddev: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessLapOfGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev);
+
+/** Convolution with a kernel full of "1"s inside a circle. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessMeanConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMeanConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessMeanConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Convolution with a float gaussian kernel. \n
+ * If sdtdev is negative its magnitude will be used as the kernel size. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessGaussianConvolve(src_image: imImage, dst_image: imImage, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessGaussianConvolveNew(image: imImage, stddev: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessGaussianConvolve(const imImage* src_image, imImage* dst_image, float stddev);
+
+/** Convolution with a barlett kernel. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessBarlettConvolve(src_image: imImage, dst_image: imImage, kernel_size: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBarlettConvolveNew(image: imImage, kernel_size: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessBarlettConvolve(const imImage* src_image, imImage* dst_image, int kernel_size);
+
+/** Magnitude of the sobel convolution. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessSobelConvolve(src_image: imImage, dst_image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSobelConvolveNew(image: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessSobelConvolve(const imImage* src_image, imImage* dst_image);
+
+/** Magnitude of the prewitt convolution. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessPrewittConvolve(src_image: imImage, dst_image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPrewittConvolveNew(image: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessPrewittConvolve(const imImage* src_image, imImage* dst_image);
+
+/** Spline edge dectection. \n
+ * Supports all data types.
+ *
+ * \verbatim im.ProcessSplineEdgeConvolve(src_image: imImage, dst_image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSplineEdgeConvolveNew(image: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imProcessSplineEdgeConvolve(const imImage* src_image, imImage* dst_image);
+
+/** Finds the zero crossings of IM_INT and IM_FLOAT images. Crossings are marked with non zero values
+ * indicating the intensity of the edge. It is usually used after a second derivative, laplace. \n
+ * Extracted from XITE, Copyright 1991, Blab, UiO \n
+ * http://www.ifi.uio.no/~blab/Software/Xite/
+ *
+ * \verbatim im.ProcessZeroCrossing(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessZeroCrossingNew(image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+void imProcessZeroCrossing(const imImage* src_image, imImage* dst_image);
+
+/** First part of the Canny edge detector. Includes the gaussian filtering and the nonmax suppression. \n
+ * After using this you could apply a Hysteresis Threshold, see \ref imProcessHysteresisThreshold. \n
+ * Image must be IM_BYTE/IM_GRAY. \n
+ * Implementation from the book:
+ \verbatim
+ J. R. Parker
+ "Algoritms for Image Processing and Computer Vision"
+ WILEY
+ \endverbatim
+ *
+ * \verbatim im.ProcessCanny(src_image: imImage, dst_image: imImage, stddev: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessCannyNew(image: imImage, stddev: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup convolve */
+void imProcessCanny(const imImage* src_image, imImage* dst_image, float stddev);
+
+/** Calculates the kernel size given the standard deviation. \n
+ * If sdtdev is negative its magnitude will be used as the kernel size.
+ *
+ * \verbatim im.GaussianStdDev2KernelSize(stddev: number) -> kernel_size: number [in Lua 5] \endverbatim
+ * \ingroup convolve */
+int imGaussianStdDev2KernelSize(float stddev);
+
+/** Calculates the standard deviation given the kernel size.
+ *
+ * \verbatim im.GaussianKernelSize2StdDev(kernel_size: number) -> stddev: number [in Lua 5] \endverbatim
+ * \ingroup convolve */
+float imGaussianKernelSize2StdDev(int kernel_size);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_process_pon.h b/include/im_process_pon.h
new file mode 100644
index 0000000..cfed5ae
--- /dev/null
+++ b/include/im_process_pon.h
@@ -0,0 +1,712 @@
+/** \file
+ * \brief Image Processing - Pontual Operations
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_PROCESS_PON_H
+#define __IM_PROCESS_PON_H
+
+#include "im_image.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/** \defgroup arithm Arithmetic Operations
+ * \par
+ * Simple math operations for images.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Unary Arithmetic Operations.
+ * Inverse and log may lead to math exceptions.
+ * \ingroup arithm */
+enum imUnaryOp {
+ IM_UN_EQL, /**< equal = a */
+ IM_UN_ABS, /**< abssolute = |a| */
+ IM_UN_LESS, /**< less = -a */
+ IM_UN_INC, /**< increment += a */
+ IM_UN_INV, /**< invert = 1/a (#) */
+ IM_UN_SQR, /**< square = a*a */
+ IM_UN_SQRT, /**< square root = a^(1/2) */
+ IM_UN_LOG, /**< natural logarithm = ln(a) (#) */
+ IM_UN_EXP, /**< exponential = exp(a) */
+ IM_UN_SIN, /**< sine = sin(a) */
+ IM_UN_COS, /**< cosine = cos(a) */
+ IM_UN_CONJ, /**< complex conjugate = ar - ai*i */
+ IM_UN_CPXNORM /**< complex normalization by magnitude = a / cpxmag(a) */
+};
+
+/** Apply an arithmetic unary operation. \n
+ * Can be done in place, images must match size, does not need to match type.
+ *
+ * \verbatim im.ProcessUnArithmeticOp(src_image: imImage, dst_image: imImage, op: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessUnArithmeticOpNew(image: imImage, op: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessUnArithmeticOp(const imImage* src_image, imImage* dst_image, int op);
+
+/** Binary Arithmetic Operations.
+ * Inverse and log may lead to math exceptions.
+ * \ingroup arithm */
+enum imBinaryOp {
+ IM_BIN_ADD, /**< add = a+b */
+ IM_BIN_SUB, /**< subtract = a-b */
+ IM_BIN_MUL, /**< multiply = a*b */
+ IM_BIN_DIV, /**< divide = a/b (#) */
+ IM_BIN_DIFF, /**< difference = |a-b| */
+ IM_BIN_POW, /**< power = a^b */
+ IM_BIN_MIN, /**< minimum = (a < b)? a: b */
+ IM_BIN_MAX /**< maximum = (a > b)? a: b */
+};
+
+/** Apply a binary arithmetic operation. \n
+ * Can be done in place, images must match size. \n
+ * Source images must match type, destiny image can be several types depending on source: \n
+ * \li byte -> byte, ushort, int, float
+ * \li ushort -> ushort, int, float
+ * \li int -> int, float
+ * \li float -> float
+ * \li complex -> complex
+ * One exception is that you can combine complex with float resulting complex.
+ *
+ * \verbatim im.ProcessArithmeticOp(src_image1: imImage, src_image2: imImage, dst_image: imImage, op: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessArithmeticOpNew(image1: imImage, image2: imImage, op: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * The New function will create a new image of the same type of the source images.
+ * \ingroup arithm */
+void imProcessArithmeticOp(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, int op);
+
+/** Apply a binary arithmetic operation with a constant value. \n
+ * Can be done in place, images must match size. \n
+ * Destiny image can be several types depending on source: \n
+ * \li byte -> byte, ushort, int, float
+ * \li ushort -> byte, ushort, int, float
+ * \li int -> byte, ushort, int, float
+ * \li float -> float
+ * \li complex -> complex
+ * The constant value is type casted to an apropriate type before the operation.
+ *
+ * \verbatim im.ProcessArithmeticConstOp(src_image: imImage, src_const: number, dst_image: imImage, op: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessArithmeticConstOpNew(image: imImage, src_const: number, op: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessArithmeticConstOp(const imImage* src_image, float src_const, imImage* dst_image, int op);
+
+/** Blend two images using an alpha value = [a * alpha + b * (1 - alpha)]. \n
+ * Can be done in place, images must match size and type. \n
+ * alpha value must be in the interval [0.0 - 1.0].
+ *
+ * \verbatim im.ProcessBlendConst(src_image1: imImage, src_image2: imImage, dst_image: imImage, alpha: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBlendConstNew(image1: imImage, image2: imImage, alpha: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessBlendConst(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, float alpha);
+
+/** Blend two images using an alpha channel = [a * alpha + b * (1 - alpha)]. \n
+ * Can be done in place, images must match size and type. \n
+ * alpha_image must have the same data type except for complex images that must be float, and color_space must be IM_GRAY.
+ * integer alpha values must be:
+\verbatim
+0 - 255 IM_BYTE
+0 - 65535 IM_USHORT
+0 - 2147483647 IM_INT
+\endverbatim
+ * that will be normalized to 0 - 1.
+ * \verbatim im.ProcessBlend(src_image1: imImage, src_image2: imImage, alpha_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBlendNew(image1: imImage, image2: imImage, alpha_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessBlend(const imImage* src_image1, const imImage* src_image2, const imImage* alpha_image, imImage* dst_image);
+
+/** Split a complex image into two images with real and imaginary parts \n
+ * or magnitude and phase parts (polar). \n
+ * Source image must be IM_CFLOAT, destiny images must be IM_FLOAT.
+ *
+ * \verbatim im.ProcessSplitComplex(src_image: imImage, dst_image1: imImage, dst_image2: imImage, do_polar: boolean) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSplitComplexNew(image: imImage, do_polar: boolean) -> dst_image1: imImage, dst_image2: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessSplitComplex(const imImage* src_image, imImage* dst_image1, imImage* dst_image2, int do_polar);
+
+/** Merges two images as the real and imaginary parts of a complex image, \n
+ * or as magnitude and phase parts (polar = 1). \n
+ * Source images must be IM_FLOAT, destiny image must be IM_CFLOAT.
+ *
+ * \verbatim im.ProcessMergeComplex(src_image1: imImage, src_image2: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMergeComplexNew(image1: imImage, image2: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessMergeComplex(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, int polar);
+
+/** Calculates the mean of multiple images. \n
+ * Images must match size and type.
+ *
+ * \verbatim im.ProcessMultipleMean(src_image_list: table of imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMultipleMeanNew(src_image_list: table of imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessMultipleMean(const imImage** src_image_list, int src_image_count, imImage* dst_image);
+
+/** Calculates the standard deviation of multiple images. \n
+ * Images must match size and type. Use \ref imProcessMultipleMean to calculate the mean_image.
+ *
+ * \verbatim im.ProcessMultipleStdDev(src_image_list: table of imImage, mean_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMultipleStdDevNew(src_image_list: table of imImage, mean_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessMultipleStdDev(const imImage** src_image_list, int src_image_count, const imImage *mean_image, imImage* dst_image);
+
+/** Calculates the auto-covariance of an image with the mean of a set of images. \n
+ * Images must match size and type. Returns zero if the counter aborted. \n
+ * Destiny is IM_FLOAT.
+ *
+ * \verbatim im.ProcessAutoCovariance(src_image: imImage, mean_image: imImage, dst_image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessAutoCovarianceNew(src_image: imImage, mean_image: imImage) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+int imProcessAutoCovariance(const imImage* src_image, const imImage* mean_image, imImage* dst_image);
+
+/** Multiplies the conjugate of one complex image with another complex image. \n
+ * Images must match size. Conj(img1) * img2 \n
+ * Can be done in-place.
+ *
+ * \verbatim im.ProcessMultiplyConj(src_image1: imImage, src_image2: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMultiplyConjNew(src_image1: imImage, src_image2: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup arithm */
+void imProcessMultiplyConj(const imImage* src_image1, const imImage* src_image2, imImage* dst_image);
+
+
+
+/** \defgroup quantize Additional Image Quantization Operations
+ * \par
+ * Additionally operations to the \ref imConvertColorSpace function.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Converts a RGB image to a MAP image using uniform quantization
+ * with an optional 8x8 ordered dither. The RGB image must have data type IM_BYTE.
+ *
+ * \verbatim im.ProcessQuantizeRGBUniform(src_image: imImage, dst_image: imImage, do_dither: boolean) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessQuantizeRGBUniformNew(src_image: imImage, do_dither: boolean) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup quantize */
+void imProcessQuantizeRGBUniform(const imImage* src_image, imImage* dst_image, int do_dither);
+
+/** Quantizes a gray scale image in less that 256 grays using uniform quantization. \n
+ * Both images must be IM_BYTE/IM_GRAY. Can be done in place.
+ *
+ * \verbatim im.ProcessQuantizeGrayUniform(src_image: imImage, dst_image: imImage, grays: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessQuantizeGrayUniformNew(src_image: imImage, grays: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup quantize */
+void imProcessQuantizeGrayUniform(const imImage* src_image, imImage* dst_image, int grays);
+
+
+
+/** \defgroup histo Histogram Based Operations
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Performs an histogram expansion based on a percentage of the number of pixels. \n
+ * Percentage defines an amount of pixels to include at the lowest level and at the highest level.
+ * If its is zero only empty counts of the histogram will be considered. \n
+ * Images must be IM_BYTE/(IM_RGB or IM_GRAY). Can be done in place. \n
+ * To expand the gammut without using the histogram, by just specifing the lowest and highest levels
+ * use the \ref IM_GAMUT_EXPAND tone gammut operation (\ref imProcessToneGamut).
+ *
+ * \verbatim im.ProcessExpandHistogram(src_image: imImage, dst_image: imImage, percent: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessExpandHistogramNew(src_image: imImage, percent: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup histo */
+void imProcessExpandHistogram(const imImage* src_image, imImage* dst_image, float percent);
+
+/** Performs an histogram equalization. \n
+ * Images must be IM_BYTE/(IM_RGB or IM_GRAY). Can be done in place.
+ *
+ * \verbatim im.ProcessEqualizeHistogram(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessEqualizeHistogramNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup histo */
+void imProcessEqualizeHistogram(const imImage* src_image, imImage* dst_image);
+
+
+
+/** \defgroup colorproc Color Processing Operations
+ * \par
+ * Operations to change the color components configuration.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Split a RGB image into luma and chroma. \n
+ * Chroma is calculated as R-Y,G-Y,B-Y. Source image must be IM_RGB/IM_BYTE. \n
+ * luma image is IM_GRAY/IM_BYTE and chroma is IM_RGB/IM_BYTE. \n
+ * Source and destiny must have the same size.
+ *
+ * \verbatim im.ProcessSplitYChroma(src_image: imImage, y_image: imImage, chroma_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSplitYChromaNew(src_image: imImage) -> y_image: imImage, chroma_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessSplitYChroma(const imImage* src_image, imImage* y_image, imImage* chroma_image);
+
+/** Split a RGB image into HSI planes. \n
+ * Source image must be IM_RGB/IM_BYTE,IM_FLOAT. Destiny images are all IM_GRAY/IM_FLOAT. \n
+ * Source images must normalized to 0-1 if type is IM_FLOAT (\ref imProcessToneGamut can be used). See \ref hsi for a definition of the color conversion.\n
+ * Source and destiny must have the same size.
+ *
+ * \verbatim im.ProcessSplitHSI(src_image: imImage, h_image: imImage, s_image: imImage, i_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSplitHSINew(src_image: imImage) -> h_image: imImage, s_image: imImage, i_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessSplitHSI(const imImage* src_image, imImage* h_image, imImage* s_image, imImage* i_image);
+
+/** Merge HSI planes into a RGB image. \n
+ * Source images must be IM_GRAY/IM_FLOAT. Destiny image can be IM_RGB/IM_BYTE,IM_FLOAT. \n
+ * Source and destiny must have the same size. See \ref hsi for a definition of the color conversion.
+ *
+ * \verbatim im.ProcessMergeHSI(h_image: imImage, s_image: imImage, i_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMergeHSINew(h_image: imImage, s_image: imImage, i_image: imImage) -> dst_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessMergeHSI(const imImage* h_image, const imImage* s_image, const imImage* i_image, imImage* dst_image);
+
+/** Split a multicomponent image into separate components.\n
+ * Destiny images must be IM_GRAY. Size and data types must be all the same.\n
+ * The number of destiny images must match the depth of the source image.
+ *
+ * \verbatim im.ProcessSplitComponents(src_image: imImage, dst_image_list: table of imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSplitComponentsNew(src_image: imImage) -> dst_image_list: table of imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessSplitComponents(const imImage* src_image, imImage** dst_image_list);
+
+/** Merges separate components into a multicomponent image.\n
+ * Source images must be IM_GRAY. Size and data types must be all the same.\n
+ * The number of source images must match the depth of the destiny image.
+ *
+ * \verbatim im.ProcessMergeComponents(src_image_list: table of imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMergeComponentsNew(src_image_list: table of imImage) -> dst_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessMergeComponents(const imImage** src_image_list, imImage* dst_image);
+
+/** Normalize the color components by their sum. Example: c1 = c1/(c1+c2+c3). \n
+ * Destiny image must be IM_FLOAT.
+ *
+ * \verbatim im.ProcessNormalizeComponents(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessNormalizeComponentsNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessNormalizeComponents(const imImage* src_image, imImage* dst_image);
+
+/** Replaces the source color by the destiny color. \n
+ * The color will be type casted to the image data type. \n
+ * The colors must have the same number of components of the images. \n
+ * Supports all color spaces and all data types except IM_CFLOAT.
+ *
+ * \verbatim im.ProcessReplaceColor(src_image: imImage, dst_image: imImage, src_color: table of numbers, dst_color: table of numbers) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessReplaceColorNew(src_image: imImage, src_color: table of numbers, dst_color: table of numbers) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup colorproc */
+void imProcessReplaceColor(const imImage* src_image, imImage* dst_image, float* src_color, float* dst_color);
+
+
+
+/** \defgroup logic Logical Arithmetic Operations
+ * \par
+ * Logical binary math operations for images.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Logical Operations.
+ * \ingroup logic */
+enum imLogicOp {
+ IM_BIT_AND, /**< and = a & b */
+ IM_BIT_OR, /**< or = a | b */
+ IM_BIT_XOR /**< xor = ~(a | b) */
+};
+
+/** Apply a logical operation.\n
+ * Images must have data type IM_BYTE, IM_USHORT or IM_INT. Can be done in place.
+ *
+ * \verbatim im.ProcessBitwiseOp(src_image1: imImage, src_image2: imImage, dst_image: imImage, op: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBitwiseOpNew(src_image1: imImage, src_image2: imImage, op: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup logic */
+void imProcessBitwiseOp(const imImage* src_image1, const imImage* src_image2, imImage* dst_image, int op);
+
+/** Apply a logical NOT operation.\n
+ * Images must have data type IM_BYTE, IM_USHORT or IM_INT. Can be done in place.
+ *
+ * \verbatim im.ProcessBitwiseNot(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBitwiseNotNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup logic */
+void imProcessBitwiseNot(const imImage* src_image, imImage* dst_image);
+
+/** Apply a bit mask. \n
+ * The same as imProcessBitwiseOp but the second image is replaced by a fixed mask. \n
+ * Images must have data type IM_BYTE. It is valid only for AND, OR and XOR. Can be done in place.
+ *
+ * \verbatim im.ProcessBitMask(src_image: imImage, dst_image: imImage, mask: string, op: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBitMaskNew(src_image: imImage, mask: string, op: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * In Lua, mask is a string with 0s and 1s, for example: "11001111".
+ * \ingroup logic */
+void imProcessBitMask(const imImage* src_image, imImage* dst_image, unsigned char mask, int op);
+
+/** Extract or Reset a bit plane. For ex: 000X0000 or XXX0XXXX (plane=3).\n
+ * Images must have data type IM_BYTE. Can be done in place.
+ *
+ * \verbatim im.ProcessBitPlane(src_image: imImage, dst_image: imImage, plane: number, do_reset: boolean) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessBitPlaneNew(src_image: imImage, plane: number, do_reset: boolean) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup logic */
+void imProcessBitPlane(const imImage* src_image, imImage* dst_image, int plane, int do_reset);
+
+
+
+/** \defgroup render Synthetic Image Render
+ * \par
+ * Renders some 2D mathematical functions as images. All the functions operates in place
+ * and supports all data types except IM_CFLOAT.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Render Funtion.
+ * \verbatim render_func(x: number, y: number, d: number, param: table of number) -> value: number [in Lua 5] \endverbatim
+ * \ingroup render */
+typedef float (*imRenderFunc)(int x, int y, int d, float* param);
+
+/** Render Conditional Funtion.
+ * \verbatim render_cond_func(x: number, y: number, d: number, param: table of number) -> value: number, cond: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+typedef float (*imRenderCondFunc)(int x, int y, int d, int *cond, float* param);
+
+/** Render a synthetic image using a render function. \n
+ * plus will make the render be added to the current image data,
+ * or else all data will be replaced. All the render functions use this or the conditional function. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRenderOp(image: imImage, render_func: function, render_name: string, param: table of number, plus: boolean) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderOp(imImage* image, imRenderFunc render_func, char* render_name, float* param, int plus);
+
+/** Render a synthetic image using a conditional render function. \n
+ * Data will be rendered only if the condional param is true. \n
+ * Returns zero if the counter aborted.
+ *
+ * \verbatim im.ProcessRenderCondOp(image: imImage, render_cond_func: function, render_name: string, param: table of number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderCondOp(imImage* image, imRenderCondFunc render_cond_func, char* render_name, float* param);
+
+/** Render speckle noise on existing data. Can be done in place.
+ *
+ * \verbatim im.ProcessRenderAddSpeckleNoise(src_image: imImage, dst_image: imImage, percent: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRenderAddSpeckleNoiseNew(src_image: imImage, percent: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderAddSpeckleNoise(const imImage* src_image, imImage* dst_image, float percent);
+
+/** Render gaussian noise on existing data. Can be done in place.
+ *
+ * \verbatim im.ProcessRenderAddGaussianNoise(src_image: imImage, dst_image: imImage, mean: number, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRenderAddGaussianNoiseNew(src_image: imImage, mean: number, stddev: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderAddGaussianNoise(const imImage* src_image, imImage* dst_image, float mean, float stddev);
+
+/** Render uniform noise on existing data. Can be done in place.
+ *
+ * \verbatim im.ProcessRenderAddUniformNoise(src_image: imImage, dst_image: imImage, mean: number, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \verbatim im.ProcessRenderAddUniformNoiseNew(src_image: imImage, mean: number, stddev: number) -> counter: boolean, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderAddUniformNoise(const imImage* src_image, imImage* dst_image, float mean, float stddev);
+
+/** Render random noise.
+ *
+ * \verbatim im.ProcessRenderRandomNoise(image: imImage) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderRandomNoise(imImage* image);
+
+/** Render a constant. The number of values must match the depth of the image.
+ *
+ * \verbatim im.ProcessRenderConstant(image: imImage, value: table of number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderConstant(imImage* image, float* value);
+
+/** Render a centered wheel.
+ *
+ * \verbatim im.ProcessRenderWheel(image: imImage, internal_radius: number, external_radius: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderWheel(imImage* image, int internal_radius, int external_radius);
+
+/** Render a centered cone.
+ *
+ * \verbatim im.ProcessRenderCone(image: imImage, radius: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderCone(imImage* image, int radius);
+
+/** Render a centered tent.
+ *
+ * \verbatim im.ProcessRenderTent(image: imImage, tent_width: number, tent_height: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderTent(imImage* image, int tent_width, int tent_height);
+
+/** Render a ramp. Direction can be vertical (1) or horizontal (0).
+ *
+ * \verbatim im.ProcessRenderRamp(image: imImage, start: number, end: number, vert_dir: boolean) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderRamp(imImage* image, int start, int end, int vert_dir);
+
+/** Render a centered box.
+ *
+ * \verbatim im.ProcessRenderBox(image: imImage, box_width: number, box_height: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderBox(imImage* image, int box_width, int box_height);
+
+/** Render a centered sinc.
+ *
+ * \verbatim im.ProcessRenderSinc(image: imImage, x_period: number, y_period: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderSinc(imImage* image, float x_period, float y_period);
+
+/** Render a centered gaussian.
+ *
+ * \verbatim im.ProcessRenderGaussian(image: imImage, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderGaussian(imImage* image, float stddev);
+
+/** Render the laplacian of a centered gaussian.
+ *
+ * \verbatim im.ProcessRenderLapOfGaussian(image: imImage, stddev: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderLapOfGaussian(imImage* image, float stddev);
+
+/** Render a centered cosine.
+ *
+ * \verbatim im.ProcessRenderCosine(image: imImage, x_period: number, y_period: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderCosine(imImage* image, float x_period, float y_period);
+
+/** Render a centered grid.
+ *
+ * \verbatim im.ProcessRenderGrid(image: imImage, x_space: number, y_space: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderGrid(imImage* image, int x_space, int y_space);
+
+/** Render a centered chessboard.
+ *
+ * \verbatim im.ProcessRenderChessboard(image: imImage, x_space: number, y_space: number) -> counter: boolean [in Lua 5] \endverbatim
+ * \ingroup render */
+int imProcessRenderChessboard(imImage* image, int x_space, int y_space);
+
+
+
+/** \defgroup tonegamut Tone Gamut Operations
+ * \par
+ * Operations that try to preserve the min-max interval in the output (the dynamic range).
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+
+/** Tone Gamut Operations.
+ * \ingroup tonegamut */
+enum imToneGamut {
+ IM_GAMUT_NORMALIZE, /**< normalize = (a-min) / (max-min) (destiny image must be IM_FLOAT) */
+ IM_GAMUT_POW, /**< pow = ((a-min) / (max-min))^gamma * (max-min) + min \n
+ param[0]=gamma */
+ IM_GAMUT_LOG, /**< log = log(K * (a-min) / (max-min) + 1))*(max-min)/log(K+1) + min \n
+ param[0]=K (K>0) */
+ IM_GAMUT_EXP, /**< exp = (exp(K * (a-min) / (max-min)) - 1))*(max-min)/(exp(K)-1) + min \n
+ param[0]=K */
+ IM_GAMUT_INVERT, /**< invert = max - (a-min) */
+ IM_GAMUT_ZEROSTART, /**< zerostart = a - min */
+ IM_GAMUT_SOLARIZE, /**< solarize = a < level ? a: (level * (max-min) - a * (level-min)) / (max-level) \n
+ param[0]=level percentage (0-100) relative to min-max \n
+ photography solarization effect. */
+ IM_GAMUT_SLICE, /**< slice = start < a || a > end ? min: binarize? max: a \n
+ param[0]=start, param[1]=end, param[2]=binarize */
+ IM_GAMUT_EXPAND, /**< expand = a < start ? min: a > end ? max : (a-start)*(max-min)/(end-start) + min \n
+ param[0]=start, param[1]=end */
+ IM_GAMUT_CROP, /**< crop = a < start ? start: a > end ? end : a \n
+ param[0]=start, param[1]=end */
+ IM_GAMUT_BRIGHTCONT /**< brightcont = a < min ? min: a > max ? max: a * tan(c_a) + b_s + (max-min)*(1 - tan(c_a))/2 \n
+ param[0]=bright_shift (-100%..+100%), param[1]=contrast_factor (-100%..+100%) \n
+ change brightness and contrast simultaneously. */
+};
+
+/** Apply a gamut operation with arguments. \n
+ * Supports all data types except IM_CFLOAT. \n
+ * The linear operation do a special convertion when min > 0 and max < 1, it forces min=0 and max=1. \n
+ * IM_BYTE images have min=0 and max=255 always. \n
+ * Can be done in place. When there is no extra params use NULL.
+ *
+ * \verbatim im.ProcessToneGamut(src_image: imImage, dst_image: imImage, op: number, param: table of number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessToneGamutNew(src_image: imImage, op: number, param: table of number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup tonegamut */
+void imProcessToneGamut(const imImage* src_image, imImage* dst_image, int op, float* param);
+
+/** Converts from (0-1) to (0-255), crop out of bounds values. \n
+ * Source image must be IM_FLOAT, and destiny image must be IM_BYTE.
+ *
+ * \verbatim im.ProcessUnNormalize(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessUnNormalizeNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup tonegamut */
+void imProcessUnNormalize(const imImage* src_image, imImage* dst_image);
+
+/** Directly converts IM_USHORT, IM_INT and IM_FLOAT into IM_BYTE images. \n
+ * This can also be done using \ref imConvertDataType with IM_CAST_DIRECT.
+ *
+ * \verbatim im.ProcessDirectConv(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessDirectConvNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup tonegamut */
+void imProcessDirectConv(const imImage* src_image, imImage* dst_image);
+
+/** A negative effect. Uses \ref imProcessToneGamut with IM_GAMUT_INVERT for non MAP images. \n
+ * Supports all color spaces and all data types except IM_CFLOAT. \n
+ * Can be done in place.
+ *
+ * \verbatim im.ProcessNegative(src_image: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessNegativeNew(src_image: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup tonegamut */
+void imProcessNegative(const imImage* src_image, imImage* dst_image);
+
+
+
+/** \defgroup threshold Threshold Operations
+ * \par
+ * Operations that converts a usually IM_GRAY/IM_BYTE image into a IM_BINARY image using several threshold techniques.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+/** Apply a manual threshold. \n
+ * threshold = a <= level ? 0: value \n
+ * Normal value is 1 but another common value is 255. Can be done in place for IM_BYTE source. \n
+ * Supports all integer IM_GRAY images as source, and IM_BINARY as destiny.
+ *
+ * \verbatim im.ProcessThreshold(src_image: imImage, dst_image: imImage, level: number, value: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessThresholdNew(src_image: imImage, level: number, value: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessThreshold(const imImage* src_image, imImage* dst_image, int level, int value);
+
+/** Apply a threshold by the difference of two images. \n
+ * threshold = a1 <= a2 ? 0: 1 \n
+ * Can be done in place.
+ *
+ * \verbatim im.ProcessThresholdByDiff(src_image1: imImage, src_image2: imImage, dst_image: imImage) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessThresholdByDiffNew(src_image1: imImage, src_image2: imImage) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessThresholdByDiff(const imImage* src_image1, const imImage* src_image2, imImage* dst_image);
+
+/** Apply a threshold by the Hysteresis method. \n
+ * Hysteresis thersholding of edge pixels. Starting at pixels with a
+ * value greater than the HIGH threshold, trace a connected sequence
+ * of pixels that have a value greater than the LOW threhsold. \n
+ * Supports only IM_BYTE images.
+ * Note: could not find the original source code author name.
+ *
+ * \verbatim im.ProcessHysteresisThreshold(src_image: imImage, dst_image: imImage, low_thres: number, high_thres: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessHysteresisThresholdNew(src_image: imImage, low_thres: number, high_thres: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessHysteresisThreshold(const imImage* src_image, imImage* dst_image, int low_thres, int high_thres);
+
+/** Estimates hysteresis low and high threshold levels. \n
+ * Supports only IM_BYTE images.
+ * Usefull for \ref imProcessHysteresisThreshold.
+ *
+ * \verbatim im.ProcessHysteresisThresEstimate(image: imImage) -> low_level: number, high_level: number [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessHysteresisThresEstimate(const imImage* image, int *low_level, int *high_level);
+
+/** Calculates the threshold level for manual threshold using an uniform error approach. \n
+ * Supports only IM_BYTE images.
+ * Extracted from XITE, Copyright 1991, Blab, UiO \n
+ * http://www.ifi.uio.no/~blab/Software/Xite/
+\verbatim
+ Reference:
+ S. M. Dunn & D. Harwood & L. S. Davis:
+ "Local Estimation of the Uniform Error Threshold"
+ IEEE Trans. on PAMI, Vol PAMI-6, No 6, Nov 1984.
+ Comments: It only works well on images whith large objects.
+ Author: Olav Borgli, BLAB, ifi, UiO
+ Image processing lab, Department of Informatics, University of Oslo
+\endverbatim
+ * Returns the used level.
+ *
+ * \verbatim im.ProcessUniformErrThreshold(src_image: imImage, dst_image: imImage) -> level: number [in Lua 5] \endverbatim
+ * \verbatim im.ProcessUniformErrThresholdNew(src_image: imImage) -> level: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessUniformErrThreshold(const imImage* src_image, imImage* dst_image);
+
+/** Apply a dithering on each image channel by using a difusion error method. \n
+ * It can be applied on any IM_BYTE images. It will "threshold" each channel indivudually, so
+ * source and destiny must be of the same depth.
+ *
+ * \verbatim im.ProcessDifusionErrThreshold(src_image: imImage, dst_image: imImage, level: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessDifusionErrThresholdNew(src_image: imImage, level: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessDifusionErrThreshold(const imImage* src_image, imImage* dst_image, int level);
+
+/** Calculates the threshold level for manual threshold using a percentage of pixels
+ * that should stay bellow the threshold. \n
+ * Supports only IM_BYTE images.
+ * Returns the used level.
+ *
+ * \verbatim im.ProcessPercentThreshold(src_image: imImage, dst_image: imImage, percent: number) -> level: number [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPercentThresholdNew(src_image: imImage, percent: number) -> level: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessPercentThreshold(const imImage* src_image, imImage* dst_image, float percent);
+
+/** Calculates the threshold level for manual threshold using the Otsu approach. \n
+ * Returns the used level. \n
+ * Supports only IM_BYTE images.
+ * Original implementation by Flavio Szenberg.
+ *
+ * \verbatim im.ProcessOtsuThreshold(src_image: imImage, dst_image: imImage) -> level: number [in Lua 5] \endverbatim
+ * \verbatim im.ProcessOtsuThresholdNew(src_image: imImage) -> level: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessOtsuThreshold(const imImage* src_image, imImage* dst_image);
+
+/** Calculates the threshold level for manual threshold using (max-min)/2. \n
+ * Returns the used level. \n
+ * Supports all integer IM_GRAY images as source, and IM_BINARY as destiny.
+ *
+ * \verbatim im.ProcessMinMaxThreshold(src_image: imImage, dst_image: imImage) -> level: number [in Lua 5] \endverbatim
+ * \verbatim im.ProcessMinMaxThresholdNew(src_image: imImage) -> level: number, new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+int imProcessMinMaxThreshold(const imImage* src_image, imImage* dst_image);
+
+/** Estimates Local Max threshold level for IM_BYTE images.
+ *
+ * \verbatim im.ProcessLocalMaxThresEstimate(image: imImage) -> level: number [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessLocalMaxThresEstimate(const imImage* image, int *level);
+
+/** Apply a manual threshold using an interval. \n
+ * threshold = start_level <= a <= end_level ? 1: 0 \n
+ * Normal value is 1 but another common value is 255. Can be done in place for IM_BYTE source. \n
+ * Supports all integer IM_GRAY images as source, and IM_BINARY as destiny.
+ *
+ * \verbatim im.ProcessSliceThreshold(src_image: imImage, dst_image: imImage, start_level: number, end_level: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessSliceThresholdNew(src_image: imImage, start_level: number, end_level: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup threshold */
+void imProcessSliceThreshold(const imImage* src_image, imImage* dst_image, int start_level, int end_level);
+
+
+/** \defgroup effects Special Effects
+ * \par
+ * Operations to change image appearance.
+ * \par
+ * See \ref im_process_pon.h
+ * \ingroup process */
+
+
+/** Generates a zoom in effect averaging colors inside a square region. \n
+ * Operates only on IM_BYTE images.
+ *
+ * \verbatim im.ProcessPixelate(src_image: imImage, dst_image: imImage, box_size: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPixelateNew(src_image: imImage, box_size: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup effects */
+void imProcessPixelate(const imImage* src_image, imImage* dst_image, int box_size);
+
+/** A simple Posterize effect. It reduces the number of colors in the image eliminating
+ * less significant bit planes. Can have 1 to 7 levels. See \ref imProcessBitMask. \n
+ * Images must have data type IM_BYTE.
+ *
+ * \verbatim im.ProcessPosterize(src_image: imImage, dst_image: imImage, level: number) [in Lua 5] \endverbatim
+ * \verbatim im.ProcessPosterizeNew(src_image: imImage, level: number) -> new_image: imImage [in Lua 5] \endverbatim
+ * \ingroup effects */
+void imProcessPosterize(const imImage* src_image, imImage* dst_image, int level);
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_raw.h b/include/im_raw.h
new file mode 100644
index 0000000..073ad7d
--- /dev/null
+++ b/include/im_raw.h
@@ -0,0 +1,34 @@
+/** \file
+ * \brief RAW File Format
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_RAW_H
+#define __IM_RAW_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** Opens a RAW image file.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim im.FileOpenRaw(file_name: string) -> ifile: imFile, error: number [in Lua 5] \endverbatim
+ * \ingroup raw */
+imFile* imFileOpenRaw(const char* file_name, int *error);
+
+/** Creates a RAW image file.
+ * See also \ref imErrorCodes.
+ *
+ * \verbatim im.FileNewRaw(file_name: string) -> ifile: imFile, error: number [in Lua 5] \endverbatim
+ * \ingroup raw */
+imFile* imFileNewRaw(const char* file_name, int *error);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/im_util.h b/include/im_util.h
new file mode 100644
index 0000000..ab50671
--- /dev/null
+++ b/include/im_util.h
@@ -0,0 +1,277 @@
+/** \file
+ * \brief Utilities
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_UTIL_H
+#define __IM_UTIL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/** \defgroup util Utilities
+ * \par
+ * See \ref im_util.h
+ * @{
+ */
+
+#define IM_MIN(_a, _b) (_a < _b? _a: _b)
+#define IM_MAX(_a, _b) (_a > _b? _a: _b)
+
+/** @} */
+
+
+/** \defgroup str String Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup util */
+
+/** Check if the two strings are equal.
+ * \ingroup str */
+int imStrEqual(const char* str1, const char* str2);
+
+/** Calculate the size of the string but limited to max_len.
+ * \ingroup str */
+int imStrNLen(const char* str, int max_len);
+
+/** Check if the data is a string.
+ * \ingroup str */
+int imStrCheck(const void* data, int count);
+
+
+
+/** \defgroup imageutil Raw Data Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup imagerep */
+
+/** Returns the size of the data buffer.
+ *
+ * \verbatim im.ImageDataSize(width: number, height: number, color_mode: number, data_type: number) -> datasize: number [in Lua 5] \endverbatim
+ * \ingroup imageutil */
+int imImageDataSize(int width, int height, int color_mode, int data_type);
+
+/** Returns the size of one line of the data buffer. \n
+ * This depends if the components are packed. If packed includes all components, if not includes only one.
+ *
+ * \verbatim im.ImageLineSize(width: number, color_mode: number, data_type: number) -> linesize: number [in Lua 5] \endverbatim
+ * \ingroup imageutil */
+int imImageLineSize(int width, int color_mode, int data_type);
+
+/** Returns the number of elements of one line of the data buffer. \n
+ * This depends if the components are packed. If packed includes all components, if not includes only one.
+ *
+ * \verbatim im.ImageLineCount(width: number, color_mode: number) -> linecount: number [in Lua 5] \endverbatim
+ * \ingroup imageutil */
+int imImageLineCount(int width, int color_mode);
+
+/** Check if the combination color_mode+data_type is valid.
+ *
+ * \verbatim im.ImageCheckFormat(color_mode: number, data_type: number) -> check: boolean [in Lua 5] \endverbatim
+ * \ingroup imageutil */
+int imImageCheckFormat(int color_mode, int data_type);
+
+
+
+/** \defgroup colorutl Color Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup util */
+
+/** Encode RGB components in a long for palete usage. \n
+ * "long" definition is compatible with the CD library definition.
+ *
+ * \verbatim im.ColorEncode(red: number, green: number, blue: number) -> color: lightuserdata [in Lua 5] \endverbatim
+ * \ingroup colorutl */
+long imColorEncode(unsigned char red, unsigned char green, unsigned char blue);
+
+/** Decode RGB components from a long for palete usage. \n
+ * "long" definition is compatible with the CD library definition.
+ *
+ * \verbatim im.ColorDecode(color: lightuserdata) -> red: number, green: number, blue: number [in Lua 5] \endverbatim
+ * \ingroup colorutl */
+void imColorDecode(unsigned char *red, unsigned char *green, unsigned char *blue, long color);
+
+
+
+/** \defgroup colormodeutl Color Mode Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup imagerep */
+
+/** Returns the color mode name.
+ *
+ * \verbatim im.ColorModeSpaceName(color_mode: number) -> name: string [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+const char* imColorModeSpaceName(int color_mode);
+
+/** Returns the number of components of the color space including alpha.
+ *
+ * \verbatim im.ColorModeDepth(color_mode: number) -> depth: number [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+int imColorModeDepth(int color_mode);
+
+/** Returns the color space of the color mode.
+ *
+ * \verbatim im.ColorModeSpace(color_mode: number) -> color_space: number [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+#define imColorModeSpace(_cm) (_cm & 0xFF)
+
+/** Check if the two color modes match. Only the color space is compared.
+ *
+ * \verbatim im.ColorModeMatch(color_mode1: number, color_mode2: number) -> match: boolean [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+#define imColorModeMatch(_cm1, _cm2) (imColorModeSpace(_cm1) == imColorModeSpace(_cm2))
+
+/** Check if the color mode has an alpha channel.
+ *
+ * \verbatim im.ColorModeHasAlpha(color_mode: number) -> has_alpha: boolean [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+#define imColorModeHasAlpha(_cm) (_cm & IM_ALPHA)
+
+/** Check if the color mode components are packed in one plane.
+ *
+ * \verbatim im.ColorModeIsPacked(color_mode: number) -> is_packed: boolean [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+#define imColorModeIsPacked(_cm) (_cm & IM_PACKED)
+
+/** Check if the color mode orients the image from top down to bottom.
+ *
+ * \verbatim im.ColorModeIsTopDown(color_mode: number) -> is_top_down: boolean [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+#define imColorModeIsTopDown(_cm) (_cm & IM_TOPDOWN)
+
+/** Returns the color space of the equivalent display bitmap image. \n
+ * Original packing and alpha are ignored. Returns IM_RGB, IM_GRAY, IM_MAP or IM_BINARY.
+ *
+ * \verbatim im.ColorModeToBitmap(color_mode: number) -> color_space: number [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+int imColorModeToBitmap(int color_mode);
+
+/** Check if the color mode and data_type defines a display bitmap image.
+ *
+ * \verbatim im.ColorModeIsBitmap(color_mode: number, data_type: number) -> is_bitmap: boolean [in Lua 5] \endverbatim
+ * \ingroup colormodeutl */
+int imColorModeIsBitmap(int color_mode, int data_type);
+
+
+
+/** \defgroup datatypeutl Data Type Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup util
+ * @{
+ */
+
+typedef unsigned char imbyte;
+typedef unsigned short imushort;
+
+#define IM_BYTECROP(_v) (_v < 0? 0: _v > 255? 255: _v)
+#define IM_CROPMAX(_v, _max) (_v < 0? 0: _v > _max? _max: _v)
+
+/** @} */
+
+/** Returns the size in bytes of a specified numeric data type.
+ *
+ * \verbatim im.DataTypeSize(data_type: number) -> size: number [in Lua 5] \endverbatim
+ * \ingroup datatypeutl */
+int imDataTypeSize(int data_type);
+
+/** Returns the numeric data type name given its identifier.
+ *
+ * \verbatim im.DataTypeName(data_type: number) -> name: string [in Lua 5] \endverbatim
+ * \ingroup datatypeutl */
+const char* imDataTypeName(int data_type);
+
+/** Returns the maximum value of an integer data type. For floating point returns 0.
+ *
+ * \verbatim im.DataTypeIntMax(data_type: number) -> int_max: number [in Lua 5] \endverbatim
+ * \ingroup datatypeutl */
+unsigned long imDataTypeIntMax(int data_type);
+
+/** Returns the minimum value of an integer data type. For floating point returns 0.
+ *
+ * \verbatim im.DataTypeIntMin(data_type: number) -> int_min: number [in Lua 5] \endverbatim
+ * \ingroup datatypeutl */
+long imDataTypeIntMin(int data_type);
+
+
+
+/** \defgroup bin Binary Data Utilities
+ * \par
+ * See \ref im_util.h
+ * \ingroup util */
+
+/** CPU Byte Orders.
+ * \ingroup bin */
+enum imByteOrder
+{
+ IM_LITTLEENDIAN, /**< Little Endian - The most significant byte is on the right end of a word. Used by Intel processors. */
+ IM_BIGENDIAN /**< Big Endian - The most significant byte is on the left end of a word. Used by Motorola processors, also is the network standard byte order. */
+};
+
+/** Returns the current CPU byte order.
+ * \ingroup bin */
+int imBinCPUByteOrder(void);
+
+/** Changes the byte order of an array of 2, 4 or 8 byte values.
+ * \ingroup bin */
+void imBinSwapBytes(void *data, int count, int size);
+
+/** Changes the byte order of an array of 2 byte values.
+ * \ingroup bin */
+void imBinSwapBytes2(void *data, int count);
+
+/** Inverts the byte order of the 4 byte values
+ * \ingroup bin */
+void imBinSwapBytes4(void *data, int count);
+
+/** Inverts the byte order of the 8 byte values
+ * \ingroup bin */
+void imBinSwapBytes8(void *data, int count);
+
+
+
+/** \defgroup compress Data Compression Utilities
+ * \par
+ * Deflate compression support uses zlib version 1.2.3. \n
+ * http://www.zlib.org/ \n
+ * Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+ * \par
+ * LZF compression support uses libLZF version 1.51. \n
+ * http://liblzf.plan9.de/ \n
+ * Copyright (C) 2000-2005 Marc Alexander Lehmann
+ * See \ref im_util.h
+ * \ingroup util */
+
+/** Compresses the data using the ZLIB Deflate compression. \n
+ * The destination buffer must be at least 0.1% larger than source_size plus 12 bytes. \n
+ * It compresses raw byte data. zip_quality can be 1 to 9. \n
+ * Returns the size of the compressed buffer or zero if failed.
+ * \ingroup compress */
+int imCompressDataZ(const void* src_data, int src_size, void* dst_data, int dst_size, int zip_quality);
+
+/** Uncompresses the data compressed with the ZLIB Deflate compression. \n
+ * Returns zero if failed.
+ * \ingroup compress */
+int imCompressDataUnZ(const void* src_data, int src_size, void* dst_data, int dst_size);
+
+/** Compresses the data using the libLZF compression. \n
+ * Returns the size of the compressed buffer or zero if failed.
+ * \ingroup compress */
+int imCompressDataLZF(const void* src_data, int src_size, void* dst_data, int dst_size, int zip_quality);
+
+/** Uncompresses the data compressed with the libLZF compression.
+ * Returns zero if failed.
+ * \ingroup compress */
+int imCompressDataUnLZF(const void* src_data, int src_size, void* dst_data, int dst_size);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/include/imlua.h b/include/imlua.h
new file mode 100644
index 0000000..5714dff
--- /dev/null
+++ b/include/imlua.h
@@ -0,0 +1,83 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IMLUA_H
+#define __IMLUA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup imlua IM Lua 5 Binding
+ * \par
+ * Binding for the Lua 5 scripting language. \n
+ * Lua 5.1 Copyright (C) 1994-2005 Lua.org, PUC-Rio \n
+ * R. Ierusalimschy, L. H. de Figueiredo & W. Celes \n
+ * http://www.lua.org
+ * \par
+ * The name of the functions were changed because of the namespace "im" and because of the object orientation. \n
+ * As a general rule use:
+\verbatim
+ imXxx -> im.Xxx
+ IM_XXX -> im.XXX
+ imFileXXX(ifile,... -> ifile:XXX(...
+ imImageXXX(image,... -> image:XXX(...
+\endverbatim
+ * All the objects are garbage collected by the Lua garbage collector.
+ * \par
+ * See \ref imlua.h
+ * \ingroup util */
+
+#ifdef LUA_NOOBJECT /* Lua 3 */
+void imlua_open(void);
+#endif
+
+#ifdef LUA_TNONE /* Lua 5 */
+
+/** Initializes the Lua binding of the main IM library. \n
+ * Returns 1 (leaves the "im" table on the top of the stack).
+ * You must link the application with the "imlua51" library.
+ * \ingroup imlua */
+int imlua_open(lua_State *L);
+int luaopen_imlua(lua_State *L);
+
+/** Pushes an image as a metatable on the stack.
+ * \ingroup imlua */
+void imlua_pushimage(lua_State *L, imImage* image);
+
+/** Gets an image as a metatable from the stack, checks for correct type.
+ * \ingroup imlua */
+imImage* imlua_checkimage(lua_State *L, int param);
+
+/** Initializes the Lua binding of the capture library. \n
+ * Returns 1 (leaves the "im" table on the top of the stack).
+ * You must link the application with the "imlua_capture51" library.
+ * \ingroup imlua */
+int imlua_open_capture(lua_State *L);
+int luaopen_imlua_capture(lua_State *L);
+
+/** Initializes the Lua binding of the process library. \n
+ * Returns 1 (leaves the "im" table on the top of the stack).
+ * You must link the application with the "imlua_process51" library.
+ * \ingroup imlua */
+int imlua_open_process(lua_State *L);
+int luaopen_imlua_process(lua_State *L);
+
+/** Initializes the Lua binding of the fourier transform library. \n
+ * Returns 1 (leaves the "im" table on the top of the stack).
+ * You must link the application with the "imlua_fftw51" library.
+ * \ingroup imlua */
+int imlua_open_fftw(lua_State *L);
+int luaopen_imlua_fftw(lua_State *L);
+
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/old_im.h b/include/old_im.h
new file mode 100644
index 0000000..f000221
--- /dev/null
+++ b/include/old_im.h
@@ -0,0 +1,59 @@
+/** \file
+ * \brief Old API
+ *
+ * See Copyright Notice in im_lib.h
+ */
+
+#ifndef __IM_OLD_H
+#define __IM_OLD_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+enum {IM_BMP, IM_PCX, IM_GIF, IM_TIF, IM_RAS, IM_SGI, IM_JPG, IM_LED, IM_TGA};
+enum {IM_NONE = 0x0000, IM_DEFAULT = 0x0100, IM_COMPRESSED = 0x0200};
+
+#define IM_ERR_READ IM_ERR_ACCESS
+#define IM_ERR_WRITE IM_ERR_ACCESS
+#define IM_ERR_TYPE IM_ERR_DATA
+#define IM_ERR_COMP IM_ERR_COMPRESS
+
+long imEncodeColor(unsigned char red, unsigned char green, unsigned char blue);
+void imDecodeColor(unsigned char* red, unsigned char* green, unsigned char* blue, long palette);
+int imFileFormat(char *filename, int* format);
+int imImageInfo(char *filename, int *width, int *height, int *type, int *palette_count);
+int imLoadRGB(char *filename, unsigned char *red, unsigned char *green, unsigned char *blue);
+int imSaveRGB(int width, int height, int format, unsigned char *red, unsigned char *green, unsigned char *blue, char *filename);
+int imLoadMap(char *filename, unsigned char *map, long *palette);
+int imSaveMap(int width, int height, int format, unsigned char *map, int palette_count, long *palette, char *filename);
+void imRGB2Map(int width, int height, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *map, int palette_count, long *palette);
+void imMap2RGB(int width, int height, unsigned char *map, int palette_count, long *colors, unsigned char *red, unsigned char *green, unsigned char *blue);
+void imRGB2Gray(int width, int height, unsigned char *red, unsigned char *green, unsigned char *blue, unsigned char *map, long *grays);
+void imMap2Gray(int width, int height, unsigned char *map, int palette_count, long *colors, unsigned char *grey_map, long *grays);
+void imResize(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map);
+void imStretch(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map);
+typedef int (*imCallback)(char *filename);
+int imRegisterCallback(imCallback cb, int cb_id, int format);
+
+#define IM_INTERRUPTED -1
+#define IM_ALL -1
+#define IM_COUNTER_CB 0
+typedef int (*imFileCounterCallback)(char *filename, int percent, int io);
+
+#define IM_RESOLUTION_CB 1
+typedef int (*imResolutionCallback)(char *filename, double* xres, double* yres, int* res_unit);
+
+enum {IM_RES_NONE, IM_RES_DPI, IM_RES_DPC};
+
+#define IM_GIF_TRANSPARENT_COLOR_CB 0
+typedef int (*imGifTranspIndex)(char *filename, unsigned char *transp_index);
+
+#define IM_TIF_IMAGE_DESCRIPTION_CB 0
+typedef int (*imTiffImageDesc)(char *filename, char* img_desc);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif