Skip to content

Commit

Permalink
c-API: add support for experimental writer API
Browse files Browse the repository at this point in the history
  • Loading branch information
axxel committed Mar 5, 2024
1 parent cdbab8d commit 964da5a
Show file tree
Hide file tree
Showing 3 changed files with 236 additions and 32 deletions.
116 changes: 116 additions & 0 deletions core/src/ZXingC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,31 @@ void ZXing_ImageView_rotate(ZXing_ImageView* iv, int degree)
*iv = iv->rotated(degree);
}

void ZXing_Image_delete(ZXing_Image* img)
{
delete img;
}

const uint8_t* ZXing_Image_data(const ZXing_Image* img)
{
return img->data();
}

int ZXing_Image_width(const ZXing_Image* img)
{
return img->width();
}

int ZXing_Image_height(const ZXing_Image* img)
{
return img->height();
}

ZXing_ImageFormat ZXing_Image_format(const ZXing_Image* img)
{
return static_cast<ZXing_ImageFormat>(img->format());
}

/*
* ZXing/BarcodeFormat.h
*/
Expand Down Expand Up @@ -288,6 +313,97 @@ ZXing_Barcode* ZXing_Barcodes_move(ZXing_Barcodes* barcodes, int i)
ZX_TRY(new Barcode(std::move((*barcodes)[i])));
}

#ifdef ZXING_BUILD_EXPERIMENTAL_API
/*
* ZXing/WriteBarcode.h
*/

ZXing_CreatorOptions* ZXing_CreatorOptions_new(ZXing_BarcodeFormat format)
{
ZX_TRY(new CreatorOptions(static_cast<BarcodeFormat>(format)));
}

void ZXing_CreatorOptions_delete(ZXing_CreatorOptions* opts)
{
delete opts;
}

#define ZX_PROPERTY(TYPE, GETTER, SETTER) \
TYPE ZXing_CreatorOptions_get##SETTER(const ZXing_CreatorOptions* opts) { return opts->GETTER(); } \
void ZXing_CreatorOptions_set##SETTER(ZXing_CreatorOptions* opts, TYPE val) { opts->GETTER(val); }

ZX_PROPERTY(bool, readerInit, ReaderInit)
ZX_PROPERTY(bool, forceSquareDataMatrix, ForceSquareDataMatrix)

#undef ZX_PROPERTY

//ZX_PROPERTY(BarcodeFormat, format, Format)

char* ZXing_CreatorOptions_getEcLevel(const ZXing_CreatorOptions* opts)
{
return copy(opts->ecLevel());
}

void ZXing_CreatorOptions_setEcLevel(ZXing_CreatorOptions* opts, const char* val)
{
opts->ecLevel(val);
}


ZXing_WriterOptions* ZXing_WriterOptions_new()
{
ZX_TRY(new ZXing_WriterOptions());
}

void ZXing_WriterOptions_delete(ZXing_CreatorOptions* opts)
{
delete opts;
}

#define ZX_PROPERTY(TYPE, GETTER, SETTER) \
TYPE ZXing_WriterOptions_get##SETTER(const ZXing_WriterOptions* opts) { return opts->GETTER(); } \
void ZXing_WriterOptions_set##SETTER(ZXing_WriterOptions* opts, TYPE val) { opts->GETTER(val); }

ZX_PROPERTY(int, scale, Scale)
ZX_PROPERTY(int, sizeHint, SizeHint)
ZX_PROPERTY(int, rotate, Rotate)
ZX_PROPERTY(bool, withHRT, WithHRT)
ZX_PROPERTY(bool, withQuietZones, WithQuietZones)

#undef ZX_PROPERTY

ZXing_Barcode* ZXing_CreateBarcodeFromText(const char* data, int size, const ZXing_CreatorOptions* opts)
{
ZX_CHECK(data && opts, "Data and/or options param in CreateBarcodeFromText is NULL")
ZX_TRY(new Barcode(CreateBarcodeFromText({data, size ? static_cast<size_t>(size) : strlen(data)}, *opts));)
}

ZXing_Barcode* ZXing_CreateBarcodeFromBytes(const void* data, int size, const ZXing_CreatorOptions* opts)
{
ZX_CHECK(data && size && opts, "Data and/or options param in CreateBarcodeFromBytes is NULL")
ZX_TRY(new Barcode(CreateBarcodeFromBytes(data, size, *opts)))
}

char* ZXing_WriteBarcodeToSVG(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts)
{
static WriterOptions defOpts;
ZX_CHECK(barcode, "Barcode param in WriteBarcodeToSVG is NULL")
ZX_TRY(copy(WriteBarcodeToSVG(*barcode, *(opts ? opts : &defOpts))))
}

ZXing_Image* ZXing_WriteBarcodeToImage(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts)
{
static WriterOptions defOpts;
ZX_CHECK(barcode, "Barcode param in WriteBarcodeToSVG is NULL")
ZX_TRY(new Image(WriteBarcodeToImage(*barcode, *(opts ? opts : &defOpts))))
}

#endif

/*
* ZXingC.h
*/

char* ZXing_LastErrorMsg()
{
if (lastErrorMsg.empty())
Expand Down
70 changes: 68 additions & 2 deletions core/src/ZXingC.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,20 @@

#ifdef __cplusplus

#include "ReaderOptions.h"
#include "ImageView.h"
#include "Barcode.h"
#include "ImageView.h"
#include "ReaderOptions.h"
#include "WriteBarcode.h"

typedef ZXing::ImageView ZXing_ImageView;
typedef ZXing::Image ZXing_Image;
#ifdef ZXING_BUILD_EXPERIMENTAL_API
typedef ZXing::CreatorOptions ZXing_CreatorOptions;
typedef ZXing::WriterOptions ZXing_WriterOptions;
#else
typedef struct ZXing_CreatorOptions ZXing_CreatorOptions;
typedef struct ZXing_WriterOptions ZXing_WriterOptions;
#endif
typedef ZXing::ReaderOptions ZXing_ReaderOptions;
typedef ZXing::Barcode ZXing_Barcode;
typedef ZXing::Barcodes ZXing_Barcodes;
Expand All @@ -26,7 +35,10 @@ extern "C"
#else

typedef struct ZXing_ImageView ZXing_ImageView;
typedef struct ZXing_Image ZXing_Image;
typedef struct ZXing_ReaderOptions ZXing_ReaderOptions;
typedef struct ZXing_CreatorOptions ZXing_CreatorOptions;
typedef struct ZXing_WriterOptions ZXing_WriterOptions;
typedef struct ZXing_Barcode ZXing_Barcode;
typedef struct ZXing_Barcodes ZXing_Barcodes;

Expand Down Expand Up @@ -57,6 +69,13 @@ void ZXing_ImageView_delete(ZXing_ImageView* iv);
void ZXing_ImageView_crop(ZXing_ImageView* iv, int left, int top, int width, int height);
void ZXing_ImageView_rotate(ZXing_ImageView* iv, int degree);

void ZXing_Image_delete(ZXing_Image* img);

const uint8_t* ZXing_Image_data(const ZXing_Image* img);
int ZXing_Image_width(const ZXing_Image* img);
int ZXing_Image_height(const ZXing_Image* img);
ZXing_ImageFormat ZXing_Image_format(const ZXing_Image* img);

/*
* ZXing/BarcodeFormat.h
*/
Expand Down Expand Up @@ -232,6 +251,53 @@ char* ZXing_LastErrorMsg();

void ZXing_free(void* ptr);

/*
* ZXing/WriteBarcode.h
*/

ZXing_CreatorOptions* ZXing_CreatorOptions_new(ZXing_BarcodeFormat format);
void ZXing_CreatorOptions_delete(ZXing_CreatorOptions* opts);

void ZXing_CreatorOptions_setFormat(ZXing_CreatorOptions* opts, ZXing_BarcodeFormat format);
ZXing_BarcodeFormat ZXing_CreatorOptions_getFormat(const ZXing_CreatorOptions* opts);

void ZXing_CreatorOptions_setReaderInit(ZXing_CreatorOptions* opts, bool readerInit);
bool ZXing_CreatorOptions_getReaderInit(const ZXing_CreatorOptions* opts);

void ZXing_CreatorOptions_setForceSquareDataMatrix(ZXing_CreatorOptions* opts, bool forceSquareDataMatrix);
bool ZXing_CreatorOptions_getForceSquareDataMatrix(const ZXing_CreatorOptions* opts);

void ZXing_CreatorOptions_setEcLevel(ZXing_CreatorOptions* opts, const char* ecLevel);
char* ZXing_CreatorOptions_getEcLevel(const ZXing_CreatorOptions* opts);


ZXing_WriterOptions* ZXing_WriterOptions_new();
void ZXing_WriterOptions_delete(ZXing_CreatorOptions* opts);

void ZXing_WriterOptions_setScale(ZXing_WriterOptions* opts, int scale);
int ZXing_WriterOptions_getScale(const ZXing_WriterOptions* opts);

void ZXing_WriterOptions_setSizeHint(ZXing_WriterOptions* opts, int sizeHint);
int ZXing_WriterOptions_getSizeHint(const ZXing_WriterOptions* opts);

void ZXing_WriterOptions_setRotate(ZXing_WriterOptions* opts, int rotate);
int ZXing_WriterOptions_getRotate(const ZXing_WriterOptions* opts);

void ZXing_WriterOptions_setWithHRT(ZXing_WriterOptions* opts, bool withHRT);
bool ZXing_WriterOptions_getWithHRT(const ZXing_WriterOptions* opts);

void ZXing_WriterOptions_setWithQuietZones(ZXing_WriterOptions* opts, bool withQuietZones);
bool ZXing_WriterOptions_getWithQuietZones(const ZXing_WriterOptions* opts);


ZXing_Barcode* ZXing_CreateBarcodeFromText(const char* data, int size, const ZXing_CreatorOptions* opts);
ZXing_Barcode* ZXing_CreateBarcodeFromBytes(const void* data, int size, const ZXing_CreatorOptions* opts);

/** Note: opts is optional, i.e. it can be NULL, which will imply default settings. */
char* ZXing_WriteBarcodeToSVG(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts);
ZXing_Image* ZXing_WriteBarcodeToImage(const ZXing_Barcode* barcode, const ZXing_WriterOptions* opts);


#ifdef __cplusplus
}
#endif
Expand Down
82 changes: 52 additions & 30 deletions wrappers/c/ZXingCTest.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ void printF(const char* fmt, char* text)
ZXing_free(text);
}

#define CHECK(GOOD) \
if (!(GOOD)) { \
char* error = ZXing_LastErrorMsg(); \
fprintf(stderr, "CHECK(%s) failed: %s\n", #GOOD, error); \
ZXing_free(error); \
return 2; \
}

int main(int argc, char** argv)
{
int ret = 0;
Expand All @@ -57,9 +65,30 @@ int main(int argc, char** argv)
int height = 0;
int channels = 0;
stbi_uc* data = stbi_load(filename, &width, &height, &channels, STBI_grey);
if (!data) {

ZXing_ImageView* iv = NULL;
ZXing_Image* img = NULL;

if (data) {
iv = ZXing_ImageView_new(data, width, height, ZXing_ImageFormat_Lum, 0, 0);
CHECK(iv)
} else {
fprintf(stderr, "Could not read image '%s'\n", filename);
#ifdef ZXING_BUILD_EXPERIMENTAL_API
if (formats == ZXing_BarcodeFormat_Invalid)
return 2;
fprintf(stderr, "Using '%s' as text input to create barcode\n", filename);
ZXing_CreatorOptions* cOpts = ZXing_CreatorOptions_new(formats);
CHECK(cOpts)
ZXing_Barcode* barcode = ZXing_CreateBarcodeFromText(filename, 0, cOpts);
CHECK(barcode)
img = ZXing_WriteBarcodeToImage(barcode, NULL);
CHECK(img)
ZXing_CreatorOptions_delete(cOpts);
ZXing_Barcode_delete(barcode);
#else
return 2;
#endif
}

ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();
Expand All @@ -68,42 +97,35 @@ int main(int argc, char** argv)
ZXing_ReaderOptions_setFormats(opts, formats);
ZXing_ReaderOptions_setReturnErrors(opts, true);

ZXing_ImageView* iv = ZXing_ImageView_new(data, width, height, ZXing_ImageFormat_Lum, 0, 0);

ZXing_Barcodes* barcodes = ZXing_ReadBarcodes(iv, opts);
ZXing_Barcodes* barcodes = ZXing_ReadBarcodes(iv ? iv : (ZXing_ImageView*)img, opts);
CHECK(barcodes)

ZXing_ImageView_delete(iv);
ZXing_Image_delete(img);
ZXing_ReaderOptions_delete(opts);
stbi_image_free(data);

if (barcodes) {
for (int i = 0, n = ZXing_Barcodes_size(barcodes); i < n; ++i) {
const ZXing_Barcode* barcode = ZXing_Barcodes_at(barcodes, i);

printF("Text : %s\n", ZXing_Barcode_text(barcode));
printF("BytesECI : %s\n", (char*)ZXing_Barcode_bytesECI(barcode, NULL));
printF("Format : %s\n", ZXing_BarcodeFormatToString(ZXing_Barcode_format(barcode)));
printF("Content : %s\n", ZXing_ContentTypeToString(ZXing_Barcode_contentType(barcode)));
printF("Identifier : %s\n", ZXing_Barcode_symbologyIdentifier(barcode));
printF("EC Level : %s\n", ZXing_Barcode_ecLevel(barcode));
printF("Error : %s\n", ZXing_Barcode_errorMsg(barcode));
printF("Position : %s\n", ZXing_PositionToString(ZXing_Barcode_position(barcode)));
printf("Rotation : %d\n", ZXing_Barcode_orientation(barcode));

if (i < n-1)
printf("\n");
}
for (int i = 0, n = ZXing_Barcodes_size(barcodes); i < n; ++i) {
const ZXing_Barcode* barcode = ZXing_Barcodes_at(barcodes, i);

printF("Text : %s\n", ZXing_Barcode_text(barcode));
printF("BytesECI : %s\n", (char*)ZXing_Barcode_bytesECI(barcode, NULL));
printF("Format : %s\n", ZXing_BarcodeFormatToString(ZXing_Barcode_format(barcode)));
printF("Content : %s\n", ZXing_ContentTypeToString(ZXing_Barcode_contentType(barcode)));
printF("Identifier : %s\n", ZXing_Barcode_symbologyIdentifier(barcode));
printF("EC Level : %s\n", ZXing_Barcode_ecLevel(barcode));
printF("Error : %s\n", ZXing_Barcode_errorMsg(barcode));
printF("Position : %s\n", ZXing_PositionToString(ZXing_Barcode_position(barcode)));
printf("Rotation : %d\n", ZXing_Barcode_orientation(barcode));

if (i < n-1)
printf("\n");
}

if (ZXing_Barcodes_size(barcodes) == 0)
printf("No barcode found\n");
if (ZXing_Barcodes_size(barcodes) == 0)
printf("No barcode found\n");

ZXing_Barcodes_delete(barcodes);
} else {
char* error = ZXing_LastErrorMsg();
fprintf(stderr, "%s\n", error);
ZXing_free(error);
ret = 2;
}
ZXing_Barcodes_delete(barcodes);

return ret;
}

0 comments on commit 964da5a

Please sign in to comment.