215 lines
6.0 KiB
C++
215 lines
6.0 KiB
C++
//------------------------------------------------------------------------
|
|
// Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
|
|
//
|
|
// This file is part of the ZBar Bar Code Reader.
|
|
//
|
|
// The ZBar Bar Code Reader is free software; you can redistribute it
|
|
// and/or modify it under the terms of the GNU Lesser Public License as
|
|
// published by the Free Software Foundation; either version 2.1 of
|
|
// the License, or (at your option) any later version.
|
|
//
|
|
// The ZBar Bar Code Reader is distributed in the hope that it will be
|
|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Lesser Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser Public License
|
|
// along with the ZBar Bar Code Reader; if not, write to the Free
|
|
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
// Boston, MA 02110-1301 USA
|
|
//
|
|
// http://sourceforge.net/projects/zbar
|
|
//------------------------------------------------------------------------
|
|
|
|
// NB do not put anything before this header
|
|
// it's here to check that we didn't omit any dependencies
|
|
#include <zbar.h>
|
|
|
|
#include <iomanip>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include "test_images.h"
|
|
|
|
bool debug = false;
|
|
bool verbose = false;
|
|
int errors = 0;
|
|
zbar::zbar_symbol_type_t expect_type = zbar::ZBAR_NONE;
|
|
std::string expect_data;
|
|
|
|
template <class T> inline std::string to_string(const T &t)
|
|
{
|
|
std::stringstream ss;
|
|
ss << t;
|
|
return ss.str();
|
|
}
|
|
|
|
static inline int error(const std::string &msg)
|
|
{
|
|
errors++;
|
|
std::cerr << "ERROR: " << msg << std::endl;
|
|
if (debug)
|
|
abort();
|
|
return (-1);
|
|
}
|
|
|
|
static inline int check_loc(const zbar::Image &img, const zbar::Symbol &sym)
|
|
{
|
|
int n = 0;
|
|
int w = img.get_width();
|
|
int h = img.get_height();
|
|
for (zbar::Symbol::PointIterator p(sym.point_begin()); p != sym.point_end();
|
|
++p, n++) {
|
|
zbar::Symbol::Point q(*p);
|
|
if (q.x < 0 || q.x >= w || q.y < 0 || q.y >= h)
|
|
error("location point out of range");
|
|
}
|
|
return (!n);
|
|
}
|
|
|
|
static inline int check_symbol(const zbar::Image &img, const zbar::Symbol &sym)
|
|
{
|
|
zbar::zbar_symbol_type_t type(sym.get_type());
|
|
std::string data(sym.get_data());
|
|
|
|
bool pass = expect_type && type == expect_type && data == expect_data &&
|
|
sym.get_data_length() == expect_data.length() &&
|
|
sym.get_quality() > 4;
|
|
if (pass)
|
|
pass = !check_loc(img, sym);
|
|
|
|
if (verbose || !pass)
|
|
std::cerr << "decode Symbol: " << sym << std::endl;
|
|
|
|
if (!expect_type)
|
|
error("unexpected");
|
|
else if (!pass)
|
|
error(std::string("expected: ") +
|
|
zbar::zbar_get_symbol_name(expect_type) + " " + expect_data);
|
|
|
|
expect_type = zbar::ZBAR_NONE;
|
|
expect_data = "";
|
|
return (!pass);
|
|
}
|
|
|
|
static inline int check_image(const zbar::Image &img)
|
|
{
|
|
zbar::SymbolSet syms(img.get_symbols());
|
|
int setn = syms.get_size(), countn = 0;
|
|
|
|
int rc = 0;
|
|
for (zbar::SymbolIterator sym(syms.symbol_begin());
|
|
sym != syms.symbol_end(); ++sym, ++countn)
|
|
rc |= check_symbol(img, *sym);
|
|
|
|
if (countn != setn)
|
|
rc |= error("SymbolSet size mismatch: exp=" + to_string(setn) +
|
|
" act=" + to_string(countn));
|
|
return (rc);
|
|
}
|
|
|
|
static inline void expect(zbar::zbar_symbol_type_t type, std::string data)
|
|
{
|
|
if (expect_type)
|
|
error(std::string("missing: ") + zbar_get_symbol_name(expect_type) +
|
|
" " + expect_data);
|
|
expect_type = type;
|
|
expect_data = data;
|
|
}
|
|
|
|
class Handler : public zbar::Image::Handler
|
|
{
|
|
void image_callback(zbar::Image &img);
|
|
};
|
|
|
|
void Handler::image_callback(zbar::Image &img)
|
|
{
|
|
bool unexpected = !expect_type;
|
|
if (unexpected)
|
|
error("unexpected image callback");
|
|
check_image(img);
|
|
}
|
|
|
|
static inline int test_processor()
|
|
{
|
|
// create processor w/no video and no window
|
|
zbar::Processor proc(debug, NULL);
|
|
Handler handler;
|
|
proc.set_handler(handler);
|
|
if (debug) {
|
|
proc.set_visible();
|
|
proc.user_wait();
|
|
}
|
|
|
|
// generate barcode test image
|
|
zbar::Image rgb3(0, 0, "RGB3");
|
|
|
|
// test cast to C image
|
|
if (test_image_ean13(rgb3))
|
|
error("failed to generate image");
|
|
|
|
// test decode
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
proc.process_image(rgb3);
|
|
if (debug)
|
|
proc.user_wait();
|
|
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
check_image(rgb3);
|
|
|
|
if (rgb3.get_format() != zbar_fourcc('R', 'G', 'B', '3'))
|
|
error("image format mismatch");
|
|
|
|
expect(zbar::ZBAR_NONE, "");
|
|
proc.set_config(zbar::ZBAR_EAN13, zbar::ZBAR_CFG_ENABLE, false);
|
|
proc.process_image(rgb3);
|
|
check_image(rgb3);
|
|
if (debug)
|
|
proc.user_wait();
|
|
|
|
proc.set_config("ean13.en");
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
proc << rgb3;
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
check_image(rgb3);
|
|
if (debug)
|
|
proc.user_wait();
|
|
|
|
{
|
|
zbar::Image grey(rgb3.convert(zbar_fourcc('G', 'R', 'E', 'Y')));
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
proc << grey;
|
|
|
|
zbar::Image y800 = grey.convert("Y800");
|
|
expect(zbar::ZBAR_EAN13, test_image_ean13_data);
|
|
proc << y800;
|
|
}
|
|
if (debug)
|
|
// check image data retention
|
|
proc.user_wait();
|
|
|
|
expect(zbar::ZBAR_NONE, "");
|
|
return (0);
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
debug = (argc > 1 && std::string(argv[1]) == "-d");
|
|
verbose = (debug || (argc > 1 && std::string(argv[1]) == "-v"));
|
|
|
|
if (test_processor()) {
|
|
error("ERROR: Processor test FAILED");
|
|
return (2);
|
|
}
|
|
|
|
if (test_image_check_cleanup())
|
|
error("cleanup failed");
|
|
|
|
if (errors) {
|
|
std::cout << "processor FAILED" << std::endl;
|
|
return (2);
|
|
} else {
|
|
std::cout << "processor PASSED." << std::endl;
|
|
return (0);
|
|
}
|
|
}
|