diff options
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  | 
