diff options
Diffstat (limited to 'src/lua5/imlua_file.c')
-rw-r--r-- | src/lua5/imlua_file.c | 661 |
1 files changed, 661 insertions, 0 deletions
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); +} |