Commit 263dd6e1 authored by Manuel Günther's avatar Manuel Günther

Added support for 16 bit gray png; added test cases

parent da410edc
Pipeline #4706 failed with stages
in 4 minutes and 40 seconds
......@@ -120,6 +120,27 @@ static void im_peek(const std::string& path, bob::io::base::array::typeinfo& inf
info.update_strides();
}
static uint16_t switch_endianess(const uint16_t p){
return p / 256 + p % 256 * 256;
}
template <typename T> static
void imbuffer_to_gray(const size_t size, const T* im, T* g)
{
std::copy(im, im+size, g);
}
template <>
void imbuffer_to_gray(const size_t size, const uint16_t* im, uint16_t* g)
{
for(size_t k=0; k<size; ++k)
{
*g++ = switch_endianess(*im++);
}
}
template <typename T> static
void im_load_gray(png_structp png_ptr, bob::io::base::array::interface& b)
{
......@@ -134,16 +155,19 @@ void im_load_gray(png_structp png_ptr, bob::io::base::array::interface& b)
int number_passes = 1;
#endif // PNG_READ_INTERLACING_SUPPORTED
// Allocate array to contain a row of pixels
boost::shared_array<T> row(new T[width]);
png_bytep row_pointer = reinterpret_cast<png_bytep>(row.get());
// Read the image (one row at a time)
// This can deal with interlacing
png_bytep ptr;
for(int pass=0; pass<number_passes; ++pass)
{
// Loop over the rows
for(size_t y=0; y<height; ++y)
{
ptr = reinterpret_cast<png_bytep>(reinterpret_cast<T*>(b.ptr())+y*width);
png_read_row(png_ptr, ptr, NULL);
png_read_row(png_ptr, row_pointer, NULL);
imbuffer_to_gray(width, reinterpret_cast<T*>(row_pointer), reinterpret_cast<T*>(b.ptr())+y*width);
}
}
}
......@@ -159,10 +183,6 @@ void imbuffer_to_rgb(const size_t size, const T* im, T* r, T* g, T* b)
}
}
static uint16_t switch_endianess(const uint16_t p){
return p / 256 + p % 256 * 256;
}
template <>
void imbuffer_to_rgb(const size_t size, const uint16_t* im, uint16_t* r, uint16_t* g, uint16_t* b)
{
......@@ -316,6 +336,22 @@ static void im_load(const std::string& filename, bob::io::base::array::interface
/**
* SAVING
*/
template <typename T> static
void gray_to_imbuffer(const size_t size, const T* g, T* im)
{
std::copy(g, g+size, im);
}
template <>
void gray_to_imbuffer(const size_t size, const uint16_t* g, uint16_t* im)
{
for (size_t k=0; k<size; ++k)
{
*im++ = switch_endianess(*g++);
}
}
template <typename T>
static void im_save_gray(const bob::io::base::array::interface& b, png_structp png_ptr)
{
......@@ -324,13 +360,16 @@ static void im_save_gray(const bob::io::base::array::interface& b, png_structp p
const size_t width = info.shape[1];
const T* row_pointer = reinterpret_cast<const T*>(b.ptr());
png_bytep row_pointer_;
// An array to store one row of pixels
boost::shared_array<T> row(new T[width]);
png_bytep array_ptr = reinterpret_cast<png_bytep>(row.get());
// Save one row at a time
for(size_t y=0; y<height; ++y)
{
row_pointer_ = reinterpret_cast<png_bytep>(const_cast<T*>(row_pointer));
png_write_row(png_ptr, row_pointer_);
gray_to_imbuffer(width, row_pointer, reinterpret_cast<T*>(array_ptr));
png_write_row(png_ptr, array_ptr);
row_pointer += width;
}
}
......
......@@ -16,6 +16,7 @@
#include <bob.blitz/capi.h>
#include <bob.blitz/cleanup.h>
#include <bob.core/api.h>
#include <bob.core/array_convert.h>
#include <bob.io.base/api.h>
#include "file.h"
......@@ -155,6 +156,24 @@ BOB_TRY
blitz::Array<uint8_t, 3> color_png = bob::io::image::read_color_image(png_color.string());
if (blitz::any(blitz::abs(color_image - color_png) > 1))
throw std::runtime_error("PNG color image IO did not succeed, check " + png_color.string());
// test writing as uint16 and reading as uint8
blitz::Array<uint16_t, 2> uint16_gray(bob::core::array::convert<uint16_t>(gray_image));
boost::filesystem::path png_uint16(tempdir); png_uint16 /= std::string("uint16.png");
bob::io::image::write_png(uint16_gray, png_uint16.string());
blitz::Array<uint8_t, 2> uint8_gray = bob::io::image::read_gray_image(png_uint16.string());
if (blitz::any(blitz::abs(gray_image - uint8_gray) > 1))
throw std::runtime_error("PNG gray type conversion not succeed, check " + png_uint16.string());
blitz::Array<uint16_t, 3> uint16_color(bob::core::array::convert<uint16_t>(color_image));
boost::filesystem::path png_uint16c(tempdir); png_uint16c /= std::string("uint16c.png");
bob::io::image::write_png(uint16_color, png_uint16c.string());
blitz::Array<uint8_t, 3> uint8_color = bob::io::image::read_color_image(png_uint16c.string());
if (blitz::any(blitz::abs(color_image - uint8_color) > 1))
throw std::runtime_error("PNG color type conversion not succeed, check " + png_uint16c.string());
#endif
#ifdef HAVE_LIBTIFF
......
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