mirror of https://github.com/davisking/dlib.git
Added some overloads of serialize/deserialize for array2d objects
which contain simple 8bit POD pixel types. This makes the serialize routines much faster in these cases.
This commit is contained in:
parent
ec09a0400e
commit
ba08e28386
|
@ -5,6 +5,7 @@
|
|||
|
||||
|
||||
#include "array2d/array2d_kernel_1.h"
|
||||
#include "array2d/serialize_pixel_overloads.h"
|
||||
|
||||
#endif // DLIB_ARRAY2d_
|
||||
|
||||
|
|
|
@ -0,0 +1,303 @@
|
|||
// Copyright (C) 2006 Davis E. King (davis@dlib.net)
|
||||
// License: Boost Software License See LICENSE.txt for the full license.
|
||||
#ifndef DLIB_ARRAY2D_SERIALIZE_PIXEL_OvERLOADS_H__
|
||||
#define DLIB_ARRAY2D_SERIALIZE_PIXEL_OvERLOADS_H__
|
||||
|
||||
#include "array2d_kernel_1.h"
|
||||
#include "../pixel.h"
|
||||
|
||||
namespace dlib
|
||||
{
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
This file contains overloads of the serialize functions for array2d object
|
||||
for the case where they contain simple 8bit POD pixel types. In these
|
||||
cases we can perform a much faster serialization by writing data in chunks
|
||||
instead of one pixel at a time (this avoids a lot of function call overhead
|
||||
inside the iostreams).
|
||||
*/
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array2d<rgb_pixel,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.nc(),out);
|
||||
serialize(item.nr(),out);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(rgb_pixel) == 3);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
out.write((char*)&item[r][0], sizeof(rgb_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array2d<rgb_pixel,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(rgb_pixel) == 3);
|
||||
|
||||
long nc, nr;
|
||||
deserialize(nc,in);
|
||||
deserialize(nr,in);
|
||||
|
||||
item.set_size(nr,nc);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
in.read((char*)&item[r][0], sizeof(rgb_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array2d<bgr_pixel,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.nc(),out);
|
||||
serialize(item.nr(),out);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(bgr_pixel) == 3);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
out.write((char*)&item[r][0], sizeof(bgr_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array2d<bgr_pixel,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(bgr_pixel) == 3);
|
||||
|
||||
long nc, nr;
|
||||
deserialize(nc,in);
|
||||
deserialize(nr,in);
|
||||
|
||||
item.set_size(nr,nc);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
in.read((char*)&item[r][0], sizeof(bgr_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array2d<hsi_pixel,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.nc(),out);
|
||||
serialize(item.nr(),out);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(hsi_pixel) == 3);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
out.write((char*)&item[r][0], sizeof(hsi_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array2d<hsi_pixel,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(hsi_pixel) == 3);
|
||||
|
||||
long nc, nr;
|
||||
deserialize(nc,in);
|
||||
deserialize(nr,in);
|
||||
|
||||
item.set_size(nr,nc);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
in.read((char*)&item[r][0], sizeof(hsi_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array2d<rgb_alpha_pixel,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.nc(),out);
|
||||
serialize(item.nr(),out);
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(rgb_alpha_pixel) == 4);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
out.write((char*)&item[r][0], sizeof(rgb_alpha_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array2d<rgb_alpha_pixel,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(rgb_alpha_pixel) == 4);
|
||||
|
||||
long nc, nr;
|
||||
deserialize(nc,in);
|
||||
deserialize(nr,in);
|
||||
|
||||
item.set_size(nr,nc);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
in.read((char*)&item[r][0], sizeof(rgb_alpha_pixel)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void serialize (
|
||||
const array2d<unsigned char,mem_manager>& item,
|
||||
std::ostream& out
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
serialize(item.nc(),out);
|
||||
serialize(item.nr(),out);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
out.write((char*)&item[r][0], sizeof(unsigned char)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
throw serialization_error(e.info + "\n while serializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
template <
|
||||
typename mem_manager
|
||||
>
|
||||
void deserialize (
|
||||
array2d<unsigned char,mem_manager>& item,
|
||||
std::istream& in
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
long nc, nr;
|
||||
deserialize(nc,in);
|
||||
deserialize(nr,in);
|
||||
|
||||
item.set_size(nr,nc);
|
||||
|
||||
// write each row
|
||||
for (long r = 0; r < item.nr(); ++r)
|
||||
in.read((char*)&item[r][0], sizeof(unsigned char)*item.nc());
|
||||
}
|
||||
catch (serialization_error e)
|
||||
{
|
||||
item.clear();
|
||||
throw serialization_error(e.info + "\n while deserializing object of type array2d");
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
#endif // DLIB_ARRAY2D_SERIALIZE_PIXEL_OvERLOADS_H__
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
#include <dlib/interfaces/enumerable.h>
|
||||
#include <dlib/array2d.h>
|
||||
#include "tester.h"
|
||||
#include <dlib/pixel.h>
|
||||
#include <dlib/image_transforms.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -395,6 +397,157 @@ namespace
|
|||
|
||||
}
|
||||
|
||||
void test_serialization()
|
||||
{
|
||||
// Do these tests because there are overloads of the serialize routines
|
||||
// specifically for these types of pixel (except for unsigned short,
|
||||
// we do that because you can never have too many tests).
|
||||
{
|
||||
array2d<rgb_alpha_pixel> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1].red = 9;
|
||||
img[1][1].green = 8;
|
||||
img[1][1].blue = 7;
|
||||
img[1][1].alpha = 3;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c].red == img2[r][c].red);
|
||||
DLIB_TEST(img[r][c].green == img2[r][c].green);
|
||||
DLIB_TEST(img[r][c].blue == img2[r][c].blue);
|
||||
DLIB_TEST(img[r][c].alpha == img2[r][c].alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
array2d<hsi_pixel> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1].h = 9;
|
||||
img[1][1].s = 2;
|
||||
img[1][1].i = 3;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c].h == img2[r][c].h);
|
||||
DLIB_TEST(img[r][c].s == img2[r][c].s);
|
||||
DLIB_TEST(img[r][c].i == img2[r][c].i);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
array2d<bgr_pixel> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1].red = 1;
|
||||
img[1][1].green = 2;
|
||||
img[1][1].blue = 3;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c].red == img2[r][c].red);
|
||||
DLIB_TEST(img[r][c].green == img2[r][c].green);
|
||||
DLIB_TEST(img[r][c].blue == img2[r][c].blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
array2d<rgb_pixel> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1].red = 1;
|
||||
img[1][1].green = 2;
|
||||
img[1][1].blue = 3;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c].red == img2[r][c].red);
|
||||
DLIB_TEST(img[r][c].green == img2[r][c].green);
|
||||
DLIB_TEST(img[r][c].blue == img2[r][c].blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
array2d<unsigned short> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1] = 9;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c] == img2[r][c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
array2d<unsigned char> img, img2;
|
||||
img.set_size(3,2);
|
||||
assign_all_pixels(img, 5);
|
||||
img[1][1] = 9;
|
||||
ostringstream sout;
|
||||
serialize(img, sout);
|
||||
istringstream sin(sout.str());
|
||||
deserialize(img2, sin);
|
||||
|
||||
DLIB_TEST(img2.nr() == 3);
|
||||
DLIB_TEST(img2.nc() == 2);
|
||||
|
||||
for (long r = 0; r < img.nr(); ++r)
|
||||
{
|
||||
for (long c = 0; c < img.nc(); ++c)
|
||||
{
|
||||
DLIB_TEST(img[r][c] == img2[r][c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class array2d_tester : public tester
|
||||
{
|
||||
|
@ -409,7 +562,9 @@ namespace
|
|||
)
|
||||
{
|
||||
dlog << LINFO << "testing kernel_1a";
|
||||
array2d_kernel_test<array2d<unsigned long> > ();
|
||||
array2d_kernel_test<array2d<unsigned long> >();
|
||||
print_spinner();
|
||||
test_serialization();
|
||||
print_spinner();
|
||||
}
|
||||
} a;
|
||||
|
|
Loading…
Reference in New Issue