mirror of
https://github.com/zxing/zxing.git
synced 2024-11-09 20:44:03 -08:00
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:
parent
addd611c25
commit
12222ad493
59
NOTICE
59
NOTICE
|
@ -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.
|
||||
|
|
18393
cpp/0001-Merge-schulzch-VS-support-and-other-cleanup.patch
Normal file
18393
cpp/0001-Merge-schulzch-VS-support-and-other-cleanup.patch
Normal file
File diff suppressed because it is too large
Load diff
82
cpp/CMakeLists.txt
Normal file
82
cpp/CMakeLists.txt
Normal 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()
|
48
cpp/README
48
cpp/README
|
@ -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
67
cpp/README.md
Normal 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`
|
159
cpp/SConscript
159
cpp/SConscript
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
112
cpp/cli/src/ImageReaderSource.cpp
Normal file
112
cpp/cli/src/ImageReaderSource.cpp
Normal 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;
|
||||
}
|
|
@ -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
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
319
cpp/cli/src/jpgd.h
Normal 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
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
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
297
cpp/cli/src/main.cpp
Normal 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;
|
||||
}
|
54
cpp/cmake/FindCPPUNIT.cmake
Normal file
54
cpp/cmake/FindCPPUNIT.cmake
Normal 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
57
cpp/cmake/FindIconv.cmake
Normal 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
|
||||
)
|
14
cpp/core/src/win32/zxing/iconv.h
Normal file
14
cpp/core/src/win32/zxing/iconv.h
Normal 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
|
247
cpp/core/src/win32/zxing/stdint.h
Normal file
247
cpp/core/src/win32/zxing/stdint.h
Normal 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_ ]
|
2035
cpp/core/src/win32/zxing/win_iconv.c
Normal file
2035
cpp/core/src/win32/zxing/win_iconv.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ protected:
|
|||
public:
|
||||
ResultPoint();
|
||||
ResultPoint(float x, float y);
|
||||
ResultPoint(int x, int y);
|
||||
virtual ~ResultPoint();
|
||||
|
||||
virtual float getX() const;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {};
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -71,6 +71,6 @@ int BitSource::readBits(int numBits) {
|
|||
}
|
||||
|
||||
int BitSource::available() {
|
||||
return 8 * (bytes_.size() - byteOffset_) - bitOffset_;
|
||||
return 8 * (bytes_->size() - byteOffset_) - bitOffset_;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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__
|
||||
|
|
|
@ -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
|
|
@ -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_ */
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}}}}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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__
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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()){
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -32,6 +32,9 @@ using zxing::NotFoundException;
|
|||
using zxing::ChecksumException;
|
||||
using zxing::oned::Code39Reader;
|
||||
|
||||
// VC++
|
||||
using zxing::BitArray;
|
||||
|
||||
namespace {
|
||||
const char* ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ using zxing::NotFoundException;
|
|||
using zxing::ChecksumException;
|
||||
using zxing::oned::Code93Reader;
|
||||
|
||||
// VC++
|
||||
using zxing::BitArray;
|
||||
|
||||
namespace {
|
||||
char const ALPHABET[] =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd*";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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])))
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -102,6 +102,7 @@ Version *Version::getProvisionalVersionForDimension(int dimension) {
|
|||
try {
|
||||
return Version::getVersionForNumber((dimension - 17) >> 2);
|
||||
} catch (IllegalArgumentException const& ignored) {
|
||||
(void)ignored;
|
||||
throw FormatException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
|
@ -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_
|
|
@ -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));
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue