mirror of
https://github.com/boostorg/gil.git
synced 2026-01-26 18:42:12 +00:00
543 lines
20 KiB
C++
543 lines
20 KiB
C++
/*
|
|
Copyright 2005-2007 Adobe Systems Incorporated
|
|
|
|
Use, modification and distribution are subject to the Boost Software License,
|
|
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
http://www.boost.org/LICENSE_1_0.txt).
|
|
|
|
See http://opensource.adobe.com/gil for most recent version including documentation.
|
|
*/
|
|
|
|
#ifdef _MSC_VER
|
|
#pragma warning(disable : 4244) // conversion from 'gil::image<V,Alloc>::coord_t' to 'int', possible loss of data (visual studio compiler doesn't realize that the two types are the same)
|
|
#pragma warning(disable : 4503) // decorated name length exceeded, name was truncated
|
|
#endif
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <ios>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <map>
|
|
#include <boost/lambda/lambda.hpp>
|
|
#include <boost/lambda/bind.hpp>
|
|
#include <boost/mpl/vector.hpp>
|
|
#include <boost/gil/extension/dynamic_image/dynamic_image_all.hpp>
|
|
#include <boost/crc.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
|
|
using namespace boost::gil;
|
|
using namespace std;
|
|
using namespace boost;
|
|
namespace fs = boost::filesystem;
|
|
|
|
extern rgb8c_planar_view_t sample_view;
|
|
void error_if(bool condition);
|
|
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4127) //conditional expression is constant
|
|
#endif
|
|
|
|
|
|
// When BOOST_GIL_GENERATE_REFERENCE_DATA is defined, the reference data is generated and saved.
|
|
// When it is undefined, regression tests are checked against it
|
|
//#define BOOST_GIL_GENERATE_REFERENCE_DATA
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Some algorithms to use in testing
|
|
///
|
|
////////////////////////////////////////////////////
|
|
|
|
template <typename GrayView, typename R>
|
|
void gray_image_hist(const GrayView& img_view, R& hist) {
|
|
// for_each_pixel(img_view,++lambda::var(hist)[lambda::_1]);
|
|
for (typename GrayView::iterator it=img_view.begin(); it!=img_view.end(); ++it)
|
|
++hist[*it];
|
|
}
|
|
|
|
template <typename V, typename R>
|
|
void get_hist(const V& img_view, R& hist) {
|
|
gray_image_hist(color_converted_view<gray8_pixel_t>(img_view), hist);
|
|
}
|
|
|
|
// testing custom color conversion
|
|
template <typename C1, typename C2>
|
|
struct my_color_converter_impl : public default_color_converter_impl<C1,C2> {};
|
|
template <typename C1>
|
|
struct my_color_converter_impl<C1,gray_t> {
|
|
template <typename P1, typename P2>
|
|
void operator()(const P1& src, P2& dst) const {
|
|
default_color_converter_impl<C1,gray_t>()(src,dst);
|
|
get_color(dst,gray_color_t())=channel_invert(get_color(dst,gray_color_t()));
|
|
}
|
|
};
|
|
|
|
struct my_color_converter {
|
|
template <typename SrcP,typename DstP>
|
|
void operator()(const SrcP& src,DstP& dst) const {
|
|
typedef typename color_space_type<SrcP>::type src_cs_t;
|
|
typedef typename color_space_type<DstP>::type dst_cs_t;
|
|
my_color_converter_impl<src_cs_t,dst_cs_t>()(src,dst);
|
|
}
|
|
};
|
|
|
|
// Models a Unary Function
|
|
template <typename P> // Models PixelValueConcept
|
|
struct mandelbrot_fn {
|
|
typedef point2<std::ptrdiff_t> point_t;
|
|
|
|
typedef mandelbrot_fn const_t;
|
|
typedef P value_type;
|
|
typedef value_type reference;
|
|
typedef value_type const_reference;
|
|
typedef point_t argument_type;
|
|
typedef reference result_type;
|
|
BOOST_STATIC_CONSTANT(bool, is_mutable=false);
|
|
|
|
value_type _in_color,_out_color;
|
|
point_t _img_size;
|
|
static const int MAX_ITER=100; // max number of iterations
|
|
|
|
mandelbrot_fn() {}
|
|
mandelbrot_fn(const point_t& sz, const value_type& in_color, const value_type& out_color) : _in_color(in_color), _out_color(out_color), _img_size(sz) {}
|
|
|
|
result_type operator()(const point_t& p) const {
|
|
// normalize the coords to (-2..1, -1.5..1.5)
|
|
// (actually make y -1.0..2 so it is asymmetric, so we can verify some view factory methods)
|
|
double t=get_num_iter(point2<double>(p.x/(double)_img_size.x*3-2, p.y/(double)_img_size.y*3-1.0f));//1.5f));
|
|
t=pow(t,0.2);
|
|
|
|
value_type ret;
|
|
for (int k=0; k<num_channels<P>::value; ++k)
|
|
ret[k]=(typename channel_type<value_type>::type)(_in_color[k]*t + _out_color[k]*(1-t));
|
|
return ret;
|
|
}
|
|
|
|
private:
|
|
double get_num_iter(const point2<double>& p) const {
|
|
point2<double> Z(0,0);
|
|
for (int i=0; i<MAX_ITER; ++i) {
|
|
Z = point2<double>(Z.x*Z.x - Z.y*Z.y + p.x, 2*Z.x*Z.y + p.y);
|
|
if (Z.x*Z.x + Z.y*Z.y > 4)
|
|
return i/(double)MAX_ITER;
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
void x_gradient(const T& src, const gray8s_view_t& dst) {
|
|
for (int y=0; y<src.height(); ++y) {
|
|
typename T::x_iterator src_it = src.row_begin(y);
|
|
gray8s_view_t::x_iterator dst_it = dst.row_begin(y);
|
|
|
|
for (int x=1; x<src.width()-1; ++x)
|
|
dst_it[x] = (src_it[x+1] - src_it[x-1]) / 2;
|
|
}
|
|
}
|
|
|
|
// A quick test whether a view is homogeneous
|
|
|
|
template <typename Pixel>
|
|
struct pixel_is_homogeneous : public mpl::true_ {};
|
|
|
|
template <typename P, typename C, typename L>
|
|
struct pixel_is_homogeneous<packed_pixel<P,C,L> > : public mpl::false_ {};
|
|
|
|
template <typename View>
|
|
struct view_is_homogeneous : public pixel_is_homogeneous<typename View::value_type> {};
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Tests image view transformations and algorithms
|
|
///
|
|
////////////////////////////////////////////////////
|
|
class image_test {
|
|
public:
|
|
virtual void initialize() {}
|
|
virtual void finalize() {}
|
|
virtual ~image_test() {}
|
|
|
|
void run();
|
|
protected:
|
|
virtual void check_view_impl(const rgb8c_view_t& view, const string& name)=0;
|
|
template <typename View>
|
|
void check_view(const View& img_view, const string& name) {
|
|
rgb8_image_t rgb_img(img_view.dimensions());
|
|
copy_and_convert_pixels(img_view,view(rgb_img));
|
|
check_view_impl(const_view(rgb_img), name);
|
|
}
|
|
private:
|
|
template <typename Img> void basic_test(const string& prefix);
|
|
template <typename View> void view_transformations_test(const View& img_view, const string& prefix);
|
|
template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_);
|
|
template <typename View> void homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::false_) {}
|
|
template <typename View> void histogram_test(const View& img_view, const string& prefix);
|
|
void virtual_view_test();
|
|
void packed_image_test();
|
|
void dynamic_image_test();
|
|
template <typename Img> void image_all_test(const string& prefix);
|
|
};
|
|
|
|
// testing image iterators, clone, fill, locators, color convert
|
|
template <typename Img>
|
|
void image_test::basic_test(const string& prefix) {
|
|
typedef typename Img::view_t View;
|
|
|
|
// make a 20x20 image
|
|
Img img(typename View::point_t(20,20));
|
|
const View& img_view=view(img);
|
|
|
|
// fill it with red
|
|
rgb8_pixel_t red8(255,0,0), green8(0,255,0), blue8(0,0,255), white8(255,255,255);
|
|
typename View::value_type red,green,blue,white;
|
|
color_convert(red8,red);
|
|
default_color_converter()(red8,red);
|
|
red=color_convert_deref_fn<rgb8_ref_t,typename Img::view_t::value_type>()(red8);
|
|
|
|
color_convert(green8,green);
|
|
color_convert(blue8,blue);
|
|
color_convert(white8,white);
|
|
fill(img_view.begin(),img_view.end(),red);
|
|
|
|
color_convert(red8,img_view[0]);
|
|
|
|
// pointer to first pixel of second row
|
|
typename View::reference rt=img_view.at(0,0)[img_view.width()];
|
|
typename View::x_iterator ptr=&rt;
|
|
typename View::reference rt2=*(img_view.at(0,0)+img_view.width());
|
|
typename View::x_iterator ptr2=&rt2;
|
|
error_if(ptr!=ptr2);
|
|
error_if(img_view.x_at(0,0)+10!=10+img_view.x_at(0,0));
|
|
|
|
// draw a blue line along the diagonal
|
|
typename View::xy_locator loc=img_view.xy_at(0,img_view.height()-1);
|
|
for (int y=0; y<img_view.height(); ++y) {
|
|
*loc=blue;
|
|
++loc.x();
|
|
loc.y()--;
|
|
}
|
|
|
|
// draw a green dotted line along the main diagonal with step of 3
|
|
loc=img_view.xy_at(img_view.width()-1,img_view.height()-1);
|
|
while (loc.x()>=img_view.x_at(0,0)) {
|
|
*loc=green;
|
|
loc-=typename View::point_t(3,3);
|
|
}
|
|
|
|
// Clone and make every red pixel white
|
|
Img imgWhite(img);
|
|
for (typename View::iterator it=view(imgWhite).end(); (it-1)!=view(imgWhite).begin(); --it) {
|
|
if (*(it-1)==red)
|
|
*(it-1)=white;
|
|
}
|
|
|
|
check_view(img_view,prefix+"red_x");
|
|
check_view(view(imgWhite),prefix+"white_x");
|
|
}
|
|
|
|
template <typename View>
|
|
void image_test::histogram_test(const View& img_view, const string& prefix) {
|
|
// vector<int> histogram(255,0);
|
|
// get_hist(cropped,histogram.begin());
|
|
unsigned char histogram[256];
|
|
fill(histogram,histogram+256,0);
|
|
get_hist(img_view,histogram);
|
|
gray8c_view_t hist_view=interleaved_view(256,1,(const gray8_pixel_t*)histogram,256);
|
|
check_view(hist_view,prefix+"histogram");
|
|
}
|
|
|
|
template <typename View>
|
|
void image_test::view_transformations_test(const View& img_view, const string& prefix) {
|
|
check_view(img_view,prefix+"original");
|
|
|
|
check_view(subimage_view(img_view, iround(img_view.dimensions()/4), iround(img_view.dimensions()/2)),prefix+"cropped");
|
|
check_view(color_converted_view<gray8_pixel_t>(img_view),prefix+"gray8");
|
|
check_view(color_converted_view<gray8_pixel_t>(img_view,my_color_converter()),prefix+"my_gray8");
|
|
check_view(transposed_view(img_view),prefix+"transpose");
|
|
check_view(rotated180_view(img_view),prefix+"rot180");
|
|
check_view(rotated90cw_view(img_view),prefix+"90cw");
|
|
check_view(rotated90ccw_view(img_view),prefix+"90ccw");
|
|
check_view(flipped_up_down_view(img_view),prefix+"flipped_ud");
|
|
check_view(flipped_left_right_view(img_view),prefix+"flipped_lr");
|
|
check_view(subsampled_view(img_view,typename View::point_t(2,1)),prefix+"subsampled");
|
|
check_view(kth_channel_view<0>(img_view),prefix+"0th_k_channel");
|
|
homogeneous_view_transformations_test(img_view, prefix, view_is_homogeneous<View>());
|
|
}
|
|
|
|
template <typename View>
|
|
void image_test::homogeneous_view_transformations_test(const View& img_view, const string& prefix, mpl::true_) {
|
|
check_view(nth_channel_view(img_view,0),prefix+"0th_n_channel");
|
|
}
|
|
|
|
void image_test::virtual_view_test() {
|
|
typedef mandelbrot_fn<rgb8_pixel_t> deref_t;
|
|
typedef deref_t::point_t point_t;
|
|
typedef virtual_2d_locator<deref_t,false> locator_t;
|
|
typedef image_view<locator_t> my_virt_view_t;
|
|
|
|
boost::function_requires<PixelLocatorConcept<locator_t> >();
|
|
gil_function_requires<StepIteratorConcept<locator_t::x_iterator> >();
|
|
|
|
point_t dims(200,200);
|
|
my_virt_view_t mandel(dims, locator_t(point_t(0,0), point_t(1,1), deref_t(dims, rgb8_pixel_t(255,0,255), rgb8_pixel_t(0,255,0))));
|
|
|
|
gray8s_image_t img(dims);
|
|
fill_pixels(view(img),0); // our x_gradient algorithm doesn't change the first & last column, so make sure they are 0
|
|
x_gradient(color_converted_view<gray8_pixel_t>(mandel), view(img));
|
|
check_view(color_converted_view<gray8_pixel_t>(const_view(img)), "mandelLuminosityGradient");
|
|
|
|
view_transformations_test(mandel,"virtual_");
|
|
histogram_test(mandel,"virtual_");
|
|
}
|
|
|
|
// Test alignment and packed images
|
|
void image_test::packed_image_test() {
|
|
typedef bit_aligned_image3_type<1,3,1, bgr_layout_t>::type bgr131_image_t;
|
|
typedef bgr131_image_t::value_type bgr131_pixel_t;
|
|
bgr131_pixel_t fill_val(1,3,1);
|
|
|
|
bgr131_image_t bgr131_img(3,10);
|
|
fill_pixels(view(bgr131_img), fill_val);
|
|
|
|
bgr131_image_t bgr131a_img(3,10,1);
|
|
copy_pixels(const_view(bgr131_img), view(bgr131a_img));
|
|
|
|
bgr131_image_t bgr131b_img(3,10,4);
|
|
copy_pixels(const_view(bgr131_img), view(bgr131b_img));
|
|
|
|
error_if(bgr131_img!=bgr131a_img || bgr131a_img!=bgr131b_img);
|
|
}
|
|
|
|
void image_test::dynamic_image_test() {
|
|
typedef any_image<mpl::vector<gray8_image_t, bgr8_image_t, argb8_image_t,
|
|
rgb8_image_t, rgb8_planar_image_t> > any_image_t;
|
|
rgb8_planar_image_t img(sample_view.dimensions());
|
|
copy_pixels(sample_view, view(img));
|
|
any_image_t any_img=any_image_t(img);
|
|
|
|
check_view(view(any_img), "dynamic_");
|
|
check_view(flipped_left_right_view(view(any_img)), "dynamic_fliplr");
|
|
check_view(flipped_up_down_view(view(any_img)), "dynamic_flipud");
|
|
|
|
any_image_t::view_t subimageView=subimage_view(view(any_img),0,0,10,15);
|
|
|
|
check_view(subimageView, "dynamic_subimage");
|
|
check_view(subsampled_view(rotated180_view(view(any_img)), 2,1), "dynamic_subimage_subsampled180rot");
|
|
}
|
|
|
|
template <typename Img>
|
|
void image_test::image_all_test(const string& prefix) {
|
|
basic_test<Img>(prefix+"basic_");
|
|
|
|
Img img;
|
|
img.recreate(sample_view.dimensions());
|
|
copy_and_convert_pixels(sample_view,view(img));
|
|
|
|
view_transformations_test(view(img), prefix+"views_");
|
|
|
|
histogram_test(const_view(img),prefix+"histogram_");
|
|
}
|
|
|
|
void image_test::run() {
|
|
initialize();
|
|
|
|
image_all_test<bgr8_image_t>("bgr8_");
|
|
image_all_test<rgb8_image_t>("rgb8_");
|
|
image_all_test<rgb8_planar_image_t>("planarrgb8_");
|
|
image_all_test<gray8_image_t>("gray8_");
|
|
|
|
typedef const bit_aligned_pixel_reference<boost::uint8_t, mpl::vector3_c<int,1,2,1>, bgr_layout_t, true> bgr121_ref_t;
|
|
typedef image<bgr121_ref_t,false> bgr121_image_t;
|
|
image_all_test<bgr121_image_t>("bgr121_");
|
|
|
|
// TODO: Remove?
|
|
view_transformations_test(subsampled_view(sample_view,point2<std::ptrdiff_t>(1,2)),"subsampled_");
|
|
view_transformations_test(color_converted_view<gray8_pixel_t>(sample_view),"color_converted_");
|
|
|
|
virtual_view_test();
|
|
packed_image_test();
|
|
dynamic_image_test();
|
|
|
|
finalize();
|
|
}
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Performs or generates image tests using checksums
|
|
///
|
|
////////////////////////////////////////////////////
|
|
|
|
class checksum_image_mgr : public image_test {
|
|
protected:
|
|
typedef map<string,boost::crc_32_type::value_type> crc_map_t;
|
|
crc_map_t _crc_map;
|
|
};
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Performs image tests by comparing image pixel checksums against a reference
|
|
///
|
|
////////////////////////////////////////////////////
|
|
|
|
class checksum_image_test : public checksum_image_mgr {
|
|
public:
|
|
checksum_image_test(const char* filename) : _filename(filename) {}
|
|
private:
|
|
const char* _filename;
|
|
virtual void initialize();
|
|
virtual void check_view_impl(const rgb8c_view_t& v, const string& name);
|
|
};
|
|
|
|
// Load the checksums from the reference file and create the start image
|
|
void checksum_image_test::initialize() {
|
|
string crc_name;
|
|
boost::crc_32_type::value_type crc_result;
|
|
fstream checksum_ref(_filename,ios::in);
|
|
while (true) {
|
|
checksum_ref >> crc_name >> std::hex >> crc_result;
|
|
if(checksum_ref.fail()) break;
|
|
_crc_map[crc_name]=crc_result;
|
|
}
|
|
checksum_ref.close();
|
|
}
|
|
|
|
// Create a checksum for the given view and compare it with the reference checksum. Throw exception if different
|
|
void checksum_image_test::check_view_impl(const rgb8c_view_t& img_view, const string& name) {
|
|
boost::crc_32_type checksum_acumulator;
|
|
checksum_acumulator.process_bytes(img_view.row_begin(0),img_view.size()*3);
|
|
|
|
cerr << "Checking checksum for " << name << endl;
|
|
if (checksum_acumulator.checksum()!=_crc_map[name]) {
|
|
cerr << "Checksum error in "<<name<<"\n";
|
|
error_if(true);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Generates a set of reference checksums to compare against
|
|
///
|
|
////////////////////////////////////////////////////
|
|
|
|
class checksum_image_generate : public checksum_image_mgr {
|
|
public:
|
|
checksum_image_generate(const char* filename) : _filename(filename) {}
|
|
private:
|
|
const char* _filename;
|
|
virtual void check_view_impl(const rgb8c_view_t& img_view, const string& name);
|
|
virtual void finalize();
|
|
};
|
|
|
|
// Add the checksum of the given view to the map of checksums
|
|
void checksum_image_generate::check_view_impl(const rgb8c_view_t& img_view, const string& name) {
|
|
boost::crc_32_type result;
|
|
result.process_bytes(img_view.row_begin(0),img_view.size()*3);
|
|
cerr << "Generating checksum for " << name << endl;
|
|
_crc_map[name] = result.checksum();
|
|
}
|
|
|
|
// Save the checksums into the reference file
|
|
void checksum_image_generate::finalize() {
|
|
fstream checksum_ref(_filename,ios::out);
|
|
for (crc_map_t::const_iterator it=_crc_map.begin(); it!=_crc_map.end(); ++it) {
|
|
checksum_ref << it->first << " " << std::hex << it->second << "\r\n";
|
|
}
|
|
checksum_ref.close();
|
|
}
|
|
|
|
////////////////////////////////////////////////////
|
|
///
|
|
/// Performs or generates image tests using image I/O
|
|
///
|
|
////////////////////////////////////////////////////
|
|
|
|
extern const string in_dir;
|
|
extern const string out_dir;
|
|
extern const string ref_dir;
|
|
|
|
const string in_dir=""; // directory of source images
|
|
const string out_dir=in_dir+"image-out/"; // directory where to write output
|
|
const string ref_dir=in_dir+"image-ref/"; // reference directory to compare written with actual output
|
|
|
|
void static_checks() {
|
|
gil_function_requires<ImageConcept<rgb8_image_t> >();
|
|
|
|
BOOST_STATIC_ASSERT(view_is_basic<rgb8_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(view_is_basic<cmyk8c_planar_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(view_is_basic<rgb8_planar_view_t>::value);
|
|
|
|
BOOST_STATIC_ASSERT(view_is_step_in_x<rgb8_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(view_is_step_in_x<cmyk8c_planar_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(!view_is_step_in_x<rgb8_planar_view_t>::value);
|
|
|
|
BOOST_STATIC_ASSERT(!is_planar<rgb8_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(is_planar<cmyk8c_planar_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(is_planar<rgb8_planar_view_t>::value);
|
|
|
|
BOOST_STATIC_ASSERT(view_is_mutable<rgb8_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(!view_is_mutable<cmyk8c_planar_step_view_t>::value);
|
|
BOOST_STATIC_ASSERT(view_is_mutable<rgb8_planar_view_t>::value);
|
|
|
|
BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t>::type, cmyk8c_planar_step_view_t>::value));
|
|
BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, bits16, rgb_layout_t>::type, rgb16c_planar_step_view_t>::value));
|
|
BOOST_STATIC_ASSERT((boost::is_same<derived_view_type<cmyk8c_planar_step_view_t, use_default, rgb_layout_t, mpl::false_, use_default, mpl::false_>::type, rgb8c_step_view_t>::value));
|
|
|
|
// test view get raw data (mostly compile-time test)
|
|
{
|
|
rgb8_image_t rgb8(100,100);
|
|
unsigned char* data=interleaved_view_get_raw_data(view(rgb8));
|
|
const unsigned char* cdata=interleaved_view_get_raw_data(const_view(rgb8));
|
|
error_if(data!=cdata);
|
|
}
|
|
|
|
{
|
|
rgb16s_planar_image_t rgb8(100,100);
|
|
short* data=planar_view_get_raw_data(view(rgb8),1);
|
|
const short* cdata=planar_view_get_raw_data(const_view(rgb8),1);
|
|
error_if(data!=cdata);
|
|
}
|
|
}
|
|
|
|
typedef checksum_image_test image_test_t;
|
|
typedef checksum_image_generate image_generate_t;
|
|
|
|
#ifdef BOOST_GIL_GENERATE_REFERENCE_DATA
|
|
typedef image_generate_t image_mgr_t;
|
|
#else
|
|
typedef image_test_t image_mgr_t;
|
|
#endif
|
|
|
|
void test_image(const char* ref_checksum) {
|
|
image_mgr_t mgr(ref_checksum);
|
|
|
|
mgr.run();
|
|
static_checks();
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
std::string here = fs::absolute(fs::path(__FILE__)).parent_path().string() + "/";
|
|
std::string local_name = here + "gil_reference_checksums.txt";
|
|
const char* name_from_status = "../libs/gil/test/gil_reference_checksums.txt";
|
|
|
|
std::ifstream file_is_there(local_name.c_str());
|
|
if (file_is_there)
|
|
{
|
|
test_image(local_name.c_str());
|
|
}
|
|
else
|
|
{
|
|
std::ifstream file_is_there(name_from_status);
|
|
if (file_is_there)
|
|
test_image(name_from_status);
|
|
else
|
|
{
|
|
std::cerr << "Unable to open gil_reference_checksums.txt"<<std::endl;
|
|
return 1;
|
|
}
|
|
}
|
|
}
|