Khoren Markosyan
2 years ago
16 changed files with 143 additions and 419 deletions
@ -1,41 +0,0 @@ |
|||||||
#include "common.h" |
|
||||||
#include <chrono> |
|
||||||
#include <stdio.h> |
|
||||||
#include <stdarg.h> |
|
||||||
|
|
||||||
using namespace std; |
|
||||||
|
|
||||||
bool isLogEnabled; |
|
||||||
|
|
||||||
void setLoggingEnabled(bool enabled) |
|
||||||
{ |
|
||||||
isLogEnabled = enabled; |
|
||||||
} |
|
||||||
|
|
||||||
long long int get_now() |
|
||||||
{ |
|
||||||
return chrono::duration_cast<std::chrono::milliseconds>( |
|
||||||
chrono::system_clock::now().time_since_epoch()) |
|
||||||
.count(); |
|
||||||
} |
|
||||||
|
|
||||||
void platform_log(const char *fmt, ...) |
|
||||||
{ |
|
||||||
if (isLogEnabled) |
|
||||||
{ |
|
||||||
va_list args; |
|
||||||
va_start(args, fmt); |
|
||||||
#ifdef __ANDROID__ |
|
||||||
__android_log_vprint(ANDROID_LOG_VERBOSE, "ndk", fmt, args); |
|
||||||
#elif defined(IS_WIN32) |
|
||||||
char *buf = new char[4096]; |
|
||||||
std::fill_n(buf, 4096, '\0'); |
|
||||||
_vsprintf_p(buf, 4096, fmt, args); |
|
||||||
OutputDebugStringA(buf); |
|
||||||
delete[] buf; |
|
||||||
#else |
|
||||||
vprintf(fmt, args); |
|
||||||
#endif |
|
||||||
va_end(args); |
|
||||||
} |
|
||||||
} |
|
@ -1,26 +0,0 @@ |
|||||||
|
|
||||||
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) |
|
||||||
#define IS_WIN32 |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef __ANDROID__ |
|
||||||
#include <android/log.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef IS_WIN32 |
|
||||||
#include <windows.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
#if defined(__GNUC__) |
|
||||||
// Attributes to prevent 'unused' function from being removed and to make it visible
|
|
||||||
#define FUNCTION_ATTRIBUTE __attribute__((visibility("default"))) __attribute__((used)) |
|
||||||
#elif defined(_MSC_VER) |
|
||||||
// Marking a function for export
|
|
||||||
#define FUNCTION_ATTRIBUTE __declspec(dllexport) |
|
||||||
#endif |
|
||||||
|
|
||||||
long long int get_now(); |
|
||||||
|
|
||||||
void platform_log(const char *fmt, ...); |
|
||||||
|
|
||||||
void setLoggingEnabled(bool enabled); |
|
@ -1,146 +0,0 @@ |
|||||||
#include "common.h" |
|
||||||
#include "ReadBarcode.h" |
|
||||||
#include "MultiFormatWriter.h" |
|
||||||
#include "TextUtfEncoding.h" |
|
||||||
#include "BitMatrix.h" |
|
||||||
#include "native_zxing.h" |
|
||||||
|
|
||||||
#include <locale> |
|
||||||
#include <codecvt> |
|
||||||
#include <stdarg.h> |
|
||||||
|
|
||||||
using namespace ZXing; |
|
||||||
using namespace std; |
|
||||||
|
|
||||||
extern "C" |
|
||||||
{ |
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
void setLogEnabled(int enable) |
|
||||||
{ |
|
||||||
setLoggingEnabled(enable); |
|
||||||
} |
|
||||||
|
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
char const *version() |
|
||||||
{ |
|
||||||
return "1.4.0"; |
|
||||||
} |
|
||||||
|
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate) |
|
||||||
{ |
|
||||||
long long start = get_now(); |
|
||||||
|
|
||||||
long length = width * height; |
|
||||||
auto *data = new uint8_t[length]; |
|
||||||
memcpy(data, bytes, length); |
|
||||||
|
|
||||||
ImageView image{data, width, height, ImageFormat::Lum}; |
|
||||||
if (cropWidth > 0 && cropHeight > 0 && cropWidth < width && cropHeight < height) |
|
||||||
{ |
|
||||||
image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight); |
|
||||||
} |
|
||||||
DecodeHints hints = DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(BarcodeFormat(format)); |
|
||||||
Result result = ReadBarcode(image, hints); |
|
||||||
|
|
||||||
struct CodeResult code = {false, nullptr}; |
|
||||||
if (result.isValid()) |
|
||||||
{ |
|
||||||
resultToCodeResult(&code, result); |
|
||||||
} |
|
||||||
|
|
||||||
delete[] data; |
|
||||||
delete[] bytes; |
|
||||||
|
|
||||||
int evalInMillis = static_cast<int>(get_now() - start); |
|
||||||
platform_log("Read Barcode in: %d ms\n", evalInMillis); |
|
||||||
return code; |
|
||||||
} |
|
||||||
|
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate) |
|
||||||
{ |
|
||||||
long long start = get_now(); |
|
||||||
|
|
||||||
long length = width * height; |
|
||||||
auto *data = new uint8_t[length]; |
|
||||||
memcpy(data, bytes, length); |
|
||||||
|
|
||||||
ImageView image{data, width, height, ImageFormat::Lum}; |
|
||||||
if (cropWidth > 0 && cropHeight > 0 && cropWidth < width && cropHeight < height) |
|
||||||
{ |
|
||||||
image = image.cropped(width / 2 - cropWidth / 2, height / 2 - cropHeight / 2, cropWidth, cropHeight); |
|
||||||
} |
|
||||||
DecodeHints hints = DecodeHints().setTryHarder(tryHarder).setTryRotate(tryRotate).setFormats(BarcodeFormat(format)); |
|
||||||
Results results = ReadBarcodes(image, hints); |
|
||||||
|
|
||||||
auto *codes = new struct CodeResult[results.size()]; |
|
||||||
int i = 0; |
|
||||||
for (auto &result : results) |
|
||||||
{ |
|
||||||
struct CodeResult code = {false, nullptr}; |
|
||||||
if (result.isValid()) |
|
||||||
{ |
|
||||||
resultToCodeResult(&code, result); |
|
||||||
codes[i] = code; |
|
||||||
i++; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
delete[] data; |
|
||||||
delete[] bytes; |
|
||||||
|
|
||||||
int evalInMillis = static_cast<int>(get_now() - start); |
|
||||||
platform_log("Read Barcode in: %d ms\n", evalInMillis); |
|
||||||
return {i, codes}; |
|
||||||
} |
|
||||||
|
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
struct EncodeResult encodeBarcode(char *contents, int width, int height, int format, int margin, int eccLevel) |
|
||||||
{ |
|
||||||
long long start = get_now(); |
|
||||||
|
|
||||||
struct EncodeResult result = {0, contents, format, nullptr, 0, nullptr}; |
|
||||||
try |
|
||||||
{ |
|
||||||
auto writer = MultiFormatWriter(BarcodeFormat(format)).setMargin(margin).setEccLevel(eccLevel).setEncoding(CharacterSet::UTF8); |
|
||||||
auto bitMatrix = writer.encode(TextUtfEncoding::FromUtf8(string(contents)), width, height); |
|
||||||
result.data = ToMatrix<int8_t>(bitMatrix).data(); |
|
||||||
result.length = bitMatrix.width() * bitMatrix.height(); |
|
||||||
result.isValid = true; |
|
||||||
} |
|
||||||
catch (const exception &e) |
|
||||||
{ |
|
||||||
platform_log("Can't encode text: %s\nError: %s\n", contents, e.what()); |
|
||||||
result.error = new char[strlen(e.what()) + 1]; |
|
||||||
strcpy(result.error, e.what()); |
|
||||||
} |
|
||||||
|
|
||||||
int evalInMillis = static_cast<int>(get_now() - start); |
|
||||||
platform_log("Encode Barcode in: %d ms\n", evalInMillis); |
|
||||||
return result; |
|
||||||
} |
|
||||||
|
|
||||||
FUNCTION_ATTRIBUTE |
|
||||||
void resultToCodeResult(struct CodeResult *code, Result result) |
|
||||||
{ |
|
||||||
code->isValid = result.isValid(); |
|
||||||
|
|
||||||
code->format = static_cast<int>(result.format()); |
|
||||||
|
|
||||||
code->bytes = result.bytes().data(); |
|
||||||
code->length = result.bytes().size(); |
|
||||||
|
|
||||||
string text = result.text(); |
|
||||||
code->text = new char[text.length() + 1]; |
|
||||||
strcpy(code->text, text.c_str()); |
|
||||||
|
|
||||||
auto p = result.position(); |
|
||||||
auto tl = p.topLeft(); |
|
||||||
auto tr = p.topRight(); |
|
||||||
auto bl = p.bottomLeft(); |
|
||||||
auto br = p.bottomRight(); |
|
||||||
code->pos = new Pos{tl.x, tl.y, tr.x, tr.y, bl.x, bl.y, br.x, br.y}; |
|
||||||
platform_log("Result: %s\n", code->text); |
|
||||||
} |
|
||||||
} |
|
@ -1,119 +0,0 @@ |
|||||||
#ifdef __cplusplus |
|
||||||
extern "C" |
|
||||||
{ |
|
||||||
#endif |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Pos is a position of a barcode in a image. |
|
||||||
* |
|
||||||
*/ |
|
||||||
struct Pos |
|
||||||
{ |
|
||||||
int topLeftX; ///< x coordinate of top left corner of barcode
|
|
||||||
int topLeftY; ///< y coordinate of top left corner of barcode
|
|
||||||
int topRightX; ///< x coordinate of top right corner of barcode
|
|
||||||
int topRightY; ///< y coordinate of top right corner of barcode
|
|
||||||
int bottomLeftX; ///< x coordinate of bottom left corner of barcode
|
|
||||||
int bottomLeftY; ///< y coordinate of bottom left corner of barcode
|
|
||||||
int bottomRightX; ///< x coordinate of bottom right corner of barcode
|
|
||||||
int bottomRightY; ///< y coordinate of bottom right corner of barcode
|
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The CodeResult class encapsulates the result of decoding a barcode within an image. |
|
||||||
*/ |
|
||||||
struct CodeResult |
|
||||||
{ |
|
||||||
int isValid; ///< Whether the barcode was successfully decoded
|
|
||||||
char *text; ///< The decoded text
|
|
||||||
const unsigned char *bytes; ///< The bytes is the raw / standard content without any modifications like character set conversions
|
|
||||||
int length; ///< The length of the bytes
|
|
||||||
int format; ///< The format of the barcode
|
|
||||||
struct Pos *pos; ///< The position of the barcode within the image
|
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief The CodeResults class encapsulates the result of decoding multiple barcodes within an image. |
|
||||||
*/ |
|
||||||
struct CodeResults |
|
||||||
{ |
|
||||||
int count; ///< The number of barcodes detected
|
|
||||||
struct CodeResult *results; ///< The results of the barcode decoding
|
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief EncodeResult encapsulates the result of encoding a barcode. |
|
||||||
* |
|
||||||
*/ |
|
||||||
struct EncodeResult |
|
||||||
{ |
|
||||||
int isValid; ///< Whether the barcode was successfully encoded
|
|
||||||
char *text; ///< The encoded text
|
|
||||||
int format; ///< The format of the barcode
|
|
||||||
const signed char *data; ///< The encoded data
|
|
||||||
int length; ///< The length of the encoded data
|
|
||||||
char *error; ///< The error message
|
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enables or disables the logging of the library. |
|
||||||
* @param enable Whether to enable or disable the logging. |
|
||||||
* |
|
||||||
* @param enabled |
|
||||||
*/ |
|
||||||
void setLogEnabled(int enable); |
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the version of the zxing-cpp library. |
|
||||||
* |
|
||||||
* @return The version of the zxing-cpp library. |
|
||||||
*/ |
|
||||||
char const *version(); |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read barcode from image bytes. |
|
||||||
* @param bytes Image bytes. |
|
||||||
* @param format Specify a set of BarcodeFormats that should be searched for. |
|
||||||
* @param width Image width in pixels. |
|
||||||
* @param height Image height in pixels. |
|
||||||
* @param cropWidth Crop width. |
|
||||||
* @param cropHeight Crop height. |
|
||||||
* @param tryHarder Spend more time to try to find a barcode; optimize for accuracy, not speed. |
|
||||||
* @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images. |
|
||||||
* @return The barcode result. |
|
||||||
*/ |
|
||||||
struct CodeResult readBarcode(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate); |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read barcodes from image bytes. |
|
||||||
* @param bytes Image bytes. |
|
||||||
* @param format Specify a set of BarcodeFormats that should be searched for. |
|
||||||
* @param width Image width in pixels. |
|
||||||
* @param height Image height in pixels. |
|
||||||
* @param cropWidth Crop width. |
|
||||||
* @param cropHeight Crop height. |
|
||||||
* @param tryHarder Spend more time to try to find a barcode, optimize for accuracy, not speed. |
|
||||||
* @param tryRotate Also try detecting code in 90, 180 and 270 degree rotated images. |
|
||||||
* @return The barcode results. |
|
||||||
*/ |
|
||||||
struct CodeResults readBarcodes(char *bytes, int format, int width, int height, int cropWidth, int cropHeight, int tryHarder, int tryRotate); |
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Encode a string into a barcode |
|
||||||
* @param contents The string to encode |
|
||||||
* @param width The width of the barcode in pixels. |
|
||||||
* @param height The height of the barcode in pixels. |
|
||||||
* @param format The format of the barcode |
|
||||||
* @param margin The margin of the barcode |
|
||||||
* @param eccLevel The error correction level of the barcode. Used for Aztec, PDF417, and QRCode only, [0-8]. |
|
||||||
* @return The barcode data |
|
||||||
*/ |
|
||||||
struct EncodeResult encodeBarcode(char *contents, int width, int height, int format, int margin, int eccLevel); |
|
||||||
|
|
||||||
// Private functions
|
|
||||||
|
|
||||||
void resultToCodeResult(struct CodeResult *code, ZXing::Result result); |
|
||||||
|
|
||||||
#ifdef __cplusplus |
|
||||||
} |
|
||||||
#endif |
|
Loading…
Reference in new issue