quagga2 icon indicating copy to clipboard operation
quagga2 copied to clipboard

Feature Request: Support for Data Matrix Format

Open tmaex opened this issue 3 years ago • 7 comments

It would be fantastic to support the format data matrix.

Besides multiple purposes the Grocy Project could use this feature to fully support 2D Grocycodes: https://github.com/grocy/grocy/pull/1500

tmaex avatar Nov 05 '21 12:11 tmaex

Thank you for filing an issue! Please be patient. :-)

github-actions[bot] avatar Nov 05 '21 12:11 github-actions[bot]

#388 also involves 2D barcodes, but I simply do not know enough about this sort of thing to even know if the existing framework is suitable for decoding that or not. I'd hoped that by keeping the project maintained, it would eventually attract people who knew image processing better than me :-D

I haven't really looked at zxing-js, probably worth doing that, might be pretty easy to write a plugin that just hands off hte image to it if quagga doesn't find anything

ericblade avatar Nov 05 '21 16:11 ericblade

Hi everyone,

unfortunately I had a bit of a fall out with the maintainer of grocy (a project which I have since forked, but still haven't got to a state of feature parity - I'm playing bug whack-a-mole right since summer while implementing core functionality in a modern UI), so I'll reply here.

To drop the big bomb: I don't have code that actually works, but I tried a few things. I'll provide a short write up here, but please bear in mind that I haven't really taken a look into it since July and never bothered to fix it in not-grocy, as this is a non-issue for me and thus very low on my priority list.

Anyway:

First, I tried shoe-horning zxing into a quagga plugin. This was kind of cumbersome, and while zxing decodes DataMatrix without problem, the detection completely failed on me. It might be worth a shot to just borrow the code instead of trying to use zxing as a dependency; but back then my typescript knowledge was basically nonexistent and I gave up after fighting with the toolchain for a considerable amount of time. I've since grown comfortable with ts; so I guess I'd fare better in a second attempt, but currently don't have the time to spare. I think I still have my attempt at this somewhere, if I find it, I'll push it somewhere.

I also tried compiling libdmtx with emscripten to use it in the browser. I got it to compile, but never got it to work in the browser. I don't really recall what the problem was; I think it had something to do with typescript not finding some types and me scratching my head about it. Sorry. However, I have found that code and attached a patch of my changes (applicable to 2eaece1100dc5bc5d28356814a1ab43f45f2c132). Unfortunately, I have absolutely no clue what my intent with it was / how I thought this should be used.

If I were to try it again, I'd give emscripten another shot, now that I have learned considerably more typescript. But I am already deep in task saturation, so I'll gladly leave that to anyone who is interested.

Good Luck!

diff --git a/dmtx.c b/dmtx.c
index a5b949a..29e4dca 100644
--- a/dmtx.c
+++ b/dmtx.c
@@ -24,6 +24,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <math.h>
+#include <emscripten.h>
 #include "dmtx.h"
 #include "dmtxstatic.h"
 
@@ -89,3 +90,11 @@ dmtxVersion(void)
 {
    return DmtxVersion;
 }
+
+// caller frees.
+EMSCRIPTEN_KEEPALIVE
+char* DmtxGetDecodedString(DmtxMessage *msg) {
+	char* ret = (char*)calloc(msg->outputIdx + 1, sizeof(unsigned char));
+	memcpy(ret, msg->output, msg->outputIdx);
+	return ret;
+}
diff --git a/dmtxdecode.c b/dmtxdecode.c
index 567d101..bbf3e0a 100644
--- a/dmtxdecode.c
+++ b/dmtxdecode.c
@@ -24,6 +24,7 @@
 
 #include <stdio.h> // for snprintf
 
+EMSCRIPTEN_KEEPALIVE
 extern DmtxDecode *
 dmtxDecodeCreate(DmtxImage *img, int scale)
 {
@@ -69,6 +70,7 @@ dmtxDecodeCreate(DmtxImage *img, int scale)
  * \param  dec
  * \return void
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxPassFail
 dmtxDecodeDestroy(DmtxDecode **dec)
 {
@@ -84,6 +86,20 @@ dmtxDecodeDestroy(DmtxDecode **dec)
 
    return DmtxPass;
 }
+EMSCRIPTEN_KEEPALIVE
+extern DmtxPassFail
+dmtxDecodeDestroySimple(DmtxDecode *dec)
+{
+   if(dec == NULL)
+      return DmtxFail;
+
+   if((dec)->cache != NULL)
+      free((dec)->cache);
+
+   free(dec);
+
+   return DmtxPass;
+}
 
 /**
  * \brief  Set decoding behavior property
@@ -327,6 +343,7 @@ CacheFillQuad(DmtxDecode *dec, DmtxPixelLoc p0, DmtxPixelLoc p1, DmtxPixelLoc p2
  * \param  fix
  * \return Decoded message
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxMessage *
 dmtxDecodeMatrixRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
 {
@@ -363,7 +380,9 @@ dmtxDecodeMatrixRegion(DmtxDecode *dec, DmtxRegion *reg, int fix)
    pxBottomRight.X = (int)(0.5 + bottomRight.X);
    pxBottomRight.Y = (int)(0.5 + bottomRight.Y);
 
+   printf("libdmtx::dmtxDecodeMatrixRegion()-Before Cache Fill\n");
    CacheFillQuad(dec, pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft);
+   printf("libdmtx::dmtxDecodeMatrixRegion()-After Cache Fill\n");
 
    return dmtxDecodePopulatedArray(reg->sizeIdx, msg, fix);
 }
diff --git a/dmtximage.c b/dmtximage.c
index bb1b9cf..f2d0cae 100644
--- a/dmtximage.c
+++ b/dmtximage.c
@@ -59,6 +59,7 @@
  * \param  XXX
  * \return XXX
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxImage *
 dmtxImageCreate(unsigned char *pxl, int width, int height, int pack)
 {
@@ -147,6 +148,7 @@ dmtxImageCreate(unsigned char *pxl, int width, int height, int pack)
  * \param  img pointer to img location
  * \return DmtxFail | DmtxPass
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxPassFail
 dmtxImageDestroy(DmtxImage **img)
 {
diff --git a/dmtxmessage.c b/dmtxmessage.c
index 217d8e7..0ca0990 100644
--- a/dmtxmessage.c
+++ b/dmtxmessage.c
@@ -77,6 +77,7 @@ dmtxMessageCreate(int sizeIdx, int symbolFormat)
  * \param  message
  * \return void
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxPassFail
 dmtxMessageDestroy(DmtxMessage **msg)
 {
@@ -98,3 +99,22 @@ dmtxMessageDestroy(DmtxMessage **msg)
 
    return DmtxPass;
 }
+
+EMSCRIPTEN_KEEPALIVE
+extern DmtxPassFail
+dmtxMessageDestroySimple(DmtxMessage *msg) {
+   if(msg == NULL)
+      return DmtxFail;
+
+   if((msg)->array != NULL)
+      free((msg)->array);
+
+   if((msg)->code != NULL)
+      free((msg)->code);
+
+   if((msg)->output != NULL)
+      free((msg)->output);
+
+   free(msg);
+   return DmtxPass;
+}
diff --git a/dmtxregion.c b/dmtxregion.c
index b51461c..bbf5e57 100644
--- a/dmtxregion.c
+++ b/dmtxregion.c
@@ -22,6 +22,7 @@
  * \param  None
  * \return Initialized DmtxRegion struct
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxRegion *
 dmtxRegionCreate(DmtxRegion *reg)
 {
@@ -41,6 +42,7 @@ dmtxRegionCreate(DmtxRegion *reg)
  * \param  reg
  * \return void
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxPassFail
 dmtxRegionDestroy(DmtxRegion **reg)
 {
@@ -60,6 +62,7 @@ dmtxRegionDestroy(DmtxRegion **reg)
  * \param  timeout Pointer to timeout time (NULL if none)
  * \return Detected region (if found)
  */
+EMSCRIPTEN_KEEPALIVE
 extern DmtxRegion *
 dmtxRegionFindNext(DmtxDecode *dec, DmtxTime *timeout)
 {

hackathi avatar Nov 05 '21 17:11 hackathi

hmm. i haven't got the slightest idea what any of that is about :-D

@tmaex @mistressofjellyfish if either of you would like to attach some sample barcode images that you would actually use with a reader, that would be helpful to get started

ericblade avatar Nov 05 '21 23:11 ericblade

Good news: I found the code I had when toying around with zxing. I've pushed it here: https://github.com/mistressofjellyfish/quagga2-reader-datamatrix

As with the libdmtx stuff I have no clue about what state this is in or even if this is the latest version I had.

hackathi avatar Nov 06 '21 01:11 hackathi

sweet! thank you

ericblade avatar Nov 06 '21 01:11 ericblade