mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
1d support for most C++ decoders; n.b. not pdf417 and rss
git-svn-id: https://zxing.googlecode.com/svn/trunk@2608 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
b323e601b7
commit
af53906502
|
@ -34,7 +34,8 @@
|
||||||
debug="true"
|
debug="true"
|
||||||
deprecation="true"
|
deprecation="true"
|
||||||
fork="true"
|
fork="true"
|
||||||
includeantruntime="false">
|
includeantruntime="false"
|
||||||
|
encoding="UTF-8">
|
||||||
</javac>
|
</javac>
|
||||||
<jar jarfile="core.jar" basedir="build"/>
|
<jar jarfile="core.jar" basedir="build"/>
|
||||||
</target>
|
</target>
|
||||||
|
@ -51,7 +52,8 @@
|
||||||
destdir="build-test"
|
destdir="build-test"
|
||||||
debug="true"
|
debug="true"
|
||||||
deprecation="true"
|
deprecation="true"
|
||||||
includeantruntime="false">
|
includeantruntime="false"
|
||||||
|
encoding="UTF-8">
|
||||||
<classpath>
|
<classpath>
|
||||||
<pathelement location="core.jar"/>
|
<pathelement location="core.jar"/>
|
||||||
<pathelement location="lib/junit-4.11.jar"/>
|
<pathelement location="lib/junit-4.11.jar"/>
|
||||||
|
|
|
@ -31,7 +31,7 @@ public final class AztecBlackBox2TestCase extends AbstractBlackBoxTestCase {
|
||||||
addTest(2, 2, 0.0f);
|
addTest(2, 2, 0.0f);
|
||||||
addTest(2, 2, 90.0f);
|
addTest(2, 2, 90.0f);
|
||||||
addTest(3, 3, 180.0f);
|
addTest(3, 3, 180.0f);
|
||||||
addTest(1, 1, 270.0f);
|
addTest(2, 2, 270.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
3
cpp/.gitignore
vendored
3
cpp/.gitignore
vendored
|
@ -3,4 +3,5 @@
|
||||||
xcuserdata
|
xcuserdata
|
||||||
callgrind.out.*
|
callgrind.out.*
|
||||||
contents.xcworkspacedata
|
contents.xcworkspacedata
|
||||||
*.pyc
|
*.pyc
|
||||||
|
/.rbenv-version
|
|
@ -34,4 +34,47 @@
|
||||||
fun:malloc_zone_calloc
|
fun:malloc_zone_calloc
|
||||||
...
|
...
|
||||||
fun:map_images
|
fun:map_images
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
c++
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:__cxa_get_globals
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
stdio
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:sprintf
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
objc
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:prepareForMethodLookup
|
||||||
|
fun:lookUpMethod
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
os
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:dlopen
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
osx
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:map_images
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
at_exit
|
||||||
|
Memcheck:Leak
|
||||||
|
...
|
||||||
|
fun:atexit_register
|
||||||
}
|
}
|
|
@ -22,8 +22,7 @@ if env['PIC']:
|
||||||
flags.append("-fPIC")
|
flags.append("-fPIC")
|
||||||
|
|
||||||
flags.append("-Wextra -Werror")
|
flags.append("-Wextra -Werror")
|
||||||
# Can't enable unless we get rid of the dynamic variable length arrays
|
flags.append("-pedantic")
|
||||||
# flags.append("-pedantic")
|
|
||||||
|
|
||||||
compile_options['CXXFLAGS'] = ' '.join(flags)
|
compile_options['CXXFLAGS'] = ' '.join(flags)
|
||||||
compile_options['LINKFLAGS'] = "-ldl -L/usr/lib -L/opt/local/lib -L/usr/local/lib"
|
compile_options['LINKFLAGS'] = "-ldl -L/usr/lib -L/opt/local/lib -L/usr/local/lib"
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
RSS_EXPANDED,
|
RSS_EXPANDED,
|
||||||
UPC_A,
|
UPC_A,
|
||||||
UPC_E,
|
UPC_E,
|
||||||
UPC_EAN_EXTENSION,
|
UPC_EAN_EXTENSION
|
||||||
};
|
};
|
||||||
|
|
||||||
BarcodeFormat(Value v) : value(v) {}
|
BarcodeFormat(Value v) : value(v) {}
|
||||||
|
|
|
@ -20,21 +20,24 @@
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <zxing/ZXing.h>
|
||||||
#include <zxing/Exception.h>
|
#include <zxing/Exception.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
namespace zxing {
|
using zxing::Exception;
|
||||||
|
|
||||||
Exception::Exception() {}
|
void Exception::deleteMessage() {
|
||||||
|
delete [] message;
|
||||||
Exception::Exception(const char *msg) :
|
|
||||||
message(msg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Exception::what() const throw() {
|
|
||||||
return message.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
Exception::~Exception() throw() {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const* Exception::copy(char const* msg) {
|
||||||
|
char* message = 0;
|
||||||
|
if (msg) {
|
||||||
|
int l = strlen(msg)+1;
|
||||||
|
if (l) {
|
||||||
|
message = new char[l];
|
||||||
|
strcpy(message, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
|
||||||
#ifndef __EXCEPTION_H__
|
#ifndef __EXCEPTION_H__
|
||||||
#define __EXCEPTION_H__
|
#define __EXCEPTION_H__
|
||||||
|
|
||||||
|
@ -24,17 +25,27 @@
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
class Exception;
|
||||||
|
}
|
||||||
|
|
||||||
class Exception : public std::exception {
|
class zxing::Exception : public std::exception {
|
||||||
private:
|
private:
|
||||||
std::string message;
|
char const* const message;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Exception();
|
Exception() throw() : message(0) {}
|
||||||
Exception(const char *msg);
|
Exception(const char* msg) throw() : message(copy(msg)) {}
|
||||||
virtual const char* what() const throw();
|
Exception(Exception const& that) throw() : std::exception(that), message(copy(that.message)) {}
|
||||||
virtual ~Exception() throw();
|
~Exception() throw() {
|
||||||
|
if(message) {
|
||||||
|
deleteMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
char const* what() const throw() {return message ? message : "";}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static char const* copy(char const*);
|
||||||
|
void deleteMessage();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
#endif // __EXCEPTION_H__
|
#endif // __EXCEPTION_H__
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <zxing/ZXing.h>
|
||||||
#include <zxing/MultiFormatReader.h>
|
#include <zxing/MultiFormatReader.h>
|
||||||
#include <zxing/qrcode/QRCodeReader.h>
|
#include <zxing/qrcode/QRCodeReader.h>
|
||||||
#include <zxing/datamatrix/DataMatrixReader.h>
|
#include <zxing/datamatrix/DataMatrixReader.h>
|
||||||
|
@ -111,7 +112,6 @@ void MultiFormatReader::setHints(DecodeHints hints) {
|
||||||
Ref<Result> MultiFormatReader::decodeInternal(Ref<BinaryBitmap> image) {
|
Ref<Result> MultiFormatReader::decodeInternal(Ref<BinaryBitmap> image) {
|
||||||
for (unsigned int i = 0; i < readers_.size(); i++) {
|
for (unsigned int i = 0; i < readers_.size(); i++) {
|
||||||
try {
|
try {
|
||||||
// std::cerr << "0 " << typeid(readers_[i]).name() << std::endl;
|
|
||||||
return readers_[i]->decode(image, hints_);
|
return readers_[i]->decode(image, hints_);
|
||||||
} catch (ReaderException const& re) {
|
} catch (ReaderException const& re) {
|
||||||
// continue
|
// continue
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
|
|
||||||
/*
|
|
||||||
* Copyright 20011 ZXing authors
|
|
||||||
*
|
|
||||||
* 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/NotFoundException.h>
|
|
||||||
|
|
||||||
using zxing::NotFoundException;
|
|
||||||
|
|
||||||
NotFoundException::NotFoundException() {}
|
|
||||||
|
|
||||||
NotFoundException::NotFoundException(const char *msg)
|
|
||||||
: ReaderException(msg) {}
|
|
||||||
|
|
||||||
NotFoundException::~NotFoundException() throw() {}
|
|
||||||
|
|
||||||
|
|
||||||
NotFoundException const&
|
|
||||||
NotFoundException::getNotFoundInstance() {
|
|
||||||
static NotFoundException instance;
|
|
||||||
return instance;
|
|
||||||
}
|
|
|
@ -22,15 +22,14 @@
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
class NotFoundException;
|
||||||
class NotFoundException : public ReaderException {
|
|
||||||
public:
|
|
||||||
NotFoundException();
|
|
||||||
NotFoundException(const char *msg);
|
|
||||||
~NotFoundException() throw();
|
|
||||||
|
|
||||||
static NotFoundException const& getNotFoundInstance();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class zxing::NotFoundException : public ReaderException {
|
||||||
|
public:
|
||||||
|
NotFoundException() throw() {}
|
||||||
|
NotFoundException(const char *msg) throw() : ReaderException(msg) {}
|
||||||
|
~NotFoundException() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // __NOT_FOUND_EXCEPTION_H__
|
#endif // __NOT_FOUND_EXCEPTION_H__
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
|
|
||||||
/*
|
|
||||||
* ReaderException.cpp
|
|
||||||
* zxing
|
|
||||||
*
|
|
||||||
* Created by Christian Brunschen on 13/05/2008.
|
|
||||||
* Copyright 2008-2011 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/ReaderException.h>
|
|
||||||
|
|
||||||
namespace zxing {
|
|
||||||
|
|
||||||
ReaderException::ReaderException() {}
|
|
||||||
|
|
||||||
ReaderException::ReaderException(const char *msg) :
|
|
||||||
Exception(msg) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ReaderException::~ReaderException() throw() {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -23,13 +23,14 @@
|
||||||
#include <zxing/Exception.h>
|
#include <zxing/Exception.h>
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
class ReaderException;
|
||||||
|
}
|
||||||
|
|
||||||
class ReaderException : public Exception {
|
class zxing::ReaderException : public Exception {
|
||||||
public:
|
public:
|
||||||
ReaderException();
|
ReaderException() throw() {}
|
||||||
ReaderException(const char *msg);
|
ReaderException(char const* msg) throw() : Exception(msg) {}
|
||||||
~ReaderException() throw();
|
~ReaderException() throw() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
|
||||||
#endif // __READER_EXCEPTION_H__
|
#endif // __READER_EXCEPTION_H__
|
||||||
|
|
97
cpp/core/src/zxing/ZXing.h
Normal file
97
cpp/core/src/zxing/ZXing.h
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
|
||||||
|
/*
|
||||||
|
* Copyright 2013 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 __ZXING_H_
|
||||||
|
#define __ZXING_H_
|
||||||
|
|
||||||
|
#define ZXING_ARRAY_LEN(v) ((int)(sizeof(v)/sizeof(v[0])))
|
||||||
|
|
||||||
|
#ifndef ZXING_DEBUG
|
||||||
|
#define ZXING_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ZXING_DEBUG
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using std::cout;
|
||||||
|
using std::cerr;
|
||||||
|
using std::endl;
|
||||||
|
using std::flush;
|
||||||
|
using std::string;
|
||||||
|
using std::ostream;
|
||||||
|
|
||||||
|
#if ZXING_DEBUG_TIMER
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
namespace zxing {
|
||||||
|
class DebugTimer;
|
||||||
|
}
|
||||||
|
|
||||||
|
class zxing::DebugTimer {
|
||||||
|
public:
|
||||||
|
DebugTimer(char const* string_) : chars(string_) {
|
||||||
|
gettimeofday(&start, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugTimer(std::string const& string_) : chars(0), string(string_) {
|
||||||
|
gettimeofday(&start, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark(char const* string) {
|
||||||
|
struct timeval end;
|
||||||
|
gettimeofday(&end, 0);
|
||||||
|
int diff =
|
||||||
|
(end.tv_sec - start.tv_sec)*1000*1000+(end.tv_usec - start.tv_usec);
|
||||||
|
|
||||||
|
cerr << diff << " " << string << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark(std::string string) {
|
||||||
|
mark(string.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
~DebugTimer() {
|
||||||
|
if (chars) {
|
||||||
|
mark(chars);
|
||||||
|
} else {
|
||||||
|
mark(string.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char const* const chars;
|
||||||
|
std::string string;
|
||||||
|
struct timeval start;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ZXING_TIME(string) DebugTimer __timer__ (string)
|
||||||
|
#define ZXING_TIME_MARK(string) __timer__.mark(string)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ZXING_DEBUG
|
||||||
|
|
||||||
|
#ifndef ZXING_TIME
|
||||||
|
#define ZXING_TIME(string) (void)0
|
||||||
|
#endif
|
||||||
|
#ifndef ZXING_TIME_MARK
|
||||||
|
#define ZXING_TIME_MARK(string) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -32,7 +32,7 @@ AztecDetectorResult::AztecDetectorResult(Ref<BitMatrix> bits,
|
||||||
compact_(compact),
|
compact_(compact),
|
||||||
nbDatablocks_(nbDatablocks),
|
nbDatablocks_(nbDatablocks),
|
||||||
nbLayers_(nbLayers) {
|
nbLayers_(nbLayers) {
|
||||||
};
|
}
|
||||||
|
|
||||||
bool AztecDetectorResult::isCompact() {
|
bool AztecDetectorResult::isCompact() {
|
||||||
return compact_;
|
return compact_;
|
||||||
|
|
|
@ -30,7 +30,7 @@ using zxing::aztec::AztecReader;
|
||||||
|
|
||||||
AztecReader::AztecReader() : decoder_() {
|
AztecReader::AztecReader() : decoder_() {
|
||||||
// nothing
|
// nothing
|
||||||
};
|
}
|
||||||
|
|
||||||
Ref<Result> AztecReader::decode(Ref<zxing::BinaryBitmap> image) {
|
Ref<Result> AztecReader::decode(Ref<zxing::BinaryBitmap> image) {
|
||||||
Detector detector(image->getBlackMatrix());
|
Detector detector(image->getBlackMatrix());
|
||||||
|
|
|
@ -328,13 +328,12 @@ Ref<BitArray> Decoder::correctBits(Ref<zxing::BitArray> rawbits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// std::printf("trying reed solomon, numECCodewords:%d\n", numECCodewords);
|
|
||||||
ReedSolomonDecoder rsDecoder(gf);
|
ReedSolomonDecoder rsDecoder(gf);
|
||||||
rsDecoder.decode(dataWords, numECCodewords);
|
rsDecoder.decode(dataWords, numECCodewords);
|
||||||
} catch (ReedSolomonException rse) {
|
} catch (ReedSolomonException const& ignored) {
|
||||||
// std::printf("got reed solomon exception:%s, throwing formatexception\n", rse.what());
|
// std::printf("got reed solomon exception:%s, throwing formatexception\n", rse.what());
|
||||||
throw FormatException("rs decoding failed");
|
throw FormatException("rs decoding failed");
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException const& iae) {
|
||||||
// std::printf("illegal argument exception: %s", iae.what());
|
// std::printf("illegal argument exception: %s", iae.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -205,7 +205,7 @@ void Detector::correctParameterData(Ref<zxing::BitArray> parameterData, bool com
|
||||||
// std::printf("parameter data reed solomon\n");
|
// std::printf("parameter data reed solomon\n");
|
||||||
ReedSolomonDecoder rsDecoder(GenericGF::AZTEC_PARAM);
|
ReedSolomonDecoder rsDecoder(GenericGF::AZTEC_PARAM);
|
||||||
rsDecoder.decode(parameterWords, numECCodewords);
|
rsDecoder.decode(parameterWords, numECCodewords);
|
||||||
} catch (ReedSolomonException e) {
|
} catch (ReedSolomonException const& ignored) {
|
||||||
// std::printf("reed solomon decoding failed\n");
|
// std::printf("reed solomon decoding failed\n");
|
||||||
throw ReaderException("failed to decode parameter data");
|
throw ReaderException("failed to decode parameter data");
|
||||||
}
|
}
|
||||||
|
@ -308,7 +308,7 @@ Ref<Point> Detector::getMatrixCenter() {
|
||||||
pointC = cornerPoints[2];
|
pointC = cornerPoints[2];
|
||||||
pointD = cornerPoints[3];
|
pointD = cornerPoints[3];
|
||||||
|
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException const& e) {
|
||||||
|
|
||||||
int cx = image_->getWidth() / 2;
|
int cx = image_->getWidth() / 2;
|
||||||
int cy = image_->getHeight() / 2;
|
int cy = image_->getHeight() / 2;
|
||||||
|
@ -331,7 +331,7 @@ Ref<Point> Detector::getMatrixCenter() {
|
||||||
pointC = cornerPoints[2];
|
pointC = cornerPoints[2];
|
||||||
pointD = cornerPoints[3];
|
pointD = cornerPoints[3];
|
||||||
|
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException const& e) {
|
||||||
|
|
||||||
pointA = getFirstDifferent(Ref<Point>(new Point(cx+15/2, cy-15/2)), false, 1, -1)->toResultPoint();
|
pointA = getFirstDifferent(Ref<Point>(new Point(cx+15/2, cy-15/2)), false, 1, -1)->toResultPoint();
|
||||||
pointB = getFirstDifferent(Ref<Point>(new Point(cx+15/2, cy+15/2)), false, 1, 1)->toResultPoint();
|
pointB = getFirstDifferent(Ref<Point>(new Point(cx+15/2, cy+15/2)), false, 1, 1)->toResultPoint();
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
|
|
||||||
|
|
||||||
namespace zxing {
|
namespace zxing {
|
||||||
|
|
||||||
template<typename T> class Array : public Counted {
|
template<typename T> class Array : public Counted {
|
||||||
|
|
|
@ -106,11 +106,11 @@ bool BitArray::isRange(int start, int end, bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<int>& BitArray::getBitArray() {
|
vector<int>& BitArray::getBitArray() {
|
||||||
return bits;
|
return bits->values();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitArray::reverse() {
|
void BitArray::reverse() {
|
||||||
vector<int> newBits(bits.size());
|
ArrayRef<int> newBits(bits.size());
|
||||||
int size = this->size;
|
int size = this->size;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (get(size - i - 1)) {
|
if (get(size - i - 1)) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
#include <zxing/common/Counted.h>
|
#include <zxing/common/Counted.h>
|
||||||
#include <zxing/common/IllegalArgumentException.h>
|
#include <zxing/common/IllegalArgumentException.h>
|
||||||
|
#include <zxing/common/Array.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -43,7 +44,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int size;
|
int size;
|
||||||
std::vector<int> bits;
|
ArrayRef<int> bits;
|
||||||
static const int logBits = ZX_LOG_DIGITS(bitsPerWord);
|
static const int logBits = ZX_LOG_DIGITS(bitsPerWord);
|
||||||
static const int bitsMask = (1 << logBits) - 1;
|
static const int bitsMask = (1 << logBits) - 1;
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ void BitMatrix::setRegion(int left, int top, int width, int height) {
|
||||||
int right = left + width;
|
int right = left + width;
|
||||||
int bottom = top + height;
|
int bottom = top + height;
|
||||||
if (bottom > this->height || right > this->width) {
|
if (bottom > this->height || right > this->width) {
|
||||||
throw new IllegalArgumentException("The region must fit inside the matrix");
|
throw IllegalArgumentException("The region must fit inside the matrix");
|
||||||
}
|
}
|
||||||
for (int y = top; y < bottom; y++) {
|
for (int y = top; y < bottom; y++) {
|
||||||
int offset = y * rowSize;
|
int offset = y * rowSize;
|
||||||
|
|
|
@ -28,67 +28,67 @@ using zxing::GenericGF;
|
||||||
using zxing::GenericGFPoly;
|
using zxing::GenericGFPoly;
|
||||||
using zxing::Ref;
|
using zxing::Ref;
|
||||||
|
|
||||||
Ref<GenericGF> GenericGF::QR_CODE_FIELD_256(new GenericGF(0x011D, 256));
|
Ref<GenericGF> GenericGF::AZTEC_DATA_12(new GenericGF(0x1069, 4096, 1));
|
||||||
Ref<GenericGF> GenericGF::DATA_MATRIX_FIELD_256(new GenericGF(0x012D, 256));
|
Ref<GenericGF> GenericGF::AZTEC_DATA_10(new GenericGF(0x409, 1024, 1));
|
||||||
Ref<GenericGF> GenericGF::AZTEC_PARAM(new GenericGF(0x13, 16));
|
Ref<GenericGF> GenericGF::AZTEC_DATA_6(new GenericGF(0x43, 64, 1));
|
||||||
Ref<GenericGF> GenericGF::AZTEC_DATA_6(new GenericGF(0x43, 64));
|
Ref<GenericGF> GenericGF::AZTEC_PARAM(new GenericGF(0x13, 16, 1));
|
||||||
Ref<GenericGF> GenericGF::AZTEC_DATA_8(GenericGF::DATA_MATRIX_FIELD_256);
|
Ref<GenericGF> GenericGF::QR_CODE_FIELD_256(new GenericGF(0x011D, 256, 0));
|
||||||
Ref<GenericGF> GenericGF::AZTEC_DATA_10(new GenericGF(0x409, 1024));
|
Ref<GenericGF> GenericGF::DATA_MATRIX_FIELD_256(new GenericGF(0x012D, 256, 1));
|
||||||
Ref<GenericGF> GenericGF::AZTEC_DATA_12(new GenericGF(0x1069, 4096));
|
Ref<GenericGF> GenericGF::AZTEC_DATA_8 = DATA_MATRIX_FIELD_256;
|
||||||
|
Ref<GenericGF> GenericGF::MAXICODE_FIELD_64 = AZTEC_DATA_6;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
int INITIALIZATION_THRESHOLD = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int INITIALIZATION_THRESHOLD = 0;
|
GenericGF::GenericGF(int primitive_, int size_, int b)
|
||||||
|
: size(size_), primitive(primitive_), generatorBase(b), initialized(false) {
|
||||||
GenericGF::GenericGF(int primitive, int size)
|
|
||||||
: size_(size), primitive_(primitive), initialized_(false) {
|
|
||||||
if (size <= INITIALIZATION_THRESHOLD) {
|
if (size <= INITIALIZATION_THRESHOLD) {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericGF::initialize() {
|
void GenericGF::initialize() {
|
||||||
//expTable_ = std::vector<int>(size_, (const int) 0);
|
expTable.resize(size);
|
||||||
//logTable_ = std::vector<int>(size_, (const int) 0);
|
logTable.resize(size);
|
||||||
expTable_.resize(size_);
|
|
||||||
logTable_.resize(size_);
|
|
||||||
|
|
||||||
int x = 1;
|
int x = 1;
|
||||||
|
|
||||||
for (int i = 0; i < size_; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
expTable_[i] = x;
|
expTable[i] = x;
|
||||||
x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
|
x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
|
||||||
if (x >= size_) {
|
if (x >= size) {
|
||||||
x ^= primitive_;
|
x ^= primitive;
|
||||||
x &= size_-1;
|
x &= size-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < size_-1; i++) {
|
for (int i = 0; i < size-1; i++) {
|
||||||
logTable_[expTable_[i]] = i;
|
logTable[expTable[i]] = i;
|
||||||
}
|
}
|
||||||
//logTable_[0] == 0 but this should never be used
|
//logTable[0] == 0 but this should never be used
|
||||||
|
zero =
|
||||||
zero_ = Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), ArrayRef<int>(new Array<int>(1))));
|
Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), ArrayRef<int>(new Array<int>(1))));
|
||||||
zero_->getCoefficients()[0] = 0;
|
zero->getCoefficients()[0] = 0;
|
||||||
one_ = Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), ArrayRef<int>(new Array<int>(1))));
|
one =
|
||||||
one_->getCoefficients()[0] = 1;
|
Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), ArrayRef<int>(new Array<int>(1))));
|
||||||
|
one->getCoefficients()[0] = 1;
|
||||||
initialized_ = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericGF::checkInit() {
|
void GenericGF::checkInit() {
|
||||||
if (!initialized_) {
|
if (!initialized) {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<GenericGFPoly> GenericGF::getZero() {
|
Ref<GenericGFPoly> GenericGF::getZero() {
|
||||||
checkInit();
|
checkInit();
|
||||||
return zero_;
|
return zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<GenericGFPoly> GenericGF::getOne() {
|
Ref<GenericGFPoly> GenericGF::getOne() {
|
||||||
checkInit();
|
checkInit();
|
||||||
return one_;
|
return one;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<GenericGFPoly> GenericGF::buildMonomial(int degree, int coefficient) {
|
Ref<GenericGFPoly> GenericGF::buildMonomial(int degree, int coefficient) {
|
||||||
|
@ -98,12 +98,11 @@ Ref<GenericGFPoly> GenericGF::buildMonomial(int degree, int coefficient) {
|
||||||
throw IllegalArgumentException("Degree must be non-negative");
|
throw IllegalArgumentException("Degree must be non-negative");
|
||||||
}
|
}
|
||||||
if (coefficient == 0) {
|
if (coefficient == 0) {
|
||||||
return zero_;
|
return zero;
|
||||||
}
|
}
|
||||||
ArrayRef<int> coefficients(new Array<int>(degree + 1));
|
ArrayRef<int> coefficients(new Array<int>(degree + 1));
|
||||||
coefficients[0] = coefficient;
|
coefficients[0] = coefficient;
|
||||||
|
|
||||||
//return new GenericGFPoly(this, coefficients);
|
|
||||||
return Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), coefficients));
|
return Ref<GenericGFPoly>(new GenericGFPoly(Ref<GenericGF>(this), coefficients));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ int GenericGF::addOrSubtract(int a, int b) {
|
||||||
|
|
||||||
int GenericGF::exp(int a) {
|
int GenericGF::exp(int a) {
|
||||||
checkInit();
|
checkInit();
|
||||||
return expTable_[a];
|
return expTable[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GenericGF::log(int a) {
|
int GenericGF::log(int a) {
|
||||||
|
@ -121,7 +120,7 @@ int GenericGF::log(int a) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
throw IllegalArgumentException("cannot give log(0)");
|
throw IllegalArgumentException("cannot give log(0)");
|
||||||
}
|
}
|
||||||
return logTable_[a];
|
return logTable[a];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GenericGF::inverse(int a) {
|
int GenericGF::inverse(int a) {
|
||||||
|
@ -129,7 +128,7 @@ int GenericGF::inverse(int a) {
|
||||||
if (a == 0) {
|
if (a == 0) {
|
||||||
throw IllegalArgumentException("Cannot calculate the inverse of 0");
|
throw IllegalArgumentException("Cannot calculate the inverse of 0");
|
||||||
}
|
}
|
||||||
return expTable_[size_ - logTable_[a] - 1];
|
return expTable[size - logTable[a] - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GenericGF::multiply(int a, int b) {
|
int GenericGF::multiply(int a, int b) {
|
||||||
|
@ -139,9 +138,13 @@ int GenericGF::multiply(int a, int b) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return expTable_[(logTable_[a] + logTable_[b]) % (size_ - 1)];
|
return expTable[(logTable[a] + logTable[b]) % (size - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int GenericGF::getSize() {
|
int GenericGF::getSize() {
|
||||||
return size_;
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GenericGF::getGeneratorBase() {
|
||||||
|
return generatorBase;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,13 +31,14 @@ namespace zxing {
|
||||||
class GenericGF : public Counted {
|
class GenericGF : public Counted {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<int> expTable_;
|
std::vector<int> expTable;
|
||||||
std::vector<int> logTable_;
|
std::vector<int> logTable;
|
||||||
Ref<GenericGFPoly> zero_;
|
Ref<GenericGFPoly> zero;
|
||||||
Ref<GenericGFPoly> one_;
|
Ref<GenericGFPoly> one;
|
||||||
int size_;
|
int size;
|
||||||
int primitive_;
|
int primitive;
|
||||||
bool initialized_;
|
int generatorBase;
|
||||||
|
bool initialized;
|
||||||
|
|
||||||
void initialize();
|
void initialize();
|
||||||
void checkInit();
|
void checkInit();
|
||||||
|
@ -50,12 +51,14 @@ namespace zxing {
|
||||||
static Ref<GenericGF> AZTEC_PARAM;
|
static Ref<GenericGF> AZTEC_PARAM;
|
||||||
static Ref<GenericGF> QR_CODE_FIELD_256;
|
static Ref<GenericGF> QR_CODE_FIELD_256;
|
||||||
static Ref<GenericGF> DATA_MATRIX_FIELD_256;
|
static Ref<GenericGF> DATA_MATRIX_FIELD_256;
|
||||||
|
static Ref<GenericGF> MAXICODE_FIELD_64;
|
||||||
|
|
||||||
GenericGF(int primitive, int size);
|
GenericGF(int primitive, int size, int b);
|
||||||
|
|
||||||
Ref<GenericGFPoly> getZero();
|
Ref<GenericGFPoly> getZero();
|
||||||
Ref<GenericGFPoly> getOne();
|
Ref<GenericGFPoly> getOne();
|
||||||
int getSize();
|
int getSize();
|
||||||
|
int getGeneratorBase();
|
||||||
Ref<GenericGFPoly> buildMonomial(int degree, int coefficient);
|
Ref<GenericGFPoly> buildMonomial(int degree, int coefficient);
|
||||||
|
|
||||||
static int addOrSubtract(int a, int b);
|
static int addOrSubtract(int a, int b);
|
||||||
|
@ -63,14 +66,6 @@ namespace zxing {
|
||||||
int log(int a);
|
int log(int a);
|
||||||
int inverse(int a);
|
int inverse(int a);
|
||||||
int multiply(int a, int b);
|
int multiply(int a, int b);
|
||||||
|
|
||||||
bool operator==(GenericGF other) {
|
|
||||||
return (other.getSize() == this->size_ &&
|
|
||||||
other.primitive_ == this->primitive_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//#warning todo: add print method
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,7 @@ using zxing::ArrayRef;
|
||||||
using zxing::ReedSolomonDecoder;
|
using zxing::ReedSolomonDecoder;
|
||||||
using zxing::GenericGFPoly;
|
using zxing::GenericGFPoly;
|
||||||
|
|
||||||
ReedSolomonDecoder::ReedSolomonDecoder(Ref<GenericGF> fld) :
|
ReedSolomonDecoder::ReedSolomonDecoder(Ref<GenericGF> field_) : field(field_) {}
|
||||||
field(fld) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ReedSolomonDecoder::~ReedSolomonDecoder() {
|
ReedSolomonDecoder::~ReedSolomonDecoder() {
|
||||||
}
|
}
|
||||||
|
@ -43,10 +41,9 @@ ReedSolomonDecoder::~ReedSolomonDecoder() {
|
||||||
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
|
void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
|
||||||
Ref<GenericGFPoly> poly(new GenericGFPoly(field, received));
|
Ref<GenericGFPoly> poly(new GenericGFPoly(field, received));
|
||||||
ArrayRef<int> syndromeCoefficients(twoS);
|
ArrayRef<int> syndromeCoefficients(twoS);
|
||||||
bool dataMatrix = (field.object_ == GenericGF::DATA_MATRIX_FIELD_256.object_);
|
|
||||||
bool noError = true;
|
bool noError = true;
|
||||||
for (int i = 0; i < twoS; i++) {
|
for (int i = 0; i < twoS; i++) {
|
||||||
int eval = poly->evaluateAt(field->exp(dataMatrix ? i + 1 : i));
|
int eval = poly->evaluateAt(field->exp(i + field->getGeneratorBase()));
|
||||||
syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval;
|
syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval;
|
||||||
if (eval != 0) {
|
if (eval != 0) {
|
||||||
noError = false;
|
noError = false;
|
||||||
|
@ -61,7 +58,7 @@ void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
|
||||||
Ref<GenericGFPoly> sigma = sigmaOmega[0];
|
Ref<GenericGFPoly> sigma = sigmaOmega[0];
|
||||||
Ref<GenericGFPoly> omega = sigmaOmega[1];
|
Ref<GenericGFPoly> omega = sigmaOmega[1];
|
||||||
ArrayRef<int> errorLocations = findErrorLocations(sigma);
|
ArrayRef<int> errorLocations = findErrorLocations(sigma);
|
||||||
ArrayRef<int> errorMagitudes = findErrorMagnitudes(omega, errorLocations, dataMatrix);
|
ArrayRef<int> errorMagitudes = findErrorMagnitudes(omega, errorLocations);
|
||||||
for (int i = 0; i < errorLocations->size(); i++) {
|
for (int i = 0; i < errorLocations->size(); i++) {
|
||||||
int position = received->size() - 1 - field->log(errorLocations[i]);
|
int position = received->size() - 1 - field->log(errorLocations[i]);
|
||||||
if (position < 0) {
|
if (position < 0) {
|
||||||
|
@ -86,7 +83,6 @@ vector<Ref<GenericGFPoly> > ReedSolomonDecoder::runEuclideanAlgorithm(Ref<Generi
|
||||||
Ref<GenericGFPoly> tLast(field->getZero());
|
Ref<GenericGFPoly> tLast(field->getZero());
|
||||||
Ref<GenericGFPoly> t(field->getOne());
|
Ref<GenericGFPoly> t(field->getOne());
|
||||||
|
|
||||||
|
|
||||||
// Run Euclidean algorithm until r's degree is less than R/2
|
// Run Euclidean algorithm until r's degree is less than R/2
|
||||||
while (r->getDegree() >= R / 2) {
|
while (r->getDegree() >= R / 2) {
|
||||||
Ref<GenericGFPoly> rLastLast(rLast);
|
Ref<GenericGFPoly> rLastLast(rLast);
|
||||||
|
@ -94,14 +90,13 @@ vector<Ref<GenericGFPoly> > ReedSolomonDecoder::runEuclideanAlgorithm(Ref<Generi
|
||||||
rLast = r;
|
rLast = r;
|
||||||
tLast = t;
|
tLast = t;
|
||||||
|
|
||||||
|
|
||||||
// Divide rLastLast by rLast, with quotient q and remainder r
|
// Divide rLastLast by rLast, with quotient q and remainder r
|
||||||
if (rLast->isZero()) {
|
if (rLast->isZero()) {
|
||||||
// Oops, Euclidean algorithm already terminated?
|
// Oops, Euclidean algorithm already terminated?
|
||||||
throw ReedSolomonException("r_{i-1} was zero");
|
throw ReedSolomonException("r_{i-1} was zero");
|
||||||
}
|
}
|
||||||
r = rLastLast;
|
r = rLastLast;
|
||||||
Ref<GenericGFPoly> q(field->getZero());
|
Ref<GenericGFPoly> q = field->getZero();
|
||||||
int denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree());
|
int denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree());
|
||||||
int dltInverse = field->inverse(denominatorLeadingTerm);
|
int dltInverse = field->inverse(denominatorLeadingTerm);
|
||||||
while (r->getDegree() >= rLast->getDegree() && !r->isZero()) {
|
while (r->getDegree() >= rLast->getDegree() && !r->isZero()) {
|
||||||
|
@ -112,7 +107,6 @@ vector<Ref<GenericGFPoly> > ReedSolomonDecoder::runEuclideanAlgorithm(Ref<Generi
|
||||||
}
|
}
|
||||||
|
|
||||||
t = q->multiply(tLast)->addOrSubtract(tLastLast);
|
t = q->multiply(tLast)->addOrSubtract(tLastLast);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sigmaTildeAtZero = t->getCoefficient(0);
|
int sigmaTildeAtZero = t->getCoefficient(0);
|
||||||
|
@ -123,17 +117,6 @@ vector<Ref<GenericGFPoly> > ReedSolomonDecoder::runEuclideanAlgorithm(Ref<Generi
|
||||||
int inverse = field->inverse(sigmaTildeAtZero);
|
int inverse = field->inverse(sigmaTildeAtZero);
|
||||||
Ref<GenericGFPoly> sigma(t->multiply(inverse));
|
Ref<GenericGFPoly> sigma(t->multiply(inverse));
|
||||||
Ref<GenericGFPoly> omega(r->multiply(inverse));
|
Ref<GenericGFPoly> omega(r->multiply(inverse));
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
#ifdef DEBUG
|
|
||||||
cout << "t = " << *t << endl;
|
|
||||||
cout << "r = " << *r << "\n";
|
|
||||||
cout << "sigma = " << *sigma << endl;
|
|
||||||
cout << "omega = " << *omega << endl;
|
|
||||||
#endif
|
|
||||||
*/
|
|
||||||
|
|
||||||
vector<Ref<GenericGFPoly> > result(2);
|
vector<Ref<GenericGFPoly> > result(2);
|
||||||
result[0] = sigma;
|
result[0] = sigma;
|
||||||
result[1] = omega;
|
result[1] = omega;
|
||||||
|
@ -151,7 +134,6 @@ ArrayRef<int> ReedSolomonDecoder::findErrorLocations(Ref<GenericGFPoly> errorLoc
|
||||||
ArrayRef<int> result(new Array<int>(numErrors));
|
ArrayRef<int> result(new Array<int>(numErrors));
|
||||||
int e = 0;
|
int e = 0;
|
||||||
for (int i = 1; i < field->getSize() && e < numErrors; i++) {
|
for (int i = 1; i < field->getSize() && e < numErrors; i++) {
|
||||||
// cout << "errorLocator(" << i << ") == " << errorLocator->evaluateAt(i) << endl;
|
|
||||||
if (errorLocator->evaluateAt(i) == 0) {
|
if (errorLocator->evaluateAt(i) == 0) {
|
||||||
result[e] = field->inverse(i);
|
result[e] = field->inverse(i);
|
||||||
e++;
|
e++;
|
||||||
|
@ -163,7 +145,7 @@ ArrayRef<int> ReedSolomonDecoder::findErrorLocations(Ref<GenericGFPoly> errorLoc
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GenericGFPoly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix) {
|
ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GenericGFPoly> errorEvaluator, ArrayRef<int> errorLocations) {
|
||||||
// This is directly applying Forney's Formula
|
// This is directly applying Forney's Formula
|
||||||
int s = errorLocations.size();
|
int s = errorLocations.size();
|
||||||
ArrayRef<int> result(new Array<int>(s));
|
ArrayRef<int> result(new Array<int>(s));
|
||||||
|
@ -172,13 +154,14 @@ ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GenericGFPoly> errorEv
|
||||||
int denominator = 1;
|
int denominator = 1;
|
||||||
for (int j = 0; j < s; j++) {
|
for (int j = 0; j < s; j++) {
|
||||||
if (i != j) {
|
if (i != j) {
|
||||||
denominator = field->multiply(denominator, GenericGF::addOrSubtract(1, field->multiply(errorLocations[j],
|
int term = field->multiply(errorLocations[j], xiInverse);
|
||||||
xiInverse)));
|
int termPlus1 = (term & 0x1) == 0 ? term | 1 : term & ~1;
|
||||||
|
denominator = field->multiply(denominator, termPlus1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result[i] = field->multiply(errorEvaluator->evaluateAt(xiInverse), field->inverse(denominator));
|
result[i] = field->multiply(errorEvaluator->evaluateAt(xiInverse),
|
||||||
|
field->inverse(denominator));
|
||||||
if (dataMatrix) {
|
if (field->getGeneratorBase() != 0) {
|
||||||
result[i] = field->multiply(result[i], xiInverse);
|
result[i] = field->multiply(result[i], xiInverse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
private:
|
private:
|
||||||
std::vector<Ref<GenericGFPoly> > runEuclideanAlgorithm(Ref<GenericGFPoly> a, Ref<GenericGFPoly> b, int R);
|
std::vector<Ref<GenericGFPoly> > runEuclideanAlgorithm(Ref<GenericGFPoly> a, Ref<GenericGFPoly> b, int R);
|
||||||
ArrayRef<int> findErrorLocations(Ref<GenericGFPoly> errorLocator);
|
ArrayRef<int> findErrorLocations(Ref<GenericGFPoly> errorLocator);
|
||||||
ArrayRef<int> findErrorMagnitudes(Ref<GenericGFPoly> errorEvaluator, ArrayRef<int> errorLocations, bool dataMatrix);
|
ArrayRef<int> findErrorMagnitudes(Ref<GenericGFPoly> errorEvaluator, ArrayRef<int> errorLocations);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,28 +36,28 @@ Ref<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints)
|
||||||
Ref<BinaryBitmap> topLeft = image->crop(0, 0, halfWidth, halfHeight);
|
Ref<BinaryBitmap> topLeft = image->crop(0, 0, halfWidth, halfHeight);
|
||||||
try {
|
try {
|
||||||
return delegate_.decode(topLeft, hints);
|
return delegate_.decode(topLeft, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BinaryBitmap> topRight = image->crop(halfWidth, 0, halfWidth, halfHeight);
|
Ref<BinaryBitmap> topRight = image->crop(halfWidth, 0, halfWidth, halfHeight);
|
||||||
try {
|
try {
|
||||||
return delegate_.decode(topRight, hints);
|
return delegate_.decode(topRight, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BinaryBitmap> bottomLeft = image->crop(0, halfHeight, halfWidth, halfHeight);
|
Ref<BinaryBitmap> bottomLeft = image->crop(0, halfHeight, halfWidth, halfHeight);
|
||||||
try {
|
try {
|
||||||
return delegate_.decode(bottomLeft, hints);
|
return delegate_.decode(bottomLeft, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BinaryBitmap> bottomRight = image->crop(halfWidth, halfHeight, halfWidth, halfHeight);
|
Ref<BinaryBitmap> bottomRight = image->crop(halfWidth, halfHeight, halfWidth, halfHeight);
|
||||||
try {
|
try {
|
||||||
return delegate_.decode(bottomRight, hints);
|
return delegate_.decode(bottomRight, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ void GenericMultipleBarcodeReader::doDecodeMultiple(Ref<BinaryBitmap> image,
|
||||||
Ref<Result> result;
|
Ref<Result> result;
|
||||||
try {
|
try {
|
||||||
result = delegate_.decode(image, hints);
|
result = delegate_.decode(image, hints);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool alreadyFound = false;
|
bool alreadyFound = false;
|
||||||
|
|
|
@ -43,7 +43,7 @@ std::vector<Ref<Result> > QRCodeMultiReader::decodeMultiple(Ref<BinaryBitmap> im
|
||||||
// result->putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult->getByteSegments());
|
// result->putMetadata(ResultMetadataType.BYTE_SEGMENTS, decoderResult->getByteSegments());
|
||||||
// result->putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult->getECLevel().toString());
|
// result->putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult->getECLevel().toString());
|
||||||
results.push_back(result);
|
results.push_back(result);
|
||||||
} catch (ReaderException re) {
|
} catch (ReaderException const& re) {
|
||||||
// ignore and continue
|
// ignore and continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ std::vector<Ref<DetectorResult> > MultiDetector::detectMulti(DecodeHints hints){
|
||||||
for(unsigned int i = 0; i < info.size(); i++){
|
for(unsigned int i = 0; i < info.size(); i++){
|
||||||
try{
|
try{
|
||||||
result.push_back(processFinderPatternInfo(info[i]));
|
result.push_back(processFinderPatternInfo(info[i]));
|
||||||
} catch (ReaderException e){
|
} catch (ReaderException const& e){
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CodaBarReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/CodaBarReader.h>
|
||||||
#include <zxing/oned/OneDResultPoint.h>
|
#include <zxing/oned/OneDResultPoint.h>
|
||||||
#include <zxing/common/Array.h>
|
#include <zxing/common/Array.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
@ -77,6 +78,7 @@ using namespace std;
|
||||||
|
|
||||||
Ref<Result> CodaBarReader::decodeRow(int rowNumber,
|
Ref<Result> CodaBarReader::decodeRow(int rowNumber,
|
||||||
Ref<BitArray> row) {
|
Ref<BitArray> row) {
|
||||||
|
|
||||||
// cerr << "cbr " << rowNumber << " " << *row << endl;
|
// cerr << "cbr " << rowNumber << " " << *row << endl;
|
||||||
setCounters(row);
|
setCounters(row);
|
||||||
int startOffset = findStartPattern();
|
int startOffset = findStartPattern();
|
||||||
|
@ -86,7 +88,7 @@ Ref<Result> CodaBarReader::decodeRow(int rowNumber,
|
||||||
do {
|
do {
|
||||||
int charOffset = toNarrowWidePattern(nextStart);
|
int charOffset = toNarrowWidePattern(nextStart);
|
||||||
if (charOffset == -1) {
|
if (charOffset == -1) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
// Hack: We store the position in the alphabet table into a
|
// Hack: We store the position in the alphabet table into a
|
||||||
// StringBuilder, so that we can access the decoded patterns in
|
// StringBuilder, so that we can access the decoded patterns in
|
||||||
|
@ -111,7 +113,7 @@ Ref<Result> CodaBarReader::decodeRow(int rowNumber,
|
||||||
// otherwise this is probably a false positive. The exception is if we are
|
// otherwise this is probably a false positive. The exception is if we are
|
||||||
// at the end of the row. (I.e. the barcode barely fits.)
|
// at the end of the row. (I.e. the barcode barely fits.)
|
||||||
if (nextStart < counterLength && trailingWhitespace < lastPatternSize / 2) {
|
if (nextStart < counterLength && trailingWhitespace < lastPatternSize / 2) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
validatePattern(startOffset);
|
validatePattern(startOffset);
|
||||||
|
@ -123,21 +125,21 @@ Ref<Result> CodaBarReader::decodeRow(int rowNumber,
|
||||||
// Ensure a valid start and end character
|
// Ensure a valid start and end character
|
||||||
char startchar = decodeRowResult[0];
|
char startchar = decodeRowResult[0];
|
||||||
if (!arrayContains(STARTEND_ENCODING, startchar)) {
|
if (!arrayContains(STARTEND_ENCODING, startchar)) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
char endchar = decodeRowResult[decodeRowResult.length() - 1];
|
char endchar = decodeRowResult[decodeRowResult.length() - 1];
|
||||||
if (!arrayContains(STARTEND_ENCODING, endchar)) {
|
if (!arrayContains(STARTEND_ENCODING, endchar)) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove stop/start characters character and check if a long enough string is contained
|
// remove stop/start characters character and check if a long enough string is contained
|
||||||
if ((int)decodeRowResult.length() <= MIN_CHARACTER_LENGTH) {
|
if ((int)decodeRowResult.length() <= MIN_CHARACTER_LENGTH) {
|
||||||
// Almost surely a false positive ( start + stop + at least 1 character)
|
// Almost surely a false positive ( start + stop + at least 1 character)
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeRowResult.erase(decodeRowResult.length() - 1, 1);
|
decodeRowResult.erase(decodeRowResult.length() - 1, 1);
|
||||||
decodeRowResult.erase(0, 1);
|
decodeRowResult.erase(0, 1);
|
||||||
|
|
||||||
int runningCount = 0;
|
int runningCount = 0;
|
||||||
for (int i = 0; i < startOffset; i++) {
|
for (int i = 0; i < startOffset; i++) {
|
||||||
|
@ -155,13 +157,10 @@ decodeRowResult.erase(0, 1);
|
||||||
resultPoints[1] =
|
resultPoints[1] =
|
||||||
Ref<OneDResultPoint>(new OneDResultPoint(right, (float) rowNumber));
|
Ref<OneDResultPoint>(new OneDResultPoint(right, (float) rowNumber));
|
||||||
|
|
||||||
return Ref<Result>(
|
return Ref<Result>(new Result(Ref<String>(new String(decodeRowResult)),
|
||||||
new Result(
|
ArrayRef<char>(),
|
||||||
Ref<String>(new String(decodeRowResult)),
|
resultPoints,
|
||||||
ArrayRef<char>(),
|
BarcodeFormat::CODABAR));
|
||||||
resultPoints,
|
|
||||||
BarcodeFormat::CODABAR)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodaBarReader::validatePattern(int start) {
|
void CodaBarReader::validatePattern(int start) {
|
||||||
|
@ -214,7 +213,7 @@ void CodaBarReader::validatePattern(int start) {
|
||||||
int category = (j & 1) + (pattern & 1) * 2;
|
int category = (j & 1) + (pattern & 1) * 2;
|
||||||
int size = counters[pos + j] << INTEGER_MATH_SHIFT;
|
int size = counters[pos + j] << INTEGER_MATH_SHIFT;
|
||||||
if (size < mins[category] || size > maxes[category]) {
|
if (size < mins[category] || size > maxes[category]) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
pattern >>= 1;
|
pattern >>= 1;
|
||||||
}
|
}
|
||||||
|
@ -237,7 +236,7 @@ void CodaBarReader::setCounters(Ref<BitArray> row) {
|
||||||
int i = row->getNextUnset(0);
|
int i = row->getNextUnset(0);
|
||||||
int end = row->getSize();
|
int end = row->getSize();
|
||||||
if (i >= end) {
|
if (i >= end) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
bool isWhite = true;
|
bool isWhite = true;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
@ -277,49 +276,59 @@ int CodaBarReader::findStartPattern() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CodaBarReader::arrayContains(char const array[], char key) {
|
bool CodaBarReader::arrayContains(char const array[], char key) {
|
||||||
return index(array, key) != 0;
|
return index(array, key) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assumes that counters[position] is a bar.
|
|
||||||
int CodaBarReader::toNarrowWidePattern(int position) {
|
int CodaBarReader::toNarrowWidePattern(int position) {
|
||||||
int end = position + 7;
|
int end = position + 7;
|
||||||
if (end >= counterLength) {
|
if (end >= counterLength) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// First element is for bars, second is for spaces.
|
|
||||||
vector<int> maxes (2, 0);
|
|
||||||
vector<int> mins (2, std::numeric_limits<int>::max());
|
|
||||||
vector<int> thresholds (2, 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
vector<int>& theCounters = counters;
|
||||||
for (int j = position + i; j < end; j += 2) {
|
|
||||||
if (counters[j] < mins[i]) {
|
int maxBar = 0;
|
||||||
mins[i] = counters[j];
|
int minBar = std::numeric_limits<int>::max();
|
||||||
}
|
for (int j = position; j < end; j += 2) {
|
||||||
if (counters[j] > maxes[i]) {
|
int currentCounter = theCounters[j];
|
||||||
maxes[i] = counters[j];
|
if (currentCounter < minBar) {
|
||||||
}
|
minBar = currentCounter;
|
||||||
|
}
|
||||||
|
if (currentCounter > maxBar) {
|
||||||
|
maxBar = currentCounter;
|
||||||
}
|
}
|
||||||
thresholds[i] = (mins[i] + maxes[i]) / 2;
|
|
||||||
}
|
}
|
||||||
|
int thresholdBar = (minBar + maxBar) / 2;
|
||||||
|
|
||||||
|
int maxSpace = 0;
|
||||||
|
int minSpace = std::numeric_limits<int>::max();
|
||||||
|
for (int j = position + 1; j < end; j += 2) {
|
||||||
|
int currentCounter = theCounters[j];
|
||||||
|
if (currentCounter < minSpace) {
|
||||||
|
minSpace = currentCounter;
|
||||||
|
}
|
||||||
|
if (currentCounter > maxSpace) {
|
||||||
|
maxSpace = currentCounter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int thresholdSpace = (minSpace + maxSpace) / 2;
|
||||||
|
|
||||||
int bitmask = 1 << 7;
|
int bitmask = 1 << 7;
|
||||||
int pattern = 0;
|
int pattern = 0;
|
||||||
for (int i = 0; i < 7; i++) {
|
for (int i = 0; i < 7; i++) {
|
||||||
int barOrSpace = i & 1;
|
int threshold = (i & 1) == 0 ? thresholdBar : thresholdSpace;
|
||||||
bitmask >>= 1;
|
bitmask >>= 1;
|
||||||
if (counters[position + i] > thresholds[barOrSpace]) {
|
if (theCounters[position + i] > threshold) {
|
||||||
pattern |= bitmask;
|
pattern |= bitmask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0;
|
for (int i = 0; i < ZXING_ARRAY_LEN(CHARACTER_ENCODINGS); i++) {
|
||||||
i < (int)(sizeof(CHARACTER_ENCODINGS)/sizeof(CHARACTER_ENCODINGS[0]));
|
|
||||||
i++) {
|
|
||||||
if (CHARACTER_ENCODINGS[i] == pattern) {
|
if (CHARACTER_ENCODINGS[i] == pattern) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ Ref<Result> Code93Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
recordPattern(row, nextStart, counters);
|
recordPattern(row, nextStart, counters);
|
||||||
int pattern = toPattern(counters);
|
int pattern = toPattern(counters);
|
||||||
if (pattern < 0) {
|
if (pattern < 0) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
decodedChar = patternToChar(pattern);
|
decodedChar = patternToChar(pattern);
|
||||||
result.append(1, decodedChar);
|
result.append(1, decodedChar);
|
||||||
|
@ -85,12 +85,12 @@ Ref<Result> Code93Reader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
|
|
||||||
// Should be at least one more black module
|
// Should be at least one more black module
|
||||||
if (nextStart == end || !row->get(nextStart)) {
|
if (nextStart == end || !row->get(nextStart)) {
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.length() < 2) {
|
if (result.length() < 2) {
|
||||||
// false positive -- need at least 2 checksum digits
|
// false positive -- need at least 2 checksum digits
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkChecksums(result);
|
checkChecksums(result);
|
||||||
|
@ -147,7 +147,7 @@ Code93Reader::Range Code93Reader::findAsteriskPattern(Ref<BitArray> row) {
|
||||||
isWhite = !isWhite;
|
isWhite = !isWhite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Code93Reader::toPattern(vector<int>& counters) {
|
int Code93Reader::toPattern(vector<int>& counters) {
|
||||||
|
@ -183,7 +183,7 @@ char Code93Reader::patternToChar(int pattern) {
|
||||||
return ALPHABET[i];
|
return ALPHABET[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<String> Code93Reader::decodeExtended(string const& encoded) {
|
Ref<String> Code93Reader::decodeExtended(string const& encoded) {
|
||||||
|
|
|
@ -34,12 +34,6 @@ EAN13Reader::EAN13Reader() : decodeMiddleCounters(4, 0) { }
|
||||||
int EAN13Reader::decodeMiddle(Ref<BitArray> row,
|
int EAN13Reader::decodeMiddle(Ref<BitArray> row,
|
||||||
Range const& startRange,
|
Range const& startRange,
|
||||||
std::string& resultString) {
|
std::string& resultString) {
|
||||||
if (false) {
|
|
||||||
std::cerr << "ba "
|
|
||||||
<< startRange[0] << " "
|
|
||||||
<< startRange[1] << " "
|
|
||||||
<< *row << std::endl;
|
|
||||||
}
|
|
||||||
vector<int>& counters (decodeMiddleCounters);
|
vector<int>& counters (decodeMiddleCounters);
|
||||||
counters.clear();
|
counters.clear();
|
||||||
counters.resize(4);
|
counters.resize(4);
|
||||||
|
@ -83,7 +77,7 @@ void EAN13Reader::determineFirstDigit(std::string& resultString, int lgPatternFo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw NotFoundException::getNotFoundInstance();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
zxing::BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
zxing::BarcodeFormat EAN13Reader::getBarcodeFormat(){
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ITFReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/ITFReader.h>
|
||||||
#include <zxing/oned/OneDResultPoint.h>
|
#include <zxing/oned/OneDResultPoint.h>
|
||||||
#include <zxing/common/Array.h>
|
#include <zxing/common/Array.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
@ -107,6 +108,7 @@ Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lengthOK) {
|
if (!lengthOK) {
|
||||||
throw FormatException();
|
throw FormatException();
|
||||||
}
|
}
|
||||||
|
@ -114,6 +116,7 @@ Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
ArrayRef< Ref<ResultPoint> > resultPoints(2);
|
ArrayRef< Ref<ResultPoint> > resultPoints(2);
|
||||||
resultPoints[0] = Ref<OneDResultPoint>(new OneDResultPoint(startRange[1], (float) rowNumber));
|
resultPoints[0] = Ref<OneDResultPoint>(new OneDResultPoint(startRange[1], (float) rowNumber));
|
||||||
resultPoints[1] = Ref<OneDResultPoint>(new OneDResultPoint(endRange[0], (float) rowNumber));
|
resultPoints[1] = Ref<OneDResultPoint>(new OneDResultPoint(endRange[0], (float) rowNumber));
|
||||||
|
|
||||||
return Ref<Result>(new Result(resultString, ArrayRef<char>(), resultPoints, BarcodeFormat::ITF));
|
return Ref<Result>(new Result(resultString, ArrayRef<char>(), resultPoints, BarcodeFormat::ITF));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,21 +230,18 @@ ITFReader::Range ITFReader::decodeEnd(Ref<BitArray> row) {
|
||||||
* @throws ReaderException if the quiet zone cannot be found, a ReaderException is thrown.
|
* @throws ReaderException if the quiet zone cannot be found, a ReaderException is thrown.
|
||||||
*/
|
*/
|
||||||
void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern) {
|
void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern) {
|
||||||
(void)row;
|
int quietCount = this->narrowLineWidth * 10; // expect to find this many pixels of quiet zone
|
||||||
(void)startPattern;
|
|
||||||
//#pragma mark needs some corrections
|
for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--) {
|
||||||
// int quietCount = narrowLineWidth * 10; // expect to find this many pixels of quiet zone
|
if (row->get(i)) {
|
||||||
//
|
break;
|
||||||
// for (int i = startPattern - 1; quietCount > 0 && i >= 0; i--) {
|
}
|
||||||
// if (row->get(i)) {
|
quietCount--;
|
||||||
// break;
|
}
|
||||||
// }
|
if (quietCount != 0) {
|
||||||
// quietCount--;
|
// Unable to find the necessary number of quiet zone pixels.
|
||||||
// }
|
throw NotFoundException();
|
||||||
// if (quietCount != 0) {
|
}
|
||||||
// // Unable to find the necessary number of quiet zone pixels.
|
|
||||||
// throw ReaderException("Unable to find the necessary number of quiet zone pixels");
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -253,15 +253,9 @@ void ITFReader::validateQuietZone(Ref<BitArray> row, int startPattern) {
|
||||||
*/
|
*/
|
||||||
int ITFReader::skipWhiteSpace(Ref<BitArray> row) {
|
int ITFReader::skipWhiteSpace(Ref<BitArray> row) {
|
||||||
int width = row->getSize();
|
int width = row->getSize();
|
||||||
int endStart = 0;
|
int endStart = row->getNextSet(0);
|
||||||
while (endStart < width) {
|
|
||||||
if (row->get(endStart)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
endStart++;
|
|
||||||
}
|
|
||||||
if (endStart == width) {
|
if (endStart == width) {
|
||||||
throw ReaderException("");
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
return endStart;
|
return endStart;
|
||||||
}
|
}
|
||||||
|
@ -281,7 +275,7 @@ ITFReader::Range ITFReader::findGuardPattern(Ref<BitArray> row,
|
||||||
// TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
|
// TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
|
||||||
// merged to a single method.
|
// merged to a single method.
|
||||||
int patternLength = pattern.size();
|
int patternLength = pattern.size();
|
||||||
vector<int> counters(patternLength, 0);
|
vector<int> counters(patternLength);
|
||||||
int width = row->getSize();
|
int width = row->getSize();
|
||||||
bool isWhite = false;
|
bool isWhite = false;
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "MultiFormatOneDReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/MultiFormatOneDReader.h>
|
||||||
#include <zxing/oned/MultiFormatUPCEANReader.h>
|
#include <zxing/oned/MultiFormatUPCEANReader.h>
|
||||||
#include <zxing/oned/Code39Reader.h>
|
#include <zxing/oned/Code39Reader.h>
|
||||||
#include <zxing/oned/Code128Reader.h>
|
#include <zxing/oned/Code128Reader.h>
|
||||||
|
@ -84,15 +84,11 @@ Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
OneDReader* reader = readers[i];
|
OneDReader* reader = readers[i];
|
||||||
try {
|
try {
|
||||||
// std::cerr << "v 1 " << typeid(*reader).name() << " " << rowNumber << std::endl;
|
|
||||||
Ref<Result> result = reader->decodeRow(rowNumber, row);
|
Ref<Result> result = reader->decodeRow(rowNumber, row);
|
||||||
// std::cerr << "^ 1 " << typeid(*reader).name() << " " << rowNumber << std::endl;
|
|
||||||
return result;
|
return result;
|
||||||
} catch (ReaderException const& re) {
|
} catch (ReaderException const& re) {
|
||||||
// std::cerr << "^ * " << typeid(*reader).name() << " " << rowNumber << std::endl;
|
|
||||||
// continue
|
// continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// std::cerr << "throwing nfe" << std::endl;
|
|
||||||
throw NotFoundException();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#include "MultiFormatUPCEANReader.h"
|
|
||||||
|
|
||||||
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/MultiFormatUPCEANReader.h>
|
||||||
#include <zxing/oned/EAN13Reader.h>
|
#include <zxing/oned/EAN13Reader.h>
|
||||||
#include <zxing/oned/EAN8Reader.h>
|
#include <zxing/oned/EAN8Reader.h>
|
||||||
#include <zxing/oned/UPCEReader.h>
|
#include <zxing/oned/UPCEReader.h>
|
||||||
|
@ -59,12 +60,10 @@ MultiFormatUPCEANReader::MultiFormatUPCEANReader(DecodeHints hints) : readers()
|
||||||
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
// Compute this location once and reuse it on multiple implementations
|
// Compute this location once and reuse it on multiple implementations
|
||||||
UPCEANReader::Range startGuardPattern = UPCEANReader::findStartGuardPattern(row);
|
UPCEANReader::Range startGuardPattern = UPCEANReader::findStartGuardPattern(row);
|
||||||
// std::cerr << "sgp " << startGuardPattern[0] << " " << startGuardPattern[1] << std::endl;
|
|
||||||
for (int i = 0, e = readers.size(); i < e; i++) {
|
for (int i = 0, e = readers.size(); i < e; i++) {
|
||||||
Ref<UPCEANReader> reader = readers[i];
|
Ref<UPCEANReader> reader = readers[i];
|
||||||
Ref<Result> result;
|
Ref<Result> result;
|
||||||
try {
|
try {
|
||||||
// std::cerr << typeid(*reader).name() << " " << rowNumber << std::endl;
|
|
||||||
result = reader->decodeRow(rowNumber, row, startGuardPattern);
|
result = reader->decodeRow(rowNumber, row, startGuardPattern);
|
||||||
} catch (ReaderException const& re) {
|
} catch (ReaderException const& re) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "OneDReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/OneDReader.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
#include <zxing/oned/OneDResultPoint.h>
|
#include <zxing/oned/OneDResultPoint.h>
|
||||||
#include <zxing/NotFoundException.h>
|
#include <zxing/NotFoundException.h>
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "UPCEANReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/UPCEANReader.h>
|
||||||
#include <zxing/oned/OneDResultPoint.h>
|
#include <zxing/oned/OneDResultPoint.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
#include <zxing/NotFoundException.h>
|
#include <zxing/NotFoundException.h>
|
||||||
|
@ -116,13 +117,8 @@ Ref<Result> UPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row) {
|
||||||
Ref<Result> UPCEANReader::decodeRow(int rowNumber,
|
Ref<Result> UPCEANReader::decodeRow(int rowNumber,
|
||||||
Ref<BitArray> row,
|
Ref<BitArray> row,
|
||||||
Range const& startGuardRange) {
|
Range const& startGuardRange) {
|
||||||
if (false) {
|
|
||||||
std::cerr << "dR " << rowNumber << " " << *row << " "
|
|
||||||
<< startGuardRange[0] << " " << startGuardRange[1] << std::endl;
|
|
||||||
}
|
|
||||||
string& result = decodeRowStringBuffer;
|
string& result = decodeRowStringBuffer;
|
||||||
result.clear();
|
result.clear();
|
||||||
// cerr << "drx " << rowNumber << endl;
|
|
||||||
int endStart = decodeMiddle(row, startGuardRange, result);
|
int endStart = decodeMiddle(row, startGuardRange, result);
|
||||||
|
|
||||||
Range endRange = decodeEnd(row, endStart);
|
Range endRange = decodeEnd(row, endStart);
|
||||||
|
@ -135,7 +131,7 @@ Ref<Result> UPCEANReader::decodeRow(int rowNumber,
|
||||||
if (quietEnd >= row->getSize() || !row->isRange(end, quietEnd, false)) {
|
if (quietEnd >= row->getSize() || !row->isRange(end, quietEnd, false)) {
|
||||||
throw NotFoundException();
|
throw NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<String> resultString (new String(result));
|
Ref<String> resultString (new String(result));
|
||||||
if (!checkChecksum(resultString)) {
|
if (!checkChecksum(resultString)) {
|
||||||
throw ChecksumException();
|
throw ChecksumException();
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "UPCEReader.h"
|
#include <zxing/ZXing.h>
|
||||||
|
#include <zxing/oned/UPCEReader.h>
|
||||||
#include <zxing/ReaderException.h>
|
#include <zxing/ReaderException.h>
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
|
@ -365,7 +365,7 @@ DecodedBitStreamParser::decode(ArrayRef<char> bytes,
|
||||||
fc1InEffect = true;
|
fc1InEffect = true;
|
||||||
} else if (mode == &Mode::STRUCTURED_APPEND) {
|
} else if (mode == &Mode::STRUCTURED_APPEND) {
|
||||||
if (bits.available() < 16) {
|
if (bits.available() < 16) {
|
||||||
throw new FormatException();
|
throw FormatException();
|
||||||
}
|
}
|
||||||
// not really supported; all we do is ignore it
|
// not really supported; all we do is ignore it
|
||||||
// Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
|
// Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
|
||||||
|
|
|
@ -96,7 +96,7 @@ void ReedSolomonTest::testTooManyErrors() {
|
||||||
checkQRRSDecode(received);
|
checkQRRSDecode(received);
|
||||||
cout << "expected exception!\n";
|
cout << "expected exception!\n";
|
||||||
CPPUNIT_FAIL("should not happen!");
|
CPPUNIT_FAIL("should not happen!");
|
||||||
} catch (ReedSolomonException e) {
|
} catch (ReedSolomonException const& e) {
|
||||||
// expected
|
// expected
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
CPPUNIT_FAIL("unexpected exception!");
|
CPPUNIT_FAIL("unexpected exception!");
|
||||||
|
|
|
@ -39,7 +39,7 @@ void ErrorCorrectionLevelTest::testForBits() {
|
||||||
try {
|
try {
|
||||||
ErrorCorrectionLevel::forBits(4);
|
ErrorCorrectionLevel::forBits(4);
|
||||||
CPPUNIT_FAIL("should have thrown an exception");
|
CPPUNIT_FAIL("should have thrown an exception");
|
||||||
} catch (zxing::ReaderException ex) {
|
} catch (zxing::ReaderException const& ex) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ void VersionTest::testVersionForNumber() {
|
||||||
try {
|
try {
|
||||||
Version::getVersionForNumber(0);
|
Version::getVersionForNumber(0);
|
||||||
CPPUNIT_FAIL("Should have thrown an exception");
|
CPPUNIT_FAIL("Should have thrown an exception");
|
||||||
} catch (zxing::ReaderException re) {
|
} catch (zxing::ReaderException const& re) {
|
||||||
// good
|
// good
|
||||||
}
|
}
|
||||||
for (int i = 1; i <= 40; i++) {
|
for (int i = 1; i <= 40; i++) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ void ModeTest::testForBits() {
|
||||||
try {
|
try {
|
||||||
Mode::forBits(0x10);
|
Mode::forBits(0x10);
|
||||||
CPPUNIT_FAIL("should have thrown an exception");
|
CPPUNIT_FAIL("should have thrown an exception");
|
||||||
} catch (zxing::ReaderException ex) {
|
} catch (zxing::ReaderException const& ex) {
|
||||||
// expected
|
// expected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,16 +98,16 @@ int test_image(Image& image, bool hybrid, string expected = "") {
|
||||||
cell_result = result->getText()->getText();
|
cell_result = result->getText()->getText();
|
||||||
result_format = BarcodeFormat::barcodeFormatNames[result->getBarcodeFormat()];
|
result_format = BarcodeFormat::barcodeFormatNames[result->getBarcodeFormat()];
|
||||||
res = 0;
|
res = 0;
|
||||||
} catch (ReaderException e) {
|
} catch (ReaderException const& e) {
|
||||||
cell_result = "zxing::ReaderException: " + string(e.what());
|
cell_result = "zxing::ReaderException: " + string(e.what());
|
||||||
res = -2;
|
res = -2;
|
||||||
} catch (zxing::IllegalArgumentException& e) {
|
} catch (zxing::IllegalArgumentException const& e) {
|
||||||
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
|
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
|
||||||
res = -3;
|
res = -3;
|
||||||
} catch (zxing::Exception& e) {
|
} catch (zxing::Exception const& e) {
|
||||||
cell_result = "zxing::Exception: " + string(e.what());
|
cell_result = "zxing::Exception: " + string(e.what());
|
||||||
res = -4;
|
res = -4;
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception const& e) {
|
||||||
cell_result = "std::exception: " + string(e.what());
|
cell_result = "std::exception: " + string(e.what());
|
||||||
res = -5;
|
res = -5;
|
||||||
}
|
}
|
||||||
|
@ -162,16 +162,16 @@ int test_image_multi(Image& image, bool hybrid){
|
||||||
Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
|
Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
|
||||||
results = decodeMultiple(binary, hints);
|
results = decodeMultiple(binary, hints);
|
||||||
res = 0;
|
res = 0;
|
||||||
} catch (ReaderException e) {
|
} catch (ReaderException const& e) {
|
||||||
cell_result = "zxing::ReaderException: " + string(e.what());
|
cell_result = "zxing::ReaderException: " + string(e.what());
|
||||||
res = -2;
|
res = -2;
|
||||||
} catch (zxing::IllegalArgumentException& e) {
|
} catch (zxing::IllegalArgumentException const& e) {
|
||||||
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
|
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
|
||||||
res = -3;
|
res = -3;
|
||||||
} catch (zxing::Exception& e) {
|
} catch (zxing::Exception const& e) {
|
||||||
cell_result = "zxing::Exception: " + string(e.what());
|
cell_result = "zxing::Exception: " + string(e.what());
|
||||||
res = -4;
|
res = -4;
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception const& e) {
|
||||||
cell_result = "std::exception: " + string(e.what());
|
cell_result = "std::exception: " + string(e.what());
|
||||||
res = -5;
|
res = -5;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue