Skip to content
Snippets Groups Projects
Commit fa84b671 authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Experimental HDF5File port

parent 54e5309c
No related branches found
No related tags found
No related merge requests found
......@@ -115,6 +115,7 @@ setup(
"xbob/io/file.cpp",
"xbob/io/videoreader.cpp",
"xbob/io/videowriter.cpp",
"xbob/io/hdf5.cpp",
"xbob/io/main.cpp",
],
define_macros=define_macros,
......
......@@ -17,6 +17,33 @@
#define FILETYPE_NAME File
PyDoc_STRVAR(s_file_str, BOOST_PP_STRINGIZE(XBOB_IO_MODULE_PREFIX) "." BOOST_PP_STRINGIZE(FILETYPE_NAME));
PyDoc_STRVAR(s_file_doc,
"File(filename, [mode='r', [pretend_extension='']]) -> new bob::io::File\n\
\n\
Use this object to read and write data into files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to open\n\
\n\
mode\n\
[str] A single character (one of ``'r'``, ``'w'``, ``'a'``),\n\
indicating if you'd like to read, write or append into the file.\n\
If you choose ``'w'`` and the file already exists, it will be\n\
truncated.By default, the opening mode is read-only (``'r'``).\n\
\n\
pretend_extension\n\
[str, optional] Normally we read the file matching the extension\n\
to one of the available codecs installed with the present release\n\
of Bob. If you set this parameter though, we will read the file\n\
as it had a given extension. The value should start with a ``'.'``.\n\
For example ``'.hdf5'``, to make the file be treated like an HDF5\n\
file.\n\
\n\
"
);
/* How to create a new PyBobIoFileObject */
static PyObject* PyBobIoFile_New(PyTypeObject* type, PyObject*, PyObject*) {
......@@ -43,9 +70,9 @@ static int PyBobIoFile_Init(PyBobIoFileObject* self, PyObject *args, PyObject* k
static char** kwlist = const_cast<char**>(const_kwlist);
char* filename = 0;
char mode = 0;
char mode = 'r';
char* pretend_extension = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "sc|s", kwlist, &filename,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|cs", kwlist, &filename,
&mode, &pretend_extension)) return -1;
if (mode != 'r' && mode != 'w' && mode != 'a') {
......@@ -73,33 +100,6 @@ static int PyBobIoFile_Init(PyBobIoFileObject* self, PyObject *args, PyObject* k
return 0; ///< SUCCESS
}
PyDoc_STRVAR(s_file_doc,
"File(filename, mode, [pretend_extension]) -> new bob::io::File\n\
\n\
Use this object to read and write data into files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to open\n\
\n\
mode\n\
[str] A single character (one of ``'r'``, ``'w'``, ``'a'``),\n\
indicating if you'd like to read, write or append into the file.\n\
If you choose ``'w'`` and the file already exists, it will be\n\
truncated.\n\
\n\
pretend_extension\n\
[str, optional] Normally we read the file matching the extension\n\
to one of the available codecs installed with the present release\n\
of Bob. If you set this parameter though, we will read the file\n\
as it had a given extension. The value should start with a ``'.'``.\n\
For example ``'.hdf5'``, to make the file be treated like an HDF5\n\
file.\n\
\n\
"
);
static PyObject* PyBobIoFile_Repr(PyBobIoFileObject* self) {
return
# if PY_VERSION_HEX >= 0x03000000
......@@ -524,14 +524,8 @@ PyObject* PyBobIo_TypeInfoAsTuple (const bob::core::array::typeinfo& ti) {
PyObject* shape = PyTuple_GET_ITEM(retval, 1);
PyObject* stride = PyTuple_GET_ITEM(retval, 2);
for (Py_ssize_t i=0; i<ti.nd; ++i) {
if (PyTuple_SetItem(shape, i, Py_BuildValue("n", ti.shape[i])) != 0) {
Py_DECREF(retval);
return 0;
}
if (PyTuple_SetItem(stride, i, Py_BuildValue("n", ti.stride[i])) != 0) {
Py_DECREF(retval);
return 0;
}
PyTuple_SET_ITEM(shape, i, Py_BuildValue("n", ti.shape[i]));
PyTuple_SET_ITEM(stride, i, Py_BuildValue("n", ti.stride[i]));
}
return retval;
......@@ -547,13 +541,8 @@ static PyObject* PyBobIoFile_Describe(PyBobIoFileObject* self, PyObject *args, P
PyObject* all = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &all)) return 0;
if (all && !PyBool_Check(all)) {
PyErr_SetString(PyExc_TypeError, "argument to `all' must be a boolean");
return 0;
}
const bob::core::array::typeinfo* info = 0;
if (all && all == Py_True) info = &self->f->type_all();
if (all && PyObject_IsTrue(all)) info = &self->f->type_all();
else info = &self->f->type();
/* Now return type description and tuples with shape and strides */
......
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include <xbob.io/config.h>
#include <bob/config.h>
#include <bob/io/File.h>
#include <bob/io/HDF5File.h>
#if WITH_FFMPEG
#include <bob/io/VideoReader.h>
......@@ -117,11 +118,34 @@ typedef struct {
#endif /* WITH_FFMPEG */
/*****************
* HDF5 bindings *
*****************/
typedef struct {
PyObject_HEAD
/* Type-specific fields go here. */
boost::shared_ptr<bob::io::HDF5File> f;
} PyBobIoHDF5FileObject;
#define PyBobIoHDF5File_Type_NUM 7
#define PyBobIoHDF5File_Type_TYPE PyTypeObject
#define PyBobIoHDF5File_Check_NUM 8
#define PyBobIoHDF5File_Check_RET int
#define PyBobIoHDF5File_Check_PROTO (PyObject* o)
#define PyBobIoHDF5File_Converter_NUM 9
#define PyBobIoHDF5File_Converter_RET int
#define PyBobIoHDF5File_Converter_PROTO (PyObject* o, PyBobIoHDF5FileObject** a)
/* Total number of C API pointers */
#if WITH_FFMPEG
# define PyXbobIo_API_pointers 7
# define PyXbobIo_API_pointers 10
#else
# define PyXbobIo_API_pointers 8
# define PyXbobIo_API_pointers 11
#endif /* WITH_FFMPEG */
#ifdef XBOB_IO_MODULE
......@@ -155,10 +179,22 @@ typedef struct {
******************/
extern PyBobIoVideoReader_Type_TYPE PyBobIoVideoReader_Type;
extern PyBobIoVideoReaderIterator_Type_TYPE PyBobIoVideoReaderIterator_Type;
extern PyBobIoVideoWriter_Type_TYPE PyBobIoVideoWriter_Type;
#endif /* WITH_FFMPEG */
/*****************
* HDF5 bindings *
*****************/
extern PyBobIoHDF5File_Type_TYPE PyBobIoHDF5File_Type;
PyBobIoHDF5File_Check_RET PyBobIoHDF5File_Check PyBobIoHDF5File_Check_PROTO;
PyBobIoHDF5File_Converter_RET PyBobIoHDF5File_Converter PyBobIoHDF5File_Converter_PROTO;
#else
/* This section is used in modules that use `blitz.array's' C-API */
......@@ -220,6 +256,16 @@ typedef struct {
# define PyBobIoVideoWriterIterator_Type (*(PyBobIoVideoWriterIterator_Type_TYPE *)PyXbobIo_API[PyBobIoVideoWriterIterator_Type_NUM])
#endif /* WITH_FFMPEG */
/*****************
* HDF5 bindings *
*****************/
# define PyBobIoHDF5File_Type (*(PyBobIoHDF5File_Type_TYPE *)PyXbobIo_API[PyBobIoHDF5File_Type_NUM])
# define PyBobIoHDF5File_Check (*(PyBobIoHDF5File_Check_RET (*)PyBobIoHDF5File_Check_PROTO) PyXbobIo_API[PyBobIoHDF5File_Check_NUM])
# define PyBobIoHDF5File_Converter (*(PyBobIoHDF5File_Converter_RET (*)PyBobIoHDF5File_Converter_PROTO) PyXbobIo_API[PyBobIoHDF5File_Converter_NUM])
/**
* Returns -1 on error, 0 on success. PyCapsule_Import will set an exception
* if there's an error.
......
......@@ -43,6 +43,9 @@ PyMODINIT_FUNC ENTRY_FUNCTION(XBOB_IO_MODULE_NAME) (void) {
if (PyType_Ready(&PyBobIoVideoWriter_Type) < 0) return;
#endif /* WITH_FFMPEG */
PyBobIoHDF5File_Type.tp_new = PyType_GenericNew;
if (PyType_Ready(&PyBobIoHDF5File_Type) < 0) return;
PyObject* m = Py_InitModule3(BOOST_PP_STRINGIZE(XBOB_IO_MODULE_NAME),
module_methods, module_docstr);
......@@ -68,6 +71,9 @@ PyMODINIT_FUNC ENTRY_FUNCTION(XBOB_IO_MODULE_NAME) (void) {
PyModule_AddObject(m, "VideoWriter", (PyObject *)&PyBobIoVideoWriter_Type);
#endif /* WITH_FFMPEG */
Py_INCREF(&PyBobIoHDF5File_Type);
PyModule_AddObject(m, "HDF5File", (PyObject *)&PyBobIoHDF5File_Type);
static void* PyXbobIo_API[PyXbobIo_API_pointers];
/* exhaustive list of C APIs */
......@@ -106,6 +112,16 @@ PyMODINIT_FUNC ENTRY_FUNCTION(XBOB_IO_MODULE_NAME) (void) {
PyXbobIo_API[PyBobIoVideoWriter_Type_NUM] = (void *)&PyBobIoVideoWriter_Type;
#endif /* WITH_FFMPEG */
/*****************
* HDF5 bindings *
*****************/
PyXbobIo_API[PyBobIoHDF5File_Type_NUM] = (void *)&PyBobIoHDF5File_Type;
PyXbobIo_API[PyBobIoHDF5File_Check_NUM] = (void *)&PyBobIoHDF5File_Check;
PyXbobIo_API[PyBobIoHDF5File_Converter_NUM] = (void *)&PyBobIoHDF5File_Converter;
/* imports the NumPy C-API */
import_array();
......
......@@ -18,6 +18,39 @@
#define VIDEOREADER_NAME VideoReader
PyDoc_STRVAR(s_videoreader_str, BOOST_PP_STRINGIZE(XBOB_IO_MODULE_PREFIX) "." BOOST_PP_STRINGIZE(VIDEOREADER_NAME));
PyDoc_STRVAR(s_videoreader_doc,
"VideoReader(filename, [check=True]) -> new bob::io::VideoReader\n\
\n\
Use this object to read frames from video files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to read data from\n\
\n\
check\n\
[bool] Format and codec will be extracted from the video metadata.\n\
By default, if the format and/or the codec are not\n\
supported by this version of Bob, an exception will be raised.\n\
You can (at your own risk) set this flag to ``False`` to\n\
avoid this check.\n\
\n\
VideoReader objects can read data from video files. The current\n\
implementation uses `FFmpeg <http://ffmpeg.org>`_ (or\n\
`libav <http://libav.org>`_ if FFmpeg is not available) which is\n\
a stable freely available video encoding and decoding library,\n\
designed specifically for these tasks. You can read an entire\n\
video in memory by using the 'load()' method or use iterators\n\
to read it frame by frame and avoid overloading your machine's\n\
memory. The maximum precision data `FFmpeg` will yield is a 24-bit\n\
(8-bit per band) representation of each pixel (32-bit depths are\n\
also supported by `FFmpeg`, but not by this extension presently).\n\
So, the output of data is done with ``uint8`` as data type.\n\
Output will be colored using the RGB standard, with each band\n\
varying between 0 and 255, with zero meaning pure black and 255,\n\
pure white (color).\n\
");
/* How to create a new PyBobIoVideoReaderObject */
static PyObject* PyBobIoVideoReader_New(PyTypeObject* type, PyObject*, PyObject*) {
......@@ -49,13 +82,8 @@ static int PyBobIoVideoReader_Init(PyBobIoVideoReaderObject* self,
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|O", kwlist,
&filename, &pycheck)) return -1;
if (pycheck && !PyBool_Check(pycheck)) {
PyErr_SetString(PyExc_TypeError, "argument to `check' must be a boolean");
return -1;
}
bool check = false;
if (pycheck && (pycheck == Py_True)) check = true;
if (pycheck && PyObject_IsTrue(pycheck)) check = true;
try {
self->v = boost::make_shared<bob::io::VideoReader>(filename, check);
......@@ -72,39 +100,6 @@ static int PyBobIoVideoReader_Init(PyBobIoVideoReaderObject* self,
return 0; ///< SUCCESS
}
PyDoc_STRVAR(s_videoreader_doc,
"VideoReader(filename, [check=True]) -> new bob::io::VideoReader\n\
\n\
Use this object to read frames from video files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to read data from\n\
\n\
check\n\
[bool] Format and codec will be extracted from the video metadata.\n\
By default, if the format and/or the codec are not\n\
supported by this version of Bob, an exception will be raised.\n\
You can (at your own risk) set this flag to ``False`` to\n\
avoid this check.\n\
\n\
VideoReader objects can read data from video files. The current\n\
implementation uses `FFmpeg <http://ffmpeg.org>`_ (or\n\
`libav <http://libav.org>`_ if FFmpeg is not available) which is\n\
a stable freely available video encoding and decoding library,\n\
designed specifically for these tasks. You can read an entire\n\
video in memory by using the 'load()' method or use iterators\n\
to read it frame by frame and avoid overloading your machine's\n\
memory. The maximum precision data `FFmpeg` will yield is a 24-bit\n\
(8-bit per band) representation of each pixel (32-bit depths are\n\
also supported by `FFmpeg`, but not by this extension presently).\n\
So, the output of data is done with ``uint8`` as data type.\n\
Output will be colored using the RGB standard, with each band\n\
varying between 0 and 255, with zero meaning pure black and 255,\n\
pure white (color).\n\
");
PyObject* PyBobIoVideoReader_Filename(PyBobIoVideoReaderObject* self) {
return Py_BuildValue("s", self->v->filename().c_str());
}
......@@ -334,13 +329,8 @@ static PyObject* PyBobIoVideoReader_Load(PyBobIoVideoReaderObject* self, PyObjec
PyObject* raise = 0;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &raise)) return 0;
if (raise && !PyBool_Check(raise)) {
PyErr_SetString(PyExc_TypeError, "argument to `raise_on_error' must be a boolean");
return 0;
}
bool raise_on_error = false;
if (raise && (raise == Py_True)) raise_on_error = true;
if (raise && PyObject_IsTrue(raise)) raise_on_error = true;
const bob::core::array::typeinfo& info = self->v->video_type();
......
......@@ -18,6 +18,59 @@
#define VIDEOWRITER_NAME VideoWriter
PyDoc_STRVAR(s_videowriter_str, BOOST_PP_STRINGIZE(XBOB_IO_MODULE_PREFIX) "." BOOST_PP_STRINGIZE(VIDEOWRITER_NAME));
PyDoc_STRVAR(s_videowriter_doc,
"VideoWriter(filename, height, width, [framerate=25., [bitrate=1500000., [gop=12, [codec='', [format='', [check=True]) -> new bob::io::VideoWriter\n\
\n\
Use this object to write frames to video files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to read data from\n\
\n\
height\n\
[int] The height of the video (must be a multiple of 2)\n\
\n\
width\n\
[int] The width of the video (must be a multiple of 2)\n\
\n\
framerate\n\
[float, optional] The number of frames per second\n\
\n\
bitrate\n\
[float, optional] The estimated bitrate of the output video\n\
\n\
gop\n\
[int, optional] Group-of-Pictures (emit one intra frame\n\
every `gop' frames at most).\n\
\n\
codec\n\
[str, optional] If you must, specify a valid FFmpeg codec\n\
name here and that will be used to encode the video stream\n\
on the output file.\n\
\n\
format\n\
[str, optional] If you must, specify a valid FFmpeg output\n\
format name and that will be used to encode the video on the\n\
output file. Leave it empty to guess from the filename extension.\n\
\n\
check\n\
[bool, optional] The video will be created if the combination\n\
of format and codec are known to work and have been tested,\n\
otherwise an exception is raised. If you set this parameter to\n\
``False``, though, we will ignore this check.\n\
\n\
VideoWriter objects can write data to video files. The current\n\
implementation uses `FFmpeg <http://ffmpeg.org>`_ (or\n\
`libav <http://libav.org>`_ if FFmpeg is not available) which is\n\
a stable freely available video encoding and decoding library,\n\
designed specifically for these tasks. Videos are objects composed\n\
of RGB colored frames. Each frame inserted should be a 3D\n\
:py:class:`numpy.ndarray` composed of unsigned integers of 8 bits.\n\
Each frame should have a shape equivalent to\n\
``(plane, height, width)``.\n\
");
/* How to create a new PyBobIoVideoWriterObject */
static PyObject* PyBobIoVideoWriter_New(PyTypeObject* type, PyObject*, PyObject*) {
......@@ -62,7 +115,7 @@ static int PyBobIoVideoWriter_Init(PyBobIoVideoWriterObject* self,
&filename, &height, &width, &framerate, &bitrate, &gop, &codec,
&format, &pycheck)) return -1;
if (pycheck && !PyBool_Check(pycheck)) {
if (pycheck && PyObject_IsTrue(pycheck)) {
PyErr_SetString(PyExc_TypeError, "argument to `check' must be a boolean");
return -1;
}
......@@ -86,59 +139,6 @@ static int PyBobIoVideoWriter_Init(PyBobIoVideoWriterObject* self,
return 0; ///< SUCCESS
}
PyDoc_STRVAR(s_videowriter_doc,
"VideoWriter(filename, height, width, [framerate=25., [bitrate=1500000., [gop=12, [codec='', [format='', [check=True]) -> new bob::io::VideoWriter\n\
\n\
Use this object to write frames to video files.\n\
\n\
Constructor parameters:\n\
\n\
filename\n\
[str] The file path to the file you want to read data from\n\
\n\
height\n\
[int] The height of the video (must be a multiple of 2)\n\
\n\
width\n\
[int] The width of the video (must be a multiple of 2)\n\
\n\
framerate\n\
[float, optional] The number of frames per second\n\
\n\
bitrate\n\
[float, optional] The estimated bitrate of the output video\n\
\n\
gop\n\
[int, optional] Group-of-Pictures (emit one intra frame\n\
every `gop' frames at most).\n\
\n\
codec\n\
[str, optional] If you must, specify a valid FFmpeg codec\n\
name here and that will be used to encode the video stream\n\
on the output file.\n\
\n\
format\n\
[str, optional] If you must, specify a valid FFmpeg output\n\
format name and that will be used to encode the video on the\n\
output file. Leave it empty to guess from the filename extension.\n\
\n\
check\n\
[bool, optional] The video will be created if the combination\n\
of format and codec are known to work and have been tested,\n\
otherwise an exception is raised. If you set this parameter to\n\
``False``, though, we will ignore this check.\n\
\n\
VideoWriter objects can write data to video files. The current\n\
implementation uses `FFmpeg <http://ffmpeg.org>`_ (or\n\
`libav <http://libav.org>`_ if FFmpeg is not available) which is\n\
a stable freely available video encoding and decoding library,\n\
designed specifically for these tasks. Videos are objects composed\n\
of RGB colored frames. Each frame inserted should be a 3D\n\
:py:class:`numpy.ndarray` composed of unsigned integers of 8 bits.\n\
Each frame should have a shape equivalent to\n\
``(plane, height, width)``.\n\
");
PyObject* PyBobIoVideoWriter_Filename(PyBobIoVideoWriterObject* self) {
return Py_BuildValue("s", self->v->filename().c_str());
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment