mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
C++: binarizer updates
- ported the HybridBinarizer from Java for improved 2D binarization - updated BinaryBitmap to report if it supports cropping and rotation - test binary updates to compare both binarizers like it used to git-svn-id: https://zxing.googlecode.com/svn/trunk@1489 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
8266b61f17
commit
348ebf3adc
|
@ -2,14 +2,18 @@
|
||||||
|
|
||||||
blackboxpath="../core/test/data/blackbox"
|
blackboxpath="../core/test/data/blackbox"
|
||||||
|
|
||||||
formats="ean13 ean8 upce upca qrcode"
|
if [ "$*" != "" ]; then
|
||||||
|
formats="$*"
|
||||||
|
else
|
||||||
|
formats="ean13 ean8 upce upca qrcode"
|
||||||
|
fi
|
||||||
|
|
||||||
passed=0;
|
passed=0;
|
||||||
failed=0;
|
failed=0;
|
||||||
oldcat="";
|
oldcat="";
|
||||||
|
|
||||||
for format in $formats; do
|
for format in $formats; do
|
||||||
for pic in `ls ${blackboxpath}/${format}-*/*.{jpg,JPG} 2>/dev/null`; do
|
for pic in `ls ${blackboxpath}/${format}-*/*.{jpg,JPG,gif,GIF,png,PNG} 2>/dev/null | sort -n`; do
|
||||||
category=${pic%/*};
|
category=${pic%/*};
|
||||||
category=${category##*/};
|
category=${category##*/};
|
||||||
if [ "$oldcat" != "$category" ]; then
|
if [ "$oldcat" != "$category" ]; then
|
||||||
|
@ -19,8 +23,14 @@ for format in $formats; do
|
||||||
failed=0;
|
failed=0;
|
||||||
fi
|
fi
|
||||||
echo -n "Processing: $pic ... "
|
echo -n "Processing: $pic ... "
|
||||||
tmp="${pic%JPG}";
|
tmp="${pic}"
|
||||||
txt="${tmp%jpg}txt";
|
tmp="${tmp%JPG}";
|
||||||
|
tmp="${tmp%jpg}";
|
||||||
|
tmp="${tmp%gif}";
|
||||||
|
tmp="${tmp%GIF}";
|
||||||
|
tmp="${tmp%png}";
|
||||||
|
tmp="${tmp%PNG}";
|
||||||
|
txt="${tmp}txt";
|
||||||
expected=`cat "$txt"`;
|
expected=`cat "$txt"`;
|
||||||
actual=`build/zxing $pic`;
|
actual=`build/zxing $pic`;
|
||||||
if [ "$expected" == "$actual" ]; then
|
if [ "$expected" == "$actual" ]; then
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
* BinaryBitmap.cpp
|
* BinaryBitmap.cpp
|
||||||
* zxing
|
* zxing
|
||||||
*
|
*
|
||||||
* Created by Ralf Kistner on 19/10/2009.
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
* Copyright 2008 ZXing authors All rights reserved.
|
|
||||||
* Modified by Lukasz Warchol on 02/02/2010.
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -50,4 +48,20 @@ namespace zxing {
|
||||||
return binarizer_->getLuminanceSource();
|
return binarizer_->getLuminanceSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool BinaryBitmap::isCropSupported() const {
|
||||||
|
return getLuminanceSource()->isCropSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<BinaryBitmap> BinaryBitmap::crop(int left, int top, int width, int height) {
|
||||||
|
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height))));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BinaryBitmap::isRotateSupported() const {
|
||||||
|
return getLuminanceSource()->isRotateSupported();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<BinaryBitmap> BinaryBitmap::rotateCounterClockwise() {
|
||||||
|
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
140
cpp/core/src/zxing/common/HybridBinarizer.cpp
Normal file
140
cpp/core/src/zxing/common/HybridBinarizer.cpp
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* HybridBinarizer.cpp
|
||||||
|
* zxing
|
||||||
|
*
|
||||||
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <zxing/common/HybridBinarizer.h>
|
||||||
|
|
||||||
|
#include <zxing/common/IllegalArgumentException.h>
|
||||||
|
|
||||||
|
namespace zxing {
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
static const int MINIMUM_DIMENSION = 40;
|
||||||
|
|
||||||
|
static const int LUMINANCE_BITS = 5;
|
||||||
|
static const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
|
||||||
|
static const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
|
||||||
|
|
||||||
|
HybridBinarizer::HybridBinarizer(Ref<LuminanceSource> source) :
|
||||||
|
GlobalHistogramBinarizer(source), cached_matrix_(NULL), cached_row_(NULL), cached_row_num_(-1) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
HybridBinarizer::~HybridBinarizer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ref<BitMatrix> HybridBinarizer::getBlackMatrix() {
|
||||||
|
binarizeEntireImage();
|
||||||
|
return cached_matrix_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<Binarizer> HybridBinarizer::createBinarizer(Ref<LuminanceSource> source) {
|
||||||
|
return Ref<Binarizer> (new HybridBinarizer(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
void HybridBinarizer::binarizeEntireImage() {
|
||||||
|
if (cached_matrix_ == NULL) {
|
||||||
|
Ref<LuminanceSource> source = getLuminanceSource();
|
||||||
|
if (source->getWidth() >= MINIMUM_DIMENSION && source->getHeight() >= MINIMUM_DIMENSION) {
|
||||||
|
unsigned char* luminances = source->getMatrix();
|
||||||
|
int width = source->getWidth();
|
||||||
|
int height = source->getHeight();
|
||||||
|
int subWidth = width >> 3;
|
||||||
|
int subHeight = height >> 3;
|
||||||
|
int *blackPoints = calculateBlackPoints(luminances, subWidth, subHeight, width);
|
||||||
|
cached_matrix_.reset(new BitMatrix(width,height));
|
||||||
|
calculateThresholdForBlock(luminances, subWidth, subHeight, width, blackPoints, cached_matrix_);
|
||||||
|
delete [] blackPoints;
|
||||||
|
} else {
|
||||||
|
// If the image is too small, fall back to the global histogram approach.
|
||||||
|
cached_matrix_.reset(GlobalHistogramBinarizer::getBlackMatrix());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HybridBinarizer::calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight,
|
||||||
|
int stride, int blackPoints[], Ref<BitMatrix> matrix) {
|
||||||
|
for (int y = 0; y < subHeight; y++) {
|
||||||
|
for (int x = 0; x < subWidth; x++) {
|
||||||
|
int left = (x > 1) ? x : 2;
|
||||||
|
left = (left < subWidth - 2) ? left : subWidth - 3;
|
||||||
|
int top = (y > 1) ? y : 2;
|
||||||
|
top = (top < subHeight - 2) ? top : subHeight - 3;
|
||||||
|
int sum = 0;
|
||||||
|
for (int z = -2; z <= 2; z++) {
|
||||||
|
int *blackRow = &blackPoints[(top + z) * subWidth];
|
||||||
|
sum += blackRow[left - 2];
|
||||||
|
sum += blackRow[left - 1];
|
||||||
|
sum += blackRow[left];
|
||||||
|
sum += blackRow[left + 1];
|
||||||
|
sum += blackRow[left + 2];
|
||||||
|
}
|
||||||
|
int average = sum / 25;
|
||||||
|
threshold8x8Block(luminances, x << 3, y << 3, average, stride, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HybridBinarizer::threshold8x8Block(unsigned char* luminances, int xoffset, int yoffset, int threshold,
|
||||||
|
int stride, Ref<BitMatrix> matrix) {
|
||||||
|
for (int y = 0; y < 8; y++) {
|
||||||
|
int offset = (yoffset + y) * stride + xoffset;
|
||||||
|
for (int x = 0; x < 8; x++) {
|
||||||
|
int pixel = luminances[offset + x] & 0xff;
|
||||||
|
if (pixel < threshold) {
|
||||||
|
matrix->set(xoffset + x, yoffset + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int* HybridBinarizer::calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight,
|
||||||
|
int stride) {
|
||||||
|
int *blackPoints = new int[subHeight * subWidth];
|
||||||
|
for (int y = 0; y < subHeight; y++) {
|
||||||
|
for (int x = 0; x < subWidth; x++) {
|
||||||
|
int sum = 0;
|
||||||
|
int min = 255;
|
||||||
|
int max = 0;
|
||||||
|
for (int yy = 0; yy < 8; yy++) {
|
||||||
|
int offset = ((y << 3) + yy) * stride + (x << 3);
|
||||||
|
for (int xx = 0; xx < 8; xx++) {
|
||||||
|
int pixel = luminances[offset + xx] & 0xff;
|
||||||
|
sum += pixel;
|
||||||
|
if (pixel < min) {
|
||||||
|
min = pixel;
|
||||||
|
}
|
||||||
|
if (pixel > max) {
|
||||||
|
max = pixel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the contrast is inadequate, use half the minimum, so that this block will be
|
||||||
|
// treated as part of the white background, but won't drag down neighboring blocks
|
||||||
|
// too much.
|
||||||
|
int average = (max - min > 24) ? (sum >> 6) : (min >> 1);
|
||||||
|
blackPoints[y * subWidth + x] = average;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blackPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace zxing
|
||||||
|
|
56
cpp/core/src/zxing/common/HybridBinarizer.h
Normal file
56
cpp/core/src/zxing/common/HybridBinarizer.h
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* HybridBinarizer.h
|
||||||
|
* zxing
|
||||||
|
*
|
||||||
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HYBRIDBINARIZER_H_
|
||||||
|
#define HYBRIDBINARIZER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <zxing/Binarizer.h>
|
||||||
|
#include <zxing/common/GlobalHistogramBinarizer.h>
|
||||||
|
#include <zxing/common/BitArray.h>
|
||||||
|
#include <zxing/common/BitMatrix.h>
|
||||||
|
|
||||||
|
namespace zxing {
|
||||||
|
|
||||||
|
class HybridBinarizer : public GlobalHistogramBinarizer {
|
||||||
|
private:
|
||||||
|
Ref<BitMatrix> cached_matrix_;
|
||||||
|
Ref<BitArray> cached_row_;
|
||||||
|
int cached_row_num_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
HybridBinarizer(Ref<LuminanceSource> source);
|
||||||
|
virtual ~HybridBinarizer();
|
||||||
|
|
||||||
|
virtual Ref<BitMatrix> getBlackMatrix();
|
||||||
|
Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source);
|
||||||
|
private:
|
||||||
|
void binarizeEntireImage();
|
||||||
|
// We'll be using one-D arrays because C++ can't dynamically allocate 2D arrays
|
||||||
|
int* calculateBlackPoints(unsigned char* luminances, int subWidth, int subHeight,
|
||||||
|
int stride);
|
||||||
|
void calculateThresholdForBlock(unsigned char* luminances, int subWidth, int subHeight,
|
||||||
|
int stride, int blackPoints[], Ref<BitMatrix> matrix);
|
||||||
|
void threshold8x8Block(unsigned char* luminances, int xoffset, int yoffset, int threshold,
|
||||||
|
int stride, Ref<BitMatrix> matrix);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* GLOBALHISTOGRAMBINARIZER_H_ */
|
|
@ -2,8 +2,7 @@
|
||||||
* MagickBitmapSource.cpp
|
* MagickBitmapSource.cpp
|
||||||
* zxing
|
* zxing
|
||||||
*
|
*
|
||||||
* Created by Ralf Kistner on 16/10/2009.
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
* Copyright 2008 ZXing authors All rights reserved.
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -75,5 +74,23 @@ unsigned char* MagickBitmapSource::getMatrix() {
|
||||||
}
|
}
|
||||||
return matrix;
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MagickBitmapSource::isRotateSupported() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<LuminanceSource> MagickBitmapSource::rotateCounterClockwise() {
|
||||||
|
//TODO(flyashi): add rotated image support.
|
||||||
|
/* this segfaults. I tried a few things, none seemed to work. Perhaps the problem is elsewhere? */
|
||||||
|
/*
|
||||||
|
Magick::Image rotated(image_);
|
||||||
|
rotated.modifyImage();
|
||||||
|
rotated.rotate(90); // Image::rotate takes CCW degrees as an argument
|
||||||
|
rotated.syncPixels();
|
||||||
|
return Ref<MagickBitmapSource> (new MagickBitmapSource(rotated));
|
||||||
|
*/
|
||||||
|
return Ref<MagickBitmapSource> (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
* MagickBitmapSource.h
|
* MagickBitmapSource.h
|
||||||
* zxing
|
* zxing
|
||||||
*
|
*
|
||||||
* Created by Ralf Kistner on 16/10/2009.
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
* Copyright 2008 ZXing authors All rights reserved.
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -42,6 +41,8 @@ public:
|
||||||
int getHeight() const;
|
int getHeight() const;
|
||||||
unsigned char* getRow(int y, unsigned char* row);
|
unsigned char* getRow(int y, unsigned char* row);
|
||||||
unsigned char* getMatrix();
|
unsigned char* getMatrix();
|
||||||
|
bool isRotateSupported() const;
|
||||||
|
Ref<LuminanceSource> rotateCounterClockwise();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
* main.cpp
|
* main.cpp
|
||||||
* zxing
|
* zxing
|
||||||
*
|
*
|
||||||
* Created by Ralf Kistner on 16/10/2009.
|
* Copyright 2010 ZXing authors All rights reserved.
|
||||||
* Copyright 2008 ZXing authors All rights reserved.
|
|
||||||
* Modified by Yakov Okshtein (flyashi@gmail.com) to add 1D barcode support.
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -31,7 +29,7 @@
|
||||||
#include <zxing/Result.h>
|
#include <zxing/Result.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
#include <zxing/common/GlobalHistogramBinarizer.h>
|
#include <zxing/common/GlobalHistogramBinarizer.h>
|
||||||
//#include <zxing/common/LocalBlockBinarizer.h>
|
#include <zxing/common/HybridBinarizer.h>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <zxing/Exception.h>
|
#include <zxing/Exception.h>
|
||||||
#include <zxing/common/IllegalArgumentException.h>
|
#include <zxing/common/IllegalArgumentException.h>
|
||||||
|
@ -46,13 +44,17 @@ using namespace std;
|
||||||
using namespace zxing;
|
using namespace zxing;
|
||||||
//using namespace zxing::qrcode;
|
//using namespace zxing::qrcode;
|
||||||
|
|
||||||
|
static bool raw_dump = false;
|
||||||
|
|
||||||
|
static const int MAX_EXPECTED = 1024;
|
||||||
|
|
||||||
Ref<Result> decode(Ref<BinaryBitmap> image) {
|
Ref<Result> decode(Ref<BinaryBitmap> image) {
|
||||||
Ref<Reader> reader(new MultiFormatReader);
|
Ref<Reader> reader(new MultiFormatReader);
|
||||||
return Ref<Result> (new Result(*reader->decode(image)));
|
return Ref<Result> (new Result(*reader->decode(image)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int test_image(Image& image, bool localized) {
|
int test_image(Image& image, bool hybrid, string expected = "") {
|
||||||
|
|
||||||
string cell_result;
|
string cell_result;
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
@ -64,8 +66,8 @@ int test_image(Image& image, bool localized) {
|
||||||
try {
|
try {
|
||||||
Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
|
Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
|
||||||
|
|
||||||
if (localized) {
|
if (hybrid) {
|
||||||
//binarizer = new LocalBlockBinarizer(source);
|
binarizer = new HybridBinarizer(source);
|
||||||
} else {
|
} else {
|
||||||
binarizer = new GlobalHistogramBinarizer(source);
|
binarizer = new GlobalHistogramBinarizer(source);
|
||||||
}
|
}
|
||||||
|
@ -88,33 +90,88 @@ int test_image(Image& image, bool localized) {
|
||||||
res = -5;
|
res = -5;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << cell_result;
|
if (cell_result.compare(expected)) {
|
||||||
|
res = -6;
|
||||||
|
if (!raw_dump) {
|
||||||
|
cout << (hybrid ? "Hybrid" : "Global") << " binarizer failed:\n";
|
||||||
|
if (expected.length() >= 0) {
|
||||||
|
cout << " Expected: " << expected << "\n";
|
||||||
|
}
|
||||||
|
cout << " Detected: " << cell_result << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (raw_dump && !hybrid) /* don't print twice, and global is a bit better */
|
||||||
|
cout << cell_result << endl;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_image_local(Image& image) {
|
int test_image_hybrid(Image& image, string expected = "") {
|
||||||
return test_image(image, true);
|
return test_image(image, true, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
int test_image_global(Image& image) {
|
int test_image_global(Image& image, string expected = "") {
|
||||||
return test_image(image, false);
|
return test_image(image, false, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
string get_expected(string imagefilename) {
|
||||||
|
string textfilename = imagefilename;
|
||||||
|
int dotpos = textfilename.rfind(".");
|
||||||
|
textfilename.replace(dotpos+1, textfilename.length() - dotpos - 1, "txt");
|
||||||
|
char data[MAX_EXPECTED];
|
||||||
|
FILE *fp = fopen(textfilename.data(), "rb");
|
||||||
|
|
||||||
|
// get file size
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
int toread = ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
|
||||||
|
if (toread > MAX_EXPECTED) {
|
||||||
|
cerr << "MAX_EXPECTED = " << MAX_EXPECTED << " but file '" << textfilename << "' has " << toread
|
||||||
|
<< " bytes! Skipping..." << endl;
|
||||||
|
fclose(fp);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int nread = fread(data, sizeof(char), toread, fp);
|
||||||
|
if (nread != toread) {
|
||||||
|
cerr << "Could not read entire contents of file '" << textfilename << "'! Skipping..." << endl;
|
||||||
|
fclose(fp);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
data[nread] = '\0';
|
||||||
|
string expected(data);
|
||||||
|
return expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
cout << "Usage: " << argv[0] << " <filename1> [<filename2> ...]" << endl;
|
cout << "Usage: " << argv[0] << " [--dump-raw] <filename1> [<filename2> ...]" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// int total = argc - 2;
|
int total = 0;
|
||||||
int gonly = 0;
|
int gonly = 0;
|
||||||
int lonly = 0;
|
int honly = 0;
|
||||||
int both = 0;
|
int both = 0;
|
||||||
int neither = 0;
|
int neither = 0;
|
||||||
|
|
||||||
|
if (argc == 2) raw_dump = true;
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
string infilename = argv[i];
|
string infilename = argv[i];
|
||||||
// cerr << "Processing: " << infilename << endl;
|
if (infilename.substr(infilename.length()-3,3).compare("txt") == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (infilename.compare("--dump-raw") == 0) {
|
||||||
|
raw_dump = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!raw_dump)
|
||||||
|
cerr << "Processing: " << infilename << endl;
|
||||||
Image image;
|
Image image;
|
||||||
try {
|
try {
|
||||||
image.read(infilename);
|
image.read(infilename);
|
||||||
|
@ -123,21 +180,31 @@ int main(int argc, char** argv) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gresult = 1;
|
string expected;
|
||||||
int lresult = 1;
|
expected = get_expected(infilename);
|
||||||
|
|
||||||
gresult = test_image_global(image);
|
int gresult = 1;
|
||||||
// lresult = test_image_local(image);
|
int hresult = 1;
|
||||||
|
|
||||||
|
hresult = test_image_hybrid(image, expected);
|
||||||
|
gresult = test_image_global(image, expected);
|
||||||
|
|
||||||
gresult = gresult == 0;
|
gresult = gresult == 0;
|
||||||
// lresult = lresult == 0;
|
hresult = hresult == 0;
|
||||||
|
|
||||||
gonly += gresult && !lresult;
|
|
||||||
lonly += lresult && !gresult;
|
|
||||||
both += gresult && lresult;
|
|
||||||
neither += !gresult && !lresult;
|
|
||||||
|
|
||||||
|
gonly += gresult && !hresult;
|
||||||
|
honly += hresult && !gresult;
|
||||||
|
both += gresult && hresult;
|
||||||
|
neither += !gresult && !hresult;
|
||||||
|
total = total + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!raw_dump)
|
||||||
|
cout << (honly+both) << " passed hybrid, " << (gonly+both) << " passed global, "
|
||||||
|
<< both << " pass both, " << neither << " pass neither, " << honly
|
||||||
|
<< " passed only hybrid, " << gonly << " passed only global, of " << total
|
||||||
|
<< " total." << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue