Skip to content

Commit

Permalink
fix C++ wrapper bugs (bug #3396068)
Browse files Browse the repository at this point in the history
    - thanks to anotheruser1 for reporting this!
    - add new C++ wrapper test
  • Loading branch information
spadix0 committed Sep 18, 2011
1 parent cb7bb29 commit 051ebcb
Show file tree
Hide file tree
Showing 7 changed files with 444 additions and 52 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
current:
* fix C++ wrapper bugs (bug #3396068)
- thanks to anotheruser1 for reporting this!
- add new C++ wrapper test
* fix avoid compositing ISBN10 data
* add support for GraphicsMagick as ImageMagick alternative
* mention xmlto in HACKING (patch #3297039)
Expand Down
13 changes: 10 additions & 3 deletions include/zbar/Image.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ class Image {

~Image ()
{
set_data(NULL, 0);
zbar_image_set_userdata(_img, NULL);
if(zbar_image_get_userdata(_img) == this)
zbar_image_set_userdata(_img, NULL);
zbar_image_ref(_img, -1);
}

Expand Down Expand Up @@ -255,6 +255,14 @@ class Image {
throw FormatError();
}

/// image format conversion.
/// see zbar_image_convert()
Image convert (std::string format) const
{
unsigned long fourcc = zbar_fourcc_parse(format.c_str());
return(convert(fourcc));
}

/// image format conversion with crop/pad.
/// see zbar_image_convert_resize()
/// @since 0.4
Expand Down Expand Up @@ -309,7 +317,6 @@ class Image {
{
// by default nothing is cleaned
assert(img);
assert(zbar_image_get_userdata(img));
}

private:
Expand Down
17 changes: 11 additions & 6 deletions include/zbar/Symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ class Symbol {
: _sym(sym),
_index(index)
{
sym->ref(1);
if(sym)
sym->ref(1);
if(!sym ||
(unsigned)_index >= zbar_symbol_get_loc_size(*_sym))
_index = -1;
Expand All @@ -162,20 +163,24 @@ class Symbol {
: _sym(iter._sym),
_index(iter._index)
{
_sym->ref();
if(_sym)
_sym->ref();
}

/// destructor.
~PointIterator ()
{
_sym->ref(-1);
if(_sym)
_sym->ref(-1);
}

/// assignment.
PointIterator& operator= (const PointIterator& iter)
{
iter._sym->ref();
_sym->ref(-1);
if(iter._sym)
iter._sym->ref();
if(_sym)
_sym->ref(-1);
_sym = iter._sym;
_index = iter._index;
return(*this);
Expand All @@ -191,7 +196,7 @@ class Symbol {
PointIterator& operator++ ()
{
unsigned int i = ++_index;
if(i >= zbar_symbol_get_loc_size(*_sym))
if(!_sym || i >= zbar_symbol_get_loc_size(*_sym))
_index = -1;
return(*this);
}
Expand Down
9 changes: 8 additions & 1 deletion test/Makefile.am.inc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ check_PROGRAMS += test/test_cpp
test_test_cpp_SOURCES = test/test_cpp.cpp
test_test_cpp_LDADD = zbar/libzbar.la $(AM_LDADD)

check_PROGRAMS += test/test_cpp_img
test_test_cpp_img_SOURCES = test/test_cpp_img.cpp $(TEST_IMAGE_SOURCES)
test_test_cpp_img_LDADD = zbar/libzbar.la $(AM_LDADD)

if HAVE_JPEG
check_PROGRAMS += test/test_jpeg
test_test_jpeg_SOURCES = test/test_jpeg.c
Expand Down Expand Up @@ -68,13 +72,16 @@ CLEANFILES += test/.libs/test_decode test/.libs/test_proc \
test/.libs/test_convert test/.libs/test_window \
test/.libs/test_video test/.libs/dbg_scan test/.libs/test_gtk

check-cpp: test/test_cpp_img
test/test_cpp_img

check-decoder: test/test_decode
test/test_decode -q

regress-decoder: test/test_decode
test/test_decode -n 100000

check-local: check-decoder check-images
check-local: check-cpp check-decoder check-images
regress: regress-decoder regress-images

.PHONY: check-decoder check-images regress-decoder regress-images regress
234 changes: 234 additions & 0 deletions test/test_cpp_img.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
//------------------------------------------------------------------------
// Copyright 2007-2009 (c) Jeff Brown <[email protected]>
//
// 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 <iostream>
#include <sstream>
#include <iomanip>
#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();
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 << "FAIL" << std::endl;
return(2);
}
else {
std::cout << "OK" << std::endl;
return(0);
}
}
Loading

0 comments on commit 051ebcb

Please sign in to comment.