summaryrefslogtreecommitdiff
path: root/src/lua5
diff options
context:
space:
mode:
authorscuri <scuri>2008-10-17 06:10:15 +0000
committerscuri <scuri>2008-10-17 06:10:15 +0000
commit5a422aba704c375a307a902bafe658342e209906 (patch)
tree5005011e086bb863d8fb587ad3319bbec59b2447 /src/lua5
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/lua5')
-rw-r--r--src/lua5/.cvsignore9
-rw-r--r--src/lua5/im_fftw.lua48
-rw-r--r--src/lua5/im_process.lua326
-rw-r--r--src/lua5/imlua.c246
-rw-r--r--src/lua5/imlua.def24
-rw-r--r--src/lua5/imlua_aux.c255
-rw-r--r--src/lua5/imlua_aux.h82
-rw-r--r--src/lua5/imlua_avi.c44
-rw-r--r--src/lua5/imlua_avi.def4
-rw-r--r--src/lua5/imlua_capture.c421
-rw-r--r--src/lua5/imlua_capture.def5
-rw-r--r--src/lua5/imlua_convert.c79
-rw-r--r--src/lua5/imlua_fftw.c162
-rw-r--r--src/lua5/imlua_fftw.def4
-rw-r--r--src/lua5/imlua_file.c661
-rw-r--r--src/lua5/imlua_image.c1061
-rw-r--r--src/lua5/imlua_image.h38
-rw-r--r--src/lua5/imlua_jp2.c44
-rw-r--r--src/lua5/imlua_jp2.def4
-rw-r--r--src/lua5/imlua_kernel.c182
-rw-r--r--src/lua5/imlua_palette.c399
-rw-r--r--src/lua5/imlua_palette.h32
-rw-r--r--src/lua5/imlua_process.c3091
-rw-r--r--src/lua5/imlua_process.def4
-rw-r--r--src/lua5/imlua_util.c279
-rw-r--r--src/lua5/imlua_wmv.c44
-rw-r--r--src/lua5/imlua_wmv.def4
27 files changed, 7552 insertions, 0 deletions
diff --git a/src/lua5/.cvsignore b/src/lua5/.cvsignore
new file mode 100644
index 0000000..521532a
--- /dev/null
+++ b/src/lua5/.cvsignore
@@ -0,0 +1,9 @@
+so_locations
+*.dep
+*.wdep
+*.loh
+.plan
+.project
+*.err
+Makefile
+*.make
diff --git a/src/lua5/im_fftw.lua b/src/lua5/im_fftw.lua
new file mode 100644
index 0000000..e57c7bf
--- /dev/null
+++ b/src/lua5/im_fftw.lua
@@ -0,0 +1,48 @@
+
+-------------------------------------------------------------------------------
+-- Creates a new function, with the name suffixed by "New". This new function
+-- creates a new image, based on a source image, and calls the previous function
+-- with this new image.
+
+local function OneSourceOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ func(src_image, dst_image, unpack(arg))
+ return dst_image
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives two source
+-- images.
+
+local function TwoSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+
+ -- see if function is really defined
+ assert(func, string.format("undefined function `%s'", funcname))
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ func(src_image1, src_image2, dst_image, unpack(arg))
+ return dst_image
+ end
+end
+
+-------------------------------------------------------------------------------
+
+TwoSourcesOneDest("ProcessCrossCorrelation")
+OneSourceOneDest("ProcessAutoCorrelation", nil, nil, nil, im.CFLOAT)
+OneSourceOneDest("ProcessFFT")
+OneSourceOneDest("ProcessIFFT")
diff --git a/src/lua5/im_process.lua b/src/lua5/im_process.lua
new file mode 100644
index 0000000..1d91d5e
--- /dev/null
+++ b/src/lua5/im_process.lua
@@ -0,0 +1,326 @@
+
+-------------------------------------------------------------------------------
+-- Creates a new function, with the name suffixed by "New". This new function
+-- creates a new image, based on a source image, and calls the previous function
+-- with this new image.
+-- We assume here that the functions returns only one parameter or none.
+
+local function OneSourceOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives two source
+-- images.
+
+local function TwoSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+
+ -- see if function is really defined
+ assert(func, string.format("undefined function `%s'", funcname))
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image1, src_image2, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it receives three source
+-- images.
+
+local function ThreeSourcesOneDest (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image1, src_image2, src_image3, ...)
+ -- create destination image
+ local dst_image = im.ImageCreateBased(src_image1, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image1, src_image2, src_image3, dst_image, unpack(arg))
+ if (ret) then
+ return ret, dst_image
+ else
+ return dst_image
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it creates two destiny
+-- images.
+
+local function OneSourceTwoDests (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image1 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image2 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image1, dst_image2, unpack(arg))
+ if (ret) then
+ return ret, dst_image1, dst_image2
+ else
+ return dst_image1, dst_image2
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- This function is similar to OneSourceOneDest, but it creates three destiny
+-- images.
+
+local function OneSourceThreeDests (funcname, width, height, color_space, data_type)
+ local func = im[funcname]
+ assert(func) -- see if function is really defined
+
+ -- define function with "New" suffix
+ im[funcname.."New"] = function (src_image, ...)
+ -- create destination image
+ local dst_image1 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image2 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+ local dst_image3 = im.ImageCreateBased(src_image, width, height, color_space, data_type)
+
+ -- call previous method, repassing all parameters
+ local ret = func(src_image, dst_image1, dst_image2, dst_image3, unpack(arg))
+ if (ret) then
+ return ret, dst_image1, dst_image2, dst_image3
+ else
+ return dst_image1, dst_image2, dst_image3
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+
+local function hough_height(image)
+ local function sqr(x) return x*x end
+ local rmax = math.sqrt(sqr(image:Width()) + sqr(image:Height())) / 2
+ return 2*rmax+1
+end
+
+OneSourceOneDest("AnalyzeFindRegions", nil, nil, nil, im.USHORT)
+OneSourceOneDest("ProcessPerimeterLine")
+OneSourceOneDest("ProcessPrune")
+OneSourceOneDest("ProcessFillHoles")
+OneSourceOneDest("ProcessHoughLines", 180, hough_height, im.GRAY, im.INT)
+OneSourceOneDest("ProcessHoughLinesDraw")
+OneSourceOneDest("ProcessDistanceTransform", nil, nil, nil, im.FLOAT)
+OneSourceOneDest("ProcessRegionalMaximum", nil, nil, im.BINARY, nil)
+
+function im.ProcessReduceNew (src_image, width, height)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessReduce(src_image, dst_image), dst_image
+end
+
+function im.ProcessResizeNew (src_image, width, height)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessResize(src_image, dst_image), dst_image
+end
+
+OneSourceOneDest("ProcessReduceBy4", function (image) return image:Width() / 2 end,
+ function (image) return image:Height() / 2 end)
+
+function im.ProcessCropNew (src_image, xmin, xmax, ymin, ymax)
+ local width = xmax - xmin + 1
+ local height = xmax - ymin + 1
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ im.ProcessCrop(src_image, dst_image, xmin, ymin)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessInsert")
+
+function im.ProcessAddMarginsNew (src_image, xmin, xmax, ymin, ymax)
+ local width = xmax - xmin + 1
+ local height = xmax - ymin + 1
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ im.ProcessAddMargins(src_image, dst_image, xmin, ymin)
+ return dst_image
+end
+
+function im.ProcessRotateNew (src_image, cos0, sin0, order)
+ local width, height = im.ProcessCalcRotateSize(src_image:Width(), src_image:Height(), cos0, sin0)
+ local dst_image = im.ImageCreateBased(src_image, width, height)
+ return im.ProcessRotate(src_image, dst_image, cos0, sin0, order), dst_image
+end
+
+OneSourceOneDest("ProcessRotateRef")
+OneSourceOneDest("ProcessRotate90", function (image) return image:Height() end, function (image) return image:Width() end)
+OneSourceOneDest("ProcessRotate180")
+OneSourceOneDest("ProcessMirror")
+OneSourceOneDest("ProcessFlip")
+OneSourceOneDest("ProcessRadial")
+OneSourceOneDest("ProcessGrayMorphConvolve")
+OneSourceOneDest("ProcessGrayMorphErode")
+OneSourceOneDest("ProcessGrayMorphDilate")
+OneSourceOneDest("ProcessGrayMorphOpen")
+OneSourceOneDest("ProcessGrayMorphClose")
+OneSourceOneDest("ProcessGrayMorphTopHat")
+OneSourceOneDest("ProcessGrayMorphWell")
+OneSourceOneDest("ProcessGrayMorphGradient")
+OneSourceOneDest("ProcessBinMorphConvolve")
+OneSourceOneDest("ProcessBinMorphErode")
+OneSourceOneDest("ProcessBinMorphDilate")
+OneSourceOneDest("ProcessBinMorphOpen")
+OneSourceOneDest("ProcessBinMorphClose")
+OneSourceOneDest("ProcessBinMorphOutline")
+OneSourceOneDest("ProcessBinMorphThin")
+OneSourceOneDest("ProcessMedianConvolve")
+OneSourceOneDest("ProcessRangeConvolve")
+OneSourceOneDest("ProcessRankClosestConvolve")
+OneSourceOneDest("ProcessRankMaxConvolve")
+OneSourceOneDest("ProcessRankMinConvolve")
+OneSourceOneDest("ProcessConvolve")
+OneSourceOneDest("ProcessConvolveSep")
+OneSourceOneDest("ProcessConvolveRep")
+OneSourceOneDest("ProcessConvolveDual")
+OneSourceOneDest("ProcessCompassConvolve")
+OneSourceOneDest("ProcessMeanConvolve")
+OneSourceOneDest("ProcessGaussianConvolve")
+OneSourceOneDest("ProcessBarlettConvolve")
+OneSourceTwoDests("ProcessInterlaceSplit", nil, function (image) if (image:Height()) then return image:Height() else return image:Height()/2 end end)
+
+function im.ProcessInterlaceSplitNew(src_image)
+ -- create destination image
+ local dst_height1 = src_image:Height()/2
+ if math.mod(src_image:Height(), 2) then
+ dst_height1 = dst_height1 + 1
+ end
+
+ local dst_image1 = im.ImageCreateBased(src_image, nil, dst_height1)
+ local dst_image2 = im.ImageCreateBased(src_image, nil, src_image:Height()/2)
+
+ -- call method, repassing all parameters
+ im.ProcessInterlaceSplit(src_image, dst_image1, dst_image2)
+ return dst_image1, dst_image2
+end
+
+local function int_datatype (image)
+ local data_type = image:DataType()
+ if data_type == im.BYTE or data_type == im.USHORT then
+ data_type = im.INT
+ end
+ return data_type
+end
+
+OneSourceOneDest("ProcessDiffOfGaussianConvolve", nil, nil, nil, int_datatype)
+OneSourceOneDest("ProcessLapOfGaussianConvolve", nil, nil, nil, int_datatype)
+OneSourceOneDest("ProcessSobelConvolve")
+OneSourceOneDest("ProcessSplineEdgeConvolve")
+OneSourceOneDest("ProcessPrewittConvolve")
+OneSourceOneDest("ProcessZeroCrossing")
+OneSourceOneDest("ProcessCanny")
+OneSourceOneDest("ProcessUnArithmeticOp")
+TwoSourcesOneDest("ProcessArithmeticOp")
+
+function im.ProcessArithmeticConstOpNew (src_image, src_const, op)
+ local dst_image = im.ImageCreateBased(src_image)
+ im.ProcessArithmeticConstOp(src_image, src_const, dst_image, op)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessBlendConst")
+ThreeSourcesOneDest("ProcessBlend")
+OneSourceTwoDests("ProcessSplitComplex")
+TwoSourcesOneDest("ProcessMergeComplex", nil, nil, nil, im.CFLOAT)
+
+function im.ProcessMultipleMeanNew (src_image_list, dst_image)
+ local dst_image = im.ImageCreateBased(src_image_list[1])
+ im.ProcessMultipleMean(src_image_list, dst_image)
+ return dst_image
+end
+
+function im.ProcessMultipleStdDevNew (src_image_list, mean_image)
+ local dst_image = im.ImageCreateBased(src_image_list[1])
+ im.ProcessMultipleStdDev(src_image_list, mean_image, dst_image)
+ return dst_image
+end
+
+TwoSourcesOneDest("ProcessAutoCovariance")
+OneSourceOneDest("ProcessMultiplyConj")
+OneSourceOneDest("ProcessQuantizeRGBUniform", nil, nil, im.MAP, nil)
+OneSourceOneDest("ProcessQuantizeGrayUniform")
+OneSourceOneDest("ProcessExpandHistogram")
+OneSourceOneDest("ProcessEqualizeHistogram")
+
+function im.ProcessSplitYChromaNew (src_image)
+ local y_image = im.ImageCreateBased(src_image, nil, nil, im.GRAY, im.BYTE)
+ local chroma_image = im.ImageCreateBased(src_image, nil, nil, im.RGB, im.BYTE)
+ im.ProcessSplitYChroma(src_image, y_image, chroma_image)
+ return y_image, chroma_image
+end
+
+OneSourceThreeDests("ProcessSplitHSI", nil, nil, im.GRAY, im.FLOAT)
+ThreeSourcesOneDest("ProcessMergeHSI", nil, nil, im.RGB, im.BYTE)
+
+function im.ProcessSplitComponentsNew (src_image)
+ local depth = src_image:Depth()
+ local dst_images = {}
+ for i = 1, depth do
+ table.insert(dst_images, im.ImageCreateBased(src_image, nil, nil, im.GRAY))
+ end
+ im.ProcessSplitComponents(src_image, dst_images)
+ return unpack(dst_images)
+end
+
+function im.ProcessMergeComponentsNew (src_image_list)
+ local dst_image = im.ImageCreateBased(src_image_list[1], nil, nil, im.RGB)
+ im.ProcessMergeComponents(src_image_list, dst_image)
+ return dst_image
+end
+
+OneSourceOneDest("ProcessNormalizeComponents", nil, nil, nil, im.FLOAT)
+OneSourceOneDest("ProcessReplaceColor")
+TwoSourcesOneDest("ProcessBitwiseOp")
+OneSourceOneDest("ProcessBitwiseNot")
+OneSourceOneDest("ProcessBitMask")
+OneSourceOneDest("ProcessBitPlane")
+OneSourceOneDest("ProcessToneGamut")
+OneSourceOneDest("ProcessUnNormalize", nil, nil, nil, im.BYTE)
+OneSourceOneDest("ProcessDirectConv", nil, nil, nil, im.BYTE)
+OneSourceOneDest("ProcessNegative")
+OneSourceOneDest("ProcessRangeContrastThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessLocalMaxThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessThreshold", nil, nil, im.BINARY, nil)
+TwoSourcesOneDest("ProcessThresholdByDiff")
+OneSourceOneDest("ProcessHysteresisThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessUniformErrThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessDifusionErrThreshold")
+OneSourceOneDest("ProcessPercentThreshold")
+OneSourceOneDest("ProcessOtsuThreshold")
+OneSourceOneDest("ProcessMinMaxThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessSliceThreshold", nil, nil, im.BINARY, nil)
+OneSourceOneDest("ProcessPixelate")
+OneSourceOneDest("ProcessPosterize")
+
diff --git a/src/lua5/imlua.c b/src/lua5/imlua.c
new file mode 100644
index 0000000..7d39ee7
--- /dev/null
+++ b/src/lua5/imlua.c
@@ -0,0 +1,246 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_lib.h"
+#include "im_image.h"
+#include "im_convert.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+
+/*****************************************************************************\
+ im.Version()
+\*****************************************************************************/
+static int imluaVersion (lua_State *L)
+{
+ lua_pushstring(L, imVersion());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VersionDate()
+\*****************************************************************************/
+static int imluaVersionDate (lua_State *L)
+{
+ lua_pushstring(L, imVersionDate());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VersionNumber()
+\*****************************************************************************/
+static int imluaVersionNumber (lua_State *L)
+{
+ lua_pushnumber(L, imVersionNumber());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FormatList()
+\*****************************************************************************/
+static int imluaFormatList (lua_State *L)
+{
+ int i, format_count;
+ char *format_list[50];
+
+ imFormatList(format_list, &format_count);
+
+ lua_newtable(L);
+ for (i = 0; i < format_count; i++)
+ {
+ lua_pushstring(L, format_list[i]);
+ lua_settable(L, -2);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FormatInfo(format)
+\*****************************************************************************/
+static int imluaFormatInfo (lua_State *L)
+{
+ char desc[50];
+ char ext[50];
+ int can_sequence;
+ int error;
+
+ error = imFormatInfo(luaL_checkstring(L, 1), desc, ext, &can_sequence);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_pushstring(L, desc);
+ lua_pushstring(L, ext);
+ lua_pushboolean(L, can_sequence);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ im.FormatCompressions(format)
+\*****************************************************************************/
+static int imluaFormatCompressions (lua_State *L)
+{
+ int i, comp_count;
+ int error;
+ char *comp[50];
+
+ int color_mode = luaL_optint(L, 2, -1);
+ int data_type = luaL_optint(L, 3, -1);
+
+ error = imFormatCompressions(luaL_checkstring(L, 1), comp, &comp_count, color_mode, data_type);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_newtable(L);
+ for (i = 0; i < comp_count; i++)
+ {
+ lua_pushstring(L, comp[i]);
+ lua_settable(L, -2);
+ }
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.FormatCanWriteImage(format, compression, color_mode, data_type)
+\*****************************************************************************/
+static int imluaFormatCanWriteImage (lua_State *L)
+{
+ const char *format = luaL_checkstring(L, 1);
+ const char *compression = luaL_checkstring(L, 2);
+ int color_mode = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ lua_pushboolean(L, imFormatCanWriteImage(format, compression, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ Constants
+\*****************************************************************************/
+static const imlua_constant im_constants[] = {
+
+ { "BYTE", IM_BYTE, NULL },
+ { "USHORT", IM_USHORT, NULL },
+ { "INT", IM_INT, NULL },
+ { "FLOAT", IM_FLOAT, NULL },
+ { "CFLOAT", IM_CFLOAT, NULL },
+
+ { "RGB", IM_RGB, NULL },
+ { "MAP", IM_MAP, NULL },
+ { "GRAY", IM_GRAY, NULL },
+ { "BINARY", IM_BINARY, NULL },
+ { "CMYK", IM_CMYK, NULL },
+ { "YCBCR", IM_YCBCR, NULL },
+ { "LAB", IM_LAB, NULL },
+ { "LUV", IM_LUV, NULL },
+ { "XYZ", IM_XYZ, NULL },
+
+ { "ALPHA", IM_ALPHA, NULL },
+ { "PACKED", IM_PACKED, NULL },
+ { "TOPDOWN", IM_TOPDOWN, NULL },
+
+ { "ERR_NONE", IM_ERR_NONE, NULL },
+ { "ERR_OPEN", IM_ERR_OPEN, NULL },
+ { "ERR_ACCESS", IM_ERR_ACCESS, NULL },
+ { "ERR_FORMAT", IM_ERR_FORMAT, NULL },
+ { "ERR_DATA", IM_ERR_DATA, NULL },
+ { "ERR_COMPRESS", IM_ERR_COMPRESS, NULL },
+ { "ERR_MEM", IM_ERR_MEM, NULL },
+ { "ERR_COUNTER", IM_ERR_COUNTER, NULL },
+
+ { "CPX_REAL", IM_CPX_REAL, NULL },
+ { "CPX_IMAG", IM_CPX_IMAG, NULL },
+ { "CPX_MAG", IM_CPX_MAG, NULL },
+ { "CPX_PHASE", IM_CPX_PHASE, NULL },
+
+ { "GAMMA_LINEAR", IM_GAMMA_LINEAR, NULL },
+ { "GAMMA_LOGLITE", IM_GAMMA_LOGLITE, NULL },
+ { "GAMMA_LOGHEAVY", IM_GAMMA_LOGHEAVY, NULL },
+ { "GAMMA_EXPLITE", IM_GAMMA_EXPLITE, NULL },
+ { "GAMMA_EXPHEAVY", IM_GAMMA_EXPHEAVY, NULL },
+
+ { "CAST_MINMAX", IM_CAST_MINMAX, NULL },
+ { "CAST_FIXED", IM_CAST_FIXED, NULL },
+ { "CAST_DIRECT", IM_CAST_DIRECT, NULL },
+
+ { "_AUTHOR", 0, IM_AUTHOR },
+ { "_COPYRIGHT", 0, IM_COPYRIGHT },
+ { "_VERSION", 0, IM_VERSION },
+ { "_VERSION_NUMBER", IM_VERSION_NUMBER, NULL },
+ { "_VERSION_DATE", 0, IM_VERSION_DATE },
+ { "_DESCRIPTION", 0, IM_DESCRIPTION },
+ { "_NAME", 0, IM_NAME },
+
+ { NULL, -1, NULL },
+};
+
+void imlua_regconstants (lua_State *L, const imlua_constant *imconst)
+{
+ const imlua_constant *l = imconst;
+ for (; l->name; l++)
+ {
+ lua_pushstring(L, l->name);
+ if (l->str_value)
+ lua_pushstring(L, l->str_value);
+ else
+ lua_pushnumber(L, l->value);
+ lua_settable(L, -3);
+ }
+}
+
+static const luaL_reg im_lib[] = {
+ {"Version", imluaVersion},
+ {"VersionDate", imluaVersionDate},
+ {"VersionNumber", imluaVersionNumber},
+
+ {"FormatList", imluaFormatList},
+ {"FormatInfo", imluaFormatInfo},
+ {"FormatCompressions", imluaFormatCompressions},
+ {"FormatCanWriteImage", imluaFormatCanWriteImage},
+
+ {NULL, NULL}
+};
+
+int imlua_open (lua_State *L)
+{
+ luaL_register(L, "im", im_lib); /* leave "im" table at the top of the stack */
+ imlua_regconstants(L, im_constants);
+
+ imlua_open_file(L);
+ imlua_open_image(L);
+ imlua_open_convert(L);
+ imlua_open_util(L);
+ imlua_open_palette(L);
+
+ return 1;
+}
+
+int luaopen_imlua(lua_State *L)
+{
+ return imlua_open(L);
+}
+
+int luaopen_imlua51(lua_State *L)
+{
+ return imlua_open(L);
+}
diff --git a/src/lua5/imlua.def b/src/lua5/imlua.def
new file mode 100644
index 0000000..259c822
--- /dev/null
+++ b/src/lua5/imlua.def
@@ -0,0 +1,24 @@
+EXPORTS
+ luaopen_imlua
+ luaopen_imlua51
+ imlua_open
+ imlua_checkimage
+ imlua_newarrayulong
+ imlua_newarrayint
+ imlua_newarrayfloat
+ imlua_checkdatatype
+ imlua_checkcolorspace
+ imlua_toarrayint
+ imlua_toarrayfloat
+ imlua_toarrayulong
+ imlua_getn
+ imlua_checktype
+ imlua_checkmask
+ imlua_regconstants
+ imlua_pushimage
+ imlua_matchcolor
+ imlua_matchsize
+ imlua_matchdatatype
+ imlua_matchcolorspace
+ imlua_match
+ \ No newline at end of file
diff --git a/src/lua5/imlua_aux.c b/src/lua5/imlua_aux.c
new file mode 100644
index 0000000..d5df8ac
--- /dev/null
+++ b/src/lua5/imlua_aux.c
@@ -0,0 +1,255 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_aux.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <memory.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+/*****************************************************************************\
+\*****************************************************************************/
+int imlua_getn (lua_State *L, int index)
+{
+ int n;
+ lua_pushstring(L, "table");
+ lua_gettable(L, LUA_GLOBALSINDEX);
+ lua_pushstring(L, "getn");
+ lua_gettable(L, -2);
+ lua_pushvalue(L, index);
+ lua_call(L, 1, 1);
+ n = luaL_checkint(L, -1);
+ lua_pop(L, 2);
+ return n;
+}
+
+/*****************************************************************************\
+ Creates an int array.
+\*****************************************************************************/
+int imlua_newarrayint (lua_State *L, int *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Creates an unsigned long array.
+\*****************************************************************************/
+int imlua_newarrayulong (lua_State *L, unsigned long *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Creates a float array.
+\*****************************************************************************/
+int imlua_newarrayfloat (lua_State *L, float *value, int count, int start)
+{
+ int i;
+ lua_newtable(L);
+ for (i = 0; i < count; i++)
+ {
+ lua_pushnumber(L, value[i]);
+ lua_rawseti(L, -2, i+start);
+ }
+ return 1;
+}
+
+/*****************************************************************************\
+ Retrieve an int array.
+\*****************************************************************************/
+int *imlua_toarrayint (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ int *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (int*) malloc (sizeof(int) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+/*****************************************************************************\
+ Retrieve an ulong array.
+\*****************************************************************************/
+unsigned long *imlua_toarrayulong (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ unsigned long *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (unsigned long*) malloc (sizeof(unsigned long) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+/*****************************************************************************\
+ Retrieve a float array.
+\*****************************************************************************/
+float *imlua_toarrayfloat (lua_State *L, int index, int *count, int start)
+{
+ int i, n;
+ float *value = NULL;
+
+ if (lua_istable(L, index))
+ {
+ n = imlua_getn(L, index);
+ if (start == 0) n++;
+ if (count) *count = n;
+
+ value = (float*) malloc (sizeof(float) * n);
+ for (i = 0; i < n; i++)
+ {
+ lua_rawgeti(L, index, i+start);
+ value[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ return value;
+}
+
+
+/*****************************************************************************\
+ Creates a bit mask based on a string formatted as "11000110".
+\*****************************************************************************/
+unsigned char imlua_checkmask (lua_State *L, int index)
+{
+ int i;
+ unsigned char mask = 0;
+ const char *str = luaL_checkstring(L, index);
+ if (strlen(str) != 8)
+ luaL_argerror(L, index, "invalid mask, must have 8 elements");
+
+ for (i = 0; i < 8; i++)
+ {
+ char c = str[i];
+ if (c != '0' && c != '1')
+ luaL_argerror(L, index, "invalid mask, must have 0s or 1s only");
+
+ mask |= (c - '0') << (7 - i);
+ }
+
+ return mask;
+}
+
+/*****************************************************************************\
+ Checks data_type and color_space of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checktype (lua_State *L, int index, imImage *image, int color_space, int data_type)
+{
+ if (image->data_type != data_type)
+ {
+ char msg[100] = "image data type must be ";
+ strcat(msg, imDataTypeName(data_type));
+ luaL_argerror(L, index, msg);
+ }
+
+ if (image->color_space != color_space)
+ {
+ char msg[100] = "image color space must be ";
+ strcat(msg, imColorModeSpaceName(color_space));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks color_space of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checkcolorspace (lua_State *L, int index, imImage *image, int color_space)
+{
+ if (image->color_space != color_space)
+ {
+ char msg[100] = "image color space must be ";
+ strcat(msg, imColorModeSpaceName(color_space));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks a data_type of an image. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_checkdatatype (lua_State *L, int index, imImage *image, int data_type)
+{
+ if (image->data_type != data_type)
+ {
+ char msg[100] = "image data type must be ";
+ strcat(msg, imDataTypeName(data_type));
+ luaL_argerror(L, index, msg);
+ }
+}
+
+/*****************************************************************************\
+ Checks if the size of the two images are equal. If it doesn't match throw a lua error.
+\*****************************************************************************/
+void imlua_matchsize(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchSize(image1, image2), "images must have the same size");
+}
+
+void imlua_matchcolor(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchColor(image1, image2), "images must have the same data type and color space");
+}
+
+void imlua_matchdatatype(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchDataType(image1, image2), "images must have the same size and data type");
+}
+
+void imlua_matchcolorspace(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatchColorSpace(image1, image2), "images must have the same size and color space");
+}
+
+void imlua_match(lua_State *L, imImage *image1, imImage *image2)
+{
+ imlua_matchcheck(L, imImageMatch(image1, image2), "images must have the same size, data type and color space");
+}
diff --git a/src/lua5/imlua_aux.h b/src/lua5/imlua_aux.h
new file mode 100644
index 0000000..2dc4466
--- /dev/null
+++ b/src/lua5/imlua_aux.h
@@ -0,0 +1,82 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_aux.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_AUX_H
+#define __IMLUA_AUX_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/********************************/
+/* exported from "imlua_aux.c". */
+/********************************/
+
+/* get table size */
+
+int imlua_getn(lua_State *L, int index);
+
+/* array */
+
+int imlua_newarrayint(lua_State *L, int *value, int count, int start);
+int imlua_newarrayulong(lua_State *L, unsigned long *value, int count, int start);
+int imlua_newarrayfloat(lua_State *L, float *value, int count, int start);
+
+int *imlua_toarrayint(lua_State *L, int index, int *count, int start);
+unsigned long *imlua_toarrayulong (lua_State *L, int index, int *count, int start);
+float *imlua_toarrayfloat(lua_State *L, int index, int *count, int start);
+
+/* other parameter checking */
+
+unsigned char imlua_checkmask(lua_State *L, int index);
+
+void imlua_checktype(lua_State *L, int index, imImage *image, int color_space, int data_type);
+void imlua_checkdatatype(lua_State *L, int index, imImage *image, int data_type);
+void imlua_checkcolorspace(lua_State *L, int index, imImage *image, int color_space);
+
+void imlua_matchsize(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchcolor(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchdatatype(lua_State *L, imImage *image1, imImage *image2);
+void imlua_matchcolorspace(lua_State *L, imImage *image1, imImage *image2);
+void imlua_match(lua_State *L, imImage *image1, imImage *image2);
+
+/* used only when comparing two images */
+#define imlua_matchcheck(L, cond, extramsg) if (!(cond)) \
+ luaL_error(L, extramsg)
+
+#define imlua_pusherror(L, _e) ((_e == IM_ERR_NONE)? lua_pushnil(L): lua_pushnumber(L, _e))
+
+
+/********************************/
+/* exported from "imlua.c". */
+/********************************/
+
+/* constant registration. */
+
+typedef struct _imlua_constant {
+ const char *name;
+ lua_Number value;
+ const char *str_value;
+} imlua_constant;
+
+void imlua_regconstants(lua_State *L, const imlua_constant *imconst);
+
+
+/********************************/
+/* private module open */
+/********************************/
+
+void imlua_open_convert(lua_State *L); /* imlua_convert.c */
+void imlua_open_util(lua_State *L); /* imlua_util.c */
+void imlua_open_file(lua_State *L); /* imlua_file.c */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lua5/imlua_avi.c b/src/lua5/imlua_avi.c
new file mode 100644
index 0000000..f2cd7f4
--- /dev/null
+++ b/src/lua5/imlua_avi.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief AVI format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_avi.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterAVI(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterAVI();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterAVI", imlua_FormatRegisterAVI},
+ {NULL, NULL},
+};
+
+
+static int imlua_avi_open (lua_State *L)
+{
+ imFormatRegisterAVI();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_avi(lua_State* L)
+{
+ return imlua_avi_open(L);
+}
+
+int luaopen_imlua_avi51(lua_State* L)
+{
+ return imlua_avi_open(L);
+}
diff --git a/src/lua5/imlua_avi.def b/src/lua5/imlua_avi.def
new file mode 100644
index 0000000..3086a0d
--- /dev/null
+++ b/src/lua5/imlua_avi.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_avi
+ luaopen_imlua_avi51
+ \ No newline at end of file
diff --git a/src/lua5/imlua_capture.c b/src/lua5/imlua_capture.c
new file mode 100644
index 0000000..15d52ce
--- /dev/null
+++ b/src/lua5/imlua_capture.c
@@ -0,0 +1,421 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_capture.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_capture.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+
+static imVideoCapture** imlua_rawcheckvideocapture (lua_State *L, int param)
+{
+ return (imVideoCapture**)luaL_checkudata(L, param, "imVideoCapture");
+}
+
+static imVideoCapture* imlua_checkvideocapture (lua_State *L, int param)
+{
+ imVideoCapture** vc_p = imlua_rawcheckvideocapture(L, param);
+
+ if (!(*vc_p))
+ luaL_argerror(L, param, "destroyed imVideoCapture");
+
+ return *vc_p;
+}
+
+static void imlua_pushvideocapture(lua_State *L, imVideoCapture* vc)
+{
+ if (!vc)
+ lua_pushnil(L);
+ else
+ {
+ imVideoCapture** vc_p = (imVideoCapture**) lua_newuserdata(L, sizeof(imVideoCapture*));
+ *vc_p = vc;
+ luaL_getmetatable(L, "imVideoCapture");
+ lua_setmetatable(L, -2);
+ }
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceCount()
+\*****************************************************************************/
+static int imluaVideoCaptureDeviceCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureDeviceCount());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceDesc(device)
+\*****************************************************************************/
+static int imluaVideoCaptureDeviceDesc (lua_State *L)
+{
+ lua_pushstring(L, imVideoCaptureDeviceDesc(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureDeviceDesc(device)
+\*****************************************************************************/
+static int imluaVideoCaptureReloadDevices (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureReloadDevices());
+ return 1;
+}
+
+/*****************************************************************************\
+ im.VideoCaptureCreate()
+\*****************************************************************************/
+static int imluaVideoCaptureCreate (lua_State *L)
+{
+ imlua_pushvideocapture(L, imVideoCaptureCreate());
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Connect([device])
+\*****************************************************************************/
+static int imluaVideoCaptureConnect (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int device = luaL_optint(L, 2, -1);
+ lua_pushnumber(L, imVideoCaptureConnect(vc, device));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Disconnect()
+\*****************************************************************************/
+static int imluaVideoCaptureDisconnect (lua_State *L)
+{
+ imVideoCaptureDisconnect(imlua_checkvideocapture(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ vc:DialogCount()
+\*****************************************************************************/
+static int imluaVideoCaptureDialogCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureDialogCount(imlua_checkvideocapture(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:ShowDialog()
+\*****************************************************************************/
+static int imluaVideoCaptureShowDialog (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int dialog = luaL_checkint(L, 2);
+ void *parent = lua_touserdata(L, 3);
+
+ lua_pushnumber(L, imVideoCaptureShowDialog(vc, dialog, parent));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:DialogDesc()
+\*****************************************************************************/
+static int imluaVideoCaptureDialogDesc (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int dialog = luaL_checkint(L, 2);
+
+ lua_pushstring(L, imVideoCaptureDialogDesc(vc, dialog));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:FormatCount()
+\*****************************************************************************/
+static int imluaVideoCaptureFormatCount (lua_State *L)
+{
+ lua_pushnumber(L, imVideoCaptureFormatCount(imlua_checkvideocapture(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:GetFormat()
+\*****************************************************************************/
+static int imluaVideoCaptureGetFormat (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int format = luaL_checkint(L, 2);
+ int width, height;
+ char desc[10];
+
+ lua_pushnumber(L, imVideoCaptureGetFormat(vc, format, &width, &height, desc));
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+ lua_pushstring(L, desc);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ vc:GetImageSize()
+\*****************************************************************************/
+static int imluaVideoCaptureGetImageSize (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int width, height;
+
+ imVideoCaptureGetImageSize(vc, &width, &height);
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ vc:SetImageSize()
+\*****************************************************************************/
+static int imluaVideoCaptureSetImageSize (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imVideoCaptureSetImageSize(vc, width, height));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:SetFormat()
+\*****************************************************************************/
+static int imluaVideoCaptureSetFormat (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int format = luaL_checkint(L, 2);
+
+ lua_pushnumber(L, imVideoCaptureSetFormat(vc, format));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:ResetAttribute(attrib, fauto)
+\*****************************************************************************/
+static int imluaVideoCaptureResetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int fauto = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imVideoCaptureResetAttribute(vc, attrib, fauto));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:SetAttribute(attrib, percent)
+\*****************************************************************************/
+static int imluaVideoCaptureSetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ lua_pushnumber(L, imVideoCaptureSetAttribute(vc, attrib, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaVideoCaptureGetAttribute (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ float percent;
+
+ lua_pushnumber(L, imVideoCaptureGetAttribute(vc, attrib, &percent));
+ lua_pushnumber(L, percent);
+ return 2;
+}
+
+/*****************************************************************************\
+ vc:GetAttributeList()
+\*****************************************************************************/
+static int imluaVideoCaptureGetAttributeList (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int num_attrib;
+ const char **attribs;
+ int i;
+
+ attribs = imVideoCaptureGetAttributeList(vc, &num_attrib);
+ lua_newtable(L);
+ for (i = 0; i < num_attrib; i++)
+ {
+ lua_pushstring(L, attribs[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Frame(image)
+\*****************************************************************************/
+static int imluaVideoCaptureFrame (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+ int timeout = luaL_checkint(L, 3);
+
+ if (!(image->color_space == IM_RGB || image->color_space == IM_GRAY))
+ luaL_argerror(L, 2, "image must be of RGB or Gray color spaces");
+ imlua_checkdatatype(L, 2, image, IM_BYTE);
+
+ lua_pushnumber(L, imVideoCaptureFrame(vc, image->data[0], image->color_space, timeout));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:OneFrame(image)
+\*****************************************************************************/
+static int imluaVideoCaptureOneFrame (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+
+ if (!(image->color_space == IM_RGB || image->color_space == IM_GRAY))
+ luaL_argerror(L, 2, "image must be of RGB or Gray color spaces");
+ imlua_checkdatatype(L, 2, image, IM_BYTE);
+
+ lua_pushnumber(L, imVideoCaptureOneFrame(vc, image->data[0], image->color_space));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Live(image)
+\*****************************************************************************/
+static int imluaVideoCaptureLive (lua_State *L)
+{
+ imVideoCapture *vc = imlua_checkvideocapture(L, 1);
+ int live = luaL_checkint(L, 2);
+
+ lua_pushnumber(L, imVideoCaptureLive(vc, live));
+
+ return 1;
+}
+
+/*****************************************************************************\
+ vc:Destroy()
+\*****************************************************************************/
+static int imluaVideoCaptureDestroy (lua_State *L)
+{
+ imVideoCapture **vc_p = imlua_rawcheckvideocapture(L, 1);
+ if (!(*vc_p))
+ luaL_argerror(L, 1, "destroyed imVideoCapture");
+
+ imVideoCaptureDestroy(*vc_p);
+ *vc_p = NULL; /* mark as destroyed */
+
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaVideoCapture_gc (lua_State *L)
+{
+ imVideoCapture **vc_p = (imVideoCapture **)lua_touserdata(L, 1);
+ if (*vc_p)
+ {
+ imVideoCaptureDestroy(*vc_p);
+ *vc_p = NULL; /* mark as destroyed */
+ }
+ return 0;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaVideoCapture_tostring (lua_State *L)
+{
+ imVideoCapture **vc_p = (imVideoCapture **)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imVideoCapture (%p)%s", vc_p, (*vc_p)? "": "-destroyed");
+ return 1;
+}
+
+static const luaL_reg imcapture_lib[] = {
+ {"VideoCaptureDeviceCount", imluaVideoCaptureDeviceCount},
+ {"VideoCaptureDeviceDesc", imluaVideoCaptureDeviceDesc},
+ {"VideoCaptureReloadDevices", imluaVideoCaptureReloadDevices},
+ {"VideoCaptureCreate", imluaVideoCaptureCreate},
+ {"VideoCaptureDestroy", imluaVideoCaptureDestroy},
+ {NULL, NULL}
+};
+
+static const luaL_reg imcapture_metalib[] = {
+ {"Destroy", imluaVideoCaptureDestroy},
+ {"Connect", imluaVideoCaptureConnect},
+ {"Disconnect", imluaVideoCaptureDisconnect},
+ {"DialogCount", imluaVideoCaptureDialogCount},
+ {"ShowDialog", imluaVideoCaptureShowDialog},
+ {"DialogDesc", imluaVideoCaptureDialogDesc},
+ {"FormatCount", imluaVideoCaptureFormatCount},
+ {"GetFormat", imluaVideoCaptureGetFormat},
+ {"SetFormat", imluaVideoCaptureSetFormat},
+ {"GetImageSize", imluaVideoCaptureGetImageSize},
+ {"SetImageSize", imluaVideoCaptureSetImageSize},
+ {"ResetAttribute", imluaVideoCaptureResetAttribute},
+ {"GetAttribute", imluaVideoCaptureGetAttribute},
+ {"SetAttribute", imluaVideoCaptureSetAttribute},
+ {"GetAttributeList", imluaVideoCaptureGetAttributeList},
+ {"OneFrame", imluaVideoCaptureOneFrame},
+ {"Frame", imluaVideoCaptureFrame},
+ {"Live", imluaVideoCaptureLive},
+
+ {"__gc", imluaVideoCapture_gc},
+ {"__tostring", imluaVideoCapture_tostring},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imVideoCapture"); /* create new metatable for imVideoCapture handle */
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imcapture_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+int imlua_open_capture(lua_State *L)
+{
+ createmeta(L);
+ luaL_register(L, "im", imcapture_lib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_capture(lua_State *L)
+{
+ return imlua_open_capture(L);
+}
+
+int luaopen_imlua_capture51(lua_State *L)
+{
+ return imlua_open_capture(L);
+}
+
diff --git a/src/lua5/imlua_capture.def b/src/lua5/imlua_capture.def
new file mode 100644
index 0000000..1b279cf
--- /dev/null
+++ b/src/lua5/imlua_capture.def
@@ -0,0 +1,5 @@
+EXPORTS
+ imlua_open_capture
+ luaopen_imlua_capture
+ luaopen_imlua_capture51
+ \ No newline at end of file
diff --git a/src/lua5/imlua_convert.c b/src/lua5/imlua_convert.c
new file mode 100644
index 0000000..5ec73c9
--- /dev/null
+++ b/src/lua5/imlua_convert.c
@@ -0,0 +1,79 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_convert.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_image.h"
+#include "im_convert.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_image.h"
+#include "imlua_aux.h"
+
+/*****************************************************************************\
+ im.ConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode)
+\*****************************************************************************/
+static int imluaConvertDataType (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int cpx2real = luaL_checkint(L, 3);
+ float gamma = (float) luaL_checknumber(L, 4);
+ int abssolute = luaL_checkint(L, 5);
+ int cast_mode = luaL_checkint(L, 6);
+
+ imlua_matchcolorspace(L, src_image, dst_image);
+ imlua_pusherror(L, imConvertDataType(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ConvertColorSpace(src_image, dst_image)
+\*****************************************************************************/
+static int imluaConvertColorSpace (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchdatatype(L, src_image, dst_image);
+ imlua_pusherror(L, imConvertColorSpace(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ConvertToBitmap(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode)
+\*****************************************************************************/
+static int imluaConvertToBitmap (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int cpx2real = luaL_checkint(L, 3);
+ float gamma = (float) luaL_checknumber(L, 4);
+ int abssolute = luaL_checkint(L, 5);
+ int cast_mode = luaL_checkint(L, 6);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_matchcheck(L, imImageIsBitmap(dst_image), "image must be a bitmap");
+
+ imlua_pusherror(L, imConvertToBitmap(src_image, dst_image, cpx2real, gamma, abssolute, cast_mode));
+ return 1;
+}
+
+static const luaL_reg imconvert_lib[] = {
+ {"ConvertDataType", imluaConvertDataType},
+ {"ConvertColorSpace", imluaConvertColorSpace},
+ {"ConvertToBitmap", imluaConvertToBitmap},
+ {NULL, NULL}
+};
+
+void imlua_open_convert (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imconvert_lib);
+}
diff --git a/src/lua5/imlua_fftw.c b/src/lua5/imlua_fftw.c
new file mode 100644
index 0000000..0966572
--- /dev/null
+++ b/src/lua5/imlua_fftw.c
@@ -0,0 +1,162 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_fftw.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <memory.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+/*****************************************************************************\
+ Domain Transform Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessFFT(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessFFT (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessFFT(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessIFFT(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessIFFT (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessIFFT(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFFTRaw(src_image, inverse, center, normalize)
+\*****************************************************************************/
+static int imluaProcessFFTraw (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int inverse = luaL_checkint(L, 2);
+ int center = luaL_checkint(L, 3);
+ int normalize = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+
+ imProcessFFTraw(src_image, inverse, center, normalize);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSwapQuadrants(src_image, inverse, center, normalize)
+\*****************************************************************************/
+static int imluaProcessSwapQuadrants (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int center2origin = luaL_checkint(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+
+ imProcessSwapQuadrants(src_image, center2origin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCrossCorrelation(image1, image2, dst_image)
+\*****************************************************************************/
+static int imluaProcessCrossCorrelation (lua_State *L)
+{
+ imImage* image1 = imlua_checkimage(L, 1);
+ imImage* image2 = imlua_checkimage(L, 2);
+ imImage* dst_image = imlua_checkimage(L, 3);
+
+ imlua_matchsize(L, image1, dst_image);
+ imlua_matchsize(L, image2, dst_image);
+ imlua_checkdatatype(L, 3, dst_image, IM_CFLOAT);
+
+ imProcessCrossCorrelation(image1, image2, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAutoCorrelation(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessAutoCorrelation (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchsize(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_CFLOAT);
+
+ imProcessAutoCorrelation(src_image, dst_image);
+ return 0;
+}
+
+static const luaL_reg imfftw_lib[] = {
+ {"ProcessFFT", imluaProcessFFT},
+ {"ProcessIFFT", imluaProcessIFFT},
+ {"ProcessFFTraw", imluaProcessFFTraw},
+ {"ProcessSwapQuadrants", imluaProcessSwapQuadrants},
+ {"ProcessCrossCorrelation", imluaProcessCrossCorrelation},
+ {"ProcessAutoCorrelation", imluaProcessAutoCorrelation},
+
+ {NULL, NULL}
+};
+
+int imlua_open_fftw (lua_State *L)
+{
+ luaL_register(L, "im", imfftw_lib); /* leave "im" table at the top of the stack */
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "im_fftw_be64.loh"
+#else
+#include "im_fftw_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "im_fftw_le64w.loh"
+#else
+#include "im_fftw_le64.loh"
+#endif
+#else
+#include "im_fftw.loh"
+#endif
+#endif
+ return 1;
+}
+
+int luaopen_imlua_fftw(lua_State *L)
+{
+ return imlua_open_fftw(L);
+}
+
+int luaopen_imlua_fftw51(lua_State *L)
+{
+ return imlua_open_fftw(L);
+}
diff --git a/src/lua5/imlua_fftw.def b/src/lua5/imlua_fftw.def
new file mode 100644
index 0000000..216c967
--- /dev/null
+++ b/src/lua5/imlua_fftw.def
@@ -0,0 +1,4 @@
+EXPORTS
+ imlua_open_fftw
+ luaopen_imlua_fftw
+ luaopen_imlua_fftw51 \ No newline at end of file
diff --git a/src/lua5/imlua_file.c b/src/lua5/imlua_file.c
new file mode 100644
index 0000000..fd20c36
--- /dev/null
+++ b/src/lua5/imlua_file.c
@@ -0,0 +1,661 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_file.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_raw.h"
+#include "im_image.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+
+
+
+static imFile** imlua_rawcheckfile(lua_State *L, int param)
+{
+ return (imFile**)luaL_checkudata(L, param, "imFile");
+}
+
+static imFile* imlua_checkfile (lua_State *L, int param)
+{
+ imFile** ifile_p = imlua_rawcheckfile(L, param);
+
+ if (!(*ifile_p))
+ luaL_argerror(L, param, "closed imFile");
+
+ return *ifile_p;
+}
+
+static int imlua_pushifileerror(lua_State *L, imFile* ifile, int error)
+{
+ if (error)
+ {
+ lua_pushnil(L);
+ imlua_pusherror(L, error);
+ return 2;
+ }
+ else
+ {
+ imFile** ifile_p = (imFile**) lua_newuserdata(L, sizeof(imFile*));
+ *ifile_p = ifile;
+ luaL_getmetatable(L, "imFile");
+ lua_setmetatable(L, -2);
+ return 1;
+ }
+}
+
+
+/*****************************************************************************\
+ im.FileOpen(filename)
+\*****************************************************************************/
+static int imluaFileOpen (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileOpen(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileOpenAs(filename)
+\*****************************************************************************/
+static int imluaFileOpenAs (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ int error;
+ imFile *ifile = imFileOpenAs(filename, format, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileOpenRaw(filename)
+\*****************************************************************************/
+static int imluaFileOpenRaw (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileOpenRaw(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileNew(filename, format)
+\*****************************************************************************/
+static int imluaFileNew (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ int error;
+
+ imFile *ifile = imFileNew(filename, format, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ im.FileNewRaw(filename)
+\*****************************************************************************/
+static int imluaFileNewRaw (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int error;
+ imFile *ifile = imFileNewRaw(filename, &error);
+ return imlua_pushifileerror(L, ifile, error);
+}
+
+/*****************************************************************************\
+ file:Handle()
+\*****************************************************************************/
+static int imluaFileHandle (lua_State *L)
+{
+ lua_pushlightuserdata(L, imFileHandle(imlua_checkfile(L, 1), luaL_checkint(L, 2)));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:LoadImage()
+\*****************************************************************************/
+static int imluaFileLoadImage (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileLoadImage(ifile, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadImageFrame()
+\*****************************************************************************/
+static int imluaFileLoadImageFrame (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+ int error;
+
+ imFileLoadImageFrame(ifile, index, image, &error);
+ imlua_pusherror(L, error);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:LoadImageRegion()
+\*****************************************************************************/
+static int imluaFileLoadImageRegion (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ int bitmap = luaL_checkint(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int xmax = luaL_checkint(L, 5);
+ int ymin = luaL_checkint(L, 6);
+ int ymax = luaL_checkint(L, 7);
+ int width = luaL_checkint(L, 8);
+ int height = luaL_checkint(L, 9);
+ int error;
+ imImage *image = imFileLoadImageRegion(ifile, index, bitmap, &error, xmin, xmax, ymin, ymax, width, height);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadBitmap()
+\*****************************************************************************/
+static int imluaFileLoadBitmap (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileLoadBitmap(ifile, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ file:LoadBitmapFrame()
+\*****************************************************************************/
+static int imluaFileLoadBitmapFrame (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_checkint(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+ int error;
+
+ imFileLoadBitmapFrame(ifile, index, image, &error);
+ imlua_pusherror(L, error);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:SaveImage()
+\*****************************************************************************/
+static int imluaFileSaveImage (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ imImage *image = imlua_checkimage(L, 2);
+
+ imlua_pusherror(L, imFileSaveImage(ifile, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:GetInfo()
+\*****************************************************************************/
+static int imluaFileGetInfo (lua_State *L)
+{
+ int image_count;
+ char format[10];
+ char compression[20];
+
+ imFile *ifile = imlua_checkfile(L, 1);
+
+ imFileGetInfo(ifile, format, compression, &image_count);
+
+ lua_pushstring(L, format);
+ lua_pushstring(L, compression);
+ lua_pushnumber(L, image_count);
+
+ return 3;
+}
+
+/*****************************************************************************\
+ file:SetInfo()
+\*****************************************************************************/
+static int imluaFileSetInfo (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *compression = luaL_checkstring(L, 2);
+
+ imFileSetInfo(ifile, compression);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ file:SetAttribute(attrib, data_type, data)
+\*****************************************************************************/
+static int imluaFileSetAttribute (lua_State *L)
+{
+ int i, count = 0;
+ void *data = NULL;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ if (!lua_isnil(L, 4))
+ {
+ if (lua_isstring(L, 4) && data_type != IM_BYTE)
+ luaL_argerror(L, 4, "if value is a string, then data type must be byte");
+ else
+ {
+ luaL_checktype(L, 4, LUA_TTABLE);
+ count = imlua_getn(L, 4);
+ data = malloc(imDataTypeSize(data_type) * count);
+ }
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (lua_isstring(L, 4))
+ {
+ const char* str = lua_tostring(L, 4);
+ count = strlen(str)+1;
+ data = malloc(imDataTypeSize(data_type) * count);
+ memcpy(data, str, count);
+ }
+ else
+ {
+ imbyte *d = (imbyte*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (imbyte) luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *d = (imushort*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (imushort) luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *d = (int*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *d = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ d[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ int two;
+ float *value = imlua_toarrayfloat(L, -1, &two, 1);
+ if (two != 2)
+ {
+ free(value);
+ luaL_argerror(L, 4, "invalid value");
+ }
+
+ data_float[i] = value[0];
+ data_float[i+1] = value[1];
+ free(value);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+ }
+ }
+
+ imFileSetAttribute(ifile, attrib, data_type, count, data);
+ return 0;
+}
+
+/*****************************************************************************\
+ file:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaFileGetAttribute (lua_State *L)
+{
+ int data_type;
+ int i, count;
+ const void *data;
+ int as_string = 0;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+
+ data = imFileGetAttribute(ifile, attrib, &data_type, &count);
+ if (!data)
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if (data_type == IM_BYTE && lua_isboolean(L, 3))
+ as_string = lua_toboolean(L, 3);
+
+ if (!as_string)
+ lua_newtable(L);
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (as_string)
+ {
+ lua_pushstring(L, (const char*)data);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++, data_byte++)
+ {
+ lua_pushnumber(L, *data_byte);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++, data_ushort += 2)
+ {
+ lua_pushnumber(L, *data_ushort);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++, data_int++)
+ {
+ lua_pushnumber(L, *data_int);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float++)
+ {
+ lua_pushnumber(L, *data_float);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float += 2)
+ {
+ imlua_newarrayfloat(L, data_float, 2, 1);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+ }
+
+ lua_pushnumber(L, data_type);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ file:GetAttributeList()
+\*****************************************************************************/
+static int imluaFileGetAttributeList (lua_State *L)
+{
+ int i, attrib_count;
+ char **attrib;
+
+ imFile* ifile = imlua_checkfile(L, 1);
+
+ imFileGetAttributeList(ifile, NULL, &attrib_count);
+
+ attrib = (char**) malloc(attrib_count * sizeof(char*));
+
+ imFileGetAttributeList(ifile, attrib, &attrib_count);
+
+ lua_newtable(L);
+ for (i = 0; i < attrib_count; i++)
+ {
+ lua_pushstring(L, attrib[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ file:GetPalette()
+\*****************************************************************************/
+static int imluaFileGetPalette (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ long* color = malloc(sizeof(long) * 256);
+ int count;
+ imFileGetPalette(ifile, color, &count);
+ imlua_pushpalette(L, color, count);
+ return 1;
+}
+
+/*****************************************************************************\
+ file:SetPalette(pal)
+\*****************************************************************************/
+static int imluaFileSetPalette (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ imluaPalette *pal = imlua_checkpalette(L, 2);
+ imFileSetPalette(ifile, pal->color, pal->count);
+ return 0;
+}
+
+/*****************************************************************************\
+ file:ReadImageInfo()
+\*****************************************************************************/
+static int imluaFileReadImageInfo (lua_State *L)
+{
+ int width, height;
+ int file_color_mode, file_data_type;
+ int error;
+
+ imFile *ifile = imlua_checkfile(L, 1);
+ int index = luaL_optint(L, 2, 0);
+
+ error = imFileReadImageInfo(ifile, index, &width, &height, &file_color_mode, &file_data_type);
+
+ imlua_pusherror(L, error);
+ if (error)
+ return 1;
+
+ lua_pushnumber(L, width);
+ lua_pushnumber(L, height);
+ lua_pushnumber(L, file_color_mode);
+ lua_pushnumber(L, file_data_type);
+ return 5;
+}
+
+/*****************************************************************************\
+ file:WriteImageInfo(width, height, user_color_mode, user_data_type)
+\*****************************************************************************/
+static int imluaFileWriteImageInfo (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+ int user_color_mode = luaL_checkint(L, 4);
+ int user_data_type = luaL_checkint(L, 5);
+
+ imlua_pusherror(L, imFileWriteImageInfo(ifile, width, height, user_color_mode, user_data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:imFileReadImageData(data)
+\*****************************************************************************/
+static int imluaFileReadImageData (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ void* data = lua_touserdata(L, 2);
+ int convert2bitmap = luaL_checkint(L, 3);
+ int color_mode_flags = luaL_checkint(L, 4);
+ imlua_pusherror(L, imFileReadImageData(ifile, data, convert2bitmap, color_mode_flags));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:imFileWriteImageData(data)
+\*****************************************************************************/
+static int imluaFileWriteImageData (lua_State *L)
+{
+ imFile *ifile = imlua_checkfile(L, 1);
+ void* data = lua_touserdata(L, 2);
+ imlua_pusherror(L, imFileWriteImageData(ifile, data));
+ return 1;
+}
+
+/*****************************************************************************\
+ file:Close()
+\*****************************************************************************/
+static int imluaFileClose (lua_State *L)
+{
+ imFile** ifile_p = imlua_rawcheckfile(L, 1);
+ if (!(*ifile_p))
+ luaL_argerror(L, 1, "closed imFile");
+
+ imFileClose(*ifile_p);
+ *ifile_p = NULL; /* mark as closed */
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaFile_gc (lua_State *L)
+{
+ imFile **ifile_p = (imFile **)lua_touserdata(L, 1);
+ if (ifile_p && *ifile_p)
+ {
+ imFileClose(*ifile_p);
+ *ifile_p = NULL; /* mark as closed */
+ }
+ return 0;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaFile_tostring (lua_State *L)
+{
+ imFile **ifile_p = (imFile **)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imFile(%p)%s", ifile_p, (*ifile_p)? "": "-closed");
+ return 1;
+}
+
+/*****************************************************************************\
+\*****************************************************************************/
+static const luaL_reg imfile_lib[] = {
+ {"FileOpen", imluaFileOpen},
+ {"FileOpenAs", imluaFileOpenAs},
+ {"FileOpenRaw", imluaFileOpenRaw},
+ {"FileNew", imluaFileNew},
+ {"FileNewRaw", imluaFileNewRaw},
+ {"FileClose", imluaFileClose},
+ {NULL, NULL}
+};
+
+static const luaL_reg imfile_metalib[] = {
+ {"Handle", imluaFileHandle},
+ {"Close", imluaFileClose},
+ {"LoadImage", imluaFileLoadImage},
+ {"LoadImageFrame", imluaFileLoadImageFrame},
+ {"LoadImageRegion", imluaFileLoadImageRegion},
+ {"LoadBitmap", imluaFileLoadBitmap},
+ {"LoadBitmapFrame", imluaFileLoadBitmapFrame},
+ {"SaveImage", imluaFileSaveImage},
+ {"GetInfo", imluaFileGetInfo},
+ {"SetInfo", imluaFileSetInfo},
+ {"SetAttribute", imluaFileSetAttribute},
+ {"GetAttribute", imluaFileGetAttribute},
+ {"GetAttributeList", imluaFileGetAttributeList},
+ {"GetPalette", imluaFileGetPalette},
+ {"SetPalette", imluaFileSetPalette},
+ {"ReadImageInfo", imluaFileReadImageInfo},
+ {"WriteImageInfo", imluaFileWriteImageInfo},
+ {"ReadImageData", imluaFileReadImageData},
+ {"WriteImageData", imluaFileWriteImageData},
+
+ {"__gc", imluaFile_gc},
+ {"__tostring", imluaFile_tostring},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imFile"); /* create new metatable for imFile handles */
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imfile_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+void imlua_open_file (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, imfile_lib);
+}
diff --git a/src/lua5/imlua_image.c b/src/lua5/imlua_image.c
new file mode 100644
index 0000000..22ed38c
--- /dev/null
+++ b/src/lua5/imlua_image.c
@@ -0,0 +1,1061 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_image.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_image.h"
+#include "imlua_palette.h"
+#include "imlua_aux.h"
+
+
+static imImage** imlua_rawcheckimage(lua_State *L, int param)
+{
+ return (imImage**) luaL_checkudata(L, param, "imImage");
+}
+
+imImage* imlua_checkimage(lua_State *L, int param)
+{
+ imImage** image_p = imlua_rawcheckimage(L, param);
+
+ if (!(*image_p))
+ luaL_argerror(L, param, "destroyed imImage");
+
+ return *image_p;
+}
+
+int imlua_pushimageerror(lua_State *L, imImage* image, int error)
+{
+ if (error)
+ {
+ lua_pushnil(L);
+ imlua_pusherror(L, error);
+ return 2;
+ }
+ else
+ {
+ imlua_pushimage(L, image);
+ return 1;
+ }
+}
+
+void imlua_pushimage(lua_State *L, imImage* image)
+{
+ if (!image)
+ lua_pushnil(L);
+ else
+ {
+ imImage **image_p = (imImage**) lua_newuserdata(L, sizeof(imImage*));
+ *image_p = image;
+ luaL_getmetatable(L, "imImage");
+ lua_setmetatable(L, -2);
+ }
+}
+
+/*****************************************************************************\
+ image channel, for indexing
+\*****************************************************************************/
+static imluaImageChannel *imlua_newimagechannel (lua_State *L, imImage *image, int channel)
+{
+ imluaImageChannel* imagechannel = (imluaImageChannel*) lua_newuserdata(L, sizeof(imluaImageChannel));
+ imagechannel->image = image;
+ imagechannel->channel = channel;
+ luaL_getmetatable(L, "imImageChannel");
+ lua_setmetatable(L, -2);
+ return imagechannel;
+}
+
+static imluaImageChannel* imlua_checkimagechannel (lua_State *L, int param)
+{
+ return (imluaImageChannel*) luaL_checkudata(L, param, "imImageChannel");
+}
+
+/*****************************************************************************\
+ image row, for indexing
+\*****************************************************************************/
+static imluaImageRow *imlua_newimagerow (lua_State *L, imImage *image, int channel, int row)
+{
+ imluaImageRow* imagerow = (imluaImageRow*) lua_newuserdata(L, sizeof(imluaImageRow));
+ imagerow->image = image;
+ imagerow->channel = channel;
+ imagerow->row = row;
+ luaL_getmetatable(L, "imImageChannelRow");
+ lua_setmetatable(L, -2);
+ return imagerow;
+}
+
+static imluaImageRow* imlua_checkimagerow (lua_State *L, int param)
+{
+ return (imluaImageRow*) luaL_checkudata(L, param, "imImageChannelRow");
+}
+
+/*****************************************************************************\
+ im.ImageCreate(width, height, color_space, data_type)
+\*****************************************************************************/
+static int imluaImageCreate (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ int color_space = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ imImage *image = imImageCreate(width, height, color_space, data_type);
+ imlua_pushimage(L, image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:AddAlpha()
+\*****************************************************************************/
+static int imluaImageAddAlpha (lua_State *L)
+{
+ imImageAddAlpha(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Reshape()
+\*****************************************************************************/
+static int imluaImageReshape (lua_State *L)
+{
+ imImage* im = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imImageReshape(im, width, height);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Copy()
+\*****************************************************************************/
+static int imluaImageCopy (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+ imImageCopy(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:CopyData()
+\*****************************************************************************/
+static int imluaImageCopyData (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+ imImageCopyData(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Duplicate()
+\*****************************************************************************/
+static int imluaImageDuplicate (lua_State *L)
+{
+ imImage* image = imlua_checkimage(L, 1);
+ imImage *new_image = imImageDuplicate(image);
+ imlua_pushimage(L, new_image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Clone()
+\*****************************************************************************/
+static int imluaImageClone (lua_State *L)
+{
+ imImage* image = imlua_checkimage(L, 1);
+ imImage *new_image = imImageClone(image);
+ imlua_pushimage(L, new_image);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetAttribute(attrib, data_type, count, data)
+\*****************************************************************************/
+static int imluaImageSetAttribute (lua_State *L)
+{
+ int i, count = 0;
+ void *data = NULL;
+
+ imImage* image = imlua_checkimage(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ if (!lua_isnil(L, 4))
+ {
+ if (lua_isstring(L, 4) && data_type != IM_BYTE)
+ luaL_argerror(L, 4, "if value is string, then data type must be byte");
+ else
+ {
+ luaL_checktype(L, 4, LUA_TTABLE);
+ count = imlua_getn(L, 4);
+ data = malloc(imDataTypeSize(data_type) * count);
+ }
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (lua_isstring(L, 4))
+ {
+ const char* str = lua_tostring(L, 4);
+ count = strlen(str)+1;
+ data = malloc(imDataTypeSize(data_type) * count);
+ memcpy(data, str, count);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_byte[i] = (imbyte)luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_ushort[i] = (imushort)luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_int[i] = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 4, i+1);
+ data_float[i] = (float) luaL_checknumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++)
+ {
+ int two;
+ float *value = imlua_toarrayfloat(L, -1, &two, 1);
+ if (two != 2)
+ {
+ free(value);
+ luaL_argerror(L, 4, "invalid value");
+ }
+
+ data_float[i] = value[0];
+ data_float[i+1] = value[1];
+ free(value);
+ lua_pop(L, 1);
+ }
+ }
+ break;
+ }
+ }
+
+ imImageSetAttribute(image, attrib, data_type, count, data);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:GetAttribute(attrib)
+\*****************************************************************************/
+static int imluaImageGetAttribute (lua_State *L)
+{
+ int data_type;
+ int i, count;
+ const void *data;
+ int as_string = 0;
+
+ imImage* image = imlua_checkimage(L, 1);
+ const char *attrib = luaL_checkstring(L, 2);
+
+ data = imImageGetAttribute(image, attrib, &data_type, &count);
+ if (!data)
+ {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ if (data_type == IM_BYTE && lua_isboolean(L, 3))
+ as_string = lua_toboolean(L, 3);
+
+ if (!as_string)
+ lua_newtable(L);
+
+ switch (data_type)
+ {
+ case IM_BYTE:
+ {
+ if (as_string)
+ {
+ lua_pushstring(L, (const char*)data);
+ }
+ else
+ {
+ imbyte *data_byte = (imbyte*) data;
+ for (i = 0; i < count; i++, data_byte++)
+ {
+ lua_pushnumber(L, *data_byte);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *data_ushort = (imushort*) data;
+ for (i = 0; i < count; i++, data_ushort += 2)
+ {
+ lua_pushnumber(L, *data_ushort);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *data_int = (int*) data;
+ for (i = 0; i < count; i++, data_int++)
+ {
+ lua_pushnumber(L, *data_int);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float++)
+ {
+ lua_pushnumber(L, *data_float);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *data_float = (float*) data;
+ for (i = 0; i < count; i++, data_float += 2)
+ {
+ imlua_newarrayfloat(L, data_float, 2, 1);
+ lua_rawseti(L, -2, i+1);
+ }
+ }
+ break;
+ }
+
+ lua_pushnumber(L, data_type);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ image:GetAttributeList()
+\*****************************************************************************/
+static int imluaImageGetAttributeList (lua_State *L)
+{
+ int i, attrib_count;
+ char **attrib;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imImageGetAttributeList(image, NULL, &attrib_count);
+
+ attrib = (char**) malloc(attrib_count * sizeof(char*));
+
+ imImageGetAttributeList(image, attrib, &attrib_count);
+
+ lua_newtable(L);
+ for (i = 0; i < attrib_count; i++)
+ {
+ lua_pushstring(L, attrib[i]);
+ lua_rawseti(L, -2, i+1);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Clear()
+\*****************************************************************************/
+static int imluaImageClear (lua_State *L)
+{
+ imImageClear(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:isBitmap()
+\*****************************************************************************/
+static int imluaImageIsBitmap (lua_State *L)
+{
+ lua_pushboolean(L, imImageIsBitmap(imlua_checkimage(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:GetPalette()
+\*****************************************************************************/
+static int imluaImageGetPalette (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ long* color = malloc(sizeof(long) * 256);
+ memcpy(color, image->palette, sizeof(long) * 256);
+ imlua_pushpalette(L, color, 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetPalette
+\*****************************************************************************/
+static int imluaImageSetPalette (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ imluaPalette *pal = imlua_checkpalette(L, 2);
+ imImageSetPalette(image, pal->color, pal->count);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:CopyAttributes(dst_image)
+\*****************************************************************************/
+static int imluaImageCopyAttributes (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imImageCopyAttributes(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ image:MatchSize(image2)
+\*****************************************************************************/
+static int imluaImageMatchSize (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchSize(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchColor(image2)
+\*****************************************************************************/
+static int imluaImageMatchColor (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchColor(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchDataType(image2)
+\*****************************************************************************/
+static int imluaImageMatchDataType (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchDataType(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:MatchColorSpace(image2)
+\*****************************************************************************/
+static int imluaImageMatchColorSpace (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatchColorSpace(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Match(image2)
+\*****************************************************************************/
+static int imluaImageMatch (lua_State *L)
+{
+ imImage *image1 = imlua_checkimage(L, 1);
+ imImage *image2 = imlua_checkimage(L, 2);
+
+ lua_pushboolean(L, imImageMatch(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:SetBinary()
+\*****************************************************************************/
+static int imluaImageSetBinary (lua_State *L)
+{
+ imImageSetBinary(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:MakeBinary()
+\*****************************************************************************/
+static int imluaImageMakeBinary (lua_State *L)
+{
+ imImageMakeBinary(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ image:Width()
+\*****************************************************************************/
+static int imluaImageWidth(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->width);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Height()
+\*****************************************************************************/
+static int imluaImageHeight(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->height);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Depth()
+\*****************************************************************************/
+static int imluaImageDepth(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->depth);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:DataType()
+\*****************************************************************************/
+static int imluaImageDataType(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->data_type);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:ColorSpace()
+\*****************************************************************************/
+static int imluaImageColorSpace(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->color_space);
+ return 1;
+}
+
+/*****************************************************************************\
+ image:HasAlpha()
+\*****************************************************************************/
+static int imluaImageHasAlpha(lua_State *L)
+{
+ imImage *im = imlua_checkimage(L, 1);
+ lua_pushnumber(L, im->has_alpha);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.FileImageLoad(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoad (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileImageLoad(filename, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageLoadRegion(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoadRegion (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_checkint(L, 2);
+ int bitmap = luaL_checkint(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int xmax = luaL_checkint(L, 5);
+ int ymin = luaL_checkint(L, 6);
+ int ymax = luaL_checkint(L, 7);
+ int width = luaL_checkint(L, 8);
+ int height = luaL_checkint(L, 9);
+ int error;
+ imImage *image = imFileImageLoadRegion(filename, index, bitmap, &error, xmin, xmax, ymin, ymax, width, height);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageLoadBitmap(filename, [index])
+\*****************************************************************************/
+static int imluaFileImageLoadBitmap (lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+ int index = luaL_optint(L, 2, 0);
+ int error;
+ imImage *image = imFileImageLoadBitmap(filename, index, &error);
+ return imlua_pushimageerror(L, image, error);
+}
+
+/*****************************************************************************\
+ im.FileImageSave(filename, format, image)
+\*****************************************************************************/
+static int imluaFileImageSave (lua_State *L)
+{
+ const char *file_name = luaL_checkstring(L, 1);
+ const char *format = luaL_checkstring(L, 2);
+ imImage *image = imlua_checkimage(L, 3);
+
+ imlua_pusherror(L, imFileImageSave(file_name, format, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Save(filename, format)
+\*****************************************************************************/
+static int imluaImageSave (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ const char *file_name = luaL_checkstring(L, 2);
+ const char *format = luaL_checkstring(L, 3);
+
+ imlua_pusherror(L, imFileImageSave(file_name, format, image));
+ return 1;
+}
+
+/*****************************************************************************\
+ image:Destroy()
+\*****************************************************************************/
+static int imluaImageDestroy (lua_State *L)
+{
+ imImage** image_p = imlua_rawcheckimage(L, 1);
+ if (!(*image_p))
+ luaL_argerror(L, 1, "destroyed imImage");
+
+ imImageDestroy(*image_p);
+ *image_p = NULL; /* mark as destroyed */
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaImage_gc (lua_State *L)
+{
+ imImage** image_p = imlua_rawcheckimage(L, 1);
+ if (*image_p)
+ {
+ imImageDestroy(*image_p);
+ *image_p = NULL; /* mark as destroyed */
+ }
+
+ return 0;
+}
+
+/*****************************************************************************\
+ image tostring
+\*****************************************************************************/
+static int imluaImage_tostring (lua_State *L)
+{
+ imImage** image_p = (imImage**)lua_touserdata(L, 1);
+ if (*image_p)
+ {
+ imImage *image = *image_p;
+ lua_pushfstring(L, "imImage(%p) [width=%d,height=%d,color_space=%s,data_type=%s,depth=%d]",
+ image_p,
+ image->width,
+ image->height,
+ imColorModeSpaceName(image->color_space),
+ imDataTypeName(image->data_type),
+ image->depth
+ );
+ }
+ else
+ {
+ lua_pushfstring(L, "imImage(%p)-destroyed", image_p);
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ imagechannel tostring
+\*****************************************************************************/
+static int imluaImageChannel_tostring (lua_State *L)
+{
+ imluaImageChannel *imagechannel = imlua_checkimagechannel(L, 1);
+ lua_pushfstring(L, "imImageChannel(%p) [channel=%d]",
+ imagechannel,
+ imagechannel->channel
+ );
+ return 1;
+}
+
+/*****************************************************************************\
+ imagerow tostring
+\*****************************************************************************/
+static int imluaImageRow_tostring (lua_State *L)
+{
+ char buff[32];
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+
+ sprintf(buff, "%p", lua_touserdata(L, 1));
+ lua_pushfstring(L, "imImageRow(%s) [channel=%d,row=%d]",
+ buff,
+ imagerow->channel,
+ imagerow->row
+ );
+ return 1;
+}
+
+/*****************************************************************************\
+ image row indexing
+\*****************************************************************************/
+static int imluaImageRow_index (lua_State *L)
+{
+ int index;
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+ imImage *image = imagerow->image;
+ int channel = imagerow->channel;
+ int row = imagerow->row;
+ int column = luaL_checkint(L, 2);
+
+ if (column < 0 || column >= imagerow->image->width)
+ luaL_argerror(L, 2, "invalid column, out of bounds");
+
+ index = channel * image->width * image->height + row * image->width + column;
+
+ switch (image->data_type)
+ {
+ case IM_BYTE:
+ {
+ imbyte *bdata = (imbyte*) image->data[0];
+ lua_pushnumber(L, (lua_Number) bdata[index]);
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ imushort *udata = (imushort*) image->data[0];
+ lua_pushnumber(L, (lua_Number) udata[index]);
+ }
+ break;
+
+ case IM_INT:
+ {
+ int *idata = (int*) image->data[0];
+ lua_pushnumber(L, (lua_Number) idata[index]);
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ float *fdata = (float*) image->data[0];
+ lua_pushnumber(L, (lua_Number) fdata[index]);
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ float *cdata = (float*) image->data[0];
+ imlua_newarrayfloat(L, cdata + (2*index), 2, 1);
+ }
+ break;
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ image row new index
+\*****************************************************************************/
+static int imluaImageRow_newindex (lua_State *L)
+{
+ int index;
+ imluaImageRow *imagerow = imlua_checkimagerow(L, 1);
+ imImage *image = imagerow->image;
+ int channel = imagerow->channel;
+ int row = imagerow->row;
+ int column = luaL_checkint(L, 2);
+
+ if (column < 0 || column >= imagerow->image->width)
+ luaL_argerror(L, 2, "invalid column, out of bounds");
+
+ index = channel * image->width * image->height + row * image->width + column;
+
+ switch (image->data_type)
+ {
+ case IM_BYTE:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ imbyte *bdata = (imbyte*) image->data[0];
+ bdata[index] = (imbyte) value;
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ imushort *udata = (imushort*) image->data[0];
+ udata[index] = (imushort) value;
+ }
+ break;
+
+ case IM_INT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ int *idata = (int*) image->data[0];
+ idata[index] = (int) value;
+ }
+ break;
+
+ case IM_FLOAT:
+ {
+ lua_Number value = luaL_checknumber(L, 3);
+ float *fdata = (float*) image->data[0];
+ fdata[index] = (float) value;
+ }
+ break;
+
+ case IM_CFLOAT:
+ {
+ int count;
+ float *cdata = (float*) image->data[0];
+ float *value = imlua_toarrayfloat(L, 3, &count, 1);
+ if (count != 2)
+ {
+ free(value);
+ luaL_argerror(L, 3, "invalid value");
+ }
+
+ cdata[2*index] = value[0];
+ cdata[2*index+1] = value[1];
+ free(value);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************\
+ image channel indexing
+\*****************************************************************************/
+static int imluaImageChannel_index (lua_State *L)
+{
+ imluaImageChannel *imagechannel = imlua_checkimagechannel(L, 1);
+ int row = luaL_checkint(L, 2);
+
+ if (row < 0 || row >= imagechannel->image->height)
+ luaL_argerror(L, 2, "invalid row, out of bounds");
+
+ imlua_newimagerow(L, imagechannel->image, imagechannel->channel, row);
+ return 1;
+}
+
+/*****************************************************************************\
+ image indexing
+\*****************************************************************************/
+static int imluaImage_index (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+
+ if (lua_isnumber(L, 2))
+ {
+ /* handle numeric indexing */
+ int channel = luaL_checkint(L, 2);
+
+ /* create channel */
+ if (channel < 0 || channel >= image->depth)
+ luaL_argerror(L, 2, "invalid channel, out of bounds");
+
+ imlua_newimagechannel(L, image, channel);
+ }
+ else if (lua_isstring(L, 2))
+ {
+ /* get raw method */
+ lua_getmetatable(L, 1);
+ lua_pushvalue(L, 2);
+ lua_rawget(L, -2);
+ }
+ else
+ {
+ lua_pushnil(L);
+ }
+
+ return 1;
+}
+
+static const luaL_reg imimage_lib[] = {
+ {"ImageCreate", imluaImageCreate},
+ {"ImageDestroy", imluaImageDestroy},
+ {"FileImageLoad", imluaFileImageLoad},
+ {"FileImageLoadBitmap", imluaFileImageLoadBitmap},
+ {"FileImageLoadRegion", imluaFileImageLoadRegion},
+ {"FileImageSave", imluaFileImageSave},
+ {NULL, NULL}
+};
+
+static const luaL_reg imimage_metalib[] = {
+ {"Destroy", imluaImageDestroy},
+ {"AddAlpha", imluaImageAddAlpha},
+ {"Reshape", imluaImageReshape},
+ {"Copy", imluaImageCopy},
+ {"CopyData", imluaImageCopyData},
+ {"Duplicate", imluaImageDuplicate},
+ {"Clone", imluaImageClone},
+ {"SetAttribute", imluaImageSetAttribute},
+ {"GetAttribute", imluaImageGetAttribute},
+ {"GetAttributeList", imluaImageGetAttributeList},
+ {"Clear", imluaImageClear},
+ {"IsBitmap", imluaImageIsBitmap},
+ {"SetPalette", imluaImageSetPalette},
+ {"GetPalette", imluaImageGetPalette},
+ {"CopyAttributes", imluaImageCopyAttributes},
+ {"MatchSize", imluaImageMatchSize},
+ {"MatchColor", imluaImageMatchColor},
+ {"MatchDataType", imluaImageMatchDataType},
+ {"MatchColorSpace", imluaImageMatchColorSpace},
+ {"Match", imluaImageMatch},
+ {"SetBinary", imluaImageSetBinary},
+ {"MakeBinary", imluaImageMakeBinary},
+ {"Width", imluaImageWidth},
+ {"Height", imluaImageHeight},
+ {"Depth", imluaImageDepth},
+ {"DataType", imluaImageDataType},
+ {"ColorSpace", imluaImageColorSpace},
+ {"HasAlpha", imluaImageHasAlpha},
+ {"Save", imluaImageSave},
+
+ {"__gc", imluaImage_gc},
+ {"__tostring", imluaImage_tostring},
+ {"__index", imluaImage_index},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ luaL_newmetatable(L, "imImageChannel"); /* create new metatable for imImageChannel handles */
+ lua_pushliteral(L, "__index");
+ lua_pushcfunction(L, imluaImageChannel_index);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__tostring");
+ lua_pushcfunction(L, imluaImageChannel_tostring);
+ lua_rawset(L, -3);
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+
+ luaL_newmetatable(L, "imImageChannelRow"); /* create new metatable for imImageChannelRow handles */
+ lua_pushliteral(L, "__index");
+ lua_pushcfunction(L, imluaImageRow_index);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__newindex");
+ lua_pushcfunction(L, imluaImageRow_newindex);
+ lua_rawset(L, -3);
+ lua_pushliteral(L, "__tostring");
+ lua_pushcfunction(L, imluaImageRow_tostring);
+ lua_rawset(L, -3);
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+
+ /* Object Oriented Access */
+ luaL_newmetatable(L, "imImage"); /* create new metatable for imImage handles */
+ lua_pushliteral(L, "__index"); /* dummy code because imluaImage_index will overwrite this behavior */
+ lua_pushvalue(L, -2); /* push metatable */
+ lua_rawset(L, -3); /* metatable.__index = metatable */
+ luaL_register(L, NULL, imimage_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+/* If all parameteres, besides the image, are nil, this is equivalent to image:Clone.
+ If any parameter is not nil, then the value is used instead of the one from the source image.
+ If a parameter is a function, then the function is called, passing the source
+ image as parameter, to obtain the substituion value. */
+static void reg_image(lua_State *L)
+{
+ const char* data = {
+"function im.ImageCreateBased(image, width, height, color_space, data_type) \n"
+" -- default values are those of the source image \n"
+" width = width or image:Width() \n"
+" height = height or image:Height() \n"
+" color_space = color_space or image:ColorSpace() \n"
+" data_type = data_type or image:DataType() \n"
+" \n"
+" -- callback to calculate parameters based on source image \n"
+" if type(width) == \"function\" then width = width(image) end \n"
+" if type(height) == \"function\" then height = height(image) end \n"
+" if type(color_space) == \"function\" then color_space = color_space(image) end \n"
+" if type(data_type) == \"function\" then data_type = data_type(image) end \n"
+" \n"
+" -- create a new image \n"
+" new_image = im.ImageCreate(width, height, color_space, data_type) \n"
+" image:CopyAttributes(new_image) \n"
+" return new_image \n"
+"end \n"
+ };
+
+ if (luaL_loadbuffer(L, data, strlen(data), "reg_image")==0) lua_pcall(L, 0, 0, 0);
+}
+
+void imlua_open_image (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, imimage_lib);
+ reg_image(L);
+}
diff --git a/src/lua5/imlua_image.h b/src/lua5/imlua_image.h
new file mode 100644
index 0000000..0a39863
--- /dev/null
+++ b/src/lua5/imlua_image.h
@@ -0,0 +1,38 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_image.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_IMAGE_H
+#define __IMLUA_IMAGE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+typedef struct _imluaImageChannel {
+ imImage *image;
+ int channel;
+} imluaImageChannel;
+
+typedef struct _imluaImageRow {
+ imImage *image;
+ int channel;
+ int row;
+} imluaImageRow;
+
+void imlua_open_image(lua_State *L);
+
+int imlua_pushimageerror(lua_State *L, imImage* image, int error);
+void imlua_pushimage(lua_State *L, imImage* image);
+imImage* imlua_checkimage(lua_State *L, int param);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lua5/imlua_jp2.c b/src/lua5/imlua_jp2.c
new file mode 100644
index 0000000..d69ba7e
--- /dev/null
+++ b/src/lua5/imlua_jp2.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief jp2 format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_jp2.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterJP2(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterJP2();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterJP2", imlua_FormatRegisterJP2},
+ {NULL, NULL},
+};
+
+
+static int imlua_jp2_open (lua_State *L)
+{
+ imFormatRegisterJP2();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_jp2(lua_State* L)
+{
+ return imlua_jp2_open(L);
+}
+
+int luaopen_imlua_jp251(lua_State* L)
+{
+ return imlua_jp2_open(L);
+}
diff --git a/src/lua5/imlua_jp2.def b/src/lua5/imlua_jp2.def
new file mode 100644
index 0000000..29aa05c
--- /dev/null
+++ b/src/lua5/imlua_jp2.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_jp2
+ luaopen_imlua_jp251
+ \ No newline at end of file
diff --git a/src/lua5/imlua_kernel.c b/src/lua5/imlua_kernel.c
new file mode 100644
index 0000000..770a989
--- /dev/null
+++ b/src/lua5/imlua_kernel.c
@@ -0,0 +1,182 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_kernel.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <memory.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+#include "im_kernel.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+static int imluaKernelSobel(lua_State *L)
+{
+ imlua_pushimage(L, imKernelSobel());
+ return 1;
+}
+
+static int imluaKernelPrewitt(lua_State *L)
+{
+ imlua_pushimage(L, imKernelPrewitt());
+ return 1;
+}
+
+static int imluaKernelKirsh(lua_State *L)
+{
+ imlua_pushimage(L, imKernelKirsh());
+ return 1;
+}
+
+static int imluaKernelLaplacian4(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian4());
+ return 1;
+}
+
+static int imluaKernelLaplacian8(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian8());
+ return 1;
+}
+
+static int imluaKernelLaplacian5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian5x5());
+ return 1;
+}
+
+static int imluaKernelLaplacian7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelLaplacian7x7());
+ return 1;
+}
+
+static int imluaKernelGradian3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGradian3x3());
+ return 1;
+}
+
+static int imluaKernelGradian7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGradian7x7());
+ return 1;
+}
+
+static int imluaKernelSculpt(lua_State *L)
+{
+ imlua_pushimage(L, imKernelSculpt());
+ return 1;
+}
+
+static int imluaKernelMean3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean3x3());
+ return 1;
+}
+
+static int imluaKernelMean5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean5x5());
+ return 1;
+}
+
+static int imluaKernelCircularMean5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelCircularMean5x5());
+ return 1;
+}
+
+static int imluaKernelMean7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelMean7x7());
+ return 1;
+}
+
+static int imluaKernelCircularMean7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelCircularMean7x7());
+ return 1;
+}
+
+static int imluaKernelGaussian3x3(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGaussian3x3());
+ return 1;
+}
+
+static int imluaKernelGaussian5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelGaussian5x5());
+ return 1;
+}
+
+static int imluaKernelBarlett5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelBarlett5x5());
+ return 1;
+}
+
+static int imluaKernelTopHat5x5(lua_State *L)
+{
+ imlua_pushimage(L, imKernelTopHat5x5());
+ return 1;
+}
+
+static int imluaKernelTopHat7x7(lua_State *L)
+{
+ imlua_pushimage(L, imKernelTopHat7x7());
+ return 1;
+}
+
+static int imluaKernelEnhance(lua_State *L)
+{
+ imlua_pushimage(L, imKernelEnhance());
+ return 1;
+}
+
+
+static const luaL_reg imkernel_lib[] = {
+ {"KernelSobel", imluaKernelSobel},
+ {"KernelPrewitt", imluaKernelPrewitt},
+ {"KernelKirsh", imluaKernelKirsh},
+ {"KernelLaplacian4", imluaKernelLaplacian4},
+ {"KernelLaplacian8", imluaKernelLaplacian8},
+ {"KernelLaplacian5x5", imluaKernelLaplacian5x5},
+ {"KernelLaplacian7x7", imluaKernelLaplacian7x7},
+ {"KernelGradian3x3", imluaKernelGradian3x3},
+ {"KernelGradian7x7", imluaKernelGradian7x7},
+ {"KernelSculpt", imluaKernelSculpt},
+ {"KernelMean3x3", imluaKernelMean3x3},
+ {"KernelMean5x5", imluaKernelMean5x5},
+ {"KernelCircularMean5x5", imluaKernelCircularMean5x5},
+ {"KernelMean7x7", imluaKernelMean7x7},
+ {"KernelCircularMean7x7", imluaKernelCircularMean7x7},
+ {"KernelGaussian3x3", imluaKernelGaussian3x3},
+ {"KernelGaussian5x5", imluaKernelGaussian5x5},
+ {"KernelBarlett5x5", imluaKernelBarlett5x5},
+ {"KernelTopHat5x5", imluaKernelTopHat5x5},
+ {"KernelTopHat7x7", imluaKernelTopHat7x7},
+ {"KernelEnhance", imluaKernelEnhance},
+ {NULL, NULL}
+};
+
+void imlua_open_kernel (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imkernel_lib);
+}
diff --git a/src/lua5/imlua_palette.c b/src/lua5/imlua_palette.c
new file mode 100644
index 0000000..80d23eb
--- /dev/null
+++ b/src/lua5/imlua_palette.c
@@ -0,0 +1,399 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_palette.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <string.h>
+#include <memory.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_util.h"
+#include "im_palette.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_palette.h"
+
+
+static imluaPalette* imlua_rawcheckpalette(lua_State *L, int param)
+{
+ void *p = lua_touserdata(L, param);
+ if (p != NULL) { /* value is a userdata? */
+ if (lua_getmetatable(L, param)) { /* does it have a metatable? */
+ lua_getfield(L, LUA_REGISTRYINDEX, "imPalette"); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return (imluaPalette*)p;
+ }
+ lua_pop(L, 1); /* remove previous metatable */
+
+ /* check also for CD palette */
+ lua_getfield(L, LUA_REGISTRYINDEX, "cdPalette"); /* get correct metatable */
+ if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
+ lua_pop(L, 2); /* remove both metatables */
+ return (imluaPalette*)p;
+ }
+ }
+ }
+ luaL_typerror(L, param, "imPalette"); /* else error */
+ return NULL; /* to avoid warnings */
+}
+
+imluaPalette* imlua_checkpalette (lua_State *L, int param)
+{
+ imluaPalette* pal = imlua_rawcheckpalette(L, param);
+ if (!pal->color)
+ luaL_argerror(L, param, "destroyed imPalette");
+
+ return pal;
+}
+
+void imlua_pushpalette(lua_State *L, long* color, int count)
+{
+ imluaPalette *pal = (imluaPalette*) lua_newuserdata(L, sizeof(imluaPalette));
+ pal->count = count;
+ pal->color = color;
+ luaL_getmetatable(L, "imPalette");
+ lua_setmetatable(L, -2);
+}
+
+/***************************************************************************\
+* Creates a palette as a "imPalette" userdata. A palette can be *
+* considered and treated as a color table. *
+* im.PaletteCreate(count: number) -> (palette: "imPalette") *
+\***************************************************************************/
+static int imluaPaletteCreate(lua_State *L)
+{
+ long* color;
+
+ int count = luaL_optint(L, 1, 256);
+ if (count < 1 || count > 256)
+ luaL_argerror(L, 1, "palette count should be a positive integer and less then 256");
+
+ color = (long*)malloc(256*sizeof(long));
+ memset(color, 0, 256*sizeof(long));
+
+ imlua_pushpalette(L, color, count);
+ return 1;
+}
+
+
+/*****************************************************************************\
+ im.PaletteFindNearest
+\*****************************************************************************/
+static int imluaPaletteFindNearest (lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ long color = (long int) lua_touserdata(L, 1);
+
+ lua_pushnumber(L, imPaletteFindNearest(pal->color, pal->count, color));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteFindColor
+\*****************************************************************************/
+static int imluaPaletteFindColor (lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ long color = (long) lua_touserdata(L, 2);
+ unsigned char tol = (unsigned char)luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imPaletteFindColor(pal->color, pal->count, color, tol));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteGray
+\*****************************************************************************/
+static int imluaPaletteGray (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteGray(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteRed
+\*****************************************************************************/
+static int imluaPaletteRed (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteRed(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteGreen
+\*****************************************************************************/
+static int imluaPaletteGreen (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteGreen(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlue
+\*****************************************************************************/
+static int imluaPaletteBlue (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlue(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteYellow
+\*****************************************************************************/
+static int imluaPaletteYellow (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteYellow(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteMagenta
+\*****************************************************************************/
+static int imluaPaletteMagenta (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteMagenta(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteCian
+\*****************************************************************************/
+static int imluaPaletteCian (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteCian(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteRainbow
+\*****************************************************************************/
+static int imluaPaletteRainbow (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteRainbow(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHues
+\*****************************************************************************/
+static int imluaPaletteHues (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHues(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlueIce
+\*****************************************************************************/
+static int imluaPaletteBlueIce (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlueIce(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHotIron
+\*****************************************************************************/
+static int imluaPaletteHotIron (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHotIron(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteBlackBody
+\*****************************************************************************/
+static int imluaPaletteBlackBody (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteBlackBody(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteHighContrast
+\*****************************************************************************/
+static int imluaPaletteHighContrast (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteHighContrast(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniform
+\*****************************************************************************/
+static int imluaPaletteUniform (lua_State *L)
+{
+ imlua_pushpalette(L, imPaletteUniform(), 256);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniformIndex
+\*****************************************************************************/
+static int imluaPaletteUniformIndex (lua_State *L)
+{
+ lua_pushnumber(L, imPaletteUniformIndex((long int) lua_touserdata(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.PaletteUniformIndexHalftoned
+\*****************************************************************************/
+static int imluaPaletteUniformIndexHalftoned (lua_State *L)
+{
+ long color = (long) lua_touserdata(L, 1);
+ int x = luaL_checkint(L, 2);
+ int y = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imPaletteUniformIndexHalftoned(color, x, y));
+ return 1;
+}
+
+/***************************************************************************\
+* Frees a previously allocated palette *
+* im.PaletteDestroy(palette: "imPalette") *
+\***************************************************************************/
+static int imluaPaletteDestroy (lua_State *L)
+{
+ imluaPalette *pal = imlua_rawcheckpalette(L, 1);
+ if (!pal->color)
+ luaL_argerror(L, 1, "destroyed imPalette");
+
+ free(pal->color);
+ pal->color = NULL; /* mark as destroyed */
+ pal->count = 0;
+
+ return 0;
+}
+
+/*****************************************************************************\
+ gc
+\*****************************************************************************/
+static int imluaPalette_gc(lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ if (pal && pal->color)
+ {
+ free(pal->color);
+ pal->color = NULL; /* mark as destroyed */
+ pal->count = 0;
+ }
+
+ return 0;
+}
+
+/***************************************************************************\
+* color = palette[i] *
+\***************************************************************************/
+static int imluaPalette_index(lua_State *L)
+{
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ int index_i = luaL_checkint(L, 2);
+
+ if (index_i < 0 || index_i >= pal->count)
+ luaL_argerror(L, 2, "index is out of bounds");
+
+ lua_pushlightuserdata(L, (void*) pal->color[index_i]);
+ return 1;
+}
+
+/***************************************************************************\
+* palette[i] = color *
+\***************************************************************************/
+static int imluaPalette_newindex(lua_State *L)
+{
+ long color_i;
+ imluaPalette *pal = imlua_checkpalette(L, 1);
+ int index_i = luaL_checkint(L, 2);
+
+ if (index_i < 0 || index_i >= pal->count)
+ luaL_argerror(L, 2, "index is out of bounds");
+
+ if (!lua_islightuserdata(L, 3))
+ luaL_argerror(L, 3, "color must be a light user data");
+
+ color_i = (long int) lua_touserdata(L, 3);
+
+ pal->color[index_i] = color_i;
+ return 0;
+}
+
+/*****************************************************************************\
+ len
+\*****************************************************************************/
+static int imluaPalette_len(lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ lua_pushinteger(L, pal->count);
+ return 1;
+}
+
+/*****************************************************************************\
+ tostring
+\*****************************************************************************/
+static int imluaPalette_tostring (lua_State *L)
+{
+ imluaPalette *pal = (imluaPalette*)lua_touserdata(L, 1);
+ lua_pushfstring(L, "imPalette(%p)%s", pal, (pal->color)? "": "-destroyed");
+ return 1;
+}
+
+static const luaL_reg impalette_lib[] = {
+ {"PaletteFindNearest", imluaPaletteFindNearest},
+ {"PaletteFindColor", imluaPaletteFindColor},
+ {"PaletteGray", imluaPaletteGray },
+ {"PaletteRed", imluaPaletteRed },
+ {"PaletteGreen", imluaPaletteGreen },
+ {"PaletteBlue", imluaPaletteBlue },
+ {"PaletteYellow", imluaPaletteYellow },
+ {"PaletteMagenta", imluaPaletteMagenta },
+ {"PaletteCian", imluaPaletteCian },
+ {"PaletteRainbow", imluaPaletteRainbow },
+ {"PaletteHues", imluaPaletteHues },
+ {"PaletteBlueIce", imluaPaletteBlueIce },
+ {"PaletteHotIron", imluaPaletteHotIron },
+ {"PaletteBlackBody", imluaPaletteBlackBody },
+ {"PaletteHighContrast", imluaPaletteHighContrast },
+ {"PaletteUniform", imluaPaletteUniform },
+ {"PaletteUniformIndex", imluaPaletteUniformIndex },
+ {"PaletteUniformIndexHalftoned", imluaPaletteUniformIndexHalftoned },
+
+ {"PaletteDestroy", imluaPaletteDestroy},
+ {"PaletteCreate", imluaPaletteCreate},
+
+ {NULL, NULL}
+};
+
+static const luaL_reg impalette_metalib[] = {
+ {"__gc", imluaPalette_gc},
+ {"__tostring", imluaPalette_tostring},
+ {"__index", imluaPalette_index},
+ {"__newindex", imluaPalette_newindex},
+ {"__len", imluaPalette_len},
+
+ {NULL, NULL}
+};
+
+static void createmeta (lua_State *L)
+{
+ /* there is no object orientation for imPalette, only array access */
+ luaL_newmetatable(L, "imPalette"); /* create new metatable for imPalette handles */
+ luaL_register(L, NULL, impalette_metalib); /* register methods */
+ lua_pop(L, 1); /* removes the metatable from the top of the stack */
+}
+
+void imlua_open_palette (lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ createmeta(L);
+ luaL_register(L, NULL, impalette_lib);
+}
diff --git a/src/lua5/imlua_palette.h b/src/lua5/imlua_palette.h
new file mode 100644
index 0000000..453fd01
--- /dev/null
+++ b/src/lua5/imlua_palette.h
@@ -0,0 +1,32 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_palette.h,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#ifndef __IMLUA_PALETTE_H
+#define __IMLUA_PALETTE_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* this is the same declaration used in the CD toolkit for cdPalette in Lua */
+typedef struct _imPalette {
+ long* color;
+ int count;
+} imluaPalette;
+
+void imlua_pushpalette(lua_State *L, long* color, int count);
+imluaPalette* imlua_checkpalette (lua_State *L, int param);
+
+void imlua_open_palette(lua_State *L);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lua5/imlua_process.c b/src/lua5/imlua_process.c
new file mode 100644
index 0000000..8a6fe64
--- /dev/null
+++ b/src/lua5/imlua_process.c
@@ -0,0 +1,3091 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_process.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include <memory.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "im.h"
+#include "im_image.h"
+#include "im_process.h"
+#include "im_util.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+#include "imlua_image.h"
+
+
+
+/*****************************************************************************\
+ Image Statistics Calculations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.CalcRMSError(image1, image2)
+\*****************************************************************************/
+static int imluaCalcRMSError (lua_State *L)
+{
+ imImage* image1 = imlua_checkimage(L, 1);
+ imImage* image2 = imlua_checkimage(L, 2);
+
+ imlua_match(L, image1, image2);
+
+ lua_pushnumber(L, imCalcRMSError(image1, image2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcSNR(src_image, noise_image)
+\*****************************************************************************/
+static int imluaCalcSNR (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* noise_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, noise_image);
+
+ lua_pushnumber(L, imCalcSNR(src_image, noise_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcCountColors(src_image)
+\*****************************************************************************/
+static int imluaCalcCountColors (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ if (src_image->color_space >= IM_CMYK)
+ luaL_argerror(L, 1, "color space can be RGB, Gray, Binary or Map only");
+
+ lua_pushnumber(L, imCalcCountColors(src_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistogram(src_image, plane, cumulative)
+\*****************************************************************************/
+static int imluaCalcHistogram (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ int plane = luaL_checkint(L, 2);
+ int cumulative = luaL_checkint(L, 3);
+
+ switch (src_image->data_type)
+ {
+ case IM_BYTE:
+ {
+ unsigned long hist[256];
+ imCalcHistogram((imbyte*) src_image->data[plane], src_image->count, hist, cumulative);
+ imlua_newarrayulong(L, hist, 256, 0);
+ }
+ break;
+
+ case IM_USHORT:
+ {
+ unsigned long hist[65535];
+ imCalcUShortHistogram(src_image->data[plane], src_image->count, hist, cumulative);
+ imlua_newarrayulong(L, hist, 65535, 0);
+ }
+ break;
+
+ default:
+ luaL_argerror(L, 1, "data_type can be byte or ushort only");
+ break;
+ }
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcGrayHistogram(src_image, cumulative)
+\*****************************************************************************/
+static int imluaCalcGrayHistogram (lua_State *L)
+{
+ unsigned long hist[256];
+ imImage* src_image = imlua_checkimage(L, 1);
+ int cumulative = luaL_checkint(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ if (src_image->color_space >= IM_CMYK)
+ luaL_argerror(L, 1, "color space can be RGB, Gray, Binary or Map only");
+
+ imCalcGrayHistogram(src_image, hist, cumulative);
+ imlua_newarrayulong(L, hist, 256, 0);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcImageStatistics(src_image)
+\*****************************************************************************/
+static int imluaCalcImageStatistics (lua_State *L)
+{
+ imStats stats;
+ imImage *image = imlua_checkimage(L, 1);
+
+ if (image->data_type == IM_CFLOAT)
+ luaL_argerror(L, 1, "data type can NOT be of type cfloat");
+
+ imCalcImageStatistics(image, &stats);
+
+ lua_newtable(L);
+ lua_pushstring(L, "max"); lua_pushnumber(L, stats.max); lua_settable(L, -3);
+ lua_pushstring(L, "min"); lua_pushnumber(L, stats.min); lua_settable(L, -3);
+ lua_pushstring(L, "positive"); lua_pushnumber(L, stats.positive); lua_settable(L, -3);
+ lua_pushstring(L, "negative"); lua_pushnumber(L, stats.negative); lua_settable(L, -3);
+ lua_pushstring(L, "zeros"); lua_pushnumber(L, stats.zeros); lua_settable(L, -3);
+ lua_pushstring(L, "mean"); lua_pushnumber(L, stats.mean); lua_settable(L, -3);
+ lua_pushstring(L, "stddev"); lua_pushnumber(L, stats.stddev); lua_settable(L, -3);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistogramStatistics(src_image)
+\*****************************************************************************/
+static int imluaCalcHistogramStatistics (lua_State *L)
+{
+ imStats stats;
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ imCalcHistogramStatistics(image, &stats);
+
+ lua_newtable(L);
+ lua_pushstring(L, "max"); lua_pushnumber(L, stats.max); lua_settable(L, -3);
+ lua_pushstring(L, "min"); lua_pushnumber(L, stats.min); lua_settable(L, -3);
+ lua_pushstring(L, "positive"); lua_pushnumber(L, stats.positive); lua_settable(L, -3);
+ lua_pushstring(L, "negative"); lua_pushnumber(L, stats.negative); lua_settable(L, -3);
+ lua_pushstring(L, "zeros"); lua_pushnumber(L, stats.zeros); lua_settable(L, -3);
+ lua_pushstring(L, "mean"); lua_pushnumber(L, stats.mean); lua_settable(L, -3);
+ lua_pushstring(L, "stddev"); lua_pushnumber(L, stats.stddev); lua_settable(L, -3);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.CalcHistoImageStatistics
+\*****************************************************************************/
+static int imluaCalcHistoImageStatistics (lua_State *L)
+{
+ int* median;
+ int* mode;
+
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ median = (int*)malloc(sizeof(int)*image->depth);
+ mode = (int*)malloc(sizeof(int)*image->depth);
+
+ imCalcHistoImageStatistics(image, median, mode);
+
+ imlua_newarrayint (L, median, image->depth, 0);
+ imlua_newarrayint (L, mode, image->depth, 0);
+
+ free(median);
+ free(mode);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ Image Analysis
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.AnalyzeFindRegions(src_image, dst_image, connect, touch_border)
+\*****************************************************************************/
+static int imluaAnalyzeFindRegions (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+ int touch_border = lua_toboolean(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_USHORT);
+
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+ lua_pushnumber(L, imAnalyzeFindRegions(src_image, dst_image, connect, touch_border));
+ return 1;
+}
+
+static int iGetMax(imImage* image)
+{
+ int max = 0;
+ int i;
+
+ imushort* data = (imushort*)image->data[0];
+ for (i = 0; i < image->count; i++)
+ {
+ if (*data > max)
+ max = *data;
+
+ data++;
+ }
+
+ return max;
+}
+
+static int imlua_checkregioncount(lua_State *L, int narg, imImage* image)
+{
+ if (lua_isnoneornil(L, narg)) return iGetMax(image);
+ else return (int)luaL_checknumber(L, narg);
+}
+
+
+/*****************************************************************************\
+ im.AnalyzeMeasureArea(image, [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasureArea (lua_State *L)
+{
+ int count;
+ int *area;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ area = (int*) malloc(sizeof(int) * count);
+
+ imAnalyzeMeasureArea(image, area, count);
+
+ imlua_newarrayint(L, area, count, 0);
+ free(area);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePerimArea(image)
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePerimArea (lua_State *L)
+{
+ int count;
+ float *perimarea;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ perimarea = (float*) malloc(sizeof(float) * count);
+
+ imAnalyzeMeasurePerimArea(image, perimarea);
+
+ imlua_newarrayfloat (L, perimarea, count, 0);
+ free(perimarea);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasureCentroid(image, [area], [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasureCentroid (lua_State *L)
+{
+ int count;
+ float *cx, *cy;
+ int *area;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ area = imlua_toarrayint(L, 2, &count, 0);
+ count = imlua_checkregioncount(L, 3, image);
+
+ cx = (float*) malloc (sizeof(float) * count);
+ cy = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasureCentroid(image, area, count, cx, cy);
+
+ imlua_newarrayfloat(L, cx, count, 0);
+ imlua_newarrayfloat(L, cy, count, 0);
+
+ if (area)
+ free(area);
+ free(cx);
+ free(cy);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePrincipalAxis(image, [area], [cx], [cy])
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePrincipalAxis (lua_State *L)
+{
+ int count;
+ float *cx, *cy;
+ int *area;
+ float *major_slope, *major_length, *minor_slope, *minor_length;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ area = imlua_toarrayint(L, 2, &count, 0);
+ cx = imlua_toarrayfloat(L, 3, NULL, 0);
+ cy = imlua_toarrayfloat(L, 4, NULL, 0);
+ count = imlua_checkregioncount(L, 5, image);
+
+ major_slope = (float*) malloc (sizeof(float) * count);
+ major_length = (float*) malloc (sizeof(float) * count);
+ minor_slope = (float*) malloc (sizeof(float) * count);
+ minor_length = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasurePrincipalAxis(image, area, cx, cy, count, major_slope, major_length, minor_slope, minor_length);
+
+ imlua_newarrayfloat(L, major_slope, count, 0);
+ imlua_newarrayfloat(L, major_length, count, 0);
+ imlua_newarrayfloat(L, minor_slope, count, 0);
+ imlua_newarrayfloat(L, minor_length, count, 0);
+
+ if (area)
+ free(area);
+ if (cx)
+ free(cx);
+ if (cy)
+ free(cy);
+
+ free(major_slope);
+ free(major_length);
+ free(minor_slope);
+ free(minor_length);
+
+ return 4;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasureHoles
+\*****************************************************************************/
+static int imluaAnalyzeMeasureHoles (lua_State *L)
+{
+ int holes_count, count;
+ int connect;
+ int *area = NULL;
+ float *perim = NULL;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ connect = luaL_checkint(L, 2);
+ count = imlua_checkregioncount(L, 3, image);
+
+ area = (int*) malloc (sizeof(int) * count);
+ perim = (float*) malloc (sizeof(float) * count);
+
+ imAnalyzeMeasureHoles(image, connect, &holes_count, area, perim);
+
+ lua_pushnumber(L, holes_count);
+ imlua_newarrayint(L, area, holes_count, 0);
+ imlua_newarrayfloat(L, perim, holes_count, 0);
+
+ if (area)
+ free(area);
+ if (perim)
+ free(perim);
+
+ return 3;
+}
+
+/*****************************************************************************\
+ im.AnalyzeMeasurePerimeter(image, [count])
+\*****************************************************************************/
+static int imluaAnalyzeMeasurePerimeter (lua_State *L)
+{
+ int count;
+ float *perim;
+
+ imImage* image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, image, IM_GRAY, IM_USHORT);
+
+ count = imlua_checkregioncount(L, 2, image);
+ perim = (float*) malloc(sizeof(float) * count);
+
+ imAnalyzeMeasurePerimeter(image, perim, count);
+
+ imlua_newarrayfloat(L, perim, count, 0);
+
+ free(perim);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessPerimeterLine(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessPerimeterLine (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessPerimeterLine(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessPrune(src_image, dst_image, connect, start_size, end_size)
+\*****************************************************************************/
+static int imluaProcessPrune (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+ int start_size = luaL_checkint(L, 4);
+ int end_size = luaL_checkint(L, 5);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+
+ imProcessPrune(src_image, dst_image, connect, start_size, end_size);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFillHoles(src_image, dst_image, connect)
+\*****************************************************************************/
+static int imluaProcessFillHoles (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int connect = luaL_checkint(L, 3);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (connect == 4 || connect == 8), 3, "invalid connect value, must be 4 or 8");
+
+ imProcessFillHoles(src_image, dst_image, connect);
+ return 0;
+}
+
+static void imlua_checkhoughsize(lua_State *L, imImage* image, imImage* hough_image, int param)
+{
+#define IMSQR(_x) (_x*_x)
+ int hough_rmax;
+ if (hough_image->width != 180)
+ luaL_argerror(L, param, "invalid image width");
+
+ hough_rmax = (int)(sqrt((double)(IMSQR(image->width) + IMSQR(image->height)))/2.0);
+ if (hough_image->height != 2*hough_rmax+1)
+ luaL_argerror(L, param, "invalid image height");
+}
+
+/*****************************************************************************\
+ im.ProcessHoughLines(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessHoughLines (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_INT);
+ imlua_checkhoughsize(L, src_image, dst_image, 2);
+
+ lua_pushboolean(L, imProcessHoughLines(src_image, dst_image));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHoughLinesDraw(src_image, hough_points, dst_image)
+\*****************************************************************************/
+static int imluaProcessHoughLinesDraw (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* hough_points = imlua_checkimage(L, 3);
+ imImage* dst_image = imlua_checkimage(L, 4);
+ imImage* hough = NULL;
+ if (lua_isuserdata(L, 2))
+ {
+ hough = imlua_checkimage(L, 2);
+ imlua_checktype(L, 2, hough, IM_GRAY, IM_INT);
+ imlua_checkhoughsize(L, src_image, hough, 2);
+ }
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 3, hough_points, IM_BINARY);
+ imlua_checkhoughsize(L, src_image, hough_points, 3);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushnumber(L, imProcessHoughLinesDraw(src_image, hough, hough_points, dst_image));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDistanceTransform(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessDistanceTransform (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_checkdatatype(L, 2, dst_image, IM_FLOAT);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDistanceTransform(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRegionalMaximum(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessRegionalMaximum (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_FLOAT);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessRegionalMaximum(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ Image Resize
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessReduce(src_image, dst_image, order)
+\*****************************************************************************/
+static int imluaProcessReduce (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int order = luaL_checkint(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1), 3, "invalid order, must be 0 or 1");
+
+ lua_pushboolean(L, imProcessReduce(src_image, dst_image, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessResize(src_image, dst_image, order)
+\*****************************************************************************/
+static int imluaProcessResize (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int order = luaL_checkint(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 3, "invalid order, must be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessResize(src_image, dst_image, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessReduceBy4(src_image, dst_image)
+\*****************************************************************************/
+static int imluaProcessReduceBy4 (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L,
+ dst_image->width == (src_image->width / 2) &&
+ dst_image->height == (src_image->height / 2), 3, "destiny image size must be source image width/2, height/2");
+
+ imProcessReduceBy4(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCrop(src_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessCrop (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int xmin = luaL_checkint(L, 3);
+ int ymin = luaL_checkint(L, 4);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, xmin > 0 && xmin < src_image->width, 3, "xmin must be > 0 and < width");
+ luaL_argcheck(L, ymin > 0 && ymin < src_image->height, 3, "ymin must be > 0 and < height");
+ luaL_argcheck(L, dst_image->width < (src_image->width - xmin), 2, "destiny image size must be smaller than source image width-xmin, height-ymin");
+ luaL_argcheck(L, dst_image->height < (src_image->height - ymin), 2, "destiny image size must be smaller than source image width-xmin, height-ymin");
+
+ imProcessCrop(src_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessInsert(src_image, region_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessInsert (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* region_image = imlua_checkimage(L, 2);
+ imImage* dst_image = imlua_checkimage(L, 3);
+ int xmin = luaL_checkint(L, 4);
+ int ymin = luaL_checkint(L, 5);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, xmin > 0 && xmin < src_image->width, 3, "xmin must be > 0 and < width");
+ luaL_argcheck(L, ymin > 0 && ymin < src_image->height, 3, "ymin must be > 0 and < height");
+
+ imProcessInsert(src_image, region_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAddMargins(src_image, dst_image, xmin, ymin)
+\*****************************************************************************/
+static int imluaProcessAddMargins (lua_State *L)
+{
+ imImage* src_image = imlua_checkimage(L, 1);
+ imImage* dst_image = imlua_checkimage(L, 2);
+ int xmin = luaL_checkint(L, 3);
+ int ymin = luaL_checkint(L, 4);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, dst_image->width > (src_image->width + xmin), 2, "destiny image size must be greatter than source image width+xmin, height+ymin");
+ luaL_argcheck(L, dst_image->height > (src_image->height + ymin), 2, "destiny image size must be greatter than source image width+xmin, height+ymin");
+
+ imProcessAddMargins(src_image, dst_image, xmin, ymin);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Geometric Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessCalcRotateSize
+\*****************************************************************************/
+static int imluaProcessCalcRotateSize (lua_State *L)
+{
+ int new_width, new_height;
+
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+
+ imProcessCalcRotateSize(width, height, &new_width, &new_height, cos0, sin0);
+ lua_pushnumber(L, new_width);
+ lua_pushnumber(L, new_height);
+ return 2;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate
+\*****************************************************************************/
+static int imluaProcessRotate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+ int order = luaL_checkint(L, 5);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 5, "invalid order, must be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessRotate(src_image, dst_image, cos0, sin0, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotateRef
+\*****************************************************************************/
+static int imluaProcessRotateRef (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ double cos0 = (double) luaL_checknumber(L, 3);
+ double sin0 = (double) luaL_checknumber(L, 4);
+ int x = luaL_checkint(L, 5);
+ int y = luaL_checkint(L, 6);
+ int to_origin = luaL_checkint(L, 7);
+ int order = luaL_checkint(L, 8);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 5, "invalid order, must be 0, 1, or 3");
+
+ lua_pushboolean(L, imProcessRotateRef(src_image, dst_image, cos0, sin0, x, y, to_origin, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate90
+\*****************************************************************************/
+static int imluaProcessRotate90 (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int dir = luaL_checkint(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image);
+ luaL_argcheck(L, dst_image->width == src_image->height && dst_image->height == src_image->width, 2, "destiny width and height must have the source height and width");
+ luaL_argcheck(L, (dir == -1 || dir == 1), 3, "invalid dir, can be -1 or 1 only");
+
+ imProcessRotate90(src_image, dst_image, dir);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRotate180
+\*****************************************************************************/
+static int imluaProcessRotate180 (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessRotate180(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMirror
+\*****************************************************************************/
+static int imluaProcessMirror (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessMirror(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessFlip
+\*****************************************************************************/
+static int imluaProcessFlip (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ imProcessFlip(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessInterlaceSplit
+\*****************************************************************************/
+static int imluaProcessInterlaceSplit (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image1 = imlua_checkimage(L, 2);
+ imImage *dst_image2 = imlua_checkimage(L, 3);
+
+ imlua_matchcolor(L, src_image, dst_image1);
+ imlua_matchcolor(L, src_image, dst_image2);
+ luaL_argcheck(L, dst_image1->width == src_image->width && dst_image2->width == src_image->width, 2, "destiny width must be equal to source width");
+
+ if (src_image->height%2)
+ {
+ int dst_height1 = src_image->height/2 + 1;
+ luaL_argcheck(L, dst_image1->height == dst_height1, 2, "destiny1 height must be equal to source height/2+1 if height odd");
+ }
+ else
+ luaL_argcheck(L, dst_image1->height == src_image->height/2, 2, "destiny1 height must be equal to source height/2 if height even");
+
+ luaL_argcheck(L, dst_image2->height == src_image->height/2, 2, "destiny2 height must be equal to source height/2");
+
+ imProcessInterlaceSplit(src_image, dst_image1, dst_image2);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessRadial
+\*****************************************************************************/
+static int imluaProcessRadial (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float k1 = (float) luaL_checknumber(L, 3);
+ int order = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 4, "invalid order");
+
+ lua_pushboolean(L, imProcessRadial(src_image, dst_image, k1, order));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSwirl
+\*****************************************************************************/
+static int imluaProcessSwirl(lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float k1 = (float) luaL_checknumber(L, 3);
+ int order = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (order == 0 || order == 1 || order == 3), 4, "invalid order, can be 0, 1 or 3");
+
+ lua_pushboolean(L, imProcessSwirl(src_image, dst_image, k1, order));
+ return 1;
+}
+
+static void imlua_checknotcfloat(lua_State *L, imImage *image, int index)
+{
+ if (image->data_type == IM_CFLOAT)
+ luaL_argerror(L, index, "image data type can NOT be cfloat");
+}
+
+
+/*****************************************************************************\
+ Morphology Operations for Gray Images
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessGrayMorphConvolve
+\*****************************************************************************/
+static int imluaProcessGrayMorphConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int ismax = lua_toboolean(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, kernel, IM_INT);
+ imlua_matchsize(L, src_image, kernel);
+
+ lua_pushboolean(L, imProcessGrayMorphConvolve(src_image, dst_image, kernel, ismax));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphErode
+\*****************************************************************************/
+static int imluaProcessGrayMorphErode (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphErode(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphDilate
+\*****************************************************************************/
+static int imluaProcessGrayMorphDilate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphDilate(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphOpen
+\*****************************************************************************/
+static int imluaProcessGrayMorphOpen (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphOpen(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphClose
+\*****************************************************************************/
+static int imluaProcessGrayMorphClose (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphClose(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphTopHat
+\*****************************************************************************/
+static int imluaProcessGrayMorphTopHat (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphTopHat(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphWell
+\*****************************************************************************/
+static int imluaProcessGrayMorphWell (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphWell(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGrayMorphGradient
+\*****************************************************************************/
+static int imluaProcessGrayMorphGradient (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGrayMorphGradient(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Morphology Operations for Binary Images
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessBinMorphConvolve
+\*****************************************************************************/
+static int imluaProcessBinMorphConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int hit_white = luaL_checkint(L, 4);
+ int iter = luaL_checkint(L, 5);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, kernel, IM_INT);
+ imlua_matchsize(L, src_image, kernel);
+
+ lua_pushboolean(L, imProcessBinMorphConvolve(src_image, dst_image, kernel, hit_white, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphErode
+\*****************************************************************************/
+static int imluaProcessBinMorphErode (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphErode(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphDilate
+\*****************************************************************************/
+static int imluaProcessBinMorphDilate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphDilate(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphOpen
+\*****************************************************************************/
+static int imluaProcessBinMorphOpen (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphOpen(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphClose
+\*****************************************************************************/
+static int imluaProcessBinMorphClose (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphClose(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphOutline
+\*****************************************************************************/
+static int imluaProcessBinMorphOutline (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int iter = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBinMorphOutline(src_image, dst_image, kernel_size, iter));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBinMorphThin
+\*****************************************************************************/
+static int imluaProcessBinMorphThin (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_BINARY);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBinMorphThin(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Rank Convolution Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessMedianConvolve
+\*****************************************************************************/
+static int imluaProcessMedianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMedianConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRangeConvolve
+\*****************************************************************************/
+static int imluaProcessRangeConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRangeConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankClosestConvolve
+\*****************************************************************************/
+static int imluaProcessRankClosestConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankClosestConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankMaxConvolve
+\*****************************************************************************/
+static int imluaProcessRankMaxConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankMaxConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRankMinConvolve
+\*****************************************************************************/
+static int imluaProcessRankMinConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRankMinConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+
+/*****************************************************************************\
+ Convolution Operations
+\*****************************************************************************/
+
+static void imlua_checkkernel(lua_State *L, imImage* kernel, int index)
+{
+ imlua_checkcolorspace(L, index, kernel, IM_GRAY);
+ luaL_argcheck(L, kernel->data_type == IM_INT || kernel->data_type == IM_FLOAT, index, "kernel data type can be int or float only");
+}
+
+/*****************************************************************************\
+ im.ProcessConvolve
+\*****************************************************************************/
+static int imluaProcessConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolve(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveDual
+\*****************************************************************************/
+static int imluaProcessConvolveDual (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel1 = imlua_checkimage(L, 3);
+ imImage *kernel2 = imlua_checkimage(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel1, 3);
+ imlua_checkkernel(L, kernel2, 4);
+
+ lua_pushboolean(L, imProcessConvolveDual(src_image, dst_image, kernel1, kernel2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveRep
+\*****************************************************************************/
+static int imluaProcessConvolveRep (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+ int count = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolveRep(src_image, dst_image, kernel, count));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessConvolveSep
+\*****************************************************************************/
+static int imluaProcessConvolveSep (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessConvolveSep(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessCompassConvolve
+\*****************************************************************************/
+static int imluaProcessCompassConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ imImage *kernel = imlua_checkimage(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ imlua_checkkernel(L, kernel, 3);
+
+ lua_pushboolean(L, imProcessCompassConvolve(src_image, dst_image, kernel));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRotateKernel
+\*****************************************************************************/
+static int imluaProcessRotateKernel (lua_State *L)
+{
+ imProcessRotateKernel(imlua_checkimage(L, 1));
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDiffOfGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessDiffOfGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev1 = (float) luaL_checknumber(L, 3);
+ float stddev2 = (float) luaL_checknumber(L, 4);
+
+ if (src_image->data_type == IM_BYTE || src_image->data_type == IM_USHORT)
+ {
+ imlua_matchcolor(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_INT);
+ }
+ else
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessDiffOfGaussianConvolve(src_image, dst_image, stddev1, stddev2));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLapOfGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessLapOfGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ if (src_image->data_type == IM_BYTE || src_image->data_type == IM_USHORT)
+ {
+ imlua_matchcolor(L, src_image, dst_image);
+ imlua_checkdatatype(L, 2, dst_image, IM_INT);
+ }
+ else
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessLapOfGaussianConvolve(src_image, dst_image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMeanConvolve
+\*****************************************************************************/
+static int imluaProcessMeanConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMeanConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessBarlettConvolve
+\*****************************************************************************/
+static int imluaProcessBarlettConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessBarlettConvolve(src_image, dst_image, kernel_size));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessGaussianConvolve
+\*****************************************************************************/
+static int imluaProcessGaussianConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessGaussianConvolve(src_image, dst_image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessPrewittConvolve
+\*****************************************************************************/
+static int imluaProcessPrewittConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessPrewittConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSplineEdgeConvolve
+\*****************************************************************************/
+static int imluaProcessSplineEdgeConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessSplineEdgeConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSobelConvolve
+\*****************************************************************************/
+static int imluaProcessSobelConvolve (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessSobelConvolve(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessZeroCrossing
+\*****************************************************************************/
+static int imluaProcessZeroCrossing (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, src_image->data_type == IM_INT || src_image->data_type == IM_FLOAT, 1, "image data type can be int or float only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessZeroCrossing(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessCanny
+\*****************************************************************************/
+static int imluaProcessCanny (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float stddev = (float) luaL_checknumber(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessCanny(src_image, dst_image, stddev);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.GaussianStdDev2Repetitions
+\*****************************************************************************/
+static int imluaGaussianKernelSize2StdDev(lua_State *L)
+{
+ lua_pushnumber(L, imGaussianKernelSize2StdDev((int)luaL_checknumber(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.GaussianStdDev2KernelSize
+\*****************************************************************************/
+static int imluaGaussianStdDev2KernelSize (lua_State *L)
+{
+ lua_pushnumber(L, imGaussianStdDev2KernelSize((float)luaL_checknumber(L, 1)));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Arithmetic Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessUnArithmeticOp
+\*****************************************************************************/
+static int imluaProcessUnArithmeticOp (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int op = luaL_checkint(L, 3);
+
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessUnArithmeticOp(src_image, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessArithmeticOp
+\*****************************************************************************/
+static int imluaProcessArithmeticOp (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_matchsize(L, src_image1, dst_image);
+ imlua_matchsize(L, src_image2, dst_image);
+
+ switch (src_image1->data_type)
+ {
+ case IM_BYTE:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_BYTE ||
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is byte, destiny image data type can be byte, ushort, int and float only.");
+ break;
+ case IM_USHORT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is ushort, destiny image data type can be ushort, int and float only.");
+ break;
+ case IM_INT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is int, destiny image data type can be int and float only.");
+ break;
+ case IM_FLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is float, destiny image data type can be float only.");
+ break;
+ case IM_CFLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_CFLOAT,
+ 2, "source image is cfloat, destiny image data type can be cfloat only.");
+ break;
+ }
+
+ imProcessArithmeticOp(src_image1, src_image2, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessArithmeticConstOp
+\*****************************************************************************/
+static int imluaProcessArithmeticConstOp (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ float src_const = (float) luaL_checknumber(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_matchsize(L, src_image, dst_image);
+
+ switch (src_image->data_type)
+ {
+ case IM_BYTE:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_BYTE ||
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is byte, destiny image data type can be byte, ushort, int and float only.");
+ break;
+ case IM_USHORT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_USHORT ||
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is ushort, destiny image data type can be ushort, int and float only.");
+ break;
+ case IM_INT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_INT ||
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is int, destiny image data type can be int and float only.");
+ break;
+ case IM_FLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_FLOAT,
+ 2, "source image is float, destiny image data type can be float only.");
+ break;
+ case IM_CFLOAT:
+ luaL_argcheck(L,
+ dst_image->data_type == IM_CFLOAT,
+ 2, "source image is cfloat, destiny image data type can be cfloat only.");
+ break;
+ }
+
+ imProcessArithmeticConstOp(src_image, src_const, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBlendConst
+\*****************************************************************************/
+static int imluaProcessBlendConst (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ float alpha = (float) luaL_checknumber(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessBlendConst(src_image1, src_image2, dst_image, alpha);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBlend
+\*****************************************************************************/
+static int imluaProcessBlend (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *alpha_image = imlua_checkimage(L, 3);
+ imImage *dst_image = imlua_checkimage(L, 4);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+ imlua_matchdatatype(L, src_image1, alpha_image);
+
+ imProcessBlend(src_image1, src_image2, alpha_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitComplex
+\*****************************************************************************/
+static int imluaProcessSplitComplex (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image1 = imlua_checkimage(L, 2);
+ imImage *dst_image2 = imlua_checkimage(L, 3);
+ int polar = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_CFLOAT);
+ imlua_checkdatatype(L, 2, dst_image1, IM_FLOAT);
+ imlua_checkdatatype(L, 3, dst_image2, IM_FLOAT);
+ imlua_matchcolorspace(L, src_image, dst_image1);
+ imlua_matchcolorspace(L, src_image, dst_image2);
+
+ imProcessSplitComplex(src_image, dst_image1, dst_image2, polar);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeComplex
+\*****************************************************************************/
+static int imluaProcessMergeComplex (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int polar = luaL_checkint(L, 5);
+
+ imlua_checkdatatype(L, 1, src_image1, IM_FLOAT);
+ imlua_checkdatatype(L, 2, src_image2, IM_FLOAT);
+ imlua_checkdatatype(L, 3, dst_image, IM_CFLOAT);
+ imlua_matchcolorspace(L, src_image1, src_image2);
+ imlua_matchcolorspace(L, src_image1, dst_image);
+
+ imProcessMergeComplex(src_image1, src_image2, dst_image, polar);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMultipleMean
+\*****************************************************************************/
+static int imluaProcessMultipleMean (lua_State *L)
+{
+ int i, src_image_count;
+ imImage *dst_image;
+ imImage **src_image_list;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+ src_image_count = imlua_getn(L, 1);
+
+ src_image_list = (imImage**)malloc(sizeof(imImage*)*src_image_count);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ lua_rawgeti(L, 1, i+1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ }
+
+ dst_image = imlua_checkimage(L, 2);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ int check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessMultipleMean((const imImage**)src_image_list, src_image_count, dst_image);
+ free(src_image_list);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMultipleStdDev
+\*****************************************************************************/
+static int imluaProcessMultipleStdDev (lua_State *L)
+{
+ int i, src_image_count, check;
+ imImage *dst_image, *mean_image;
+ imImage **src_image_list;
+
+ if (!lua_istable(L, 1))
+ luaL_argerror(L, 1, "must be a table");
+
+ lua_pushstring(L, "table");
+ lua_gettable(L, LUA_GLOBALSINDEX);
+ lua_pushstring(L, "getn");
+ lua_gettable(L, -2);
+ src_image_count = luaL_checkint(L, -1);
+ lua_pop(L, 1);
+
+ src_image_list = (imImage**) malloc(src_image_count * sizeof(imImage*));
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ lua_rawgeti(L, 1, i+1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ }
+
+ mean_image = imlua_checkimage(L, 2);
+ dst_image = imlua_checkimage(L, 3);
+
+ for (i = 0; i < src_image_count; i++)
+ {
+ check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+ check = imImageMatchDataType(mean_image, dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+
+ imProcessMultipleStdDev((const imImage**)src_image_list, src_image_count, mean_image, dst_image);
+ free(src_image_list);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessAutoCovariance
+\*****************************************************************************/
+static int imluaProcessAutoCovariance (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *mean_image = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image, mean_image);
+ imlua_matchcolorspace(L, src_image, dst_image);
+ imlua_checkdatatype(L, 3, dst_image, IM_FLOAT);
+
+ lua_pushnumber(L, imProcessAutoCovariance(src_image, mean_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMultiplyConj
+\*****************************************************************************/
+static int imluaProcessMultiplyConj (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessMultiplyConj(src_image1, src_image2, dst_image);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Additional Image Quantization Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessQuantizeRGBUniform
+\*****************************************************************************/
+static int imluaProcessQuantizeRGBUniform (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int dither = luaL_checkint(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_RGB, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_MAP);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessQuantizeRGBUniform(src_image, dst_image, dither);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessQuantizeGrayUniform
+\*****************************************************************************/
+static int imluaProcessQuantizeGrayUniform (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int grays = luaL_checkint(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checktype(L, 2, dst_image, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessQuantizeGrayUniform(src_image, dst_image, grays);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Histogram Based Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessExpandHistogram
+\*****************************************************************************/
+static int imluaProcessExpandHistogram (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_image->color_space == IM_RGB || src_image->color_space == IM_GRAY, 1, "color space can be RGB or Gray only");
+ luaL_argcheck(L, dst_image->color_space == IM_RGB || dst_image->color_space == IM_GRAY, 2, "color space can be RGB or Gray only");
+
+ imProcessExpandHistogram(src_image, dst_image, percent);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessEqualizeHistogram
+\*****************************************************************************/
+static int imluaProcessEqualizeHistogram (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_image->color_space == IM_RGB || src_image->color_space == IM_GRAY, 1, "color space can be RGB or Gray only");
+ luaL_argcheck(L, dst_image->color_space == IM_RGB || dst_image->color_space == IM_GRAY, 2, "color space can be RGB or Gray only");
+
+ imProcessEqualizeHistogram(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Color Processing Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessSplitYChroma
+\*****************************************************************************/
+static int imluaProcessSplitYChroma (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *y_image = imlua_checkimage(L, 2);
+ imImage *chroma_image = imlua_checkimage(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_RGB, IM_BYTE);
+ imlua_checktype(L, 2, y_image, IM_GRAY, IM_BYTE);
+ imlua_checktype(L, 3, chroma_image, IM_RGB, IM_BYTE);
+ imlua_matchsize(L, src_image, y_image);
+ imlua_matchsize(L, src_image, chroma_image);
+
+ imProcessSplitYChroma(src_image, y_image, chroma_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitHSI
+\*****************************************************************************/
+static int imluaProcessSplitHSI (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *h_image = imlua_checkimage(L, 2);
+ imImage *s_image = imlua_checkimage(L, 3);
+ imImage *i_image = imlua_checkimage(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_RGB);
+ luaL_argcheck(L, src_image->data_type == IM_BYTE || src_image->data_type == IM_FLOAT, 1, "data type can be float or byte only");
+ imlua_checktype(L, 2, h_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 3, s_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 4, i_image, IM_GRAY, IM_FLOAT);
+ imlua_matchsize(L, src_image, h_image);
+ imlua_matchsize(L, src_image, s_image);
+ imlua_matchsize(L, src_image, i_image);
+
+ imProcessSplitHSI(src_image, h_image, s_image, i_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeHSI
+\*****************************************************************************/
+static int imluaProcessMergeHSI (lua_State *L)
+{
+ imImage *h_image = imlua_checkimage(L, 1);
+ imImage *s_image = imlua_checkimage(L, 2);
+ imImage *i_image = imlua_checkimage(L, 3);
+ imImage *dst_image = imlua_checkimage(L, 4);
+
+ imlua_checktype(L, 1, h_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 2, s_image, IM_GRAY, IM_FLOAT);
+ imlua_checktype(L, 3, i_image, IM_GRAY, IM_FLOAT);
+ imlua_checkcolorspace(L, 4, dst_image, IM_RGB);
+ luaL_argcheck(L, dst_image->data_type == IM_BYTE || dst_image->data_type == IM_FLOAT, 4, "data type can be float or byte only");
+ imlua_matchsize(L, dst_image, h_image);
+ imlua_matchsize(L, dst_image, s_image);
+ imlua_matchsize(L, dst_image, i_image);
+
+ imProcessMergeHSI(h_image, s_image, i_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessSplitComponents(src_image, { r, g, b} )
+\*****************************************************************************/
+static int imluaProcessSplitComponents (lua_State *L)
+{
+ int i;
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage **dst_image_list;
+
+ luaL_checktype(L, 2, LUA_TTABLE);
+
+ if (imlua_getn(L, 2) != src_image->depth)
+ luaL_error(L, "number of destiny images must match the depth of the source image");
+
+ dst_image_list = (imImage**)malloc(sizeof(imImage*)*src_image->depth);
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ lua_pushnumber(L, i+1);
+ lua_gettable(L, 2);
+ dst_image_list[i] = imlua_checkimage(L, -1);
+ imlua_checkcolorspace(L, 2, dst_image_list[i], IM_GRAY); /* if error here, there will be a memory leak */
+ lua_pop(L, 1);
+ }
+
+ for (i = 0; i < src_image->depth; i++)
+ {
+ int check = imImageMatchDataType(src_image, dst_image_list[i]);
+ if (!check) free(dst_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessSplitComponents(src_image, dst_image_list);
+
+ free(dst_image_list);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessMergeComponents({r, g, b}, rgb)
+\*****************************************************************************/
+static int imluaProcessMergeComponents (lua_State *L)
+{
+ int i;
+ imImage** src_image_list;
+ imImage *dst_image;
+
+ luaL_checktype(L, 1, LUA_TTABLE);
+ dst_image = imlua_checkimage(L, 2);
+
+ if (imlua_getn(L, 1) != dst_image->depth)
+ luaL_error(L, "number of source images must match the depth of the destination image");
+
+ src_image_list = (imImage**)malloc(sizeof(imImage*)*dst_image->depth);
+
+ for (i = 0; i < dst_image->depth; i++)
+ {
+ lua_pushnumber(L, i+1);
+ lua_gettable(L, 1);
+ src_image_list[i] = imlua_checkimage(L, -1);
+ imlua_checkcolorspace(L, 1, src_image_list[i], IM_GRAY);
+ lua_pop(L, 1);
+ }
+
+ for (i = 0; i < dst_image->depth; i++)
+ {
+ int check = imImageMatchDataType(src_image_list[i], dst_image);
+ if (!check) free(src_image_list);
+ imlua_matchcheck(L, check, "images must have the same size and data type");
+ }
+
+ imProcessMergeComponents((const imImage**)src_image_list, dst_image);
+
+ free(src_image_list);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessNormalizeComponents
+\*****************************************************************************/
+static int imluaProcessNormalizeComponents (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 2, dst_image, IM_FLOAT);
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessNormalizeComponents(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessReplaceColor
+\*****************************************************************************/
+static int imluaProcessReplaceColor (lua_State *L)
+{
+ int src_count, dst_count;
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float *src_color = imlua_toarrayfloat(L, 3, &src_count, 1);
+ float *dst_color = imlua_toarrayfloat(L, 4, &dst_count, 1);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, src_count == src_image->depth, 3, "the colors must have the same number of components of the images");
+ luaL_argcheck(L, dst_count == src_image->depth, 4, "the colors must have the same number of components of the images");
+
+ imProcessReplaceColor(src_image, dst_image, src_color, dst_color);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Logical Arithmetic Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessBitwiseOp
+\*****************************************************************************/
+static int imluaProcessBitwiseOp (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ luaL_argcheck(L, (src_image1->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image1, src_image2);
+ imlua_match(L, src_image1, dst_image);
+
+ imProcessBitwiseOp(src_image1, src_image2, dst_image, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitwiseNot
+\*****************************************************************************/
+static int imluaProcessBitwiseNot (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitwiseNot(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitMask(src_image, dst_image, mask, op)
+\*****************************************************************************/
+static int imluaProcessBitMask (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ unsigned char mask = imlua_checkmask(L, 3);
+ int op = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitMask(src_image, dst_image, mask, op);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessBitPlane(src_image, dst_image, plane, reset)
+\*****************************************************************************/
+static int imluaProcessBitPlane (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int plane = luaL_checkint(L, 3);
+ int reset = luaL_checkint(L, 4);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessBitPlane(src_image, dst_image, plane, reset);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Synthetic Image Render
+\*****************************************************************************/
+
+/* NOTE: This breaks on multithread */
+static lua_State *g_renderState = NULL;
+int g_paramCount = 0;
+
+static float imluaRenderFunc (int x, int y, int d, float *param)
+{
+ lua_State *L = g_renderState;
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushvalue(L, 2);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, d);
+ imlua_newarrayfloat(L, param, g_paramCount, 1);
+
+ lua_call(L, 4, 1);
+
+ return (float) luaL_checknumber(L, -1);
+}
+
+/*****************************************************************************\
+ im.ProcessRenderOp(image, function, name, param, plus)
+\*****************************************************************************/
+static int imluaProcessRenderOp (lua_State *L)
+{
+ int count;
+
+ imImage *image = imlua_checkimage(L, 1);
+ const char *render_name = luaL_checkstring(L, 3);
+ float *param = imlua_toarrayfloat(L, 4, &count, 1);
+ int plus = luaL_checkint(L, 5);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ g_renderState = L;
+ g_paramCount = count;
+ lua_pushboolean(L, imProcessRenderOp(image, imluaRenderFunc, (char*) render_name, param, plus));
+ return 1;
+}
+
+static float imluaRenderCondFunc (int x, int y, int d, int *cond, float *param)
+{
+ lua_State *L = g_renderState;
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+ lua_pushvalue(L, 2);
+ lua_pushnumber(L, x);
+ lua_pushnumber(L, y);
+ lua_pushnumber(L, d);
+ imlua_newarrayfloat(L, param, g_paramCount, 1);
+
+ lua_call(L, 4, 2);
+
+ *cond = luaL_checkint(L, -1);
+ return (float) luaL_checknumber(L, -2);
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCondOp(image, function, name, param)
+\*****************************************************************************/
+static int imluaProcessRenderCondOp (lua_State *L)
+{
+ int count;
+
+ imImage *image = imlua_checkimage(L, 1);
+ const char *render_name = luaL_checkstring(L, 3);
+ float *param = imlua_toarrayfloat(L, 4, &count, 1);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ luaL_checktype(L, 2, LUA_TFUNCTION);
+
+ g_renderState = L;
+ g_paramCount = count;
+ lua_pushboolean(L, imProcessRenderCondOp(image, imluaRenderCondFunc, (char*) render_name, param));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddSpeckleNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddSpeckleNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddSpeckleNoise(src_image, dst_image, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddGaussianNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddGaussianNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float mean = (float) luaL_checknumber(L, 3);
+ float stddev = (float) luaL_checknumber(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddGaussianNoise(src_image, dst_image, mean, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderAddUniformNoise
+\*****************************************************************************/
+static int imluaProcessRenderAddUniformNoise (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float mean = (float) luaL_checknumber(L, 3);
+ float stddev = (float) luaL_checknumber(L, 4);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRenderAddUniformNoise(src_image, dst_image, mean, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderRandomNoise
+\*****************************************************************************/
+static int imluaProcessRenderRandomNoise (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ imlua_checknotcfloat(L, image, 1);
+ lua_pushboolean(L, imProcessRenderRandomNoise(image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderConstant(image, [count])
+\*****************************************************************************/
+static int imluaProcessRenderConstant (lua_State *L)
+{
+ int i;
+ float *value = NULL;
+
+ imImage *image = imlua_checkimage(L, 1);
+ int count = image->depth;
+
+ imlua_checknotcfloat(L, image, 1);
+
+ if (lua_istable(L, 2))
+ {
+ value = (float*) malloc (sizeof(float) * count);
+
+ for (i = 0; i < count; i++)
+ {
+ lua_rawgeti(L, 2, i+1);
+ value[i] = (float) lua_tonumber(L, -1);
+ lua_pop(L, 1);
+ }
+ }
+
+ lua_pushboolean(L, imProcessRenderConstant(image, value));
+
+ if (value)
+ free(value);
+
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderWheel
+\*****************************************************************************/
+static int imluaProcessRenderWheel (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int int_radius = luaL_checkint(L, 2);
+ int ext_radius = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderWheel(image, int_radius, ext_radius));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCone
+\*****************************************************************************/
+static int imluaProcessRenderCone (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int radius = luaL_checkint(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderCone(image, radius));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderTent
+\*****************************************************************************/
+static int imluaProcessRenderTent (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderTent(image, width, height));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderRamp
+\*****************************************************************************/
+static int imluaProcessRenderRamp (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int start = luaL_checkint(L, 2);
+ int end = luaL_checkint(L, 3);
+ int dir = luaL_checkint(L, 4);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderRamp(image, start, end, dir));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderBox
+\*****************************************************************************/
+static int imluaProcessRenderBox (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int width = luaL_checkint(L, 2);
+ int height = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderBox(image, width, height));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderSinc
+\*****************************************************************************/
+static int imluaProcessRenderSinc (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float xperiod = (float) luaL_checknumber(L, 2);
+ float yperiod = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderSinc(image, xperiod, yperiod));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderGaussian
+\*****************************************************************************/
+static int imluaProcessRenderGaussian (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float stddev = (float) luaL_checknumber(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderGaussian(image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderLapOfGaussian
+\*****************************************************************************/
+static int imluaProcessRenderLapOfGaussian (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float stddev = (float) luaL_checknumber(L, 2);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderLapOfGaussian(image, stddev));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderCosine
+\*****************************************************************************/
+static int imluaProcessRenderCosine (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ float xperiod = (float) luaL_checknumber(L, 2);
+ float yperiod = (float) luaL_checknumber(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderCosine(image, xperiod, yperiod));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderGrid
+\*****************************************************************************/
+static int imluaProcessRenderGrid (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int x_space = luaL_checkint(L, 2);
+ int y_space = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderGrid(image, x_space, y_space));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessRenderChessboard
+\*****************************************************************************/
+static int imluaProcessRenderChessboard (lua_State *L)
+{
+ imImage *image = imlua_checkimage(L, 1);
+ int x_space = luaL_checkint(L, 2);
+ int y_space = luaL_checkint(L, 3);
+
+ imlua_checknotcfloat(L, image, 1);
+
+ lua_pushboolean(L, imProcessRenderChessboard(image, x_space, y_space));
+ return 1;
+}
+
+
+
+/*****************************************************************************\
+ Tone Gamut Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessToneGamut
+\*****************************************************************************/
+static int imluaProcessToneGamut (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int op = luaL_checkint(L, 3);
+ float *param = NULL;
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ param = imlua_toarrayfloat(L, 4, NULL, 1);
+
+ imProcessToneGamut(src_image, dst_image, op, param);
+
+ if (param)
+ free(param);
+
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessUnNormalize
+\*****************************************************************************/
+static int imluaProcessUnNormalize (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkdatatype(L, 1, src_image, IM_FLOAT);
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchcolorspace(L, src_image, dst_image);
+
+ imProcessUnNormalize(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessDirectConv
+\*****************************************************************************/
+static int imluaProcessDirectConv (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ luaL_argcheck(L,
+ src_image->data_type == IM_USHORT ||
+ src_image->data_type == IM_INT ||
+ src_image->data_type == IM_FLOAT,
+ 1, "data type can be ushort, int or float only");
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDirectConv(src_image, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessNegative
+\*****************************************************************************/
+static int imluaProcessNegative (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checknotcfloat(L, src_image, 1);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessNegative(src_image, dst_image);
+ return 0;
+}
+
+
+
+/*****************************************************************************\
+ Threshold Operations
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessRangeContrastThreshold
+\*****************************************************************************/
+static int imluaProcessRangeContrastThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int min_range = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessRangeContrastThreshold(src_image, dst_image, kernel_size, min_range));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLocalMaxThreshold
+\*****************************************************************************/
+static int imluaProcessLocalMaxThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int kernel_size = luaL_checkint(L, 3);
+ int min_thres = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessLocalMaxThreshold(src_image, dst_image, kernel_size, min_thres));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessThreshold
+\*****************************************************************************/
+static int imluaProcessThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+ int value = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessThreshold(src_image, dst_image, level, value);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessThresholdByDiff
+\*****************************************************************************/
+static int imluaProcessThresholdByDiff (lua_State *L)
+{
+ imImage *src_image1 = imlua_checkimage(L, 1);
+ imImage *src_image2 = imlua_checkimage(L, 2);
+ imImage *dst_image = imlua_checkimage(L, 3);
+
+ imlua_checktype(L, 1, src_image1, IM_GRAY, IM_BYTE);
+ imlua_match(L, src_image1, src_image2);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image1, dst_image);
+
+ imProcessThresholdByDiff(src_image1, src_image2, dst_image);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHysteresisThreshold
+\*****************************************************************************/
+static int imluaProcessHysteresisThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int low_thres = luaL_checkint(L, 3);
+ int high_thres = luaL_checkint(L, 4);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessHysteresisThreshold(src_image, dst_image, low_thres, high_thres);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessHysteresisThresEstimate
+\*****************************************************************************/
+static int imluaProcessHysteresisThresEstimate (lua_State *L)
+{
+ int low_thres, high_thres;
+
+ imImage *src_image = imlua_checkimage(L, 1);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+
+ imProcessHysteresisThresEstimate(src_image, &low_thres, &high_thres);
+ lua_pushnumber(L, low_thres);
+ lua_pushnumber(L, high_thres);
+
+ return 2;
+}
+
+/*****************************************************************************\
+ im.ProcessUniformErrThreshold
+\*****************************************************************************/
+static int imluaProcessUniformErrThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessUniformErrThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessDifusionErrThreshold
+\*****************************************************************************/
+static int imluaProcessDifusionErrThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_checkdatatype(L, 2, dst_image, IM_BYTE);
+ imlua_matchcheck(L, src_image->depth == dst_image->depth, "images must have the same depth");
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessDifusionErrThreshold(src_image, dst_image, level);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessPercentThreshold
+\*****************************************************************************/
+static int imluaProcessPercentThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ float percent = (float) luaL_checknumber(L, 3);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessPercentThreshold(src_image, dst_image, percent));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessOtsuThreshold
+\*****************************************************************************/
+static int imluaProcessOtsuThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checktype(L, 1, src_image, IM_GRAY, IM_BYTE);
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushnumber(L, imProcessOtsuThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessMinMaxThreshold
+\*****************************************************************************/
+static int imluaProcessMinMaxThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_GRAY);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ lua_pushboolean(L, imProcessMinMaxThreshold(src_image, dst_image));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessLocalMaxThresEstimate
+\*****************************************************************************/
+static int imluaProcessLocalMaxThresEstimate (lua_State *L)
+{
+ int thres;
+ imImage *image = imlua_checkimage(L, 1);
+
+ imlua_checkdatatype(L, 1, image, IM_BYTE);
+
+ imProcessLocalMaxThresEstimate(image, &thres);
+
+ lua_pushnumber(L, thres);
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ProcessSliceThreshold
+\*****************************************************************************/
+static int imluaProcessSliceThreshold (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+
+ int start_level = luaL_checkint(L, 3);
+ int end_level = luaL_checkint(L, 4);
+
+ imlua_checkcolorspace(L, 1, src_image, IM_GRAY);
+ luaL_argcheck(L, (src_image->data_type < IM_FLOAT), 1, "image data type can be integer only");
+ imlua_checkcolorspace(L, 2, dst_image, IM_BINARY);
+ imlua_matchsize(L, src_image, dst_image);
+
+ imProcessSliceThreshold(src_image, dst_image, start_level, end_level);
+ return 0;
+}
+
+
+/*****************************************************************************\
+ Special Effects
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ProcessPixelate
+\*****************************************************************************/
+static int imluaProcessPixelate (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int box_size = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+
+ imProcessPixelate(src_image, dst_image, box_size);
+ return 0;
+}
+
+/*****************************************************************************\
+ im.ProcessPosterize
+\*****************************************************************************/
+static int imluaProcessPosterize (lua_State *L)
+{
+ imImage *src_image = imlua_checkimage(L, 1);
+ imImage *dst_image = imlua_checkimage(L, 2);
+ int level = luaL_checkint(L, 3);
+
+ imlua_checkdatatype(L, 1, src_image, IM_BYTE);
+ imlua_match(L, src_image, dst_image);
+ luaL_argcheck(L, (level >= 1 && level <= 7), 3, "invalid level, must be >=1 and <=7");
+
+ imProcessPosterize(src_image, dst_image, level);
+ return 0;
+}
+
+
+
+static const luaL_reg improcess_lib[] = {
+ {"CalcRMSError", imluaCalcRMSError},
+ {"CalcSNR", imluaCalcSNR},
+ {"CalcCountColors", imluaCalcCountColors},
+ {"CalcHistogram", imluaCalcHistogram},
+ /*{"CalcUShortHistogram", imluaCalcUShortHistogram}, done by imluaCalcHistogram */
+ {"CalcGrayHistogram", imluaCalcGrayHistogram},
+ {"CalcImageStatistics", imluaCalcImageStatistics},
+ {"CalcHistogramStatistics", imluaCalcHistogramStatistics},
+ {"CalcHistoImageStatistics", imluaCalcHistoImageStatistics},
+
+ {"AnalyzeFindRegions", imluaAnalyzeFindRegions},
+ {"AnalyzeMeasureArea", imluaAnalyzeMeasureArea},
+ {"AnalyzeMeasurePerimArea", imluaAnalyzeMeasurePerimArea},
+ {"AnalyzeMeasureCentroid", imluaAnalyzeMeasureCentroid},
+ {"AnalyzeMeasurePrincipalAxis", imluaAnalyzeMeasurePrincipalAxis},
+ {"AnalyzeMeasurePerimeter", imluaAnalyzeMeasurePerimeter},
+ {"AnalyzeMeasureHoles", imluaAnalyzeMeasureHoles},
+
+ {"ProcessPerimeterLine", imluaProcessPerimeterLine},
+ {"ProcessPrune", imluaProcessPrune},
+ {"ProcessFillHoles", imluaProcessFillHoles},
+
+ {"ProcessHoughLines", imluaProcessHoughLines},
+ {"ProcessHoughLinesDraw", imluaProcessHoughLinesDraw},
+ {"ProcessDistanceTransform", imluaProcessDistanceTransform},
+ {"ProcessRegionalMaximum", imluaProcessRegionalMaximum},
+
+ {"ProcessReduce", imluaProcessReduce},
+ {"ProcessResize", imluaProcessResize},
+ {"ProcessReduceBy4", imluaProcessReduceBy4},
+ {"ProcessCrop", imluaProcessCrop},
+ {"ProcessAddMargins", imluaProcessAddMargins},
+ {"ProcessInsert", imluaProcessInsert},
+
+ {"ProcessCalcRotateSize", imluaProcessCalcRotateSize},
+ {"ProcessRotate", imluaProcessRotate},
+ {"ProcessRotateRef", imluaProcessRotateRef},
+ {"ProcessRotate90", imluaProcessRotate90},
+ {"ProcessRotate180", imluaProcessRotate180},
+ {"ProcessMirror", imluaProcessMirror},
+ {"ProcessFlip", imluaProcessFlip},
+ {"ProcessRadial", imluaProcessRadial},
+ {"ProcessSwirl", imluaProcessSwirl},
+ {"ProcessInterlaceSplit", imluaProcessInterlaceSplit},
+
+ {"ProcessGrayMorphConvolve", imluaProcessGrayMorphConvolve},
+ {"ProcessGrayMorphErode", imluaProcessGrayMorphErode},
+ {"ProcessGrayMorphDilate", imluaProcessGrayMorphDilate},
+ {"ProcessGrayMorphOpen", imluaProcessGrayMorphOpen},
+ {"ProcessGrayMorphClose", imluaProcessGrayMorphClose},
+ {"ProcessGrayMorphTopHat", imluaProcessGrayMorphTopHat},
+ {"ProcessGrayMorphWell", imluaProcessGrayMorphWell},
+ {"ProcessGrayMorphGradient", imluaProcessGrayMorphGradient},
+
+ {"ProcessBinMorphConvolve", imluaProcessBinMorphConvolve},
+ {"ProcessBinMorphErode", imluaProcessBinMorphErode},
+ {"ProcessBinMorphDilate", imluaProcessBinMorphDilate},
+ {"ProcessBinMorphOpen", imluaProcessBinMorphOpen},
+ {"ProcessBinMorphClose", imluaProcessBinMorphClose},
+ {"ProcessBinMorphOutline", imluaProcessBinMorphOutline},
+ {"ProcessBinMorphThin", imluaProcessBinMorphThin},
+
+ {"ProcessMedianConvolve", imluaProcessMedianConvolve},
+ {"ProcessRangeConvolve", imluaProcessRangeConvolve},
+ {"ProcessRankClosestConvolve", imluaProcessRankClosestConvolve},
+ {"ProcessRankMaxConvolve", imluaProcessRankMaxConvolve},
+ {"ProcessRankMinConvolve", imluaProcessRankMinConvolve},
+
+ {"ProcessConvolve", imluaProcessConvolve},
+ {"ProcessConvolveDual", imluaProcessConvolveDual},
+ {"ProcessConvolveRep", imluaProcessConvolveRep},
+ {"ProcessConvolveSep", imluaProcessConvolveSep},
+ {"ProcessCompassConvolve", imluaProcessCompassConvolve},
+ {"ProcessRotateKernel", imluaProcessRotateKernel},
+ {"ProcessDiffOfGaussianConvolve", imluaProcessDiffOfGaussianConvolve},
+ {"ProcessLapOfGaussianConvolve", imluaProcessLapOfGaussianConvolve},
+ {"ProcessMeanConvolve", imluaProcessMeanConvolve},
+ {"ProcessBarlettConvolve", imluaProcessBarlettConvolve},
+ {"ProcessGaussianConvolve", imluaProcessGaussianConvolve},
+ {"ProcessSobelConvolve", imluaProcessSobelConvolve},
+ {"ProcessPrewittConvolve", imluaProcessPrewittConvolve},
+ {"ProcessSplineEdgeConvolve", imluaProcessSplineEdgeConvolve},
+ {"ProcessZeroCrossing", imluaProcessZeroCrossing},
+ {"ProcessCanny", imluaProcessCanny},
+ {"GaussianKernelSize2StdDev", imluaGaussianKernelSize2StdDev},
+ {"GaussianStdDev2KernelSize", imluaGaussianStdDev2KernelSize},
+
+ {"ProcessUnArithmeticOp", imluaProcessUnArithmeticOp},
+ {"ProcessArithmeticOp", imluaProcessArithmeticOp},
+ {"ProcessArithmeticConstOp", imluaProcessArithmeticConstOp},
+ {"ProcessBlendConst", imluaProcessBlendConst},
+ {"ProcessBlend", imluaProcessBlend},
+ {"ProcessSplitComplex", imluaProcessSplitComplex},
+ {"ProcessMergeComplex", imluaProcessMergeComplex},
+ {"ProcessMultipleMean", imluaProcessMultipleMean},
+ {"ProcessMultipleStdDev", imluaProcessMultipleStdDev},
+ {"ProcessAutoCovariance", imluaProcessAutoCovariance},
+ {"ProcessMultiplyConj", imluaProcessMultiplyConj},
+
+ {"ProcessQuantizeRGBUniform", imluaProcessQuantizeRGBUniform},
+ {"ProcessQuantizeGrayUniform", imluaProcessQuantizeGrayUniform},
+
+ {"ProcessExpandHistogram", imluaProcessExpandHistogram},
+ {"ProcessEqualizeHistogram", imluaProcessEqualizeHistogram},
+
+ {"ProcessSplitYChroma", imluaProcessSplitYChroma},
+ {"ProcessSplitHSI", imluaProcessSplitHSI},
+ {"ProcessMergeHSI", imluaProcessMergeHSI},
+ {"ProcessSplitComponents", imluaProcessSplitComponents},
+ {"ProcessMergeComponents", imluaProcessMergeComponents},
+ {"ProcessNormalizeComponents", imluaProcessNormalizeComponents},
+ {"ProcessReplaceColor", imluaProcessReplaceColor},
+
+ {"ProcessBitwiseOp", imluaProcessBitwiseOp},
+ {"ProcessBitwiseNot", imluaProcessBitwiseNot},
+ {"ProcessBitMask", imluaProcessBitMask},
+ {"ProcessBitPlane", imluaProcessBitPlane},
+
+ {"ProcessRenderOp", imluaProcessRenderOp},
+ {"ProcessRenderCondOp", imluaProcessRenderCondOp},
+ {"ProcessRenderAddSpeckleNoise", imluaProcessRenderAddSpeckleNoise},
+ {"ProcessRenderAddGaussianNoise", imluaProcessRenderAddGaussianNoise},
+ {"ProcessRenderAddUniformNoise", imluaProcessRenderAddUniformNoise},
+ {"ProcessRenderRandomNoise", imluaProcessRenderRandomNoise},
+ {"ProcessRenderConstant", imluaProcessRenderConstant},
+ {"ProcessRenderWheel", imluaProcessRenderWheel},
+ {"ProcessRenderCone", imluaProcessRenderCone},
+ {"ProcessRenderTent", imluaProcessRenderTent},
+ {"ProcessRenderRamp", imluaProcessRenderRamp},
+ {"ProcessRenderBox", imluaProcessRenderBox},
+ {"ProcessRenderSinc", imluaProcessRenderSinc},
+ {"ProcessRenderGaussian", imluaProcessRenderGaussian},
+ {"ProcessRenderLapOfGaussian", imluaProcessRenderLapOfGaussian},
+ {"ProcessRenderCosine", imluaProcessRenderCosine},
+ {"ProcessRenderGrid", imluaProcessRenderGrid},
+ {"ProcessRenderChessboard", imluaProcessRenderChessboard},
+
+ {"ProcessToneGamut", imluaProcessToneGamut},
+ {"ProcessUnNormalize", imluaProcessUnNormalize},
+ {"ProcessDirectConv", imluaProcessDirectConv},
+ {"ProcessNegative", imluaProcessNegative},
+
+ {"ProcessRangeContrastThreshold", imluaProcessRangeContrastThreshold},
+ {"ProcessLocalMaxThreshold", imluaProcessLocalMaxThreshold},
+ {"ProcessThreshold", imluaProcessThreshold},
+ {"ProcessThresholdByDiff", imluaProcessThresholdByDiff},
+ {"ProcessHysteresisThreshold", imluaProcessHysteresisThreshold},
+ {"ProcessHysteresisThresEstimate", imluaProcessHysteresisThresEstimate},
+ {"ProcessUniformErrThreshold", imluaProcessUniformErrThreshold},
+ {"ProcessDifusionErrThreshold", imluaProcessDifusionErrThreshold},
+ {"ProcessPercentThreshold", imluaProcessPercentThreshold},
+ {"ProcessOtsuThreshold", imluaProcessOtsuThreshold},
+ {"ProcessMinMaxThreshold", imluaProcessMinMaxThreshold},
+ {"ProcessLocalMaxThresEstimate", imluaProcessLocalMaxThresEstimate},
+ {"ProcessSliceThreshold", imluaProcessSliceThreshold},
+
+ {"ProcessPixelate", imluaProcessPixelate},
+ {"ProcessPosterize", imluaProcessPosterize},
+
+ {NULL, NULL}
+};
+
+/*****************************************************************************\
+ Constants
+\*****************************************************************************/
+static const imlua_constant im_process_constants[] = {
+
+ { "UN_EQL", IM_UN_EQL, NULL },
+ { "UN_ABS", IM_UN_ABS, NULL },
+ { "UN_LESS", IM_UN_LESS, NULL },
+ { "UN_INC", IM_UN_INC, NULL },
+ { "UN_INV", IM_UN_INV, NULL },
+ { "UN_SQR", IM_UN_SQR, NULL },
+ { "UN_SQRT", IM_UN_SQRT, NULL },
+ { "UN_LOG", IM_UN_LOG, NULL },
+ { "UN_EXP", IM_UN_EXP, NULL },
+ { "UN_SIN", IM_UN_SIN, NULL },
+ { "UN_COS", IM_UN_COS, NULL },
+ { "UN_CONJ", IM_UN_CONJ, NULL },
+ { "UN_CPXNORM", IM_UN_CPXNORM, NULL },
+
+ { "BIN_ADD", IM_BIN_ADD, NULL },
+ { "BIN_SUB", IM_BIN_SUB, NULL },
+ { "BIN_MUL", IM_BIN_MUL, NULL },
+ { "BIN_DIV", IM_BIN_DIV, NULL },
+ { "BIN_DIFF", IM_BIN_DIFF, NULL },
+ { "BIN_POW", IM_BIN_POW, NULL },
+ { "BIN_MIN", IM_BIN_MIN, NULL },
+ { "BIN_MAX", IM_BIN_MAX, NULL },
+
+ { "BIT_AND", IM_BIT_AND, NULL },
+ { "BIT_OR", IM_BIT_OR, NULL },
+ { "BIT_XOR", IM_BIT_XOR, NULL },
+
+ { "GAMUT_NORMALIZE", IM_GAMUT_NORMALIZE, NULL },
+ { "GAMUT_POW", IM_GAMUT_POW, NULL },
+ { "GAMUT_LOG", IM_GAMUT_LOG, NULL },
+ { "GAMUT_EXP", IM_GAMUT_EXP, NULL },
+ { "GAMUT_INVERT", IM_GAMUT_INVERT, NULL },
+ { "GAMUT_ZEROSTART", IM_GAMUT_ZEROSTART, NULL },
+ { "GAMUT_SOLARIZE", IM_GAMUT_SOLARIZE, NULL },
+ { "GAMUT_SLICE", IM_GAMUT_SLICE, NULL },
+ { "GAMUT_EXPAND", IM_GAMUT_EXPAND, NULL },
+ { "GAMUT_CROP", IM_GAMUT_CROP, NULL },
+ { "GAMUT_BRIGHTCONT", IM_GAMUT_BRIGHTCONT, NULL },
+
+ { NULL, -1, NULL },
+};
+
+/* from imlua_kernel.c */
+void imlua_open_kernel(lua_State *L);
+
+int imlua_open_process(lua_State *L)
+{
+ luaL_register(L, "im", improcess_lib); /* leave "im" table at the top of the stack */
+ imlua_regconstants(L, im_process_constants);
+#ifdef TEC_BIGENDIAN
+#ifdef TEC_64
+#include "im_process_be64.loh"
+#else
+#include "im_process_be32.loh"
+#endif
+#else
+#ifdef TEC_64
+#ifdef WIN64
+#include "im_process_le64w.loh"
+#else
+#include "im_process_le64.loh"
+#endif
+#else
+#include "im_process.loh"
+#endif
+#endif
+ imlua_open_kernel(L);
+ return 1;
+}
+
+int luaopen_imlua_process(lua_State *L)
+{
+ return imlua_open_process(L);
+}
+
+int luaopen_imlua_process51(lua_State *L)
+{
+ return imlua_open_process(L);
+}
+
diff --git a/src/lua5/imlua_process.def b/src/lua5/imlua_process.def
new file mode 100644
index 0000000..2b77e77
--- /dev/null
+++ b/src/lua5/imlua_process.def
@@ -0,0 +1,4 @@
+EXPORTS
+ imlua_open_process
+ luaopen_imlua_process
+ luaopen_imlua_process51 \ No newline at end of file
diff --git a/src/lua5/imlua_util.c b/src/lua5/imlua_util.c
new file mode 100644
index 0000000..69cfb19
--- /dev/null
+++ b/src/lua5/imlua_util.c
@@ -0,0 +1,279 @@
+/** \file
+ * \brief IM Lua 5 Binding
+ *
+ * See Copyright Notice in im_lib.h
+ * $Id: imlua_util.c,v 1.1 2008/10/17 06:16:32 scuri Exp $
+ */
+
+#include "im.h"
+#include "im_util.h"
+#include "im_image.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+#include "imlua.h"
+#include "imlua_aux.h"
+
+/*****************************************************************************\
+ im.ImageDataSize(width, height, color_mode, data_type)
+\*****************************************************************************/
+static int imluaImageDataSize (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int height = luaL_checkint(L, 2);
+ int color_mode = luaL_checkint(L, 3);
+ int data_type = luaL_checkint(L, 4);
+
+ lua_pushnumber(L, imImageDataSize(width, height, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageLineSize(width, color_mode, data_type)
+\*****************************************************************************/
+static int imluaImageLineSize (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int color_mode = luaL_checkint(L, 2);
+ int data_type = luaL_checkint(L, 3);
+
+ lua_pushnumber(L, imImageLineSize(width, color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageLineCount(width, color_mode)
+\*****************************************************************************/
+static int imluaImageLineCount (lua_State *L)
+{
+ int width = luaL_checkint(L, 1);
+ int color_mode = luaL_checkint(L, 2);
+
+ lua_pushnumber(L, imImageLineCount(width, color_mode));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ImageCheckFormat(width, color_mode)
+\*****************************************************************************/
+static int imluaImageCheckFormat (lua_State *L)
+{
+ int color_mode = luaL_checkint(L, 1);
+ int data_type = luaL_checkint(L, 2);
+
+ lua_pushboolean(L, imImageCheckFormat(color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeSpaceName(color_mode)
+\*****************************************************************************/
+static int imluaColorModeSpaceName (lua_State *L)
+{
+ lua_pushstring(L, imColorModeSpaceName(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeDepth(color_mode)
+\*****************************************************************************/
+static int imluaColorModeDepth (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeDepth(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+
+\*****************************************************************************/
+
+/*****************************************************************************\
+ im.ColorModeSpace(color_mode)
+\*****************************************************************************/
+static int imluaColorModeSpace (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeSpace(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeHasAlpha(color_mode)
+\*****************************************************************************/
+static int imluaColorModeMatch (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeMatch(luaL_checkint(L, 1), luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeHasAlpha(color_mode)
+\*****************************************************************************/
+static int imluaColorModeHasAlpha (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeHasAlpha(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsPacked(color_mode)
+\*****************************************************************************/
+static int imluaColorModeIsPacked (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeIsPacked(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsTopDown(color_mode)
+\*****************************************************************************/
+static int imluaColorModeIsTopDown (lua_State *L)
+{
+ lua_pushboolean(L, imColorModeIsTopDown(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeToBitmap(color_mode)
+\*****************************************************************************/
+static int imluaColorModeToBitmap (lua_State *L)
+{
+ lua_pushnumber(L, imColorModeToBitmap(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.ColorModeIsBitmap
+\*****************************************************************************/
+static int imluaColorModeIsBitmap (lua_State *L)
+{
+ int color_mode = luaL_checkint(L, 1);
+ int data_type = luaL_checkint(L, 2);
+
+ lua_pushboolean(L, imColorModeIsBitmap(color_mode, data_type));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeSize(data_type)
+\*****************************************************************************/
+static int imluaDataTypeSize (lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeSize(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeName(data_type)
+\*****************************************************************************/
+static int imluaDataTypeName (lua_State *L)
+{
+ lua_pushstring(L, imDataTypeName(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeIntMax(data_type)
+\*****************************************************************************/
+static int imluaDataTypeIntMax(lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeIntMax(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/*****************************************************************************\
+ im.DataTypeIntMin(data_type)
+\*****************************************************************************/
+static int imluaDataTypeIntMin(lua_State *L)
+{
+ lua_pushnumber(L, imDataTypeIntMin(luaL_checkint(L, 1)));
+ return 1;
+}
+
+/***************************************************************************\
+* Creates a color as a light userdata. The color value is *
+* placed in the (void *) value. Not beautiful, but works best. *
+* im.ColorEncode(r, g, b: number) -> (c: color) *
+\***************************************************************************/
+static int imlua_colorencode(lua_State *L)
+{
+ int red_f, green_f, blue_f;
+ unsigned char red_i, green_i, blue_i;
+ long int color_i;
+
+ red_f = luaL_checkint(L, 1);
+ green_f = luaL_checkint(L, 2);
+ blue_f = luaL_checkint(L, 3);
+
+ if (red_f < 0 || red_f > 255)
+ luaL_argerror(L, 1, "color components values should be in range [0, 255]");
+ if (green_f < 0 || green_f > 255)
+ luaL_argerror(L, 2, "color components values should be in range [0, 255]");
+ if (blue_f < 0 || blue_f > 255)
+ luaL_argerror(L, 3, "color components values should be in range [0, 255]");
+
+ red_i = (unsigned char) (red_f);
+ green_i = (unsigned char) (green_f);
+ blue_i = (unsigned char) (blue_f);
+
+ color_i = imColorEncode(red_i, green_i, blue_i);
+ lua_pushlightuserdata(L, (void *)color_i);
+
+ return 1;
+}
+
+/***************************************************************************\
+* Decodes a color previously created. *
+* im.ColorDecode(c: color) -> (r, g, b: number) *
+\***************************************************************************/
+static int imlua_colordecode(lua_State *L)
+{
+ long int color_i;
+ unsigned char red_i, green_i, blue_i;
+
+ if (!lua_islightuserdata(L, 1))
+ luaL_argerror(L, 1, "color must be a light user data");
+
+ color_i = (long int) lua_touserdata(L,1);
+
+ imColorDecode(&red_i, &green_i, &blue_i, color_i);
+ lua_pushnumber(L, red_i);
+ lua_pushnumber(L, green_i);
+ lua_pushnumber(L, blue_i);
+
+ return 3;
+}
+
+static const luaL_reg imutil_lib[] = {
+ {"ImageDataSize", imluaImageDataSize},
+ {"ImageLineSize", imluaImageLineSize},
+ {"ImageLineCount", imluaImageLineCount},
+ {"ImageCheckFormat", imluaImageCheckFormat},
+
+ {"ColorModeSpace", imluaColorModeSpace},
+ {"ColorModeSpaceName", imluaColorModeSpaceName},
+ {"ColorModeDepth", imluaColorModeDepth},
+
+ {"ColorModeToBitmap", imluaColorModeToBitmap},
+ {"ColorModeIsBitmap", imluaColorModeIsBitmap},
+ {"ColorModeMatch", imluaColorModeMatch},
+ {"ColorModeHasAlpha", imluaColorModeHasAlpha},
+ {"ColorModeIsPacked", imluaColorModeIsPacked},
+ {"ColorModeIsTopDown", imluaColorModeIsTopDown},
+
+ {"DataTypeSize", imluaDataTypeSize},
+ {"DataTypeName", imluaDataTypeName},
+ {"DataTypeIntMax", imluaDataTypeIntMax},
+ {"DataTypeIntMin", imluaDataTypeIntMin},
+
+ {"ColorEncode", imlua_colorencode},
+ {"ColorDecode", imlua_colordecode},
+
+ {NULL, NULL}
+};
+
+void imlua_open_util(lua_State *L)
+{
+ /* "im" table is at the top of the stack */
+ luaL_register(L, NULL, imutil_lib);
+}
diff --git a/src/lua5/imlua_wmv.c b/src/lua5/imlua_wmv.c
new file mode 100644
index 0000000..7f61030
--- /dev/null
+++ b/src/lua5/imlua_wmv.c
@@ -0,0 +1,44 @@
+/** \file
+ * \brief wmv format Lua 5 Binding
+ *
+ * See Copyright Notice in cd.h
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "im_format_wmv.h"
+
+#include <lua.h>
+#include <lauxlib.h>
+
+
+static int imlua_FormatRegisterWMV(lua_State *L)
+{
+ (void)L;
+ imFormatRegisterWMV();
+ return 0;
+}
+
+static const struct luaL_reg imlib[] = {
+ {"FormatRegisterWMV", imlua_FormatRegisterWMV},
+ {NULL, NULL},
+};
+
+
+static int imlua_wmv_open (lua_State *L)
+{
+ imFormatRegisterWMV();
+ luaL_register(L, "im", imlib); /* leave "im" table at the top of the stack */
+ return 1;
+}
+
+int luaopen_imlua_wmv(lua_State* L)
+{
+ return imlua_wmv_open(L);
+}
+
+int luaopen_imlua_wmv51(lua_State* L)
+{
+ return imlua_wmv_open(L);
+}
diff --git a/src/lua5/imlua_wmv.def b/src/lua5/imlua_wmv.def
new file mode 100644
index 0000000..0c05563
--- /dev/null
+++ b/src/lua5/imlua_wmv.def
@@ -0,0 +1,4 @@
+EXPORTS
+ luaopen_imlua_wmv
+ luaopen_imlua_wmv51
+ \ No newline at end of file