Commit ac2f1e9d authored by Manuel Günther's avatar Manuel Günther

Started introducing C++ interface for image IO

parent 8c2089e9
# import Libraries of other lib packages
import bob.io.base
# import our own Library
import bob.extension
bob.extension.load_bob_library('bob.io.image', __file__)
from . import _library
from . import version
from .version import module as __version__
......
......@@ -32,7 +32,9 @@
* file using a specific backend.
*/
boost::shared_ptr<bob::io::base::File> make_tiff_file (const char* path, char mode);
#ifdef HAVE_LIBJPEG
boost::shared_ptr<bob::io::base::File> make_jpeg_file (const char* path, char mode);
#endif
boost::shared_ptr<bob::io::base::File> make_gif_file (const char* path, char mode);
boost::shared_ptr<bob::io::base::File> make_netpbm_file (const char* path, char mode);
boost::shared_ptr<bob::io::base::File> make_png_file (const char* path, char mode);
......
/**
* @date Wed May 11 12:39:37 MDT 2016
* @author Manuel Gunther <siebenkopf@googlemail.com>
*
* @brief The file provides an easy C++ interface to read and write images
*
* Copyright (c) 2016 , Regents of the University of Colorado on behalf of the University of Colorado Colorado Springs.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BOB_IO_IMAGE_IO_H
#define BOB_IO_IMAGE_IO_H
#include <stdexcept>
#include <string>
#include <boost/shared_ptr.hpp>
#include <blitz/array.h>
/**
* @brief Array submodule API of the I/O module
*/
namespace bob { namespace io { namespace image {
#ifdef HAVE_LIBJPEG
template <int N>
blitz::Array<uint8_t,N> read_jpeg(const std::string& filename);
template <int N>
void write_jpeg(const blitz::Array<uint8_t,N>& image, const std::string& filename);
#endif
}}}
#endif /* BOB_IO_IMAGE_IO_H */
......@@ -9,6 +9,8 @@
* Copyright (C) 2011-2013 Idiap Research Institute, Martigny, Switzerland
*/
#ifdef HAVE_LIBJPEG
#include <boost/filesystem.hpp>
#include <boost/shared_array.hpp>
#include <boost/shared_ptr.hpp>
......@@ -19,6 +21,7 @@
#include <string>
#include <bob.io.base/File.h>
#include <bob.io.image/io.h>
#include <jpeglib.h>
......@@ -406,3 +409,25 @@ std::string ImageJpegFile::s_codecname = "bob.image_jpeg";
boost::shared_ptr<bob::io::base::File> make_jpeg_file (const char* path, char mode) {
return boost::make_shared<ImageJpegFile>(path, mode);
}
template <int N>
blitz::Array<uint8_t,N> bob::io::image::read_jpeg(const std::string& filename){
ImageJpegFile jpeg(filename.c_str(), 'r');
return dynamic_cast<bob::io::base::File&>(jpeg).read<uint8_t,N>(0);
}
template <int N>
void bob::io::image::write_jpeg(const blitz::Array<uint8_t,N>& image, const std::string& filename){
ImageJpegFile jpeg(filename.c_str(), 'w');
dynamic_cast<bob::io::base::File&>(jpeg).write(image);
}
// instantiate
template blitz::Array<uint8_t, 2> bob::io::image::read_jpeg(const std::string&);
template blitz::Array<uint8_t, 3> bob::io::image::read_jpeg(const std::string&);
template void bob::io::image::write_jpeg(const blitz::Array<uint8_t, 2>&, const std::string&);
template void bob::io::image::write_jpeg(const blitz::Array<uint8_t, 3>&, const std::string&);
#endif // HAVE_LIBJPEG
......@@ -15,9 +15,69 @@
#include <bob.io.base/api.h>
#include "file.h"
#include <bob.extension/documentation.h>
#include <bob.io.image/io.h>
#include <boost/format.hpp>
#include <boost/filesystem.hpp>
#ifdef HAVE_LIBJPEG
#include <jpeglib.h>
#endif
static auto s_test_io = bob::extension::FunctionDoc(
"_test_io",
"Tests the C++ API of reading and writing images"
)
.add_prototype("tempdir")
.add_parameter("tempdir", "str", "A temporary directory to write data to")
;
static PyObject* _test_io(PyObject*, PyObject *args, PyObject* kwds) {
BOB_TRY
static char** kwlist = s_test_io.kwlist();
const char* tempdir;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &tempdir)) return 0;
blitz::Array<uint8_t, 2> gray_image(100, 100);
gray_image = 0;
for (int i = 0; i < 100; ++i){
gray_image(i, 100-i) = 127;
gray_image(i,i) = 255;
}
blitz::Array<uint8_t, 3> color_image(3, 100, 100);
for (int i = 0; i < 3; ++i)
color_image(i, blitz::Range::all(), blitz::Range::all()) = gray_image(blitz::Range::all(), blitz::Range::all());
#ifdef HAVE_LIBJPEG
boost::filesystem::path jpeg_gray(tempdir); jpeg_gray /= std::string("gray.jpg");
bob::io::image::write_jpeg(gray_image, jpeg_gray.string());
blitz::Array<uint8_t, 2> gray_jpeg = bob::io::image::read_jpeg<2>(jpeg_gray.string());
if (blitz::any(blitz::abs(gray_image - gray_jpeg) > 10))
throw std::runtime_error("Gray image IO did not succeed, check " + jpeg_gray.string());
boost::filesystem::path jpeg_color(tempdir); jpeg_color /= std::string("color.jpg");
bob::io::image::write_jpeg(color_image, jpeg_color.string());
blitz::Array<uint8_t, 3> color_jpeg = bob::io::image::read_jpeg<3>(jpeg_color.string());
if (blitz::any(blitz::abs(color_image - color_jpeg) > 10))
throw std::runtime_error("Color image IO did not succeed, check " + jpeg_color.string());
#endif
Py_RETURN_NONE;
BOB_CATCH_FUNCTION("_test_io", 0)
}
static PyMethodDef module_methods[] = {
{
s_test_io.name(),
(PyCFunction)_test_io,
METH_VARARGS|METH_KEYWORDS,
s_test_io.doc(),
},
{0} /* Sentinel */
};
......@@ -62,6 +122,7 @@ static PyObject* create_module (void) {
PyErr_Print();
}
#ifdef HAVE_LIBJPEG
if (BITS_IN_JSAMPLE == 8) {
if (!PyBobIoCodec_Register(".jpg", "JPEG, compresssed (libjpeg)",
&make_jpeg_file)) {
......@@ -76,6 +137,7 @@ static PyObject* create_module (void) {
PyErr_Format(PyExc_RuntimeError, "libjpeg compiled with `%d' bits depth (instead of 8). JPEG images are hence not supported.", BITS_IN_JSAMPLE);
PyErr_Print();
}
#endif
if (!PyBobIoCodec_Register(".gif", "GIF (giflib)", &make_gif_file)) {
PyErr_Print();
......
......@@ -65,3 +65,15 @@ def test_netpbm():
transcode(test_utils.datafile('test_2.ppm', __name__)) # indexed, works fine
# transcode(test_utils.datafile('test.jpg', __name__)) #does not work
# because of re-compression
def test_cpp_interface():
from _library import _test_io
import tempfile
import shutil
tmpdir = tempfile.mkdtemp(prefix="bob_io_image")
try:
_test_io(tmpdir)
finally:
shutil.rmtree(tmpdir)
......@@ -9,7 +9,7 @@ import os
from setuptools import setup, find_packages, dist
dist.Distribution(dict(setup_requires=['bob.extension', 'bob.blitz'] + bob_packages))
from bob.extension.utils import egrep, find_header, find_library
from bob.blitz.extension import Extension, build_ext
from bob.blitz.extension import Extension, Library, build_ext
from bob.extension.utils import load_requirements
build_requires = load_requirements()
......@@ -35,7 +35,7 @@ def libjpeg_turbo_version(header):
vv = egrep(header, r"#\s*define\s+LIBJPEG_TURBO_VERSION\s+([\d\.]+)")
if not len(vv): return None
return vv[0].group(1) + ' (turbo)'
return vv[0].group(1) + '-turbo'
class jpeg:
......@@ -373,8 +373,6 @@ setup(
setup_requires = build_requires,
install_requires = build_requires,
ext_modules = [
Extension("bob.io.image.version",
[
......@@ -390,7 +388,7 @@ setup(
define_macros = define_macros,
),
Extension("bob.io.image._library",
Library("bob.io.image.bob_io_image",
[
"bob/io/image/tiff.cpp",
"bob/io/image/gif.cpp",
......@@ -399,6 +397,19 @@ setup(
"bob/io/image/bmp.cpp",
"bob/io/image/pnmio.cpp",
"bob/io/image/netpbm.cpp",
],
packages = packages,
boost_modules = boost_modules,
bob_packages = bob_packages,
version = version,
system_include_dirs = system_include_dirs,
library_dirs = library_dirs,
libraries = libraries,
define_macros = define_macros,
),
Extension("bob.io.image._library",
[
"bob/io/image/main.cpp",
],
packages = packages,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment