Added external lib for QRCode decode and QTMultimedia for Camera

qr-code-scan^2
mrdeveloper 4 years ago committed by tobtoht
parent 485fb89941
commit 442aced06f

@ -5,7 +5,7 @@ set(CMAKE_AUTOUIC ON)
# pthread
find_package(Threads REQUIRED)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets)
find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Network Svg Xml WebSockets Multimedia)
add_subdirectory(libwalletqt)
add_subdirectory(model)
@ -109,6 +109,7 @@ target_include_directories(feather PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/utils
${CMAKE_CURRENT_SOURCE_DIR}/tor
${CMAKE_CURRENT_SOURCE_DIR}/qrcode
${CMAKE_CURRENT_SOURCE_DIR}/qzxing
${X11_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
@ -119,6 +120,7 @@ target_include_directories(feather PUBLIC
${Qt5Svg_INCLUDE_DIRS}
${Qt5Xml_INCLUDE_DIRS}
${Qt5WebSockets_INCLUDE_DIRS}
${Qt5Multimedia_INCLUDE_DIRS}
)
if(DONATE_BEG)
@ -195,6 +197,7 @@ target_link_libraries(feather
Qt5::Svg
Qt5::Xml
Qt5::WebSockets
Qt5::Multimedia
${ICU_LIBRARIES}
openpgp
Threads::Threads

@ -0,0 +1,87 @@
cmake_minimum_required(VERSION 3.2)
project(QZXing)
find_package(Qt5 COMPONENTS Core REQUIRED)
find_package(Qt5 COMPONENTS Gui REQUIRED)
find_package(Qt5 COMPONENTS Multimedia )
find_package(Qt5 REQUIRED Svg Quick QuickControls2)
SET(BIGINT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zxing/bigint)
SET(WIN32_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zxing/win32/zxing)
SET(ZXING_DIR ${CMAKE_CURRENT_SOURCE_DIR}/zxing/zxing)
set(CMAKE_AUTOMOC ON)
set(CMAKE_WARN_ON)
set(SOURCES
CameraImageWrapper.cpp
CameraImageWrapper.h
ImageHandler.cpp
ImageHandler.h
QZXing.cpp
QZXing.h
QZXing_global.h
)
if(QZXING_MULTIMEDIA)
LIST(APPEND SOURCES QZXingFilter.cpp QZXingFilter.h)
add_definitions(-DQZXING_MULTIMEDIA)
SET(QZXING_USE_QML ON)
endif(QZXING_MULTIMEDIA)
if(QZXING_USE_QML)
LIST(APPEND SOURCES QZXingImageProvider.cpp QZXingImageProvider.h)
add_definitions(-DQZXING_QML)
endif(QZXING_USE_QML)
add_library(qzxing "" ${SOURCES})
if(WIN32)
add_subdirectory(zxing/win32)
if(MSVC)
add_definitions(-D__STDC_LIMIT_MACROS)
endif(MSVC)
add_definitions(-DNO_ICONV)
endif(WIN32)
if(VS_WINRT_COMPONENT)
add_definitions(-DNO_ICONV)
endif(VS_WINRT_COMPONENT)
add_subdirectory(zxing/bigint)
add_subdirectory(zxing/zxing)
target_link_libraries(qzxing Qt5::Core Qt5::Gui)
if(QZXING_MULTIMEDIA)
target_link_libraries(qzxing Qt5::Multimedia)
endif(QZXING_MULTIMEDIA)
if(QZXING_USE_QML)
target_link_libraries(qzxing
Qt5::Svg
Qt5::Quick
Qt5::QuickControls2)
endif(QZXING_USE_QML)
# Change Global Definitions depending on how you want to use the library
target_compile_definitions(qzxing PUBLIC DISABLE_LIBRARY_FEATURES)
# Target includes
target_include_directories(qzxing
PRIVATE
.
zxing
zxing/win32/zxing
zxing/zxing
zxing/bigint
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

@ -0,0 +1,224 @@
#include "CameraImageWrapper.h"
#include <QColor>
//values based on http://entropymine.com/imageworsener/grayscale/
//round(0,2127*R)
const zxing::byte CameraImageWrapper::R_TO_GREYSCALE[256] = {
0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21,
22, 22, 22, 22, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 25, 25, 25, 25,
26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 29, 29, 29, 29,
30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 33,
34, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37,
38, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41,
42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45,
46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49,
50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 53,
54, 54, 54, 54
};
//values based on http://entropymine.com/imageworsener/grayscale/
//round(0,7152*G)
const zxing::byte CameraImageWrapper::G_TO_GREYSCALE[256] = {
0, 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13,
14, 14, 15, 16, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 24, 24,
25, 26, 26, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35,
36, 36, 37, 38, 39, 39, 40, 41, 41, 42, 43, 44, 44, 45, 46, 46, 47,
48, 49, 49, 50, 51, 51, 52, 53, 54, 54, 55, 56, 57, 57, 58, 59, 59,
60, 61, 62, 62, 63, 64, 64, 65, 66, 67, 67, 68, 69, 69, 70, 71,
72, 72, 73, 74, 74, 75, 76, 77, 77, 78, 79, 79, 80, 81, 82, 82,
83, 84, 84, 85, 86, 87, 87, 88, 89, 89, 90, 91, 92, 92, 93, 94, 94,
95, 96, 97, 97, 98, 99, 99, 100, 101, 102, 102, 103, 104, 104, 105, 106,
107, 107, 108, 109, 109, 110, 111, 112, 112, 113, 114, 114, 115, 116,
117, 117, 118, 119, 119, 120, 121, 122, 122, 123, 124, 124, 125, 126,
127, 127, 128, 129, 129, 130, 131, 132, 132, 133, 134, 134, 135, 136,
137, 137, 138, 139, 139, 140, 141, 142, 142, 143, 144, 144, 145, 146,
147, 147, 148, 149, 149, 150, 151, 152, 152, 153, 154, 154, 155, 156,
157, 157, 158, 159, 159, 160, 161, 162, 162, 163, 164, 164, 165, 166,
167, 167, 168, 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176,
177, 177, 178, 179, 180, 180, 181, 182, 182
};
//values based on http://entropymine.com/imageworsener/grayscale/
//round(0,0722*B)
const zxing::byte CameraImageWrapper::B_TO_GREYSCALE[256] = {
0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18
};
CameraImageWrapper::CameraImageWrapper() : LuminanceSource(0,0)
{
}
CameraImageWrapper::CameraImageWrapper(const QImage &sourceImage) : LuminanceSource(sourceImage.width(), sourceImage.height())
{
updateImageAsGrayscale( sourceImage );
delegate = Ref<GreyscaleLuminanceSource>(
new GreyscaleLuminanceSource(getMatrixP(), sourceImage.width(), sourceImage.height(),0, 0, sourceImage.width(), sourceImage.height()));
}
CameraImageWrapper::CameraImageWrapper(CameraImageWrapper& otherInstance) : LuminanceSource(otherInstance.getWidth(), otherInstance.getHeight())
{
imageBytesPerRow = otherInstance.getOriginalImage();
delegate = otherInstance.getDelegate();
}
CameraImageWrapper::~CameraImageWrapper()
{
}
CameraImageWrapper *CameraImageWrapper::Factory(const QImage &sourceImage, int maxWidth, int maxHeight, bool smoothTransformation)
{
if((maxWidth != -1 && sourceImage.width() > maxWidth) || (maxHeight != -1 && sourceImage.height() > maxHeight))
{
QImage image;
image = sourceImage.scaled(
maxWidth != -1 ? maxWidth : sourceImage.width(),
maxHeight != -1 ? maxHeight : sourceImage.height(),
Qt::KeepAspectRatio,
smoothTransformation ? Qt::SmoothTransformation : Qt::FastTransformation);
return new CameraImageWrapper(image);
}
else
return new CameraImageWrapper(sourceImage);
}
ArrayRef<ArrayRef<zxing::byte> > CameraImageWrapper::getOriginalImage()
{
return imageBytesPerRow;
}
ArrayRef<zxing::byte> CameraImageWrapper::getRow(int y, ArrayRef<zxing::byte> row) const
{
if(delegate)
return delegate->getRow(y, row);
else
return getRowP(y, row);
}
ArrayRef<zxing::byte> CameraImageWrapper::getMatrix() const
{
if(delegate)
return delegate->getMatrix();
else
return getMatrixP();
}
bool CameraImageWrapper::isCropSupported() const
{
if(delegate)
return delegate->isCropSupported();
else
return LuminanceSource::isCropSupported();
}
Ref<LuminanceSource> CameraImageWrapper::crop(int left, int top, int width, int height) const
{
if(delegate)
return delegate->crop(left, top, width, height);
else
return LuminanceSource::crop(left, top, width, height);
}
bool CameraImageWrapper::isRotateSupported() const
{
if(delegate)
return delegate->isRotateSupported();
else
return LuminanceSource::isRotateSupported();
}
Ref<LuminanceSource> CameraImageWrapper::invert() const
{
if(delegate)
return delegate->invert();
else
return LuminanceSource::invert();
}
Ref<LuminanceSource> CameraImageWrapper::rotateCounterClockwise() const
{
if(delegate)
return delegate->rotateCounterClockwise();
else
return LuminanceSource::rotateCounterClockwise();
}
ArrayRef<zxing::byte> CameraImageWrapper::getRowP(int y, ArrayRef<zxing::byte> row) const
{
int width = getWidth();
if (row->size() != width)
row.reset(ArrayRef<zxing::byte>(width));
Q_ASSERT(y >= 0 && y < getHeight());
return imageBytesPerRow[y];
}
ArrayRef<zxing::byte> CameraImageWrapper::getMatrixP() const
{
return imageBytes;
}
zxing::byte CameraImageWrapper::gray(const unsigned int r, const unsigned int g, const unsigned int b)
{
//the values are not masked with (x & 0xFF) because functions qRed, qGreen, qBlue already do it
return R_TO_GREYSCALE[r] + G_TO_GREYSCALE[g] + B_TO_GREYSCALE[b];
}
void CameraImageWrapper::updateImageAsGrayscale(const QImage &origin)
{
bool needsConvesionToGrayscale = origin.format() != QImage::Format_Grayscale8;
QRgb pixel;
zxing::byte pixelGrayscale;
const int width = getWidth();
const int height = getHeight();
imageBytes = ArrayRef<zxing::byte>(height*width);
imageBytesPerRow = ArrayRef<ArrayRef<zxing::byte>>(height);
zxing::byte* m = &imageBytes[0];
for(int j=0; j<height; j++)
{
ArrayRef<zxing::byte> line(width);
for(int i=0; i<width; i++)
{
pixel = origin.pixel(i,j);
if(needsConvesionToGrayscale)
pixelGrayscale = gray(qRed(pixel),qGreen(pixel),qBlue(pixel));
else
pixelGrayscale = pixel & 0xFF;
line[i] = pixelGrayscale;
}
imageBytesPerRow[j] = line;
#if __cplusplus > 199711L
memcpy(m, line->values().data(), width);
#else
memcpy(m, &line[0], width);
#endif
m += width * sizeof(zxing::byte);
}
}

@ -0,0 +1,64 @@
/*
* Copyright 2011 QZXing 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.
*/
#ifndef CAMERAIMAGE_H
#define CAMERAIMAGE_H
#include <QImage>
#include <QString>
#include <zxing/zxing/common/GreyscaleLuminanceSource.h>
using namespace zxing;
class CameraImageWrapper : public LuminanceSource
{
public:
CameraImageWrapper();
CameraImageWrapper(const QImage& sourceImage);
CameraImageWrapper(CameraImageWrapper& otherInstance);
~CameraImageWrapper();
static CameraImageWrapper* Factory(const QImage& image, int maxWidth=-1, int maxHeight=-1, bool smoothTransformation=false);
ArrayRef<ArrayRef<zxing::byte> > getOriginalImage();
Ref<GreyscaleLuminanceSource> getDelegate() { return delegate; }
ArrayRef<zxing::byte> getRow(int y, ArrayRef<zxing::byte> row) const;
ArrayRef<zxing::byte> getMatrix() const;
bool isCropSupported() const;
Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
bool isRotateSupported() const;
Ref<LuminanceSource> invert() const;
Ref<LuminanceSource> rotateCounterClockwise() const;
inline zxing::byte gray(const unsigned int r, const unsigned int g, const unsigned int b);
private:
ArrayRef<zxing::byte> getRowP(int y, ArrayRef<zxing::byte> row) const;
ArrayRef<zxing::byte> getMatrixP() const;
void updateImageAsGrayscale(const QImage &origin);
Ref<GreyscaleLuminanceSource> delegate;
ArrayRef<ArrayRef<zxing::byte>> imageBytesPerRow;
ArrayRef<zxing::byte> imageBytes;
static const zxing::byte B_TO_GREYSCALE[256];
static const zxing::byte G_TO_GREYSCALE[256];
static const zxing::byte R_TO_GREYSCALE[256];
};
#endif //CAMERAIMAGE_H

@ -0,0 +1,106 @@
#include "ImageHandler.h"
#include <QImage>
#include <QPainter>
#include <QDebug>
#include <QThread>
#include <QTime>
#if QT_VERSION < 0x050000
#include <QGraphicsObject>
#include <QStyleOptionGraphicsItem>
#endif // QT_VERSION < Qt 5.0
#if defined(QZXING_QML)
#include <QQuickItem>
#include <QQuickItemGrabResult>
#include <QQuickWindow>
#endif //QZXING_QML
ImageHandler::ImageHandler(QObject *parent) :
QObject(parent)
{
}
QImage ImageHandler::extractQImage(QObject *imageObj, int offsetX, int offsetY, int width, int height)
{
QImage img;
#if defined(QZXING_QML)
#if QT_VERSION >= 0x050000
QQuickItem *item = qobject_cast<QQuickItem *>(imageObj);
if (!item || !item->window()->isVisible()) {
qWarning() << "ImageHandler: item is NULL";
return QImage();
}
QTime timer;
timer.start();
QSharedPointer<QQuickItemGrabResult> result = item->grabToImage();
if (result) {
pendingGrabbersLocker.lockForWrite();
pendingGrabbers << result.data();
pendingGrabbersLocker.unlock();
connect(result.data(), &QQuickItemGrabResult::ready, this, &ImageHandler::imageGrabberReady);
while (timer.elapsed() < 1000) {
pendingGrabbersLocker.lockForRead();
if (!pendingGrabbers.contains(result.data())) {
pendingGrabbersLocker.unlock();
break;
}
pendingGrabbersLocker.unlock();
qApp->processEvents();
QThread::yieldCurrentThread();
}
img = result->image();
}
#else // QT_VERSION >= 0x050000
QGraphicsObject *item = qobject_cast<QGraphicsObject*>(imageObj);
if (!item) {
qWarning() << "ImageHandler: item is NULL";
return QImage();
}
img = QImage(item->boundingRect().size().toSize(), QImage::Format_RGB32);
img.fill(QColor(255, 255, 255).rgb());
QPainter painter(&img);
QStyleOptionGraphicsItem styleOption;
item->paint(&painter, &styleOption);
#endif // QT_VERSION >= 0x050000
#else // defined(QZXING_QML)
Q_UNUSED(imageObj);
#endif // defined(QZXING_QML)
if (offsetX < 0)
offsetX = 0;
if (offsetY < 0)
offsetY = 0;
if (width < 0)
width = 0;
if (height < 0)
height = 0;
if (offsetX || offsetY || width || height)
return img.copy(offsetX, offsetY, width, height);
return img;
}
void ImageHandler::save(QObject *imageObj, const QString &path,
const int offsetX, const int offsetY,
const int width, const int height)
{
QImage img = extractQImage(imageObj, offsetX, offsetY, width, height);
img.save(path);
}
#if QT_VERSION >= 0x050000
void ImageHandler::imageGrabberReady()
{
pendingGrabbersLocker.lockForWrite();
pendingGrabbers.remove(sender());
pendingGrabbersLocker.unlock();
}
#endif

@ -0,0 +1,49 @@
/*
* Copyright 2011 QZXing 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.
*/
#ifndef IMAGEHANDLER_H
#define IMAGEHANDLER_H
#include <QObject>
#include <QImage>
#if QT_VERSION >= 0x050000
#include <QSet>
#include <QReadWriteLock>
#endif
class ImageHandler : public QObject
{
Q_OBJECT
public:
explicit ImageHandler(QObject *parent = 0);
QImage extractQImage(QObject *imageObj,
int offsetX = 0, int offsetY = 0,
int width = 0, int height = 0);
public slots:
void save(QObject *imageObj, const QString &path,
const int offsetX = 0, const int offsetY = 0,
const int width = 0, const int height = 0);
private:
#if QT_VERSION >= 0x050000
void imageGrabberReady();
QSet<QObject *> pendingGrabbers;
QReadWriteLock pendingGrabbersLocker;
#endif
};
#endif // IMAGEHANDLER_H

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

@ -0,0 +1,7 @@
#include "QZXing.h"
#ifdef QZXING_QML
#include "QZXingImageProvider.h"
#endif //QZXING_QML
#ifdef QZXING_MULTIMEDIA
#include "QZXingFilter.h"
#endif //QZXING_MULTIMEDIA

@ -0,0 +1,501 @@
#
# Copyright 2011 QZXing 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.
#
CONFIG += qt warn_on
DEFINES += QZXING_LIBRARY \
ZXING_ICONV_CONST \
DISABLE_LIBRARY_FEATURES
INCLUDEPATH += $$PWD \
$$PWD/zxing
HEADERS += $$PWD/QZXing_global.h \
$$PWD/CameraImageWrapper.h \
$$PWD/ImageHandler.h \
$$PWD/QZXing.h \
$$PWD/zxing/zxing/ZXing.h \
$$PWD/zxing/zxing/IllegalStateException.h \
$$PWD/zxing/zxing/InvertedLuminanceSource.h \
$$PWD/zxing/zxing/ChecksumException.h \
$$PWD/zxing/zxing/ResultPointCallback.h \
$$PWD/zxing/zxing/ResultPoint.h \
$$PWD/zxing/zxing/Result.h \
$$PWD/zxing/zxing/ResultMetadata.h \
$$PWD/zxing/zxing/ReaderException.h \
$$PWD/zxing/zxing/Reader.h \
$$PWD/zxing/zxing/NotFoundException.h \
$$PWD/zxing/zxing/MultiFormatReader.h \
$$PWD/zxing/zxing/LuminanceSource.h \
$$PWD/zxing/zxing/FormatException.h \
$$PWD/zxing/zxing/Exception.h \
$$PWD/zxing/zxing/DecodeHints.h \
$$PWD/zxing/zxing/BinaryBitmap.h \
$$PWD/zxing/zxing/Binarizer.h \
$$PWD/zxing/zxing/BarcodeFormat.h \
$$PWD/zxing/zxing/common/StringUtils.h \
$$PWD/zxing/zxing/common/Str.h \
$$PWD/zxing/zxing/common/Point.h \
$$PWD/zxing/zxing/common/PerspectiveTransform.h \
$$PWD/zxing/zxing/common/IllegalArgumentException.h \
$$PWD/zxing/zxing/common/HybridBinarizer.h \
$$PWD/zxing/zxing/common/GridSampler.h \
$$PWD/zxing/zxing/common/GreyscaleRotatedLuminanceSource.h \
$$PWD/zxing/zxing/common/GreyscaleLuminanceSource.h \
$$PWD/zxing/zxing/common/GlobalHistogramBinarizer.h \
$$PWD/zxing/zxing/common/DetectorResult.h \
$$PWD/zxing/zxing/common/DecoderResult.h \
$$PWD/zxing/zxing/common/Counted.h \
$$PWD/zxing/zxing/common/CharacterSetECI.h \
$$PWD/zxing/zxing/common/BitSource.h \
$$PWD/zxing/zxing/common/BitMatrix.h \
$$PWD/zxing/zxing/common/BitArray.h \
$$PWD/zxing/zxing/common/Array.h \
$$PWD/zxing/zxing/common/detector/MathUtils.h \
$$PWD/zxing/zxing/common/detector/JavaMath.h \
$$PWD/zxing/zxing/common/detector/WhiteRectangleDetector.h \
$$PWD/zxing/zxing/common/detector/MonochromeRectangleDetector.h \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonException.h \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonDecoder.h \
$$PWD/zxing/zxing/common/reedsolomon/GenericGFPoly.h \
$$PWD/zxing/zxing/common/reedsolomon/GenericGF.h \
$$PWD/zxing/zxing/common/ByteArray.h \
$$PWD/zxing/zxing/multi/MultipleBarcodeReader.h \
$$PWD/zxing/zxing/multi/GenericMultipleBarcodeReader.h \
$$PWD/zxing/zxing/multi/ByQuadrantReader.h \
$$PWD/zxing/bigint/NumberlikeArray.hh \
$$PWD/zxing/bigint/BigUnsignedInABase.hh \
$$PWD/zxing/bigint/BigUnsigned.hh \
$$PWD/zxing/bigint/BigIntegerUtils.hh \
$$PWD/zxing/bigint/BigIntegerLibrary.hh \
$$PWD/zxing/bigint/BigIntegerAlgorithms.hh \
$$PWD/zxing/bigint/BigInteger.hh \
$$PWD/zxing/zxing/WriterException.h \
$$PWD/zxing/zxing/common/Types.h
SOURCES += $$PWD/CameraImageWrapper.cpp \
$$PWD/QZXing.cpp \
$$PWD/ImageHandler.cpp \
$$PWD/zxing/zxing/ResultIO.cpp \
$$PWD/zxing/zxing/InvertedLuminanceSource.cpp \
$$PWD/zxing/zxing/ChecksumException.cpp \
$$PWD/zxing/zxing/ResultPointCallback.cpp \
$$PWD/zxing/zxing/ResultPoint.cpp \
$$PWD/zxing/zxing/Result.cpp \
$$PWD/zxing/zxing/ResultMetadata.cpp \
$$PWD/zxing/zxing/Reader.cpp \
$$PWD/zxing/zxing/MultiFormatReader.cpp \
$$PWD/zxing/zxing/LuminanceSource.cpp \
$$PWD/zxing/zxing/FormatException.cpp \
$$PWD/zxing/zxing/Exception.cpp \
$$PWD/zxing/zxing/DecodeHints.cpp \
$$PWD/zxing/zxing/BinaryBitmap.cpp \
$$PWD/zxing/zxing/Binarizer.cpp \
$$PWD/zxing/zxing/BarcodeFormat.cpp \
$$PWD/zxing/zxing/ReaderException.cpp \
$$PWD/zxing/zxing/IllegalStateException.cpp \
$$PWD/zxing/zxing/NotFoundException.cpp \
$$PWD/zxing/zxing/WriterException.cpp \
$$PWD/zxing/zxing/common/Counted.cpp \
$$PWD/zxing/zxing/common/StringUtils.cpp \
$$PWD/zxing/zxing/common/Str.cpp \
$$PWD/zxing/zxing/common/PerspectiveTransform.cpp \
$$PWD/zxing/zxing/common/IllegalArgumentException.cpp \
$$PWD/zxing/zxing/common/HybridBinarizer.cpp \
$$PWD/zxing/zxing/common/GridSampler.cpp \
$$PWD/zxing/zxing/common/GreyscaleRotatedLuminanceSource.cpp \
$$PWD/zxing/zxing/common/GreyscaleLuminanceSource.cpp \
$$PWD/zxing/zxing/common/GlobalHistogramBinarizer.cpp \
$$PWD/zxing/zxing/common/DetectorResult.cpp \
$$PWD/zxing/zxing/common/DecoderResult.cpp \
$$PWD/zxing/zxing/common/CharacterSetECI.cpp \
$$PWD/zxing/zxing/common/BitSource.cpp \
$$PWD/zxing/zxing/common/BitMatrix.cpp \
$$PWD/zxing/zxing/common/BitArray.cpp \
$$PWD/zxing/zxing/common/BitArrayIO.cpp \
$$PWD/zxing/zxing/common/detector/WhiteRectangleDetector.cpp \
$$PWD/zxing/zxing/common/detector/MonochromeRectangleDetector.cpp \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonException.cpp \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonDecoder.cpp \
$$PWD/zxing/zxing/common/reedsolomon/GenericGFPoly.cpp \
$$PWD/zxing/zxing/common/reedsolomon/GenericGF.cpp \
$$PWD/zxing/zxing/multi/MultipleBarcodeReader.cpp \
$$PWD/zxing/zxing/multi/GenericMultipleBarcodeReader.cpp \
$$PWD/zxing/zxing/multi/ByQuadrantReader.cpp \
$$PWD/zxing/bigint/BigUnsignedInABase.cc \
$$PWD/zxing/bigint/BigUnsigned.cc \
$$PWD/zxing/bigint/BigIntegerUtils.cc \
$$PWD/zxing/bigint/BigIntegerAlgorithms.cc \
$$PWD/zxing/bigint/BigInteger.cc \
enable_decoder_1d_barcodes {
DEFINES += ENABLE_DECODER_1D_BARCODES
HEADERS += \
$$PWD/zxing/zxing/oned/UPCEReader.h \
$$PWD/zxing/zxing/oned/UPCEANReader.h \
$$PWD/zxing/zxing/oned/UPCEANExtensionSupport.h \
$$PWD/zxing/zxing/oned/UPCEANExtension2Support.h \
$$PWD/zxing/zxing/oned/UPCEANExtension5Support.h \
$$PWD/zxing/zxing/oned/UPCAReader.h \
$$PWD/zxing/zxing/oned/OneDResultPoint.h \
$$PWD/zxing/zxing/oned/OneDReader.h \
$$PWD/zxing/zxing/oned/MultiFormatUPCEANReader.h \
$$PWD/zxing/zxing/oned/MultiFormatOneDReader.h \
$$PWD/zxing/zxing/oned/ITFReader.h \
$$PWD/zxing/zxing/oned/EAN13Reader.h \
$$PWD/zxing/zxing/oned/EAN8Reader.h \
$$PWD/zxing/zxing/oned/EANManufacturerOrgSupport.h \
$$PWD/zxing/zxing/oned/Code128Reader.h \
$$PWD/zxing/zxing/oned/Code39Reader.h \
$$PWD/zxing/zxing/oned/CodaBarReader.h \
$$PWD/zxing/zxing/oned/Code93Reader.h \
$$PWD/zxing/zxing/oned/rss/AbstractRSSReader.h \
$$PWD/zxing/zxing/oned/rss/DataCharacter.h \
$$PWD/zxing/zxing/oned/rss/FinderPattern.h \
$$PWD/zxing/zxing/oned/rss/Pair.h \
$$PWD/zxing/zxing/oned/rss/RSS14Reader.h \
$$PWD/zxing/zxing/oned/rss/RSSUtils.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013103decoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01320xDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01392xDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01393xDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01decoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01weightDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AnyAIDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/BlockParsedResult.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/CurrentParsingState.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedChar.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedInformation.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedNumeric.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedObject.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/FieldParser.h \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.h \
$$PWD/zxing/zxing/oned/rss/expanded/BitArrayBuilder.h \
$$PWD/zxing/zxing/oned/rss/expanded/ExpandedPair.h \
$$PWD/zxing/zxing/oned/rss/expanded/ExpandedRow.h \
$$PWD/zxing/zxing/oned/rss/expanded/RSSExpandedReader.h
SOURCES += \
$$PWD/zxing/zxing/oned/UPCEReader.cpp \
$$PWD/zxing/zxing/oned/UPCEANReader.cpp \
$$PWD/zxing/zxing/oned/UPCEANExtensionSupport.cpp \
$$PWD/zxing/zxing/oned/UPCEANExtension2Support.cpp \
$$PWD/zxing/zxing/oned/UPCEANExtension5Support.cpp \
$$PWD/zxing/zxing/oned/UPCAReader.cpp \
$$PWD/zxing/zxing/oned/OneDResultPoint.cpp \
$$PWD/zxing/zxing/oned/OneDReader.cpp \
$$PWD/zxing/zxing/oned/MultiFormatUPCEANReader.cpp \
$$PWD/zxing/zxing/oned/MultiFormatOneDReader.cpp \
$$PWD/zxing/zxing/oned/ITFReader.cpp \
$$PWD/zxing/zxing/oned/EAN13Reader.cpp \
$$PWD/zxing/zxing/oned/EAN8Reader.cpp \
$$PWD/zxing/zxing/oned/EANManufacturerOrgSupport.cpp \
$$PWD/zxing/zxing/oned/Code128Reader.cpp \
$$PWD/zxing/zxing/oned/Code39Reader.cpp \
$$PWD/zxing/zxing/oned/CodaBarReader.cpp \
$$PWD/zxing/zxing/oned/Code93Reader.cpp \
$$PWD/zxing/zxing/oned/rss/AbstractRSSReader.cpp \
$$PWD/zxing/zxing/oned/rss/DataCharacter.cpp \
$$PWD/zxing/zxing/oned/rss/FinderPattern.cpp \
$$PWD/zxing/zxing/oned/rss/Pair.cpp \
$$PWD/zxing/zxing/oned/rss/RSS14Reader.cpp \
$$PWD/zxing/zxing/oned/rss/RSSUtils.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/BitArrayBuilder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/ExpandedPair.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/ExpandedRow.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/RSSExpandedReader.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AbstractExpandedDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01AndOtherAIs.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01decoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01weightDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013x0x1xDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013x0xDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01320xDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01392xDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI01393xDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AI013103decoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/AnyAIDecoder.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/BlockParsedResult.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/CurrentParsingState.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedChar.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedInformation.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedNumeric.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/DecodedObject.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/FieldParser.cpp \
$$PWD/zxing/zxing/oned/rss/expanded/decoders/GeneralAppIdDecoder.cpp
}
enable_decoder_qr_code {
DEFINES += ENABLE_DECODER_QR_CODE
CONFIG += enable_generic_qrcode
HEADERS += \
$$PWD/zxing/zxing/qrcode/decoder/Decoder.h \
$$PWD/zxing/zxing/qrcode/decoder/DecodedBitStreamParser.h \
$$PWD/zxing/zxing/qrcode/decoder/DataMask.h \
$$PWD/zxing/zxing/qrcode/decoder/DataBlock.h \
$$PWD/zxing/zxing/qrcode/decoder/BitMatrixParser.h \
$$PWD/zxing/zxing/qrcode/detector/FinderPatternInfo.h \
$$PWD/zxing/zxing/qrcode/detector/FinderPatternFinder.h \
$$PWD/zxing/zxing/qrcode/detector/FinderPattern.h \
$$PWD/zxing/zxing/qrcode/detector/Detector.h \
$$PWD/zxing/zxing/qrcode/detector/AlignmentPatternFinder.h \
$$PWD/zxing/zxing/qrcode/detector/AlignmentPattern.h \
$$PWD/zxing/zxing/multi/qrcode/QRCodeMultiReader.h \
$$PWD/zxing/zxing/multi/qrcode/detector/MultiFinderPatternFinder.h \
$$PWD/zxing/zxing/multi/qrcode/detector/MultiDetector.h \
SOURCES += \
$$PWD/zxing/zxing/qrcode/decoder/QRBitMatrixParser.cpp \
$$PWD/zxing/zxing/qrcode/decoder/QRDataBlock.cpp \
$$PWD/zxing/zxing/qrcode/decoder/QRDataMask.cpp \
$$PWD/zxing/zxing/qrcode/decoder/QRDecodedBitStreamParser.cpp \
$$PWD/zxing/zxing/qrcode/decoder/QRDecoder.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRAlignmentPattern.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRAlignmentPatternFinder.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRDetector.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRFinderPattern.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRFinderPatternFinder.cpp \
$$PWD/zxing/zxing/qrcode/detector/QRFinderPatternInfo.cpp \
$$PWD/zxing/zxing/qrcode/QRCodeReader.cpp \
$$PWD/zxing/zxing/multi/qrcode/QRCodeMultiReader.cpp \
$$PWD/zxing/zxing/multi/qrcode/detector/MultiFinderPatternFinder.cpp \
$$PWD/zxing/zxing/multi/qrcode/detector/MultiDetector.cpp
}
enable_encoder_qr_code {
DEFINES += ENABLE_ENCODER_QR_CODE
CONFIG += enable_generic_qrcode \
enable_encoder_generic
HEADERS += \
$$PWD/zxing/zxing/qrcode/encoder/BlockPair.h \
$$PWD/zxing/zxing/qrcode/encoder/ByteMatrix.h \
$$PWD/zxing/zxing/qrcode/encoder/Encoder.h \
$$PWD/zxing/zxing/qrcode/encoder/MaskUtil.h \
$$PWD/zxing/zxing/qrcode/encoder/MatrixUtil.h \
$$PWD/zxing/zxing/qrcode/encoder/QRCode.h
SOURCES += \
$$PWD/zxing/zxing/qrcode/encoder/ByteMatrix.cpp \
$$PWD/zxing/zxing/qrcode/encoder/QREncoder.cpp \
$$PWD/zxing/zxing/qrcode/encoder/MaskUtil.cpp \
$$PWD/zxing/zxing/qrcode/encoder/MatrixUtil.cpp \
$$PWD/zxing/zxing/qrcode/encoder/QRCode.cpp
}
enable_decoder_data_matrix {
DEFINES += ENABLE_DECODER_DATA_MATRIX
HEADERS += \
$$PWD/zxing/zxing/datamatrix/Version.h \
$$PWD/zxing/zxing/datamatrix/DataMatrixReader.h \
$$PWD/zxing/zxing/datamatrix/decoder/Decoder.h \
$$PWD/zxing/zxing/datamatrix/decoder/DecodedBitStreamParser.h \
$$PWD/zxing/zxing/datamatrix/decoder/DataBlock.h \
$$PWD/zxing/zxing/datamatrix/decoder/BitMatrixParser.h \
$$PWD/zxing/zxing/datamatrix/detector/DetectorException.h \
$$PWD/zxing/zxing/datamatrix/detector/Detector.h \
$$PWD/zxing/zxing/datamatrix/detector/CornerPoint.h
SOURCES += \
$$PWD/zxing/zxing/datamatrix/DataMatrixReader.cpp \
$$PWD/zxing/zxing/datamatrix/DataMatrixVersion.cpp \
$$PWD/zxing/zxing/datamatrix/decoder/DataMatrixDecoder.cpp \
$$PWD/zxing/zxing/datamatrix/decoder/DataMatrixBitMatrixParser.cpp \
$$PWD/zxing/zxing/datamatrix/decoder/DataMatrixDataBlock.cpp \
$$PWD/zxing/zxing/datamatrix/decoder/DataMatrixDecodedBitStreamParser.cpp \
$$PWD/zxing/zxing/datamatrix/detector/DataMatrixCornerPoint.cpp \
$$PWD/zxing/zxing/datamatrix/detector/DataMatrixDetector.cpp \
$$PWD/zxing/zxing/datamatrix/detector/DataMatrixDetectorException.cpp
}
enable_decoder_aztec {
DEFINES += ENABLE_DECODER_AZTEC
HEADERS += \
$$PWD/zxing/zxing/aztec/AztecReader.h \
$$PWD/zxing/zxing/aztec/AztecDetectorResult.h \
$$PWD/zxing/zxing/aztec/decoder/Decoder.h \
$$PWD/zxing/zxing/aztec/detector/Detector.h
SOURCES += \
$$PWD/zxing/zxing/aztec/AztecReader.cpp \
$$PWD/zxing/zxing/aztec/AztecDetectorResult.cpp \
$$PWD/zxing/zxing/aztec/decoder/AztecDecoder.cpp \
$$PWD/zxing/zxing/aztec/detector/AztecDetector.cpp
}
enable_decoder_pdf17 {
DEFINES += ENABLE_DECODER_PDF17
HEADERS += \
$$PWD/zxing/zxing/pdf417/decoder/ec/ErrorCorrection.h \
$$PWD/zxing/zxing/pdf417/decoder/ec/ModulusGF.h \
$$PWD/zxing/zxing/pdf417/decoder/ec/ModulusPoly.h \
$$PWD/zxing/zxing/pdf417/decoder/BitMatrixParser.h \
$$PWD/zxing/zxing/pdf417/decoder/DecodedBitStreamParser.h \
$$PWD/zxing/zxing/pdf417/decoder/Decoder.h \
$$PWD/zxing/zxing/pdf417/detector/Detector.h \
$$PWD/zxing/zxing/pdf417/detector/LinesSampler.h \
$$PWD/zxing/zxing/pdf417/PDF417Reader.h
SOURCES += \
$$PWD/zxing/zxing/pdf417/decoder/ec/ErrorCorrection.cpp \
$$PWD/zxing/zxing/pdf417/decoder/ec/ModulusGF.cpp \
$$PWD/zxing/zxing/pdf417/decoder/ec/ModulusPoly.cpp \
$$PWD/zxing/zxing/pdf417/decoder/PDF417BitMatrixParser.cpp \
$$PWD/zxing/zxing/pdf417/decoder/PDF417DecodedBitStreamParser.cpp \
$$PWD/zxing/zxing/pdf417/decoder/PDF417Decoder.cpp \
$$PWD/zxing/zxing/pdf417/detector/PDF417Detector.cpp \
$$PWD/zxing/zxing/pdf417/detector/LinesSampler.cpp \
$$PWD/zxing/zxing/pdf417/PDF417Reader.cpp
}
enable_generic_qrcode {
CONFIG += enable_encoder_generic
HEADERS += \
$$PWD/zxing/zxing/qrcode/Version.h \
$$PWD/zxing/zxing/qrcode/QRCodeReader.h \
$$PWD/zxing/zxing/qrcode/FormatInformation.h \
$$PWD/zxing/zxing/qrcode/ErrorCorrectionLevel.h \
$$PWD/zxing/zxing/qrcode/decoder/Mode.h
SOURCES += \
$$PWD/zxing/zxing/qrcode/QRVersion.cpp \
$$PWD/zxing/zxing/qrcode/QRFormatInformation.cpp \
$$PWD/zxing/zxing/qrcode/QRErrorCorrectionLevel.cpp \
$$PWD/zxing/zxing/qrcode/decoder/QRMode.cpp \
}
enable_encoder_generic {
DEFINES += ENABLE_ENCODER_GENERIC
HEADERS += \
$$PWD/zxing/zxing/EncodeHint.h \
$$PWD/zxing/zxing/UnsupportedEncodingException.h \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.h \
SOURCES += \
$$PWD/zxing/zxing/EncodeHint.cpp \
$$PWD/zxing/zxing/UnsupportedEncodingException.cpp \
$$PWD/zxing/zxing/common/reedsolomon/ReedSolomonEncoder.cpp
}
qzxing_multimedia {
QT += multimedia
CONFIG += qzxing_qml
DEFINES += QZXING_MULTIMEDIA
PRL_EXPORT_DEFINES += QZXING_MULTIMEDIA
HEADERS += \
$$PWD/QZXingFilter.h
SOURCES += \
$$PWD/QZXingFilter.cpp
}
qzxing_qml {
greaterThan(QT_VERSION, 4.7): lessThan(QT_VERSION, 5.0): QT += declarative
greaterThan(QT_MAJOR_VERSION, 4): QT += quick
DEFINES += QZXING_QML
PRL_EXPORT_DEFINES += QZXING_QML
HEADERS += \
$$PWD/QZXingImageProvider.h
SOURCES += \
$$PWD/QZXingImageProvider.cpp
}
symbian {
TARGET.UID3 = 0xE618743C
TARGET.EPOCALLOWDLLDATA = 1
#TARGET.CAPABILITY = All -TCB -AllFiles -DRM
TARGET.CAPABILITY += NetworkServices \
ReadUserData \
WriteUserData \
LocalServices \
UserEnvironment \
Location
}
!symbian {
isEmpty(PREFIX) {
maemo5 {
PREFIX = /opt/usr
} else {
PREFIX = /usr
}
}
DEFINES += NOFMAXL
# Installation
headers.files = $$PWD/QZXing.h $$PWD/QZXing_global.h
headers.path = $$PREFIX/include
target.path = $$PREFIX/lib
INSTALLS += headers target
# pkg-config support
CONFIG += create_pc create_prl no_install_prl
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
QMAKE_PKGCONFIG_LIBDIR = ${prefix}/lib
QMAKE_PKGCONFIG_INCDIR = ${prefix}/include
unix:QMAKE_CLEAN += -r pkgconfig lib$${TARGET}.prl
}
win32-msvc*{
DEFINES += __STDC_LIMIT_MACROS
INCLUDEPATH += $$PWD/zxing/win32/zxing \
$$PWD/zxing/win32/zxing/msvc
HEADERS += $$PWD/zxing/win32/zxing/msvc/stdint.h \
$$PWD/zxing/win32/zxing/iconv.h
SOURCES += $$PWD/zxing/win32/zxing/win_iconv.c
}
win32-g++{
INCLUDEPATH += $$PWD/zxing/win32/zxing
HEADERS += $$PWD/zxing/win32/zxing/iconv.h
SOURCES += $$PWD/zxing/win32/zxing/win_iconv.c
}
!win32{
DEFINES += NO_ICONV
}
winrt {
DEFINES += NO_ICONV
}

@ -0,0 +1,714 @@
#include "QZXing.h"
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/Binarizer.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/DecodeHints.h>
#include <zxing/ResultMetadata.h>
#include <zxing/common/detector/WhiteRectangleDetector.h>
#include <zxing/InvertedLuminanceSource.h>
#include "CameraImageWrapper.h"
#include "ImageHandler.h"
#include <QTime>
#include <QUrl>
#include <QFileInfo>
#include <QColor>
#include <QtCore/QTextCodec>
#include <QDebug>
#ifdef ENABLE_ENCODER_QR_CODE
#include <zxing/qrcode/encoder/Encoder.h>
#include <zxing/qrcode/ErrorCorrectionLevel.h>
#endif // ENABLE_ENCODER_QR_CODE
#ifdef QZXING_MULTIMEDIA
#include "QZXingFilter.h"
#endif //QZXING_MULTIMEDIA
#ifdef QZXING_QML
#if QT_VERSION >= 0x040700 && QT_VERSION < 0x050000
#include <QtDeclarative>
#elif QT_VERSION >= 0x050000
#include <QtQml/qqml.h>
#endif
#include <QQmlEngine>
#include <QQmlContext>
#include <QQuickImageProvider>
#include "QZXingImageProvider.h"
#endif //QZXING_QML
using namespace zxing;
QZXing::QZXing(QObject *parent) : QObject(parent), tryHarder_(false), lastDecodeOperationSucceded_(false)
{
decoder = new MultiFormatReader();
setDecoder(DecoderFormat_QR_CODE |
DecoderFormat_DATA_MATRIX |
DecoderFormat_UPC_E |
DecoderFormat_UPC_A |
DecoderFormat_UPC_EAN_EXTENSION |
DecoderFormat_RSS_14 |
DecoderFormat_RSS_EXPANDED |
DecoderFormat_PDF_417 |
DecoderFormat_MAXICODE |
DecoderFormat_EAN_8 |
DecoderFormat_EAN_13 |
DecoderFormat_CODE_128 |
DecoderFormat_CODE_93 |
DecoderFormat_CODE_39 |
DecoderFormat_CODABAR |
DecoderFormat_ITF |
DecoderFormat_Aztec);
setTryHarderBehaviour(TryHarderBehaviour_Rotate |
TryHarderBehaviour_ThoroughScanning);
setSourceFilterType(SourceFilter_ImageNormal);
imageHandler = new ImageHandler();
}
QZXing::~QZXing()
{
if (imageHandler)
delete imageHandler;
if (decoder)
delete decoder;
}
QZXing::QZXing(QZXing::DecoderFormat decodeHints, QObject *parent) : QObject(parent), lastDecodeOperationSucceded_(false)
{
decoder = new MultiFormatReader();
imageHandler = new ImageHandler();
setDecoder(decodeHints);
setSourceFilterType(SourceFilter_ImageNormal);
}
#ifdef QZXING_QML
#if QT_VERSION >= 0x040700
void QZXing::registerQMLTypes()
{
qmlRegisterType<QZXing>("QZXing", 2, 3, "QZXing");
#ifdef QZXING_MULTIMEDIA
qmlRegisterType<QZXingFilter>("QZXing", 2, 3, "QZXingFilter");
#endif //QZXING_MULTIMEDIA
}
#endif //QT_VERSION >= Qt 4.7
#if QT_VERSION >= 0x050000
void QZXing::registerQMLImageProvider(QQmlEngine& engine)
{
engine.addImageProvider(QLatin1String("QZXing"), new QZXingImageProvider());
}
#endif //QT_VERSION >= Qt 5.0
#endif //QZXING_QML
void QZXing::setTryHarder(bool tryHarder)
{
tryHarder_ = tryHarder;
}
bool QZXing::getTryHarder()
{
return tryHarder_;
}
void QZXing::setTryHarderBehaviour(QZXing::TryHarderBehaviourType tryHarderBehaviour)
{
tryHarderType = tryHarderBehaviour;
}
QZXing::TryHarderBehaviourType QZXing::getTryHarderBehaviour()
{
return tryHarderType;
}
void QZXing::setSourceFilterType(QZXing::SourceFilterType sourceFilter)
{
imageSourceFilter = sourceFilter;
}
QZXing::SourceFilterType QZXing::getSourceFilterType()
{
return imageSourceFilter;
}
void QZXing::setAllowedExtensions(const QVariantList& extensions)
{
std::set<int> allowedExtensions;
for (const QVariant& extension: extensions) {
allowedExtensions.insert(extension.toInt());
}
allowedExtensions_ = allowedExtensions;
}
QVariantList QZXing::getAllowedExtensions()
{
QVariantList allowedExtensions;
for (const int& extension: allowedExtensions_) {
allowedExtensions << extension;
}
return allowedExtensions;
}
QString QZXing::decoderFormatToString(int fmt)
{
switch (fmt) {
case DecoderFormat_Aztec:
return "AZTEC";
case DecoderFormat_CODABAR:
return "CODABAR";
case DecoderFormat_CODE_39:
return "CODE_39";
case DecoderFormat_CODE_93:
return "CODE_93";
case DecoderFormat_CODE_128:
return "CODE_128";
case DecoderFormat_CODE_128_GS1:
return "CODE_128_GS1";
case DecoderFormat_DATA_MATRIX:
return "DATA_MATRIX";
case DecoderFormat_EAN_8:
return "EAN_8";
case DecoderFormat_EAN_13:
return "EAN_13";
case DecoderFormat_ITF:
return "ITF";
case DecoderFormat_MAXICODE:
return "MAXICODE";
case DecoderFormat_PDF_417:
return "PDF_417";
case DecoderFormat_QR_CODE:
return "QR_CODE";
case DecoderFormat_RSS_14:
return "RSS_14";
case DecoderFormat_RSS_EXPANDED:
return "RSS_EXPANDED";
case DecoderFormat_UPC_A:
return "UPC_A";
case DecoderFormat_UPC_E:
return "UPC_E";
case DecoderFormat_UPC_EAN_EXTENSION:
return "UPC_EAN_EXTENSION";
} // switch
return QString();
}
QString QZXing::foundedFormat() const
{
return foundedFmt;
}
QString QZXing::charSet() const
{
return charSet_;
}
bool QZXing::getLastDecodeOperationSucceded()
{
return lastDecodeOperationSucceded_;
}
QVariantMap QZXing::metadataToMap(const ResultMetadata &metadata)
{
QVariantMap obj;
for (const ResultMetadata::Key &key: metadata.keys()) {
QString keyName = QString::fromStdString(metadata.keyToString(key));
switch (key) {
case ResultMetadata::ORIENTATION:
case ResultMetadata::ISSUE_NUMBER:
case ResultMetadata::STRUCTURED_APPEND_SEQUENCE:
case ResultMetadata::STRUCTURED_APPEND_CODE_COUNT:
case ResultMetadata::STRUCTURED_APPEND_PARITY:
obj[keyName] = QVariant(metadata.getInt(key));
break;
case ResultMetadata::ERROR_CORRECTION_LEVEL:
case ResultMetadata::SUGGESTED_PRICE:
case ResultMetadata::POSSIBLE_COUNTRY:
case ResultMetadata::UPC_EAN_EXTENSION:
obj[keyName] = QVariant(metadata.getString(key).c_str());
break;
case ResultMetadata::OTHER:
case ResultMetadata::PDF417_EXTRA_METADATA:
case ResultMetadata::BYTE_SEGMENTS:
break;
}
}
return obj;
}
void QZXing::setDecoder(const uint &hint)
{
unsigned int newHints = 0;
if(hint & DecoderFormat_Aztec)
newHints |= DecodeHints::AZTEC_HINT;
if(hint & DecoderFormat_CODABAR)
newHints |= DecodeHints::CODABAR_HINT;
if(hint & DecoderFormat_CODE_39)
newHints |= DecodeHints::CODE_39_HINT;
if(hint & DecoderFormat_CODE_93)
newHints |= DecodeHints::CODE_93_HINT;
if(hint & DecoderFormat_CODE_128)
newHints |= DecodeHints::CODE_128_HINT;
if(hint & DecoderFormat_DATA_MATRIX)
newHints |= DecodeHints::DATA_MATRIX_HINT;
if(hint & DecoderFormat_EAN_8)
newHints |= DecodeHints::EAN_8_HINT;
if(hint & DecoderFormat_EAN_13)
newHints |= DecodeHints::EAN_13_HINT;
if(hint & DecoderFormat_ITF)
newHints |= DecodeHints::ITF_HINT;
if(hint & DecoderFormat_MAXICODE)
newHints |= DecodeHints::MAXICODE_HINT;
if(hint & DecoderFormat_PDF_417)
newHints |= DecodeHints::PDF_417_HINT;
if(hint & DecoderFormat_QR_CODE)
newHints |= DecodeHints::QR_CODE_HINT;
if(hint & DecoderFormat_RSS_14)
newHints |= DecodeHints::RSS_14_HINT;
if(hint & DecoderFormat_RSS_EXPANDED)
newHints |= DecodeHints::RSS_EXPANDED_HINT;
if(hint & DecoderFormat_UPC_A)
newHints |= DecodeHints::UPC_A_HINT;
if(hint & DecoderFormat_UPC_E)
newHints |= DecodeHints::UPC_E_HINT;
if(hint & DecoderFormat_UPC_EAN_EXTENSION)
newHints |= DecodeHints::UPC_EAN_EXTENSION_HINT;
if(hint & DecoderFormat_CODE_128_GS1)
{
newHints |= DecodeHints::CODE_128_HINT;
newHints |= DecodeHints::ASSUME_GS1;
}
enabledDecoders = newHints;
emit enabledFormatsChanged();
}
/*!
* \brief getTagRec - returns rectangle containing the tag.
*
* To be able display tag rectangle regardless of the size of the bit matrix rect is in related coordinates [0; 1].
* \param resultPoints
* \param bitMatrix
* \return
*/
QRectF getTagRect(const ArrayRef<Ref<ResultPoint> > &resultPoints, const Ref<BitMatrix> &bitMatrix)
{
if (resultPoints->size() < 2)
return QRectF();
int matrixWidth = bitMatrix->getWidth();
int matrixHeight = bitMatrix->getHeight();
// 1D barcode
if (resultPoints->size() == 2) {
WhiteRectangleDetector detector(bitMatrix);
std::vector<Ref<ResultPoint> > resultRectPoints = detector.detect();
if (resultRectPoints.size() != 4)
return QRectF();
qreal xMin = qreal(resultPoints[0]->getX());
qreal xMax = xMin;
for (int i = 1; i < resultPoints->size(); ++i) {
qreal x = qreal(resultPoints[i]->getX());
if (x < xMin)
xMin = x;
if (x > xMax)
xMax = x;
}
qreal yMin = qreal(resultRectPoints[0]->getY());
qreal yMax = yMin;
for (size_t i = 1; i < resultRectPoints.size(); ++i) {
qreal y = qreal(resultRectPoints[i]->getY());
if (y < yMin)
yMin = y;
if (y > yMax)
yMax = y;
}
return QRectF(QPointF(xMin / matrixWidth, yMax / matrixHeight), QPointF(xMax / matrixWidth, yMin / matrixHeight));
}
// 2D QR code
if (resultPoints->size() == 4) {
qreal xMin = qreal(resultPoints[0]->getX());
qreal xMax = xMin;
qreal yMin = qreal(resultPoints[0]->getY());
qreal yMax = yMin;
for (int i = 1; i < resultPoints->size(); ++i) {
qreal x = qreal(resultPoints[i]->getX());
qreal y = qreal(resultPoints[i]->getY());
if (x < xMin)
xMin = x;
if (x > xMax)
xMax = x;
if (y < yMin)
yMin = y;
if (y > yMax)
yMax = y;
}
return QRectF(QPointF(xMin / matrixWidth, yMax / matrixHeight), QPointF(xMax / matrixWidth, yMin / matrixHeight));
}
return QRectF();
}
QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bool smoothTransformation)
{
//qDebug() << "Start decoding";
QElapsedTimer t;
t.start();
processingTime = -1;
Ref<Result> res;
emit decodingStarted();
if(image.isNull())
{
emit decodingFinished(false);
processingTime = t.elapsed();
//qDebug() << "End decoding 1";
return "";
}
CameraImageWrapper *ciw = ZXING_NULLPTR;
if ((maxWidth > 0) || (maxHeight > 0))
ciw = CameraImageWrapper::Factory(image, maxWidth, maxHeight, smoothTransformation);
else
ciw = CameraImageWrapper::Factory(image, 999, 999, true);
QString errorMessage = "Unknown";
Ref<LuminanceSource> imageRefOriginal = Ref<LuminanceSource>(ciw);
Ref<LuminanceSource> imageRef = imageRefOriginal;
Ref<GlobalHistogramBinarizer> binz;
Ref<BinaryBitmap> bb;
size_t numberOfIterations = 0;
if (imageSourceFilter & SourceFilter_ImageNormal)
numberOfIterations++;
if (imageSourceFilter & SourceFilter_ImageInverted)
numberOfIterations++;
//qDebug() << "Iterations: "<< numberOfIterations << ", sourceFilter: " << imageSourceFilter;
for(size_t i=0; i<numberOfIterations; ++i){
try {
if((numberOfIterations == 1 && (imageSourceFilter & SourceFilter_ImageInverted)) || i == 1) {
//qDebug() << "Selecting Inverted Luminance source";
imageRef = Ref<LuminanceSource>((LuminanceSource*)(new InvertedLuminanceSource(imageRefOriginal)));
}
binz = Ref<GlobalHistogramBinarizer>( new GlobalHistogramBinarizer(imageRef) );
bb = Ref<BinaryBitmap>( new BinaryBitmap(binz) );
DecodeHints hints(static_cast<DecodeHintType>(enabledDecoders));
if (hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION)) {
hints.setAllowedEanExtensions(allowedExtensions_);
}
lastDecodeOperationSucceded_ = false;
try {
//qDebug() << "Decoding phase 1: started";
res = decoder->decode(bb, hints);
processingTime = t.elapsed();
lastDecodeOperationSucceded_ = true;
break;
} catch(zxing::Exception &/*e*/){
//qDebug() << "Decoding phase 1: failed";
}
if(!lastDecodeOperationSucceded_ && tryHarder_ && (tryHarderType & TryHarderBehaviour_ThoroughScanning))
{
//qDebug() << "Decoding phase 2, thorought scan: starting";
hints.setTryHarder(true);
if(hints.containsFormat(BarcodeFormat::UPC_EAN_EXTENSION) &&
!allowedExtensions_.empty() &&
!(hints & DecodeHints::PRODUCT_HINT).isEmpty() )
hints.setAllowedEanExtensions(std::set<int>());
try {
res = decoder->decode(bb, hints);
processingTime = t.elapsed();
lastDecodeOperationSucceded_ = true;
break;
} catch(zxing::Exception &/*e*/) {
//qDebug() << "Decoding phase 2, thorought scan: failed";
}
}
if (!lastDecodeOperationSucceded_&& tryHarder_ && (tryHarderType & TryHarderBehaviour_Rotate) && bb->isRotateSupported()) {
Ref<BinaryBitmap> bbTmp = bb;
//qDebug() << "Decoding phase 2, rotate: starting";
hints.setTryHarder(true);
for (int i=0; (i<3 && !lastDecodeOperationSucceded_); i++) {
Ref<BinaryBitmap> rotatedImage(bbTmp->rotateCounterClockwise());
bbTmp = rotatedImage;
try {
res = decoder->decode(rotatedImage, hints);
processingTime = t.elapsed();
lastDecodeOperationSucceded_ = true;
break;
} catch(zxing::Exception &/*e*/) {
//qDebug() << "Decoding phase 2, rotate: failed";
}
}
}
}
catch(zxing::Exception &e)
{
errorMessage = QString(e.what());
//qDebug() << "Decoding failed: " << errorMessage;
}
}
if (lastDecodeOperationSucceded_) {
//qDebug() << "Decoding succeeded.";
QString string = QString(res->getText()->getText().c_str());
if (!string.isEmpty() && (string.length() > 0)) {
int fmt = res->getBarcodeFormat().value;
foundedFmt = decoderFormatToString(1<<fmt);
charSet_ = QString::fromStdString(res->getCharSet());
if (!charSet_.isEmpty()) {
QTextCodec *codec = QTextCodec::codecForName(res->getCharSet().c_str());
if (codec)
string = codec->toUnicode(res->getText()->getText().c_str());
}
emit tagFound(string);
emit tagFoundAdvanced(string, foundedFmt, charSet_);
QVariantMap metadataMap = metadataToMap(res->getMetadata());
emit tagFoundAdvanced(string, foundedFmt, charSet_, metadataMap);
try {
const QRectF rect = getTagRect(res->getResultPoints(), binz->getBlackMatrix());
emit tagFoundAdvanced(string, foundedFmt, charSet_, rect);
}catch(zxing::Exception &/*e*/){}
}
emit decodingFinished(true);
//qDebug() << "End decoding 2";
return string;
}
emit error(errorMessage);
emit decodingFinished(false);
processingTime = t.elapsed();
//qDebug() << "End decoding 3";
return "";
}
QString QZXing::decodeImageFromFile(const QString& imageFilePath, int maxWidth, int maxHeight, bool smoothTransformation)
{
// used to have a check if this image exists
// but was removed because if the image file path doesn't point to a valid image
// then the QImage::isNull will return true and the decoding will fail eitherway.
const QString header = "file://";
QString filePath = imageFilePath;
if(imageFilePath.startsWith(header))
filePath = imageFilePath.right(imageFilePath.size() - header.size());
QUrl imageUrl = QUrl::fromLocalFile(filePath);
QImage tmpImage = QImage(imageUrl.toLocalFile());
return decodeImage(tmpImage, maxWidth, maxHeight, smoothTransformation);
}
QString QZXing::decodeImageQML(QObject *item)
{
return decodeSubImageQML(item);
}
QString QZXing::decodeSubImageQML(QObject *item,
const int offsetX, const int offsetY,
const int width, const int height)
{
if(item == ZXING_NULLPTR)
{
processingTime = 0;
emit decodingFinished(false);
return "";
}
QImage img = imageHandler->extractQImage(item, offsetX, offsetY, width, height);
return decodeImage(img);
}
QString QZXing::decodeImageQML(const QUrl &imageUrl)
{
return decodeSubImageQML(imageUrl);
}
QString QZXing::decodeSubImageQML(const QUrl &imageUrl,
const int offsetX, const int offsetY,
const int width, const int height)
{
#ifdef QZXING_QML
QString imagePath = imageUrl.path();
imagePath = imagePath.trimmed();
QImage img;
if (imageUrl.scheme() == "image") {
if (imagePath.startsWith("/"))
imagePath = imagePath.right(imagePath.length() - 1);
QQmlEngine *engine = QQmlEngine::contextForObject(this)->engine();
QQuickImageProvider *imageProvider = dynamic_cast<QQuickImageProvider *>(engine->imageProvider(imageUrl.host()));
QSize imgSize;
img = imageProvider->requestImage(imagePath, &imgSize, QSize());
} else {
QFileInfo fileInfo(imagePath);
if (!fileInfo.exists()) {
qDebug() << "[decodeSubImageQML()] The file" << imagePath << "does not exist.";
emit decodingFinished(false);
return "";
}
img = QImage(imagePath);
}
if (offsetX || offsetY || width || height)
img = img.copy(offsetX, offsetY, width, height);
return decodeImage(img);
#else
Q_UNUSED(imageUrl);
Q_UNUSED(offsetX);
Q_UNUSED(offsetY);
Q_UNUSED(width);
Q_UNUSED(height);
return decodeImage(QImage());
#endif //QZXING_QML
}
#ifdef ENABLE_ENCODER_GENERIC
QImage QZXing::encodeData(const QString& data,
const EncoderFormat encoderFormat,
const QSize encoderImageSize,
const EncodeErrorCorrectionLevel errorCorrectionLevel,
const bool border,
const bool transparent)
{
return encodeData(data,
QZXingEncoderConfig(encoderFormat,
encoderImageSize,
errorCorrectionLevel,
border,
transparent));
}
QImage QZXing::encodeData(const QString &data, const QZXingEncoderConfig &encoderConfig)
{
QImage image;
try {
switch (encoderConfig.format) {
#ifdef ENABLE_ENCODER_QR_CODE
case EncoderFormat_QR_CODE:
{
Ref<qrcode::QRCode> barcode = qrcode::Encoder::encode(
data.toStdWString(),
encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_H ?
qrcode::ErrorCorrectionLevel::H :
(encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_Q ?
qrcode::ErrorCorrectionLevel::Q :
(encoderConfig.errorCorrectionLevel == EncodeErrorCorrectionLevel_M ?
qrcode::ErrorCorrectionLevel::M :
qrcode::ErrorCorrectionLevel::L)));
Ref<qrcode::ByteMatrix> bytesRef = barcode->getMatrix();
const std::vector< std::vector <zxing::byte> >& bytes = bytesRef->getArray();
const int width = int(bytesRef->getWidth()) + (encoderConfig.border ? 2 : 0);
const int height = int(bytesRef->getHeight()) + (encoderConfig.border ? 2 : 0);
const QRgb black = qRgba(0, 0, 0, encoderConfig.transparent ? 0 : 255);
const QRgb white = qRgba(255, 255, 255, 255);
image = QImage(width, height, QImage::Format_ARGB32);
image.fill(white);
int offset = encoderConfig.border ? 1 : 0;
for (size_t i=0; i<bytesRef->getWidth(); ++i) {
for (size_t j=0; j<bytesRef->getHeight(); ++j) {
if (bytes[j][i]) {
image.setPixel(offset+int(i), offset+int(j), black);
}
}
}
image = image.scaled(encoderConfig.imageSize);
break;
}
#endif // ENABLE_ENCODER_QR_CODE
case EncoderFormat_INVALID:
break;
}
} catch (std::exception& e) {
std::cout << "Error: " << e.what() << std::endl;
}
return image;
}
#endif // ENABLE_ENCODER_GENERIC
int QZXing::getProcessTimeOfLastDecoding()
{
return processingTime;
}
uint QZXing::getEnabledFormats() const
{
return enabledDecoders;
}

@ -0,0 +1,289 @@
/*
* Copyright 2011 QZXing 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.
*/
#ifndef QZXING_H
#define QZXING_H
#include "QZXing_global.h"
#include <QObject>
#include <QImage>
#include <QVariantList>
#include <QElapsedTimer>
#include <set>
#if QT_VERSION >= 0x050000
class QQmlEngine;
#endif
// forward declaration
namespace zxing {
class MultiFormatReader;
class ResultMetadata;
}
class ImageHandler;
#ifdef ENABLE_ENCODER_GENERIC
struct QZXingEncoderConfig;
#endif // ENABLE_ENCODER_GENERIC
/**
* A class containing a very very small subset of the ZXing library.
* Created for ease of use.
*
* Anyone interested in using more technical stuff
* from the ZXing library is welcomed to add/edit on free will.
*
* Regarding DecoderFormat, by default all of those are enabled
*/
class
#ifndef DISABLE_LIBRARY_FEATURES
QZXINGSHARED_EXPORT
#endif
QZXing : public QObject {
Q_OBJECT
Q_ENUMS(DecoderFormat)
Q_ENUMS(TryHarderBehaviour)
Q_ENUMS(SourceFilter)
Q_PROPERTY(int processingTime READ getProcessTimeOfLastDecoding)
Q_PROPERTY(uint enabledDecoders READ getEnabledFormats WRITE setDecoder NOTIFY enabledFormatsChanged)
Q_PROPERTY(uint tryHarderType READ getTryHarderBehaviour WRITE setTryHarderBehaviour)
Q_PROPERTY(uint imageSourceFilter READ getSourceFilterType WRITE setSourceFilterType)
Q_PROPERTY(bool tryHarder READ getTryHarder WRITE setTryHarder)
Q_PROPERTY(QVariantList allowedExtensions READ getAllowedExtensions WRITE setAllowedExtensions)
public:
/*
*
*/
enum DecoderFormat {
DecoderFormat_None = 0,
DecoderFormat_Aztec = 1 << 1,
DecoderFormat_CODABAR = 1 << 2,
DecoderFormat_CODE_39 = 1 << 3,
DecoderFormat_CODE_93 = 1 << 4,
DecoderFormat_CODE_128 = 1 << 5,
DecoderFormat_DATA_MATRIX = 1 << 6,
DecoderFormat_EAN_8 = 1 << 7,
DecoderFormat_EAN_13 = 1 << 8,
DecoderFormat_ITF = 1 << 9,
DecoderFormat_MAXICODE = 1 << 10,
DecoderFormat_PDF_417 = 1 << 11,
DecoderFormat_QR_CODE = 1 << 12,
DecoderFormat_RSS_14 = 1 << 13,
DecoderFormat_RSS_EXPANDED = 1 << 14,
DecoderFormat_UPC_A = 1 << 15,
DecoderFormat_UPC_E = 1 << 16,
DecoderFormat_UPC_EAN_EXTENSION = 1 << 17,
DecoderFormat_CODE_128_GS1 = 1 << 18
} ;
typedef unsigned int DecoderFormatType;
enum TryHarderBehaviour {
TryHarderBehaviour_ThoroughScanning = 1 << 1,
TryHarderBehaviour_Rotate = 1 << 2
};
typedef unsigned int TryHarderBehaviourType;
enum SourceFilter {
SourceFilter_ImageNormal = 1 << 1,
SourceFilter_ImageInverted = 1 << 2
};
typedef unsigned int SourceFilterType;
enum EncoderFormat {
EncoderFormat_INVALID,
EncoderFormat_QR_CODE
};
enum EncodeErrorCorrectionLevel {
EncodeErrorCorrectionLevel_L = 0,
EncodeErrorCorrectionLevel_M,
EncodeErrorCorrectionLevel_Q,
EncodeErrorCorrectionLevel_H
};
QZXing(QObject *parent = Q_NULLPTR);
~QZXing();
QZXing(DecoderFormat decodeHints, QObject *parent = Q_NULLPTR);
#ifdef QZXING_QML
#if QT_VERSION >= 0x040700
static void registerQMLTypes();
#endif //QT_VERSION >= Qt 4.7
#if QT_VERSION >= 0x050000
static void registerQMLImageProvider(QQmlEngine& engine);
#endif //QT_VERSION >= Qt 5.0
#endif //QZXING_QML
void setTryHarder(bool tryHarder);
bool getTryHarder();
void setTryHarderBehaviour(TryHarderBehaviourType tryHarderBehaviour);
TryHarderBehaviourType getTryHarderBehaviour();
void setSourceFilterType(SourceFilterType sourceFilter);
SourceFilterType getSourceFilterType();
void setAllowedExtensions(const QVariantList& extensions);
QVariantList getAllowedExtensions();
static QString decoderFormatToString(int fmt);
Q_INVOKABLE QString foundedFormat() const;
Q_INVOKABLE QString charSet() const;
bool getLastDecodeOperationSucceded();
private:
QVariantMap metadataToMap(const zxing::ResultMetadata& metadata);
public slots:
/**
* The decoding function. Will try to decode the given image based on the enabled decoders.
* If the image width is larger than maxWidth or image height is larger
* than maxHeight then the image will be scaled down. Either way, in case of scaling, the aspect
* ratio of the image will be kept.
*
* The smoothTransformation flag determines whether the transformation will be smooth or fast.
* Smooth transformation provides better results but fast transformation is...faster.
*/
QString decodeImage(const QImage &image, int maxWidth = -1, int maxHeight = -1, bool smoothTransformation = false);
/**
* The decoding function. Will try to decode the given image based on the enabled decoders.
* The input image is read from a local image file.
*/
QString decodeImageFromFile(const QString& imageFilePath, int maxWidth=-1, int maxHeight=-1, bool smoothTransformation = false);
/**
* The decoding function accessible from QML. (Suggested for Qt 4.x)
*/
QString decodeImageQML(QObject *item);
/**
* The decoding function accessible from QML. Able to set the decoding
* of a portion of the image. (Suggested for Qt 4.x)
*/
QString decodeSubImageQML(QObject *item,
const int offsetX = 0, const int offsetY = 0,
const int width = 0, const int height = 0);
/**
* The decoding function accessible from QML. (Suggested for Qt 5.x)
* Can be used to decode image from the Camera element preview by providing
* the following string: image://camera/preview_1
*/
QString decodeImageQML(const QUrl &imageUrl);
/**
* The decoding function accessible from QML. Able to set the decoding
* of a portion of the image.
* Can be used to decode image from the Camera element preview by providing
* the following string: image://camera/preview_1
* (Suggested for Qt 5.x)
*/
QString decodeSubImageQML(const QUrl &imageUrl,
const int offsetX = 0, const int offsetY = 0,
const int width = 0, const int height = 0);
#ifdef ENABLE_ENCODER_GENERIC
/**
* The main encoding function. Currently supports only Qr code encoding
*/
static QImage encodeData(const QString &data,
const QZXingEncoderConfig &encoderConfig);
/**
* Overloaded function of encodeData.
*/
static QImage encodeData(const QString& data,
const EncoderFormat encoderFormat = EncoderFormat_QR_CODE,
const QSize encoderImageSize = QSize(240, 240),
const EncodeErrorCorrectionLevel errorCorrectionLevel = EncodeErrorCorrectionLevel_L,
const bool border = false,
const bool transparent = false);
#endif // ENABLE_ENCODER_GENERIC
/**
* Get the prossecing time in millisecond of the last decode operation.
* Added mainly as a statistic measure.
* Decoding operation fails, the processing time equals to -1.
*/
int getProcessTimeOfLastDecoding();
/**
* Get the decoders that are enabled at the moment.
* Returns a uint which is a bitwise OR of DecoderFormat enumeration values.
*/
uint getEnabledFormats() const;
/**
* Set the enabled decoders.
* As argument it is possible to pass conjuction of decoders by using logic OR.
* e.x. setDecoder ( DecoderFormat_QR_CODE | DecoderFormat_EAN_13 | DecoderFormat_CODE_39 )
*/
void setDecoder(const uint &hint);
signals:
void decodingStarted();
void decodingFinished(bool succeeded);
void enabledFormatsChanged();
void tagFound(QString tag);
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet) const;
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet, const QRectF &rect) const;
void tagFoundAdvanced(const QString &tag, const QString &format, const QString &charSet, const QVariantMap &metadata) const;
void error(QString msg);
private:
zxing::MultiFormatReader *decoder;
DecoderFormatType enabledDecoders;
TryHarderBehaviourType tryHarderType;
SourceFilterType imageSourceFilter;
ImageHandler *imageHandler;
int processingTime;
QString foundedFmt;
QString charSet_;
bool tryHarder_;
bool lastDecodeOperationSucceded_;
std::set<int> allowedExtensions_;
/**
* If true, the decoding operation will take place at a different thread.
*/
bool isThreaded;
};
#ifdef ENABLE_ENCODER_GENERIC
typedef struct QZXingEncoderConfig
{
QZXing::EncoderFormat format;
QSize imageSize;
QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel;
bool border;
bool transparent;
QZXingEncoderConfig(const QZXing::EncoderFormat encoderFormat_ = QZXing::EncoderFormat_QR_CODE,
const QSize encoderImageSize_ = QSize(240, 240),
const QZXing::EncodeErrorCorrectionLevel errorCorrectionLevel_ = QZXing::EncodeErrorCorrectionLevel_L,
const bool border_ = false,
const bool transparent_ = false) :
format(encoderFormat_), imageSize(encoderImageSize_),
errorCorrectionLevel(errorCorrectionLevel_), border(border_), transparent(transparent_) {}
} QZXingEncoderConfig;
#endif // ENABLE_ENCODER_GENERIC
#endif // QZXING_H

@ -0,0 +1,10 @@
#For backward compatibility, when using QZXing.pri, enable the complete
# library functionality
CONFIG += enable_decoder_1d_barcodes \
enable_decoder_qr_code \
enable_decoder_data_matrix \
enable_decoder_aztec \
enable_decoder_pdf17 \
enable_encoder_qr_code
include(./QZXing-components.pri)

@ -0,0 +1,35 @@
#
# Copyright 2011 QZXing 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.
#
CONFIG += \
enable_decoder_1d_barcodes \
enable_decoder_qr_code \
enable_decoder_data_matrix \
enable_decoder_aztec \
enable_decoder_pdf17 \
enable_encoder_qr_code
#staticlib
#qzxing_qml
#qzxing_multimedia
VERSION = 2.3
TARGET = QZXing
TEMPLATE = lib
DEFINES -= DISABLE_LIBRARY_FEATURES
include(QZXing-components.pri)

@ -0,0 +1,384 @@
#include "zxing/ZXing.h"
#include "QZXingFilter.h"
#include <QDebug>
#include <QtConcurrent/QtConcurrent>
//#include "QZXingImageProvider.h"
namespace {
uchar gray(uchar r, uchar g, uchar b)
{
return (306 * (r & 0xFF) +
601 * (g & 0xFF) +
117 * (b & 0xFF) +
0x200) >> 10;
}
uchar yuvToGray(uchar Y, uchar U, uchar V)
{
const int C = int(Y) - 16;
const int D = int(U) - 128;
const int E = int(V) - 128;
return gray(
qBound(0, ((298 * C + 409 * E + 128) >> 8), 255),
qBound(0, ((298 * C - 100 * D - 208 * E + 128) >> 8), 255),
qBound(0, ((298 * C + 516 * D + 128) >> 8), 255)
);
}
uchar yuvToGray2(uchar y, uchar u, uchar v)
{
double rD = y + 1.4075 * (v - 128);
double gD = y - 0.3455 * (u - 128) - (0.7169 * (v - 128));
double bD = y + 1.7790 * (u - 128);
return gray(
qBound<uchar>(0, (uchar)::floor(rD), 255),
qBound<uchar>(0, (uchar)::floor(gD), 255),
qBound<uchar>(0, (uchar)::floor(bD), 255)
);
}
}
QZXingFilter::QZXingFilter(QObject *parent)
: QAbstractVideoFilter(parent)
, decoder(QZXing::DecoderFormat_QR_CODE)
, decoding(false)
{
/// Connecting signals to handlers that will send signals to QML
connect(&decoder, &QZXing::decodingStarted,
this, &QZXingFilter::handleDecodingStarted);
connect(&decoder, &QZXing::decodingFinished,
this, &QZXingFilter::handleDecodingFinished);
}
QZXingFilter::~QZXingFilter()
{
}
void QZXingFilter::handleDecodingStarted()
{
decoding = true;
emit decodingStarted();
emit isDecodingChanged();
}
void QZXingFilter::handleDecodingFinished(bool succeeded)
{
decoding = false;
emit decodingFinished(succeeded, decoder.getProcessTimeOfLastDecoding());
emit isDecodingChanged();
}
QVideoFilterRunnable * QZXingFilter::createFilterRunnable()
{
return new QZXingFilterRunnable(this);
}
///
/// QZXingFilterRunnable
///
QZXingFilterRunnable::QZXingFilterRunnable(QZXingFilter * filter)
: QObject(ZXING_NULLPTR)
, filter(filter)
{
}
QZXingFilterRunnable::~QZXingFilterRunnable()
{
if(filter != ZXING_NULLPTR && !filter->processThread.isFinished())
{
filter->processThread.cancel();
filter->processThread.waitForFinished();
}
filter = ZXING_NULLPTR;
}
QVideoFrame QZXingFilterRunnable::run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags)
{
Q_UNUSED(surfaceFormat);
Q_UNUSED(flags);
/// We dont want to decode every single frame we get, as this would be very costly
/// These checks are attempt on having only 1 frame being processed at a time.
if(!input || !input->isValid())
{
//qDebug() << "[QZXingFilterRunnable] Invalid Input ";
return QVideoFrame();
}
if(filter->isDecoding())
{
//qDebug() << "------ decoder busy.";
return * input;
}
if(!filter->processThread.isFinished())
{
//qDebug() << "--[]-- decoder busy.";
return * input;
}
filter->decoding = true;
/// Copy the data we need to the filter.
/// TODO: Depending on the system / platform, this copy hangs up the UI for some seconds. Fix this.
filter->frame.copyData(* input);
/// All processing that has to happen in another thread, as we are now in the UI thread.
filter->processThread = QtConcurrent::run(this, &QZXingFilterRunnable::processVideoFrameProbed, filter->frame, filter->captureRect.toRect());
return * input;
}
static bool isRectValid(const QRect& rect)
{
return rect.x() >= 0 && rect.y() >= 0 && rect.isValid();
}
struct CaptureRect
{
CaptureRect(const QRect& captureRect, int sourceWidth, int sourceHeight)
: isValid(isRectValid(captureRect))
, sourceWidth(sourceWidth)
, sourceHeight(sourceHeight)
, startX(isValid ? captureRect.x() : 0)
, targetWidth(isValid ? captureRect.width() : sourceWidth)
, endX(startX + targetWidth)
, startY(isValid ? captureRect.y() : 0)
, targetHeight(isValid ? captureRect.height() : sourceHeight)
, endY(startY + targetHeight)
{}
bool isValid;
char pad[3]; // avoid warning about padding
int sourceWidth;
int sourceHeight;
int startX;
int targetWidth;
int endX;
int startY;
int targetHeight;
int endY;
};
static QImage* rgbDataToGrayscale(const uchar* data, const CaptureRect& captureRect,
const int alpha, const int red,
const int green, const int blue,
const bool isPremultiplied = false)
{
const int stride = (alpha < 0) ? 3 : 4;
const int endX = captureRect.sourceWidth - captureRect.startX - captureRect.targetWidth;
const int skipX = (endX + captureRect.startX) * stride;
QImage *image_ptr = new QImage(captureRect.targetWidth, captureRect.targetHeight, QImage::Format_Grayscale8);
uchar* pixelInit = image_ptr->bits();
data += (captureRect.startY * captureRect.sourceWidth + captureRect.startX) * stride;
for (int y = 1; y <= captureRect.targetHeight; ++y) {
//Quick fix for iOS devices. Will be handled better in the future
#ifdef Q_OS_IOS
uchar* pixel = pixelInit + (y - 1) * captureRect.targetWidth;
#else
uchar* pixel = pixelInit + (captureRect.targetHeight - y) * captureRect.targetWidth;
#endif
for (int x = 0; x < captureRect.targetWidth; ++x) {
uchar r = data[red];
uchar g = data[green];
uchar b = data[blue];
if (isPremultiplied) {
uchar a = data[alpha];
r = uchar((uint(r) * 255) / a);
g = uchar((uint(g) * 255) / a);
b = uchar((uint(b) * 255) / a);
}
*pixel = gray(r, g, b);
++pixel;
data += stride;
}
data += skipX;
}
return image_ptr;
}
static void YUV_NV21_TO_RGB(uchar* argb, const uchar* yuv, int width, int height) {
int frameSize = width * height;
int ii = 0;
int ij = 0;
int di = +1;
int dj = +1;
int a = 0;
for (int i = 0, ci = ii; i < height; ++i, ci += di) {
for (int j = 0, cj = ij; j < width; ++j, cj += dj) {
int y = (0xff & ((int) yuv[ci * width + cj]));
int v = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 0]));
int u = (0xff & ((int) yuv[frameSize + (ci >> 1) * width + (cj & ~1) + 1]));
y = y < 16 ? 16 : y;
int r = (int) (1.164f * (y - 16) + 1.596f * (v - 128));
int g = (int) (1.164f * (y - 16) - 0.813f * (v - 128) - 0.391f * (u - 128));
int b = (int) (1.164f * (y - 16) + 2.018f * (u - 128));
r = r < 0 ? 0 : (r > 255 ? 255 : r);
g = g < 0 ? 0 : (g > 255 ? 255 : g);
b = b < 0 ? 0 : (b > 255 ? 255 : b);
argb[a++] = 0xff000000 | (r << 16) | (g << 8) | b;
}
}
}
void QZXingFilterRunnable::processVideoFrameProbed(SimpleVideoFrame & videoFrame, const QRect& _captureRect)
{
if (videoFrame.data.length() < 1) {
qDebug() << "QZXingFilterRunnable: Buffer is empty";
filter->decoding = false;
return;
}
static unsigned int i = 0; i++;
// qDebug() << "Future: Going to process frame: " << i;
const int width = videoFrame.size.width();
const int height = videoFrame.size.height();
const CaptureRect captureRect(_captureRect, width, height);
const uchar* data = reinterpret_cast<const uchar *>(videoFrame.data.constData());
uchar* pixel;
int wh;
int w_2;
int wh_54;
const uint32_t *yuvPtr = reinterpret_cast<const uint32_t *>(data);
/// Create QImage from QVideoFrame.
QImage *image_ptr = ZXING_NULLPTR;
switch (videoFrame.pixelFormat) {
case QVideoFrame::Format_RGB32:
image_ptr = rgbDataToGrayscale(data, captureRect, 0, 1, 2, 3);
break;
case QVideoFrame::Format_ARGB32:
image_ptr = rgbDataToGrayscale(data, captureRect, 0, 1, 2, 3);
break;
case QVideoFrame::Format_ARGB32_Premultiplied:
image_ptr = rgbDataToGrayscale(data, captureRect, 0, 1, 2, 3, true);
break;
case QVideoFrame::Format_BGRA32:
image_ptr = rgbDataToGrayscale(data, captureRect, 3, 2, 1, 0);
break;
case QVideoFrame::Format_BGRA32_Premultiplied:
image_ptr = rgbDataToGrayscale(data, captureRect, 3, 2, 1, 0, true);
break;
case QVideoFrame::Format_BGR32:
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
case QVideoFrame::Format_ABGR32:
#endif
image_ptr = rgbDataToGrayscale(data, captureRect, 3, 2, 1, 0);
break;
case QVideoFrame::Format_BGR24:
image_ptr = rgbDataToGrayscale(data, captureRect, -1, 2, 1, 0);
break;
case QVideoFrame::Format_BGR555:
/// This is a forced "conversion", colors end up swapped.
image_ptr = new QImage(data, width, height, QImage::Format_RGB555);
break;
case QVideoFrame::Format_BGR565:
/// This is a forced "conversion", colors end up swapped.
image_ptr = new QImage(data, width, height, QImage::Format_RGB16);
break;
case QVideoFrame::Format_YUV420P:
/// Format_YUV420P format, encountered on raspberry pi
image_ptr = new QImage(captureRect.targetWidth, captureRect.targetHeight, QImage::Format_Grayscale8);
pixel = image_ptr->bits();
wh = width * height;
w_2 = width / 2;
wh_54 = wh * 5 / 4;
for (int y = captureRect.startY; y < captureRect.endY; y++) {
const int Y_offset = y * width;
const int y_2 = y / 2;
const int U_offset = y_2 * w_2 + wh;
const int V_offset = y_2 * w_2 + wh_54;
for (int x = captureRect.startX; x < captureRect.endX; x++) {
const int x_2 = x / 2;
const uchar Y = data[Y_offset + x];
const uchar U = data[U_offset + x_2];
const uchar V = data[V_offset + x_2];
*pixel = yuvToGray(Y, U, V);
++pixel;
}
}
break;
case QVideoFrame::Format_NV12:
/// nv12 format, encountered on macOS
image_ptr = new QImage(captureRect.targetWidth, captureRect.targetHeight, QImage::Format_Grayscale8);
YUV_NV21_TO_RGB((uchar*) image_ptr->bits(), (const uchar*) yuvPtr, width, height);
break;
case QVideoFrame::Format_YUYV:
image_ptr = new QImage(captureRect.targetWidth, captureRect.targetHeight, QImage::Format_Grayscale8);
pixel = image_ptr->bits();
for (int y = captureRect.startY; y < captureRect.endY; y++){
const uint32_t *row = &yuvPtr[y*(width/2)];
int end = captureRect.startX/2 + (captureRect.endX - captureRect.startX)/2;
for (int x = captureRect.startX/2; x < end; x++){
const uint8_t *pxl = reinterpret_cast<const uint8_t *>(&row[x]);
const uint8_t y0 = pxl[0];
const uint8_t u = pxl[1];
const uint8_t v = pxl[3];
const uint8_t y1 = pxl[2];
*pixel = yuvToGray2(y0, u, v);
++pixel;
*pixel = yuvToGray2(y1, u, v);
++pixel;
}
}
break;
/// TODO: Handle (create QImages from) YUV formats.
default:
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(videoFrame.pixelFormat);
image_ptr = new QImage(data, width, height, imageFormat);
break;
}
if(!image_ptr || image_ptr->isNull())
{
qDebug() << "QZXingFilterRunnable error: Cant create image file to process.";
qDebug() << "Maybe it was a format conversion problem? ";
qDebug() << "VideoFrame format: " << videoFrame.pixelFormat;
qDebug() << "Image corresponding format: " << QVideoFrame::imageFormatFromPixelFormat(videoFrame.pixelFormat);
filter->decoding = false;
return;
}
if (captureRect.isValid && image_ptr->size() != _captureRect.size())
image_ptr = new QImage(image_ptr->copy(_captureRect));
//qDebug() << "image.size()" << image_ptr->size();
//qDebug() << "image.format()" << image_ptr->format();
//qDebug() << "videoFrame.pixelFormat" << videoFrame.pixelFormat;
//const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i % 100) + ".png";
//qDebug() << "saving image" << i << "at:" << path << image_ptr->save(path);
//QZXingImageProvider::getInstance()->storeImage(image);
decode(*image_ptr);
delete image_ptr;
}
QString QZXingFilterRunnable::decode(const QImage &image)
{
return (filter != ZXING_NULLPTR) ?
filter->decoder.decodeImage(image, image.width(), image.height()) : QString();
}

@ -0,0 +1,126 @@
/*
* Copyright 2017 QZXing 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.
*/
#ifndef QZXingFilter_H
#define QZXingFilter_H
#include <QObject>
#include <QAbstractVideoFilter>
#include <QDebug>
#include <QFuture>
#include "QZXing.h"
///
/// References:
///
/// https://blog.qt.io/blog/2015/03/20/introducing-video-filters-in-qt-multimedia/
/// http://doc.qt.io/qt-5/qabstractvideofilter.html
/// http://doc.qt.io/qt-5/qml-qtmultimedia-videooutput.html#filters-prop
/// http://doc.qt.io/qt-5/qvideofilterrunnable.html
/// http://doc.qt.io/qt-5/qtconcurrent-runfunction-main-cpp.html
///
/// This is used to store a QVideoFrame info while we are searching the image for QRCodes.
struct SimpleVideoFrame
{
QByteArray data;
QSize size;
QVideoFrame::PixelFormat pixelFormat;
SimpleVideoFrame()
: size{0,0}
, pixelFormat{QVideoFrame::Format_Invalid}
{}
void copyData(QVideoFrame & frame)
{
frame.map(QAbstractVideoBuffer::ReadOnly);
/// Copy video frame bytes to this.data
/// This is made to try to get a better performance (less memory allocation, faster unmap)
/// Any other task is performed in a QFuture task, as we want to leave the UI thread asap
if(data.size() != frame.mappedBytes())
{
qDebug() << "needed to resize";
qDebug() << "size: " << data.size() << ", new size: " << frame.mappedBytes();
data.resize(frame.mappedBytes());
}
memcpy(data.data(), frame.bits(), frame.mappedBytes());
size = frame.size();
pixelFormat = frame.pixelFormat();
frame.unmap();
}
};
/// Video filter is the filter that has to be registered in C++, instantiated and attached in QML
class QZXingFilter : public QAbstractVideoFilter
{
friend class QZXingFilterRunnable;
Q_OBJECT
Q_PROPERTY(bool decoding READ isDecoding NOTIFY isDecodingChanged)
Q_PROPERTY(QZXing* decoder READ getDecoder)
Q_PROPERTY(QRectF captureRect MEMBER captureRect NOTIFY captureRectChanged)
signals:
void isDecodingChanged();
void decodingFinished(bool succeeded, int decodeTime);
void decodingStarted();
void captureRectChanged();
private slots:
void handleDecodingStarted();
void handleDecodingFinished(bool succeeded);
private: /// Attributes
QZXing decoder;
bool decoding;
QRectF captureRect;
SimpleVideoFrame frame;
QFuture<void> processThread;
public: /// Methods
explicit QZXingFilter(QObject *parent = 0);
virtual ~QZXingFilter();
bool isDecoding() {return decoding; }
QZXing* getDecoder() { return &decoder; }
QVideoFilterRunnable * createFilterRunnable();
};
/// A new Runnable is created everytime the filter gets a new frame
class QZXingFilterRunnable : public QObject, public QVideoFilterRunnable
{
Q_OBJECT
public:
explicit QZXingFilterRunnable(QZXingFilter * filter);
virtual ~QZXingFilterRunnable();
/// This method is called whenever we get a new frame. It runs in the UI thread.
QVideoFrame run(QVideoFrame * input, const QVideoSurfaceFormat &surfaceFormat, RunFlags flags);
void processVideoFrameProbed(SimpleVideoFrame & videoFrame, const QRect& captureRect);
private:
QString decode(const QImage &image);
private:
QZXingFilter * filter;
};
#endif // QZXingFilter_H

@ -0,0 +1,80 @@
#include "QZXingImageProvider.h"
#include <QDebug>
#include <QUrlQuery>
#include "QZXing.h"
#include <QRegularExpression>
QZXingImageProvider::QZXingImageProvider() : QQuickImageProvider(QQuickImageProvider::Image)
{
}
QImage QZXingImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
int slashIndex = id.indexOf('/');
if (slashIndex == -1)
{
qWarning() << "Can't parse url" << id << ". Usage is encode?<format>/<data>";
return QImage();
}
//Detect operation (ex. encode)
QString operationName = id.left(slashIndex);
if(operationName != "encode")
{
qWarning() << "Operation not supported: " << operationName;
return QImage();
}
QString data;
QZXing::EncoderFormat format = QZXing::EncoderFormat_QR_CODE;
QZXing::EncodeErrorCorrectionLevel correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
bool border = false;
bool transparent = false;
int customSettingsIndex = id.lastIndexOf(QRegularExpression("\\?(correctionLevel|format|border|transparent)="));
if(customSettingsIndex >= 0)
{
int startOfDataIndex = slashIndex + 1;
data = id.mid(startOfDataIndex, customSettingsIndex - (startOfDataIndex));
//The dummy option has been added due to a bug(?) of QUrlQuery
// it could not recognize the first key-value pair provided
QUrlQuery optionQuery("options?dummy=&" + id.mid(customSettingsIndex + 1));
if (optionQuery.hasQueryItem("format")) {
QString formatString = optionQuery.queryItemValue("format");
if (formatString != "qrcode") {
qWarning() << "Format not supported: " << formatString;
return QImage();
}
}
QString correctionLevelString = optionQuery.queryItemValue("correctionLevel");
if(correctionLevelString == "H")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_H;
else if(correctionLevelString == "Q")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_Q;
else if(correctionLevelString == "M")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_M;
else if(correctionLevelString == "L")
correctionLevel = QZXing::EncodeErrorCorrectionLevel_L;
if (optionQuery.hasQueryItem("border"))
border = optionQuery.queryItemValue("border") == "true";
if (optionQuery.hasQueryItem("transparent"))
transparent = optionQuery.queryItemValue("transparent") == "true";
}
else
{
data = id.mid(slashIndex + 1);
}
QZXingEncoderConfig encoderConfig(format, requestedSize, correctionLevel, border, transparent);
QString dataTemp(QUrl::fromPercentEncoding(data.toUtf8()));
QImage result = QZXing::encodeData(dataTemp, encoderConfig);
*size = result.size();
return result;
}

@ -0,0 +1,30 @@
/*
* Copyright 2011 QZXing 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.
*/
#ifndef QZXINGIMAGEPROVIDER_H
#define QZXINGIMAGEPROVIDER_H
#include <QQuickImageProvider>
#include <QImage>
class QZXingImageProvider : public QQuickImageProvider
{
public:
QZXingImageProvider();
QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);
};
#endif // QZXINGIMAGEPROVIDER_H

@ -0,0 +1,28 @@
/*
* Copyright 2011 QZXing 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.
*/
#ifndef QZXING_GLOBAL_H
#define QZXING_GLOBAL_H
#include <QtCore/QtGlobal>
#if defined(QZXING_LIBRARY)
# define QZXINGSHARED_EXPORT Q_DECL_EXPORT
#else
# define QZXINGSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif //QZXING_GLOBAL_H

@ -0,0 +1,11 @@
Qt wrapper library for the ZXing decoding library.
# How to use
## To compile as dynamic library
qmake src/QZXing.pro
make
## Include the complete code to your project
In the .pro file of your project add the following line (update the path to point to the correct location of QZXing src):
include(../../src/QZXing.pri)

@ -0,0 +1,405 @@
#include "BigInteger.hh"
void BigInteger::operator =(const BigInteger &x) {
// Calls like a = a have no effect
if (this == &x)
return;
// Copy sign
sign = x.sign;
// Copy the rest
mag = x.mag;
}
BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
switch (s) {
case zero:
if (!mag.isZero())
throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude";
sign = zero;
break;
case positive:
case negative:
// If the magnitude is zero, force the sign to zero.
sign = mag.isZero() ? zero : s;
break;
default:
/* g++ seems to be optimizing out this case on the assumption
* that the sign is a valid member of the enumeration. Oh well. */
throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign";
}
}
BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
switch (s) {
case zero:
if (!mag.isZero())
throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude";
sign = zero;
break;
case positive:
case negative:
// If the magnitude is zero, force the sign to zero.
sign = mag.isZero() ? zero : s;
break;
default:
/* g++ seems to be optimizing out this case on the assumption
* that the sign is a valid member of the enumeration. Oh well. */
throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign";
}
}
/* CONSTRUCTION FROM PRIMITIVE INTEGERS
* Same idea as in BigUnsigned.cc, except that negative input results in a
* negative BigInteger instead of an exception. */
// Done longhand to let us use initialization.
BigInteger::BigInteger(unsigned long x) : mag(x) { sign = mag.isZero() ? zero : positive; }
BigInteger::BigInteger(unsigned int x) : mag(x) { sign = mag.isZero() ? zero : positive; }
BigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
// For signed input, determine the desired magnitude and sign separately.
namespace {
template <class X, class UX>
BigInteger::Blk magOf(X x) {
/* UX(...) cast needed to stop short(-2^15), which negates to
* itself, from sign-extending in the conversion to Blk. */
return BigInteger::Blk(x < 0 ? UX(-x) : x);
}
template <class X>
BigInteger::Sign signOf(X x) {
return (x == 0) ? BigInteger::zero
: (x > 0) ? BigInteger::positive
: BigInteger::negative;
}
}
BigInteger::BigInteger(long x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
BigInteger::BigInteger(int x) : sign(signOf(x)), mag(magOf<int , unsigned int >(x)) {}
BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
// CONVERSION TO PRIMITIVE INTEGERS
/* Reuse BigUnsigned's conversion to an unsigned primitive integer.
* The friend is a separate function rather than
* BigInteger::convertToUnsignedPrimitive to avoid requiring BigUnsigned to
* declare BigInteger. */
template <class X>
inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) {
return a.convertToPrimitive<X>();
}
template <class X>
X BigInteger::convertToUnsignedPrimitive() const {
if (sign == negative)
throw "BigInteger::to<Primitive>: "
"Cannot convert a negative integer to an unsigned type";
else
return convertBigUnsignedToPrimitiveAccess<X>(mag);
}
/* Similar to BigUnsigned::convertToPrimitive, but split into two cases for
* nonnegative and negative numbers. */
template <class X, class UX>
X BigInteger::convertToSignedPrimitive() const {
if (sign == zero)
return 0;
else if (mag.getLength() == 1) {
// The single block might fit in an X. Try the conversion.
Blk b = mag.getBlock(0);
if (sign == positive) {
X x = X(b);
if (x >= 0 && Blk(x) == b)
return x;
} else {
X x = -X(b);
/* UX(...) needed to avoid rejecting conversion of
* -2^15 to a short. */
if (x < 0 && Blk(UX(-x)) == b)
return x;
}
// Otherwise fall through.
}
throw "BigInteger::to<Primitive>: "
"Value is too big to fit in the requested type";
}
unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive<unsigned long > (); }
unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive<unsigned int > (); }
unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive<unsigned short> (); }
long BigInteger::toLong () const { return convertToSignedPrimitive <long , unsigned long> (); }
int BigInteger::toInt () const { return convertToSignedPrimitive <int , unsigned int> (); }
short BigInteger::toShort () const { return convertToSignedPrimitive <short, unsigned short>(); }
// COMPARISON
BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
// A greater sign implies a greater number
if (sign < x.sign)
return less;
else if (sign > x.sign)
return greater;
else switch (sign) {
// If the signs are the same...
case zero:
return equal; // Two zeros are equal
case positive:
// Compare the magnitudes
return mag.compareTo(x.mag);
case negative:
// Compare the magnitudes, but return the opposite result
return CmpRes(-mag.compareTo(x.mag));
default:
throw "BigInteger internal error";
}
}
/* COPY-LESS OPERATIONS
* These do some messing around to determine the sign of the result,
* then call one of BigUnsigned's copy-less operations. */
// See remarks about aliased calls in BigUnsigned.cc .
#define DTRT_ALIASED(cond, op) \
if (cond) { \
BigInteger tmpThis; \
tmpThis.op; \
*this = tmpThis; \
return; \
}
void BigInteger::add(const BigInteger &a, const BigInteger &b) {
DTRT_ALIASED(this == &a || this == &b, add(a, b));
// If one argument is zero, copy the other.
if (a.sign == zero)
operator =(b);
else if (b.sign == zero)
operator =(a);
// If the arguments have the same sign, take the
// common sign and add their magnitudes.
else if (a.sign == b.sign) {
sign = a.sign;
mag.add(a.mag, b.mag);
} else {
// Otherwise, their magnitudes must be compared.
switch (a.mag.compareTo(b.mag)) {
case equal:
// If their magnitudes are the same, copy zero.
mag = 0;
sign = zero;
break;
// Otherwise, take the sign of the greater, and subtract
// the lesser magnitude from the greater magnitude.
case greater:
sign = a.sign;
mag.subtract(a.mag, b.mag);
break;
case less:
sign = b.sign;
mag.subtract(b.mag, a.mag);
break;
}
}
}
void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
// Notice that this routine is identical to BigInteger::add,
// if one replaces b.sign by its opposite.
DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
// If a is zero, copy b and flip its sign. If b is zero, copy a.
if (a.sign == zero) {
mag = b.mag;
// Take the negative of _b_'s, sign, not ours.
// Bug pointed out by Sam Larkin on 2005.03.30.
sign = Sign(-b.sign);
} else if (b.sign == zero)
operator =(a);
// If their signs differ, take a.sign and add the magnitudes.
else if (a.sign != b.sign) {
sign = a.sign;
mag.add(a.mag, b.mag);
} else {
// Otherwise, their magnitudes must be compared.
switch (a.mag.compareTo(b.mag)) {
// If their magnitudes are the same, copy zero.
case equal:
mag = 0;
sign = zero;
break;
// If a's magnitude is greater, take a.sign and
// subtract a from b.
case greater:
sign = a.sign;
mag.subtract(a.mag, b.mag);
break;
// If b's magnitude is greater, take the opposite
// of b.sign and subtract b from a.
case less:
sign = Sign(-b.sign);
mag.subtract(b.mag, a.mag);
break;
}
}
}
void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
// If one object is zero, copy zero and return.
if (a.sign == zero || b.sign == zero) {
sign = zero;
mag = 0;
return;
}
// If the signs of the arguments are the same, the result
// is positive, otherwise it is negative.
sign = (a.sign == b.sign) ? positive : negative;
// Multiply the magnitudes.
mag.multiply(a.mag, b.mag);
}
/*
* DIVISION WITH REMAINDER
* Please read the comments before the definition of
* `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
* information you should know before reading this function.
*
* Following Knuth, I decree that x / y is to be
* 0 if y==0 and floor(real-number x / y) if y!=0.
* Then x % y shall be x - y*(integer x / y).
*
* Note that x = y * (x / y) + (x % y) always holds.
* In addition, (x % y) is from 0 to y - 1 if y > 0,
* and from -(|y| - 1) to 0 if y < 0. (x % y) = x if y = 0.
*
* Examples: (q = a / b, r = a % b)
* a b q r
* === === === ===
* 4 3 1 1
* -4 3 -2 2
* 4 -3 -2 -2
* -4 -3 1 -1
*/
void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
// Defend against aliased calls;
// same idea as in BigUnsigned::divideWithRemainder .
if (this == &q)
throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
if (this == &b || &q == &b) {
BigInteger tmpB(b);
divideWithRemainder(tmpB, q);
return;
}
// Division by zero gives quotient 0 and remainder *this
if (b.sign == zero) {
q.mag = 0;
q.sign = zero;
return;
}
// 0 / b gives quotient 0 and remainder 0
if (sign == zero) {
q.mag = 0;
q.sign = zero;
return;
}
// Here *this != 0, b != 0.
// Do the operands have the same sign?
if (sign == b.sign) {
// Yes: easy case. Quotient is zero or positive.
q.sign = positive;
} else {
// No: harder case. Quotient is negative.
q.sign = negative;
// Decrease the magnitude of the dividend by one.
mag--;
/*
* We tinker with the dividend before and with the
* quotient and remainder after so that the result
* comes out right. To see why it works, consider the following
* list of examples, where A is the magnitude-decreased
* a, Q and R are the results of BigUnsigned division
* with remainder on A and |b|, and q and r are the
* final results we want:
*
* a A b Q R q r
* -3 -2 3 0 2 -1 0
* -4 -3 3 1 0 -2 2
* -5 -4 3 1 1 -2 1
* -6 -5 3 1 2 -2 0
*
* It appears that we need a total of 3 corrections:
* Decrease the magnitude of a to get A. Increase the
* magnitude of Q to get q (and make it negative).
* Find r = (b - 1) - R and give it the desired sign.
*/
}
// Divide the magnitudes.
mag.divideWithRemainder(b.mag, q.mag);
if (sign != b.sign) {
// More for the harder case (as described):
// Increase the magnitude of the quotient by one.
q.mag++;
// Modify the remainder.
mag.subtract(b.mag, mag);
mag--;
}
// Sign of the remainder is always the sign of the divisor b.
sign = b.sign;
// Set signs to zero as necessary. (Thanks David Allen!)
if (mag.isZero())
sign = zero;
if (q.mag.isZero())
q.sign = zero;
// WHEW!!!
}
// Negation
void BigInteger::negate(const BigInteger &a) {
DTRT_ALIASED(this == &a, negate(a));
// Copy a's magnitude
mag = a.mag;
// Copy the opposite of a.sign
sign = Sign(-a.sign);
}
// INCREMENT/DECREMENT OPERATORS
// Prefix increment
void BigInteger::operator ++() {
if (sign == negative) {
mag--;
if (mag == 0)
sign = zero;
} else {
mag++;
sign = positive; // if not already
}
}
// Postfix increment: same as prefix
void BigInteger::operator ++(int) {
operator ++();
}
// Prefix decrement
void BigInteger::operator --() {
if (sign == positive) {
mag--;
if (mag == 0)
sign = zero;
} else {
mag++;
sign = negative;
}
}
// Postfix decrement: same as prefix
void BigInteger::operator --(int) {
operator --();
}

@ -0,0 +1,215 @@
#ifndef BIGINTEGER_H
#define BIGINTEGER_H
#include "BigUnsigned.hh"
/* A BigInteger object represents a signed integer of size limited only by
* available memory. BigUnsigneds support most mathematical operators and can
* be converted to and from most primitive integer types.
*
* A BigInteger is just an aggregate of a BigUnsigned and a sign. (It is no
* longer derived from BigUnsigned because that led to harmful implicit
* conversions.) */
class BigInteger {
public:
typedef BigUnsigned::Blk Blk;
typedef BigUnsigned::Index Index;
typedef BigUnsigned::CmpRes CmpRes;
static const CmpRes
less = BigUnsigned::less ,
equal = BigUnsigned::equal ,
greater = BigUnsigned::greater;
// Enumeration for the sign of a BigInteger.
enum Sign { negative = -1, zero = 0, positive = 1 };
protected:
Sign sign;
BigUnsigned mag;
public:
// Constructs zero.
BigInteger() : sign(zero), mag() {}
// Copy constructor
BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {};
// Assignment operator
void operator=(const BigInteger &x);
// Constructor that copies from a given array of blocks with a sign.
BigInteger(const Blk *b, Index blen, Sign s);
// Nonnegative constructor that copies from a given array of blocks.
BigInteger(const Blk *b, Index blen) : mag(b, blen) {
sign = mag.isZero() ? zero : positive;
}
// Constructor from a BigUnsigned and a sign
BigInteger(const BigUnsigned &x, Sign s);
// Nonnegative constructor from a BigUnsigned
BigInteger(const BigUnsigned &x) : mag(x) {
sign = mag.isZero() ? zero : positive;
}
// Constructors from primitive integer types
BigInteger(unsigned long x);
BigInteger( long x);
BigInteger(unsigned int x);
BigInteger( int x);
BigInteger(unsigned short x);
BigInteger( short x);
/* Converters to primitive integer types
* The implicit conversion operators caused trouble, so these are now
* named. */
unsigned long toUnsignedLong () const;
long toLong () const;
unsigned int toUnsignedInt () const;
int toInt () const;
unsigned short toUnsignedShort() const;
short toShort () const;
protected:
// Helper
template <class X> X convertToUnsignedPrimitive() const;
template <class X, class UX> X convertToSignedPrimitive() const;
public:
// ACCESSORS
Sign getSign() const { return sign; }
/* The client can't do any harm by holding a read-only reference to the
* magnitude. */
const BigUnsigned &getMagnitude() const { return mag; }
// Some accessors that go through to the magnitude
Index getLength() const { return mag.getLength(); }
Index getCapacity() const { return mag.getCapacity(); }
Blk getBlock(Index i) const { return mag.getBlock(i); }
bool isZero() const { return sign == zero; } // A bit special
// COMPARISONS
// Compares this to x like Perl's <=>
CmpRes compareTo(const BigInteger &x) const;
// Ordinary comparison operators
bool operator ==(const BigInteger &x) const {
return sign == x.sign && mag == x.mag;
}
bool operator !=(const BigInteger &x) const { return !operator ==(x); };
bool operator < (const BigInteger &x) const { return compareTo(x) == less ; }
bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
bool operator >=(const BigInteger &x) const { return compareTo(x) != less ; }
bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
// OPERATORS -- See the discussion in BigUnsigned.hh.
void add (const BigInteger &a, const BigInteger &b);
void subtract(const BigInteger &a, const BigInteger &b);
void multiply(const BigInteger &a, const BigInteger &b);
/* See the comment on BigUnsigned::divideWithRemainder. Semantics
* differ from those of primitive integers when negatives and/or zeros
* are involved. */
void divideWithRemainder(const BigInteger &b, BigInteger &q);
void negate(const BigInteger &a);
/* Bitwise operators are not provided for BigIntegers. Use
* getMagnitude to get the magnitude and operate on that instead. */
BigInteger operator +(const BigInteger &x) const;
BigInteger operator -(const BigInteger &x) const;
BigInteger operator *(const BigInteger &x) const;
BigInteger operator /(const BigInteger &x) const;
BigInteger operator %(const BigInteger &x) const;
BigInteger operator -() const;
void operator +=(const BigInteger &x);
void operator -=(const BigInteger &x);
void operator *=(const BigInteger &x);
void operator /=(const BigInteger &x);
void operator %=(const BigInteger &x);
void flipSign();
// INCREMENT/DECREMENT OPERATORS
void operator ++( );
void operator ++(int);
void operator --( );
void operator --(int);
};
// NORMAL OPERATORS
/* These create an object to hold the result and invoke
* the appropriate put-here operation on it, passing
* this and x. The new object is then returned. */
inline BigInteger BigInteger::operator +(const BigInteger &x) const {
BigInteger ans;
ans.add(*this, x);
return ans;
}
inline BigInteger BigInteger::operator -(const BigInteger &x) const {
BigInteger ans;
ans.subtract(*this, x);
return ans;
}
inline BigInteger BigInteger::operator *(const BigInteger &x) const {
BigInteger ans;
ans.multiply(*this, x);
return ans;
}
inline BigInteger BigInteger::operator /(const BigInteger &x) const {
if (x.isZero()) throw "BigInteger::operator /: division by zero";
BigInteger q, r;
r = *this;
r.divideWithRemainder(x, q);
return q;
}
inline BigInteger BigInteger::operator %(const BigInteger &x) const {
if (x.isZero()) throw "BigInteger::operator %: division by zero";
BigInteger q, r;
r = *this;
r.divideWithRemainder(x, q);
return r;
}
inline BigInteger BigInteger::operator -() const {
BigInteger ans;
ans.negate(*this);
return ans;
}
/*
* ASSIGNMENT OPERATORS
*
* Now the responsibility for making a temporary copy if necessary
* belongs to the put-here operations. See Assignment Operators in
* BigUnsigned.hh.
*/
inline void BigInteger::operator +=(const BigInteger &x) {
add(*this, x);
}
inline void BigInteger::operator -=(const BigInteger &x) {
subtract(*this, x);
}
inline void BigInteger::operator *=(const BigInteger &x) {
multiply(*this, x);
}
inline void BigInteger::operator /=(const BigInteger &x) {
if (x.isZero()) throw "BigInteger::operator /=: division by zero";
/* The following technique is slightly faster than copying *this first
* when x is large. */
BigInteger q;
divideWithRemainder(x, q);
// *this contains the remainder, but we overwrite it with the quotient.
*this = q;
}
inline void BigInteger::operator %=(const BigInteger &x) {
if (x.isZero()) throw "BigInteger::operator %=: division by zero";
BigInteger q;
// Mods *this by x. Don't care about quotient left in q.
divideWithRemainder(x, q);
}
// This one is trivial
inline void BigInteger::flipSign() {
sign = Sign(-sign);
}
#endif

@ -0,0 +1,70 @@
#include "BigIntegerAlgorithms.hh"
BigUnsigned gcd(BigUnsigned a, BigUnsigned b) {
BigUnsigned trash;
// Neat in-place alternating technique.
for (;;) {
if (b.isZero())
return a;
a.divideWithRemainder(b, trash);
if (a.isZero())
return b;
b.divideWithRemainder(a, trash);
}
}
void extendedEuclidean(BigInteger m, BigInteger n,
BigInteger &g, BigInteger &r, BigInteger &s) {
if (&g == &r || &g == &s || &r == &s)
throw "BigInteger extendedEuclidean: Outputs are aliased";
BigInteger r1(1), s1(0), r2(0), s2(1), q;
/* Invariants:
* r1*m(orig) + s1*n(orig) == m(current)
* r2*m(orig) + s2*n(orig) == n(current) */
for (;;) {
if (n.isZero()) {
r = r1; s = s1; g = m;
return;
}
// Subtract q times the second invariant from the first invariant.
m.divideWithRemainder(n, q);
r1 -= q*r2; s1 -= q*s2;
if (m.isZero()) {
r = r2; s = s2; g = n;
return;
}
// Subtract q times the first invariant from the second invariant.
n.divideWithRemainder(m, q);
r2 -= q*r1; s2 -= q*s1;
}
}
BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n) {
BigInteger g, r, s;
extendedEuclidean(x, n, g, r, s);
if (g == 1)
// r*x + s*n == 1, so r*x === 1 (mod n), so r is the answer.
return (r % n).getMagnitude(); // (r % n) will be nonnegative
else
throw "BigInteger modinv: x and n have a common factor";
}
BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
const BigUnsigned &modulus) {
BigUnsigned ans = 1, base2 = (base % modulus).getMagnitude();
BigUnsigned::Index i = exponent.bitLength();
// For each bit of the exponent, most to least significant...
while (i > 0) {
i--;
// Square.
ans *= ans;
ans %= modulus;
// And multiply if the bit is a 1.
if (exponent.getBit(i)) {
ans *= base2;
ans %= modulus;
}
}
return ans;
}

@ -0,0 +1,25 @@
#ifndef BIGINTEGERALGORITHMS_H
#define BIGINTEGERALGORITHMS_H
#include "BigInteger.hh"
/* Some mathematical algorithms for big integers.
* This code is new and, as such, experimental. */
// Returns the greatest common divisor of a and b.
BigUnsigned gcd(BigUnsigned a, BigUnsigned b);
/* Extended Euclidean algorithm.
* Given m and n, finds gcd g and numbers r, s such that r*m + s*n == g. */
void extendedEuclidean(BigInteger m, BigInteger n,
BigInteger &g, BigInteger &r, BigInteger &s);
/* Returns the multiplicative inverse of x modulo n, or throws an exception if
* they have a common factor. */
BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n);
// Returns (base ^ exponent) % modulus.
BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
const BigUnsigned &modulus);
#endif

@ -0,0 +1,8 @@
// This header file includes all of the library header files.
#include "NumberlikeArray.hh"
#include "BigUnsigned.hh"
#include "BigInteger.hh"
#include "BigIntegerAlgorithms.hh"
#include "BigUnsignedInABase.hh"
#include "BigIntegerUtils.hh"

@ -0,0 +1,50 @@
#include "BigIntegerUtils.hh"
#include "BigUnsignedInABase.hh"
std::string bigUnsignedToString(const BigUnsigned &x) {
return std::string(BigUnsignedInABase(x, 10));
}
std::string bigIntegerToString(const BigInteger &x) {
return (x.getSign() == BigInteger::negative)
? (std::string("-") + bigUnsignedToString(x.getMagnitude()))
: (bigUnsignedToString(x.getMagnitude()));
}
BigUnsigned stringToBigUnsigned(const std::string &s) {
return BigUnsigned(BigUnsignedInABase(s, 10));
}
BigInteger stringToBigInteger(const std::string &s) {
// Recognize a sign followed by a BigUnsigned.
return (s[0] == '-') ? BigInteger(stringToBigUnsigned(s.substr(1, s.length() - 1)), BigInteger::negative)
: (s[0] == '+') ? BigInteger(stringToBigUnsigned(s.substr(1, s.length() - 1)))
: BigInteger(stringToBigUnsigned(s));
}
std::ostream &operator <<(std::ostream &os, const BigUnsigned &x) {
BigUnsignedInABase::Base base;
long osFlags = os.flags();
if (osFlags & os.dec)
base = 10;
else if (osFlags & os.hex) {
base = 16;
if (osFlags & os.showbase)
os << "0x";
} else if (osFlags & os.oct) {
base = 8;
if (osFlags & os.showbase)
os << '0';
} else
throw "std::ostream << BigUnsigned: Could not determine the desired base from output-stream flags";
std::string s = std::string(BigUnsignedInABase(x, base));
os << s;
return os;
}
std::ostream &operator <<(std::ostream &os, const BigInteger &x) {
if (x.getSign() == BigInteger::negative)
os << '-';
os << x.getMagnitude();
return os;
}

@ -0,0 +1,72 @@
#ifndef BIGINTEGERUTILS_H
#define BIGINTEGERUTILS_H
#include "BigInteger.hh"
#include <string>
#include <iostream>
/* This file provides:
* - Convenient std::string <-> BigUnsigned/BigInteger conversion routines
* - std::ostream << operators for BigUnsigned/BigInteger */
// std::string conversion routines. Base 10 only.
std::string bigUnsignedToString(const BigUnsigned &x);
std::string bigIntegerToString(const BigInteger &x);
BigUnsigned stringToBigUnsigned(const std::string &s);
BigInteger stringToBigInteger(const std::string &s);
// Creates a BigInteger from data such as `char's; read below for details.
template <class T>
BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign);
// Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
std::ostream &operator <<(std::ostream &os, const BigUnsigned &x);
// Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
// My somewhat arbitrary policy: a negative sign comes before a base indicator (like -0xFF).
std::ostream &operator <<(std::ostream &os, const BigInteger &x);
// BEGIN TEMPLATE DEFINITIONS.
/*
* Converts binary data to a BigInteger.
* Pass an array `data', its length, and the desired sign.
*
* Elements of `data' may be of any type `T' that has the following
* two properties (this includes almost all integral types):
*
* (1) `sizeof(T)' correctly gives the amount of binary data in one
* value of `T' and is a factor of `sizeof(Blk)'.
*
* (2) When a value of `T' is casted to a `Blk', the low bytes of
* the result contain the desired binary data.
*/
template <class T>
BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign) {
// really ceiling(numBytes / sizeof(BigInteger::Blk))
unsigned int pieceSizeInBits = 8 * sizeof(T);
unsigned int piecesPerBlock = sizeof(BigInteger::Blk) / sizeof(T);
unsigned int numBlocks = (length + piecesPerBlock - 1) / piecesPerBlock;
// Allocate our block array
BigInteger::Blk *blocks = new BigInteger::Blk[numBlocks];
BigInteger::Index blockNum, pieceNum, pieceNumHere;
// Convert
for (blockNum = 0, pieceNum = 0; blockNum < numBlocks; blockNum++) {
BigInteger::Blk curBlock = 0;
for (pieceNumHere = 0; pieceNumHere < piecesPerBlock && pieceNum < length;
pieceNumHere++, pieceNum++)
curBlock |= (BigInteger::Blk(data[pieceNum]) << (pieceSizeInBits * pieceNumHere));
blocks[blockNum] = curBlock;
}
// Create the BigInteger.
BigInteger x(blocks, numBlocks, sign);
delete [] blocks;
return x;
}
#endif

@ -0,0 +1,697 @@
#include "BigUnsigned.hh"
// Memory management definitions have moved to the bottom of NumberlikeArray.hh.
// The templates used by these constructors and converters are at the bottom of
// BigUnsigned.hh.
BigUnsigned::BigUnsigned(unsigned long x) { initFromPrimitive (x); }
BigUnsigned::BigUnsigned(unsigned int x) { initFromPrimitive (x); }
BigUnsigned::BigUnsigned(unsigned short x) { initFromPrimitive (x); }
BigUnsigned::BigUnsigned( long x) { initFromSignedPrimitive(x); }
BigUnsigned::BigUnsigned( int x) { initFromSignedPrimitive(x); }
BigUnsigned::BigUnsigned( short x) { initFromSignedPrimitive(x); }
unsigned long BigUnsigned::toUnsignedLong () const { return convertToPrimitive <unsigned long >(); }
unsigned int BigUnsigned::toUnsignedInt () const { return convertToPrimitive <unsigned int >(); }
unsigned short BigUnsigned::toUnsignedShort() const { return convertToPrimitive <unsigned short>(); }
long BigUnsigned::toLong () const { return convertToSignedPrimitive< long >(); }
int BigUnsigned::toInt () const { return convertToSignedPrimitive< int >(); }
short BigUnsigned::toShort () const { return convertToSignedPrimitive< short>(); }
// BIT/BLOCK ACCESSORS
void BigUnsigned::setBlock(Index i, Blk newBlock) {
if (newBlock == 0) {
if (i < len) {
blk[i] = 0;
zapLeadingZeros();
}
// If i >= len, no effect.
} else {
if (i >= len) {
// The nonzero block extends the number.
allocateAndCopy(i+1);
// Zero any added blocks that we aren't setting.
for (Index j = len; j < i; j++)
blk[j] = 0;
len = i+1;
}
blk[i] = newBlock;
}
}
/* Evidently the compiler wants BigUnsigned:: on the return type because, at
* that point, it hasn't yet parsed the BigUnsigned:: on the name to get the
* proper scope. */
BigUnsigned::Index BigUnsigned::bitLength() const {
if (isZero())
return 0;
else {
Blk leftmostBlock = getBlock(len - 1);
Index leftmostBlockLen = 0;
while (leftmostBlock != 0) {
leftmostBlock >>= 1;
leftmostBlockLen++;
}
return leftmostBlockLen + (len - 1) * N;
}
}
void BigUnsigned::setBit(Index bi, bool newBit) {
Index blockI = bi / N;
Blk block = getBlock(blockI), mask = Blk(1) << (bi % N);
block = newBit ? (block | mask) : (block & ~mask);
setBlock(blockI, block);
}
// COMPARISON
BigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const {
// A bigger length implies a bigger number.
if (len < x.len)
return less;
else if (len > x.len)
return greater;
else {
// Compare blocks one by one from left to right.
Index i = len;
while (i > 0) {
i--;
if (blk[i] == x.blk[i])
continue;
else if (blk[i] > x.blk[i])
return greater;
else
return less;
}
// If no blocks differed, the numbers are equal.
return equal;
}
}
// COPY-LESS OPERATIONS
/*
* On most calls to copy-less operations, it's safe to read the inputs little by
* little and write the outputs little by little. However, if one of the
* inputs is coming from the same variable into which the output is to be
* stored (an "aliased" call), we risk overwriting the input before we read it.
* In this case, we first compute the result into a temporary BigUnsigned
* variable and then copy it into the requested output variable *this.
* Each put-here operation uses the DTRT_ALIASED macro (Do The Right Thing on
* aliased calls) to generate code for this check.
*
* I adopted this approach on 2007.02.13 (see Assignment Operators in
* BigUnsigned.hh). Before then, put-here operations rejected aliased calls
* with an exception. I think doing the right thing is better.
*
* Some of the put-here operations can probably handle aliased calls safely
* without the extra copy because (for example) they process blocks strictly
* right-to-left. At some point I might determine which ones don't need the
* copy, but my reasoning would need to be verified very carefully. For now
* I'll leave in the copy.
*/
#define DTRT_ALIASED(cond, op) \
if (cond) { \
BigUnsigned tmpThis; \
tmpThis.op; \
*this = tmpThis; \
return; \
}
void BigUnsigned::add(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, add(a, b));
// If one argument is zero, copy the other.
if (a.len == 0) {
operator =(b);
return;
} else if (b.len == 0) {
operator =(a);
return;
}
// Some variables...
// Carries in and out of an addition stage
bool carryIn, carryOut;
Blk temp;
Index i;
// a2 points to the longer input, b2 points to the shorter
const BigUnsigned *a2, *b2;
if (a.len >= b.len) {
a2 = &a;
b2 = &b;
} else {
a2 = &b;
b2 = &a;
}
// Set prelimiary length and make room in this BigUnsigned
len = a2->len + 1;
allocate(len);
// For each block index that is present in both inputs...
for (i = 0, carryIn = false; i < b2->len; i++) {
// Add input blocks
temp = a2->blk[i] + b2->blk[i];
// If a rollover occurred, the result is less than either input.
// This test is used many times in the BigUnsigned code.
carryOut = (temp < a2->blk[i]);
// If a carry was input, handle it
if (carryIn) {
temp++;
carryOut |= (temp == 0);
}
blk[i] = temp; // Save the addition result
carryIn = carryOut; // Pass the carry along
}
// If there is a carry left over, increase blocks until
// one does not roll over.
for (; i < a2->len && carryIn; i++) {
temp = a2->blk[i] + 1;
carryIn = (temp == 0);
blk[i] = temp;
}
// If the carry was resolved but the larger number
// still has blocks, copy them over.
for (; i < a2->len; i++)
blk[i] = a2->blk[i];
// Set the extra block if there's still a carry, decrease length otherwise
if (carryIn)
blk[i] = 1;
else
len--;
}
void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
if (b.len == 0) {
// If b is zero, copy a.
operator =(a);
return;
} else if (a.len < b.len)
// If a is shorter than b, the result is negative.
throw "BigUnsigned::subtract: "
"Negative result in unsigned calculation";
// Some variables...
bool borrowIn, borrowOut;
Blk temp;
Index i;
// Set preliminary length and make room
len = a.len;
allocate(len);
// For each block index that is present in both inputs...
for (i = 0, borrowIn = false; i < b.len; i++) {
temp = a.blk[i] - b.blk[i];
// If a reverse rollover occurred,
// the result is greater than the block from a.
borrowOut = (temp > a.blk[i]);
// Handle an incoming borrow
if (borrowIn) {
borrowOut |= (temp == 0);
temp--;
}
blk[i] = temp; // Save the subtraction result
borrowIn = borrowOut; // Pass the borrow along
}
// If there is a borrow left over, decrease blocks until
// one does not reverse rollover.
for (; i < a.len && borrowIn; i++) {
borrowIn = (a.blk[i] == 0);
blk[i] = a.blk[i] - 1;
}
/* If there's still a borrow, the result is negative.
* Throw an exception, but zero out this object so as to leave it in a
* predictable state. */
if (borrowIn) {
len = 0;
throw "BigUnsigned::subtract: Negative result in unsigned calculation";
} else
// Copy over the rest of the blocks
for (; i < a.len; i++)
blk[i] = a.blk[i];
// Zap leading zeros
zapLeadingZeros();
}
/*
* About the multiplication and division algorithms:
*
* I searched unsucessfully for fast C++ built-in operations like the `b_0'
* and `c_0' Knuth describes in Section 4.3.1 of ``The Art of Computer
* Programming'' (replace `place' by `Blk'):
*
* ``b_0[:] multiplication of a one-place integer by another one-place
* integer, giving a two-place answer;
*
* ``c_0[:] division of a two-place integer by a one-place integer,
* provided that the quotient is a one-place integer, and yielding
* also a one-place remainder.''
*
* I also missed his note that ``[b]y adjusting the word size, if
* necessary, nearly all computers will have these three operations
* available'', so I gave up on trying to use algorithms similar to his.
* A future version of the library might include such algorithms; I
* would welcome contributions from others for this.
*
* I eventually decided to use bit-shifting algorithms. To multiply `a'
* and `b', we zero out the result. Then, for each `1' bit in `a', we
* shift `b' left the appropriate amount and add it to the result.
* Similarly, to divide `a' by `b', we shift `b' left varying amounts,
* repeatedly trying to subtract it from `a'. When we succeed, we note
* the fact by setting a bit in the quotient. While these algorithms
* have the same O(n^2) time complexity as Knuth's, the ``constant factor''
* is likely to be larger.
*
* Because I used these algorithms, which require single-block addition
* and subtraction rather than single-block multiplication and division,
* the innermost loops of all four routines are very similar. Study one
* of them and all will become clear.
*/
/*
* This is a little inline function used by both the multiplication
* routine and the division routine.
*
* `getShiftedBlock' returns the `x'th block of `num << y'.
* `y' may be anything from 0 to N - 1, and `x' may be anything from
* 0 to `num.len'.
*
* Two things contribute to this block:
*
* (1) The `N - y' low bits of `num.blk[x]', shifted `y' bits left.
*
* (2) The `y' high bits of `num.blk[x-1]', shifted `N - y' bits right.
*
* But we must be careful if `x == 0' or `x == num.len', in
* which case we should use 0 instead of (2) or (1), respectively.
*
* If `y == 0', then (2) contributes 0, as it should. However,
* in some computer environments, for a reason I cannot understand,
* `a >> b' means `a >> (b % N)'. This means `num.blk[x-1] >> (N - y)'
* will return `num.blk[x-1]' instead of the desired 0 when `y == 0';
* the test `y == 0' handles this case specially.
*/
inline BigUnsigned::Blk getShiftedBlock(const BigUnsigned &num,
BigUnsigned::Index x, unsigned int y) {
BigUnsigned::Blk part1 = (x == 0 || y == 0) ? 0 : (num.blk[x - 1] >> (BigUnsigned::N - y));
BigUnsigned::Blk part2 = (x == num.len) ? 0 : (num.blk[x] << y);
return part1 | part2;
}
void BigUnsigned::multiply(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
// If either a or b is zero, set to zero.
if (a.len == 0 || b.len == 0) {
len = 0;
return;
}
/*
* Overall method:
*
* Set this = 0.
* For each 1-bit of `a' (say the `i2'th bit of block `i'):
* Add `b << (i blocks and i2 bits)' to *this.
*/
// Variables for the calculation
Index i, j, k;
unsigned int i2;
Blk temp;
bool carryIn, carryOut;
// Set preliminary length and make room
len = a.len + b.len;
allocate(len);
// Zero out this object
for (i = 0; i < len; i++)
blk[i] = 0;
// For each block of the first number...
for (i = 0; i < a.len; i++) {
// For each 1-bit of that block...
for (i2 = 0; i2 < N; i2++) {
if ((a.blk[i] & (Blk(1) << i2)) == 0)
continue;
/*
* Add b to this, shifted left i blocks and i2 bits.
* j is the index in b, and k = i + j is the index in this.
*
* `getShiftedBlock', a short inline function defined above,
* is now used for the bit handling. It replaces the more
* complex `bHigh' code, in which each run of the loop dealt
* immediately with the low bits and saved the high bits to
* be picked up next time. The last run of the loop used to
* leave leftover high bits, which were handled separately.
* Instead, this loop runs an additional time with j == b.len.
* These changes were made on 2005.01.11.
*/
for (j = 0, k = i, carryIn = false; j <= b.len; j++, k++) {
/*
* The body of this loop is very similar to the body of the first loop
* in `add', except that this loop does a `+=' instead of a `+'.
*/
temp = blk[k] + getShiftedBlock(b, j, i2);
carryOut = (temp < blk[k]);
if (carryIn) {
temp++;
carryOut |= (temp == 0);
}
blk[k] = temp;
carryIn = carryOut;
}
// No more extra iteration to deal with `bHigh'.
// Roll-over a carry as necessary.
for (; carryIn; k++) {
blk[k]++;
carryIn = (blk[k] == 0);
}
}
}
// Zap possible leading zero
if (blk[len - 1] == 0)
len--;
}
/*
* DIVISION WITH REMAINDER
* This monstrous function mods *this by the given divisor b while storing the
* quotient in the given object q; at the end, *this contains the remainder.
* The seemingly bizarre pattern of inputs and outputs was chosen so that the
* function copies as little as possible (since it is implemented by repeated
* subtraction of multiples of b from *this).
*
* "modWithQuotient" might be a better name for this function, but I would
* rather not change the name now.
*/
void BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) {
/* Defending against aliased calls is more complex than usual because we
* are writing to both *this and q.
*
* It would be silly to try to write quotient and remainder to the
* same variable. Rule that out right away. */
if (this == &q)
throw "BigUnsigned::divideWithRemainder: Cannot write quotient and remainder into the same variable";
/* Now *this and q are separate, so the only concern is that b might be
* aliased to one of them. If so, use a temporary copy of b. */
if (this == &b || &q == &b) {
BigUnsigned tmpB(b);
divideWithRemainder(tmpB, q);
return;
}
/*
* Knuth's definition of mod (which this function uses) is somewhat
* different from the C++ definition of % in case of division by 0.
*
* We let a / 0 == 0 (it doesn't matter much) and a % 0 == a, no
* exceptions thrown. This allows us to preserve both Knuth's demand
* that a mod 0 == a and the useful property that
* (a / b) * b + (a % b) == a.
*/
if (b.len == 0) {
q.len = 0;
return;
}
/*
* If *this.len < b.len, then *this < b, and we can be sure that b doesn't go into
* *this at all. The quotient is 0 and *this is already the remainder (so leave it alone).
*/
if (len < b.len) {
q.len = 0;
return;
}
// At this point we know (*this).len >= b.len > 0. (Whew!)
/*
* Overall method:
*
* For each appropriate i and i2, decreasing:
* Subtract (b << (i blocks and i2 bits)) from *this, storing the
* result in subtractBuf.
* If the subtraction succeeds with a nonnegative result:
* Turn on bit i2 of block i of the quotient q.
* Copy subtractBuf back into *this.
* Otherwise bit i2 of block i remains off, and *this is unchanged.
*
* Eventually q will contain the entire quotient, and *this will
* be left with the remainder.
*
* subtractBuf[x] corresponds to blk[x], not blk[x+i], since 2005.01.11.
* But on a single iteration, we don't touch the i lowest blocks of blk
* (and don't use those of subtractBuf) because these blocks are
* unaffected by the subtraction: we are subtracting
* (b << (i blocks and i2 bits)), which ends in at least `i' zero
* blocks. */
// Variables for the calculation
Index i, j, k;
unsigned int i2;
Blk temp;
bool borrowIn, borrowOut;
/*
* Make sure we have an extra zero block just past the value.
*
* When we attempt a subtraction, we might shift `b' so
* its first block begins a few bits left of the dividend,
* and then we'll try to compare these extra bits with
* a nonexistent block to the left of the dividend. The
* extra zero block ensures sensible behavior; we need
* an extra block in `subtractBuf' for exactly the same reason.
*/
Index origLen = len; // Save real length.
/* To avoid an out-of-bounds access in case of reallocation, allocate
* first and then increment the logical length. */
allocateAndCopy(len + 1);
len++;
blk[origLen] = 0; // Zero the added block.
// subtractBuf holds part of the result of a subtraction; see above.
Blk *subtractBuf = new Blk[len];
// Set preliminary length for quotient and make room
q.len = origLen - b.len + 1;
q.allocate(q.len);
// Zero out the quotient
for (i = 0; i < q.len; i++)
q.blk[i] = 0;
// For each possible left-shift of b in blocks...
i = q.len;
while (i > 0) {
i--;
// For each possible left-shift of b in bits...
// (Remember, N is the number of bits in a Blk.)
q.blk[i] = 0;
i2 = N;
while (i2 > 0) {
i2--;
/*
* Subtract b, shifted left i blocks and i2 bits, from *this,
* and store the answer in subtractBuf. In the for loop, `k == i + j'.
*
* Compare this to the middle section of `multiply'. They
* are in many ways analogous. See especially the discussion
* of `getShiftedBlock'.
*/
for (j = 0, k = i, borrowIn = false; j <= b.len; j++, k++) {
temp = blk[k] - getShiftedBlock(b, j, i2);
borrowOut = (temp > blk[k]);
if (borrowIn) {
borrowOut |= (temp == 0);
temp--;
}
// Since 2005.01.11, indices of `subtractBuf' directly match those of `blk', so use `k'.
subtractBuf[k] = temp;
borrowIn = borrowOut;
}
// No more extra iteration to deal with `bHigh'.
// Roll-over a borrow as necessary.
for (; k < origLen && borrowIn; k++) {
borrowIn = (blk[k] == 0);
subtractBuf[k] = blk[k] - 1;
}
/*
* If the subtraction was performed successfully (!borrowIn),
* set bit i2 in block i of the quotient.
*
* Then, copy the portion of subtractBuf filled by the subtraction
* back to *this. This portion starts with block i and ends--
* where? Not necessarily at block `i + b.len'! Well, we
* increased k every time we saved a block into subtractBuf, so
* the region of subtractBuf we copy is just [i, k).
*/
if (!borrowIn) {
q.blk[i] |= (Blk(1) << i2);
while (k > i) {
k--;
blk[k] = subtractBuf[k];
}
}
}
}
// Zap possible leading zero in quotient
if (q.blk[q.len - 1] == 0)
q.len--;
// Zap any/all leading zeros in remainder
zapLeadingZeros();
// Deallocate subtractBuf.
// (Thanks to Brad Spencer for noticing my accidental omission of this!)
delete [] subtractBuf;
}
/* BITWISE OPERATORS
* These are straightforward blockwise operations except that they differ in
* the output length and the necessity of zapLeadingZeros. */
void BigUnsigned::bitAnd(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, bitAnd(a, b));
// The bitwise & can't be longer than either operand.
len = (a.len >= b.len) ? b.len : a.len;
allocate(len);
Index i;
for (i = 0; i < len; i++)
blk[i] = a.blk[i] & b.blk[i];
zapLeadingZeros();
}
void BigUnsigned::bitOr(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, bitOr(a, b));
Index i;
const BigUnsigned *a2, *b2;
if (a.len >= b.len) {
a2 = &a;
b2 = &b;
} else {
a2 = &b;
b2 = &a;
}
allocate(a2->len);
for (i = 0; i < b2->len; i++)
blk[i] = a2->blk[i] | b2->blk[i];
for (; i < a2->len; i++)
blk[i] = a2->blk[i];
len = a2->len;
// Doesn't need zapLeadingZeros.
}
void BigUnsigned::bitXor(const BigUnsigned &a, const BigUnsigned &b) {
DTRT_ALIASED(this == &a || this == &b, bitXor(a, b));
Index i;
const BigUnsigned *a2, *b2;
if (a.len >= b.len) {
a2 = &a;
b2 = &b;
} else {
a2 = &b;
b2 = &a;
}
allocate(a2->len);
for (i = 0; i < b2->len; i++)
blk[i] = a2->blk[i] ^ b2->blk[i];
for (; i < a2->len; i++)
blk[i] = a2->blk[i];
len = a2->len;
zapLeadingZeros();
}
void BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) {
DTRT_ALIASED(this == &a, bitShiftLeft(a, b));
if (b < 0) {
if (b << 1 == 0)
throw "BigUnsigned::bitShiftLeft: "
"Pathological shift amount not implemented";
else {
bitShiftRight(a, -b);
return;
}
}
Index shiftBlocks = b / N;
unsigned int shiftBits = b % N;
// + 1: room for high bits nudged left into another block
len = a.len + shiftBlocks + 1;
allocate(len);
Index i, j;
for (i = 0; i < shiftBlocks; i++)
blk[i] = 0;
for (j = 0, i = shiftBlocks; j <= a.len; j++, i++)
blk[i] = getShiftedBlock(a, j, shiftBits);
// Zap possible leading zero
if (blk[len - 1] == 0)
len--;
}
void BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) {
DTRT_ALIASED(this == &a, bitShiftRight(a, b));
if (b < 0) {
if (b << 1 == 0)
throw "BigUnsigned::bitShiftRight: "
"Pathological shift amount not implemented";
else {
bitShiftLeft(a, -b);
return;
}
}
// This calculation is wacky, but expressing the shift as a left bit shift
// within each block lets us use getShiftedBlock.
Index rightShiftBlocks = (b + N - 1) / N;
unsigned int leftShiftBits = N * rightShiftBlocks - b;
// Now (N * rightShiftBlocks - leftShiftBits) == b
// and 0 <= leftShiftBits < N.
if (rightShiftBlocks >= a.len + 1) {
// All of a is guaranteed to be shifted off, even considering the left
// bit shift.
len = 0;
return;
}
// Now we're allocating a positive amount.
// + 1: room for high bits nudged left into another block
len = a.len + 1 - rightShiftBlocks;
allocate(len);
Index i, j;
for (j = rightShiftBlocks, i = 0; j <= a.len; j++, i++)
blk[i] = getShiftedBlock(a, j, leftShiftBits);
// Zap possible leading zero
if (blk[len - 1] == 0)
len--;
}
// INCREMENT/DECREMENT OPERATORS
// Prefix increment
void BigUnsigned::operator ++() {
Index i;
bool carry = true;
for (i = 0; i < len && carry; i++) {
blk[i]++;
carry = (blk[i] == 0);
}
if (carry) {
// Allocate and then increase length, as in divideWithRemainder
allocateAndCopy(len + 1);
len++;
blk[i] = 1;
}
}
// Postfix increment: same as prefix
void BigUnsigned::operator ++(int) {
operator ++();
}
// Prefix decrement
void BigUnsigned::operator --() {
if (len == 0)
throw "BigUnsigned::operator --(): Cannot decrement an unsigned zero";
Index i;
bool borrow = true;
for (i = 0; borrow; i++) {
borrow = (blk[i] == 0);
blk[i]--;
}
// Zap possible leading zero (there can only be one)
if (blk[len - 1] == 0)
len--;
}
// Postfix decrement: same as prefix
void BigUnsigned::operator --(int) {
operator --();
}

@ -0,0 +1,418 @@
#ifndef BIGUNSIGNED_H
#define BIGUNSIGNED_H
#include "NumberlikeArray.hh"
/* A BigUnsigned object represents a nonnegative integer of size limited only by
* available memory. BigUnsigneds support most mathematical operators and can
* be converted to and from most primitive integer types.
*
* The number is stored as a NumberlikeArray of unsigned longs as if it were
* written in base 256^sizeof(unsigned long). The least significant block is
* first, and the length is such that the most significant block is nonzero. */
class BigUnsigned : protected NumberlikeArray<unsigned long> {
public:
// Enumeration for the result of a comparison.
enum CmpRes { less = -1, equal = 0, greater = 1 };
// BigUnsigneds are built with a Blk type of unsigned long.
typedef unsigned long Blk;
typedef NumberlikeArray<Blk>::Index Index;
using NumberlikeArray<Blk>::N;
protected:
// Creates a BigUnsigned with a capacity; for internal use.
BigUnsigned(int, Index c) : NumberlikeArray<Blk>(0, c) {}
// Decreases len to eliminate any leading zero blocks.
void zapLeadingZeros() {
while (len > 0 && blk[len - 1] == 0)
len--;
}
public:
// Constructs zero.
BigUnsigned() : NumberlikeArray<Blk>() {}
// Copy constructor
BigUnsigned(const BigUnsigned &x) : NumberlikeArray<Blk>(x) {}
// Assignment operator
void operator=(const BigUnsigned &x) {
NumberlikeArray<Blk>::operator =(x);
}
// Constructor that copies from a given array of blocks.
BigUnsigned(const Blk *b, Index blen) : NumberlikeArray<Blk>(b, blen) {
// Eliminate any leading zeros we may have been passed.
zapLeadingZeros();
}
// Destructor. NumberlikeArray does the delete for us.
~BigUnsigned() {}
// Constructors from primitive integer types
BigUnsigned(unsigned long x);
BigUnsigned( long x);
BigUnsigned(unsigned int x);
BigUnsigned( int x);
BigUnsigned(unsigned short x);
BigUnsigned( short x);
protected:
// Helpers
template <class X> void initFromPrimitive (X x);
template <class X> void initFromSignedPrimitive(X x);
public:
/* Converters to primitive integer types
* The implicit conversion operators caused trouble, so these are now
* named. */
unsigned long toUnsignedLong () const;
long toLong () const;
unsigned int toUnsignedInt () const;
int toInt () const;
unsigned short toUnsignedShort() const;
short toShort () const;
protected:
// Helpers
template <class X> X convertToSignedPrimitive() const;
template <class X> X convertToPrimitive () const;
public:
// BIT/BLOCK ACCESSORS
// Expose these from NumberlikeArray directly.
using NumberlikeArray<Blk>::getCapacity;
using NumberlikeArray<Blk>::getLength;
/* Returns the requested block, or 0 if it is beyond the length (as if
* the number had 0s infinitely to the left). */
Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; }
/* Sets the requested block. The number grows or shrinks as necessary. */
void setBlock(Index i, Blk newBlock);
// The number is zero if and only if the canonical length is zero.
bool isZero() const { return NumberlikeArray<Blk>::isEmpty(); }
/* Returns the length of the number in bits, i.e., zero if the number
* is zero and otherwise one more than the largest value of bi for
* which getBit(bi) returns true. */
Index bitLength() const;
/* Get the state of bit bi, which has value 2^bi. Bits beyond the
* number's length are considered to be 0. */
bool getBit(Index bi) const {
return (getBlock(bi / N) & (Blk(1) << (bi % N))) != 0;
}
/* Sets the state of bit bi to newBit. The number grows or shrinks as
* necessary. */
void setBit(Index bi, bool newBit);
// COMPARISONS
// Compares this to x like Perl's <=>
CmpRes compareTo(const BigUnsigned &x) const;
// Ordinary comparison operators
bool operator ==(const BigUnsigned &x) const {
return NumberlikeArray<Blk>::operator ==(x);
}
bool operator !=(const BigUnsigned &x) const {
return NumberlikeArray<Blk>::operator !=(x);
}
bool operator < (const BigUnsigned &x) const { return compareTo(x) == less ; }
bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; }
bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less ; }
bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; }
/*
* BigUnsigned and BigInteger both provide three kinds of operators.
* Here ``big-integer'' refers to BigInteger or BigUnsigned.
*
* (1) Overloaded ``return-by-value'' operators:
* +, -, *, /, %, unary -, &, |, ^, <<, >>.
* Big-integer code using these operators looks identical to code using
* the primitive integer types. These operators take one or two
* big-integer inputs and return a big-integer result, which can then
* be assigned to a BigInteger variable or used in an expression.
* Example:
* BigInteger a(1), b = 1;
* BigInteger c = a + b;
*
* (2) Overloaded assignment operators:
* +=, -=, *=, /=, %=, flipSign, &=, |=, ^=, <<=, >>=, ++, --.
* Again, these are used on big integers just like on ints. They take
* one writable big integer that both provides an operand and receives a
* result. Most also take a second read-only operand.
* Example:
* BigInteger a(1), b(1);
* a += b;
*
* (3) Copy-less operations: `add', `subtract', etc.
* These named methods take operands as arguments and store the result
* in the receiver (*this), avoiding unnecessary copies and allocations.
* `divideWithRemainder' is special: it both takes the dividend from and
* stores the remainder into the receiver, and it takes a separate
* object in which to store the quotient. NOTE: If you are wondering
* why these don't return a value, you probably mean to use the
* overloaded return-by-value operators instead.
*
* Examples:
* BigInteger a(43), b(7), c, d;
*
* c = a + b; // Now c == 50.
* c.add(a, b); // Same effect but without the two copies.
*
* c.divideWithRemainder(b, d);
* // 50 / 7; now d == 7 (quotient) and c == 1 (remainder).
*
* // ``Aliased'' calls now do the right thing using a temporary
* // copy, but see note on `divideWithRemainder'.
* a.add(a, b);
*/
// COPY-LESS OPERATIONS
// These 8: Arguments are read-only operands, result is saved in *this.
void add(const BigUnsigned &a, const BigUnsigned &b);
void subtract(const BigUnsigned &a, const BigUnsigned &b);
void multiply(const BigUnsigned &a, const BigUnsigned &b);
void bitAnd(const BigUnsigned &a, const BigUnsigned &b);
void bitOr(const BigUnsigned &a, const BigUnsigned &b);
void bitXor(const BigUnsigned &a, const BigUnsigned &b);
/* Negative shift amounts translate to opposite-direction shifts,
* except for -2^(8*sizeof(int)-1) which is unimplemented. */
void bitShiftLeft(const BigUnsigned &a, int b);
void bitShiftRight(const BigUnsigned &a, int b);
/* `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'.
* / and % use semantics similar to Knuth's, which differ from the
* primitive integer semantics under division by zero. See the
* implementation in BigUnsigned.cc for details.
* `a.divideWithRemainder(b, a)' throws an exception: it doesn't make
* sense to write quotient and remainder into the same variable. */
void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
/* `divide' and `modulo' are no longer offered. Use
* `divideWithRemainder' instead. */
// OVERLOADED RETURN-BY-VALUE OPERATORS
BigUnsigned operator +(const BigUnsigned &x) const;
BigUnsigned operator -(const BigUnsigned &x) const;
BigUnsigned operator *(const BigUnsigned &x) const;
BigUnsigned operator /(const BigUnsigned &x) const;
BigUnsigned operator %(const BigUnsigned &x) const;
/* OK, maybe unary minus could succeed in one case, but it really
* shouldn't be used, so it isn't provided. */
BigUnsigned operator &(const BigUnsigned &x) const;
BigUnsigned operator |(const BigUnsigned &x) const;
BigUnsigned operator ^(const BigUnsigned &x) const;
BigUnsigned operator <<(int b) const;
BigUnsigned operator >>(int b) const;
// OVERLOADED ASSIGNMENT OPERATORS
void operator +=(const BigUnsigned &x);
void operator -=(const BigUnsigned &x);
void operator *=(const BigUnsigned &x);
void operator /=(const BigUnsigned &x);
void operator %=(const BigUnsigned &x);
void operator &=(const BigUnsigned &x);
void operator |=(const BigUnsigned &x);
void operator ^=(const BigUnsigned &x);
void operator <<=(int b);
void operator >>=(int b);
/* INCREMENT/DECREMENT OPERATORS
* To discourage messy coding, these do not return *this, so prefix
* and postfix behave the same. */
void operator ++( );
void operator ++(int);
void operator --( );
void operator --(int);
// Helper function that needs access to BigUnsigned internals
friend Blk getShiftedBlock(const BigUnsigned &num, Index x,
unsigned int y);
// See BigInteger.cc.
template <class X>
friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a);
};
/* Implementing the return-by-value and assignment operators in terms of the
* copy-less operations. The copy-less operations are responsible for making
* any necessary temporary copies to work around aliasing. */
inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {
BigUnsigned ans;
ans.add(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {
BigUnsigned ans;
ans.subtract(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {
BigUnsigned ans;
ans.multiply(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {
if (x.isZero()) throw "BigUnsigned::operator /: division by zero";
BigUnsigned q, r;
r = *this;
r.divideWithRemainder(x, q);
return q;
}
inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
if (x.isZero()) throw "BigUnsigned::operator %: division by zero";
BigUnsigned q, r;
r = *this;
r.divideWithRemainder(x, q);
return r;
}
inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitAnd(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitOr(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitXor(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator <<(int b) const {
BigUnsigned ans;
ans.bitShiftLeft(*this, b);
return ans;
}
inline BigUnsigned BigUnsigned::operator >>(int b) const {
BigUnsigned ans;
ans.bitShiftRight(*this, b);
return ans;
}
inline void BigUnsigned::operator +=(const BigUnsigned &x) {
add(*this, x);
}
inline void BigUnsigned::operator -=(const BigUnsigned &x) {
subtract(*this, x);
}
inline void BigUnsigned::operator *=(const BigUnsigned &x) {
multiply(*this, x);
}
inline void BigUnsigned::operator /=(const BigUnsigned &x) {
if (x.isZero()) throw "BigUnsigned::operator /=: division by zero";
/* The following technique is slightly faster than copying *this first
* when x is large. */
BigUnsigned q;
divideWithRemainder(x, q);
// *this contains the remainder, but we overwrite it with the quotient.
*this = q;
}
inline void BigUnsigned::operator %=(const BigUnsigned &x) {
if (x.isZero()) throw "BigUnsigned::operator %=: division by zero";
BigUnsigned q;
// Mods *this by x. Don't care about quotient left in q.
divideWithRemainder(x, q);
}
inline void BigUnsigned::operator &=(const BigUnsigned &x) {
bitAnd(*this, x);
}
inline void BigUnsigned::operator |=(const BigUnsigned &x) {
bitOr(*this, x);
}
inline void BigUnsigned::operator ^=(const BigUnsigned &x) {
bitXor(*this, x);
}
inline void BigUnsigned::operator <<=(int b) {
bitShiftLeft(*this, b);
}
inline void BigUnsigned::operator >>=(int b) {
bitShiftRight(*this, b);
}
/* Templates for conversions of BigUnsigned to and from primitive integers.
* BigInteger.cc needs to instantiate convertToPrimitive, and the uses in
* BigUnsigned.cc didn't do the trick; I think g++ inlined convertToPrimitive
* instead of generating linkable instantiations. So for consistency, I put
* all the templates here. */
// CONSTRUCTION FROM PRIMITIVE INTEGERS
/* Initialize this BigUnsigned from the given primitive integer. The same
* pattern works for all primitive integer types, so I put it into a template to
* reduce code duplication. (Don't worry: this is protected and we instantiate
* it only with primitive integer types.) Type X could be signed, but x is
* known to be nonnegative. */
template <class X>
void BigUnsigned::initFromPrimitive(X x) {
if (x == 0)
; // NumberlikeArray already initialized us to zero.
else {
// Create a single block. blk is NULL; no need to delete it.
cap = 1;
blk = new Blk[1];
len = 1;
blk[0] = Blk(x);
}
}
/* Ditto, but first check that x is nonnegative. I could have put the check in
* initFromPrimitive and let the compiler optimize it out for unsigned-type
* instantiations, but I wanted to avoid the warning stupidly issued by g++ for
* a condition that is constant in *any* instantiation, even if not in all. */
template <class X>
void BigUnsigned::initFromSignedPrimitive(X x) {
if (x < 0)
throw "BigUnsigned constructor: "
"Cannot construct a BigUnsigned from a negative number";
else
initFromPrimitive(x);
}
// CONVERSION TO PRIMITIVE INTEGERS
/* Template with the same idea as initFromPrimitive. This might be slightly
* slower than the previous version with the masks, but it's much shorter and
* clearer, which is the library's stated goal. */
template <class X>
X BigUnsigned::convertToPrimitive() const {
if (len == 0)
// The number is zero; return zero.
return 0;
else if (len == 1) {
// The single block might fit in an X. Try the conversion.
X x = X(blk[0]);
// Make sure the result accurately represents the block.
if (Blk(x) == blk[0])
// Successful conversion.
return x;
// Otherwise fall through.
}
throw "BigUnsigned::to<Primitive>: "
"Value is too big to fit in the requested type";
}
/* Wrap the above in an x >= 0 test to make sure we got a nonnegative result,
* not a negative one that happened to convert back into the correct nonnegative
* one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again,
* separated to avoid a g++ warning. */
template <class X>
X BigUnsigned::convertToSignedPrimitive() const {
X x = convertToPrimitive<X>();
if (x >= 0)
return x;
else
throw "BigUnsigned::to(Primitive): "
"Value is too big to fit in the requested type";
}
#endif

@ -0,0 +1,125 @@
#include "BigUnsignedInABase.hh"
BigUnsignedInABase::BigUnsignedInABase(const Digit *d, Index l, Base base)
: NumberlikeArray<Digit>(d, l), base(base) {
// Check the base
if (base < 2)
throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): The base must be at least 2";
// Validate the digits.
for (Index i = 0; i < l; i++)
if (blk[i] >= base)
throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base";
// Eliminate any leading zeros we may have been passed.
zapLeadingZeros();
}
namespace {
unsigned int bitLen(unsigned int x) {
unsigned int len = 0;
while (x > 0) {
x >>= 1;
len++;
}
return len;
}
unsigned int ceilingDiv(unsigned int a, unsigned int b) {
return (a + b - 1) / b;
}
}
BigUnsignedInABase::BigUnsignedInABase(const BigUnsigned &x, Base base) {
// Check the base
if (base < 2)
throw "BigUnsignedInABase(BigUnsigned, Base): The base must be at least 2";
this->base = base;
// Get an upper bound on how much space we need
int maxBitLenOfX = x.getLength() * BigUnsigned::N;
int minBitsPerDigit = bitLen(base) - 1;
int maxDigitLenOfX = ceilingDiv(maxBitLenOfX, minBitsPerDigit);
len = maxDigitLenOfX; // Another change to comply with `staying in bounds'.
allocate(len); // Get the space
BigUnsigned x2(x), buBase(base);
Index digitNum = 0;
while (!x2.isZero()) {
// Get last digit. This is like `lastDigit = x2 % buBase, x2 /= buBase'.
BigUnsigned lastDigit(x2);
lastDigit.divideWithRemainder(buBase, x2);
// Save the digit.
blk[digitNum] = lastDigit.toUnsignedShort();
// Move on. We can't run out of room: we figured it out above.
digitNum++;
}
// Save the actual length.
len = digitNum;
}
BigUnsignedInABase::operator BigUnsigned() const {
BigUnsigned ans(0), buBase(base), temp;
Index digitNum = len;
while (digitNum > 0) {
digitNum--;
temp.multiply(ans, buBase);
ans.add(temp, BigUnsigned(blk[digitNum]));
}
return ans;
}
BigUnsignedInABase::BigUnsignedInABase(const std::string &s, Base base) {
// Check the base.
if (base > 36)
throw "BigUnsignedInABase(std::string, Base): The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine.";
// Save the base.
// This pattern is seldom seen in C++, but the analogous ``this.'' is common in Java.
this->base = base;
// `s.length()' is a `size_t', while `len' is a `NumberlikeArray::Index',
// also known as an `unsigned int'. Some compilers warn without this cast.
len = Index(s.length());
allocate(len);
Index digitNum, symbolNumInString;
for (digitNum = 0; digitNum < len; digitNum++) {
symbolNumInString = len - 1 - digitNum;
char theSymbol = s[symbolNumInString];
if (theSymbol >= '0' && theSymbol <= '9')
blk[digitNum] = theSymbol - '0';
else if (theSymbol >= 'A' && theSymbol <= 'Z')
blk[digitNum] = theSymbol - 'A' + 10;
else if (theSymbol >= 'a' && theSymbol <= 'z')
blk[digitNum] = theSymbol - 'a' + 10;
else
throw "BigUnsignedInABase(std::string, Base): Bad symbol in input. Only 0-9, A-Z, a-z are accepted.";
if (blk[digitNum] >= base)
throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base";
}
zapLeadingZeros();
}
BigUnsignedInABase::operator std::string() const {
if (base > 36)
throw "BigUnsignedInABase ==> std::string: The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine.";
if (len == 0)
return std::string("0");
// Some compilers don't have push_back, so use a char * buffer instead.
char *s = new char[len + 1];
s[len] = '\0';
Index digitNum, symbolNumInString;
for (symbolNumInString = 0; symbolNumInString < len; symbolNumInString++) {
digitNum = len - 1 - symbolNumInString;
Digit theDigit = blk[digitNum];
if (theDigit < 10)
s[symbolNumInString] = char('0' + theDigit);
else
s[symbolNumInString] = char('A' + theDigit - 10);
}
std::string s2(s);
delete [] s;
return s2;
}

@ -0,0 +1,122 @@
#ifndef BIGUNSIGNEDINABASE_H
#define BIGUNSIGNEDINABASE_H
#include "NumberlikeArray.hh"
#include "BigUnsigned.hh"
#include <string>
/*
* A BigUnsignedInABase object represents a nonnegative integer of size limited
* only by available memory, represented in a user-specified base that can fit
* in an `unsigned short' (most can, and this saves memory).
*
* BigUnsignedInABase is intended as an intermediary class with little
* functionality of its own. BigUnsignedInABase objects can be constructed
* from, and converted to, BigUnsigneds (requiring multiplication, mods, etc.)
* and `std::string's (by switching digit values for appropriate characters).
*
* BigUnsignedInABase is similar to BigUnsigned. Note the following:
*
* (1) They represent the number in exactly the same way, except that
* BigUnsignedInABase uses ``digits'' (or Digit) where BigUnsigned uses
* ``blocks'' (or Blk).
*
* (2) Both use the management features of NumberlikeArray. (In fact, my desire
* to add a BigUnsignedInABase class without duplicating a lot of code led me to
* introduce NumberlikeArray.)
*
* (3) The only arithmetic operation supported by BigUnsignedInABase is an
* equality test. Use BigUnsigned for arithmetic.
*/
class BigUnsignedInABase : protected NumberlikeArray<unsigned short> {
public:
// The digits of a BigUnsignedInABase are unsigned shorts.
typedef unsigned short Digit;
// That's also the type of a base.
typedef Digit Base;
protected:
// The base in which this BigUnsignedInABase is expressed
Base base;
// Creates a BigUnsignedInABase with a capacity; for internal use.
BigUnsignedInABase(int, Index c) : NumberlikeArray<Digit>(0, c) {}
// Decreases len to eliminate any leading zero digits.
void zapLeadingZeros() {
while (len > 0 && blk[len - 1] == 0)
len--;
}
public:
// Constructs zero in base 2.
BigUnsignedInABase() : NumberlikeArray<Digit>(), base(2) {}
// Copy constructor
BigUnsignedInABase(const BigUnsignedInABase &x) : NumberlikeArray<Digit>(x), base(x.base) {}
// Assignment operator
void operator =(const BigUnsignedInABase &x) {
NumberlikeArray<Digit>::operator =(x);
base = x.base;
}
// Constructor that copies from a given array of digits.
BigUnsignedInABase(const Digit *d, Index l, Base base);
// Destructor. NumberlikeArray does the delete for us.
~BigUnsignedInABase() {}
// LINKS TO BIGUNSIGNED
BigUnsignedInABase(const BigUnsigned &x, Base base);
operator BigUnsigned() const;
/* LINKS TO STRINGS
*
* These use the symbols ``0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'' to
* represent digits of 0 through 35. When parsing strings, lowercase is
* also accepted.
*
* All string representations are big-endian (big-place-value digits
* first). (Computer scientists have adopted zero-based counting; why
* can't they tolerate little-endian numbers?)
*
* No string representation has a ``base indicator'' like ``0x''.
*
* An exception is made for zero: it is converted to ``0'' and not the
* empty string.
*
* If you want different conventions, write your own routines to go
* between BigUnsignedInABase and strings. It's not hard.
*/
operator std::string() const;
BigUnsignedInABase(const std::string &s, Base base);
public:
// ACCESSORS
Base getBase() const { return base; }
// Expose these from NumberlikeArray directly.
using NumberlikeArray<Digit>::getCapacity;
using NumberlikeArray<Digit>::getLength;
/* Returns the requested digit, or 0 if it is beyond the length (as if
* the number had 0s infinitely to the left). */
Digit getDigit(Index i) const { return i >= len ? 0 : blk[i]; }
// The number is zero if and only if the canonical length is zero.
bool isZero() const { return NumberlikeArray<Digit>::isEmpty(); }
/* Equality test. For the purposes of this test, two BigUnsignedInABase
* values must have the same base to be equal. */
bool operator ==(const BigUnsignedInABase &x) const {
return base == x.base && NumberlikeArray<Digit>::operator ==(x);
}
bool operator !=(const BigUnsignedInABase &x) const { return !operator ==(x); }
};
#endif

@ -0,0 +1,16 @@
SET(SOURCES
${BIGINT_DIR}/BigInteger.hh
${BIGINT_DIR}/BigInteger.cc
${BIGINT_DIR}/BigIntegerAlgorithms.hh
${BIGINT_DIR}/BigIntegerAlgorithms.cc
${BIGINT_DIR}/BigIntegerLibrary.hh
${BIGINT_DIR}/BigIntegerUtils.hh
${BIGINT_DIR}/BigIntegerUtils.cc
${BIGINT_DIR}/BigUnsigned.hh
${BIGINT_DIR}/BigUnsigned.cc
${BIGINT_DIR}/BigUnsignedInABase.hh
${BIGINT_DIR}/BigUnsignedInABase.cc
${BIGINT_DIR}/NumberlikeArray.hh
)
target_sources(qzxing PRIVATE ${SOURCES})

@ -0,0 +1,146 @@
Change Log
These entries tell you what was added, fixed, or improved in each version as
compared to the previous one. In case you haven't noticed, a version number
roughly corresponds to the release date of that version in `YYYY.MM.DD[.N]'
format, where `.N' goes `.2', `.3', etc. if there are multiple versions on the
same day. The topmost version listed is the one you have.
2010.04.30
----------
- Strengthen the advice about build/IDE configuration in the README.
2009.05.03
----------
- BigUnsigned::{get,set}Bit: Change two remaining `1 <<' to `Blk(1) <<' to work
on systems where sizeof(unsigned int) != sizeof(Blk). Bug reported by Brad
Spencer.
- dataToBigInteger: Change a `delete' to `delete []' to avoid leaking memory.
Bug reported by Nicolás Carrasco.
2009.03.26
----------
- BigUnsignedInABase(std::string) Reject digits too big for the base.
Bug reported by Niakam Kazemi.
2008.07.20
----------
Dennis Yew pointed out serious problems with ambiguities and unwanted
conversions when mixing BigInteger/BigUnsigned and primitive integers. To fix
these, I removed the implicit conversions from BigInteger/BigUnsigned to
primitive integers and from BigInteger to BigUnsigned. Removing the
BigInteger-to-BigUnsigned conversion required changing BigInteger to have a
BigUnsigned field instead of inheriting from it; this was a complex task but
ultimately gave a saner design. At the same time, I went through the entire
codebase, making the formatting and comments prettier and reworking anything I
thought was unclear. I also added a testsuite (currently for 32-bit systems
only); it doesn't yet cover the entire library but should help to ensure that
things work the way they should.
A number of changes from version 2007.07.07 break compatibility with existing
code that uses the library, but updating that code should be pretty easy:
- BigInteger can no longer be implicitly converted to BigUnsigned. Use
getMagnitude() instead.
- BigUnsigned and BigInteger can no longer be implicitly converted to primitive
integers. Use the toInt() family of functions instead.
- The easy* functions have been renamed to more mature names:
bigUnsignedToString, bigIntegerToString, stringToBigUnsigned,
stringToBigInteger, dataToBigInteger.
- BigInteger no longer supports bitwise operations. Get the magnitude with
getMagnitude() and operate on that instead.
- The old {BigUnsigned,BigInteger}::{divide,modulo} copy-less options have been
removed. Use divideWithRemainder instead.
- Added a base argument to BigUnsignedInABase's digit-array constructor. I
ope no one used that constructor in its broken state anyway.
Other notable changes:
- Added BigUnsigned functions setBlock, bitLength, getBit, setBit.
- The bit-shifting operations now support negative shift amounts, which shift in
the other direction.
- Added some big-integer algorithms in BigIntegerAlgorithms.hh: gcd,
extendedEuclidean, modinv, modexp.
2007.07.07
----------
Update the "Running the sample program produces this output:" comment in
sample.cc for the bitwise operators.
2007.06.14
----------
- Implement << and >> for BigUnsigned in response to email from Marco Schulze.
- Fix name: DOTR_ALIASED -> DTRT_ALIASED.
- Demonstrate all bitwise operators (&, |, ^, <<, >>) in sample.cc.
2007.02.16
----------
Boris Dessy pointed out that the library threw an exception on "a *= a", so I changed all the put-here operations to handle aliased calls correctly using a temporary copy instead of throwing exceptions.
2006.08.14
----------
In BigUnsigned::bitXor, change allocate(b2->len) to allocate(a2->len): we should allocate enough space for the longer number, not the shorter one! Thanks to Sriram Sankararaman for pointing this out.
2006.05.03
----------
I ran the sample program using valgrind and discovered a `delete s' that should be `delete [] s' and a `len++' before an `allocateAndCopy(len)' that should have been after an `allocateAndCopy(len + 1)'. I fixed both. Yay for valgrind!
2006.05.01
----------
I fixed incorrect results reported by Mohand Mezmaz and related memory corruption on platforms where Blk is bigger than int. I replaced (1 << x) with (Blk(1) << x) in two places in BigUnsigned.cc.
2006.04.24
----------
Two bug fixes: BigUnsigned "++x" no longer segfaults when x grows in length, and BigUnsigned == and != are now redeclared so as to be usable. I redid the Makefile: I removed the *.tag mechanism and hard-coded the library's header dependencies, I added comments, and I made the Makefile more useful for building one's own programs instead of just the sample.
2006.02.26
----------
A few tweaks in preparation for a group to distribute the library. The project Web site has moved; I updated the references. I fixed a typo and added a missing function in NumberlikeArray.hh. I'm using Eclipse now, so you get Eclipse project files.
2005.03.30
----------
Sam Larkin found a bug in `BigInteger::subtract'; I fixed it.
2005.01.18
----------
I fixed some problems with `easyDataToBI'. Due to some multiply declared variables, this function would not compile. However, it is a template function, so the compiler parses it and doesn't compile the parsed representation until something uses the function; this is how I missed the problems. I also removed debugging output from this function.
2005.01.17
----------
A fix to some out-of-bounds accesses reported by Milan Tomic (see the comment under `BigUnsigned::divideWithRemainder'). `BigUnsigned::multiply' and `BigUnsigned::divideWithRemainder' implementations neatened up a bit with the help of a function `getShiftedBlock'. I (finally!) introduced a constant `BigUnsigned::N', the number of bits in a `BigUnsigned::Blk', which varies depending on machine word size. In both code and comments, it replaces the much clunkier `8*sizeof(Blk)'. Numerous other small changes. There's a new conversion routine `easyDataToBI' that will convert almost any format of binary data to a `BigInteger'.
I have inserted a significant number of new comments. Most explain unobvious aspects of the code.
2005.01.06
----------
Some changes to the way zero-length arrays are handled by `NumberlikeArray', which fixed a memory leak reported by Milan Tomic.
2004.12.24.2
------------
I tied down a couple of loose ends involving division/modulo. I added an explanation of put-here vs. overloaded operators in the sample program; this has confused too many people. Miscellaneous other improvements.
I believe that, at this point, the Big Integer Library makes no assumptions about the word size of the machine it is using. `BigUnsigned::Blk' is always an `unsigned long', whatever that may be, and its size is computed with `sizeof' when necessary. However, just in case, I would be interested to have someone test the library on a non-32-bit machine to see if it works.
2004.12.24
----------
This is a _major_ upgrade to the library. Among the things that have changed:
I wrote the original version of the library, particularly the four ``classical algorithms'' in `BigUnsigned.cc', using array indexing. Then I rewrote it to use pointers because I thought that would be faster. But recently, I revisited the code in `BigUnsigned.cc' and found that I could not begin to understand what it was doing.
I have decided that the drawbacks of pointers, increased coding difficulty and reduced code readability, far outweigh their speed benefits. Plus, any modern optimizing compiler should produce fast code either way. Therefore, I rewrote the library to use array indexing again. (Thank goodness for regular-expression find-and-replace. It saved me a lot of time.)
The put-here operations `divide' and `modulo' of each of `BigUnsigned' and `BigInteger' have been supplanted by a single operation `divideWithRemainder'. Read the profuse comments for more information on its exact behavior.
There is a new class `BigUnsignedInABase' that is like `BigUnsigned' but uses a user-specified, small base instead of `256 ^ sizeof(unsigned long)'. Much of the code common to the two has been factored out into `NumberlikeArray'.
`BigUnsignedInABase' facilitates conversion between `BigUnsigned's and digit-by-digit string representations using `std::string'. Convenience routines to do this conversion are in `BigIntegerUtils.hh'. `iostream' compatibility has been improved.
I would like to thank Chris Morbitzer for the e-mail message that catalyzed this major upgrade. He wanted a way to convert a string to a BigInteger. One thing just led to another, roughly in reverse order from how they are listed here.
2004.1216
---------
Brad Spencer pointed out a memory leak in `BigUnsigned::divide'. It is fixed in the December 16, 2004 version.
2004.1205
---------
After months of inactivity, I fixed a bug in the `BigInteger' division routine; thanks to David Allen for reporting the bug. I also added simple routines for decimal output to `std::ostream's, and there is a demo that prints out powers of 3.
~~~~

@ -0,0 +1,177 @@
#ifndef NUMBERLIKEARRAY_H
#define NUMBERLIKEARRAY_H
// Make sure we have NULL.
#ifndef NULL
#define NULL 0
#endif
/* A NumberlikeArray<Blk> object holds a heap-allocated array of Blk with a
* length and a capacity and provides basic memory management features.
* BigUnsigned and BigUnsignedInABase both subclass it.
*
* NumberlikeArray provides no information hiding. Subclasses should use
* nonpublic inheritance and manually expose members as desired using
* declarations like this:
*
* public:
* NumberlikeArray< the-type-argument >::getLength;
*/
template <class Blk>
class NumberlikeArray {
public:
// Type for the index of a block in the array
typedef unsigned int Index;
// The number of bits in a block, defined below.
static const unsigned int N;
// The current allocated capacity of this NumberlikeArray (in blocks)
Index cap;
// The actual length of the value stored in this NumberlikeArray (in blocks)
Index len;
// Heap-allocated array of the blocks (can be NULL if len == 0)
Blk *blk;
// Constructs a ``zero'' NumberlikeArray with the given capacity.
NumberlikeArray(Index c) : cap(c), len(0) {
blk = (cap > 0) ? (new Blk[cap]) : NULL;
}
/* Constructs a zero NumberlikeArray without allocating a backing array.
* A subclass that doesn't know the needed capacity at initialization
* time can use this constructor and then overwrite blk without first
* deleting it. */
NumberlikeArray() : cap(0), len(0) {
blk = NULL;
}
// Destructor. Note that `delete NULL' is a no-op.
~NumberlikeArray() {
delete [] blk;
}
/* Ensures that the array has at least the requested capacity; may
* destroy the contents. */
void allocate(Index c);
/* Ensures that the array has at least the requested capacity; does not
* destroy the contents. */
void allocateAndCopy(Index c);
// Copy constructor
NumberlikeArray(const NumberlikeArray<Blk> &x);
// Assignment operator
void operator=(const NumberlikeArray<Blk> &x);
// Constructor that copies from a given array of blocks
NumberlikeArray(const Blk *b, Index blen);
// ACCESSORS
Index getCapacity() const { return cap; }
Index getLength() const { return len; }
Blk getBlock(Index i) const { return blk[i]; }
bool isEmpty() const { return len == 0; }
/* Equality comparison: checks if both objects have the same length and
* equal (==) array elements to that length. Subclasses may wish to
* override. */
bool operator ==(const NumberlikeArray<Blk> &x) const;
bool operator !=(const NumberlikeArray<Blk> &x) const {
return !operator ==(x);
}
};
/* BEGIN TEMPLATE DEFINITIONS. They are present here so that source files that
* include this header file can generate the necessary real definitions. */
template <class Blk>
const unsigned int NumberlikeArray<Blk>::N = 8 * sizeof(Blk);
template <class Blk>
void NumberlikeArray<Blk>::allocate(Index c) {
// If the requested capacity is more than the current capacity...
if (c > cap) {
// Delete the old number array
delete [] blk;
// Allocate the new array
cap = c;
blk = new Blk[cap];
}
}
template <class Blk>
void NumberlikeArray<Blk>::allocateAndCopy(Index c) {
// If the requested capacity is more than the current capacity...
if (c > cap) {
Blk *oldBlk = blk;
// Allocate the new number array
cap = c;
blk = new Blk[cap];
// Copy number blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = oldBlk[i];
// Delete the old array
delete [] oldBlk;
}
}
template <class Blk>
NumberlikeArray<Blk>::NumberlikeArray(const NumberlikeArray<Blk> &x)
: len(x.len) {
// Create array
cap = len;
blk = new Blk[cap];
// Copy blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = x.blk[i];
}
template <class Blk>
void NumberlikeArray<Blk>::operator=(const NumberlikeArray<Blk> &x) {
/* Calls like a = a have no effect; catch them before the aliasing
* causes a problem */
if (this == &x)
return;
// Copy length
len = x.len;
// Expand array if necessary
allocate(len);
// Copy number blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = x.blk[i];
}
template <class Blk>
NumberlikeArray<Blk>::NumberlikeArray(const Blk *b, Index blen)
: cap(blen), len(blen) {
// Create array
blk = new Blk[cap];
// Copy blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = b[i];
}
template <class Blk>
bool NumberlikeArray<Blk>::operator ==(const NumberlikeArray<Blk> &x) const {
if (len != x.len)
// Definitely unequal.
return false;
else {
// Compare corresponding blocks one by one.
Index i;
for (i = 0; i < len; i++)
if (blk[i] != x.blk[i])
return false;
// No blocks differed, so the objects are equal.
return true;
}
}
#endif

@ -0,0 +1,71 @@
C++ Big Integer Library
(see ChangeLog for version)
http://mattmccutchen.net/bigint/
Written and maintained by Matt McCutchen <matt@mattmccutchen.net>
You can use this library in a C++ program to do arithmetic on integers of size
limited only by your computer's memory. The library provides BigUnsigned and
BigInteger classes that represent nonnegative integers and signed integers,
respectively. Most of the C++ arithmetic operators are overloaded for these
classes, so big-integer calculations are as easy as:
#include "BigIntegerLibrary.hh"
BigInteger a = 65536;
cout << (a * a * a * a * a * a * a * a);
(prints 340282366920938463463374607431768211456)
The code in `sample.cc' demonstrates the most important features of the library.
To get started quickly, read the code and explanations in that file and run it.
If you want more detail or a feature not shown in `sample.cc', consult the
consult the actual header and source files, which are thoroughly commented.
This library emphasizes ease of use and clarity of implementation over speed;
some users will prefer GMP (http://swox.com/gmp/), which is faster. The code is
intended to be reasonably portable across computers and modern C++ compilers; in
particular, it uses whatever word size the computer provides (32-bit, 64-bit, or
otherwise).
Compiling programs that use the library
---------------------------------------
The library consists of a folder full of C++ header files (`.hh') and source
files (`.cc'). Your own programs should `#include' the necessary header files
and link with the source files. A makefile that builds the sample program
(`sample.cc') is included; you can adapt it to replace the sample with your own
program.
Alternatively, you can use your own build system or IDE. In that case, you must
put the library header files where the compiler will find them and arrange to
have your program linked with the library source files; otherwise, you will get
errors about missing header files or "undefined references". To learn how to do
this, consult the documentation for the build system or IDE; don't bother asking
me. Adding all the library files to your project will work in many IDEs but may
not be the most desirable approach.
Resources
---------
The library's Web site (above) provides links to released versions, the current
development version, and a mailing list for release announcements, questions,
bug reports, and other discussion of the library. I would be delighted to hear
from you if you like this library and/or find a good use for it.
Bugs and enhancements
---------------------
The library has been tested by me and others but is by no means bug-free. If
you find a bug, please report it, whether it comes in the form of compiling
trouble, a mathematically inaccurate result, or a memory-management blooper
(since I use Java, these are altogether too common in my C++). I generally fix
all reported bugs. You are also welcome to request enhancements, but I am
unlikely to do substantial amounts of work on enhancements at this point.
Legal
-----
I, Matt McCutchen, the sole author of the original Big Integer Library, waive my
copyright to it, placing it in the public domain. The library comes with
absolutely no warranty.
~~~~

@ -0,0 +1,11 @@
SET(SOURCES
${WIN32_DIR}/iconv.h
${WIN32_DIR}/win_iconv.c
)
if(MSVC)
LIST(APPEND SOURCES ${WIN32_DIR}/zxing/msvc/stdint.h)
endif(MSVC)
target_sources(qzxing PRIVATE ${SOURCES})

@ -0,0 +1,14 @@
#ifndef _LIBICONV_H
#define _LIBICONV_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* iconv_t;
iconv_t iconv_open(const char *tocode, const char *fromcode);
int iconv_close(iconv_t cd);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
#ifdef __cplusplus
}
#endif
#endif//_LIBICONV_H

@ -0,0 +1,247 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

File diff suppressed because it is too large Load Diff

@ -0,0 +1,41 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/BarcodeFormat.h>
const char* zxing::BarcodeFormat::barcodeFormatNames[] = {
0,
"AZTEC",
"CODABAR",
"CODE_39",
"CODE_93",
"CODE_128",
"DATA_MATRIX",
"EAN_8",
"EAN_13",
"ITF",
"MAXICODE",
"PDF_417",
"QR_CODE",
"RSS_14",
"RSS_EXPANDED",
"UPC_A",
"UPC_E",
"UPC_EAN_EXTENSION",
"ASSUME_GS1"
};

@ -0,0 +1,61 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_BARCODE_FORMAT_H
#define ZXING_BARCODE_FORMAT_H
/*
* BarcodeFormat.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.
*/
namespace zxing {
class BarcodeFormat {
public:
// if you update the enum, update BarcodeFormat.cpp
enum Value {
NONE,
AZTEC,
CODABAR,
CODE_39,
CODE_93,
CODE_128,
DATA_MATRIX,
EAN_8,
EAN_13,
ITF,
MAXICODE,
PDF_417,
QR_CODE,
RSS_14,
RSS_EXPANDED,
UPC_A,
UPC_E,
UPC_EAN_EXTENSION,
ASSUME_GS1
};
BarcodeFormat(Value v) : value(v) {}
const Value value;
operator Value () const {return value;}
static char const* barcodeFormatNames[];
};
}
#endif // ZXING_BARCODE_FORMAT_H

@ -0,0 +1,45 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Binarizer.cpp
* zxing
*
* Created by Ralf Kistner on 16/10/2009.
* 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");
* 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/Binarizer.h>
namespace zxing {
Binarizer::Binarizer(Ref<LuminanceSource> source) : source_(source) {
}
Binarizer::~Binarizer() {
}
Ref<LuminanceSource> Binarizer::getLuminanceSource() const {
return source_;
}
int Binarizer::getWidth() const {
return source_->getWidth();
}
int Binarizer::getHeight() const {
return source_->getHeight();
}
}

@ -0,0 +1,50 @@
#ifndef BINARIZER_H_
#define BINARIZER_H_
/*
* Binarizer.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.
*/
#include <zxing/LuminanceSource.h>
#include <zxing/common/BitArray.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/common/Counted.h>
namespace zxing {
class Binarizer : public Counted {
private:
Ref<LuminanceSource> source_;
public:
Binarizer(Ref<LuminanceSource> source);
virtual ~Binarizer();
virtual Ref<BitArray> getBlackRow(int y, Ref<BitArray> row) = 0;
virtual Ref<BitMatrix> getBlackMatrix() = 0;
Ref<LuminanceSource> getLuminanceSource() const ;
virtual Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source) = 0;
int getWidth() const;
int getHeight() const;
};
}
#endif /* BINARIZER_H_ */

@ -0,0 +1,74 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* 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/BinaryBitmap.h>
using zxing::Ref;
using zxing::BitArray;
using zxing::BitMatrix;
using zxing::LuminanceSource;
using zxing::BinaryBitmap;
// VC++
using zxing::Binarizer;
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : binarizer_(binarizer) {
}
BinaryBitmap::~BinaryBitmap() {
}
Ref<BitArray> BinaryBitmap::getBlackRow(int y, Ref<BitArray> row) {
return binarizer_->getBlackRow(y, row);
}
Ref<BitMatrix> BinaryBitmap::getBlackMatrix() {
return binarizer_->getBlackMatrix();
}
int BinaryBitmap::getWidth() const {
return getLuminanceSource()->getWidth();
}
int BinaryBitmap::getHeight() const {
return getLuminanceSource()->getHeight();
}
Ref<LuminanceSource> BinaryBitmap::getLuminanceSource() const {
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())));
}
Ref<zxing::BinaryBitmap> BinaryBitmap::rotateCounterClockwise45()
{
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise45())));
}

@ -0,0 +1,56 @@
#ifndef ZXING_BINARYBITMAP_H
#define ZXING_BINARYBITMAP_H
/*
* BinaryBitmap.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.
*/
#include <zxing/common/Counted.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/common/BitArray.h>
#include <zxing/Binarizer.h>
namespace zxing {
class BinaryBitmap : public Counted {
private:
Ref<Binarizer> binarizer_;
public:
BinaryBitmap(Ref<Binarizer> binarizer);
virtual ~BinaryBitmap();
Ref<BitArray> getBlackRow(int y, Ref<BitArray> row);
Ref<BitMatrix> getBlackMatrix();
Ref<LuminanceSource> getLuminanceSource() const;
int getWidth() const;
int getHeight() const;
bool isRotateSupported() const;
Ref<BinaryBitmap> rotateCounterClockwise();
Ref<BinaryBitmap> rotateCounterClockwise45();
bool isCropSupported() const;
Ref<BinaryBitmap> crop(int left, int top, int width, int height);
};
}
#endif /* ZXING_BINARYBITMAP_H */

@ -0,0 +1,351 @@
SET(SOURCES
${ZXING_DIR}/BarcodeFormat.cpp
${ZXING_DIR}/BarcodeFormat.h
${ZXING_DIR}/Binarizer.cpp
${ZXING_DIR}/Binarizer.h
${ZXING_DIR}/BinaryBitmap.cpp
${ZXING_DIR}/BinaryBitmap.h
${ZXING_DIR}/ChecksumException.cpp
${ZXING_DIR}/ChecksumException.h
${ZXING_DIR}/DecodeHints.cpp
${ZXING_DIR}/DecodeHints.h
${ZXING_DIR}/EncodeHint.cpp
${ZXING_DIR}/EncodeHint.h
${ZXING_DIR}/Exception.cpp
${ZXING_DIR}/Exception.h
${ZXING_DIR}/FormatException.cpp
${ZXING_DIR}/FormatException.h
${ZXING_DIR}/IllegalStateException.cpp
${ZXING_DIR}/IllegalStateException.h
${ZXING_DIR}/InvertedLuminanceSource.cpp
${ZXING_DIR}/InvertedLuminanceSource.h
${ZXING_DIR}/LuminanceSource.cpp
${ZXING_DIR}/LuminanceSource.h
${ZXING_DIR}/MultiFormatReader.cpp
${ZXING_DIR}/MultiFormatReader.h
${ZXING_DIR}/NotFoundException.h
${ZXING_DIR}/NotFoundException.cpp
${ZXING_DIR}/Reader.cpp
${ZXING_DIR}/Reader.h
${ZXING_DIR}/ReaderException.h
${ZXING_DIR}/ReaderException.cpp
${ZXING_DIR}/Result.cpp
${ZXING_DIR}/Result.h
${ZXING_DIR}/ResultMetadata.cpp
${ZXING_DIR}/ResultMetadata.h
${ZXING_DIR}/ResultIO.cpp
${ZXING_DIR}/ResultPoint.cpp
${ZXING_DIR}/ResultPoint.h
${ZXING_DIR}/ResultPointCallback.cpp
${ZXING_DIR}/ResultPointCallback.h
${ZXING_DIR}/UnsupportedEncodingException.h
${ZXING_DIR}/WriterException.h
${ZXING_DIR}/WriterException.cpp
${ZXING_DIR}/ZXing.h
)
SET(AZTEC_DIR
${ZXING_DIR}/aztec/AztecDetectorResult.cpp
${ZXING_DIR}/aztec/AztecDetectorResult.h
${ZXING_DIR}/aztec/AztecReader.cpp
${ZXING_DIR}/aztec/AztecReader.h
${ZXING_DIR}/aztec/decoder/AztecDecoder.cpp
${ZXING_DIR}/aztec/decoder/Decoder.h
${ZXING_DIR}/aztec/detector/AztecDetector.cpp
${ZXING_DIR}/aztec/detector/Detector.h
)
SET(COMMON_DIR
${ZXING_DIR}/common/Array.h
${ZXING_DIR}/common/BitArray.cpp
${ZXING_DIR}/common/BitArray.h
${ZXING_DIR}/common/BitArrayIO.cpp
${ZXING_DIR}/common/BitMatrix.cpp
${ZXING_DIR}/common/BitMatrix.h
${ZXING_DIR}/common/BitSource.cpp
${ZXING_DIR}/common/BitSource.h
${ZXING_DIR}/common/CharacterSetECI.cpp
${ZXING_DIR}/common/CharacterSetECI.h
${ZXING_DIR}/common/Counted.h
${ZXING_DIR}/common/Counted.cpp
${ZXING_DIR}/common/DecoderResult.cpp
${ZXING_DIR}/common/DecoderResult.h
${ZXING_DIR}/common/DetectorResult.cpp
${ZXING_DIR}/common/DetectorResult.h
${ZXING_DIR}/common/GlobalHistogramBinarizer.cpp
${ZXING_DIR}/common/GlobalHistogramBinarizer.h
${ZXING_DIR}/common/GreyscaleLuminanceSource.cpp
${ZXING_DIR}/common/GreyscaleLuminanceSource.h
${ZXING_DIR}/common/GreyscaleRotatedLuminanceSource.cpp
${ZXING_DIR}/common/GreyscaleRotatedLuminanceSource.h
${ZXING_DIR}/common/GridSampler.cpp
${ZXING_DIR}/common/GridSampler.h
${ZXING_DIR}/common/HybridBinarizer.cpp
${ZXING_DIR}/common/HybridBinarizer.h
${ZXING_DIR}/common/IllegalArgumentException.cpp
${ZXING_DIR}/common/IllegalArgumentException.h
${ZXING_DIR}/common/PerspectiveTransform.cpp
${ZXING_DIR}/common/PerspectiveTransform.h
${ZXING_DIR}/common/Point.h
${ZXING_DIR}/common/Str.cpp
${ZXING_DIR}/common/Str.h
${ZXING_DIR}/common/StringUtils.cpp
${ZXING_DIR}/common/StringUtils.h
${ZXING_DIR}/common/Types.h
${ZXING_DIR}/common/detector/JavaMath.h
${ZXING_DIR}/common/detector/MathUtils.h
${ZXING_DIR}/common/detector/MonochromeRectangleDetector.cpp
${ZXING_DIR}/common/detector/MonochromeRectangleDetector.h
${ZXING_DIR}/common/detector/WhiteRectangleDetector.cpp
${ZXING_DIR}/common/detector/WhiteRectangleDetector.h
${ZXING_DIR}/common/reedsolomon/GenericGF.cpp
${ZXING_DIR}/common/reedsolomon/GenericGF.h
${ZXING_DIR}/common/reedsolomon/GenericGFPoly.cpp
${ZXING_DIR}/common/reedsolomon/GenericGFPoly.h
${ZXING_DIR}/common/reedsolomon/ReedSolomonDecoder.cpp
${ZXING_DIR}/common/reedsolomon/ReedSolomonDecoder.h
${ZXING_DIR}/common/reedsolomon/ReedSolomonEncoder.cpp
${ZXING_DIR}/common/reedsolomon/ReedSolomonEncoder.h
${ZXING_DIR}/common/reedsolomon/ReedSolomonException.cpp
${ZXING_DIR}/common/reedsolomon/ReedSolomonException.h
)
SET(DATAMATRIX_DIR
${ZXING_DIR}/datamatrix/DataMatrixReader.cpp
${ZXING_DIR}/datamatrix/DataMatrixReader.h
${ZXING_DIR}/datamatrix/DataMatrixVersion.cpp
${ZXING_DIR}/datamatrix/Version.h
${ZXING_DIR}/datamatrix/decoder/BitMatrixParser.h
${ZXING_DIR}/datamatrix/decoder/DataBlock.h
${ZXING_DIR}/datamatrix/decoder/DataMatrixBitMatrixParser.cpp
${ZXING_DIR}/datamatrix/decoder/DataMatrixDataBlock.cpp
${ZXING_DIR}/datamatrix/decoder/DataMatrixDecodedBitStreamParser.cpp
${ZXING_DIR}/datamatrix/decoder/DataMatrixDecoder.cpp
${ZXING_DIR}/datamatrix/decoder/DecodedBitStreamParser.h
${ZXING_DIR}/datamatrix/decoder/Decoder.h
${ZXING_DIR}/datamatrix/detector/CornerPoint.h
${ZXING_DIR}/datamatrix/detector/DataMatrixCornerPoint.cpp
${ZXING_DIR}/datamatrix/detector/DataMatrixDetector.cpp
${ZXING_DIR}/datamatrix/detector/DataMatrixDetectorException.cpp
${ZXING_DIR}/datamatrix/detector/Detector.h
${ZXING_DIR}/datamatrix/detector/DetectorException.h
)
SET(MULTI_DIR
${ZXING_DIR}/multi/ByQuadrantReader.cpp
${ZXING_DIR}/multi/ByQuadrantReader.h
${ZXING_DIR}/multi/GenericMultipleBarcodeReader.cpp
${ZXING_DIR}/multi/GenericMultipleBarcodeReader.h
${ZXING_DIR}/multi/MultipleBarcodeReader.cpp
${ZXING_DIR}/multi/MultipleBarcodeReader.h
${ZXING_DIR}/multi/qrcode/QRCodeMultiReader.cpp
${ZXING_DIR}/multi/qrcode/QRCodeMultiReader.h
${ZXING_DIR}/multi/qrcode/detector/MultiDetector.cpp
${ZXING_DIR}/multi/qrcode/detector/MultiDetector.h
${ZXING_DIR}/multi/qrcode/detector/MultiFinderPatternFinder.cpp
${ZXING_DIR}/multi/qrcode/detector/MultiFinderPatternFinder.h
)
SET(ONED_DIR
${ZXING_DIR}/oned/UPCEReader.h
${ZXING_DIR}/oned/UPCEANReader.h
${ZXING_DIR}/oned/UPCEANExtensionSupport.h
${ZXING_DIR}/oned/UPCEANExtension2Support.h
${ZXING_DIR}/oned/UPCEANExtension5Support.h
${ZXING_DIR}/oned/UPCAReader.h
${ZXING_DIR}/oned/OneDResultPoint.h
${ZXING_DIR}/oned/OneDReader.h
${ZXING_DIR}/oned/MultiFormatUPCEANReader.h
${ZXING_DIR}/oned/MultiFormatOneDReader.h
${ZXING_DIR}/oned/ITFReader.h
${ZXING_DIR}/oned/EAN13Reader.h
${ZXING_DIR}/oned/EAN8Reader.h
${ZXING_DIR}/oned/EANManufacturerOrgSupport.h
${ZXING_DIR}/oned/Code128Reader.h
${ZXING_DIR}/oned/Code39Reader.h
${ZXING_DIR}/oned/CodaBarReader.h
${ZXING_DIR}/oned/Code93Reader.h
${ZXING_DIR}/oned/rss/AbstractRSSReader.h
${ZXING_DIR}/oned/rss/DataCharacter.h
${ZXING_DIR}/oned/rss/FinderPattern.h
${ZXING_DIR}/oned/rss/Pair.h
${ZXING_DIR}/oned/rss/RSS14Reader.h
${ZXING_DIR}/oned/rss/RSSUtils.h
${ZXING_DIR}/oned/rss/expanded/decoders/AbstractExpandedDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI013103decoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01320xDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01392xDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01393xDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI013x0x1xDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI013x0xDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01AndOtherAIs.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01decoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AI01weightDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/AnyAIDecoder.h
${ZXING_DIR}/oned/rss/expanded/decoders/BlockParsedResult.h
${ZXING_DIR}/oned/rss/expanded/decoders/CurrentParsingState.h
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedChar.h
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedInformation.h
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedNumeric.h
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedObject.h
${ZXING_DIR}/oned/rss/expanded/decoders/FieldParser.h
${ZXING_DIR}/oned/rss/expanded/decoders/GeneralAppIdDecoder.h
${ZXING_DIR}/oned/rss/expanded/BitArrayBuilder.h
${ZXING_DIR}/oned/rss/expanded/ExpandedPair.h
${ZXING_DIR}/oned/rss/expanded/ExpandedRow.h
${ZXING_DIR}/oned/rss/expanded/RSSExpandedReader.h
${ZXING_DIR}/oned/UPCEReader.cpp
${ZXING_DIR}/oned/UPCEANReader.cpp
${ZXING_DIR}/oned/UPCEANExtensionSupport.cpp
${ZXING_DIR}/oned/UPCEANExtension2Support.cpp
${ZXING_DIR}/oned/UPCEANExtension5Support.cpp
${ZXING_DIR}/oned/UPCAReader.cpp
${ZXING_DIR}/oned/OneDResultPoint.cpp
${ZXING_DIR}/oned/OneDReader.cpp
${ZXING_DIR}/oned/MultiFormatUPCEANReader.cpp
${ZXING_DIR}/oned/MultiFormatOneDReader.cpp
${ZXING_DIR}/oned/ITFReader.cpp
${ZXING_DIR}/oned/EAN13Reader.cpp
${ZXING_DIR}/oned/EAN8Reader.cpp
${ZXING_DIR}/oned/EANManufacturerOrgSupport.cpp
${ZXING_DIR}/oned/Code128Reader.cpp
${ZXING_DIR}/oned/Code39Reader.cpp
${ZXING_DIR}/oned/CodaBarReader.cpp
${ZXING_DIR}/oned/Code93Reader.cpp
${ZXING_DIR}/oned/rss/AbstractRSSReader.cpp
${ZXING_DIR}/oned/rss/DataCharacter.cpp
${ZXING_DIR}/oned/rss/FinderPattern.cpp
${ZXING_DIR}/oned/rss/Pair.cpp
${ZXING_DIR}/oned/rss/RSS14Reader.cpp
${ZXING_DIR}/oned/rss/RSSUtils.cpp
${ZXING_DIR}/oned/rss/expanded/BitArrayBuilder.cpp
${ZXING_DIR}/oned/rss/expanded/ExpandedPair.cpp
${ZXING_DIR}/oned/rss/expanded/ExpandedRow.cpp
${ZXING_DIR}/oned/rss/expanded/RSSExpandedReader.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AbstractExpandedDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01AndOtherAIs.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01decoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01weightDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI013x0x1xDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI013x0xDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01320xDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01392xDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI01393xDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AI013103decoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/AnyAIDecoder.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/BlockParsedResult.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/CurrentParsingState.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedChar.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedInformation.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedNumeric.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/DecodedObject.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/FieldParser.cpp
${ZXING_DIR}/oned/rss/expanded/decoders/GeneralAppIdDecoder.cpp
)
SET(PDF417_DIR
${ZXING_DIR}/pdf417/PDF417Reader.cpp
${ZXING_DIR}/pdf417/PDF417Reader.h
${ZXING_DIR}/pdf417/decoder/BitMatrixParser.h
${ZXING_DIR}/pdf417/decoder/DecodedBitStreamParser.h
${ZXING_DIR}/pdf417/decoder/Decoder.h
${ZXING_DIR}/pdf417/decoder/PDF417BitMatrixParser.cpp
${ZXING_DIR}/pdf417/decoder/PDF417DecodedBitStreamParser.cpp
${ZXING_DIR}/pdf417/decoder/PDF417Decoder.cpp
${ZXING_DIR}/pdf417/decoder/ec/ErrorCorrection.cpp
${ZXING_DIR}/pdf417/decoder/ec/ErrorCorrection.h
${ZXING_DIR}/pdf417/decoder/ec/ModulusGF.cpp
${ZXING_DIR}/pdf417/decoder/ec/ModulusGF.h
${ZXING_DIR}/pdf417/decoder/ec/ModulusPoly.cpp
${ZXING_DIR}/pdf417/decoder/ec/ModulusPoly.h
${ZXING_DIR}/pdf417/detector/Detector.h
${ZXING_DIR}/pdf417/detector/LinesSampler.cpp
${ZXING_DIR}/pdf417/detector/LinesSampler.h
${ZXING_DIR}/pdf417/detector/PDF417Detector.cpp
)
SET(QRCODE_DIR
${ZXING_DIR}/qrcode/ErrorCorrectionLevel.h
${ZXING_DIR}/qrcode/FormatInformation.h
${ZXING_DIR}/qrcode/QRCodeReader.cpp
${ZXING_DIR}/qrcode/QRCodeReader.h
${ZXING_DIR}/qrcode/QRErrorCorrectionLevel.cpp
${ZXING_DIR}/qrcode/QRFormatInformation.cpp
${ZXING_DIR}/qrcode/QRVersion.cpp
${ZXING_DIR}/qrcode/Version.h
${ZXING_DIR}/qrcode/decoder/BitMatrixParser.h
${ZXING_DIR}/qrcode/decoder/DataBlock.h
${ZXING_DIR}/qrcode/decoder/DataMask.h
${ZXING_DIR}/qrcode/decoder/DecodedBitStreamParser.h
${ZXING_DIR}/qrcode/decoder/Decoder.h
${ZXING_DIR}/qrcode/decoder/Mode.h
${ZXING_DIR}/qrcode/decoder/QRBitMatrixParser.cpp
${ZXING_DIR}/qrcode/decoder/QRDataBlock.cpp
${ZXING_DIR}/qrcode/decoder/QRDataMask.cpp
${ZXING_DIR}/qrcode/decoder/QRDecodedBitStreamParser.cpp
${ZXING_DIR}/qrcode/decoder/QRDecoder.cpp
${ZXING_DIR}/qrcode/decoder/QRMode.cpp
${ZXING_DIR}/qrcode/detector/AlignmentPattern.h
${ZXING_DIR}/qrcode/detector/AlignmentPatternFinder.h
${ZXING_DIR}/qrcode/detector/Detector.h
${ZXING_DIR}/qrcode/detector/FinderPattern.h
${ZXING_DIR}/qrcode/detector/FinderPatternFinder.h
${ZXING_DIR}/qrcode/detector/FinderPatternInfo.h
${ZXING_DIR}/qrcode/detector/QRAlignmentPattern.cpp
${ZXING_DIR}/qrcode/detector/QRAlignmentPatternFinder.cpp
${ZXING_DIR}/qrcode/detector/QRDetector.cpp
${ZXING_DIR}/qrcode/detector/QRFinderPattern.cpp
${ZXING_DIR}/qrcode/detector/QRFinderPatternFinder.cpp
${ZXING_DIR}/qrcode/detector/QRFinderPatternInfo.cpp
${ZXING_DIR}/qrcode/encoder/BlockPair.h
${ZXING_DIR}/qrcode/encoder/ByteMatrix.cpp
${ZXING_DIR}/qrcode/encoder/ByteMatrix.h
${ZXING_DIR}/qrcode/encoder/Encoder.h
${ZXING_DIR}/qrcode/encoder/MaskUtil.cpp
${ZXING_DIR}/qrcode/encoder/MaskUtil.h
${ZXING_DIR}/qrcode/encoder/MatrixUtil.cpp
${ZXING_DIR}/qrcode/encoder/MatrixUtil.h
${ZXING_DIR}/qrcode/encoder/QRCode.cpp
${ZXING_DIR}/qrcode/encoder/QRCode.h
${ZXING_DIR}/qrcode/encoder/QREncoder.cpp
)
target_sources(qzxing PRIVATE
${SOURCES}
${AZTEC_DIR}
${COMMON_DIR}
${DATAMATRIX_DIR}
${MULTI_DIR}
${ONED_DIR}
${PDF417_DIR}
${QRCODE_DIR})

@ -0,0 +1,28 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* ChecksumException.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/ChecksumException.h>
using zxing::ChecksumException;
ChecksumException::ChecksumException() ZXING_NOEXCEPT {}
ChecksumException::ChecksumException(const char *msg) ZXING_NOEXCEPT : ReaderException(msg) {}
ChecksumException::~ChecksumException() ZXING_NOEXCEPT {}

@ -0,0 +1,33 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_CHECKSUM_EXCEPTION_H
#define ZXING_CHECKSUM_EXCEPTION_H
/*
* 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/ReaderException.h>
namespace zxing {
class ChecksumException : public ReaderException {
public:
ChecksumException() ZXING_NOEXCEPT;
ChecksumException(const char *msg) ZXING_NOEXCEPT;
~ChecksumException() ZXING_NOEXCEPT;
};
}
#endif // ZXING_CHECKSUM_EXCEPTION_H

@ -0,0 +1,209 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* DecodeHintType.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/DecodeHints.h>
#include <zxing/common/IllegalArgumentException.h>
#include <qglobal.h>
#include <iterator>
using zxing::Ref;
using zxing::ResultPointCallback;
using zxing::DecodeHints;
// VC++
using zxing::BarcodeFormat;
const zxing::DecodeHintType DecodeHints::AZTEC_HINT = 1 << BarcodeFormat::AZTEC;
const zxing::DecodeHintType DecodeHints::CODABAR_HINT = 1 << BarcodeFormat::CODABAR;
const zxing::DecodeHintType DecodeHints::CODE_39_HINT = 1 << BarcodeFormat::CODE_39;
const zxing::DecodeHintType DecodeHints::CODE_93_HINT = 1 << BarcodeFormat::CODE_93;
const zxing::DecodeHintType DecodeHints::CODE_128_HINT = 1 << BarcodeFormat::CODE_128;
const zxing::DecodeHintType DecodeHints::DATA_MATRIX_HINT = 1 << BarcodeFormat::DATA_MATRIX;
const zxing::DecodeHintType DecodeHints::EAN_8_HINT = 1 << BarcodeFormat::EAN_8;
const zxing::DecodeHintType DecodeHints::EAN_13_HINT = 1 << BarcodeFormat::EAN_13;
const zxing::DecodeHintType DecodeHints::ITF_HINT = 1 << BarcodeFormat::ITF;
const zxing::DecodeHintType DecodeHints::MAXICODE_HINT = 1 << BarcodeFormat::MAXICODE;
const zxing::DecodeHintType DecodeHints::PDF_417_HINT = 1 << BarcodeFormat::PDF_417;
const zxing::DecodeHintType DecodeHints::QR_CODE_HINT = 1 << BarcodeFormat::QR_CODE;
const zxing::DecodeHintType DecodeHints::RSS_14_HINT = 1 << BarcodeFormat::RSS_14;
const zxing::DecodeHintType DecodeHints::RSS_EXPANDED_HINT = 1 << BarcodeFormat::RSS_EXPANDED;
const zxing::DecodeHintType DecodeHints::UPC_A_HINT = 1 << BarcodeFormat::UPC_A;
const zxing::DecodeHintType DecodeHints::UPC_E_HINT = 1 << BarcodeFormat::UPC_E;
const zxing::DecodeHintType DecodeHints::UPC_EAN_EXTENSION_HINT = 1 << BarcodeFormat::UPC_EAN_EXTENSION;
const zxing::DecodeHintType DecodeHints::ASSUME_GS1 = 1 << BarcodeFormat::ASSUME_GS1;
const zxing::DecodeHintType DecodeHints::TRYHARDER_HINT = 1 << 31;
const zxing::DecodeHintType DecodeHints::CHARACTER_SET = 1 << 30;
const zxing::DecodeHints DecodeHints::PRODUCT_HINT(
DecodeHints::UPC_A_HINT |
DecodeHints::UPC_E_HINT |
DecodeHints::EAN_13_HINT |
DecodeHints::EAN_8_HINT |
DecodeHints::RSS_14_HINT
);
const zxing::DecodeHints DecodeHints::ONED_HINT(
DecodeHints::CODE_39_HINT |
DecodeHints::CODE_93_HINT |
DecodeHints::CODE_128_HINT |
DecodeHints::ITF_HINT |
DecodeHints::CODABAR_HINT |
DecodeHints::PRODUCT_HINT
);
const zxing::DecodeHints DecodeHints::DEFAULT_HINT(
DecodeHints::ONED_HINT |
DecodeHints::QR_CODE_HINT |
DecodeHints::DATA_MATRIX_HINT |
DecodeHints::AZTEC_HINT |
DecodeHints::PDF_417_HINT
);
DecodeHints::DecodeHints() {
hints = 0;
allowedEanExtensions = {};
}
DecodeHints::DecodeHints(const zxing::DecodeHintType &init) {
hints = init;
}
DecodeHints::DecodeHints(const DecodeHints &other) {
hints = other.hints;
callback = other.callback;
allowedEanExtensions = other.allowedEanExtensions;
}
void DecodeHints::addFormat(BarcodeFormat toadd) {
switch (toadd) {
case BarcodeFormat::AZTEC: hints |= AZTEC_HINT; break;
case BarcodeFormat::CODABAR: hints |= CODABAR_HINT; break;
case BarcodeFormat::CODE_39: hints |= CODE_39_HINT; break;
case BarcodeFormat::CODE_93: hints |= CODE_93_HINT; break;
case BarcodeFormat::CODE_128: hints |= CODE_128_HINT; break;
case BarcodeFormat::DATA_MATRIX: hints |= DATA_MATRIX_HINT; break;
case BarcodeFormat::EAN_8: hints |= EAN_8_HINT; break;
case BarcodeFormat::EAN_13: hints |= EAN_13_HINT; break;
case BarcodeFormat::ITF: hints |= ITF_HINT; break;
case BarcodeFormat::MAXICODE: hints |= MAXICODE_HINT; break;
case BarcodeFormat::PDF_417: hints |= PDF_417_HINT; break;
case BarcodeFormat::QR_CODE: hints |= QR_CODE_HINT; break;
case BarcodeFormat::RSS_14: hints |= RSS_14_HINT; break;
case BarcodeFormat::RSS_EXPANDED: hints |= RSS_EXPANDED_HINT; break;
case BarcodeFormat::UPC_A: hints |= UPC_A_HINT; break;
case BarcodeFormat::UPC_E: hints |= UPC_E_HINT; break;
case BarcodeFormat::UPC_EAN_EXTENSION: hints |= UPC_EAN_EXTENSION_HINT; break;
case BarcodeFormat::ASSUME_GS1: hints |= ASSUME_GS1; break;
default: throw IllegalArgumentException("Unrecognizd barcode format");
}
}
bool DecodeHints::containsFormat(BarcodeFormat tocheck) const {
DecodeHintType checkAgainst = 0;
switch (tocheck) {
case BarcodeFormat::AZTEC: checkAgainst |= AZTEC_HINT; break;
case BarcodeFormat::CODABAR: checkAgainst |= CODABAR_HINT; break;
case BarcodeFormat::CODE_39: checkAgainst |= CODE_39_HINT; break;
case BarcodeFormat::CODE_93: checkAgainst |= CODE_93_HINT; break;
case BarcodeFormat::CODE_128: checkAgainst |= CODE_128_HINT; break;
case BarcodeFormat::DATA_MATRIX: checkAgainst |= DATA_MATRIX_HINT; break;
case BarcodeFormat::EAN_8: checkAgainst |= EAN_8_HINT; break;
case BarcodeFormat::EAN_13: checkAgainst |= EAN_13_HINT; break;
case BarcodeFormat::ITF: checkAgainst |= ITF_HINT; break;
case BarcodeFormat::MAXICODE: checkAgainst |= MAXICODE_HINT; break;
case BarcodeFormat::PDF_417: checkAgainst |= PDF_417_HINT; break;
case BarcodeFormat::QR_CODE: checkAgainst |= QR_CODE_HINT; break;
case BarcodeFormat::RSS_14: checkAgainst |= RSS_14_HINT; break;
case BarcodeFormat::RSS_EXPANDED: checkAgainst |= RSS_EXPANDED_HINT; break;
case BarcodeFormat::UPC_A: checkAgainst |= UPC_A_HINT; break;
case BarcodeFormat::UPC_E: checkAgainst |= UPC_E_HINT; break;
case BarcodeFormat::UPC_EAN_EXTENSION: checkAgainst |= UPC_EAN_EXTENSION_HINT; break;
case BarcodeFormat::ASSUME_GS1: checkAgainst |= ASSUME_GS1; break;
default: throw IllegalArgumentException("Unrecognizd barcode format");
}
return (hints & checkAgainst) != 0;
}
void DecodeHints::setTryHarder(bool toset) {
if (toset) {
hints |= TRYHARDER_HINT;
} else {
hints &= ~TRYHARDER_HINT;
}
}
bool DecodeHints::getTryHarder() const {
return (hints & TRYHARDER_HINT) != 0;
}
void DecodeHints::setAllowedEanExtensions(std::set<int> toset) {
allowedEanExtensions = toset;
}
std::set<int> DecodeHints::getAllowedEanExtensions() const {
return allowedEanExtensions;
}
void DecodeHints::setResultPointCallback(Ref<ResultPointCallback> const& _callback) {
callback = _callback;
}
Ref<ResultPointCallback> DecodeHints::getResultPointCallback() const {
return callback;
}
zxing::DecodeHints &zxing::DecodeHints::operator =(const zxing::DecodeHints &other)
{
hints = other.hints;
callback = other.callback;
allowedEanExtensions = other.allowedEanExtensions;
return *this;
}
zxing::DecodeHints zxing::operator | (DecodeHints const& l, DecodeHints const& r) {
DecodeHints result (l);
result.hints |= r.hints;
if (!result.callback) {
result.callback = r.callback;
}
result.allowedEanExtensions = l.allowedEanExtensions;
result.allowedEanExtensions.insert(r.allowedEanExtensions.begin(),
r.allowedEanExtensions.end());
return result;
}
zxing::DecodeHints zxing::operator & (DecodeHints const& l, DecodeHints const& r) {
DecodeHints result (l);
result.hints &= r.hints;
if (!result.callback) {
result.callback = r.callback;
}
std::set<int> intersect;
std::set_intersection(l.allowedEanExtensions.begin(), l.allowedEanExtensions.end(),
r.allowedEanExtensions.begin(), r.allowedEanExtensions.end(),
std::inserter(intersect, intersect.begin()));
result.allowedEanExtensions = intersect;
return result;
}

@ -0,0 +1,97 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_DECODEHINTS_H
#define ZXING_DECODEHINTS_H
/*
* DecodeHintType.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.
*/
#include <zxing/BarcodeFormat.h>
#include <zxing/ResultPointCallback.h>
#include <set>
namespace zxing {
typedef unsigned int DecodeHintType;
class DecodeHints;
DecodeHints operator | (DecodeHints const&, DecodeHints const&);
DecodeHints operator & (DecodeHints const&, DecodeHints const&);
class DecodeHints {
private:
DecodeHintType hints;
Ref<ResultPointCallback> callback;
std::set<int> allowedEanExtensions;
public:
static const DecodeHintType AZTEC_HINT;
static const DecodeHintType CODABAR_HINT;
static const DecodeHintType CODE_39_HINT;
static const DecodeHintType CODE_93_HINT;
static const DecodeHintType CODE_128_HINT;
static const DecodeHintType DATA_MATRIX_HINT;
static const DecodeHintType EAN_8_HINT;
static const DecodeHintType EAN_13_HINT;
static const DecodeHintType ITF_HINT;
static const DecodeHintType MAXICODE_HINT;
static const DecodeHintType PDF_417_HINT;
static const DecodeHintType QR_CODE_HINT;
static const DecodeHintType RSS_14_HINT;
static const DecodeHintType RSS_EXPANDED_HINT;
static const DecodeHintType UPC_A_HINT;
static const DecodeHintType UPC_E_HINT;
static const DecodeHintType UPC_EAN_EXTENSION_HINT;
static const DecodeHintType ASSUME_GS1;
static const DecodeHintType TRYHARDER_HINT;
static const DecodeHintType CHARACTER_SET;
// static const DecodeHintType ALLOWED_LENGTHS = 1 << 29;
// static const DecodeHintType ASSUME_CODE_39_CHECK_DIGIT = 1 << 28;
// static const DecodeHintType NEED_RESULT_POINT_CALLBACK = 1 << 26;
static const DecodeHints PRODUCT_HINT;
static const DecodeHints ONED_HINT;
static const DecodeHints DEFAULT_HINT;
DecodeHints();
DecodeHints(const DecodeHintType &init);
DecodeHints(const DecodeHints &other);
void addFormat(BarcodeFormat toadd);
bool containsFormat(BarcodeFormat tocheck) const;
bool isEmpty() const {return (hints==0);}
void clear() {hints=0;}
void setTryHarder(bool toset);
bool getTryHarder() const;
void setAllowedEanExtensions(std::set<int> toset);
std::set<int> getAllowedEanExtensions() const;
void setResultPointCallback(Ref<ResultPointCallback> const&);
Ref<ResultPointCallback> getResultPointCallback() const;
DecodeHints& operator =(DecodeHints const &other);
friend DecodeHints operator| (DecodeHints const&, DecodeHints const&);
friend DecodeHints operator& (DecodeHints const&, DecodeHints const&);
};
}
#endif // ZXING_DECODEHINTS_H

@ -0,0 +1,9 @@
#include "EncodeHint.h"
namespace zxing {
EncodeHint::EncodeHint() :
errorCorrectionLevel_(NULL), characterSet_(""), margin_(0)
{}
}

@ -0,0 +1,46 @@
#ifndef ENCODEHINTTYPE_H
#define ENCODEHINTTYPE_H
#include <string>
#include <zxing/qrcode/ErrorCorrectionLevel.h>
namespace zxing {
class EncodeHint
{
private:
/**
* Specifies what degree of error correction to use, for example in QR Codes.
* Type depends on the encoder. For example for QR codes it's type
* {@link com.google.zxing.qrcode.decoder.ErrorCorrectionLevel ErrorCorrectionLevel}.
* For Aztec it is of type {@link Integer}, representing the minimal percentage of error correction words.
* Note: an Aztec symbol should have a minimum of 25% EC words.
*/
zxing::qrcode::ErrorCorrectionLevel* errorCorrectionLevel_;
/**
* Specifies what character encoding to use where applicable (type {@link String})
*/
std::string characterSet_;
/**
* Specifies margin, in pixels, to use when generating the barcode. The meaning can vary
* by format; for example it controls margin before and after the barcode horizontally for
* most 1D formats. (Type {@link Integer}).
*/
int margin_;
public:
EncodeHint();
std::string getCharacterSet() const { return characterSet_; }
const zxing::qrcode::ErrorCorrectionLevel* getErrorCorrectionLevel() { return errorCorrectionLevel_; }
void setCharacterSet(const std::string& characterSet) { characterSet_ = characterSet; }
void setErrorCorrectionLevel(zxing::qrcode::ErrorCorrectionLevel* errorCorectionLevel)
{ errorCorrectionLevel_ = errorCorectionLevel; }
};
}
#endif //ENCODEHINTTYPE_H

@ -0,0 +1,66 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Exception.cpp
* ZXing
*
* Created by Christian Brunschen on 03/06/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/ZXing.h>
#include <zxing/Exception.h>
#include <string.h>
using zxing::Exception;
Exception::Exception() ZXING_NOEXCEPT
: message(ZXING_NULLPTR) {
}
Exception::Exception(const char *msg) ZXING_NOEXCEPT
: message(copy(msg)) {
}
Exception::Exception(const zxing::Exception &that) ZXING_NOEXCEPT
: std::exception(that),
message(copy(that.message)) {
}
Exception::~Exception() ZXING_NOEXCEPT {
if(message) {
deleteMessage();
}
}
const char *Exception::what() const ZXING_NOEXCEPT {
return message ? message : "";
}
void Exception::deleteMessage() {
delete [] message;
}
char const* Exception::copy(char const* msg) {
char* message = ZXING_NULLPTR;
if (msg) {
size_t l = strlen(msg)+1;
if (l) {
message = new char[l];
strcpy(message, msg);
}
}
return message;
}

@ -0,0 +1,49 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_EXCEPTION_H
#define ZXING_EXCEPTION_H
/*
* Exception.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.
*/
#include <zxing/ZXing.h>
#include <string>
#include <exception>
namespace zxing {
class Exception : public std::exception {
private:
char const* const message;
public:
Exception() ZXING_NOEXCEPT;
Exception(const char* msg) ZXING_NOEXCEPT;
Exception(Exception const& that) ZXING_NOEXCEPT;
~Exception() ZXING_NOEXCEPT;
char const* what() const ZXING_NOEXCEPT;
private:
static char const* copy(char const*);
void deleteMessage();
};
}
#endif // ZXING_EXCEPTION_H

@ -0,0 +1,41 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* FormatException.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/FormatException.h>
namespace zxing {
FormatException::FormatException() {}
FormatException::FormatException(const char *msg) :
ReaderException(msg) {
}
FormatException::~FormatException() ZXING_NOEXCEPT {
}
FormatException const&
FormatException::getFormatInstance() {
static FormatException instance;
return instance;
}
}

@ -0,0 +1,37 @@
#ifndef ZXING_FORMAT_EXCEPTION_H
#define ZXING_FORMAT_EXCEPTION_H
/*
* FormatException.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.
*/
#include <zxing/ReaderException.h>
namespace zxing {
class FormatException : public ReaderException {
public:
FormatException();
FormatException(const char *msg);
~FormatException() ZXING_NOEXCEPT;
static FormatException const& getFormatInstance();
};
}
#endif // ZXING_FORMAT_EXCEPTION_H

@ -0,0 +1,30 @@
/*
* IllegalStateException.cpp
* zxing
*
* Created by Alexander Stillich on 05/11/2018.
* Copyright 2008 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/IllegalStateException.h>
zxing::IllegalStateException::IllegalStateException() ZXING_NOEXCEPT {
}
zxing::IllegalStateException::IllegalStateException(const char *msg) ZXING_NOEXCEPT
: ReaderException(msg) {
}
zxing::IllegalStateException::~IllegalStateException() ZXING_NOEXCEPT {
}

@ -0,0 +1,35 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_ILLEGAL_STATE_EXCEPTION_H
#define ZXING_ILLEGAL_STATE_EXCEPTION_H
/*
* Copyright 20011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may illegal 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 {
class IllegalStateException : public ReaderException {
public:
IllegalStateException() ZXING_NOEXCEPT;
IllegalStateException(const char *msg) ZXING_NOEXCEPT;
~IllegalStateException() ZXING_NOEXCEPT;
};
}
#endif // ZXING_ILLEGAL_STATE_EXCEPTION_H

@ -0,0 +1,69 @@
// -*- 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.
*/
#include <zxing/ZXing.h>
#include <zxing/InvertedLuminanceSource.h>
using zxing::Ref;
using zxing::ArrayRef;
using zxing::LuminanceSource;
namespace zxing {
InvertedLuminanceSource::InvertedLuminanceSource(Ref<LuminanceSource> const& delegate_)
: Super(delegate_->getWidth(), delegate_->getHeight()), delegate(delegate_) {}
ArrayRef<zxing::byte> InvertedLuminanceSource::getRow(int y, ArrayRef<zxing::byte> row) const {
row = delegate->getRow(y, row);
int width = getWidth();
for (int i = 0; i < width; i++) {
row[i] = 0xFF - row[i];
}
return row;
}
ArrayRef<zxing::byte> InvertedLuminanceSource::getMatrix() const {
ArrayRef<zxing::byte> matrix = delegate->getMatrix();
int length = getWidth() * getHeight();
ArrayRef<zxing::byte> invertedMatrix(length);
for (int i = 0; i < length; i++) {
invertedMatrix[i] = 0xFF - matrix[i];
}
return invertedMatrix;
}
zxing::boolean InvertedLuminanceSource::isCropSupported() const {
return delegate->isCropSupported();
}
Ref<LuminanceSource> InvertedLuminanceSource::crop(int left, int top, int width, int height) const {
return Ref<LuminanceSource>(new InvertedLuminanceSource(delegate->crop(left, top, width, height)));
}
zxing::boolean InvertedLuminanceSource::isRotateSupported() const {
return delegate->isRotateSupported();
}
Ref<LuminanceSource> InvertedLuminanceSource::invert() const {
return delegate;
}
Ref<LuminanceSource> InvertedLuminanceSource::rotateCounterClockwise() const {
return Ref<LuminanceSource>(new InvertedLuminanceSource(delegate->rotateCounterClockwise()));
}
}

@ -0,0 +1,48 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_INVERTEDLUMINANCESOURCE_H
#define ZXING_INVERTEDLUMINANCESOURCE_H
/*
* 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.
*/
#include <zxing/ZXing.h>
#include <zxing/LuminanceSource.h>
namespace zxing {
class InvertedLuminanceSource : public LuminanceSource {
private:
typedef LuminanceSource Super;
const Ref<LuminanceSource> delegate;
public:
InvertedLuminanceSource(Ref<LuminanceSource> const&);
ArrayRef<zxing::byte> getRow(int y, ArrayRef<zxing::byte> row) const;
ArrayRef<zxing::byte> getMatrix() const;
boolean isCropSupported() const;
Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
boolean isRotateSupported() const;
virtual Ref<LuminanceSource> invert() const;
Ref<LuminanceSource> rotateCounterClockwise() const;
};
}
#endif // ZXING_INVERTEDLUMINANCESOURCE_H

@ -0,0 +1,91 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* LuminanceSource.cpp
* zxing
*
* Copyright 2008 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 <sstream>
#include <zxing/LuminanceSource.h>
#include <zxing/InvertedLuminanceSource.h>
#include <zxing/common/IllegalArgumentException.h>
using zxing::Ref;
using zxing::LuminanceSource;
LuminanceSource::LuminanceSource(int width_, int height_) :width(width_), height(height_) {}
LuminanceSource::~LuminanceSource() {}
bool LuminanceSource::isCropSupported() const {
return false;
}
Ref<LuminanceSource> LuminanceSource::crop(int, int, int, int) const {
throw IllegalArgumentException("This luminance source does not support cropping.");
}
bool LuminanceSource::isRotateSupported() const {
return false;
}
Ref<LuminanceSource> LuminanceSource::rotateCounterClockwise() const {
throw IllegalArgumentException("This luminance source does not support rotation.");
}
Ref<zxing::LuminanceSource> LuminanceSource::rotateCounterClockwise45() const
{
throw IllegalArgumentException("This luminance source does not support rotation 45.");
}
LuminanceSource::operator std::string() const {
ArrayRef<zxing::byte> row;
std::ostringstream oss;
for (int y = 0; y < getHeight(); y++) {
row = getRow(y, row);
for (int x = 0; x < getWidth(); x++) {
int luminance = row[x];// & 0xFF;
char c;
if (luminance < 0x40) {
c = '#';
} else if (luminance < 0x80) {
c = '+';
} else if (luminance < 0xC0) {
c = '.';
} else {
c = ' ';
}
oss << c;
}
oss << '\n';
}
return oss.str();
}
Ref<LuminanceSource> LuminanceSource::invert() const {
// N.B.: this only works because we use counted objects with the
// count in the object. This is _not_ how things like shared_ptr
// work. They do not allow you to make a smart pointer from a native
// pointer more than once. If we ever switch to (something like)
// shared_ptr's, the luminace source is going to have keep a weak
// pointer to itself from which it can create a strong pointer as
// needed. And, FWIW, that has nasty semantics in the face of
// exceptions during construction.
return Ref<LuminanceSource>
(new InvertedLuminanceSource(Ref<LuminanceSource>(const_cast<LuminanceSource*>(this))));
}

@ -0,0 +1,62 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_LUMINANCESOURCE_H
#define ZXING_LUMINANCESOURCE_H
/*
* LuminanceSource.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.
*/
#include <zxing/common/Counted.h>
#include <zxing/common/Array.h>
#include <string.h>
#include "common/Types.h"
namespace zxing {
class LuminanceSource : public Counted {
private:
const int width;
const int height;
public:
LuminanceSource(int width, int height);
virtual ~LuminanceSource();
int getWidth() const { return width; }
int getHeight() const { return height; }
// Callers take ownership of the returned memory and must call delete [] on it themselves.
virtual ArrayRef<zxing::byte> getRow(int y, ArrayRef<zxing::byte> row) const = 0;
virtual ArrayRef<zxing::byte> getMatrix() const = 0;
virtual bool isCropSupported() const;
virtual Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
virtual bool isRotateSupported() const;
virtual Ref<LuminanceSource> invert() const;
virtual Ref<LuminanceSource> rotateCounterClockwise() const;
virtual Ref<LuminanceSource> rotateCounterClockwise45() const;
operator std::string () const;
};
}
#endif // ZXING_LUMINANCESOURCE_H

@ -0,0 +1,152 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* 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/MultiFormatReader.h>
#include <zxing/ReaderException.h>
#include <zxing/ZXing.h>
#ifdef ENABLE_DECODER_AZTEC
#include <zxing/aztec/AztecReader.h>
#endif // ENABLE_DECODER_AZTEC
#ifdef ENABLE_DECODER_DATA_MATRIX
#include <zxing/datamatrix/DataMatrixReader.h>
#endif // ENABLE_DECODER_DATA_MATRIX
#ifdef ENABLE_DECODER_1D_BARCODES
#include <zxing/oned/MultiFormatOneDReader.h>
#include <zxing/oned/MultiFormatUPCEANReader.h>
#endif // ENABLE_DECODER_1D_BARCODES
#ifdef ENABLE_DECODER_PDF17
#include <zxing/pdf417/PDF417Reader.h>
#endif // ENABLE_DECODER_PDF17
#ifdef ENABLE_DECODER_QR_CODE
#include <zxing/qrcode/QRCodeReader.h>
#endif // ENABLE_DECODER_QR_CODE
using zxing::Ref;
using zxing::Result;
using zxing::MultiFormatReader;
// VC++
using zxing::DecodeHints;
using zxing::BinaryBitmap;
MultiFormatReader::MultiFormatReader() {}
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image) {
setHints(DecodeHints::DEFAULT_HINT);
return decodeInternal(image);
}
Ref<Result> MultiFormatReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
setHints(hints);
return decodeInternal(image);
}
Ref<Result> MultiFormatReader::decodeWithState(Ref<BinaryBitmap> image) {
// Make sure to set up the default state so we don't crash
if (readers_.empty()) {
setHints(DecodeHints::DEFAULT_HINT);
}
return decodeInternal(image);
}
void MultiFormatReader::setHints(DecodeHints hints) {
hints_ = hints;
readers_.clear();
enableReaders(hints, false);
if (readers_.empty())
enableReaders(hints, true);
}
void MultiFormatReader::enableReaders(zxing::DecodeHints hints, bool allowAll)
{
bool tryHarder = hints.getTryHarder();
bool addOneDReader = hints.containsFormat(BarcodeFormat::UPC_E) ||
hints.containsFormat(BarcodeFormat::UPC_A) ||
hints.containsFormat(BarcodeFormat::UPC_E) ||
hints.containsFormat(BarcodeFormat::EAN_13) ||
hints.containsFormat(BarcodeFormat::EAN_8) ||
hints.containsFormat(BarcodeFormat::CODABAR) ||
hints.containsFormat(BarcodeFormat::CODE_39) ||
hints.containsFormat(BarcodeFormat::CODE_93) ||
hints.containsFormat(BarcodeFormat::CODE_128) ||
hints.containsFormat(BarcodeFormat::ITF) ||
hints.containsFormat(BarcodeFormat::RSS_14) ||
hints.containsFormat(BarcodeFormat::RSS_EXPANDED);
#ifdef ENABLE_DECODER_1D_BARCODES
if ((allowAll || addOneDReader) && !tryHarder) {
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
}
#endif
#ifdef ENABLE_DECODER_QR_CODE
if (allowAll || hints.containsFormat(BarcodeFormat::QR_CODE)) {
readers_.push_back(Ref<Reader>(new zxing::qrcode::QRCodeReader()));
}
#endif
#ifdef ENABLE_DECODER_DATA_MATRIX
if (allowAll || hints.containsFormat(BarcodeFormat::DATA_MATRIX)) {
readers_.push_back(Ref<Reader>(new zxing::datamatrix::DataMatrixReader()));
}
#endif
#ifdef ENABLE_DECODER_AZTEC
if (allowAll || hints.containsFormat(BarcodeFormat::AZTEC)) {
readers_.push_back(Ref<Reader>(new zxing::aztec::AztecReader()));
}
#endif
#ifdef ENABLE_DECODER_PDF17
if (allowAll || hints.containsFormat(BarcodeFormat::PDF_417)) {
readers_.push_back(Ref<Reader>(new zxing::pdf417::PDF417Reader()));
}
#endif
/*
if (hints.contains(BarcodeFormat.MAXICODE)) {
readers.add(new MaxiCodeReader());
}
*/
#ifdef ENABLE_DECODER_1D_BARCODES
if ((allowAll || addOneDReader) && tryHarder) {
readers_.push_back(Ref<Reader>(new zxing::oned::MultiFormatOneDReader(hints)));
}
#endif
}
Ref<Result> MultiFormatReader::decodeInternal(Ref<BinaryBitmap> image) {
for (size_t i = 0; i < readers_.size(); i++) {
try {
return readers_[i]->decode(image, hints_);
} catch (ReaderException const& re) {
(void)re;
// continue
}
}
throw ReaderException("No code detected");
}
MultiFormatReader::~MultiFormatReader() {}

@ -0,0 +1,50 @@
#ifndef ZXING_MULTI_FORMAT_READER_H
#define ZXING_MULTI_FORMAT_READER_H
/*
* MultiFormatBarcodeReader.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.
*/
#include <zxing/Reader.h>
#include <zxing/common/BitArray.h>
#include <zxing/Result.h>
#include <zxing/DecodeHints.h>
namespace zxing {
class MultiFormatReader : public Reader {
private:
Ref<Result> decodeInternal(Ref<BinaryBitmap> image);
std::vector<Ref<Reader> > readers_;
DecodeHints hints_;
public:
MultiFormatReader();
Ref<Result> decode(Ref<BinaryBitmap> image);
Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
Ref<Result> decodeWithState(Ref<BinaryBitmap> image);
void setHints(DecodeHints hints);
void enableReaders(DecodeHints hints, bool allowAll = false);
~MultiFormatReader();
};
}
#endif // ZXING_MULTI_FORMAT_READER_H

@ -0,0 +1,30 @@
/*
* IllegalStateException.cpp
* zxing
*
* Created by Alexander Stillich on 05/11/2018.
* Copyright 2008 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/NotFoundException.h>
zxing::NotFoundException::NotFoundException() ZXING_NOEXCEPT {
}
zxing::NotFoundException::NotFoundException(const char *msg) ZXING_NOEXCEPT
: ReaderException(msg) {
}
zxing::NotFoundException::~NotFoundException() ZXING_NOEXCEPT {
}

@ -0,0 +1,35 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_NOT_FOUND_EXCEPTION_H
#define ZXING_NOT_FOUND_EXCEPTION_H
/*
* 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/ReaderException.h>
namespace zxing {
class NotFoundException : public ReaderException {
public:
NotFoundException() ZXING_NOEXCEPT;
NotFoundException(const char *msg) ZXING_NOEXCEPT;
~NotFoundException() ZXING_NOEXCEPT;
};
}
#endif // ZXING_NOT_FOUND_EXCEPTION_H

@ -0,0 +1,31 @@
/*
* Reader.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/Reader.h>
namespace zxing {
Reader::~Reader() { }
Ref<Result> Reader::decode(Ref<BinaryBitmap> image) {
return decode(image, DecodeHints::DEFAULT_HINT);
}
}

@ -0,0 +1,40 @@
#ifndef ZXING_READER_H
#define ZXING_READER_H
/*
* Reader.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.
*/
#include <zxing/BinaryBitmap.h>
#include <zxing/Result.h>
#include <zxing/DecodeHints.h>
namespace zxing {
class Reader : public Counted {
protected:
Reader() {}
public:
virtual Ref<Result> decode(Ref<BinaryBitmap> image);
virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints) = 0;
virtual ~Reader();
};
}
#endif // ZXING_READER_H

@ -0,0 +1,30 @@
/*
* ReaderException.cpp
* zxing
*
* Created by Alexander Stillich on 05/11/2018.
* Copyright 2008 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>
zxing::ReaderException::ReaderException() ZXING_NOEXCEPT {
}
zxing::ReaderException::ReaderException(const char *msg) ZXING_NOEXCEPT
: Exception(msg) {
}
zxing::ReaderException::~ReaderException() ZXING_NOEXCEPT {
}

@ -0,0 +1,37 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_READER_EXCEPTION_H
#define ZXING_READER_EXCEPTION_H
/*
* ReaderException.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.
*/
#include <zxing/Exception.h>
namespace zxing {
class ReaderException : public Exception {
public:
ReaderException() ZXING_NOEXCEPT;
ReaderException(char const* msg) ZXING_NOEXCEPT;
~ReaderException() ZXING_NOEXCEPT;
};
}
#endif // ZXING_READER_EXCEPTION_H

@ -0,0 +1,76 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Result.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/Result.h>
using zxing::Result;
using zxing::Ref;
using zxing::ArrayRef;
using zxing::String;
using zxing::ResultPoint;
// VC++
using zxing::BarcodeFormat;
namespace zxing {
Result::Result(Ref<String> text,
ArrayRef<zxing::byte> rawBytes,
ArrayRef< Ref<ResultPoint> > resultPoints,
BarcodeFormat format, const std::string &charSet,
ResultMetadata metadata) :
text_(text), rawBytes_(rawBytes), resultPoints_(resultPoints), format_(format), charSet_(charSet), metadata_(metadata) {
}
Result::~Result() {
}
Ref<String> Result::getText() {
return text_;
}
ArrayRef<zxing::byte> Result::getRawBytes() {
return rawBytes_;
}
ArrayRef< Ref<ResultPoint> > const& Result::getResultPoints() const {
return resultPoints_;
}
ArrayRef< Ref<ResultPoint> >& Result::getResultPoints() {
return resultPoints_;
}
zxing::BarcodeFormat Result::getBarcodeFormat() const {
return format_;
}
std::string Result::getCharSet() const
{
return charSet_;
}
ResultMetadata &Result::getMetadata()
{
return metadata_;
}
}

@ -0,0 +1,62 @@
#ifndef ZXING_RESULT_H
#define ZXING_RESULT_H
/*
* Result.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.
*/
#include <string>
#include <zxing/common/Array.h>
#include <zxing/common/Counted.h>
#include <zxing/common/Str.h>
#include <zxing/common/Types.h>
#include <zxing/ResultPoint.h>
#include <zxing/ResultMetadata.h>
#include <zxing/BarcodeFormat.h>
namespace zxing {
class Result : public Counted {
private:
Ref<String> text_;
ArrayRef<zxing::byte> rawBytes_;
ArrayRef< Ref<ResultPoint> > resultPoints_;
BarcodeFormat format_;
std::string charSet_;
ResultMetadata metadata_;
public:
Result(Ref<String> text,
ArrayRef<zxing::byte> rawBytes,
ArrayRef< Ref<ResultPoint> > resultPoints,
BarcodeFormat format, const std::string &charSet = "",
ResultMetadata metadata = ResultMetadata());
~Result();
Ref<String> getText();
ArrayRef<zxing::byte> getRawBytes();
ArrayRef< Ref<ResultPoint> > const& getResultPoints() const;
ArrayRef< Ref<ResultPoint> >& getResultPoints();
BarcodeFormat getBarcodeFormat() const;
std::string getCharSet() const;
ResultMetadata& getMetadata();
friend std::ostream& operator<<(std::ostream &out, Result& result);
};
}
#endif // ZXING_RESULT_H

@ -0,0 +1,34 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* ResultIO.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/Result.h>
using zxing::Result;
using std::ostream;
ostream& zxing::operator<<(ostream &out, Result& result) {
if (result.text_ != 0) {
out << result.text_->getText();
} else {
out << "[" << result.rawBytes_->size() << " bytes]";
}
return out;
}

@ -0,0 +1,111 @@
/*
* Copyright 2008 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.
*
* 2019-05-08 translation from Java into C++
*/
#include <zxing/ResultMetadata.h>
#include <zxing/common/ByteArray.h>
namespace zxing {
struct ResultMetadata::Value
{
virtual ~Value() {}
virtual int toInteger(int fallback) const {
return fallback;
}
virtual std::string toString() const {
return std::string();
}
};
struct ResultMetadata::IntegerValue : public Value
{
int value;
explicit IntegerValue(int v) : value(v) {}
int toInteger(int) const override {
return value;
}
};
struct ResultMetadata::StringValue : public Value
{
std::string value;
explicit StringValue(std::string v) : value(std::move(v)) {}
std::string toString() const override {
return value;
}
};
int ResultMetadata::getInt(Key key, int fallbackValue) const
{
std::map<Key, std::shared_ptr<Value>>::const_iterator it = _contents.find(key);
return it != _contents.end() ? it->second->toInteger(fallbackValue) : fallbackValue;
}
std::string ResultMetadata::getString(Key key) const {
std::map<Key, std::shared_ptr<Value>>::const_iterator it = _contents.find(key);
return it != _contents.end() ? it->second->toString() : std::string();
}
void ResultMetadata::put(Key key, int value) {
_contents[key] = std::make_shared<IntegerValue>(value);
}
void ResultMetadata::put(Key key, const std::string &value) {
_contents[key] = std::make_shared<StringValue>(value);
}
void ResultMetadata::putAll(const ResultMetadata& other) {
_contents.insert(other._contents.begin(), other._contents.end());
}
std::list<ResultMetadata::Key> ResultMetadata::keys() const
{
std::list<Key> keys;
for(std::map<Key, std::shared_ptr<Value>>::const_iterator it = _contents.begin(); it != _contents.end(); ++it) {
keys.push_back(it->first);
}
return keys;
}
bool ResultMetadata::empty() const
{
return _contents.empty();
}
std::string ResultMetadata::keyToString(Key key) const
{
switch (key)
{
case OTHER: return "OTHER";
case ORIENTATION: return "ORIENTATION";
case BYTE_SEGMENTS: return "BYTE_SEGMENTS";
case ERROR_CORRECTION_LEVEL: return "ERROR_CORRECTION_LEVEL";
case ISSUE_NUMBER: return "ISSUE_NUMBER";
case SUGGESTED_PRICE: return "SUGGESTED_PRICE";
case POSSIBLE_COUNTRY: return "POSSIBLE_COUNTRY";
case UPC_EAN_EXTENSION: return "UPC_EAN_EXTENSION";
case PDF417_EXTRA_METADATA: return "PDF417_EXTRA_METADATA";
case STRUCTURED_APPEND_SEQUENCE: return "STRUCTURED_APPEND_SEQUENCE";
case STRUCTURED_APPEND_CODE_COUNT: return "STRUCTURED_APPEND_CODE_COUNT";
case STRUCTURED_APPEND_PARITY: return "STRUCTURED_APPEND_PARITY";
}
return "UNKNOWN";
}
} // zxing

@ -0,0 +1,137 @@
#ifndef ZXING_RESULT_METADATA_H
#define ZXING_RESULT_METADATA_H
/*
* Copyright 2008 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.
*
* 2019-05-08 translation from Java into C++
*/
#include <string>
#include <map>
#include <memory>
#include <list>
namespace zxing {
class ByteArray;
/**
* Represents some type of metadata about the result of the decoding that the decoder
* wishes to communicate back to the caller.
*/
class ResultMetadata
{
public:
enum Key {
/**
* Unspecified, application-specific metadata. Maps to an unspecified {@link Object}.
*/
OTHER,
/**
* Denotes the likely approximate orientation of the barcode in the image. This value
* is given as degrees rotated clockwise from the normal, upright orientation.
* For example a 1D barcode which was found by reading top-to-bottom would be
* said to have orientation "90". This key maps to an {@link Integer} whose
* value is in the range [0,360).
*/
ORIENTATION,
/**
* <p>2D barcode formats typically encode text, but allow for a sort of 'byte mode'
* which is sometimes used to encode binary data. While {@link Result} makes available
* the complete raw bytes in the barcode for these formats, it does not offer the bytes
* from the byte segments alone.</p>
*/
BYTE_SEGMENTS,
/**
* Error correction level used, if applicable. The value type depends on the
* format, but is typically a String.
*/
ERROR_CORRECTION_LEVEL,
/**
* For some periodicals, indicates the issue number as an {@link Integer}.
*/
ISSUE_NUMBER,
/**
* For some products, indicates the suggested retail price in the barcode as a
* formatted {@link String}.
*/
SUGGESTED_PRICE,
/**
* For some products, the possible country of manufacture as a {@link String} denoting the
* ISO country code. Some map to multiple possible countries, like "US/CA".
*/
POSSIBLE_COUNTRY,
/**
* For some products, the extension text
*/
UPC_EAN_EXTENSION,
/**
* PDF417-specific metadata
*/
PDF417_EXTRA_METADATA,
/**
* If the code format supports structured append and the current scanned code is part of one then the
* sequence number is given with it.
*/
STRUCTURED_APPEND_SEQUENCE,
/**
* If the code format supports structured append and the current scanned code is part of one then the
* total code count is given with it.
*/
STRUCTURED_APPEND_CODE_COUNT,
/**
* If the code format supports structured append and the current scanned code is part of one then the
* parity is given with it.
*/
STRUCTURED_APPEND_PARITY
};
int getInt(Key key, int fallbackValue = 0) const;
std::string getString(Key key) const;
void put(Key key, int value);
void put(Key key, const std::string& value);
void putAll(const ResultMetadata& other);
std::list<Key> keys() const;
std::string keyToString(Key key) const;
bool empty() const;
private:
struct Value;
struct IntegerValue;
struct StringValue;
std::map<Key, std::shared_ptr<Value>> _contents;
};
}
#endif

@ -0,0 +1,111 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* ResultPoint.cpp
* zxing
*
* Created by Christian Brunschen on 13/05/2008.
* Copyright 2008 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/ResultPoint.h>
#include <zxing/common/detector/MathUtils.h>
using zxing::common::detector::MathUtils;
namespace zxing {
ResultPoint::ResultPoint() : posX_(0), posY_(0) {}
ResultPoint::ResultPoint(float x, float y) : posX_(x), posY_(y) {}
ResultPoint::ResultPoint(int x, int y) : posX_(float(x)), posY_(float(y)) {}
ResultPoint::~ResultPoint() {}
float ResultPoint::getX() const {
return posX_;
}
float ResultPoint::getY() const {
return posY_;
}
bool ResultPoint::equals(const Ref<ResultPoint> &other) {
return posX_ == other->getX() && posY_ == other->getY();
}
/**
* <p>Orders an array of three ResultPoints in an order [A,B,C] such that AB < AC and
* BC < AC and the angle between BC and BA is less than 180 degrees.
*/
void ResultPoint::orderBestPatterns(std::vector<Ref<ResultPoint> > &patterns) {
if(patterns.size() != 3)
return;
// Find distances between pattern centers
float zeroOneDistance = distance(patterns[0]->getX(), patterns[1]->getX(),patterns[0]->getY(), patterns[1]->getY());
float oneTwoDistance = distance(patterns[1]->getX(), patterns[2]->getX(),patterns[1]->getY(), patterns[2]->getY());
float zeroTwoDistance = distance(patterns[0]->getX(), patterns[2]->getX(),patterns[0]->getY(), patterns[2]->getY());
Ref<ResultPoint> pointA, pointB, pointC;
// Assume one closest to other two is B; A and C will just be guesses at first
if (oneTwoDistance >= zeroOneDistance && oneTwoDistance >= zeroTwoDistance) {
pointB = patterns[0];
pointA = patterns[1];
pointC = patterns[2];
} else if (zeroTwoDistance >= oneTwoDistance && zeroTwoDistance >= zeroOneDistance) {
pointB = patterns[1];
pointA = patterns[0];
pointC = patterns[2];
} else {
pointB = patterns[2];
pointA = patterns[0];
pointC = patterns[1];
}
// Use cross product to figure out whether A and C are correct or flipped.
// This asks whether BC x BA has a positive z component, which is the arrangement
// we want for A, B, C. If it's negative, then we've got it flipped around and
// should swap A and C.
if (crossProductZ(pointA, pointB, pointC) < 0.0f) {
Ref<ResultPoint> temp = pointA;
pointA = pointC;
pointC = temp;
}
patterns[0] = pointA;
patterns[1] = pointB;
patterns[2] = pointC;
}
float ResultPoint::distance(Ref<ResultPoint> pattern1, Ref<ResultPoint> pattern2) {
return MathUtils::distance(pattern1->posX_,
pattern1->posY_,
pattern2->posX_,
pattern2->posY_);
}
float ResultPoint::distance(float x1, float x2, float y1, float y2) {
float xDiff = x1 - x2;
float yDiff = y1 - y2;
return (float) sqrt((double) (xDiff * xDiff + yDiff * yDiff));
}
float ResultPoint::crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC) {
float bX = pointB->getX();
float bY = pointB->getY();
return ((pointC->getX() - bX) * (pointA->getY() - bY)) - ((pointC->getY() - bY) * (pointA->getX() - bX));
}
}

@ -0,0 +1,55 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_RESULT_POINT_H
#define ZXING_RESULT_POINT_H
/*
* ResultPoint.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.
*/
#include <zxing/common/Counted.h>
#include <vector>
namespace zxing {
class ResultPoint : public Counted {
protected:
const float posX_;
const float posY_;
public:
ResultPoint();
ResultPoint(float x, float y);
ResultPoint(int x, int y);
virtual ~ResultPoint();
virtual float getX() const;
virtual float getY() const;
bool equals(const Ref<ResultPoint> &other);
static void orderBestPatterns(std::vector<Ref<ResultPoint> > &patterns);
static float distance(Ref<ResultPoint> point1, Ref<ResultPoint> point2);
static float distance(float x1, float x2, float y1, float y2);
private:
static float crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC);
};
}
#endif // ZXING_RESULT_POINT_H

@ -0,0 +1,26 @@
/*
* ResultPointCallback.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/ResultPointCallback.h>
namespace zxing {
ResultPointCallback::~ResultPointCallback() {}
}

@ -0,0 +1,39 @@
#ifndef ZXING_RESULT_POINT_CALLBACK_H
#define ZXING_RESULT_POINT_CALLBACK_H
/*
* ResultPointCallback.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.
*/
#include <zxing/common/Counted.h>
namespace zxing {
class ResultPoint;
class ResultPointCallback : public Counted {
protected:
ResultPointCallback() {}
public:
virtual void foundPossibleResultPoint(ResultPoint const& point) = 0;
virtual ~ResultPointCallback();
};
}
#endif // ZXING_RESULT_POINT_CALLBACK_H

@ -0,0 +1,30 @@
/*
* UnsupportedEncodingException.cpp
* zxing
*
* Created by Alexander Stillich on 05/11/2018.
* Copyright 2008 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/UnsupportedEncodingException.h>
zxing::UnsupportedEncodingException::UnsupportedEncodingException() ZXING_NOEXCEPT {
}
zxing::UnsupportedEncodingException::UnsupportedEncodingException(const char *msg) ZXING_NOEXCEPT
: Exception(msg) {
}
zxing::UnsupportedEncodingException::~UnsupportedEncodingException() ZXING_NOEXCEPT {
}

@ -0,0 +1,17 @@
#ifndef UNSUPPORTEDENCODINGEXCEPTION_H
#define UNSUPPORTEDENCODINGEXCEPTION_H
#include <zxing/Exception.h>
namespace zxing {
class UnsupportedEncodingException : public Exception {
public:
UnsupportedEncodingException() ZXING_NOEXCEPT;
UnsupportedEncodingException(char const* msg) ZXING_NOEXCEPT;
~UnsupportedEncodingException() ZXING_NOEXCEPT;
};
}
#endif // UNSUPPORTEDENCODINGEXCEPTION_H

@ -0,0 +1,30 @@
/*
* UnsupportedEncodingException.cpp
* zxing
*
* Created by Alexander Stillich on 05/11/2018.
* Copyright 2008 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/WriterException.h>
zxing::WriterException::WriterException() ZXING_NOEXCEPT {
}
zxing::WriterException::WriterException(const char *msg) ZXING_NOEXCEPT
: Exception(msg) {
}
zxing::WriterException::~WriterException() ZXING_NOEXCEPT {
}

@ -0,0 +1,17 @@
#ifndef WRITEREXCEPTION_H
#define WRITEREXCEPTION_H
#include <zxing/Exception.h>
namespace zxing {
class WriterException : public Exception {
public:
WriterException() ZXING_NOEXCEPT;
WriterException(char const* msg) ZXING_NOEXCEPT;
~WriterException() ZXING_NOEXCEPT;
};
}
#endif // WRITEREXCEPTION_H

@ -0,0 +1,168 @@
// -*- 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])))
#define ZX_LOG_DIGITS(digits) \
((digits == 8) ? 3 : \
((digits == 16) ? 4 : \
((digits == 32) ? 5 : \
((digits == 64) ? 6 : \
((digits == 128) ? 7 : \
(-1))))))
#ifndef ZXING_DEBUG
#define ZXING_DEBUG 0
#endif
#include <limits>
#include "common/Types.h"
#if defined(_WIN32) || defined(_WIN64)
#include <float.h>
#include <cmath>
namespace zxing {
inline bool isnan_z(float v) {return std::isnan(v) != 0;}
inline bool isnan_z(double v) {return std::isnan(v) != 0;}
}
#elif (__cplusplus >= 201103L)
#include <cmath>
namespace zxing {
inline bool isnan_z(float v) {
return std::isnan(v);
}
inline bool isnan_z(double v) {
return std::isnan(v);
}
}
#elif(__STDC_VERSION__ >= 199901L)
#include <math.h>
namespace zxing {
inline bool isnan_z(float v) {
return isnan(v);
}
inline bool isnan_z(double v) {
return isnan(v);
}
}
#else
namespace zxing {
inline bool isnan_z(float v) {
volatile float d = v;
return d != d;
}
inline bool isnan_z(double v) {
volatile double d = v;
return d != d;
}
}
#endif
namespace zxing {
inline float nan() {return std::numeric_limits<float>::quiet_NaN();}
}
#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 {
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
#ifndef ZXING_NULLPTR
#if __cplusplus >= 201103L
#define ZXING_NULLPTR nullptr
#else
#define ZXING_NULLPTR NULL
#endif
#endif // ZXING_NULLPTR
#if __cplusplus >= 201103L
#define ZXING_NOEXCEPT noexcept
#else
#define ZXING_NOEXCEPT throw()
#endif
#endif

@ -0,0 +1,54 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AtztecDetecorResult.cpp
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/aztec/AztecDetectorResult.h>
using zxing::aztec::AztecDetectorResult;
// VC++
using zxing::Ref;
using zxing::ArrayRef;
using zxing::BitMatrix;
using zxing::ResultPoint;
AztecDetectorResult::AztecDetectorResult(Ref<BitMatrix> bits,
ArrayRef< Ref<ResultPoint> > points,
bool compact,
int nbDatablocks,
int nbLayers)
: DetectorResult(bits, points),
compact_(compact),
nbDatablocks_(nbDatablocks),
nbLayers_(nbLayers) {
}
bool AztecDetectorResult::isCompact() {
return compact_;
}
int AztecDetectorResult::getNBDatablocks() {
return nbDatablocks_;
}
int AztecDetectorResult::getNBLayers() {
return nbLayers_;
}

@ -0,0 +1,48 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AtztecDetecorResult.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/DetectorResult.h>
#ifndef ZXingWidget_AtztecDetecorResult_h
#define ZXingWidget_AtztecDetecorResult_h
namespace zxing {
namespace aztec {
class AztecDetectorResult : public DetectorResult {
private:
bool compact_;
int nbDatablocks_, nbLayers_;
public:
AztecDetectorResult(Ref<BitMatrix> bits,
ArrayRef< Ref<ResultPoint> > points,
bool compact,
int nbDatablocks,
int nbLayers);
bool isCompact();
int getNBDatablocks();
int getNBLayers();
};
}
}
#endif

@ -0,0 +1,68 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AztecReader.cpp
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/aztec/AztecReader.h>
#include <zxing/aztec/detector/Detector.h>
#include <zxing/common/DecoderResult.h>
#include <iostream>
using zxing::Ref;
using zxing::ArrayRef;
using zxing::Result;
using zxing::aztec::AztecReader;
// VC++
using zxing::BinaryBitmap;
using zxing::DecodeHints;
AztecReader::AztecReader() : decoder_() {
// nothing
}
Ref<Result> AztecReader::decode(Ref<zxing::BinaryBitmap> image) {
Detector detector(image->getBlackMatrix());
Ref<AztecDetectorResult> detectorResult(detector.detect());
ArrayRef< Ref<ResultPoint> > points(detectorResult->getPoints());
Ref<DecoderResult> decoderResult(decoder_.decode(detectorResult));
Ref<Result> result(new Result(decoderResult->getText(),
decoderResult->getRawBytes(),
points,
BarcodeFormat::AZTEC));
return result;
}
Ref<Result> AztecReader::decode(Ref<BinaryBitmap> image, DecodeHints) {
//cout << "decoding with hints not supported for aztec" << "\n" << flush;
return this->decode(image);
}
AztecReader::~AztecReader() {
// nothing
}
zxing::aztec::Decoder& AztecReader::getDecoder() {
return decoder_;
}

@ -0,0 +1,49 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AztecReader.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/Reader.h>
#include <zxing/aztec/decoder/Decoder.h>
#include <zxing/DecodeHints.h>
#ifndef ZXingWidget_AztecReader_h
#define ZXingWidget_AztecReader_h
namespace zxing {
namespace aztec {
class AztecReader : public Reader {
private:
Decoder decoder_;
protected:
Decoder &getDecoder();
public:
AztecReader();
virtual Ref<Result> decode(Ref<BinaryBitmap> image);
virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
virtual ~AztecReader();
};
}
}
#endif

@ -0,0 +1,495 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Decoder.cpp
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/aztec/decoder/Decoder.h>
#ifndef NO_ICONV
#include <iconv.h>
#endif
#include <iostream>
#include <zxing/FormatException.h>
#include <zxing/common/reedsolomon/ReedSolomonDecoder.h>
#include <zxing/common/reedsolomon/ReedSolomonException.h>
#include <zxing/common/reedsolomon/GenericGF.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/common/DecoderResult.h>
#include <qglobal.h>
using zxing::aztec::Decoder;
using zxing::DecoderResult;
using zxing::String;
using zxing::BitArray;
using zxing::BitMatrix;
using zxing::Ref;
using std::string;
namespace {
void add(string& result, char character) {
#ifndef NO_ICONV
char character2 = character & 0xff;
char s[] = {character2};
char* ss = s;
size_t sl = sizeof(s);
char d[4];
char* ds = d;
size_t dl = sizeof(d);
iconv_t ic = iconv_open("UTF-8", "ISO-8859-1");
#if defined(Q_OS_SYMBIAN)
iconv(ic, (const char**)&ss, &sl, &ds, &dl);
#else
iconv(ic, (char**)&ss, &sl, &ds, &dl);
#endif
iconv_close(ic);
d[sizeof(d)-dl] = 0;
result.append(d);
#else
result.push_back(character);
#endif
}
const int NB_BITS_COMPACT[] = {
0, 104, 240, 408, 608
};
const int NB_BITS[] = {
0, 128, 288, 480, 704, 960, 1248, 1568, 1920, 2304, 2720, 3168, 3648, 4160, 4704, 5280, 5888, 6528,
7200, 7904, 8640, 9408, 10208, 11040, 11904, 12800, 13728, 14688, 15680, 16704, 17760, 18848, 19968
};
const int NB_DATABLOCK_COMPACT[] = {
0, 17, 40, 51, 76
};
const int NB_DATABLOCK[] = {
0, 21, 48, 60, 88, 120, 156, 196, 240, 230, 272, 316, 364, 416, 470, 528, 588, 652, 720, 790, 864,
940, 1020, 920, 992, 1066, 1144, 1224, 1306, 1392, 1480, 1570, 1664
};
const char* UPPER_TABLE[] = {
"CTRL_PS", " ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "CTRL_LL", "CTRL_ML", "CTRL_DL", "CTRL_BS"
};
const char* LOWER_TABLE[] = {
"CTRL_PS", " ", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
"q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "CTRL_US", "CTRL_ML", "CTRL_DL", "CTRL_BS"
};
const char* MIXED_TABLE[] = {
"CTRL_PS", " ", "\1", "\2", "\3", "\4", "\5", "\6", "\7", "\b", "\t", "\n",
"\13", "\f", "\r", "\33", "\34", "\35", "\36", "\37", "@", "\\", "^", "_",
"`", "|", "~", "\177", "CTRL_LL", "CTRL_UL", "CTRL_PL", "CTRL_BS"
};
const char* PUNCT_TABLE[] = {
"", "\r", "\r\n", ". ", ", ", ": ", "!", "\"", "#", "$", "%", "&", "'", "(", ")",
"*", "+", ",", "-", ".", "/", ":", ";", "<", "=", ">", "?", "[", "]", "{", "}", "CTRL_UL"
};
const char* DIGIT_TABLE[] = {
"CTRL_PS", " ", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ",", ".", "CTRL_UL", "CTRL_US"
};
}
Decoder::Table Decoder::getTable(char t) {
switch (t) {
case 'L':
return LOWER;
case 'P':
return PUNCT;
case 'M':
return MIXED;
case 'D':
return DIGIT;
case 'B':
return BINARY;
case 'U':
default:
return UPPER;
}
}
const char* Decoder::getCharacter(zxing::aztec::Decoder::Table table, int code) {
switch (table) {
case UPPER:
return UPPER_TABLE[code];
case LOWER:
return LOWER_TABLE[code];
case MIXED:
return MIXED_TABLE[code];
case PUNCT:
return PUNCT_TABLE[code];
case DIGIT:
return DIGIT_TABLE[code];
default:
return "";
}
}
Decoder::Decoder() {
// nothing
}
Ref<DecoderResult> Decoder::decode(Ref<zxing::aztec::AztecDetectorResult> detectorResult) {
ddata_ = detectorResult;
// std::printf("getting bits\n");
Ref<BitMatrix> matrix = detectorResult->getBits();
if (!ddata_->isCompact()) {
// std::printf("removing lines\n");
matrix = removeDashedLines(ddata_->getBits());
}
// std::printf("extracting bits\n");
Ref<BitArray> rawbits = extractBits(matrix);
// std::printf("correcting bits\n");
Ref<BitArray> aCorrectedBits = correctBits(rawbits);
// std::printf("decoding bits\n");
Ref<String> result = getEncodedData(aCorrectedBits);
// std::printf("constructing array\n");
ArrayRef<zxing::byte> arrayOut(aCorrectedBits->getSize());
for (size_t i = 0; i < aCorrectedBits->count(); i++) {
arrayOut[i] = (zxing::byte)aCorrectedBits->get(i);
}
// std::printf("returning\n");
return Ref<DecoderResult>(new DecoderResult(arrayOut, result));
}
Ref<String> Decoder::getEncodedData(Ref<zxing::BitArray> correctedBits) {
int endIndex = codewordSize_ * ddata_->getNBDatablocks() - invertedBitCount_;
if (endIndex > (int)correctedBits->getSize()) {
// std::printf("invalid input\n");
throw FormatException("invalid input data");
}
Table lastTable = UPPER;
Table table = UPPER;
int startIndex = 0;
std::string result;
bool end = false;
bool shift = false;
bool switchShift = false;
bool binaryShift = false;
while (!end) {
// std::printf("decoooooding\n");
if (shift) {
switchShift = true;
} else {
lastTable = table;
}
int code;
if (binaryShift) {
if (endIndex - startIndex < 5) {
break;
}
int length = readCode(correctedBits, startIndex, 5);
startIndex += 5;
if (length == 0) {
if (endIndex - startIndex < 11) {
break;
}
length = readCode(correctedBits, startIndex, 11) + 31;
startIndex += 11;
}
for (int charCount = 0; charCount < length; charCount++) {
if (endIndex - startIndex < 8) {
end = true;
break;
}
code = readCode(correctedBits, startIndex, 8);
add(result, code);
startIndex += 8;
}
binaryShift = false;
} else {
if (table == BINARY) {
if (endIndex - startIndex < 8) {
break;
}
code = readCode(correctedBits, startIndex, 8);
startIndex += 8;
add(result, code);
} else {
int size = 5;
if (table == DIGIT) {
size = 4;
}
if (endIndex - startIndex < size) {
break;
}
code = readCode(correctedBits, startIndex, size);
startIndex += size;
const char *str = getCharacter(table, code);
std::string string(str);
if ((int)string.find("CTRL_") != -1) {
table = getTable(str[5]);
if (str[6] == 'S') {
shift = true;
if (str[5] == 'B') {
binaryShift = true;
}
}
} else {
result.append(string);
}
}
}
if (switchShift) {
table = lastTable;
shift = false;
switchShift = false;
}
}
return Ref<String>(new String(result));
}
Ref<BitArray> Decoder::correctBits(Ref<zxing::BitArray> rawbits) {
//return rawbits;
// std::printf("decoding stuff:%d datablocks in %d layers\n", ddata_->getNBDatablocks(), ddata_->getNBLayers());
Ref<GenericGF> gf = GenericGF::AZTEC_DATA_6;
if (ddata_->getNBLayers() <= 2) {
codewordSize_ = 6;
gf = GenericGF::AZTEC_DATA_6;
} else if (ddata_->getNBLayers() <= 8) {
codewordSize_ = 8;
gf = GenericGF::AZTEC_DATA_8;
} else if (ddata_->getNBLayers() <= 22) {
codewordSize_ = 10;
gf = GenericGF::AZTEC_DATA_10;
} else {
codewordSize_ = 12;
gf = GenericGF::AZTEC_DATA_12;
}
int numDataCodewords = ddata_->getNBDatablocks();
int numECCodewords;
int offset;
if (ddata_->isCompact()) {
offset = NB_BITS_COMPACT[ddata_->getNBLayers()] - numCodewords_ * codewordSize_;
numECCodewords = NB_DATABLOCK_COMPACT[ddata_->getNBLayers()] - numDataCodewords;
} else {
offset = NB_BITS[ddata_->getNBLayers()] - numCodewords_ * codewordSize_;
numECCodewords = NB_DATABLOCK[ddata_->getNBLayers()] - numDataCodewords;
}
ArrayRef<int> dataWords(numCodewords_);
for (int i = 0; i < numCodewords_; i++) {
int flag = 1;
for (int j = 1; j <= codewordSize_; j++) {
if (rawbits->get(codewordSize_ * i + codewordSize_ - j + offset)) {
dataWords[i] += flag;
}
flag <<= 1;
}
//
//
//
}
try {
ReedSolomonDecoder rsDecoder(gf);
rsDecoder.decode(dataWords, numECCodewords);
} catch (ReedSolomonException const& ignored) {
(void)ignored;
// std::printf("got reed solomon exception:%s, throwing formatexception\n", rse.what());
throw FormatException("rs decoding failed");
} catch (IllegalArgumentException const& iae) {
(void)iae;
// std::printf("illegal argument exception: %s", iae.what());
}
offset = 0;
invertedBitCount_ = 0;
Ref<BitArray> correctedBits(new BitArray(numDataCodewords * codewordSize_));
for (int i = 0; i < numDataCodewords; i++) {
bool seriesColor = false;
int seriesCount = 0;
int flag = 1 << (codewordSize_ - 1);
for (int j = 0; j < codewordSize_; j++) {
bool color = (dataWords[i] & flag) == flag;
if (seriesCount == codewordSize_ - 1) {
if (color == seriesColor) {
throw FormatException("bit was not inverted");
}
seriesColor = false;
seriesCount = 0;
offset++;
invertedBitCount_++;
} else {
if (seriesColor == color) {
seriesCount++;
} else {
seriesCount = 1;
seriesColor = color;
}
if (color) correctedBits->set(i * codewordSize_ + j - offset);
}
flag = ((unsigned int)flag) >> 1;
}
}
return correctedBits;
}
Ref<BitArray> Decoder::extractBits(Ref<zxing::BitMatrix> matrix) {
std::vector<bool> rawbits;
if (ddata_->isCompact()) {
if (ddata_->getNBLayers() > 5) { //NB_BITS_COMPACT length
throw FormatException("data is too long");
}
rawbits = std::vector<bool>(NB_BITS_COMPACT[ddata_->getNBLayers()]);
numCodewords_ = NB_DATABLOCK_COMPACT[ddata_->getNBLayers()];
} else {
if (ddata_->getNBLayers() > 33) { //NB_BITS length
throw FormatException("data is too long");
}
rawbits = std::vector<bool>(NB_BITS[ddata_->getNBLayers()]);
numCodewords_ = NB_DATABLOCK[ddata_->getNBLayers()];
}
int layer = ddata_->getNBLayers();
int size = matrix->getHeight();
int rawbitsOffset = 0;
int matrixOffset = 0;
while (layer != 0) {
int flip = 0;
for (int i = 0; i < 2 * size - 4; i++) {
rawbits[rawbitsOffset + i] = matrix->get(matrixOffset + flip, matrixOffset + i / 2);
rawbits[rawbitsOffset + 2 * size - 4 + i] = matrix->get(matrixOffset + i / 2, matrixOffset + size - 1 - flip);
flip = (flip + 1) % 2;
}
flip = 0;
for (int i = 2 * size + 1; i > 5; i--) {
rawbits[rawbitsOffset + 4 * size - 8 + (2 * size - i) + 1] =
matrix->get(matrixOffset + size - 1 - flip, matrixOffset + i / 2 - 1);
rawbits[rawbitsOffset + 6 * size - 12 + (2 * size - i) + 1] =
matrix->get(matrixOffset + i / 2 - 1, matrixOffset + flip);
flip = (flip + 1) % 2;
}
matrixOffset += 2;
rawbitsOffset += 8 * size - 16;
layer--;
size -= 4;
}
Ref<BitArray> returnValue(new BitArray(int(rawbits.size())));
for (int i = 0; i < (int)rawbits.size(); i++) {
if (rawbits[i]) returnValue->set(i);
}
return returnValue;
}
Ref<BitMatrix> Decoder::removeDashedLines(Ref<zxing::BitMatrix> matrix) {
int nbDashed = 1 + 2 * ((matrix->getWidth() - 1) / 2 / 16);
Ref<BitMatrix> newMatrix(new BitMatrix(matrix->getWidth() - nbDashed, matrix->getHeight() - nbDashed));
int nx = 0;
for (int x = 0; x < (int)matrix->getWidth(); x++) {
if ((matrix->getWidth() / 2 - x) % 16 == 0) {
continue;
}
int ny = 0;
for (int y = 0; y < (int)matrix->getHeight(); y++) {
if ((matrix->getWidth() / 2 - y) % 16 == 0) {
continue;
}
if (matrix->get(x, y)) {
newMatrix->set(nx, ny);
}
ny++;
}
nx++;
}
return newMatrix;
}
int Decoder::readCode(Ref<zxing::BitArray> rawbits, int startIndex, int length) {
int res = 0;
for (int i = startIndex; i < startIndex + length; i++) {
res <<= 1;
if (rawbits->get(i)) {
res ++;
}
}
return res;
}

@ -0,0 +1,69 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Decoder.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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_AZTEC_DECODER_DECODER_H
#define ZXING_AZTEC_DECODER_DECODER_H
#include <zxing/common/BitMatrix.h>
#include <zxing/common/Str.h>
#include <zxing/aztec/AztecDetectorResult.h>
namespace zxing {
class DecoderResult;
namespace aztec {
class Decoder : public Counted {
private:
enum Table {
UPPER,
LOWER,
MIXED,
DIGIT,
PUNCT,
BINARY
};
static Table getTable(char t);
static const char* getCharacter(Table table, int code);
int numCodewords_;
int codewordSize_;
Ref<AztecDetectorResult> ddata_;
int invertedBitCount_;
Ref<String> getEncodedData(Ref<BitArray> correctedBits);
Ref<BitArray> correctBits(Ref<BitArray> rawbits);
Ref<BitArray> extractBits(Ref<BitMatrix> matrix);
static Ref<BitMatrix> removeDashedLines(Ref<BitMatrix> matrix);
static int readCode(Ref<BitArray> rawbits, int startIndex, int length);
public:
Decoder();
Ref<DecoderResult> decode(Ref<AztecDetectorResult> detectorResult);
};
}
}
#endif // ZXING_AZTEC_DECODER_DECODER_H

@ -0,0 +1,548 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Detector.cpp
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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/aztec/detector/Detector.h>
#include <zxing/common/GridSampler.h>
#include <zxing/common/detector/WhiteRectangleDetector.h>
#include <zxing/common/reedsolomon/ReedSolomonDecoder.h>
#include <zxing/common/reedsolomon/ReedSolomonException.h>
#include <zxing/common/reedsolomon/GenericGF.h>
#include <iostream>
#include <zxing/common/detector/MathUtils.h>
#include <zxing/NotFoundException.h>
using std::vector;
using zxing::aztec::Detector;
using zxing::aztec::Point;
using zxing::aztec::AztecDetectorResult;
using zxing::Ref;
using zxing::ArrayRef;
using zxing::ResultPoint;
using zxing::BitArray;
using zxing::BitMatrix;
using zxing::common::detector::MathUtils;
Detector::Detector(Ref<BitMatrix> image):
image_(image),
nbLayers_(0),
nbDataBlocks_(0),
nbCenterLayers_(0) {
}
Ref<AztecDetectorResult> Detector::detect() {
Ref<Point> pCenter = getMatrixCenter();
std::vector<Ref<Point> > bullEyeCornerPoints = getBullEyeCornerPoints(pCenter);
extractParameters(bullEyeCornerPoints);
ArrayRef< Ref<ResultPoint> > corners = getMatrixCornerPoints(bullEyeCornerPoints);
Ref<BitMatrix> bits =
sampleGrid(image_,
corners[shift_%4],
corners[(shift_+3)%4],
corners[(shift_+2)%4],
corners[(shift_+1)%4]);
// std::printf("------------\ndetected: compact:%s, nbDataBlocks:%d, nbLayers:%d\n------------\n",compact_?"YES":"NO", nbDataBlocks_, nbLayers_);
return Ref<AztecDetectorResult>(new AztecDetectorResult(bits, corners, compact_, nbDataBlocks_, nbLayers_));
}
void Detector::extractParameters(std::vector<Ref<Point> > bullEyeCornerPoints) {
int twoCenterLayers = 2 * nbCenterLayers_;
// get the bits around the bull's eye
Ref<BitArray> resab = sampleLine(bullEyeCornerPoints[0], bullEyeCornerPoints[1], twoCenterLayers+1);
Ref<BitArray> resbc = sampleLine(bullEyeCornerPoints[1], bullEyeCornerPoints[2], twoCenterLayers+1);
Ref<BitArray> rescd = sampleLine(bullEyeCornerPoints[2], bullEyeCornerPoints[3], twoCenterLayers+1);
Ref<BitArray> resda = sampleLine(bullEyeCornerPoints[3], bullEyeCornerPoints[0], twoCenterLayers+1);
// determin the orientation of the matrix
if (resab->get(0) && resab->get(twoCenterLayers)) {
shift_ = 0;
} else if (resbc->get(0) && resbc->get(twoCenterLayers)) {
shift_ = 1;
} else if (rescd->get(0) && rescd->get(twoCenterLayers)) {
shift_ = 2;
} else if (resda->get(0) && resda->get(twoCenterLayers)) {
shift_ = 3;
} else {
// std::printf("could not detemine orientation\n");
throw ReaderException("could not determine orientation");
}
//d a
//
//c b
//flatten the bits in a single array
Ref<BitArray> parameterData(new BitArray(compact_?28:40));
Ref<BitArray> shiftedParameterData(new BitArray(compact_?28:40));
if (compact_) {
for (int i = 0; i < 7; i++) {
if (resab->get(2+i)) shiftedParameterData->set(i);
if (resbc->get(2+i)) shiftedParameterData->set(i+7);
if (rescd->get(2+i)) shiftedParameterData->set(i+14);
if (resda->get(2+i)) shiftedParameterData->set(i+21);
}
for (int i = 0; i < 28; i++) {
if (shiftedParameterData->get((i+shift_*7)%28)) parameterData->set(i);
}
} else {
for (int i = 0; i < 11; i++) {
if (i < 5) {
if (resab->get(2+i)) shiftedParameterData->set(i);
if (resbc->get(2+i)) shiftedParameterData->set(i+10);
if (rescd->get(2+i)) shiftedParameterData->set(i+20);
if (resda->get(2+i)) shiftedParameterData->set(i+30);
}
if (i > 5) {
if (resab->get(2+i)) shiftedParameterData->set(i-1);
if (resbc->get(2+i)) shiftedParameterData->set(i+9);
if (rescd->get(2+i)) shiftedParameterData->set(i+19);
if (resda->get(2+i)) shiftedParameterData->set(i+29);
}
}
for (int i = 0; i < 40; i++) {
if (shiftedParameterData->get((i+shift_*10)%40)) parameterData->set(i);
}
}
correctParameterData(parameterData, compact_);
getParameters(parameterData);
}
ArrayRef< Ref<ResultPoint> >
Detector::getMatrixCornerPoints(std::vector<Ref<Point> > bullEyeCornerPoints) {
float ratio = (2 * nbLayers_ + (nbLayers_ > 4 ? 1 : 0) + (nbLayers_ - 4) / 8) / (2.0f * nbCenterLayers_);
int dx = bullEyeCornerPoints[0]->getX() - bullEyeCornerPoints[2]->getX();
dx += dx > 0 ? 1 : -1;
int dy = bullEyeCornerPoints[0]->getY() - bullEyeCornerPoints[2]->getY();
dy += dy > 0 ? 1 : -1;
int targetcx = MathUtils::round(bullEyeCornerPoints[2]->getX() - ratio * dx);
int targetcy = MathUtils::round(bullEyeCornerPoints[2]->getY() - ratio * dy);
int targetax = MathUtils::round(bullEyeCornerPoints[0]->getX() + ratio * dx);
int targetay = MathUtils::round(bullEyeCornerPoints[0]->getY() + ratio * dy);
dx = bullEyeCornerPoints[1]->getX() - bullEyeCornerPoints[3]->getX();
dx += dx > 0 ? 1 : -1;
dy = bullEyeCornerPoints[1]->getY() - bullEyeCornerPoints[3]->getY();
dy += dy > 0 ? 1 : -1;
int targetdx = MathUtils::round(bullEyeCornerPoints[3]->getX() - ratio * dx);
int targetdy = MathUtils::round(bullEyeCornerPoints[3]->getY() - ratio * dy);
int targetbx = MathUtils::round(bullEyeCornerPoints[1]->getX() + ratio * dx);
int targetby = MathUtils::round(bullEyeCornerPoints[1]->getY() + ratio * dy);
if (!isValid(targetax, targetay) ||
!isValid(targetbx, targetby) ||
!isValid(targetcx, targetcy) ||
!isValid(targetdx, targetdy)) {
throw ReaderException("matrix extends over image bounds");
}
Array< Ref<ResultPoint> >* array = new Array< Ref<ResultPoint> >();
vector< Ref<ResultPoint> >& returnValue (array->values());
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(float(targetax), float(targetay))));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(float(targetbx), float(targetby))));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(float(targetcx), float(targetcy))));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(float(targetdx), float(targetdy))));
return ArrayRef< Ref<ResultPoint> >(array);
}
void Detector::correctParameterData(Ref<zxing::BitArray> parameterData, bool compact) {
int numCodewords;
int numDataCodewords;
if (compact) {
numCodewords = 7;
numDataCodewords = 2;
} else {
numCodewords = 10;
numDataCodewords = 4;
}
int numECCodewords = numCodewords - numDataCodewords;
ArrayRef<int> parameterWords(new Array<int>(numCodewords));
int codewordSize = 4;
for (int i = 0; i < numCodewords; i++) {
int flag = 1;
for (int j = 1; j <= codewordSize; j++) {
if (parameterData->get(codewordSize*i + codewordSize - j)) {
parameterWords[i] += flag;
}
flag <<= 1;
}
}
try {
// std::printf("parameter data reed solomon\n");
ReedSolomonDecoder rsDecoder(GenericGF::AZTEC_PARAM);
rsDecoder.decode(parameterWords, numECCodewords);
} catch (ReedSolomonException const& ignored) {
(void)ignored;
// std::printf("reed solomon decoding failed\n");
throw ReaderException("failed to decode parameter data");
}
parameterData->clear();
for (int i = 0; i < numDataCodewords; i++) {
int flag = 1;
for (int j = 1; j <= codewordSize; j++) {
if ((parameterWords[i] & flag) == flag) {
parameterData->set(i*codewordSize+codewordSize-j);
}
flag <<= 1;
}
}
}
std::vector<Ref<Point> > Detector::getBullEyeCornerPoints(Ref<zxing::aztec::Point> pCenter) {
Ref<Point> pina = pCenter;
Ref<Point> pinb = pCenter;
Ref<Point> pinc = pCenter;
Ref<Point> pind = pCenter;
bool color = true;
for (nbCenterLayers_ = 1; nbCenterLayers_ < 9; nbCenterLayers_++) {
Ref<Point> pouta = getFirstDifferent(pina, color, 1, -1);
Ref<Point> poutb = getFirstDifferent(pinb, color, 1, 1);
Ref<Point> poutc = getFirstDifferent(pinc, color, -1, 1);
Ref<Point> poutd = getFirstDifferent(pind, color, -1, -1);
//d a
//
//c b
if (nbCenterLayers_ > 2) {
float q = distance(poutd, pouta) * nbCenterLayers_ / (distance(pind, pina) * (nbCenterLayers_ + 2));
if (q < 0.75 || q > 1.25 || !isWhiteOrBlackRectangle(pouta, poutb, poutc, poutd)) {
break;
}
}
pina = pouta;
pinb = poutb;
pinc = poutc;
pind = poutd;
color = !color;
}
if (nbCenterLayers_ != 5 && nbCenterLayers_ != 7) {
throw ReaderException("encountered wrong bullseye ring count");
}
compact_ = nbCenterLayers_ == 5;
float ratio = 0.75f*2 / (2*nbCenterLayers_-3);
int dx = pina->getX() - pind->getX();
int dy = pina->getY() - pinc->getY();
int targetcx = MathUtils::round(pinc->getX() - ratio * dx);
int targetcy = MathUtils::round(pinc->getY() - ratio * dy);
int targetax = MathUtils::round(pina->getX() + ratio * dx);
int targetay = MathUtils::round(pina->getY() + ratio * dy);
dx = pinb->getX() - pind->getX();
dy = pinb->getY() - pind->getY();
int targetdx = MathUtils::round(pind->getX() - ratio * dx);
int targetdy = MathUtils::round(pind->getY() - ratio * dy);
int targetbx = MathUtils::round(pinb->getX() + ratio * dx);
int targetby = MathUtils::round(pinb->getY() + ratio * dy);
if (!isValid(targetax, targetay) ||
!isValid(targetbx, targetby) ||
!isValid(targetcx, targetcy) ||
!isValid(targetdx, targetdy)) {
throw ReaderException("bullseye extends over image bounds");
}
std::vector<Ref<Point> > returnValue;
returnValue.push_back(Ref<Point>(new Point(targetax, targetay)));
returnValue.push_back(Ref<Point>(new Point(targetbx, targetby)));
returnValue.push_back(Ref<Point>(new Point(targetcx, targetcy)));
returnValue.push_back(Ref<Point>(new Point(targetdx, targetdy)));
return returnValue;
}
Ref<Point> Detector::getMatrixCenter() {
Ref<ResultPoint> pointA, pointB, pointC, pointD;
try {
std::vector<Ref<ResultPoint> > cornerPoints = WhiteRectangleDetector(image_).detect();
pointA = cornerPoints[0];
pointB = cornerPoints[1];
pointC = cornerPoints[2];
pointD = cornerPoints[3];
} catch (NotFoundException const& e) {
(void)e;
int cx = image_->getWidth() / 2;
int cy = image_->getHeight() / 2;
pointA = getFirstDifferent(Ref<Point>(new Point(cx+7, cy-7)), false, 1, -1)->toResultPoint();
pointB = getFirstDifferent(Ref<Point>(new Point(cx+7, cy+7)), false, 1, 1)->toResultPoint();
pointC = getFirstDifferent(Ref<Point>(new Point(cx-7, cy+7)), false, -1, -1)->toResultPoint();
pointD = getFirstDifferent(Ref<Point>(new Point(cx-7, cy-7)), false, -1, -1)->toResultPoint();
}
int cx = MathUtils::round((pointA->getX() + pointD->getX() + pointB->getX() + pointC->getX()) / 4.0f);
int cy = MathUtils::round((pointA->getY() + pointD->getY() + pointB->getY() + pointC->getY()) / 4.0f);
try {
std::vector<Ref<ResultPoint> > cornerPoints = WhiteRectangleDetector(image_, 15, cx, cy).detect();
pointA = cornerPoints[0];
pointB = cornerPoints[1];
pointC = cornerPoints[2];
pointD = cornerPoints[3];
} catch (NotFoundException const& e) {
(void)e;
pointA = getFirstDifferent(Ref<Point>(new Point(cx+7, cy-7)), false, 1, -1)->toResultPoint();
pointB = getFirstDifferent(Ref<Point>(new Point(cx+7, cy+7)), false, 1, 1)->toResultPoint();
pointC = getFirstDifferent(Ref<Point>(new Point(cx-7, cy+7)), false, -1, 1)->toResultPoint();
pointD = getFirstDifferent(Ref<Point>(new Point(cx-7, cy-7)), false, -1, -1)->toResultPoint();
}
cx = MathUtils::round((pointA->getX() + pointD->getX() + pointB->getX() + pointC->getX()) / 4.0f);
cy = MathUtils::round((pointA->getY() + pointD->getY() + pointB->getY() + pointC->getY()) / 4.0f);
return Ref<Point>(new Point(cx, cy));
}
Ref<BitMatrix> Detector::sampleGrid(Ref<zxing::BitMatrix> image,
Ref<zxing::ResultPoint> topLeft,
Ref<zxing::ResultPoint> bottomLeft,
Ref<zxing::ResultPoint> bottomRight,
Ref<zxing::ResultPoint> topRight) {
int dimension;
if (compact_) {
dimension = 4 * nbLayers_+11;
} else {
if (nbLayers_ <= 4) {
dimension = 4 * nbLayers_ + 15;
} else {
dimension = 4 * nbLayers_ + 2 * ((nbLayers_-4)/8 + 1) + 15;
}
}
GridSampler sampler = GridSampler::getInstance();
return sampler.sampleGrid(image,
dimension,
0.5f,
0.5f,
dimension - 0.5f,
0.5f,
dimension - 0.5f,
dimension - 0.5f,
0.5f,
dimension - 0.5f,
topLeft->getX(),
topLeft->getY(),
topRight->getX(),
topRight->getY(),
bottomRight->getX(),
bottomRight->getY(),
bottomLeft->getX(),
bottomLeft->getY());
}
void Detector::getParameters(Ref<zxing::BitArray> parameterData) {
nbLayers_ = 0;
nbDataBlocks_ = 0;
int nbBitsForNbLayers;
int nbBitsForNbDatablocks;
if (compact_) {
nbBitsForNbLayers = 2;
nbBitsForNbDatablocks = 6;
} else {
nbBitsForNbLayers = 5;
nbBitsForNbDatablocks = 11;
}
for (int i = 0; i < nbBitsForNbLayers; i++) {
nbLayers_ <<= 1;
if (parameterData->get(i)) {
nbLayers_++;
}
}
for (int i = nbBitsForNbLayers; i < nbBitsForNbLayers + nbBitsForNbDatablocks; i++) {
nbDataBlocks_ <<= 1;
if (parameterData->get(i)) {
nbDataBlocks_++;
}
}
nbLayers_++;
nbDataBlocks_++;
}
Ref<BitArray> Detector::sampleLine(Ref<zxing::aztec::Point> p1, Ref<zxing::aztec::Point> p2, int size) {
Ref<BitArray> res(new BitArray(size));
float d = distance(p1, p2);
float moduleSize = d / (size-1);
float dx = moduleSize * float(p2->getX() - p1->getX())/d;
float dy = moduleSize * float(p2->getY() - p1->getY())/d;
float px = float(p1->getX());
float py = float(p1->getY());
for (int i = 0; i < size; i++) {
if (image_->get(MathUtils::round(px), MathUtils::round(py))) res->set(i);
px+=dx;
py+=dy;
}
return res;
}
bool Detector::isWhiteOrBlackRectangle(Ref<zxing::aztec::Point> p1,
Ref<zxing::aztec::Point> p2,
Ref<zxing::aztec::Point> p3,
Ref<zxing::aztec::Point> p4) {
int corr = 3;
p1 = new Point(p1->getX() - corr, p1->getY() + corr);
p2 = new Point(p2->getX() - corr, p2->getY() - corr);
p3 = new Point(p3->getX() + corr, p3->getY() - corr);
p4 = new Point(p4->getX() + corr, p4->getY() + corr);
int cInit = getColor(p4, p1);
if (cInit == 0) {
return false;
}
int c = getColor(p1, p2);
if (c != cInit) {
return false;
}
c = getColor(p2, p3);
if (c != cInit) {
return false;
}
c = getColor(p3, p4);
if (c != cInit) {
return false;
}
return true;
}
int Detector::getColor(Ref<zxing::aztec::Point> p1, Ref<zxing::aztec::Point> p2) {
float d = distance(p1, p2);
float dx = (p2->getX() - p1->getX()) / d;
float dy = (p2->getY() - p1->getY()) / d;
int error = 0;
float px = float(p1->getX());
float py = float(p1->getY());
bool colorModel = image_->get(p1->getX(), p1->getY());
for (int i = 0; i < d; i++) {
px += dx;
py += dy;
if (image_->get(MathUtils::round(px), MathUtils::round(py)) != colorModel) {
error ++;
}
}
float errRatio = (float)error/d;
if (errRatio > 0.1f && errRatio < 0.9f) {
return 0;
}
return (errRatio <= 0.1) == colorModel ? 1 : -1;
}
Ref<Point> Detector::getFirstDifferent(Ref<zxing::aztec::Point> init, bool color, int dx, int dy) {
int x = init->getX() + dx;
int y = init->getY() + dy;
while (isValid(x, y) && image_->get(x, y) == color) {
x += dx;
y += dy;
}
x -= dx;
y -= dy;
while (isValid(x, y) && image_->get(x, y) == color) {
x += dx;
}
x -= dx;
while (isValid(x, y) && image_->get(x, y) == color) {
y += dy;
}
y -= dy;
return Ref<Point>(new Point(x, y));
}
bool Detector::isValid(int x, int y) {
return x >= 0 && x < (int)image_->getWidth() && y > 0 && y < (int)image_->getHeight();
}
float Detector::distance(Ref<zxing::aztec::Point> a, Ref<zxing::aztec::Point> b) {
return sqrtf((float)((a->getX() - b->getX()) * (a->getX() - b->getX()) + (a->getY() - b->getY()) * (a->getY() - b->getY())));
}

@ -0,0 +1,92 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Detector.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 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_AZTEC_DETECTOR_DETECTOR_H
#define ZXING_AZTEC_DETECTOR_DETECTOR_H
#include <vector>
#include <zxing/common/BitArray.h>
#include <zxing/ResultPoint.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/DecodeHints.h>
#include <zxing/aztec/AztecDetectorResult.h>
namespace zxing {
namespace aztec {
class Point : public Counted {
private:
const int x;
const int y;
public:
Ref<ResultPoint> toResultPoint() {
return Ref<ResultPoint>(new ResultPoint(float(x), float(y)));
}
Point(int ax, int ay) : x(ax), y(ay) {}
int getX() const { return x; }
int getY() const { return y; }
};
class Detector : public Counted {
private:
Ref<BitMatrix> image_;
bool compact_;
int nbLayers_;
int nbDataBlocks_;
int nbCenterLayers_;
int shift_;
void extractParameters(std::vector<Ref<Point> > bullEyeCornerPoints);
ArrayRef< Ref<ResultPoint> > getMatrixCornerPoints(std::vector<Ref<Point> > bullEyeCornerPoints);
static void correctParameterData(Ref<BitArray> parameterData, bool compact);
std::vector<Ref<Point> > getBullEyeCornerPoints(Ref<Point> pCenter);
Ref<Point> getMatrixCenter();
Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image,
Ref<ResultPoint> topLeft,
Ref<ResultPoint> bottomLeft,
Ref<ResultPoint> bottomRight,
Ref<ResultPoint> topRight);
void getParameters(Ref<BitArray> parameterData);
Ref<BitArray> sampleLine(Ref<Point> p1, Ref<Point> p2, int size);
bool isWhiteOrBlackRectangle(Ref<Point> p1,
Ref<Point> p2,
Ref<Point> p3,
Ref<Point> p4);
int getColor(Ref<Point> p1, Ref<Point> p2);
Ref<Point> getFirstDifferent(Ref<Point> init, bool color, int dx, int dy);
bool isValid(int x, int y);
static float distance(Ref<Point> a, Ref<Point> b);
public:
Detector(Ref<BitMatrix> image);
Ref<AztecDetectorResult> detect();
};
}
}
#endif // ZXING_AZTEC_DETECTOR_DETECTOR_H

@ -0,0 +1,173 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_ARRAY_H
#define ZXING_ARRAY_H
/*
* Array.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.
*/
#include <vector>
#include <zxing/common/Counted.h>
namespace zxing {
template<typename T> class Array : public Counted {
protected:
public:
std::vector<T> values_;
Array() {}
Array(int n) :
Counted(), values_(n, T()) {
}
Array(T const* ts, int n) :
Counted(), values_(ts, ts+n) {
}
Array(T const* ts, T const* te) :
Counted(), values_(ts, te) {
}
Array(T v, int n) :
Counted(), values_(n, v) {
}
Array(std::vector<T> &v) :
Counted(), values_(v) {
}
Array(Array<T> &other) :
Counted(), values_(other.values_) {
}
Array(Array<T> *other) :
Counted(), values_(other->values_) {
}
virtual ~Array() {
}
Array<T>& operator=(const Array<T> &other) {
values_ = other.values_;
return *this;
}
Array<T>& operator=(const std::vector<T> &array) {
values_ = array;
return *this;
}
T const& operator[](int i) const {
return values_[i];
}
T& operator[](int i) {
return values_[i];
}
int size() const {
return int(values_.size());
}
bool empty() const {
return values_.size() == 0;
}
std::vector<T> const& values() const {
return values_;
}
std::vector<T>& values() {
return values_;
}
void push_back(T value) {
values_.push_back(value);
}
};
template<typename T> class ArrayRef : public Counted {
private:
public:
Array<T> *array_;
ArrayRef() :
array_(0) {
}
explicit ArrayRef(int n) :
array_(0) {
reset(new Array<T> (n));
}
ArrayRef(T *ts, int n) :
array_(0) {
reset(new Array<T> (ts, n));
}
ArrayRef(Array<T> *a) :
array_(0) {
reset(a);
}
ArrayRef(const ArrayRef &other) :
Counted(), array_(0) {
reset(other.array_);
}
template<class Y>
ArrayRef(const ArrayRef<Y> &other) :
array_(0) {
reset(static_cast<const Array<T> *>(other.array_));
}
~ArrayRef() {
if (array_) {
array_->release();
}
array_ = 0;
}
T const& operator[](int i) const {
return (*array_)[i];
}
T& operator[](int i) {
return (*array_)[i];
}
void reset(Array<T> *a) {
if (a) {
a->retain();
}
if (array_) {
array_->release();
}
array_ = a;
}
void reset(const ArrayRef<T> &other) {
reset(other.array_);
}
ArrayRef<T>& operator=(const ArrayRef<T> &other) {
reset(other);
return *this;
}
ArrayRef<T>& operator=(Array<T> *a) {
reset(a);
return *this;
}
Array<T>& operator*() const {
return *array_;
}
Array<T>* operator->() const {
return array_;
}
operator bool () const {
return array_ != 0;
}
bool operator ! () const {
return array_ == 0;
}
};
} // namespace zxing
#endif // ZXING_ARRAY_H

@ -0,0 +1,299 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* 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/BitArray.h>
#include <zxing/common/Array.h>
#include <cstring>
#include <sstream>
using std::vector;
using zxing::BitArray;
// VC++
using zxing::Ref;
namespace zxing {
int BitArray::makeArraySize(int size) {
return (size + 31) / 32;
}
BitArray::BitArray(): size(0), bits(1) {}
BitArray::BitArray(int size_)
: size(size_), bits(makeArraySize(size)) {}
//this could be wrong. TODO: check size value
BitArray::BitArray(std::vector<int> other)
: size(int(other.size())), bits(int(other.size()))
{
for(size_t i=0; i<other.size(); i++)
{
if(other[i])
set(int(i));
}
}
BitArray::~BitArray() {
}
int BitArray::getSize() const {
return size;
}
int BitArray::getSizeInBytes() const
{
return (size + 7)/8;
}
void BitArray::setBulk(int i, int newBits) {
bits[i / 32] = newBits;
}
void BitArray::clear() {
int max = bits->size();
for (int i = 0; i < max; i++) {
bits[i] = 0;
}
}
bool BitArray::isRange(int start, int end, bool value) {
if (end < start) {
throw IllegalArgumentException();
}
if (end == start) {
return true; // empty range matches
}
end--; // will be easier to treat this as the last actually set bit -- inclusive
int firstInt = start / 32;
int lastInt = end / 32;
for (int i = firstInt; i <= lastInt; i++) {
int firstBit = i > firstInt ? 0 : start & 0x1F;
int lastBit = i < lastInt ? 31 : end & 0x1F;
int mask = (2 << lastBit) - (1 << firstBit);
// int mask;
// if (firstBit == 0 && lastBit == 31) {
// mask = -1;
// } else {
// mask = 0;
// for (int j = firstBit; j <= lastBit; j++) {
// mask |= 1 << j;
// }
// }
// Return false if we're looking for 1s and the masked bits[i] isn't all 1s (that is,
// equals the mask, or we're looking for 0s and the masked portion is not all 0s
if ((bits[i] & mask) != (value ? mask : 0)) {
return false;
}
}
return true;
}
vector<int>& BitArray::getBitArray() {
return bits->values();
}
void BitArray::reverse()
{
ArrayRef<int> newBits(bits->size());
// reverse all int's first
int len = ((this->size-1) / 32);
int oldBitsLen = len + 1;
for (int i = 0; i < oldBitsLen; i++) {
long x = long(bits[i]);
x = ((x >> 1) & 0x55555555L) | ((x & 0x55555555L) << 1);
x = ((x >> 2) & 0x33333333L) | ((x & 0x33333333L) << 2);
x = ((x >> 4) & 0x0f0f0f0fL) | ((x & 0x0f0f0f0fL) << 4);
x = ((x >> 8) & 0x00ff00ffL) | ((x & 0x00ff00ffL) << 8);
x = ((x >> 16) & 0x0000ffffL) | ((x & 0x0000ffffL) << 16);
newBits[len - i] = int(x);
}
// now correct the int's if the bit size isn't a multiple of 32
if (size != oldBitsLen * 32) {
int leftOffset = oldBitsLen * 32 - size;
int mask = 1;
for (int i = 0; i < 31 - leftOffset; i++) {
mask = (mask << 1) | 1;
}
int currentInt = (newBits[0] >> leftOffset) & mask;
for (int i = 1; i < oldBitsLen; i++) {
int nextInt = newBits[i];
currentInt |= nextInt << (32 - leftOffset);
newBits[i - 1] = currentInt;
currentInt = (nextInt >> leftOffset) & mask;
}
newBits[oldBitsLen - 1] = currentInt;
}
bits = newBits;
}
BitArray::Reverse::Reverse(Ref<BitArray> array_) : array(array_) {
array->reverse();
}
BitArray::Reverse::~Reverse() {
array->reverse();
}
namespace {
// N.B.: This only works for 32 bit ints ...
int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
#if defined(__clang__) || defined(__GNUC__)
return __builtin_ctz(unsigned(i));
#else
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - (((unsigned int)(i << 1)) >> 31);
#endif
}
}
int BitArray::getNextSet(int from) {
if (from >= size) {
return size;
}
int bitsOffset = from >> logBits;
int currentBits = bits[bitsOffset];
// mask off lesser bits first
currentBits &= ~((1 << (from & bitsMask)) - 1);
while (currentBits == 0) {
if (++bitsOffset == bits->size()) {
return size;
}
currentBits = bits[bitsOffset];
}
int result = (bitsOffset << logBits) + numberOfTrailingZeros(currentBits);
return result > size ? size : result;
}
int BitArray::getNextUnset(int from) {
if (from >= size) {
return size;
}
int bitsOffset = from >> logBits;
int currentBits = ~bits[bitsOffset];
// mask off lesser bits first
currentBits &= ~((1 << (from & bitsMask)) - 1);
while (currentBits == 0) {
if (++bitsOffset == bits->size()) {
return size;
}
currentBits = ~bits[bitsOffset];
}
int result = (bitsOffset << logBits) + numberOfTrailingZeros(currentBits);
return result > size ? size : result;
}
void BitArray::appendBit(bool bit)
{
ensureCapacity(size + 1);
if (bit) {
bits[size / 32] |= 1 << (size & 0x1F);
}
size++;
}
void BitArray::appendBits(int value, int numBits)
{
if (numBits < 0 || numBits > 32) {
throw IllegalArgumentException("Num bits must be between 0 and 32");
}
ensureCapacity(size + numBits);
for (int numBitsLeft = numBits; numBitsLeft > 0; numBitsLeft--) {
appendBit(((value >> (numBitsLeft - 1)) & 0x01) == 1);
}
}
void BitArray::appendBitArray(const BitArray& other)
{
int otherSize = other.size;
ensureCapacity(size + otherSize);
for (int i = 0; i < otherSize; i++) {
appendBit(other.get(i));
}
}
void BitArray::ensureCapacity(int size)
{
if (size > bits->size() * 32)
{
ArrayRef<int> newBits = makeArray(size);
//memcpy(bits, newBits->, bits->size());
for (int i=0; i<bits->size(); ++i) {
newBits[i] = bits[i];
}
bits = newBits;
}
}
void BitArray::xor_(const BitArray& other)
{
if (bits->size() != other.bits->size()) {
throw IllegalArgumentException("Sizes don't match");
}
for (int i = 0; i < bits->size(); i++) {
// The last byte could be incomplete (i.e. not have 8 bits in
// it) but there is no problem since 0 XOR 0 == 0.
bits[i] ^= other.bits[i];
}
}
void BitArray::toBytes(int bitOffset, std::vector<zxing::byte>& array, int offset, int numBytes) const
{
if(int(array.size()) < (numBytes + offset))
array.resize(size_t(numBytes + offset));
for (int i = 0; i < numBytes; i++) {
int theByte = 0;
for (int j = 0; j < 8; j++) {
if (get(bitOffset)) {
theByte |= 1 << (7 - j);
}
bitOffset++;
}
array[size_t(offset + i)] = zxing::byte(theByte);
}
}
std::string BitArray::toString() const
{
std::stringstream result;// = new StringBuilder(2 * width * height + 2);
for (int i = 0; i < size; i++) {
if ((i & 0x07) == 0) {
result << ' ';
}
result << (get(i) ? 'X' : '.');
}
return result.str();
}
}

@ -0,0 +1,103 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_BIT_ARRAY_H
#define ZXING_BIT_ARRAY_H
/*
* 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/ZXing.h>
#include <zxing/common/Counted.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/common/Array.h>
#include <vector>
#include <limits>
#include <iostream>
namespace zxing {
class BitArray : public Counted {
public:
static const int bitsPerWord = std::numeric_limits<unsigned int>::digits;
private:
int size;
ArrayRef<int> bits;
static const int logBits = ZX_LOG_DIGITS(bitsPerWord);
static const int bitsMask = (1 << logBits) - 1;
public:
BitArray();
BitArray(int size);
BitArray(std::vector<int> other);
~BitArray();
int getSize() const;
int getSizeInBytes() const;
bool get(int i) const {
return (bits[i / 32] & (1 << (i & 0x1F))) != 0;
}
void set(int i) {
bits[i / 32] |= 1 << (i & 0x1F);
}
void flip(int i) {
bits[i / 32] ^= 1 << (i & 0x1F);
}
int getNextSet(int from);
int getNextUnset(int from);
void setBulk(int i, int newBits);
void setRange(int start, int end);
void clear();
bool isRange(int start, int end, bool value);
std::vector<int>& getBitArray();
void appendBit(bool bit);
void appendBits(int value, int numBits);
void appendBitArray(const BitArray& other);
void ensureCapacity(int size);
void xor_(const BitArray& other);
void toBytes(int bitOffset, std::vector<zxing::byte>& array, int offset, int numBytes) const;
std::string toString() const;
static ArrayRef<int> makeArray(int size) {
return ArrayRef<int>((size + 31) / 32);
}
void reverse();
class Reverse {
private:
Ref<BitArray> array;
public:
Reverse(Ref<BitArray> array);
~Reverse();
};
private:
static int makeArraySize(int size);
};
std::ostream& operator << (std::ostream&, BitArray const&);
}
#endif // ZXING_BIT_ARRAY_H

@ -0,0 +1,31 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* 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/BitArray.h>
using zxing::BitArray;
using std::ostream;
ostream& zxing::operator << (ostream& os, BitArray const& ba) {
for (int i = 0, size = ba.getSize(); i < size; i++) {
if ((i & 0x07) == 0) {
os << ' ';
}
os << (ba.get(i) ? 'X' : '.');
}
return os;
}

@ -0,0 +1,227 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* 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/BitMatrix.h>
#include <zxing/common/IllegalArgumentException.h>
#include <iostream>
#include <sstream>
#include <string>
using std::ostream;
using std::ostringstream;
using zxing::BitMatrix;
using zxing::BitArray;
using zxing::ArrayRef;
using zxing::Ref;
void BitMatrix::init(int width, int height) {
if (width < 1 || height < 1) {
throw IllegalArgumentException("Both dimensions must be greater than 0");
}
this->width = width;
this->height = height;
this->rowSize = (width + 31) >> 5;
bits = ArrayRef<int>(rowSize * height);
}
BitMatrix::BitMatrix(int dimension) {
init(dimension, dimension);
}
BitMatrix::BitMatrix(int width, int height) {
init(width, height);
}
BitMatrix::~BitMatrix() {}
void BitMatrix::flip(int x, int y) {
int offset = y * rowSize + (x >> 5);
bits[offset] ^= 1 << (x & 0x1f);
}
void BitMatrix::rotate180()
{
int width = getWidth();
int height = getHeight();
Ref<BitArray> topRow( new BitArray(width) );
Ref<BitArray> bottomRow( new BitArray(width) );
for (int i = 0; i < (height+1) / 2; i++) {
getRow(i, topRow);
bottomRow = getRow(height - 1 - i, bottomRow);
topRow->reverse();
bottomRow->reverse();
setRow(i, bottomRow);
setRow(height - 1 - i, topRow);
}
}
void BitMatrix::setRegion(int left, int top, int width, int height) {
if (top < 0 || left < 0) {
throw IllegalArgumentException("Left and top must be nonnegative");
}
if (height < 1 || width < 1) {
throw IllegalArgumentException("Height and width must be at least 1");
}
int right = left + width;
int bottom = top + height;
if (bottom > this->height || right > this->width) {
throw IllegalArgumentException("The region must fit inside the matrix");
}
for (int y = top; y < bottom; y++) {
int offset = y * rowSize;
for (int x = left; x < right; x++) {
bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
}
}
}
Ref<BitArray> BitMatrix::getRow(int y, Ref<BitArray> row) {
if (row.empty() || row->getSize() < width) {
row = new BitArray(width);
}
int offset = y * rowSize;
for (int x = 0; x < rowSize; x++) {
row->setBulk(x << 5, bits[offset + x]);
}
return row;
}
void BitMatrix::setRow(int y, Ref<zxing::BitArray> row)
{
if (y < 0 || y >= bits->size() ||
row->getSize() != width)
{
throw IllegalArgumentException("setRow arguments invalid");
}
//change with memcopy
for(int i=0; i<width; i++)
bits[y * rowSize + i] = row->get(i);
}
int BitMatrix::getWidth() const {
return width;
}
int BitMatrix::getHeight() const {
return height;
}
ArrayRef<int> BitMatrix::getTopLeftOnBit() const {
int bitsOffset = 0;
while (bitsOffset < bits->size() && bits[bitsOffset] == 0) {
bitsOffset++;
}
if (bitsOffset == bits->size()) {
return ArrayRef<int>();
}
int y = bitsOffset / rowSize;
int x = (bitsOffset % rowSize) << 5;
int theBits = bits[bitsOffset];
int bit = 0;
while ((theBits << (31-bit)) == 0) {
bit++;
}
x += bit;
ArrayRef<int> res (2);
res[0]=x;
res[1]=y;
return res;
}
ArrayRef<int> BitMatrix::getBottomRightOnBit() const {
int bitsOffset = bits->size() - 1;
while (bitsOffset >= 0 && bits[bitsOffset] == 0) {
bitsOffset--;
}
if (bitsOffset < 0) {
return ArrayRef<int>();
}
int y = bitsOffset / rowSize;
int x = (bitsOffset % rowSize) << 5;
int theBits = bits[bitsOffset];
int bit = 31;
while ((theBits >> bit) == 0) {
bit--;
}
x += bit;
ArrayRef<int> res (2);
res[0]=x;
res[1]=y;
return res;
}
ArrayRef<int> BitMatrix::getEnclosingRectangle() const
{
int left = width;
int top = height;
int right = -1;
int bottom = -1;
for (int y = 0; y < height; y++) {
for (int x32 = 0; x32 < rowSize; x32++) {
int theBits = bits[y * rowSize + x32];
if (theBits != 0) {
if (y < top) {
top = y;
}
if (y > bottom) {
bottom = y;
}
if (x32 * 32 < left) {
int bit = 0;
while ((theBits << (31 - bit)) == 0) {
bit++;
}
if ((x32 * 32 + bit) < left) {
left = x32 * 32 + bit;
}
}
if (x32 * 32 + 31 > right) {
int bit = 31;
while ((unsigned(theBits) >> unsigned(bit)) == 0) {
bit--;
}
if ((x32 * 32 + bit) > right) {
right = x32 * 32 + bit;
}
}
}
}
}
int width = right - left;
int height = bottom - top;
if (width < 0 || height < 0) {
return ArrayRef<int>();
}
ArrayRef<int> res(4);
res[0] = left;
res[1] = top;
res[2] = width;
res[3] = height;
return res;
}

@ -0,0 +1,84 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef ZXING_BIT_MATRIX_H
#define ZXING_BIT_MATRIX_H
/*
* BitMatrix.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.
*/
#include <zxing/common/Counted.h>
#include <zxing/common/BitArray.h>
#include <zxing/common/Array.h>
#include <limits>
namespace zxing {
class BitMatrix : public Counted {
public:
static const int bitsPerWord = std::numeric_limits<unsigned int>::digits;
private:
int width;
int height;
int rowSize;
ArrayRef<int> bits;
public:
BitMatrix(int dimension);
BitMatrix(int width, int height);
~BitMatrix();
bool get(int x, int y) const {
int offset = y * rowSize + (x >> 5);
return ((((unsigned)bits[offset]) >> (x & 0x1f)) & 1) != 0;
}
void set(int x, int y) {
int offset = y * rowSize + (x >> 5);
bits[offset] |= 1 << (x & 0x1f);
}
void flip(int x, int y);
void rotate180();
void clear();
void setRegion(int left, int top, int width, int height);
Ref<BitArray> getRow(int y, Ref<BitArray> row);
void setRow(int y, Ref<BitArray> row);
int getWidth() const;
int getHeight() const;
ArrayRef<int> getTopLeftOnBit() const;
ArrayRef<int> getBottomRightOnBit() const;
ArrayRef<int> getEnclosingRectangle() const;
friend std::ostream& operator<<(std::ostream &out, const BitMatrix &bm);
const char *description();
private:
inline void init(int, int);
BitMatrix(const BitMatrix&);
BitMatrix& operator =(const BitMatrix&);
};
}
#endif // ZXING_BIT_MATRIX_H

@ -0,0 +1,76 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* BitSource.cpp
* zxing
*
* Created by Christian Brunschen on 09/05/2008.
* Copyright 2008 Google UK. 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/BitSource.h>
#include <sstream>
#include <zxing/common/IllegalArgumentException.h>
namespace zxing {
int BitSource::readBits(int numBits) {
if (numBits < 0 || numBits > 32 || numBits > available()) {
std::ostringstream oss;
oss << numBits;
throw IllegalArgumentException(oss.str().c_str());
}
int result = 0;
// First, read remainder from current byte
if (bitOffset_ > 0) {
int bitsLeft = 8 - bitOffset_;
int toRead = numBits < bitsLeft ? numBits : bitsLeft;
int bitsToNotRead = bitsLeft - toRead;
int mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
result = (bytes_[byteOffset_] & mask) >> bitsToNotRead;
numBits -= toRead;
bitOffset_ += toRead;
if (bitOffset_ == 8) {
bitOffset_ = 0;
byteOffset_++;
}
}
// Next read whole bytes
if (numBits > 0) {
while (numBits >= 8) {
result = (result << 8) | (bytes_[byteOffset_] & 0xFF);
byteOffset_++;
numBits -= 8;
}
// Finally read a partial byte
if (numBits > 0) {
int bitsToNotRead = 8 - numBits;
int mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
result = (result << numBits) | ((bytes_[byteOffset_] & mask) >> bitsToNotRead);
bitOffset_ += numBits;
}
}
return result;
}
int BitSource::available() {
return 8 * (bytes_->size() - byteOffset_) - bitOffset_;
}
}

@ -0,0 +1,74 @@
#ifndef ZXING_BIT_SOURCE_H
#define ZXING_BIT_SOURCE_H
/*
* BitSource.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.
*/
#include <zxing/common/Array.h>
#include <zxing/common/Types.h>
namespace zxing {
/**
* <p>This provides an easy abstraction to read bits at a time from a sequence of bytes, where the
* number of bits read is not often a multiple of 8.</p>
*
* <p>This class is not thread-safe.</p>
*
* @author srowen@google.com (Sean Owen)
* @author christian.brunschen@gmail.com (Christian Brunschen)
*/
class BitSource : public Counted {
private:
ArrayRef<zxing::byte> bytes_;
int byteOffset_;
int bitOffset_;
public:
/**
* @param bytes bytes from which this will read bits. Bits will be read from the first byte first.
* Bits are read within a byte from most-significant to least-significant bit.
*/
BitSource(ArrayRef<zxing::byte> &bytes) :
bytes_(bytes), byteOffset_(0), bitOffset_(0) {
}
int getBitOffset() {
return bitOffset_;
}
int getByteOffset() {
return byteOffset_;
}
/**
* @param numBits number of bits to read
* @return int representing the bits read. The bits will appear as the least-significant
* bits of the int
* @throws IllegalArgumentException if numBits isn't in [1,32]
*/
int readBits(int numBits);
/**
* @return number of bits that can be read successfully
*/
int available();
};
}
#endif // ZXING_BIT_SOURCE_H

@ -0,0 +1,43 @@
#ifndef ZXING_BYTE_ARRAY_H
#define ZXING_BYTE_ARRAY_H
/*
* Copyright 2008 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.
*
* 2019-05-08 translation from Java into C++
*/
#include <vector>
#include <cstdint>
#include "Types.h"
namespace zxing {
/**
* ByteArray is an extension of std::vector<unsigned char>.
*/
class ByteArray : public std::vector<zxing::byte>
{
public:
ByteArray() {}
ByteArray(std::initializer_list<zxing::byte> list) : std::vector<zxing::byte>(list) {}
explicit ByteArray(int len) : std::vector<zxing::byte>(len, 0) {}
int length() const { return static_cast<int>(size()); }
const zxing::byte* bytePtr() const { return data(); }
zxing::byte* bytePtr() { return data(); }
};
}
#endif

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save