5 * Copyright 2010 ZXing authors All rights reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
24 #include "MagickBitmapSource.h"
25 #include <zxing/common/Counted.h>
26 //#include <zxing/qrcode/QRCodeReader.h>
27 #include <zxing/Binarizer.h>
28 #include <zxing/MultiFormatReader.h>
29 #include <zxing/Result.h>
30 #include <zxing/ReaderException.h>
31 #include <zxing/common/GlobalHistogramBinarizer.h>
32 #include <zxing/common/HybridBinarizer.h>
34 #include <zxing/Exception.h>
35 #include <zxing/common/IllegalArgumentException.h>
36 #include <zxing/BinaryBitmap.h>
37 #include <zxing/DecodeHints.h>
39 //#include <zxing/qrcode/detector/Detector.h>
40 //#include <zxing/qrcode/detector/QREdgeDetector.h>
41 //#include <zxing/qrcode/decoder/Decoder.h>
43 using namespace Magick;
45 using namespace zxing;
46 //using namespace zxing::qrcode;
48 static bool raw_dump = false;
49 static bool show_format = false;
50 static bool tryHarder = false;
51 static bool show_filename = false;
53 static const int MAX_EXPECTED = 1024;
55 Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints) {
56 Ref<Reader> reader(new MultiFormatReader);
57 return reader->decode(image, hints);
61 int test_image(Image& image, bool hybrid, string expected = "") {
66 Ref<BitMatrix> matrix(NULL);
67 Ref<Binarizer> binarizer(NULL);
68 const char* result_format = "";
71 Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
74 binarizer = new HybridBinarizer(source);
76 binarizer = new GlobalHistogramBinarizer(source);
79 DecodeHints hints(DecodeHints::DEFAULT_HINT);
80 hints.setTryHarder(tryHarder);
81 Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
82 Ref<Result> result(decode(binary, hints));
83 cell_result = result->getText()->getText();
84 result_format = barcodeFormatNames[result->getBarcodeFormat()];
86 } catch (ReaderException e) {
87 cell_result = "zxing::ReaderException: " + string(e.what());
89 } catch (zxing::IllegalArgumentException& e) {
90 cell_result = "zxing::IllegalArgumentException: " + string(e.what());
92 } catch (zxing::Exception& e) {
93 cell_result = "zxing::Exception: " + string(e.what());
95 } catch (std::exception& e) {
96 cell_result = "std::exception: " + string(e.what());
100 if (cell_result.compare(expected)) {
103 cout << (hybrid ? "Hybrid" : "Global") << " binarizer failed:\n";
104 if (expected.length() >= 0) {
105 cout << " Expected: " << expected << "\n";
107 cout << " Detected: " << cell_result << endl;
112 if (raw_dump && !hybrid) {/* don't print twice, and global is a bit better */
115 cout << " " << result_format;
123 int test_image_hybrid(Image& image, string expected = "") {
124 return test_image(image, true, expected);
127 int test_image_global(Image& image, string expected = "") {
128 return test_image(image, false, expected);
131 string get_expected(string imagefilename) {
132 string textfilename = imagefilename;
133 int dotpos = textfilename.rfind(".");
134 textfilename.replace(dotpos+1, textfilename.length() - dotpos - 1, "txt");
135 char data[MAX_EXPECTED];
136 FILE *fp = fopen(textfilename.data(), "rb");
139 // could not open file
143 fseek(fp, 0, SEEK_END);
144 int toread = ftell(fp);
147 if (toread > MAX_EXPECTED) {
148 cerr << "MAX_EXPECTED = " << MAX_EXPECTED << " but file '" << textfilename << "' has " << toread
149 << " bytes! Skipping..." << endl;
154 int nread = fread(data, sizeof(char), toread, fp);
155 if (nread != toread) {
156 cerr << "Could not read entire contents of file '" << textfilename << "'! Skipping..." << endl;
162 string expected(data);
166 int main(int argc, char** argv) {
168 cout << "Usage: " << argv[0] << " [--dump-raw] [--show-format] [--try-harder] [--show-filename] <filename1> [<filename2> ...]" << endl;
178 if (argc == 2) raw_dump = true;
180 for (int i = 1; i < argc; i++) {
181 string infilename = argv[i];
182 if (infilename.substr(infilename.length()-3,3).compare("txt") == 0) {
185 if (infilename.compare("--dump-raw") == 0) {
189 if (infilename.compare("--show-format") == 0) {
193 if (infilename.compare("--try-harder") == 0) {
197 if (infilename.compare("--show-filename") == 0) {
198 show_filename = true;
202 cerr << "Processing: " << infilename << endl;
204 cout << infilename << " ";
207 image.read(infilename);
209 cerr << "Unable to open image, ignoring" << endl;
214 expected = get_expected(infilename);
219 hresult = test_image_hybrid(image, expected);
220 gresult = test_image_global(image, expected);
222 gresult = gresult == 0;
223 hresult = hresult == 0;
225 gonly += gresult && !hresult;
226 honly += hresult && !gresult;
227 both += gresult && hresult;
228 neither += !gresult && !hresult;
233 cout << (honly+both) << " passed hybrid, " << (gonly+both) << " passed global, "
234 << both << " pass both, " << neither << " pass neither, " << honly
235 << " passed only hybrid, " << gonly << " passed only global, of " << total
236 << " total." << endl;