From d87c34117e163c006f0ab4bb315748b85e381c98 Mon Sep 17 00:00:00 2001 From: Ronan Collobert Date: Thu, 3 Oct 2013 19:04:29 +0200 Subject: exe can now be compiled in a standalone way --- CMakeLists.txt | 21 ++++++ dok/index.dok | 54 +++++++++++++++ generic/qttorch.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++ init.lua | 16 +++++ qttorch.cpp | 62 +++++++++++++++++ qttorch.h | 34 ++++++++++ 6 files changed, 379 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 dok/index.dok create mode 100644 generic/qttorch.cpp create mode 100644 init.lua create mode 100644 qttorch.cpp create mode 100644 qttorch.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3e7c93f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +# -*- cmake -*- + +IF(Torch_SOURCE_DIR) + + INCLUDE_DIRECTORIES("${Torch_SOURCE_DIR}/lib/TH") + INCLUDE_DIRECTORIES("${Torch_SOURCE_DIR}/lib/luaT") + INCLUDE_DIRECTORIES("${Torch_BINARY_DIR}/lib/TH") + INCLUDE_DIRECTORIES(".") + INCLUDE(${QT_USE_FILE}) + + SET(qttorch_SRC qttorch.h qttorch.cpp) + + MACRO_INSTALL_QTLUA_FILES(qttorch init.lua) + + MACRO_ADD_QTLUA_MODULE(libqttorch ${qttorch_SRC}) + + TARGET_LINK_LIBRARIES(libqttorch luaT TH) + +# ADD_TORCH_DOK(dok qttorch "QT Interface" "Torch Tensor interface" 6.) + +ENDIF(Torch_SOURCE_DIR) diff --git a/dok/index.dok b/dok/index.dok new file mode 100644 index 0000000..cf6fc60 --- /dev/null +++ b/dok/index.dok @@ -0,0 +1,54 @@ +====== QTTorch Package Reference Manual ====== +{{anchor:qttorch.dok}} + +Package ''qttorch'' declares two functions +that convert ''torch.Tensor'' to ''QImage'' and vice-versa. + +Loading this package automatically loads +packages [[..:torch:index|torch]] +and [[..:qt:index|qt]]. + + +==== qt.QImage.fromTensor(tensor) ==== +{{anchor:qimagefromtensor}} + +''qt.QImage.fromTensor(tensor)'' + +Return a new [[..:qtgui:index#qimage|QImage]] filled +with data from a torch [[..:torch:index#Tensor|Tensor]]. + +Tensor ''tensor'' must have 2 or 3 dimensions. + * The first dimension defines the image width. + * The second dimension defines the image height. + * The third dimension size must be 1, 3, or 4 +for monochrome, rgb, and rgba images respectively. +Each component is a floating point number in range 0 to 1. + + +==== qimage:toTensor(arg) ==== +{{anchor:qimagetotensor}} + +''qimage.toTensor(tensor)'' + +Fill the [[..:torch:index#Tensor|Tensor]] ''tensor'' with data +from [[..:qtgui:index#qimage|QImage]] ''qimage''. +Tensor ''tensor'' must have 2 or 3 dimensions. +The first two dimensions must be equal to the +image width and height respectively. +The third dimension must be 1, 3, or 4 +for monochromatic, rgb or rgba images. +The ''qimage'' data will be converted to the desired format +and stored into the tensor, each component being +represented by a floating point number in range 0 to 1. +This function returns the filled tensor. + +''qimage.toTensor(depth)'' + +Create a tensor with data from image ''qimage''. +Argument ''depth'' must be 1, 3, or 4 +for extracting monochromatic, rgb or rgba data. +When ''depth'' is one, this function returns a two-dimensional tensor. +Otherwise it returns a three-dimensional tensor with +the third dimension equal to ''depth''. +The first two dimensions are always +the image width and height. diff --git a/generic/qttorch.cpp b/generic/qttorch.cpp new file mode 100644 index 0000000..0ff66e7 --- /dev/null +++ b/generic/qttorch.cpp @@ -0,0 +1,192 @@ +#ifndef TH_GENERIC_FILE +#define TH_GENERIC_FILE "generic/qttorch.cpp" +#else + +static int qttorch_(qimage_fromtensor)(lua_State *L) +{ + THTensor *Tsrc = (THTensor*)luaT_checkudata(L,1,torch_Tensor); + double scale = 255.0 / luaL_optnumber(L, 2, 1); + long depth = 1; + int ddim, wdim = 1, hdim = 0; + + if ( Tsrc->nDimension == 3) + { + ddim = 0; + hdim = 1; + wdim = 2; + depth = Tsrc->size[ddim]; + } + else if (Tsrc->nDimension != 2) + luaL_error(L, "tensor must have 2 or 3 dimensions"); + if (depth != 1 && depth != 3 && depth != 4) + luaL_error(L, "tensor first dimension must be 1, 3, or 4."); + // create image + if (Tsrc->size[wdim] >= INT_MAX || Tsrc->size[hdim] >= INT_MAX) + luaL_error(L, "image is too large"); + int width = (int)(Tsrc->size[wdim]); + int height = (int)(Tsrc->size[hdim]); + QImage image(width, height, QImage::Format_ARGB32_Premultiplied); + // fill image + long sw = Tsrc->stride[wdim]; + long sh = Tsrc->stride[hdim]; + long sd = (depth > 1) ? Tsrc->stride[ddim] : 0; + real *tdata = THTensor_(data)(Tsrc); + for(int j=0; j(L, 1); + int width = image.width(); + int height = image.height(); + int depth = 1; + int ddim, wdim = 1, hdim = 0; + int tpos = 0; + double scale = 255.0 / luaL_optnumber(L, 3, 1); + + // validate arguments + if (lua_type(L, 2) == LUA_TUSERDATA) + { + tpos = 2; + Tdst = (THTensor*)luaT_checkudata(L,2,torch_Tensor); + if (Tdst->nDimension == 3) + { + ddim = 0; + hdim = 1; + wdim = 2; + depth = Tdst->size[ddim]; + } + else if (Tdst->nDimension != 2) + luaL_error(L, "tensor must have 2 or 3 dimensions"); + if (depth != 1 && depth != 3 && depth != 4) + luaL_error(L, "tensor third dimension must be 1, 3, or 4."); + if (width != Tdst->size[wdim] || height != Tdst->size[hdim]) + luaL_error(L, "tensor dimensions must match the image size."); + } + else + { + depth = luaL_optinteger(L, 2, 3); + if (depth != 1 && depth != 3 && depth != 4) + luaL_error(L, "depth must be 1, 3, or 4."); + if (depth == 1) + Tdst = THTensor_(newWithSize2d)(height, width); + else + { + ddim = 0; + hdim = 1; + wdim = 2; + Tdst = THTensor_(newWithSize3d)(depth, height, width); + } + } + + // convert image + if (image.format() != QImage::Format_ARGB32) + image = image.convertToFormat(QImage::Format_ARGB32); + if (image.format() != QImage::Format_ARGB32) + luaL_error(L, "Cannot convert image to format ARGB32"); + + // fill tensor + long sw = Tdst->stride[wdim]; + long sh = Tdst->stride[hdim]; + long sd = (depth > 1) ? Tdst->stride[ddim] : 0; + real *tdata = THTensor_(data)(Tdst); + for(int j=0; j 0) + lua_pushvalue(L, tpos); + else + luaT_pushudata(L, (void*)Tdst, torch_Tensor); + return 1; +} + + +static struct luaL_Reg qttorch_(qimage_lib)[] = { + {"QImageFromTensor", qttorch_(qimage_fromtensor)}, + {"QImageToTensor", qttorch_(qimage_totensor)}, + {0,0} +}; + +static void qttorch_(Tensor_init)(lua_State *L) +{ + luaT_pushmetatable(L, torch_Tensor); + luaT_registeratname(L, qttorch_(qimage_lib), "qttorch"); + lua_pop(L,1); +} + +#endif diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..4cd88ea --- /dev/null +++ b/init.lua @@ -0,0 +1,16 @@ +require 'qt' +require 'torch' +require 'libqttorch' + +qt.QImage.fromTensor = function(tensor, scale) + return tensor.qttorch.QImageFromTensor(tensor, scale) + end + +qt.QImage.toTensor = function(self, tensor, scale) + if type(tensor) == 'userdata' then + return tensor.qttorch.QImageToTensor(self, tensor, scale) + else + local t = torch.getmetatable(torch.getdefaulttensortype()) + return t.qttorch.QImageToTensor(self, tensor, scale) + end + end diff --git a/qttorch.cpp b/qttorch.cpp new file mode 100644 index 0000000..00a41a7 --- /dev/null +++ b/qttorch.cpp @@ -0,0 +1,62 @@ +// -*- C++ -*- + +#include "qttorch.h" + +#include +#include +#include +#include + +#include "TH.h" +#include "luaT.h" + +#define torch_Tensor TH_CONCAT_STRING_3(torch.,Real,Tensor) +#define qttorch_(NAME) TH_CONCAT_3(qttorch_, Real, NAME) + +#include "generic/qttorch.cpp" +#include "THGenerateAllTypes.h" + +struct luaL_Reg qttorch_qimage_lib[] = { + {"toByteTensor", qttorch_Byteqimage_totensor}, + {"toCharTensor", qttorch_Charqimage_totensor}, + {"toShortTensor", qttorch_Shortqimage_totensor}, + {"toIntTensor", qttorch_Intqimage_totensor}, + {"toLongTensor", qttorch_Longqimage_totensor}, + {"toFloatTensor", qttorch_Floatqimage_totensor}, + {"toDoubleTensor", qttorch_Doubleqimage_totensor}, + {0,0} +}; + +int luaopen_libqttorch(lua_State *L) +{ + // load module 'qt' + if (luaL_dostring(L, "require 'qt'")) + lua_error(L); + // load modules 'torch' + if (luaL_dostring(L, "require 'torch'")) + lua_error(L); + + qttorch_ByteTensor_init(L); + qttorch_CharTensor_init(L); + qttorch_ShortTensor_init(L); + qttorch_IntTensor_init(L); + qttorch_LongTensor_init(L); + qttorch_FloatTensor_init(L); + qttorch_DoubleTensor_init(L); + + // enrichs QImage + luaQ_pushmeta(L, QMetaType::QImage); + luaQ_getfield(L, -1, "__metatable"); + luaL_register(L, 0, qttorch_qimage_lib); + + return 0; +} + + + +/* ------------------------------------------------------------- + Local Variables: + c++-font-lock-extra-types: ("\\sw+_t" "\\(lua_\\)?[A-Z]\\sw*[a-z]\\sw*") + End: + ------------------------------------------------------------- */ + diff --git a/qttorch.h b/qttorch.h new file mode 100644 index 0000000..34118c1 --- /dev/null +++ b/qttorch.h @@ -0,0 +1,34 @@ +// -*- C++ -*- + +#ifndef QTTORCH_H +#define QTTORCH_H + +#include "lua.h" +#include "lauxlib.h" +#include "qtluaengine.h" +#include "qtluautils.h" + + +#ifdef LUA_BUILD_AS_DLL +# ifdef libqttorch_EXPORTS +# define QTTORCH_API __declspec(dllexport) +# else +# define QTTORCH_API __declspec(dllimport) +# endif +#else +# define QTTORCH_API /**/ +#endif + +LUA_EXTERNC QTTORCH_API int luaopen_libqttorch(lua_State *L); + + +#endif + + +/* ------------------------------------------------------------- + Local Variables: + c++-font-lock-extra-types: ("\\sw+_t" "\\(lua_\\)?[A-Z]\\sw*[a-z]\\sw*") + End: + ------------------------------------------------------------- */ + + -- cgit v1.2.3