Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/qttorch.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRonan Collobert <ronan@collobert.com>2013-10-03 21:04:29 +0400
committerRonan Collobert <ronan@collobert.com>2013-10-03 21:04:29 +0400
commitd87c34117e163c006f0ab4bb315748b85e381c98 (patch)
treec1934d8171bb2286522163ae84885bfcb20dca39
exe can now be compiled in a standalone way
-rw-r--r--CMakeLists.txt21
-rw-r--r--dok/index.dok54
-rw-r--r--generic/qttorch.cpp192
-rw-r--r--init.lua16
-rw-r--r--qttorch.cpp62
-rw-r--r--qttorch.h34
6 files changed, 379 insertions, 0 deletions
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<height; j++)
+ {
+ QRgb *ip = (QRgb*)image.scanLine(j);
+ real *tp = tdata + sh * j;
+ if (depth == 1)
+ {
+ for (int i=0; i<width; i++)
+ {
+ int g = (int)(tp[0] * scale) & 0xff;
+ tp += sw;
+ ip[i] = qRgb(g,g,g);
+ }
+ }
+ else if (depth == 3)
+ {
+ for (int i=0; i<width; i++)
+ {
+ int r = (int)(tp[0] * scale) & 0xff;
+ int g = (int)(tp[sd] * scale) & 0xff;
+ int b = (int)(tp[sd+sd] * scale) & 0xff;
+ tp += sw;
+ ip[i] = qRgb(r,g,b);
+ }
+ }
+ else if (depth == 4)
+ {
+ for (int i=0; i<width; i++)
+ {
+ int a = (int)(tp[sd+sd+sd] * scale) & 0xff;
+ int r = (int)(tp[0] * scale) & 0xff;
+ int g = (int)(tp[sd] * scale) & 0xff;
+ int b = (int)(tp[sd+sd] * scale) & 0xff;
+ tp += sw;
+ ip[i] = qRgba(r,g,b,a);
+ }
+ }
+ }
+ // return
+ luaQ_pushqt(L, image);
+ return 1;
+}
+
+static int qttorch_(qimage_totensor)(lua_State *L)
+{
+ THTensor *Tdst = 0;
+ QImage image = luaQ_checkqvariant<QImage>(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<height; j++)
+ {
+ QRgb *ip = (QRgb*)image.scanLine(j);
+ real *tp = tdata + sh * j;
+ if (depth == 1)
+ {
+ for (int i=0; i<width; i++)
+ {
+ QRgb v = ip[i];
+ tp[0] = (real)qGray(v) / scale;
+ tp += sw;
+ }
+ }
+ else if (depth == 3)
+ {
+ for (int i=0; i<width; i++)
+ {
+ QRgb v = ip[i];
+ tp[0] = (real)qRed(v) / scale;
+ tp[sd] = (real)qGreen(v) / scale;
+ tp[sd+sd] = (real)qBlue(v) / scale;
+ tp += sw;
+ }
+ }
+ else if (depth == 4)
+ {
+ for (int i=0; i<width; i++)
+ {
+ QRgb v = ip[i];
+ tp[0] = (real)qRed(v) / scale;
+ tp[sd] = (real)qGreen(v) / scale;
+ tp[sd+sd] = (real)qBlue(v) / scale;
+ tp[sd+sd+sd] = (real)qAlpha(v) / scale;
+ tp += sw;
+ }
+ }
+ }
+ // return
+ if (tpos > 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 <QColor>
+#include <QDebug>
+#include <QImage>
+#include <QMetaType>
+
+#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:
+ ------------------------------------------------------------- */
+
+