Merge schulzch VS support and other cleanup

git-svn-id: https://zxing.googlecode.com/svn/trunk@2654 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
smparkes@smparkes.net 2013-04-14 23:32:38 +00:00
parent addd611c25
commit 12222ad493
88 changed files with 33396 additions and 1694 deletions

59
NOTICE
View file

@ -17,4 +17,61 @@ NOTICES FOR APACHE COMMONS FILEUPLOAD, IO, LANG
Copyright 2002-2010 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
The Apache Software Foundation (http://www.apache.org/).
--------------------------------------------------------------------------------
NOTICES FOR 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.
--------------------------------------------------------------------------------
NOTICES FOR LodePNG
--------------------------------------------------------------------------------
Copyright (c) 2005-2013 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

File diff suppressed because it is too large Load diff

82
cpp/CMakeLists.txt Normal file
View file

@ -0,0 +1,82 @@
#
# CMake listfile to specify the build process, see:
# http://www.cmake.org/cmake/help/documentation.html
#
project(zxing)
cmake_minimum_required(VERSION 2.8.0)
set(CMAKE_LIBRARY_PATH /opt/local/lib ${CMAKE_LIBRARY_PATH})
# Check for polluted source tree.
if(EXISTS ${CMAKE_SOURCE_DIR}/CMakeCache.txt OR
EXISTS ${CMAKE_SOURCE_DIR}/CMakeFiles)
message(FATAL_ERROR
"Source directory is polluted:"
"\n * remove CMakeCache.txt"
"\n * remove CMakeFiles directory")
endif()
# Suppress in-source builds.
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR
"CMake generation is not allowed within the source directory:"
"\n * mkdir build"
"\n * cd build"
"\n * Unix-like: cmake -G \"Unix Makefiles\" .."
"\n * Windows: cmake -G \"Visual Studio 10\" ..")
endif()
# Adjust CMake's module path.
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
# Suppress MSVC CRT warnings.
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(/Za)
endif()
# Add libzxing library.
file(GLOB_RECURSE LIBZXING_FILES
"./core/src/*.cpp"
"./core/src/*.h"
)
if(WIN32)
file(GLOB LIBZXING_WIN32_FILES
"./core/lib/win32/*.c"
"./core/lib/win32/*.h"
)
set(LIBZXING_FILES ${LIBZXING_FILES} ${LIBZXING_WIN32_FILES})
include_directories(SYSTEM "./core/lib/win32/")
endif()
include_directories("./core/src/")
add_library(libzxing STATIC ${LIBZXING_FILES})
set_target_properties(libzxing PROPERTIES PREFIX "")
find_package(Iconv)
if(ICONV_FOUND)
include_directories(${ICONV_INCLUDE_DIR})
target_link_libraries(libzxing ${ICONV_LIBRARIES})
else()
add_definitions(-DNO_ICONV=1)
endif()
# Add cli executable.
file(GLOB_RECURSE ZXING_FILES
"./cli/src/*.cpp"
"./cli/src/*.h"
)
add_executable(zxing ${ZXING_FILES})
target_link_libraries(zxing libzxing)
# Add testrunner executable.
find_package(CPPUNIT)
if(CPPUNIT_FOUND)
file(GLOB_RECURSE TESTRUNNER_FILES
"./core/tests/src/*.cpp"
"./core/tests/src/*.h"
)
add_executable(testrunner ${TESTRUNNER_FILES})
include_directories(${CPPUNIT_INCLUDE_DIR})
target_link_libraries(testrunner libzxing ${CPPUNIT_LIBRARIES})
else()
message(WARNING "Not building testrunner, because CppUnit is missing")
endif()

View file

@ -1,48 +0,0 @@
This is only tested on Linux. With some trouble, it might work on Windows as well.
The build process uses scons, a build tool written in python. You'll
need to have python installed, but scons installation is optional: a
runtime copy of scons (called scons-local) is included with zxing. To
use the included copy of scons-local, where the instructons says enter
"scons", enter "python scons/scons.py" instead. For example, to build
the library only, you'd use "python scons/scons.py lib" instead of
"scons lib".
To build the library only:
- Run "scons lib" in this folder (cpp)
To build the unit tests:
- Install cppunit (libcppunit-dev on Ubuntu)
- Run "scons tests"
- Run "testrunner" in the build folder
To build the test utility:
- Install Magick++ (libmagick++-dev on Ubuntu)
- Run "scons zxing"
An simple example application is now also included, but no compilation instructions yet.
To clean:
- Run "scons -c all"
To use the test utility:
- Basic usage:
- "mkdir testout"
- "zxing testout *.jpg > report.html"
- With the zxing test data, from the cpp folder:
- "mkdir testout"
- "build/zxing testout ../core/test/data/blackbox/qrcode-*/* > report.html"
To format the code:
- Install astyle
- Run ./format
To profile the code (very useful to optimize the code):
- Install valgrind
- "valgrind --tool=callgrind build/zxing - path/to/test/data/*.jpg > report.html"
- kcachegrind is a very nice tool to analize the output
To run the blackbox tests and check for changes:
- build the test util, e.g., scons zxing
- run the tests: bash blackboxtest.sh 2>&1 | tee bb.results
- diff them with the known results: diff bb.results blackboxtest.results

67
cpp/README.md Normal file
View file

@ -0,0 +1,67 @@
# ZXing C++ Port
This is a manual port of ZXing to C++. It has been tested on Linux, Mac OS X and Windows.
## Building using SCons
SCons is a build tool written in Python. You'll need to have Python
installed, but scons installation is optional: a run time copy of
SCons (called `scons-local`) is included. To use the included copy,
replace `scons` with `python scons/scons.py` in the instructions below.
To build the library only:
1. Install libiconv (optional; included in many operating systems)
2. `cd` to the `cpp` folder
3. Run `scons lib`
To build the command line utility utility:
1. Run `scons zxing`
2. Run `build/zxing` for a command line reference
To build the unit tests (optional):
1. Install CppUnit (`libcppunit-dev` on Ubuntu)
2. Run `scons tests`
3. Run `build/testrunner`
To clean:
1. Run `scons -c all`
# Building using CMake
CMake is a tool, that generates native makefiles and workspaces. It
integrates well with a number of IDEs including Qt Creator and Visual
Studio.
Usage with Qt Creator:
1. Open `CMakeLists.txt` as new project
2. Specify command line arguments (see below) and press _Finish_
Usage with Makefiles, Visual Studio, etc. (see `cmake --help` for a complete list of generators):
1. `cd` to `cpp/build`
3. Unix: run `cmake -G "Unix Makefiles" ..`
3. Windows: run `cmake -G "Visual Studio 10" ..`
You can switch between build modes by specifying:
- `-DCMAKE_BUILD_TYPE=Debug` or
- `-DCMAKE_BUILD_TYPE=Release`
# Development tips
To profile the code (very useful to optimize the code):
1. Install Valgrind
2. Run `valgrind --tool=callgrind build/zxing - path/to/test/data/*.jpg > report.html`
3. Analyze output using KCachegrind
To run the black box tests and check for changes:
1. Build `zxing-img`, e.g., scons zxing
2. Run the tests: `bash blackboxtest.sh 2>&1 | tee bb.results`
3. Diff them with the known results: `diff bb.results blackboxtest.results`

View file

@ -1,72 +1,87 @@
# -*- python -*-
Decider('MD5')
import fnmatch
import os
vars = Variables()
vars.Add(BoolVariable('DEBUG', 'Set to disable optimizations', 1))
vars.Add(BoolVariable('PIC', 'Set to 1 for to always generate PIC code', 0))
env = Environment(variables = vars)
# env.Replace(CXX = "clang++")
debug = env['DEBUG']
compile_options = {}
flags = []
if debug:
#compile_options['CPPDEFINES'] = "-DDEBUG"
flags.append("-O0 -g3 -ggdb -Wall")
else:
flags.append("-Os -g3 -Wall")
if env['PIC']:
flags.append("-fPIC")
flags.append("-Wextra -Werror")
# flags.append("-pedantic") # imagemagick ...
compile_options['CXXFLAGS'] = ' '.join(flags)
compile_options['LINKFLAGS'] = "-ldl -L/usr/lib -L/opt/local/lib -L/usr/local/lib"
def all_files(dir, ext='.cpp', level=6):
files = []
for i in range(1, level):
files += Glob(dir + ('/*' * i) + ext)
return files
magick_include = [
'/usr/include/ImageMagick/',
'/opt/local/include/ImageMagick/',
'/usr/local/include/ImageMagick/'
]
magick_libs = ['Magick++', 'MagickWand', 'MagickCore']
# check for existence of libiconv and add it to magick_libs if possible
matches = []
for root, dirnames, filenames in os.walk('/usr/lib/'):
for filename in fnmatch.filter(filenames, 'libiconv.*'):
matches.append(os.path.join(root, filename))
if matches:
magick_libs.append('iconv')
cppunit_include = ['/opt/local/include/']
cppunit_libs = ['cppunit']
zxing_files = all_files('core/src')
zxing_include = ['core/src']
zxing_libs = env.Library('zxing', source=zxing_files, CPPPATH=zxing_include, **compile_options)
app_files = ['magick/src/MagickBitmapSource.cpp', 'magick/src/main.cpp']
app_executable = env.Program('zxing', app_files, CPPPATH=magick_include + zxing_include, LIBS=zxing_libs + magick_libs, **compile_options)
test_files = all_files('core/tests/src')
test_executable = env.Program('testrunner', test_files, CPPPATH=zxing_include + cppunit_include, LIBS=zxing_libs + cppunit_libs, **compile_options)
Alias('lib', zxing_libs)
Alias('tests', test_executable)
Alias('zxing', app_executable)
# -*- python -*-
#
# SConscript file to specify the build process, see:
# http://scons.org/doc/production/HTML/scons-man.html
#
Decider('MD5')
import platform
import fnmatch
import os
vars = Variables()
vars.Add(BoolVariable('DEBUG', 'Set to disable optimizations', True))
vars.Add(BoolVariable('PIC', 'Set to 1 for to always generate PIC code', False))
env = Environment(variables = vars)
#env.Replace(CXX = 'clang++')
compile_options = {}
if platform.system() is 'Windows':
compile_options['CXXFLAGS'] = '-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc'
else:
# Force ANSI (C++98) to ensure compatibility with MSVC.
cxxflags = ['-ansi -pedantic']
if env['DEBUG']:
#compile_options['CPPDEFINES'] = '-DDEBUG'
cxxflags.append('-O0 -g3 -ggdb')
cxxflags.append('-Wall -Wextra -Werror')
# -Werror
else:
cxxflags.append('-O3 -g3 -ggdb -Wall -Wextra')
if env['PIC']:
cxxflags.append('-fPIC')
compile_options['CXXFLAGS'] = ' '.join(cxxflags)
compile_options['LINKFLAGS'] = '-ldl -L/usr/lib -L/opt/local/lib -L/usr/local/lib'
def all_files(dir, ext='.cpp', level=6):
files = []
for i in range(1, level):
files += Glob(dir + ('/*' * i) + ext)
return files
def all_libs(name, dir):
matches = []
for root, dirnames, filenames in os.walk(dir):
for filename in fnmatch.filter(filenames, name):
matches.append(os.path.join(root, filename))
return matches
# Setup libiconv, if possible
libiconv_include = []
libiconv_libs = []
if all_libs('libiconv.*', '/opt/local/lib'):
libiconv_include.append('/opt/local/include/')
libiconv_libs.append('iconv')
else:
if all_libs('libiconv.*', '/usr/lib'):
libiconv_libs.append('iconv')
# Add libzxing library.
libzxing_files = all_files('core/src')
libzxing_include = ['core/src']
if platform.system() is 'Windows':
libzxing_files += all_files('core/src/win32')
libzxing_include += ['core/src/win32']
libzxing = env.Library('zxing', source=libzxing_files,
CPPPATH=libzxing_include + libiconv_libs, **compile_options)
# Add cli.
zxing_files = all_files('cli/src')
zxing = env.Program('zxing', zxing_files,
CPPPATH=libzxing_include,
LIBS=libzxing + libiconv_libs, **compile_options)
# Setup CPPUnit.
cppunit_include = ['/opt/local/include/']
cppunit_libs = ['cppunit']
# Add testrunner program.
test_files = all_files('core/tests/src')
test = env.Program('testrunner', test_files,
CPPPATH=libzxing_include + cppunit_include,
LIBS=libzxing + cppunit_libs, **compile_options)
# Setup some aliases.
Alias('lib', libzxing)
Alias('zxing', zxing)
Alias('tests', test)

View file

@ -1,12 +0,0 @@
# Start with the java style
style=java
# Indent with 2 spaces
indent=spaces=2
# Insert space padding around operators
-p
# Unpad paren
-U

View file

@ -0,0 +1,112 @@
/*
* Copyright 2010-2011 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 "ImageReaderSource.h"
#include <zxing/common/IllegalArgumentException.h>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include "lodepng.h"
#include "jpgd.h"
using std::string;
using std::ostringstream;
using zxing::Ref;
using zxing::ArrayRef;
using zxing::LuminanceSource;
inline char ImageReaderSource::convertPixel(char const* pixel_) const {
unsigned char const* pixel = (unsigned char const*)pixel_;
if (comps == 1 || comps == 2) {
// Gray or gray+alpha
return pixel[0];
} if (comps == 3 || comps == 4) {
// Red, Green, Blue, (Alpha)
// We assume 16 bit values here
// 0x200 = 1<<9, half an lsb of the result to force rounding
return (char)((306 * (int)pixel[0] + 601 * (int)pixel[1] +
117 * (int)pixel[2] + 0x200) >> 10);
} else {
throw zxing::IllegalArgumentException("Unexpected image depth");
}
}
ImageReaderSource::ImageReaderSource(ArrayRef<char> image_, int width, int height, int comps_)
: Super(width, height), image(image_), comps(comps_) {}
Ref<LuminanceSource> ImageReaderSource::create(string const& filename) {
string extension = filename.substr(filename.find_last_of(".") + 1);
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
int width, height;
int comps = 0;
zxing::ArrayRef<char> image;
if (extension == "png") {
std::vector<unsigned char> out;
{ unsigned w, h;
unsigned error = lodepng::decode(out, w, h, filename);
if (error) {
ostringstream msg;
msg << "Error while loading '" << lodepng_error_text(error) << "'";
throw zxing::IllegalArgumentException(msg.str().c_str());
}
width = w;
height = h;
}
comps = 4;
image = zxing::ArrayRef<char>(4 * width * height);
memcpy(&image[0], &out[0], image->size());
} else if (extension == "jpg" || extension == "jpeg") {
char *buffer = reinterpret_cast<char*>(jpgd::decompress_jpeg_image_from_file(
filename.c_str(), &width, &height, &comps, 4));
image = zxing::ArrayRef<char>(buffer, 4 * width * height);
}
if (!image) {
ostringstream msg;
msg << "Loading \"" << filename << "\" failed.";
throw zxing::IllegalArgumentException(msg.str().c_str());
}
return Ref<LuminanceSource>(new ImageReaderSource(image, width, height, comps));
}
zxing::ArrayRef<char> ImageReaderSource::getRow(int y, zxing::ArrayRef<char> row) const {
const char* pixelRow = &image[0] + y * getWidth() * 4;
if (!row) {
row = zxing::ArrayRef<char>(getWidth());
}
for (int x = 0; x < getWidth(); x++) {
row[x] = convertPixel(pixelRow + (x * 4));
}
return row;
}
/** This is a more efficient implementation. */
zxing::ArrayRef<char> ImageReaderSource::getMatrix() const {
const char* p = &image[0];
zxing::ArrayRef<char> matrix(getWidth() * getHeight());
char* m = &matrix[0];
for (int y = 0; y < getHeight(); y++) {
for (int x = 0; x < getWidth(); x++) {
*m = convertPixel(p);
m++;
p += 4;
}
}
return matrix;
}

View file

@ -1,6 +1,6 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __MAGICK_BITMAP_SOURCE_H_
#define __MAGICK_BITMAP_SOURCE_H_
#ifndef __IMAGE_READER_SOURCE_H_
#define __IMAGE_READER_SOURCE_H_
/*
* Copyright 2010-2011 ZXing authors
*
@ -17,30 +17,24 @@
* limitations under the License.
*/
#include <Magick++.h>
#include <zxing/LuminanceSource.h>
namespace zxing {
class MagickBitmapSource : public LuminanceSource {
class ImageReaderSource : public zxing::LuminanceSource {
private:
typedef LuminanceSource Super;
Magick::Image image_;
const zxing::ArrayRef<char> image;
const int comps;
char convertPixel(const char* pixel) const;
public:
MagickBitmapSource(Magick::Image& image);
static zxing::Ref<LuminanceSource> create(std::string const& filename);
~MagickBitmapSource();
ImageReaderSource(zxing::ArrayRef<char> image, int width, int height, int comps);
ArrayRef<char> getRow(int y, ArrayRef<char> row) const;
ArrayRef<char> getMatrix() const;
bool isCropSupported() const;
Ref<LuminanceSource> crop(int left, int top, int width, int height);
bool isRotateSupported() const;
Ref<LuminanceSource> rotateCounterClockwise();
zxing::ArrayRef<char> getRow(int y, zxing::ArrayRef<char> row) const;
zxing::ArrayRef<char> getMatrix() const;
};
}
#endif /* MAGICKMONOCHROMEBITMAPSOURCE_H_ */
#endif /* __IMAGE_READER_SOURCE_H_ */

3174
cpp/cli/src/jpgd.cpp Normal file

File diff suppressed because it is too large Load diff

319
cpp/cli/src/jpgd.h Normal file
View file

@ -0,0 +1,319 @@
// jpgd.h - C++ class for JPEG decompression.
// Public domain, Rich Geldreich <richgel99@gmail.com>
#ifndef JPEG_DECODER_H
#define JPEG_DECODER_H
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
#ifdef _MSC_VER
#define JPGD_NORETURN __declspec(noreturn)
#elif defined(__GNUC__)
#define JPGD_NORETURN __attribute__ ((noreturn))
#else
#define JPGD_NORETURN
#endif
namespace jpgd
{
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef unsigned int uint;
typedef signed int int32;
// Loads a JPEG image from a memory buffer or a file.
// req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
// On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB).
// Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly.
// Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp.
unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps);
unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps);
// Success/failure error codes.
enum jpgd_status
{
JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR,
JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM
};
// Input stream interface.
// Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available.
// The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set.
// It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer.
// Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding.
class jpeg_decoder_stream
{
public:
jpeg_decoder_stream() { }
virtual ~jpeg_decoder_stream() { }
// The read() method is called when the internal input buffer is empty.
// Parameters:
// pBuf - input buffer
// max_bytes_to_read - maximum bytes that can be written to pBuf
// pEOF_flag - set this to true if at end of stream (no more bytes remaining)
// Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0).
// Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full.
virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0;
};
// stdio FILE stream class.
class jpeg_decoder_file_stream : public jpeg_decoder_stream
{
jpeg_decoder_file_stream(const jpeg_decoder_file_stream &);
jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &);
FILE *m_pFile;
bool m_eof_flag, m_error_flag;
public:
jpeg_decoder_file_stream();
virtual ~jpeg_decoder_file_stream();
bool open(const char *Pfilename);
void close();
virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
};
// Memory stream class.
class jpeg_decoder_mem_stream : public jpeg_decoder_stream
{
const uint8 *m_pSrc_data;
uint m_ofs, m_size;
public:
jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
virtual ~jpeg_decoder_mem_stream() { }
bool open(const uint8 *pSrc_data, uint size);
void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
};
// Loads JPEG file from a jpeg_decoder_stream.
unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps);
enum
{
JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384
};
typedef int16 jpgd_quant_t;
typedef int16 jpgd_block_t;
class jpeg_decoder
{
public:
// Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc.
// methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline.
jpeg_decoder(jpeg_decoder_stream *pStream);
~jpeg_decoder();
// Call this method after constructing the object to begin decompression.
// If JPGD_SUCCESS is returned you may then call decode() on each scanline.
int begin_decoding();
// Returns the next scan line.
// For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
// Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
// Returns JPGD_SUCCESS if a scan line has been returned.
// Returns JPGD_DONE if all scan lines have been returned.
// Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info.
int decode(const void** pScan_line, uint* pScan_line_len);
inline jpgd_status get_error_code() const { return m_error_code; }
inline int get_width() const { return m_image_x_size; }
inline int get_height() const { return m_image_y_size; }
inline int get_num_components() const { return m_comps_in_frame; }
inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; }
inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); }
// Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file).
inline int get_total_bytes_read() const { return m_total_bytes_read; }
private:
jpeg_decoder(const jpeg_decoder &);
jpeg_decoder &operator =(const jpeg_decoder &);
typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int);
struct huff_tables
{
bool ac_table;
uint look_up[256];
uint look_up2[256];
uint8 code_size[256];
uint tree[512];
};
struct coeff_buf
{
uint8 *pData;
int block_num_x, block_num_y;
int block_len_x, block_len_y;
int block_size;
};
struct mem_block
{
mem_block *m_pNext;
size_t m_used_count;
size_t m_size;
char m_data[1];
};
jmp_buf m_jmp_state;
mem_block *m_pMem_blocks;
int m_image_x_size;
int m_image_y_size;
jpeg_decoder_stream *m_pStream;
int m_progressive_flag;
uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES];
uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size
uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size
jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables
int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported)
int m_comps_in_frame; // # of components in frame
int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor
int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor
int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector
int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
int m_comps_in_scan; // # of components in scan
int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
int m_spectral_start; // spectral selection start
int m_spectral_end; // spectral selection end
int m_successive_low; // successive approximation low
int m_successive_high; // successive approximation high
int m_max_mcu_x_size; // MCU's max. X size in pixels
int m_max_mcu_y_size; // MCU's max. Y size in pixels
int m_blocks_per_mcu;
int m_max_blocks_per_row;
int m_mcus_per_row, m_mcus_per_col;
int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
int m_total_lines_left; // total # lines left in image
int m_mcu_lines_left; // total # lines left in this MCU
int m_real_dest_bytes_per_scan_line;
int m_dest_bytes_per_scan_line; // rounded up
int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
int m_eob_run;
int m_block_y_mcu[JPGD_MAX_COMPONENTS];
uint8* m_pIn_buf_ofs;
int m_in_buf_left;
int m_tem_flag;
bool m_eof_flag;
uint8 m_in_buf_pad_start[128];
uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128];
uint8 m_in_buf_pad_end[128];
int m_bits_left;
uint m_bit_buf;
int m_restart_interval;
int m_restarts_left;
int m_next_restart_num;
int m_max_mcus_per_row;
int m_max_blocks_per_mcu;
int m_expanded_blocks_per_mcu;
int m_expanded_blocks_per_row;
int m_expanded_blocks_per_component;
bool m_freq_domain_chroma_upsample;
int m_max_mcus_per_col;
uint m_last_dc_val[JPGD_MAX_COMPONENTS];
jpgd_block_t* m_pMCU_coefficients;
int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU];
uint8* m_pSample_buf;
int m_crr[256];
int m_cbb[256];
int m_crg[256];
int m_cbg[256];
uint8* m_pScan_line_0;
uint8* m_pScan_line_1;
jpgd_status m_error_code;
bool m_ready_flag;
int m_total_bytes_read;
void free_all_blocks();
JPGD_NORETURN void stop_decoding(jpgd_status status);
void *alloc(size_t n, bool zero = false);
void word_clear(void *p, uint16 c, uint n);
void prep_in_buffer();
void read_dht_marker();
void read_dqt_marker();
void read_sof_marker();
void skip_variable_marker();
void read_dri_marker();
void read_sos_marker();
int next_marker();
int process_markers();
void locate_soi_marker();
void locate_sof_marker();
int locate_sos_marker();
void init(jpeg_decoder_stream * pStream);
void create_look_ups();
void fix_in_buffer();
void transform_mcu(int mcu_row);
void transform_mcu_expand(int mcu_row);
coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y);
inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y);
void load_next_row();
void decode_next_row();
void make_huff_table(int index, huff_tables *pH);
void check_quant_tables();
void check_huff_tables();
void calc_mcu_block_order();
int init_scan();
void init_frame();
void process_restart();
void decode_scan(pDecode_block_func decode_block_func);
void init_progressive();
void init_sequential();
void decode_start();
void decode_init(jpeg_decoder_stream * pStream);
void H2V2Convert();
void H2V1Convert();
void H1V2Convert();
void H1V1Convert();
void gray_convert();
void expanded_convert();
void find_eoi();
inline uint get_char();
inline uint get_char(bool *pPadding_flag);
inline void stuff_char(uint8 q);
inline uint8 get_octet();
inline uint get_bits(int num_bits);
inline uint get_bits_no_markers(int numbits);
inline int huff_decode(huff_tables *pH);
inline int huff_decode(huff_tables *pH, int& extrabits);
static inline uint8 clamp(int i);
static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
};
} // namespace jpgd
#endif // JPEG_DECODER_H

6261
cpp/cli/src/lodepng.cpp Normal file

File diff suppressed because it is too large Load diff

1695
cpp/cli/src/lodepng.h Normal file

File diff suppressed because it is too large Load diff

297
cpp/cli/src/main.cpp Normal file
View file

@ -0,0 +1,297 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Copyright 2010-2011 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 <iostream>
#include <fstream>
#include <string>
#include "ImageReaderSource.h"
#include <zxing/common/Counted.h>
#include <zxing/Binarizer.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/Result.h>
#include <zxing/ReaderException.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/common/HybridBinarizer.h>
#include <exception>
#include <zxing/Exception.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/DecodeHints.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/multi/qrcode/QRCodeMultiReader.h>
#include <zxing/multi/ByQuadrantReader.h>
#include <zxing/multi/MultipleBarcodeReader.h>
#include <zxing/multi/GenericMultipleBarcodeReader.h>
using namespace std;
using namespace zxing;
using namespace zxing::multi;
using namespace zxing::qrcode;
namespace {
bool more = false;
bool test_mode = false;
bool try_harder = false;
bool search_multi = false;
bool use_hybrid = false;
bool use_global = false;
bool verbose = false;
}
vector<Ref<Result> > decode(Ref<BinaryBitmap> image, DecodeHints hints) {
Ref<Reader> reader(new MultiFormatReader);
return vector<Ref<Result> >(1, reader->decode(image, hints));
}
vector<Ref<Result> > decode_multi(Ref<BinaryBitmap> image, DecodeHints hints) {
MultiFormatReader delegate;
GenericMultipleBarcodeReader reader(delegate);
return reader.decodeMultiple(image, hints);
}
int read_image(Ref<LuminanceSource> source, bool hybrid, string expected) {
vector<Ref<Result> > results;
string cell_result;
int res = -1;
try {
Ref<Binarizer> binarizer;
if (hybrid) {
binarizer = new HybridBinarizer(source);
} else {
binarizer = new GlobalHistogramBinarizer(source);
}
DecodeHints hints(DecodeHints::DEFAULT_HINT);
hints.setTryHarder(try_harder);
Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
if (search_multi) {
results = decode_multi(binary, hints);
} else {
results = decode(binary, hints);
}
res = 0;
} catch (const ReaderException& e) {
cell_result = "zxing::ReaderException: " + string(e.what());
res = -2;
} catch (const zxing::IllegalArgumentException& e) {
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
res = -3;
} catch (const zxing::Exception& e) {
cell_result = "zxing::Exception: " + string(e.what());
res = -4;
} catch (const std::exception& e) {
cell_result = "std::exception: " + string(e.what());
res = -5;
}
if (test_mode && results.size() == 1) {
std::string result = results[0]->getText()->getText();
if (expected.empty()) {
cout << " Expected text or binary data for image missing." << endl
<< " Detected: " << result << endl;
res = -6;
} else {
if (expected.compare(result) != 0) {
cout << " Expected: " << expected << endl
<< " Detected: " << result << endl;
cell_result = "data did not match";
res = -6;
}
}
}
if (res != 0 && (verbose || (use_global ^ use_hybrid))) {
cout << (hybrid ? "Hybrid" : "Global")
<< " binarizer failed: " << cell_result << endl;
} else if (!test_mode) {
if (verbose) {
cout << (hybrid ? "Hybrid" : "Global")
<< " binarizer succeeded: " << endl;
}
for (size_t i = 0; i < results.size(); i++) {
if (more) {
cout << " Format: "
<< BarcodeFormat::barcodeFormatNames[results[i]->getBarcodeFormat()]
<< endl;
for (int j = 0; j < results[i]->getResultPoints()->size(); j++) {
cout << " Point[" << j << "]: "
<< results[i]->getResultPoints()[j]->getX() << " "
<< results[i]->getResultPoints()[j]->getY() << endl;
}
}
if (verbose) {
cout << " ";
}
cout << results[i]->getText()->getText() << endl;
}
}
return res;
}
string read_expected(string imagefilename) {
string textfilename = imagefilename;
string::size_type dotpos = textfilename.rfind(".");
textfilename.replace(dotpos + 1, textfilename.length() - dotpos - 1, "txt");
ifstream textfile(textfilename.c_str(), ios::binary);
textfilename.replace(dotpos + 1, textfilename.length() - dotpos - 1, "bin");
ifstream binfile(textfilename.c_str(), ios::binary);
ifstream *file = 0;
if (textfile.is_open()) {
file = &textfile;
} else if (binfile.is_open()) {
file = &binfile;
} else {
return std::string();
}
file->seekg(0, ios_base::end);
size_t size = size_t(file->tellg());
file->seekg(0, ios_base::beg);
if (size == 0) {
return std::string();
}
char* data = new char[size + 1];
file->read(data, size);
data[size] = '\0';
string expected(data);
delete[] data;
return expected;
}
int main(int argc, char** argv) {
if (argc <= 1) {
cout << "Usage: " << argv[0] << " [OPTION]... <IMAGE>..." << endl
<< "Read barcodes from each IMAGE file." << endl
<< endl
<< "Options:" << endl
<< " (-h|--hybrid) use the hybrid binarizer (default)" << endl
<< " (-g|--global) use the global binarizer" << endl
<< " (-v|--verbose) chattier results printing" << endl
<< " --more display more information about the barcode" << endl
<< " --test-mode compare IMAGEs against text files" << endl
<< " --try-harder spend more time to try to find a barcode" << endl
<< " --search-multi search for more than one bar code" << endl
<< endl
<< "Example usage:" << endl
<< " zxing --test-mode *.jpg" << endl
<< endl;
return 1;
}
int total = 0;
int gonly = 0;
int honly = 0;
int both = 0;
int neither = 0;
for (int i = 1; i < argc; i++) {
string filename = argv[i];
if (filename.compare("--verbose") == 0 ||
filename.compare("-v") == 0) {
verbose = true;
continue;
}
if (filename.compare("--hybrid") == 0 ||
filename.compare("-h") == 0) {
use_hybrid = true;
continue;
}
if (filename.compare("--global") == 0 ||
filename.compare("-g") == 0) {
use_global = true;
continue;
}
if (filename.compare("--more") == 0) {
more = true;
continue;
}
if (filename.compare("--test-mode") == 0) {
test_mode = true;
continue;
}
if (filename.compare("--try-harder") == 0) {
try_harder = true;
continue;
}
if (filename.compare("--search-multi") == 0){
search_multi = true;
continue;
}
if (filename.length() > 3 &&
(filename.substr(filename.length() - 3, 3).compare("txt") == 0 ||
filename.substr(filename.length() - 3, 3).compare("bin") == 0)) {
continue;
}
if (!use_global && !use_hybrid) {
use_global = use_hybrid = true;
}
if (test_mode) {
cerr << "Testing: " << filename << endl;
}
Ref<LuminanceSource> source;
try {
source = ImageReaderSource::create(filename);
} catch (const zxing::IllegalArgumentException &e) {
cerr << e.what() << " (ignoring)" << endl;
continue;
}
string expected = read_expected(filename);
int gresult = 1;
int hresult = 1;
if (use_hybrid) {
hresult = read_image(source, true, expected);
}
if (use_global && (verbose || hresult != 0)) {
gresult = read_image(source, false, expected);
if (!verbose && gresult != 0) {
cout << "decoding failed" << endl;
}
}
gresult = gresult == 0;
hresult = hresult == 0;
gonly += gresult && !hresult;
honly += hresult && !gresult;
both += gresult && hresult;
neither += !gresult && !hresult;
total = total + 1;
}
if (test_mode) {
cout << endl
<< "Summary:" << endl
<< " " << total << " images tested total," << endl
<< " " << (honly + both) << " passed hybrid, " << (gonly + both)
<< " passed global, " << both << " pass both, " << endl
<< " " << honly << " passed only hybrid, " << gonly
<< " passed only global, " << neither << " pass neither." << endl;
}
return 0;
}

View file

@ -0,0 +1,54 @@
#
# Find the CppUnit includes and library
#
# This module defines
# CPPUNIT_INCLUDE_DIR, where to find tiff.h, etc.
# CPPUNIT_LIBRARIES, the libraries to link against to use CppUnit.
# CPPUNIT_FOUND, If false, do not try to use CppUnit.
# also defined, but not for general use are
# CPPUNIT_LIBRARY, where to find the CppUnit library.
# CPPUNIT_DEBUG_LIBRARY, where to find the CppUnit library in debug
# mode.
SET(CPPUNIT_FOUND "NO")
FIND_PATH(CPPUNIT_INCLUDE_DIR cppunit/TestCase.h /usr/local/include /usr/include)
# With Win32, important to have both
IF(WIN32)
FIND_LIBRARY(CPPUNIT_LIBRARY cppunit
${CPPUNIT_INCLUDE_DIR}/../lib
/usr/local/lib
/usr/lib)
FIND_LIBRARY(CPPUNIT_DEBUG_LIBRARY cppunitd
${CPPUNIT_INCLUDE_DIR}/../lib
/usr/local/lib
/usr/lib)
ELSE(WIN32)
# On unix system, debug and release have the same name
FIND_LIBRARY(CPPUNIT_LIBRARY cppunit
${CPPUNIT_INCLUDE_DIR}/../lib
/usr/local/lib
/usr/lib)
FIND_LIBRARY(CPPUNIT_DEBUG_LIBRARY cppunit
${CPPUNIT_INCLUDE_DIR}/../lib
/usr/local/lib
/usr/lib)
ENDIF(WIN32)
IF(CPPUNIT_INCLUDE_DIR)
IF(CPPUNIT_LIBRARY)
SET(CPPUNIT_FOUND "YES")
SET(CPPUNIT_LIBRARIES ${CPPUNIT_LIBRARY} ${CMAKE_DL_LIBS})
SET(CPPUNIT_DEBUG_LIBRARIES ${CPPUNIT_DEBUG_LIBRARY} ${CMAKE_DL_LIBS})
ELSE (CPPUNIT_LIBRARY)
IF (CPPUNIT_FIND_REQUIRED)
MESSAGE(SEND_ERROR "Could not find library CppUnit.")
ENDIF (CPPUNIT_FIND_REQUIRED)
ENDIF(CPPUNIT_LIBRARY)
ELSE(CPPUNIT_INCLUDE_DIR)
IF (CPPUNIT_FIND_REQUIRED)
MESSAGE(SEND_ERROR "Could not find library CppUnit.")
ENDIF(CPPUNIT_FIND_REQUIRED)
ENDIF(CPPUNIT_INCLUDE_DIR)

57
cpp/cmake/FindIconv.cmake Normal file
View file

@ -0,0 +1,57 @@
# - Try to find Iconv
# Once done this will define
#
# ICONV_FOUND - system has Iconv
# ICONV_INCLUDE_DIR - the Iconv include directory
# ICONV_LIBRARIES - Link these to use Iconv
# ICONV_SECOND_ARGUMENT_IS_CONST - the second argument for iconv() is const
#
include(CheckCXXSourceCompiles)
IF (ICONV_INCLUDE_DIR)
# Already in cache, be silent
SET(ICONV_FIND_QUIETLY TRUE)
ENDIF (ICONV_INCLUDE_DIR)
FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
FIND_LIBRARY(ICONV_LIBRARIES NAMES iconv libiconv libiconv-2 c)
IF(ICONV_INCLUDE_DIR)
SET(ICONV_FOUND TRUE)
ENDIF(ICONV_INCLUDE_DIR)
set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES})
IF(ICONV_FOUND)
check_cxx_source_compiles("
#include <iconv.h>
int main(){
iconv_t conv = 0;
char* in = 0;
size_t ilen = 0;
char* out = 0;
size_t olen = 0;
iconv(conv, &in, &ilen, &out, &olen);
return 0;
}
" ICONV_SECOND_ARGUMENT_IS_CONST )
ENDIF(ICONV_FOUND)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
IF(ICONV_FOUND)
IF(NOT ICONV_FIND_QUIETLY)
MESSAGE(STATUS "Found Iconv: ${ICONV_LIBRARIES}")
ENDIF(NOT ICONV_FIND_QUIETLY)
ELSE(ICONV_FOUND)
IF(Iconv_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find Iconv")
ENDIF(Iconv_FIND_REQUIRED)
ENDIF(ICONV_FOUND)
MARK_AS_ADVANCED(
ICONV_INCLUDE_DIR
ICONV_LIBRARIES
ICONV_SECOND_ARGUMENT_IS_CONST
)

View file

@ -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

View file

@ -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

View file

@ -1,8 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* BinaryBitmap.cpp
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -26,6 +23,9 @@ using zxing::BitMatrix;
using zxing::LuminanceSource;
using zxing::BinaryBitmap;
// VC++
using zxing::Binarizer;
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : binarizer_(binarizer) {
}

View file

@ -26,6 +26,9 @@ using zxing::ResultPointCallback;
using zxing::DecodeHintType;
using zxing::DecodeHints;
// VC++
using zxing::BarcodeFormat;
const DecodeHintType DecodeHints::CHARACTER_SET;
const DecodeHints DecodeHints::PRODUCT_HINT(
@ -103,7 +106,7 @@ bool DecodeHints::containsFormat(BarcodeFormat tocheck) const {
case BarcodeFormat::UPC_EAN_EXTENSION: checkAgainst |= UPC_EAN_EXTENSION_HINT; break;
default: throw IllegalArgumentException("Unrecognizd barcode format");
}
return (hints & checkAgainst);
return (hints & checkAgainst) != 0;
}
void DecodeHints::setTryHarder(bool toset) {
@ -115,7 +118,7 @@ void DecodeHints::setTryHarder(bool toset) {
}
bool DecodeHints::getTryHarder() const {
return (hints & TRYHARDER_HINT);
return (hints & TRYHARDER_HINT) != 0;
}
void DecodeHints::setResultPointCallback(Ref<ResultPointCallback> const& _callback) {

View file

@ -69,6 +69,8 @@ class DecodeHints {
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;

View file

@ -1,10 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* MultiFormatBarcodeReader.cpp
* ZXing
*
* Created by Lukasz Warchol on 10-01-26.
* Modified by Luiz Silva on 09/02/2010.
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -33,6 +28,10 @@ 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) {
@ -114,6 +113,7 @@ Ref<Result> MultiFormatReader::decodeInternal(Ref<BinaryBitmap> image) {
try {
return readers_[i]->decode(image, hints_);
} catch (ReaderException const& re) {
(void)re;
// continue
}
}

View file

@ -27,6 +27,9 @@ using zxing::ArrayRef;
using zxing::String;
using zxing::ResultPoint;
// VC++
using zxing::BarcodeFormat;
Result::Result(Ref<String> text,
ArrayRef<char> rawBytes,
ArrayRef< Ref<ResultPoint> > resultPoints,

View file

@ -20,7 +20,7 @@
*/
#include <zxing/ResultPoint.h>
#include <zxing/common/detector/math_utils.h>
#include <zxing/common/detector/MathUtils.h>
namespace math_utils = zxing::common::detector::math_utils;
@ -29,6 +29,8 @@ 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() {}

View file

@ -34,6 +34,7 @@ protected:
public:
ResultPoint();
ResultPoint(float x, float y);
ResultPoint(int x, int y);
virtual ~ResultPoint();
virtual float getX() const;

View file

@ -31,12 +31,34 @@
#endif
namespace zxing {
typedef char byte;
typedef bool boolean;
}
#include <limits>
#if defined(_WIN32) || defined(_WIN64)
#include <float.h>
namespace zxing {
inline bool isnan(float v) {return _isnan(v) != 0;}
inline bool isnan(double v) {return _isnan(v) != 0;}
inline float nan() {return std::numeric_limits<float>::quiet_NaN();}
}
#else
#include <cmath>
namespace zxing {
inline bool isnan(float v) {return std::isnan(v);}
inline bool isnan(double v) {return std::isnan(v);}
inline float nan() {return std::numeric_limits<float>::quiet_NaN();}
}
#endif
#if ZXING_DEBUG
#include <iostream>

View file

@ -23,6 +23,13 @@
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,

View file

@ -28,6 +28,10 @@ using zxing::Ref;
using zxing::ArrayRef;
using zxing::Result;
using zxing::aztec::AztecReader;
// VC++
using zxing::BinaryBitmap;
using zxing::DecodeHints;
AztecReader::AztecReader() : decoder_() {
// nothing

View file

@ -332,9 +332,11 @@ Ref<BitArray> Decoder::correctBits(Ref<zxing::BitArray> rawbits) {
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());
}

View file

@ -26,7 +26,7 @@
#include <zxing/common/reedsolomon/ReedSolomonException.h>
#include <zxing/common/reedsolomon/GenericGF.h>
#include <iostream>
#include <zxing/common/detector/math_utils.h>
#include <zxing/common/detector/MathUtils.h>
#include <zxing/NotFoundException.h>
using std::vector;
@ -38,8 +38,9 @@ using zxing::ArrayRef;
using zxing::ResultPoint;
using zxing::BitArray;
using zxing::BitMatrix;
namespace math_utils = zxing::common::detector::math_utils;
Detector::Detector(Ref<BitMatrix> image):
image_(image),
nbLayers_(0),
@ -169,10 +170,10 @@ Detector::getMatrixCornerPoints(std::vector<Ref<Point> > bullEyeCornerPoints) {
}
Array< Ref<ResultPoint> >* array = new Array< Ref<ResultPoint> >();
vector< Ref<ResultPoint> >& returnValue (array->values());
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(targetax, targetay)));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(targetbx, targetby)));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(targetcx, targetcy)));
returnValue.push_back(Ref<ResultPoint>(new ResultPoint(targetdx, targetdy)));
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);
}
@ -208,6 +209,7 @@ void Detector::correctParameterData(Ref<zxing::BitArray> parameterData, bool com
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");
}
@ -311,6 +313,7 @@ Ref<Point> Detector::getMatrixCenter() {
pointD = cornerPoints[3];
} catch (NotFoundException const& e) {
(void)e;
int cx = image_->getWidth() / 2;
int cy = image_->getHeight() / 2;
@ -334,6 +337,7 @@ Ref<Point> Detector::getMatrixCenter() {
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();
@ -425,11 +429,11 @@ Ref<BitArray> Detector::sampleLine(Ref<zxing::aztec::Point> p1, Ref<zxing::aztec
float d = distance(p1, p2);
float moduleSize = d / (size-1);
float dx = moduleSize * (p2->x - p1->x)/d;
float dy = moduleSize * (p2->y - p1->y)/d;
float px = p1->x;
float py = p1->y;
float dx = moduleSize * float(p2->x - p1->x)/d;
float dy = moduleSize * float(p2->y - p1->y)/d;
float px = float(p1->x);
float py = float(p1->y);
for (int i = 0; i < size; i++) {
if (image_->get(math_utils::round(px), math_utils::round(py))) res->set(i);
@ -486,8 +490,8 @@ int Detector::getColor(Ref<zxing::aztec::Point> p1, Ref<zxing::aztec::Point> p2)
int error = 0;
float px = p1->x;
float py = p1->y;
float px = float(p1->x);
float py = float(p1->y);
bool colorModel = image_->get(p1->x, p1->y);

View file

@ -39,7 +39,7 @@ public:
int y;
Ref<ResultPoint> toResultPoint() {
return Ref<ResultPoint>(new ResultPoint(x, y));
return Ref<ResultPoint>(new ResultPoint(float(x), float(y)));
}
Point(int ax, int ay):x(ax),y(ay) {};

View file

@ -1,22 +0,0 @@
/*
* Array.cpp
* zxing
*
* Created by Christian Brunschen on 07/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/Array.h>

View file

@ -120,12 +120,10 @@ public:
T const& operator[](int i) const {
return (*array_)[i];
}
T& operator[](int i) {
return (*array_)[i];
}
int size() const {
return array_->size();
}
void reset(Array<T> *a) {
if (a) {
@ -148,12 +146,14 @@ public:
return *this;
}
Array<T>& operator*() {
Array<T>& operator*() const {
return *array_;
}
Array<T>* operator->() {
Array<T>* operator->() const {
return array_;
}
operator bool () const {
return array_ != 0;
}

View file

@ -20,6 +20,9 @@
using std::vector;
using zxing::BitArray;
// VC++
using zxing::Ref;
int BitArray::makeArraySize(int size) {
return (size + bitsPerWord-1) >> logBits;
}
@ -38,36 +41,8 @@ void BitArray::setBulk(int i, int newBits) {
bits[i >> logBits] = newBits;
}
/*
void BitArray::setRange(int start, int end) {
if (end < start) {
throw IllegalArgumentException("invalid call to BitArray::setRange");
}
if (end == start) {
return;
}
end--; // will be easier to treat this as the last actually set bit -- inclusive
int firstInt = start >> 5;
int lastInt = end >> 5;
for (int i = firstInt; i <= lastInt; i++) {
int firstBit = i > firstInt ? 0 : start & 0x1F;
int lastBit = i < lastInt ? 31 : end & 0x1F;
int mask;
if (firstBit == 0 && lastBit == 31) {
mask = -1;
} else {
mask = 0;
for (int j = firstBit; j <= lastBit; j++) {
mask |= 1 << j;
}
}
bits_[i] |= mask;
}
}
*/
void BitArray::clear() {
int max = bits.size();
int max = bits->size();
for (int i = 0; i < max; i++) {
bits[i] = 0;
}
@ -110,7 +85,7 @@ vector<int>& BitArray::getBitArray() {
}
void BitArray::reverse() {
ArrayRef<int> newBits(bits.size());
ArrayRef<int> newBits(bits->size());
int size = this->size;
for (int i = 0; i < size; i++) {
if (get(size - i - 1)) {
@ -152,7 +127,7 @@ int BitArray::getNextSet(int from) {
// mask off lesser bits first
currentBits &= ~((1 << (from & bitsMask)) - 1);
while (currentBits == 0) {
if (++bitsOffset == (int)bits.size()) {
if (++bitsOffset == (int)bits->size()) {
return size;
}
currentBits = bits[bitsOffset];
@ -170,7 +145,7 @@ int BitArray::getNextUnset(int from) {
// mask off lesser bits first
currentBits &= ~((1 << (from & bitsMask)) - 1);
while (currentBits == 0) {
if (++bitsOffset == (int)bits.size()) {
if (++bitsOffset == (int)bits->size()) {
return size;
}
currentBits = ~bits[bitsOffset];

View file

@ -71,6 +71,6 @@ int BitSource::readBits(int numBits) {
}
int BitSource::available() {
return 8 * (bytes_.size() - byteOffset_) - bitOffset_;
return 8 * (bytes_->size() - byteOffset_) - bitOffset_;
}
}

View file

@ -1,32 +0,0 @@
/*
* Counted.cpp
* zxing
*
* Created by Christian Brunschen on 07/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/Counted.h>
namespace zxing {
using namespace std;
template<class T>
ostream& operator<<(ostream &out, Ref<T>& ref) {
out << "Ref(" << (ref.object_ ? (*ref.object_) : "NULL") << ")";
return out;
}
}

View file

@ -133,10 +133,8 @@ public:
bool empty() const {
return object_ == 0;
}
template<class Y>
friend std::ostream& operator<<(std::ostream &out, Ref<Y>& ref);
};
}
#endif // __COUNTED_H__

View file

@ -1,191 +0,0 @@
/*
* EdgeDetector.cpp
* zxing
*
* Created by Ralf Kistner on 7/12/2009.
* 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/common/EdgeDetector.h>
#include <algorithm>
#include <cmath>
using namespace std;
namespace zxing {
namespace EdgeDetector {
void findEdgePoints(std::vector<Point>& points, const BitMatrix& image, Point start, Point end, bool invert, int skip, float deviation) {
float xdist = end.x - start.x;
float ydist = end.y - start.y;
float length = sqrt(xdist * xdist + ydist * ydist);
int var;
if (abs(xdist) > abs(ydist)) {
// Horizontal
if (xdist < 0)
skip = -skip;
var = int(abs(deviation * length / xdist));
float dy = ydist / xdist * skip;
bool left = (skip < 0) ^ invert;
int x = int(start.x);
int steps = int(xdist / skip);
for (int i = 0; i < steps; i++) {
x += skip;
if (x < 0 || x >= (int)image.getWidth())
continue; // In case we start off the edge
int my = int(start.y + dy * i);
int ey = min(my + var + 1, (int)image.getHeight() - 1);
int sy = max(my - var, 0);
for (int y = sy + 1; y < ey; y++) {
if (left) {
if (image.get(x, y) && !image.get(x, y + 1)) {
points.push_back(Point(x, y + 0.5f));
}
} else {
if (!image.get(x, y) && image.get(x, y + 1)) {
points.push_back(Point(x, y + 0.5f));
}
}
}
}
} else {
// Vertical
if (ydist < 0)
skip = -skip;
var = int(abs(deviation * length / ydist));
float dx = xdist / ydist * skip;
bool down = (skip > 0) ^ invert;
int y = int(start.y);
int steps = int(ydist / skip);
for (int i = 0; i < steps; i++) {
y += skip;
if (y < 0 || y >= (int)image.getHeight())
continue; // In case we start off the edge
int mx = int(start.x + dx * i);
int ex = min(mx + var + 1, (int)image.getWidth() - 1);
int sx = max(mx - var, 0);
for (int x = sx + 1; x < ex; x++) {
if (down) {
if (image.get(x, y) && !image.get(x + 1, y)) {
points.push_back(Point(x + 0.5f, y));
}
} else {
if (!image.get(x, y) && image.get(x + 1, y)) {
points.push_back(Point(x + 0.5f, y));
}
}
}
}
}
}
Line findLine(const BitMatrix& image, Line estimate, bool invert, int deviation, float threshold, int skip) {
float t = threshold * threshold;
Point start = estimate.start;
Point end = estimate.end;
vector<Point> edges;
edges.clear();
findEdgePoints(edges, image, start, end, invert, skip, deviation);
int n = edges.size();
float xdist = end.x - start.x;
float ydist = end.y - start.y;
bool horizontal = abs(xdist) > abs(ydist);
float max = 0;
Line bestLine(start, end); // prepopulate with the given line, in case we can't find any line for some reason
for (int i = -deviation; i < deviation; i++) {
float x1, y1;
if (horizontal) {
y1 = start.y + i;
x1 = start.x - i * ydist / xdist;
} else {
y1 = start.y - i * xdist / ydist;
x1 = start.x + i;
}
for (int j = -deviation; j < deviation; j++) {
float x2, y2;
if (horizontal) {
y2 = end.y + j;
x2 = end.x - j * ydist / xdist;
} else {
y2 = end.y - j * xdist / ydist;
x2 = end.x + j;
}
float dx = x1 - x2;
float dy = y1 - y2;
float length = sqrt(dx * dx + dy * dy);
float score = 0;
for(int k = 0; k < n; k++) {
const Point& edge = edges[k];
float dist = ((x1 - edge.x) * dy - (y1 - edge.y) * dx) / length;
// Similar to least squares method
float s = t - dist * dist;
if (s > 0)
score += s;
}
if (score > max) {
max = score;
bestLine.start = Point(x1, y1);
bestLine.end = Point(x2, y2);
}
}
}
return bestLine;
}
Point intersection(Line a, Line b) {
float dxa = a.start.x - a.end.x;
float dxb = b.start.x - b.end.x;
float dya = a.start.y - a.end.y;
float dyb = b.start.y - b.end.y;
float p = a.start.x * a.end.y - a.start.y * a.end.x;
float q = b.start.x * b.end.y - b.start.y * b.end.x;
float denom = dxa * dyb - dya * dxb;
if(denom == 0) // Lines don't intersect
return Point(INFINITY, INFINITY);
float x = (p * dxb - dxa * q) / denom;
float y = (p * dyb - dya * q) / denom;
return Point(x, y);
}
} // namespace EdgeDetector
} // namespace zxing

View file

@ -1,38 +0,0 @@
#ifndef __EDGEDETECTOR_H__
#define __EDGEDETECTOR_H__
/*
* EdgeDetector.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/BitMatrix.h>
#include <zxing/common/Point.h>
namespace zxing {
namespace EdgeDetector {
void findEdgePoints(std::vector<Point>& points, const BitMatrix& image, Point start, Point end, bool invert, int skip, float deviation);
Line findLine(const BitMatrix& image, Line estimate, bool invert, int deviation, float threshold, int skip);
Point intersection(Line a, Line b);
}
}
#endif /* EDGEDETECTOR_H_ */

View file

@ -29,6 +29,9 @@ using zxing::Ref;
using zxing::BitArray;
using zxing::BitMatrix;
// VC++
using zxing::LuminanceSource;
namespace {
const int LUMINANCE_BITS = 5;
const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
@ -42,7 +45,7 @@ GlobalHistogramBinarizer::GlobalHistogramBinarizer(Ref<LuminanceSource> source)
GlobalHistogramBinarizer::~GlobalHistogramBinarizer() {}
void GlobalHistogramBinarizer::initArrays(int luminanceSize) {
if (luminances.size() < luminanceSize) {
if (luminances->size() < luminanceSize) {
luminances = ArrayRef<char>(luminanceSize);
}
for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
@ -133,7 +136,7 @@ using namespace std;
int GlobalHistogramBinarizer::estimateBlackPoint(ArrayRef<int> const& buckets) {
// Find tallest peak in histogram
int numBuckets = buckets.size();
int numBuckets = buckets->size();
int maxBucketCount = 0;
int firstPeak = 0;
int firstPeakSize = 0;

View file

@ -47,7 +47,7 @@ ArrayRef<char> GreyscaleLuminanceSource::getRow(int y, ArrayRef<char> row) const
throw IllegalArgumentException("Requested row is outside the image.");
}
int width = getWidth();
if (!row || row.size() < width) {
if (!row || row->size() < width) {
ArrayRef<char> temp (width);
row = temp;
}

View file

@ -49,7 +49,7 @@ GreyscaleRotatedLuminanceSource::getRow(int y, ArrayRef<char> row) const {
if (y < 0 || y >= getHeight()) {
throw IllegalArgumentException("Requested row is outside the image.");
}
if (!row || row.size() < getWidth()) {
if (!row || row->size() < getWidth()) {
row = ArrayRef<char>(getWidth());
}
int offset = (left_ * dataWidth_) + (dataWidth_ - 1 - (y + top_));

View file

@ -105,12 +105,12 @@ void GridSampler::checkAndNudgePoints(Ref<BitMatrix> image, vector<float> &point
if (x == -1) {
points[offset] = 0.0f;
} else if (x == width) {
points[offset] = width - 1;
points[offset] = float(width - 1);
}
if (y == -1) {
points[offset + 1] = 0.0f;
} else if (y == height) {
points[offset + 1] = height - 1;
points[offset + 1] = float(height - 1);
}
}

View file

@ -28,17 +28,29 @@ using zxing::Ref;
String::String(const std::string &text) :
text_(text) {
}
const std::string& String::getText() const {
return text_;
}
char String::charAt(int i) const { return text_[i]; }
int String::size() const { return text_.size(); }
int String::length() const { return text_.size(); }
Ref<String> String::substring(int i) const {
return Ref<String>(new String(text_.substr(i)));
}
void String::append(const std::string &tail) {
text_.append(tail);
}
void String::append(char c) {
text_.append(1,c);
}
std::ostream& zxing::operator << (std::ostream& out, String const& s) {
out << s.text_;
return out;

View file

@ -39,6 +39,8 @@ public:
Ref<String> substring(int) const;
const std::string& getText() const;
int size() const;
void append(std::string const& tail);
void append(char c);
int length() const;
friend std::ostream& zxing::operator << (std::ostream& out, String const& s);
};

View file

@ -17,7 +17,7 @@
* limitations under the License.
*/
#include <math.h>
#include <cmath>
namespace zxing { namespace common { namespace detector { namespace math_utils {
@ -32,13 +32,13 @@ inline int round(float d) {
inline float distance(float aX, float aY, float bX, float bY) {
float xDiff = aX - bX;
float yDiff = aY - bY;
return (float) sqrt(xDiff * xDiff + yDiff * yDiff);
return sqrt(xDiff * xDiff + yDiff * yDiff);
}
inline float distance(int aX, int aY, int bX, int bY) {
int xDiff = aX - bX;
int yDiff = aY - bY;
return (float) sqrt(xDiff * xDiff + yDiff * yDiff);
return sqrt(float(xDiff * xDiff + yDiff * yDiff));
}
}}}}

View file

@ -1,3 +1,4 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* MonochromeRectangleDetector.cpp
* y_wmk
@ -22,150 +23,152 @@
#include <zxing/common/detector/MonochromeRectangleDetector.h>
#include <sstream>
namespace zxing {
using namespace std;
using std::vector;
using zxing::Ref;
using zxing::ResultPoint;
using zxing::TwoInts;
using zxing::MonochromeRectangleDetector;
std::vector<Ref<ResultPoint> > MonochromeRectangleDetector::detect() {
int height = image_->getHeight();
int width = image_->getWidth();
int halfHeight = height >> 1;
int halfWidth = width >> 1;
int deltaY = max(1, height / (MAX_MODULES << 3));
int deltaX = max(1, width / (MAX_MODULES << 3));
vector<Ref<ResultPoint> > MonochromeRectangleDetector::detect() {
int height = image_->getHeight();
int width = image_->getWidth();
int halfHeight = height >> 1;
int halfWidth = width >> 1;
int deltaY = std::max(1, height / (MAX_MODULES << 3));
int deltaX = std::max(1, width / (MAX_MODULES << 3));
int top = 0;
int bottom = height;
int left = 0;
int right = width;
Ref<ResultPoint> pointA(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 1));
top = (int) pointA->getY() - 1;;
Ref<ResultPoint> pointB(findCornerFromCenter(halfWidth, -deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
left = (int) pointB->getX() - 1;
Ref<ResultPoint> pointC(findCornerFromCenter(halfWidth, deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
right = (int) pointC->getX() + 1;
Ref<ResultPoint> pointD(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, deltaY, top, bottom, halfWidth >> 1));
bottom = (int) pointD->getY() + 1;
int top = 0;
int bottom = height;
int left = 0;
int right = width;
Ref<ResultPoint> pointA(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 1));
top = (int) pointA->getY() - 1;;
Ref<ResultPoint> pointB(findCornerFromCenter(halfWidth, -deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
left = (int) pointB->getX() - 1;
Ref<ResultPoint> pointC(findCornerFromCenter(halfWidth, deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
right = (int) pointC->getX() + 1;
Ref<ResultPoint> pointD(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, deltaY, top, bottom, halfWidth >> 1));
bottom = (int) pointD->getY() + 1;
// Go try to find point A again with better information -- might have been off at first.
pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 2));
// Go try to find point A again with better information -- might have been off at first.
pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 2));
std::vector<Ref<ResultPoint> > corners(4);
corners[0].reset(pointA);
corners[1].reset(pointB);
corners[2].reset(pointC);
corners[3].reset(pointD);
return corners;
}
vector<Ref<ResultPoint> > corners(4);
corners[0].reset(pointA);
corners[1].reset(pointB);
corners[2].reset(pointC);
corners[3].reset(pointD);
return corners;
}
Ref<ResultPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {
Ref<TwoInts> lastRange(NULL);
for (int y = centerY, x = centerX;
y < bottom && y >= top && x < right && x >= left;
y += deltaY, x += deltaX) {
Ref<TwoInts> range(NULL);
if (deltaX == 0) {
// horizontal slices, up and down
range = blackWhiteRange(y, maxWhiteRun, left, right, true);
int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {
Ref<TwoInts> lastRange(NULL);
for (int y = centerY, x = centerX;
y < bottom && y >= top && x < right && x >= left;
y += deltaY, x += deltaX) {
Ref<TwoInts> range(NULL);
if (deltaX == 0) {
// horizontal slices, up and down
range = blackWhiteRange(y, maxWhiteRun, left, right, true);
} else {
// vertical slices, left and right
range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
}
if (range == NULL) {
if (lastRange == NULL) {
throw NotFoundException("Couldn't find corners (lastRange = NULL) ");
} else {
// vertical slices, left and right
range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
}
if (range == NULL) {
if (lastRange == NULL) {
throw NotFoundException("Couldn't find corners (lastRange = NULL) ");
} else {
// lastRange was found
if (deltaX == 0) {
int lastY = y - deltaY;
if (lastRange->start < centerX) {
if (lastRange->end > centerX) {
// straddle, choose one or the other based on direction
Ref<ResultPoint> result(new ResultPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));
return result;
Ref<ResultPoint> result(new ResultPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));
return result;
}
Ref<ResultPoint> result(new ResultPoint(lastRange->start, lastY));
return result;
Ref<ResultPoint> result(new ResultPoint(lastRange->start, lastY));
return result;
} else {
Ref<ResultPoint> result(new ResultPoint(lastRange->end, lastY));
return result;
}
Ref<ResultPoint> result(new ResultPoint(lastRange->end, lastY));
return result;
}
} else {
int lastX = x - deltaX;
if (lastRange->start < centerY) {
if (lastRange->end > centerY) {
Ref<ResultPoint> result(new ResultPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));
return result;
Ref<ResultPoint> result(new ResultPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));
return result;
}
Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->start));
return result;
Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->start));
return result;
} else {
Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->end));
return result;
}
Ref<ResultPoint> result(new ResultPoint(lastX, lastRange->end));
return result;
}
}
}
lastRange = range;
}
throw NotFoundException("Couldn't find corners");
}
}
lastRange = range;
}
throw NotFoundException("Couldn't find corners");
}
Ref<TwoInts> MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal) {
bool horizontal) {
int center = (minDim + maxDim) >> 1;
int center = (minDim + maxDim) >> 1;
// Scan left/up first
int start = center;
while (start >= minDim) {
if (horizontal ? image_->get(start, fixedDimension) : image_->get(fixedDimension, start)) {
// Scan left/up first
int start = center;
while (start >= minDim) {
if (horizontal ? image_->get(start, fixedDimension) : image_->get(fixedDimension, start)) {
start--;
} else {
int whiteRunStart = start;
do {
start--;
} else {
int whiteRunStart = start;
do {
start--;
} while (start >= minDim && !(horizontal ? image_->get(start, fixedDimension) :
image_->get(fixedDimension, start)));
int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart;
break;
}
} while (start >= minDim && !(horizontal ? image_->get(start, fixedDimension) :
image_->get(fixedDimension, start)));
int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart;
break;
}
}
start++;
// Then try right/down
int end = center;
while (end < maxDim) {
if (horizontal ? image_->get(end, fixedDimension) : image_->get(fixedDimension, end)) {
end++;
} else {
int whiteRunStart = end;
do {
end++;
} while (end < maxDim && !(horizontal ? image_->get(end, fixedDimension) :
image_->get(fixedDimension, end)));
int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart;
break;
}
}
}
end--;
Ref<TwoInts> result(NULL);
if (end > start) {
result = new TwoInts;
result->start = start;
result->end = end;
}
return result;
}
start++;
// Then try right/down
int end = center;
while (end < maxDim) {
if (horizontal ? image_->get(end, fixedDimension) : image_->get(fixedDimension, end)) {
end++;
} else {
int whiteRunStart = end;
do {
end++;
} while (end < maxDim && !(horizontal ? image_->get(end, fixedDimension) :
image_->get(fixedDimension, end)));
int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart;
break;
}
}
}
end--;
Ref<TwoInts> result(NULL);
if (end > start) {
result = new TwoInts;
result->start = start;
result->end = end;
}
return result;
}

View file

@ -1,3 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __MONOCHROMERECTANGLEDETECTOR_H__
#define __MONOCHROMERECTANGLEDETECTOR_H__
@ -28,33 +30,33 @@
#include <zxing/common/Counted.h>
#include <zxing/ResultPoint.h>
namespace zxing {
struct TwoInts: public Counted {
int start;
int end;
int start;
int end;
};
class MonochromeRectangleDetector : public Counted {
private:
private:
static const int MAX_MODULES = 32;
Ref<BitMatrix> image_;
public:
public:
MonochromeRectangleDetector(Ref<BitMatrix> image) : image_(image) { };
std::vector<Ref<ResultPoint> > detect();
private:
private:
Ref<ResultPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun);
int centerY, int deltaY, int top, int bottom, int maxWhiteRun);
Ref<TwoInts> blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal);
bool horizontal);
int max(int a, float b) { return (float) a > b ? a : (int) b;};
};
}
#endif // __MONOCHROMERECTANGLEDETECTOR_H__

View file

@ -21,18 +21,22 @@
#include <zxing/NotFoundException.h>
#include <zxing/common/detector/WhiteRectangleDetector.h>
#include <zxing/common/detector/math_utils.h>
#include <zxing/common/detector/MathUtils.h>
#include <sstream>
namespace math_utils = zxing::common::detector::math_utils;
namespace zxing {
using namespace std;
using std::vector;
using zxing::Ref;
using zxing::ResultPoint;
using zxing::WhiteRectangleDetector;
// VC++
using zxing::BitMatrix;
int WhiteRectangleDetector::INIT_SIZE = 30;
int WhiteRectangleDetector::CORR = 1;
WhiteRectangleDetector::WhiteRectangleDetector(Ref<BitMatrix> image) : image_(image) {
width_ = image->getWidth();
height_ = image->getHeight();
@ -225,7 +229,9 @@ std::vector<Ref<ResultPoint> > WhiteRectangleDetector::detect() {
}
}
Ref<ResultPoint> WhiteRectangleDetector::getBlackPointOnSegment(float aX, float aY, float bX, float bY) {
Ref<ResultPoint>
WhiteRectangleDetector::getBlackPointOnSegment(int aX_, int aY_, int bX_, int bY_) {
float aX = float(aX_), aY = float(aY_), bX = float(bX_), bY = float(bY_);
int dist = math_utils::round(math_utils::distance(aX, aY, bX, bY));
float xStep = (bX - aX) / dist;
float yStep = (bY - aY) / dist;
@ -234,7 +240,7 @@ Ref<ResultPoint> WhiteRectangleDetector::getBlackPointOnSegment(float aX, float
int x = math_utils::round(aX + i * xStep);
int y = math_utils::round(aY + i * yStep);
if (image_->get(x, y)) {
Ref<ResultPoint> point(new ResultPoint(x, y));
Ref<ResultPoint> point(new ResultPoint(float(x), float(y)));
return point;
}
}
@ -323,4 +329,3 @@ bool WhiteRectangleDetector::containsBlackPoint(int a, int b, int fixed, bool ho
return false;
}
}

View file

@ -49,7 +49,7 @@ class WhiteRectangleDetector : public Counted {
std::vector<Ref<ResultPoint> > detect();
private:
Ref<ResultPoint> getBlackPointOnSegment(float aX, float aY, float bX, float bY);
Ref<ResultPoint> getBlackPointOnSegment(int aX, int aY, int bX, int bY);
std::vector<Ref<ResultPoint> > centerEdges(Ref<ResultPoint> y, Ref<ResultPoint> z,
Ref<ResultPoint> x, Ref<ResultPoint> t);
bool containsBlackPoint(int a, int b, int fixed, bool horizontal);

View file

@ -28,13 +28,16 @@ using zxing::GenericGFPoly;
using zxing::ArrayRef;
using zxing::Ref;
// VC++
using zxing::GenericGF;
GenericGFPoly::GenericGFPoly(Ref<GenericGF> field,
ArrayRef<int> coefficients)
: field_(field) {
if (coefficients.size() == 0) {
if (coefficients->size() == 0) {
throw IllegalArgumentException("need coefficients");
}
int coefficientsLength = coefficients.size();
int coefficientsLength = coefficients->size();
if (coefficientsLength > 1 && coefficients[0] == 0) {
// Leading term must be non-zero for anything except the constant polynomial "0"
int firstNonZero = 1;
@ -45,7 +48,7 @@ GenericGFPoly::GenericGFPoly(Ref<GenericGF> field,
coefficients_ = field->getZero()->getCoefficients();
} else {
coefficients_ = ArrayRef<int>(new Array<int>(coefficientsLength-firstNonZero));
for (int i = 0; i < (int)coefficients_.size(); i++) {
for (int i = 0; i < (int)coefficients_->size(); i++) {
coefficients_[i] = coefficients[i + firstNonZero];
}
}
@ -59,7 +62,7 @@ ArrayRef<int> GenericGFPoly::getCoefficients() {
}
int GenericGFPoly::getDegree() {
return coefficients_.size() - 1;
return coefficients_->size() - 1;
}
bool GenericGFPoly::isZero() {
@ -67,7 +70,7 @@ bool GenericGFPoly::isZero() {
}
int GenericGFPoly::getCoefficient(int degree) {
return coefficients_[coefficients_.size() - 1 - degree];
return coefficients_[coefficients_->size() - 1 - degree];
}
int GenericGFPoly::evaluateAt(int a) {
@ -76,7 +79,7 @@ int GenericGFPoly::evaluateAt(int a) {
return getCoefficient(0);
}
int size = coefficients_.size();
int size = coefficients_->size();
if (a == 1) {
// Just the sum of the coefficients
int result = 0;
@ -105,20 +108,20 @@ Ref<GenericGFPoly> GenericGFPoly::addOrSubtract(Ref<zxing::GenericGFPoly> other)
ArrayRef<int> smallerCoefficients = coefficients_;
ArrayRef<int> largerCoefficients = other->getCoefficients();
if (smallerCoefficients.size() > largerCoefficients.size()) {
if (smallerCoefficients->size() > largerCoefficients->size()) {
ArrayRef<int> temp = smallerCoefficients;
smallerCoefficients = largerCoefficients;
largerCoefficients = temp;
}
ArrayRef<int> sumDiff(new Array<int>(largerCoefficients.size()));
int lengthDiff = largerCoefficients.size() - smallerCoefficients.size();
ArrayRef<int> sumDiff(new Array<int>(largerCoefficients->size()));
int lengthDiff = largerCoefficients->size() - smallerCoefficients->size();
// Copy high-order terms only found in higher-degree polynomial's coefficients
for (int i = 0; i < lengthDiff; i++) {
sumDiff[i] = largerCoefficients[i];
}
for (int i = lengthDiff; i < (int)largerCoefficients.size(); i++) {
for (int i = lengthDiff; i < (int)largerCoefficients->size(); i++) {
sumDiff[i] = GenericGF::addOrSubtract(smallerCoefficients[i-lengthDiff],
largerCoefficients[i]);
}
@ -136,10 +139,10 @@ Ref<GenericGFPoly> GenericGFPoly::multiply(Ref<zxing::GenericGFPoly> other) {
}
ArrayRef<int> aCoefficients = coefficients_;
int aLength = aCoefficients.size();
int aLength = aCoefficients->size();
ArrayRef<int> bCoefficients = other->getCoefficients();
int bLength = bCoefficients.size();
int bLength = bCoefficients->size();
ArrayRef<int> product(new Array<int>(aLength + bLength - 1));
for (int i = 0; i < aLength; i++) {
@ -160,7 +163,7 @@ Ref<GenericGFPoly> GenericGFPoly::multiply(int scalar) {
if (scalar == 1) {
return Ref<GenericGFPoly>(this);
}
int size = coefficients_.size();
int size = coefficients_->size();
ArrayRef<int> product(new Array<int>(size));
for (int i = 0; i < size; i++) {
product[i] = field_->multiply(coefficients_[i], scalar);
@ -175,7 +178,7 @@ Ref<GenericGFPoly> GenericGFPoly::multiplyByMonomial(int degree, int coefficient
if (coefficient == 0) {
return field_->getZero();
}
int size = coefficients_.size();
int size = coefficients_->size();
ArrayRef<int> product(new Array<int>(size+degree));
for (int i = 0; i < size; i++) {
product[i] = field_->multiply(coefficients_[i], coefficient);

View file

@ -1,8 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* ReedSolomonDecoder.cpp
* zxing
*
* Created by Christian Brunschen on 05/05/2008.
* Copyright 2008 Google UK. All rights reserved.
*
@ -33,6 +30,9 @@ using zxing::ArrayRef;
using zxing::ReedSolomonDecoder;
using zxing::GenericGFPoly;
// VC++
using zxing::GenericGF;
ReedSolomonDecoder::ReedSolomonDecoder(Ref<GenericGF> field_) : field(field_) {}
ReedSolomonDecoder::~ReedSolomonDecoder() {
@ -147,7 +147,7 @@ ArrayRef<int> ReedSolomonDecoder::findErrorLocations(Ref<GenericGFPoly> errorLoc
ArrayRef<int> ReedSolomonDecoder::findErrorMagnitudes(Ref<GenericGFPoly> errorEvaluator, ArrayRef<int> errorLocations) {
// This is directly applying Forney's Formula
int s = errorLocations.size();
int s = errorLocations->size();
ArrayRef<int> result(new Array<int>(s));
for (int i = 0; i < s; i++) {
int xiInverse = field->inverse(errorLocations[i]);

View file

@ -66,10 +66,10 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
// All blocks have the same amount of data, except that the last n
// (where n may be 0) have 1 more byte. Figure out where these start.
int shorterBlocksTotalCodewords = result[0]->codewords_.size();
int shorterBlocksTotalCodewords = result[0]->codewords_->size();
int longerBlocksStartAt = result.size() - 1;
while (longerBlocksStartAt >= 0) {
int numCodewords = result[longerBlocksStartAt]->codewords_.size();
int numCodewords = result[longerBlocksStartAt]->codewords_->size();
if (numCodewords == shorterBlocksTotalCodewords) {
break;
}
@ -94,7 +94,7 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
result[j]->codewords_[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
}
// Now add in error correction blocks
int max = result[0]->codewords_.size();
int max = result[0]->codewords_->size();
for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
for (int j = 0; j < numResultBlocks; j++) {
int iOffset = j < longerBlocksStartAt ? i : i + 1;
@ -102,7 +102,7 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
}
}
if (rawCodewordsOffset != rawCodewords.size()) {
if (rawCodewordsOffset != rawCodewords->size()) {
throw IllegalArgumentException("rawCodewordsOffset != rawCodewords.length");
}

View file

@ -31,6 +31,10 @@ using zxing::Ref;
using zxing::DecoderResult;
using zxing::datamatrix::Decoder;
// VC++
using zxing::ArrayRef;
using zxing::BitMatrix;
Decoder::Decoder() : rsDecoder_(GenericGF::DATA_MATRIX_FIELD_256) {}
void Decoder::correctErrors(ArrayRef<char> codewordBytes, int numDataCodewords) {
@ -43,6 +47,7 @@ void Decoder::correctErrors(ArrayRef<char> codewordBytes, int numDataCodewords)
try {
rsDecoder_.decode(codewordInts, numECCodewords);
} catch (ReedSolomonException const& ignored) {
(void)ignored;
throw ChecksumException();
}
// Copy back into array of bytes -- only need to worry about the bytes that were data

View file

@ -23,7 +23,7 @@
#include <zxing/ResultPoint.h>
#include <zxing/common/GridSampler.h>
#include <zxing/datamatrix/detector/Detector.h>
#include <zxing/common/detector/math_utils.h>
#include <zxing/common/detector/MathUtils.h>
#include <zxing/NotFoundException.h>
#include <sstream>
#include <cstdlib>

View file

@ -1,172 +0,0 @@
/*
* MonochromeRectangleDetector.cpp
* zxing
*
* Created by Luiz Silva on 09/02/2010.
* 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>
#include <zxing/datamatrix/detector/MonochromeRectangleDetector.h>
#include <sstream>
namespace zxing {
namespace datamatrix {
std::vector<Ref<CornerPoint> > MonochromeRectangleDetector::detect() {
int height = image_->getHeight();
int width = image_->getWidth();
int halfHeight = height >> 1;
int halfWidth = width >> 1;
int deltaY = max(1, height / (MAX_MODULES << 3));
int deltaX = max(1, width / (MAX_MODULES << 3));
int top = 0;
int bottom = height;
int left = 0;
int right = width;
Ref<CornerPoint> pointA(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 1));
top = (int) pointA->getY() - 1;
Ref<CornerPoint> pointB(findCornerFromCenter(halfWidth, -deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
left = (int) pointB->getX() - 1;
Ref<CornerPoint> pointC(findCornerFromCenter(halfWidth, deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1));
right = (int) pointC->getX() + 1;
Ref<CornerPoint> pointD(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, deltaY, top, bottom, halfWidth >> 1));
bottom = (int) pointD->getY() + 1;
// Go try to find point A again with better information -- might have been off at first.
pointA.reset(findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 2));
std::vector<Ref<CornerPoint> > corners(4);
corners[0].reset(pointA);
corners[1].reset(pointB);
corners[2].reset(pointC);
corners[3].reset(pointD);
return corners;
}
Ref<CornerPoint> MonochromeRectangleDetector::findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun) {
Ref<TwoInts> lastRange(NULL);
for (int y = centerY, x = centerX;
y < bottom && y >= top && x < right && x >= left;
y += deltaY, x += deltaX) {
Ref<TwoInts> range(NULL);
if (deltaX == 0) {
// horizontal slices, up and down
range = blackWhiteRange(y, maxWhiteRun, left, right, true);
} else {
// vertical slices, left and right
range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
}
if (range == NULL) {
if (lastRange == NULL) {
throw ReaderException("Couldn't find corners (lastRange = NULL) ");
} else {
// lastRange was found
if (deltaX == 0) {
int lastY = y - deltaY;
if (lastRange->start < centerX) {
if (lastRange->end > centerX) {
// straddle, choose one or the other based on direction
Ref<CornerPoint> result(new CornerPoint(deltaY > 0 ? lastRange->start : lastRange->end, lastY));
return result;
}
Ref<CornerPoint> result(new CornerPoint(lastRange->start, lastY));
return result;
} else {
Ref<CornerPoint> result(new CornerPoint(lastRange->end, lastY));
return result;
}
} else {
int lastX = x - deltaX;
if (lastRange->start < centerY) {
if (lastRange->end > centerY) {
Ref<CornerPoint> result(new CornerPoint(lastX, deltaX < 0 ? lastRange->start : lastRange->end));
return result;
}
Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->start));
return result;
} else {
Ref<CornerPoint> result(new CornerPoint(lastX, lastRange->end));
return result;
}
}
}
}
lastRange = range;
}
throw ReaderException("Couldn't find corners");
}
Ref<TwoInts> MonochromeRectangleDetector::blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal) {
int center = (minDim + maxDim) >> 1;
// Scan left/up first
int start = center;
while (start >= minDim) {
if (horizontal ? image_->get(start, fixedDimension) : image_->get(fixedDimension, start)) {
start--;
} else {
int whiteRunStart = start;
do {
start--;
} while (start >= minDim && !(horizontal ? image_->get(start, fixedDimension) :
image_->get(fixedDimension, start)));
int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart;
break;
}
}
}
start++;
// Then try right/down
int end = center;
while (end < maxDim) {
if (horizontal ? image_->get(end, fixedDimension) : image_->get(fixedDimension, end)) {
end++;
} else {
int whiteRunStart = end;
do {
end++;
} while (end < maxDim && !(horizontal ? image_->get(end, fixedDimension) :
image_->get(fixedDimension, end)));
int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart;
break;
}
}
}
end--;
Ref<TwoInts> result(NULL);
if (end > start) {
result = new TwoInts;
result->start = start;
result->end = end;
}
return result;
}
}
}

View file

@ -1,61 +0,0 @@
#ifndef __MONOCHROMERECTANGLEDETECTOR_H__
#define __MONOCHROMERECTANGLEDETECTOR_H__
/*
* MonochromeRectangleDetector.h
* zxing
*
* Created by Luiz Silva on 09/02/2010.
* 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/ReaderException.h>
#include <zxing/ResultPoint.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/common/Counted.h>
#include <zxing/datamatrix/detector/CornerPoint.h>
namespace zxing {
namespace datamatrix {
struct TwoInts: public Counted {
int start;
int end;
};
class MonochromeRectangleDetector : public Counted {
private:
static const int MAX_MODULES = 32;
Ref<BitMatrix> image_;
public:
MonochromeRectangleDetector(Ref<BitMatrix> image) : image_(image) { };
std::vector<Ref<CornerPoint> > detect();
private:
Ref<CornerPoint> findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerY, int deltaY, int top, int bottom, int maxWhiteRun);
Ref<TwoInts> blackWhiteRange(int fixedDimension, int maxWhiteRun, int minDim, int maxDim,
bool horizontal);
int max(int a, float b) { return (float) a > b ? a : (int) b;};
};
}
}
#endif // __MONOCHROMERECTANGLEDETECTOR_H__

View file

@ -37,6 +37,7 @@ Ref<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints)
try {
return delegate_.decode(topLeft, hints);
} catch (ReaderException const& re) {
(void)re;
// continue
}
@ -44,6 +45,7 @@ Ref<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints)
try {
return delegate_.decode(topRight, hints);
} catch (ReaderException const& re) {
(void)re;
// continue
}
@ -51,6 +53,7 @@ Ref<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints)
try {
return delegate_.decode(bottomLeft, hints);
} catch (ReaderException const& re) {
(void)re;
// continue
}
@ -58,6 +61,7 @@ Ref<Result> ByQuadrantReader::decode(Ref<BinaryBitmap> image, DecodeHints hints)
try {
return delegate_.decode(bottomRight, hints);
} catch (ReaderException const& re) {
(void)re;
// continue
}

View file

@ -24,6 +24,11 @@ using zxing::Ref;
using zxing::Result;
using zxing::multi::GenericMultipleBarcodeReader;
// VC++
using zxing::Reader;
using zxing::BinaryBitmap;
using zxing::DecodeHints;
GenericMultipleBarcodeReader::GenericMultipleBarcodeReader(Reader& delegate)
: delegate_(delegate) {}
@ -52,6 +57,7 @@ void GenericMultipleBarcodeReader::doDecodeMultiple(Ref<BinaryBitmap> image,
try {
result = delegate_.decode(image, hints);
} catch (ReaderException const& ignored) {
(void)ignored;
return;
}
bool alreadyFound = false;
@ -73,11 +79,11 @@ void GenericMultipleBarcodeReader::doDecodeMultiple(Ref<BinaryBitmap> image,
int width = image->getWidth();
int height = image->getHeight();
float minX = width;
float minY = height;
float minX = float(width);
float minY = float(height);
float maxX = 0.0f;
float maxY = 0.0f;
for (int i = 0; i < resultPoints.size(); i++) {
for (int i = 0; i < resultPoints->size(); i++) {
Ref<ResultPoint> point = resultPoints[i];
float x = point->getX();
float y = point->getY();
@ -123,7 +129,7 @@ Ref<Result> GenericMultipleBarcodeReader::translateResultPoints(Ref<Result> resu
return result;
}
ArrayRef< Ref<ResultPoint> > newResultPoints;
for (int i = 0; i < oldResultPoints.size(); i++) {
for (int i = 0; i < oldResultPoints->size(); i++) {
Ref<ResultPoint> oldPoint = oldResultPoints[i];
newResultPoints->values().push_back(Ref<ResultPoint>(new ResultPoint(oldPoint->getX() + xOffset, oldPoint->getY() + yOffset)));
}

View file

@ -44,7 +44,8 @@ std::vector<Ref<Result> > QRCodeMultiReader::decodeMultiple(Ref<BinaryBitmap> im
// result->putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult->getECLevel().toString());
results.push_back(result);
} catch (ReaderException const& re) {
// ignore and continue
(void)re;
// ignore and continue
}
}
if (results.empty()){

View file

@ -35,6 +35,7 @@ std::vector<Ref<DetectorResult> > MultiDetector::detectMulti(DecodeHints hints){
try{
result.push_back(processFinderPatternInfo(info[i]));
} catch (ReaderException const& e){
(void)e;
// ignore
}
}

View file

@ -24,7 +24,6 @@
#include <zxing/FormatException.h>
#include <zxing/ChecksumException.h>
#include <math.h>
#include <string.h>
#include <sstream>
using std::vector;
@ -36,6 +35,9 @@ using zxing::Ref;
using zxing::Result;
using zxing::oned::CodaBarReader;
// VC++
using zxing::BitArray;
namespace {
char const ALPHABET_STRING[] = "0123456789-$:/.+ABCD";
char const* const ALPHABET = ALPHABET_STRING;
@ -281,7 +283,7 @@ int CodaBarReader::findStartPattern() {
}
bool CodaBarReader::arrayContains(char const array[], char key) {
return index(array, key) != 0;
return strchr(array, key) != 0;
}

View file

@ -36,6 +36,9 @@ using zxing::Ref;
using zxing::Result;
using zxing::oned::Code128Reader;
// VC++
using zxing::BitArray;
const int Code128Reader::MAX_AVG_VARIANCE = int(PATTERN_MATCH_RESULT_SCALE_FACTOR * 250/1000);
const int Code128Reader::MAX_INDIVIDUAL_VARIANCE = int(PATTERN_MATCH_RESULT_SCALE_FACTOR * 700/1000);

View file

@ -32,6 +32,9 @@ using zxing::NotFoundException;
using zxing::ChecksumException;
using zxing::oned::Code39Reader;
// VC++
using zxing::BitArray;
namespace {
const char* ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";

View file

@ -34,6 +34,9 @@ using zxing::NotFoundException;
using zxing::ChecksumException;
using zxing::oned::Code93Reader;
// VC++
using zxing::BitArray;
namespace {
char const ALPHABET[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";

View file

@ -21,7 +21,11 @@
using std::vector;
using zxing::oned::EAN8Reader;
EAN8Reader::EAN8Reader() : decodeMiddleCounters(4, 0) { }
// VC++
using zxing::Ref;
using zxing::BitArray;
EAN8Reader::EAN8Reader() : decodeMiddleCounters(4, 0) {}
int EAN8Reader::decodeMiddle(Ref<BitArray> row,
Range const& startRange,

View file

@ -33,6 +33,9 @@ using zxing::FormatException;
using zxing::NotFoundException;
using zxing::oned::ITFReader;
// VC++
using zxing::BitArray;
#define VECTOR_INIT(v) v, v + sizeof(v)/sizeof(v[0])
namespace {
@ -114,9 +117,10 @@ Ref<Result> ITFReader::decodeRow(int rowNumber, Ref<BitArray> row) {
}
ArrayRef< Ref<ResultPoint> > resultPoints(2);
resultPoints[0] = Ref<OneDResultPoint>(new OneDResultPoint(startRange[1], (float) rowNumber));
resultPoints[1] = Ref<OneDResultPoint>(new OneDResultPoint(endRange[0], (float) rowNumber));
resultPoints[0] =
Ref<OneDResultPoint>(new OneDResultPoint(float(startRange[1]), float(rowNumber)));
resultPoints[1] =
Ref<OneDResultPoint>(new OneDResultPoint(float(endRange[0]), float(rowNumber)));
return Ref<Result>(new Result(resultString, ArrayRef<char>(), resultPoints, BarcodeFormat::ITF));
}

View file

@ -1,8 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* MultiFormatOneDReader.cpp
* ZXing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -33,6 +30,10 @@ using zxing::Ref;
using zxing::Result;
using zxing::oned::MultiFormatOneDReader;
// VC++
using zxing::DecodeHints;
using zxing::BitArray;
MultiFormatOneDReader::MultiFormatOneDReader(DecodeHints hints) : readers() {
if (hints.containsFormat(BarcodeFormat::EAN_13) ||
hints.containsFormat(BarcodeFormat::EAN_8) ||
@ -87,6 +88,7 @@ Ref<Result> MultiFormatOneDReader::decodeRow(int rowNumber, Ref<BitArray> row) {
Ref<Result> result = reader->decodeRow(rowNumber, row);
return result;
} catch (ReaderException const& re) {
(void)re;
// continue
}
}

View file

@ -35,6 +35,10 @@ using zxing::Ref;
using zxing::Result;
using zxing::oned::MultiFormatUPCEANReader;
// VC++
using zxing::DecodeHints;
using zxing::BitArray;
MultiFormatUPCEANReader::MultiFormatUPCEANReader(DecodeHints hints) : readers() {
if (hints.containsFormat(BarcodeFormat::EAN_13)) {
readers.push_back(Ref<UPCEANReader>(new EAN13Reader()));
@ -66,6 +70,7 @@ Ref<Result> MultiFormatUPCEANReader::decodeRow(int rowNumber, Ref<BitArray> row)
try {
result = reader->decodeRow(rowNumber, row, startGuardPattern);
} catch (ReaderException const& ignored) {
(void)ignored;
continue;
}

View file

@ -1,8 +1,5 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* OneDReader.cpp
* ZXing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -32,6 +29,11 @@ using zxing::Result;
using zxing::NotFoundException;
using zxing::oned::OneDReader;
// VC++
using zxing::BinaryBitmap;
using zxing::BitArray;
using zxing::DecodeHints;
OneDReader::OneDReader() {}
Ref<Result> OneDReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
@ -49,7 +51,7 @@ Ref<Result> OneDReader::decode(Ref<BinaryBitmap> image, DecodeHints hints) {
ArrayRef< Ref<ResultPoint> >& points (result->getResultPoints());
if (points && !points->empty()) {
int height = rotatedImage->getHeight();
for (int i = 0; i < points.size(); i++) {
for (int i = 0; i < points->size(); i++) {
points[i].reset(new OneDResultPoint(height - points[i]->getY() - 1, points[i]->getX()));
}
}
@ -106,6 +108,7 @@ Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints) {
try {
row = image->getBlackRow(rowNumber, row);
} catch (NotFoundException const& ignored) {
(void)ignored;
continue;
}
@ -138,6 +141,7 @@ Ref<Result> OneDReader::doDecode(Ref<BinaryBitmap> image, DecodeHints hints) {
}
return result;
} catch (ReaderException const& re) {
(void)re;
continue;
}
}

View file

@ -25,8 +25,12 @@ using zxing::oned::UPCAReader;
using zxing::Ref;
using zxing::Result;
UPCAReader::UPCAReader() : ean13Reader() {
}
// VC++
using zxing::BitArray;
using zxing::BinaryBitmap;
using zxing::DecodeHints;
UPCAReader::UPCAReader() : ean13Reader() {}
Ref<Result> UPCAReader::decodeRow(int rowNumber, Ref<BitArray> row) {
return maybeReturnResult(ean13Reader.decodeRow(rowNumber, row));

View file

@ -25,12 +25,18 @@
#include <zxing/NotFoundException.h>
#include <zxing/ChecksumException.h>
using std::vector;
using std::string;
using zxing::Ref;
using zxing::Result;
using zxing::NotFoundException;
using zxing::ChecksumException;
using zxing::oned::UPCEANReader;
using namespace std; // remove
// VC++
using zxing::BitArray;
using zxing::String;
#define LEN(v) ((int)(sizeof(v)/sizeof(v[0])))

View file

@ -25,6 +25,9 @@ using zxing::Ref;
using zxing::String;
using zxing::oned::UPCEReader;
// VC++
using zxing::BitArray;
#define VECTOR_INIT(v) v, v + sizeof(v)/sizeof(v[0])
namespace {

View file

@ -102,6 +102,7 @@ Version *Version::getProvisionalVersionForDimension(int dimension) {
try {
return Version::getVersionForNumber((dimension - 17) >> 2);
} catch (IllegalArgumentException const& ignored) {
(void)ignored;
throw FormatException();
}
}

View file

@ -71,10 +71,10 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
// All blocks have the same amount of data, except that the last n
// (where n may be 0) have 1 more byte. Figure out where these start.
int shorterBlocksTotalCodewords = result[0]->codewords_.size();
int shorterBlocksTotalCodewords = result[0]->codewords_->size();
int longerBlocksStartAt = result.size() - 1;
while (longerBlocksStartAt >= 0) {
int numCodewords = result[longerBlocksStartAt]->codewords_.size();
int numCodewords = result[longerBlocksStartAt]->codewords_->size();
if (numCodewords == shorterBlocksTotalCodewords) {
break;
}
@ -99,7 +99,7 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
result[j]->codewords_[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
}
// Now add in error correction blocks
int max = result[0]->codewords_.size();
int max = result[0]->codewords_->size();
for (int i = shorterBlocksNumDataCodewords; i < max; i++) {
for (int j = 0; j < numResultBlocks; j++) {
int iOffset = j < longerBlocksStartAt ? i : i + 1;
@ -107,7 +107,7 @@ std::vector<Ref<DataBlock> > DataBlock::getDataBlocks(ArrayRef<char> rawCodeword
}
}
if (rawCodewordsOffset != rawCodewords.size()) {
if (rawCodewordsOffset != rawCodewords->size()) {
throw IllegalArgumentException("rawCodewordsOffset != rawCodewords.length");
}

View file

@ -134,6 +134,7 @@ void DecodedBitStreamParser::decodeHanziSegment(Ref<BitSource> bits_,
try {
append(result, buffer, nBytes, StringUtils::GB2312);
} catch (ReaderException const& ignored) {
(void)ignored;
delete [] buffer;
throw FormatException();
}
@ -167,6 +168,7 @@ void DecodedBitStreamParser::decodeKanjiSegment(Ref<BitSource> bits, std::string
try {
append(result, buffer, nBytes, StringUtils::SHIFT_JIS);
} catch (ReaderException const& ignored) {
(void)ignored;
delete [] buffer;
throw FormatException();
}
@ -205,6 +207,7 @@ void DecodedBitStreamParser::decodeByteSegment(Ref<BitSource> bits_,
try {
append(result, readBytes, nBytes, encoding.c_str());
} catch (ReaderException const& ignored) {
(void)ignored;
throw FormatException();
}
byteSegments->values().push_back(bytes_);
@ -412,6 +415,7 @@ DecodedBitStreamParser::decode(ArrayRef<char> bytes,
}
} while (mode != &Mode::TERMINATOR);
} catch (IllegalArgumentException const& iae) {
(void)iae;
// from readBits() calls
throw FormatException();
}

View file

@ -33,6 +33,10 @@ using zxing::qrcode::Decoder;
using zxing::DecoderResult;
using zxing::Ref;
// VC++
using zxing::ArrayRef;
using zxing::BitMatrix;
Decoder::Decoder() :
rsDecoder_(GenericGF::QR_CODE_FIELD_256) {
}
@ -48,6 +52,7 @@ void Decoder::correctErrors(ArrayRef<char> codewordBytes, int numDataCodewords)
try {
rsDecoder_.decode(codewordInts, numECCodewords);
} catch (ReedSolomonException const& ignored) {
(void)ignored;
throw ChecksumException();
}

View file

@ -29,6 +29,9 @@
using zxing::qrcode::Mode;
using std::ostringstream;
// VC++
using zxing::qrcode::Version;
Mode Mode::TERMINATOR(0, 0, 0, 0x00, "TERMINATOR");
Mode Mode::NUMERIC(10, 12, 14, 0x01, "NUMERIC");
Mode Mode::ALPHANUMERIC(9, 11, 13, 0x02, "ALPHANUMERIC");

View file

@ -37,7 +37,7 @@ float AlignmentPatternFinder::centerFromEnd(vector<int> &stateCount, int end) {
bool AlignmentPatternFinder::foundPatternCross(vector<int> &stateCount) {
float maxVariance = moduleSize_ / 2.0f;
for (size_t i = 0; i < 3; i++) {
for (int i = 0; i < 3; i++) {
if (abs(moduleSize_ - stateCount[i]) >= maxVariance) {
return false;
}
@ -45,7 +45,7 @@ bool AlignmentPatternFinder::foundPatternCross(vector<int> &stateCount) {
return true;
}
float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount,
float AlignmentPatternFinder::crossCheckVertical(int startI, int centerJ, int maxCount,
int originalStateCountTotal) {
int maxI = image_->getHeight();
vector<int> stateCount(3, 0);
@ -59,14 +59,14 @@ float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ,
}
// If already too many modules in this state or ran off the edge:
if (i < 0 || stateCount[1] > maxCount) {
return NAN;
return nan();
}
while (i >= 0 && !image_->get(centerJ, i) && stateCount[0] <= maxCount) {
stateCount[0]++;
i--;
}
if (stateCount[0] > maxCount) {
return NAN;
return nan();
}
// Now also count down from center
@ -76,25 +76,25 @@ float AlignmentPatternFinder::crossCheckVertical(size_t startI, size_t centerJ,
i++;
}
if (i == maxI || stateCount[1] > maxCount) {
return NAN;
return nan();
}
while (i < maxI && !image_->get(centerJ, i) && stateCount[2] <= maxCount) {
stateCount[2]++;
i++;
}
if (stateCount[2] > maxCount) {
return NAN;
return nan();
}
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
return NAN;
return nan();
}
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : nan();
}
Ref<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(vector<int> &stateCount, size_t i, size_t j) {
Ref<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(vector<int> &stateCount, int i, int j) {
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
float centerJ = centerFromEnd(stateCount, j);
float centerI = crossCheckVertical(i, (int)centerJ, 2 * stateCount[1], stateCountTotal);
@ -120,15 +120,15 @@ Ref<AlignmentPattern> AlignmentPatternFinder::handlePossibleCenter(vector<int> &
return result;
}
AlignmentPatternFinder::AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width,
size_t height, float moduleSize,
AlignmentPatternFinder::AlignmentPatternFinder(Ref<BitMatrix> image, int startX, int startY, int width,
int height, float moduleSize,
Ref<ResultPointCallback>const& callback) :
image_(image), possibleCenters_(new vector<AlignmentPattern *> ()), startX_(startX), startY_(startY),
width_(width), height_(height), moduleSize_(moduleSize), callback_(callback) {
}
AlignmentPatternFinder::~AlignmentPatternFinder() {
for (size_t i = 0; i < possibleCenters_->size(); i++) {
for (int i = 0; i < int(possibleCenters_->size()); i++) {
(*possibleCenters_)[i]->release();
(*possibleCenters_)[i] = 0;
}
@ -136,20 +136,20 @@ AlignmentPatternFinder::~AlignmentPatternFinder() {
}
Ref<AlignmentPattern> AlignmentPatternFinder::find() {
size_t maxJ = startX_ + width_;
size_t middleI = startY_ + (height_ >> 1);
int maxJ = startX_ + width_;
int middleI = startY_ + (height_ >> 1);
// Ref<BitArray> luminanceRow(new BitArray(width_));
// We are looking for black/white/black modules in 1:1:1 ratio;
// this tracks the number of black/white/black modules seen so far
vector<int> stateCount(3, 0);
for (size_t iGen = 0; iGen < height_; iGen++) {
for (int iGen = 0; iGen < height_; iGen++) {
// Search from middle outwards
size_t i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
int i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
// image_->getBlackRow(i, luminanceRow, startX_, width_);
stateCount[0] = 0;
stateCount[1] = 0;
stateCount[2] = 0;
size_t j = startX_;
int j = startX_;
// Burn off leading white pixels before anything else; if we start in the middle of
// a white run, it doesn't make sense to count its length, since we don't know if the
// white run continued to the left of the start point

View file

@ -37,21 +37,21 @@ private:
Ref<BitMatrix> image_;
std::vector<AlignmentPattern *> *possibleCenters_;
size_t startX_;
size_t startY_;
size_t width_;
size_t height_;
int startX_;
int startY_;
int width_;
int height_;
float moduleSize_;
static float centerFromEnd(std::vector<int> &stateCount, int end);
bool foundPatternCross(std::vector<int> &stateCount);
float crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal);
float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal);
Ref<AlignmentPattern> handlePossibleCenter(std::vector<int> &stateCount, size_t i, size_t j);
Ref<AlignmentPattern> handlePossibleCenter(std::vector<int> &stateCount, int i, int j);
public:
AlignmentPatternFinder(Ref<BitMatrix> image, size_t startX, size_t startY, size_t width, size_t height,
AlignmentPatternFinder(Ref<BitMatrix> image, int startX, int startY, int width, int height,
float moduleSize, Ref<ResultPointCallback>const& callback);
~AlignmentPatternFinder();
Ref<AlignmentPattern> find();

View file

@ -27,7 +27,7 @@
#include <zxing/qrcode/Version.h>
#include <zxing/common/GridSampler.h>
#include <zxing/DecodeHints.h>
#include <zxing/common/detector/math_utils.h>
#include <zxing/common/detector/MathUtils.h>
#include <sstream>
#include <cstdlib>
@ -36,7 +36,7 @@ namespace math_utils = zxing::common::detector::math_utils;
using std::ostringstream;
using std::min;
using std::max;
using std::isnan;
using zxing::isnan;
using zxing::qrcode::Detector;
using zxing::Ref;
using zxing::BitMatrix;
@ -45,6 +45,12 @@ using zxing::DetectorResult;
using zxing::PerspectiveTransform;
using zxing::qrcode::AlignmentPattern;
// VC++
using zxing::DecodeHints;
using zxing::qrcode::FinderPatternFinder;
using zxing::qrcode::FinderPatternInfo;
using zxing::ResultPoint;
Detector::Detector(Ref<BitMatrix> image) :
image_(image) {
}
@ -100,6 +106,7 @@ Ref<DetectorResult> Detector::processFinderPatternInfo(Ref<FinderPatternInfo> in
alignmentPattern = findAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (float)i);
break;
} catch (zxing::ReaderException const& re) {
(void)re;
// try next round
}
}
@ -283,7 +290,7 @@ float Detector::sizeOfBlackWhiteBlackRun(int fromX, int fromY, int toX, int toY)
return math_utils::distance(toX + xstep, toY, fromX, fromY);
}
// else we didn't find even black-white-black; no estimate is really possible
return NAN;
return nan();
}
Ref<AlignmentPattern> Detector::findAlignmentInRegion(float overallEstModuleSize, int estAlignmentX, int estAlignmentY,

View file

@ -106,7 +106,7 @@ float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int
i--;
}
if (i < 0) {
return NAN;
return nan();
}
while (i >= 0 && !image_->get(centerJ, i) && stateCount[1] <= maxCount) {
stateCount[1]++;
@ -114,14 +114,14 @@ float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int
}
// If already too many modules in this state or ran off the edge:
if (i < 0 || stateCount[1] > maxCount) {
return NAN;
return nan();
}
while (i >= 0 && image_->get(centerJ, i) && stateCount[0] <= maxCount) {
stateCount[0]++;
i--;
}
if (stateCount[0] > maxCount) {
return NAN;
return nan();
}
// Now also count down from center
@ -131,31 +131,31 @@ float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int
i++;
}
if (i == maxI) {
return NAN;
return nan();
}
while (i < maxI && !image_->get(centerJ, i) && stateCount[3] < maxCount) {
stateCount[3]++;
i++;
}
if (i == maxI || stateCount[3] >= maxCount) {
return NAN;
return nan();
}
while (i < maxI && image_->get(centerJ, i) && stateCount[4] < maxCount) {
stateCount[4]++;
i++;
}
if (stateCount[4] >= maxCount) {
return NAN;
return nan();
}
// If we found a finder-pattern-like section, but its size is more than 40% different than
// the original, assume it's a false positive
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
if (5 * abs(stateCountTotal - originalStateCountTotal) >= 2 * originalStateCountTotal) {
return NAN;
return nan();
}
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : NAN;
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : nan();
}
float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, int maxCount,
@ -172,21 +172,21 @@ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, i
j--;
}
if (j < 0) {
return NAN;
return nan();
}
while (j >= 0 && !image_->get(j, centerI) && stateCount[1] <= maxCount) {
stateCount[1]++;
j--;
}
if (j < 0 || stateCount[1] > maxCount) {
return NAN;
return nan();
}
while (j >= 0 && image_->get(j, centerI) && stateCount[0] <= maxCount) {
stateCount[0]++;
j--;
}
if (stateCount[0] > maxCount) {
return NAN;
return nan();
}
j = startJ + 1;
@ -195,31 +195,31 @@ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, i
j++;
}
if (j == maxJ) {
return NAN;
return nan();
}
while (j < maxJ && !image_->get(j, centerI) && stateCount[3] < maxCount) {
stateCount[3]++;
j++;
}
if (j == maxJ || stateCount[3] >= maxCount) {
return NAN;
return nan();
}
while (j < maxJ && image_->get(j, centerI) && stateCount[4] < maxCount) {
stateCount[4]++;
j++;
}
if (stateCount[4] >= maxCount) {
return NAN;
return nan();
}
// If we found a finder-pattern-like section, but its size is significantly different than
// the original, assume it's a false positive
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
if (5 * abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
return NAN;
return nan();
}
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : NAN;
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : nan();
}
bool FinderPatternFinder::handlePossibleCenter(int* stateCount, size_t i, size_t j) {

View file

@ -1,168 +0,0 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Created by Ralf Kistner on 7/12/2009.
* 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/qrcode/detector/QREdgeDetector.h>
#include <zxing/common/EdgeDetector.h>
#include <cstdlib>
using namespace std;
namespace zxing {
namespace qrcode {
static const float patternEdgeThreshold = 2;
static const int patternEdgeWidth = 3;
static const float patternEdgeSearchRatio = 1.1;
static const int patternEdgeSkip = 2;
static const float accurateEdgeThreshold = 3.3;
static const int accurateEdgeWidth = 7;
static const int accurateEdgeSkip = 2;
static Point guessLastPattern(Point topLeft, Point topRight, Point bottomLeft) {
return Point(topRight.x - topLeft.x + bottomLeft.x, topRight.y - topLeft.y + bottomLeft.y);
}
static Point rp(Ref<ResultPoint> rp) {
return Point(rp->getX(), rp->getY());
}
QREdgeDetector::QREdgeDetector(Ref<BitMatrix> image) : Detector(image) { }
Ref<PerspectiveTransform> QREdgeDetector::createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension) {
if(alignmentPattern == NULL) {
Point corner = findCorner(*Detector::getImage(), rp(topLeft), rp(topRight), rp(bottomLeft), dimension);
return get1CornerTransform(rp(topLeft), rp(topRight), rp(bottomLeft), corner, dimension);
} else {
return Detector::createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);
}
}
Point QREdgeDetector::findCorner(const BitMatrix& image, Point topLeft, Point topRight, Point bottomLeft, int dimension) {
(void)dimension;
Point bottomRight = guessLastPattern(topLeft, topRight, bottomLeft);
Line bottomEst = findPatternEdge(image, bottomLeft, topLeft, bottomRight, false);
Line rightEst = findPatternEdge(image, topRight, topLeft, bottomRight, true);
//return EdgeDetector::intersection(bottomEst, rightEst);
Line bottom = EdgeDetector::findLine(image, bottomEst, false, accurateEdgeWidth, accurateEdgeThreshold, accurateEdgeSkip);
Line right = EdgeDetector::findLine(image, rightEst, true, accurateEdgeWidth, accurateEdgeThreshold, accurateEdgeSkip);
return EdgeDetector::intersection(bottom, right);
}
Line QREdgeDetector::findPatternEdge(const BitMatrix& image, Point pattern, Point opposite, Point direction, bool invert) {
Point start = endOfReverseBlackWhiteBlackRun(image, pattern, opposite);
float dx = pattern.x - start.x;
float dy = pattern.y - start.y;
float dist = sqrt(dx*dx + dy*dy);
float dirX = direction.x - pattern.x;
float dirY = direction.y - pattern.y;
float dirSize = sqrt(dirX*dirX + dirY*dirY);
float nx = dirX/dirSize;
float ny = dirY/dirSize;
float search = dist * patternEdgeSearchRatio;
Point a(start.x + nx*search, start.y + ny*search);
Point b(start.x - nx*search, start.y - ny*search);
return EdgeDetector::findLine(image, Line(a, b), invert, patternEdgeWidth, patternEdgeThreshold, patternEdgeSkip);
}
Ref<PerspectiveTransform> QREdgeDetector::get1CornerTransform(Point topLeft, Point topRight, Point bottomLeft, Point corner, int dimension) {
float dimMinusThree = (float) dimension - 3.5f;
Ref<PerspectiveTransform> transform(PerspectiveTransform::quadrilateralToQuadrilateral(3.5f, 3.5f, dimMinusThree, 3.5f, dimension,
dimension, 3.5f, dimMinusThree, topLeft.x, topLeft.y, topRight.x,
topRight.y, corner.x, corner.y, bottomLeft.x, bottomLeft.y));
return transform;
}
// Adapted from "sizeOfBlackWhiteBlackRun" in zxing::qrcode::Detector
Point QREdgeDetector::endOfReverseBlackWhiteBlackRun(const BitMatrix& image, Point from, Point to) {
int fromX = (int)from.x;
int fromY = (int)from.y;
int toX = (int)to.x;
int toY = (int)to.y;
bool steep = abs(toY - fromY) > abs(toX - fromX);
if (steep) {
int temp = fromX;
fromX = fromY;
fromY = temp;
temp = toX;
toX = toY;
toY = temp;
}
int dx = abs(toX - fromX);
int dy = abs(toY - fromY);
int error = -dx >> 1;
int ystep = fromY < toY ? -1 : 1;
int xstep = fromX < toX ? -1 : 1;
int state = 0; // In black pixels, looking for white, first or second time
// In case there are no points, prepopulate to from
int realX = fromX;
int realY = fromY;
for (int x = fromX, y = fromY; x != toX; x += xstep) {
realX = steep ? y : x;
realY = steep ? x : y;
if(realX < 0 || realY < 0 || realX >= (int)image.getWidth() || realY >= (int)image.getHeight())
break;
if (state == 1) { // In white pixels, looking for black
if (image.get(realX, realY)) {
state++;
}
} else {
if (!image.get(realX, realY)) {
state++;
}
}
if (state == 3) { // Found black, white, black, and stumbled back onto white; done
return Point(realX, realY);
}
error += dy;
if (error > 0) {
y += ystep;
error -= dx;
}
}
// B-W-B run not found, return the last point visited.
return Point(realX, realY);
}
} // namespace qrcode
} // namespace zxing

View file

@ -1,48 +0,0 @@
#ifndef __QREDGEDETECTOR_H__
#define __QREDGEDETECTOR_H__
/*
* QREdgeDetector.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/qrcode/detector/Detector.h>
#include <zxing/common/Point.h>
namespace zxing {
namespace qrcode {
class QREdgeDetector : public Detector {
public:
QREdgeDetector(Ref<BitMatrix> image);
virtual Ref<PerspectiveTransform> createTransform(Ref<ResultPoint> topLeft, Ref<ResultPoint> topRight, Ref <
ResultPoint > bottomLeft, Ref<ResultPoint> alignmentPattern, int dimension);
private:
Point findCorner(const BitMatrix& image, Point topLeft, Point topRight, Point bottomLeft, int dimension);
Line findPatternEdge(const BitMatrix& image, Point pattern, Point opposite, Point direction, bool invert);
Point endOfReverseBlackWhiteBlackRun(const BitMatrix& image, Point from, Point to);
Ref<PerspectiveTransform> get1CornerTransform(Point topLeft, Point topRight, Point bottomLeft, Point corner, int dimension);
};
}
}
#endif // QREDGEDETECTOR_H_

View file

@ -1,98 +0,0 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Copyright 2010-2011 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 "MagickBitmapSource.h"
#include <iostream>
using namespace Magick;
using zxing::ArrayRef;
using zxing::Ref;
using zxing::LuminanceSource;
using zxing::MagickBitmapSource;
MagickBitmapSource::MagickBitmapSource(Image& image)
: Super(image.columns(), image.rows()), image_(image) {}
MagickBitmapSource::~MagickBitmapSource() {
}
ArrayRef<char> MagickBitmapSource::getRow(int y, ArrayRef<char> row) const {
const int width = getWidth();
const Magick::PixelPacket* pixel_cache =
image_.getConstPixels(0, y, width, 1);
if (!row || row->size() < width) {
row =ArrayRef<char>(width);
}
for (int x = 0; x < width; x++) {
const PixelPacket* p = pixel_cache + x;
// We assume 16 bit values here
// 0x200 = 1<<9, half an lsb of the result to force rounding
row[x] = (char)((306 * ((int)p->red >> 8) + 601 * ((int)p->green >> 8) +
117 * ((int)p->blue >> 8) + 0x200) >> 10);
}
return row;
}
/** This is a more efficient implementation. */
ArrayRef<char> MagickBitmapSource::getMatrix() const {
const int width = getWidth();
const int height = getHeight();
const Magick::PixelPacket* pixel_cache = image_.getConstPixels(0, 0, width, height);
ArrayRef<char> matrix = ArrayRef<char>(width*height);
char* m = &matrix[0];
const Magick::PixelPacket* p = pixel_cache;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
*m = (unsigned char)((306 * ((int)p->red >> 8) + 601 * ((int)p->green >> 8) +
117 * ((int)p->blue >> 8) + 0x200) >> 10);
m++;
p++;
}
}
return matrix;
}
bool MagickBitmapSource::isRotateSupported() const {
return true;
}
Ref<LuminanceSource> MagickBitmapSource::rotateCounterClockwise() {
Magick::Image rotated(image_);
rotated.modifyImage();
rotated.rotate(90); // Image::rotate takes CCW degrees as an argument
rotated.syncPixels();
return Ref<MagickBitmapSource> (new MagickBitmapSource(rotated));
}
bool MagickBitmapSource::isCropSupported() const{
return true;
}
Ref<LuminanceSource> MagickBitmapSource::crop(int left, int top, int width, int height){
/* TODO Investigate memory leak:
* This method "possibly leaks" 160 bytes in 1 block */
Image copy(image_);
copy.modifyImage();
copy.crop( Geometry(width,height,left,top));
copy.syncPixels();
return Ref<MagickBitmapSource>(new MagickBitmapSource(copy));
}

View file

@ -1,83 +0,0 @@
/*
* example.cpp
* zxing
*
* Created by Ralf Kistner on 16/10/2009.
* 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 <iostream>
#include <fstream>
#include <string>
#include <Magick++.h>
#include "MagickBitmapSource.h"
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/common/LocalBlockBinarizer.h>
#include <zxing/Exception.h>
using namespace Magick;
using namespace std;
using namespace zxing;
using namespace zxing::qrcode;
void decode_image(Image& image, bool localized) {
try {
Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
Ref<Binarizer> binarizer(NULL);
if (localized) {
binarizer = new LocalBlockBinarizer(source);
} else {
binarizer = new GlobalHistogramBinarizer(source);
}
Ref<BinaryBitmap> image(new BinaryBitmap(binarizer));
QRCodeReader reader;
Ref<Result> result(reader.decode(image));
cout << result->getText()->getText() << endl;
} catch (zxing::Exception& e) {
cerr << "Error: " << e.what() << endl;
}
}
int main(int argc, char** argv) {
if (argc < 2) {
cout << "Usage: " << argv[0] << "<filename1> [<filename2> ...]" << endl;
return 1;
}
for (int i = 1; i < argc; i++) {
string infilename = argv[i];
cout << "Processing: " << infilename << endl;
Image image;
try {
image.read(infilename);
} catch (...) {
cerr << "Unable to open image, ignoring" << endl;
continue;
}
bool local = true; // Use local thresholding
decode_image(image, local);
}
return 0;
}

View file

@ -1,331 +0,0 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Copyright 2010-2011 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 <iostream>
#include <fstream>
#include <string>
#include <Magick++.h>
#include "MagickBitmapSource.h"
#include <zxing/common/Counted.h>
#include <zxing/Binarizer.h>
#include <zxing/MultiFormatReader.h>
#include <zxing/Result.h>
#include <zxing/ReaderException.h>
#include <zxing/common/GlobalHistogramBinarizer.h>
#include <zxing/common/HybridBinarizer.h>
#include <exception>
#include <zxing/Exception.h>
#include <zxing/common/IllegalArgumentException.h>
#include <zxing/BinaryBitmap.h>
#include <zxing/DecodeHints.h>
#include <zxing/qrcode/QRCodeReader.h>
#include <zxing/multi/qrcode/QRCodeMultiReader.h>
#include <zxing/multi/ByQuadrantReader.h>
#include <zxing/multi/MultipleBarcodeReader.h>
#include <zxing/multi/GenericMultipleBarcodeReader.h>
//#include <zxing/qrcode/detector/Detector.h>
//#include <zxing/qrcode/detector/QREdgeDetector.h>
//#include <zxing/qrcode/decoder/Decoder.h>
using namespace Magick;
using namespace std;
using namespace zxing;
using namespace zxing::multi;
using namespace zxing::qrcode;
static bool raw_dump = false;
static bool show_format = false;
static bool tryHarder = false;
static bool show_filename = false;
static bool search_multi = false;
static const int MAX_EXPECTED = 4096;
Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints) {
Ref<Reader> reader(new MultiFormatReader);
return reader->decode(image, hints);
}
vector<Ref<Result> > decodeMultiple(Ref<BinaryBitmap> image, DecodeHints hints){
MultiFormatReader delegate;
// MultiFormatReader mformat;
// ByQuadrantReader delegate(mformat);
GenericMultipleBarcodeReader reader(delegate);
// QRCodeMultiReader reader;
return reader.decodeMultiple(image,hints);
}
int test_image(Image& image, bool hybrid, string expected = "") {
string cell_result;
int res = -1;
Ref<BitMatrix> matrix(NULL);
Ref<Binarizer> binarizer(NULL);
const char* result_format = "";
try {
Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
if (hybrid) {
binarizer = new HybridBinarizer(source);
} else {
binarizer = new GlobalHistogramBinarizer(source);
}
DecodeHints hints(DecodeHints::DEFAULT_HINT);
hints.setTryHarder(tryHarder);
Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
Ref<Result> result(decode(binary, hints));
cell_result = result->getText()->getText();
result_format = BarcodeFormat::barcodeFormatNames[result->getBarcodeFormat()];
res = 0;
} catch (ReaderException const& e) {
cell_result = "zxing::ReaderException: " + string(e.what());
res = -2;
} catch (zxing::IllegalArgumentException const& e) {
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
res = -3;
} catch (zxing::Exception const& e) {
cell_result = "zxing::Exception: " + string(e.what());
res = -4;
} catch (std::exception const& e) {
cell_result = "std::exception: " + string(e.what());
res = -5;
}
if (cell_result.compare(expected)) {
res = -6;
if (!raw_dump) {
cout << (hybrid ? "Hybrid" : "Global") << " binarizer failed:\n";
if (!expected.empty()) {
cout << " Expected: " << expected << "\n";
}
cout << " Detected: " << cell_result << endl;
}
}
if (res == 0) {
cout << cell_result;
if (show_format) {
cout << " " << result_format;
}
cout << endl;
}
return res;
}
int test_image_hybrid(Image& image, string expected = "") {
return test_image(image, true, expected);
}
int test_image_global(Image& image, string expected = "") {
return test_image(image, false, expected);
}
int test_image_multi(Image& image, bool hybrid){
vector<Ref<Result> > results;
string cell_result;
int res = -1;
Ref<BitMatrix> matrix(NULL);
Ref<Binarizer> binarizer(NULL);
try {
Ref<MagickBitmapSource> source(new MagickBitmapSource(image));
if (hybrid) {
binarizer = new HybridBinarizer(source);
} else {
binarizer = new GlobalHistogramBinarizer(source);
}
DecodeHints hints(DecodeHints::DEFAULT_HINT);
hints.setTryHarder(tryHarder);
Ref<BinaryBitmap> binary(new BinaryBitmap(binarizer));
results = decodeMultiple(binary, hints);
res = 0;
} catch (ReaderException const& e) {
cell_result = "zxing::ReaderException: " + string(e.what());
res = -2;
} catch (zxing::IllegalArgumentException const& e) {
cell_result = "zxing::IllegalArgumentException: " + string(e.what());
res = -3;
} catch (zxing::Exception const& e) {
cell_result = "zxing::Exception: " + string(e.what());
res = -4;
} catch (std::exception const& e) {
cell_result = "std::exception: " + string(e.what());
res = -5;
}
cout << (hybrid ? "Hybrid" : "Global");
if (res != 0){
cout<<" binarizer failed: "<<cell_result<<endl;
} else {
cout<<" binarizer succeeded: "<<endl;
for (unsigned int i = 0; i < results.size(); i++){
cout << " "<<results[i]->getText()->getText();
if (show_format) {
cout << " " << BarcodeFormat::barcodeFormatNames[results[i]->getBarcodeFormat()];
}
cout << endl;
}
}
return res;
}
int test_image_multi_hybrid(Image& image){
return test_image_multi(image, true);
}
int test_image_multi_global(Image& image){
return test_image_multi(image, false);
}
string get_expected(string imagefilename) {
string textfilename = imagefilename;
int dotpos = textfilename.rfind(".");
textfilename.replace(dotpos+1, textfilename.length() - dotpos - 1, "txt");
char data[MAX_EXPECTED];
FILE *fp = fopen(textfilename.data(), "rb");
if (!fp) {
// could not open file
return "";
}
// get file size
fseek(fp, 0, SEEK_END);
int toread = ftell(fp);
rewind(fp);
if (toread > MAX_EXPECTED) {
cerr << "MAX_EXPECTED = " << MAX_EXPECTED << " but file '" << textfilename << "' has " << toread
<< " bytes! Skipping..." << endl;
fclose(fp);
return "";
}
int nread = fread(data, sizeof(char), toread, fp);
if (nread != toread) {
cerr << "Could not read entire contents of file '" << textfilename << "'! Skipping..." << endl;
fclose(fp);
return "";
}
fclose(fp);
data[nread] = '\0';
string expected(data);
return expected;
}
int main(int argc, char** argv) {
if (argc <= 1) {
cout << "Usage: " << argv[0] << " [--dump-raw] [--show-format] [--try-harder] [--search_multi] [--show-filename] <filename1> [<filename2> ...]" << endl;
return 1;
}
int total = 0;
int gonly = 0;
int honly = 0;
int both = 0;
int neither = 0;
if (argc == 2) raw_dump = true;
for (int i = 1; i < argc; i++) {
string infilename = argv[i];
if (infilename.substr(infilename.length()-3,3).compare("txt") == 0) {
continue;
}
if (infilename.compare("--dump-raw") == 0) {
raw_dump = true;
continue;
}
if (infilename.compare("--show-format") == 0) {
show_format = true;
continue;
}
if (infilename.compare("--try-harder") == 0) {
tryHarder = true;
continue;
}
if (infilename.compare("--show-filename") == 0) {
show_filename = true;
continue;
}
if (infilename.compare("--search_multi") == 0){
search_multi = true;
continue;
}
if (!raw_dump)
cerr << "Processing: " << infilename << endl;
if (show_filename)
cout << infilename << " ";
Image image;
try {
image.read(infilename);
} catch (...) {
cerr << "Unable to open image, ignoring" << endl;
continue;
}
string expected;
expected = get_expected(infilename);
if (search_multi){
int gresult = 1;
int hresult = 1;
gresult = test_image_multi_global(image);
hresult = test_image_multi_hybrid(image);
gresult = gresult == 0;
hresult = hresult == 0;
gonly += gresult && !hresult;
honly += hresult && !gresult;
both += gresult && hresult;
neither += !gresult && !hresult;
total = total + 1;
} else {
int gresult = 1;
int hresult = 1;
hresult = test_image_hybrid(image, expected);
if (!raw_dump || hresult != 0) {
gresult = test_image_global(image, expected);
if (raw_dump && gresult != 0) {
cout << "decoding failed" << endl;
}
}
gresult = gresult == 0;
hresult = hresult == 0;
gonly += gresult && !hresult;
honly += hresult && !gresult;
both += gresult && hresult;
neither += !gresult && !hresult;
total = total + 1;
}
}
if (!raw_dump)
cout << (honly+both) << " passed hybrid, " << (gonly+both) << " passed global, "
<< both << " pass both, " << neither << " pass neither, " << honly
<< " passed only hybrid, " << gonly << " passed only global, of " << total
<< " total." << endl;
return 0;
}