Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add symbol field to ReadResult and WriteResult #191

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
5 changes: 5 additions & 0 deletions .changeset/sharp-shrimps-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"zxing-wasm": minor
---

feat: add `symbol` field to `ReadResult` and `WriteResult`
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__snapshots__/** linguist-vendored
tests/__snapshots__/** linguist-generated=true
2 changes: 1 addition & 1 deletion main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
type WriterOptions,
readBarcodes,
writeBarcode,
} from "./src/full/index";
} from "./src/full/index.js";

const imageFile = await fetch(
"https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=Hello%20world!",
Expand Down
17 changes: 17 additions & 0 deletions src/bindings/barcodeSymbol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Barcode symbol in the shape of a one-channel image.
*/
export interface BarcodeSymbol {
/**
* Image data of the barcode symbol.
*/
data: Uint8ClampedArray;
/**
* Width of the barcode symbol.
*/
width: number;
/**
* Height of the barcode symbol.
*/
height: number;
}
5 changes: 5 additions & 0 deletions src/bindings/readResult.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type ReadOutputBarcodeFormat, decodeFormat } from "./barcodeFormat.js";
import type { BarcodeSymbol } from "./barcodeSymbol.js";
import { type ContentType, decodeContentType } from "./contentType.js";
import type { EcLevel } from "./ecLevel.js";
import type { Position, ZXingPosition } from "./position.js";
Expand Down Expand Up @@ -104,6 +105,10 @@ export interface ZXingReadResult {
* @deprecated
*/
version: string;
/**
* Barcode symbol in the shape of a one-channel image.
*/
symbol: BarcodeSymbol;
}

/**
Expand Down
6 changes: 6 additions & 0 deletions src/bindings/writeResult.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { BarcodeSymbol } from "./barcodeSymbol.js";

/**
* @internal
*/
Expand All @@ -21,6 +23,10 @@ export interface ZXingWriteResult {
* @see {@link WriteResult.error | `WriteResult.error`}
*/
error: string;
/**
* Barcode symbol in the shape of a one-channel image.
*/
symbol: BarcodeSymbol;
}

/**
Expand Down
52 changes: 41 additions & 11 deletions src/cpp/ZXingWasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@

using namespace emscripten;

struct Symbol {
val data;
int width;
int height;
};

#if defined(READER)

struct JsReaderOptions {
Expand All @@ -32,9 +38,7 @@ struct JsReaderOptions {
bool tryRotate;
bool tryInvert;
bool tryDownscale;
#ifdef ZXING_EXPERIMENTAL_API
bool tryDenoise;
#endif
uint8_t binarizer;
bool isPure;
uint16_t downscaleThreshold;
Expand Down Expand Up @@ -69,6 +73,7 @@ struct JsReadResult {
bool readerInit;
int lineCount;
std::string version;
Symbol symbol;
};

using JsReadResults = std::vector<JsReadResult>;
Expand All @@ -83,9 +88,7 @@ JsReadResults readBarcodes(ZXing::ImageView imageView, const JsReaderOptions &js
.setTryRotate(jsReaderOptions.tryRotate)
.setTryInvert(jsReaderOptions.tryInvert)
.setTryDownscale(jsReaderOptions.tryDownscale)
#ifdef ZXING_EXPERIMENTAL_API
.setTryDenoise(jsReaderOptions.tryDenoise)
#endif
.setBinarizer(static_cast<ZXing::Binarizer>(jsReaderOptions.binarizer))
.setIsPure(jsReaderOptions.isPure)
.setDownscaleThreshold(jsReaderOptions.downscaleThreshold)
Expand All @@ -100,6 +103,7 @@ JsReadResults readBarcodes(ZXing::ImageView imageView, const JsReaderOptions &js
);

thread_local const val Uint8Array = val::global("Uint8Array");
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");

JsReadResults jsReadResults;
jsReadResults.reserve(barcodes.size());
Expand All @@ -125,7 +129,14 @@ JsReadResults readBarcodes(ZXing::ImageView imageView, const JsReaderOptions &js
.sequenceId = barcode.sequenceId(),
.readerInit = barcode.readerInit(),
.lineCount = barcode.lineCount(),
.version = barcode.version()}
.version = barcode.version(),
.symbol = std::move(Symbol{
.data = std::move(
Uint8ClampedArray.new_(val(typed_memory_view(barcode.symbol().rowStride() * barcode.symbol().height(), barcode.symbol().data())))
),
.width = barcode.symbol().width(),
.height = barcode.symbol().height()
})}
);
}
return jsReadResults;
Expand Down Expand Up @@ -194,6 +205,7 @@ struct JsWriteResult {
std::string svg;
std::string utf8;
val image;
Symbol symbol;
};

JsWriteResult writeBarcodeFromText(std::string text, const JsWriterOptions &jsWriterOptions) {
Expand All @@ -204,14 +216,22 @@ JsWriteResult writeBarcodeFromText(std::string text, const JsWriterOptions &jsWr
auto image = ZXing::WriteBarcodeToImage(barcode, writerOptions);

thread_local const val Uint8Array = val::global("Uint8Array");
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");

int len;
uint8_t *bytes = stbi_write_png_to_mem(image.data(), image.rowStride(), image.width(), image.height(), ZXing::PixStride(image.format()), &len);

return {
.svg = ZXing::WriteBarcodeToSVG(barcode, writerOptions),
.utf8 = ZXing::WriteBarcodeToUtf8(barcode, writerOptions),
.image = std::move(Uint8Array.new_(val(typed_memory_view(len, bytes))))
.image = std::move(Uint8Array.new_(val(typed_memory_view(len, bytes)))),
.symbol = std::move(Symbol{
.data =
std::move(Uint8ClampedArray.new_(val(typed_memory_view(barcode.symbol().rowStride() * barcode.symbol().height(), barcode.symbol().data())))
),
.width = barcode.symbol().width(),
.height = barcode.symbol().height()
})
};
} catch (const std::exception &e) {
return {.error = e.what()};
Expand All @@ -228,14 +248,22 @@ JsWriteResult writeBarcodeFromBytes(int bufferPtr, int bufferLength, const JsWri
auto image = ZXing::WriteBarcodeToImage(barcode, writerOptions);

thread_local const val Uint8Array = val::global("Uint8Array");
thread_local const val Uint8ClampedArray = val::global("Uint8ClampedArray");

int len;
uint8_t *bytes = stbi_write_png_to_mem(image.data(), image.rowStride(), image.width(), image.height(), ZXing::PixStride(image.format()), &len);

return {
.svg = ZXing::WriteBarcodeToSVG(barcode, writerOptions),
.utf8 = ZXing::WriteBarcodeToUtf8(barcode, writerOptions),
.image = std::move(Uint8Array.new_(val(typed_memory_view(len, bytes))))
.image = std::move(Uint8Array.new_(val(typed_memory_view(len, bytes)))),
.symbol = std::move(Symbol{
.data =
std::move(Uint8ClampedArray.new_(val(typed_memory_view(barcode.symbol().rowStride() * barcode.symbol().height(), barcode.symbol().data())))
),
.width = barcode.symbol().width(),
.height = barcode.symbol().height()
})
};
} catch (const std::exception &e) {
return {.error = e.what()};
Expand All @@ -248,6 +276,8 @@ JsWriteResult writeBarcodeFromBytes(int bufferPtr, int bufferLength, const JsWri

EMSCRIPTEN_BINDINGS(ZXingWasm) {

value_object<Symbol>("Symbol").field("data", &Symbol::data).field("width", &Symbol::width).field("height", &Symbol::height);

#if defined(READER)

value_object<JsReaderOptions>("ReaderOptions")
Expand All @@ -256,9 +286,7 @@ EMSCRIPTEN_BINDINGS(ZXingWasm) {
.field("tryRotate", &JsReaderOptions::tryRotate)
.field("tryInvert", &JsReaderOptions::tryInvert)
.field("tryDownscale", &JsReaderOptions::tryDownscale)
#ifdef ZXING_EXPERIMENTAL_API
.field("tryDenoise", &JsReaderOptions::tryDenoise)
#endif
.field("binarizer", &JsReaderOptions::binarizer)
.field("isPure", &JsReaderOptions::isPure)
.field("downscaleThreshold", &JsReaderOptions::downscaleThreshold)
Expand Down Expand Up @@ -299,7 +327,8 @@ EMSCRIPTEN_BINDINGS(ZXingWasm) {
.field("sequenceId", &JsReadResult::sequenceId)
.field("readerInit", &JsReadResult::readerInit)
.field("lineCount", &JsReadResult::lineCount)
.field("version", &JsReadResult::version);
.field("version", &JsReadResult::version)
.field("symbol", &JsReadResult::symbol);

register_vector<JsReadResult>("ReadResults");

Expand All @@ -325,7 +354,8 @@ EMSCRIPTEN_BINDINGS(ZXingWasm) {
.field("error", &JsWriteResult::error)
.field("svg", &JsWriteResult::svg)
.field("utf8", &JsWriteResult::utf8)
.field("image", &JsWriteResult::image);
.field("image", &JsWriteResult::image)
.field("symbol", &JsWriteResult::symbol);

function("writeBarcodeFromText", &writeBarcodeFromText);
function("writeBarcodeFromBytes", &writeBarcodeFromBytes);
Expand Down
5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/fast-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/fast-180.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/fast-270.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/fast-90.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/pure-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/slow-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/slow-180.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/slow-270.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#128/slow-90.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/fast-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/fast-180.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/fast-270.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/fast-90.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/pure-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions tests/__snapshots__/aztec-1/#217/slow-0.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading