//------------------------------------------------------------------------ // Copyright 2007-2009 (c) Jeff Brown // // 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 #include #include #include #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 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); } }