Skip to content

Commit

Permalink
Merge pull request #8 from SylvainCorlay/readme
Browse files Browse the repository at this point in the history
Update readme, formatting in xaudio/ximage/xnpz and remove C-style casting
  • Loading branch information
wolfv committed Nov 22, 2017
2 parents f39594c + 8f1db84 commit 3c15dae
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 140 deletions.
108 changes: 44 additions & 64 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,49 @@
[![ReadTheDocs](https://readthedocs.org/projects/xtensor-io/badge/?version=stable)](http://xtensor-io.readthedocs.io/en/stable/)
[![Join the Gitter Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/QuantStack/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

Reading and writing image, sound and npz file formats to and from xtensor data structures.

xtensor-io offers a couple of functions to read and write images, audio files, and
NumPy's compressed storage format (NPZ) from C++ into xtensor data structures.
It makes use of well known libraries for image and audio handling (OpenImageIO and libsndfile).
Currently, only a few basic functions are provided, but upon demand we can consider to
improve the interface and offer more options to customize and improve the input-output
performance.
## Introduction

We haven't started building and testing on Windows, yet! Contributions welcome!
**xtensor-io is an early developer preview, and is not suitable for general usage yet. Features and implementation are subject to change.**

### Example
`xtensor-io` offers API of to read and write various file formats into `xtensor` data structures:

- images,
- audio files,
- NumPy's compressed storage format (NPZ).

`xtensor-io` wraps the [OpenImageIO](https://github.com/OpenImageIO/oiio), [libsndfile](https://github.com/erikd/libsndfile) and [zlib](https://github.com/madler/zlib) libraries.

## Installation

`xtensor-io` is a header-only library. We provide a package for the conda package manager.

```bash
conda install xtensor-io -c QuantStack
```

- `xtensor-io` depends on `xtensor` `^0.13.2`.

- `OpenImageIO`, `libsndfile` and `zlib` are optional dependencies to `xtensor-io`

- `OpenImageIO` is required to read and write image files.
- `libsndfile` is required to read and write sound files.
- `zlib` is required to load NPZ files.

All three libraries are available for the conda package manager.

You can also install `xtensor-io` from source:

```
mkdir build
cd build
cmake ..
make
sudo make install
```

## Usage

```cpp
// loads png image into xarray with shape WIDTH x HEIGHT x CHANNELS
Expand Down Expand Up @@ -44,61 +76,9 @@ auto y = xt::sin(2.0 * numeric_constants<double>::PI * freq * t);
xt::dump_audio("files/sine.wav", y, sampling_freq);
```
### Installation
## License
xtensor-io depends on thirdparty libraries for audio and image handling.
We use a shared copyright model that enables all contributors to maintain the
copyright on their contributions.
The easiest way to install xtensor-io (including all dependencies) is through conda:
```bash
conda install xtensor-io
```

To use xaudio, it's required to link with [`libsndfile`](http://www.mega-nerd.com/libsndfile/).
The library can be installed as follows:

```bash
# Conda
conda install libsndfile -c conda-forge
# Ubuntu / Debian
sudo apt-get install libsndfile-dev
# Fedora
sudo dnf install libsndfile-devel
```

For image handling, [`OpenImageIO`](http://openimageio.org/) is required.
We have a build of OpenImageIO on the conda QuantStack channel, but it can also
be optained from your favorite package manager on Linux. Note the conda build
is only tested with the `gcc-6` package from the QuantStack channel.

```bash
# Conda
(maybe: ) conda install gcc-6 -c QuantStack
conda install openimageio -c QuantStack
# Ubuntu / Debian
sudo apt-get install libopenimageio-dev
# Fedora
sudo dnf install OpenImageIO-devel
```

In order to decompress and read NPZ files, zlib is needed. It should be installed
on linux, but you can also obtain it:

```bash
# Conda
conda install zlib -c conda-forge
# Ubuntu / Debian
sudo apt-get install zlib1g-dev
# Fedora
sudo dnf install zlib-devel
```

From this directory:

```
mkdir build
cd build
cmake ..
make
sudo make install
```
This software is licensed under the BSD-3-Clause license. See the [LICENSE](LICENSE) file for details.
15 changes: 9 additions & 6 deletions include/xtensor-io/xaudio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ namespace xt
{
throw std::runtime_error(std::string("load_wav: ") + file.strError());
}
auto result = xarray<T>::from_shape({(std::size_t) file.frames(), (std::size_t) file.channels()});
file.read(result.raw_data(), (sf_count_t) result.size());
auto result = xarray<T>::from_shape({
static_cast<std::size_t>(file.frames()),
static_cast<std::size_t>(file.channels())
});
file.read(result.raw_data(), static_cast<sf_count_t>(result.size()));
return std::make_tuple(file.samplerate(), std::move(result));
}

Expand All @@ -47,15 +50,15 @@ namespace xt
*/
template <class E>
void dump_audio(std::string filename, const xexpression<E>& data, int samplerate,
int format = SF_FORMAT_WAV | SF_FORMAT_PCM_16)
int format = SF_FORMAT_WAV | SF_FORMAT_PCM_16)
{
auto&& de = xt::eval(data.derived_cast());
SndfileHandle file(filename, SFM_WRITE, format, (int) de.shape()[1], samplerate);
SndfileHandle file(filename, SFM_WRITE, format, static_cast<int>(de.shape()[1]), samplerate);
// need to explicitly check the rawHandle otherwise permission errors etc. are not detected
if (!file || file.rawHandle() == nullptr)
{
throw std::runtime_error(std::string("dump_wav: ") + file.strError());
throw std::runtime_error(std::string("dump_audio: ") + file.strError());
}
file.write(de.raw_data(), (sf_count_t) de.size());
file.write(de.raw_data(), static_cast<sf_count_t>(de.size()));
}
}
10 changes: 6 additions & 4 deletions include/xtensor-io/ximage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ namespace xt
xarray<T> load_image(std::string filename)
{
// TODO handle types better
OIIO::ImageInput *in = OIIO::ImageInput::open(filename);
OIIO::ImageInput* in = OIIO::ImageInput::open(filename);
if (!in)
{
// something went wrong
throw std::runtime_error("Error reading image.");
}
const OIIO::ImageSpec &spec = in->spec();
const OIIO::ImageSpec& spec = in->spec();
int xres = spec.width;
int yres = spec.height;
int channels = spec.nchannels;
Expand Down Expand Up @@ -66,13 +66,15 @@ namespace xt
{
auto&& ex = eval(data.derived_cast());

OIIO::ImageOutput *out = OIIO::ImageOutput::create(filename);
OIIO::ImageOutput* out = OIIO::ImageOutput::create(filename);
if (!out)
{
// something went wrong
throw std::runtime_error("Error opening file to write image.");
}
OIIO::ImageSpec spec((int) ex.shape()[0], (int) ex.shape()[1], (int) ex.shape()[2], OIIO::TypeDesc::UINT8);
OIIO::ImageSpec spec(static_cast<int>(ex.shape()[0]),
static_cast<int>(ex.shape()[1]),
static_cast<int>(ex.shape()[2]), OIIO::TypeDesc::UINT8);

spec.attribute("CompressionQuality", quality);

Expand Down

0 comments on commit 3c15dae

Please sign in to comment.