diff options
author | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
---|---|---|
committer | scuri <scuri> | 2008-10-17 06:10:15 +0000 |
commit | 5a422aba704c375a307a902bafe658342e209906 (patch) | |
tree | 5005011e086bb863d8fb587ad3319bbec59b2447 /src/lua5 |
First commit - moving from LuaForge to SourceForge
Diffstat (limited to 'src/lua5')
-rw-r--r-- | src/lua5/.cvsignore | 9 | ||||
-rw-r--r-- | src/lua5/im_fftw.lua | 48 | ||||
-rw-r--r-- | src/lua5/im_process.lua | 326 | ||||
-rw-r--r-- | src/lua5/imlua.c | 246 | ||||
-rw-r--r-- | src/lua5/imlua.def | 24 | ||||
-rw-r--r-- | src/lua5/imlua_aux.c | 255 | ||||
-rw-r--r-- | src/lua5/imlua_aux.h | 82 | ||||
-rw-r--r-- | src/lua5/imlua_avi.c | 44 | ||||
-rw-r--r-- | src/lua5/imlua_avi.def | 4 | ||||
-rw-r--r-- | src/lua5/imlua_capture.c | 421 | ||||
-rw-r--r-- | src/lua5/imlua_capture.def | 5 | ||||
-rw-r--r-- | src/lua5/imlua_convert.c | 79 | ||||
-rw-r--r-- | src/lua5/imlua_fftw.c | 162 | ||||
-rw-r--r-- | src/lua5/imlua_fftw.def | 4 | ||||
-rw-r--r-- | src/lua5/imlua_file.c | 661 | ||||
-rw-r--r-- | src/lua5/imlua_image.c | 1061 | ||||
-rw-r--r-- | src/lua5/imlua_image.h | 38 | ||||
-rw-r--r-- | src/lua5/imlua_jp2.c | 44 | ||||
-rw-r--r-- | src/lua5/imlua_jp2.def | 4 | ||||
-rw-r--r-- | src/lua5/imlua_kernel.c | 182 | ||||
-rw-r--r-- | src/lua5/imlua_palette.c | 399 | ||||
-rw-r--r-- | src/lua5/imlua_palette.h | 32 | ||||
-rw-r--r-- | src/lua5/imlua_process.c | 3091 | ||||
-rw-r--r-- | src/lua5/imlua_process.def | 4 | ||||
-rw-r--r-- | src/lua5/imlua_util.c | 279 | ||||
-rw-r--r-- | src/lua5/imlua_wmv.c | 44 | ||||
-rw-r--r-- | src/lua5/imlua_wmv.def | 4 |
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 |