/*------------------------------------------------------------------------ * 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 *------------------------------------------------------------------------*/ #include #include #include #include #include using namespace std; using namespace zbar; #ifndef ZBAR_FIXED #define ZBAR_FIXED 5 #endif #define ZBAR_FRAC (1 << ZBAR_FIXED) Decoder decoder; Scanner scanner; /* undocumented API for drawing cutesy debug graphics */ extern "C" void zbar_scanner_get_state(const zbar_scanner_t *scn, unsigned *x, unsigned *cur_edge, unsigned *last_edge, int *y0, int *y1, int *y2, int *y1_thresh); void scan_image(const char *filename) { scanner.reset(); // normally scanner would reset associated decoder, // but this debug program connects them manually // (to make intermediate state more readily available) // so decoder must also be reset manually decoder.reset(); Magick::Image image; image.read(filename); string file = image.baseFilename(); size_t baseidx = file.rfind('/'); if (baseidx != string::npos) file = file.substr(baseidx + 1, file.length() - baseidx - 1); ofstream svg((file + ".svg").c_str()); unsigned inwidth = image.columns(); unsigned width = inwidth + 3; unsigned height = image.rows(); unsigned midy = height / 2; cerr << "x+: " << midy << endl; image.crop(Magick::Geometry(inwidth, 1, 0, midy)); svg << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl; // brute force unsigned raw[inwidth]; { // extract scan from image pixels image.modifyImage(); Magick::Pixels view(image); Magick::PixelPacket *pxp = view.get(0, 0, inwidth, 1); Magick::ColorYUV y; double max = 0; svg << "" << endl << "" << endl; } image.depth(8); image.write(file + ".png"); // process scan and capture calculated values unsigned cur_edge[width], last_edge[width]; int y0[width], y1[width], y2[width], y1_thr[width]; svg << "" << endl; for (unsigned i = 0; i < width; i++) { int edge; if (i < inwidth) edge = scanner.scan_y(raw[i]); else edge = scanner.flush(); unsigned x; zbar_scanner_get_state(scanner, &x, &cur_edge[i], &last_edge[i], &y0[i], &y1[i], &y2[i], &y1_thr[i]); if (edge) { unsigned w = scanner.get_width(); if (w) svg << "" << endl << "" << endl << w << "" << endl; zbar_symbol_type_t sym = decoder.decode_width(w); if (sym > ZBAR_PARTIAL) { svg << "" << decoder.get_data_string() << "" << endl; } } else if ((!i) ? last_edge[i] : last_edge[i] == last_edge[i - 1]) last_edge[i] = 0; } svg << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl; svg << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl << "" << endl; svg << "" << endl; } int main(int argc, const char *argv[]) { if (argc < 2) { cerr << "ERROR: specify image file(s) to scan" << endl; return (1); } for (int i = 1; i < argc; i++) scan_image(argv[i]); return (0); }