static VALUE rdmtx_encode(VALUE self, VALUE string) { /* Create and initialize libdmtx structures */ DmtxEncode * enc = dmtxEncodeCreate(); VALUE safeString = StringValue(string); dmtxEncodeSetProp(enc, DmtxPropPixelPacking, DmtxPack24bppRGB); dmtxEncodeSetProp(enc, DmtxPropSizeRequest, DmtxSymbolSquareAuto); /* Create barcode image */ if (dmtxEncodeDataMatrix(enc, RSTRING(safeString)->len, (unsigned char *)RSTRING(safeString)->ptr) == DmtxFail) { // printf("Fatal error !\n"); dmtxEncodeDestroy(&enc); return Qnil; } int width = dmtxImageGetProp(enc->image, DmtxPropWidth); int height = dmtxImageGetProp(enc->image, DmtxPropHeight); VALUE magickImageClass = rb_path2class("Magick::Image"); VALUE outputImage = rb_funcall(magickImageClass, rb_intern("new"), 2, INT2NUM(width), INT2NUM(height)); rb_funcall(outputImage, rb_intern("import_pixels"), 7, INT2NUM(0), INT2NUM(0), INT2NUM(width), INT2NUM(height), rb_str_new("RGB", 3), rb_str_new((char *)enc->image->pxl, 3*width*height), // rb_const_get("Magick" ,rb_intern("CharPixel")) rb_eval_string("Magick::CharPixel")); /* Clean up */ dmtxEncodeDestroy(&enc); return outputImage; }
static PyObject * dmtx_encode(PyObject *self, PyObject *arglist, PyObject *kwargs) { const unsigned char *data; int count = 0; int data_size = 0; int module_size = DmtxUndefined; int margin_size = DmtxUndefined; int scheme = DmtxUndefined; int shape = DmtxUndefined; PyObject *plotter = NULL; PyObject *start_cb = NULL; PyObject *finish_cb = NULL; PyObject *context = Py_None; PyObject *args; DmtxEncode *enc; int row, col; int rgb[3]; static char *kwlist[] = { "data", "module_size", "margin_size", "scheme", "shape", "plotter", "start", "finish", "context", NULL }; /* Parse out the options which are applicable */ PyObject *filtered_kwargs; filtered_kwargs = PyDict_New(); count = 1; /* Skip the first keyword as it is sent in arglist */ while(kwlist[count]){ if(PyDict_GetItemString(kwargs, kwlist[count])) { PyDict_SetItemString(filtered_kwargs, kwlist[count], PyDict_GetItemString(kwargs, kwlist[count])); } count++; } if(!PyArg_ParseTupleAndKeywords(arglist, filtered_kwargs, "s#iiii|OOOO", kwlist, &data, &data_size, &module_size, &margin_size, &scheme, &shape, &plotter, &start_cb, &finish_cb, &context)) return NULL; Py_INCREF(context); /* Plotter is required, and must be callable */ if(plotter == NULL || !PyCallable_Check(plotter)) { PyErr_SetString(PyExc_TypeError, "plotter must be callable"); return NULL; } enc = dmtxEncodeCreate(); if(enc == NULL) return NULL; dmtxEncodeSetProp(enc, DmtxPropPixelPacking, DmtxPack24bppRGB); dmtxEncodeSetProp(enc, DmtxPropImageFlip, DmtxFlipNone); if(scheme != DmtxUndefined) dmtxEncodeSetProp(enc, DmtxPropScheme, scheme); if(shape != DmtxUndefined) dmtxEncodeSetProp(enc, DmtxPropSizeRequest, shape); if(margin_size != DmtxUndefined) dmtxEncodeSetProp(enc, DmtxPropMarginSize, margin_size); if(module_size != DmtxUndefined) dmtxEncodeSetProp(enc, DmtxPropModuleSize, module_size); dmtxEncodeDataMatrix(enc, data_size, (unsigned char *)data); if((start_cb != NULL) && PyCallable_Check(start_cb)) { args = Py_BuildValue("(iiO)", enc->image->width, enc->image->height, context); (void)PyEval_CallObject(start_cb, args); Py_DECREF(args); } for(row = 0; row < enc->image->height; row++) { for(col = 0; col < enc->image->width; col++) { dmtxImageGetPixelValue(enc->image, col, row, 0, &rgb[0]); dmtxImageGetPixelValue(enc->image, col, row, 1, &rgb[1]); dmtxImageGetPixelValue(enc->image, col, row, 2, &rgb[2]); args = Py_BuildValue("(ii(iii)O)", col, row, rgb[0], rgb[1], rgb[2], context); (void)PyEval_CallObject(plotter, args); Py_DECREF(args); } } if((finish_cb != NULL) && PyCallable_Check(finish_cb)) { args = Py_BuildValue("(O)", context); (void)PyEval_CallObject(finish_cb, args); Py_DECREF(args); } dmtxEncodeDestroy(&enc); Py_DECREF(context); return Py_None; }
/** * Construct from ID (static factory method since JNI doesn't allow native * constructors). */ JNIEXPORT jobject JNICALL Java_org_libdmtx_DMTXImage_createTag(JNIEnv *aEnv, jclass aClass, jstring aID) { DmtxEncode *lEncoded; jclass lImageClass; jmethodID lConstructor; jobject lResult; jintArray lJavaData; int lW, lH, lBPP; jint *lPixels; /* Convert ID into string */ const char *sStrID = (*aEnv)->GetStringUTFChars(aEnv, aID, NULL); /* Create Data Matrix */ lEncoded = dmtxEncodeCreate(); dmtxEncodeSetProp(lEncoded, DmtxPropPixelPacking, DmtxPack32bppRGBX); dmtxEncodeSetProp(lEncoded, DmtxPropImageFlip, DmtxFlipNone); dmtxEncodeDataMatrix(lEncoded, strlen(sStrID), (unsigned char *)sStrID); /* Finished with ID, so release it */ (*aEnv)->ReleaseStringUTFChars(aEnv, aID, sStrID); /* Find DMTXImage class */ lImageClass = (*aEnv)->FindClass(aEnv, "org/libdmtx/DMTXImage"); if(lImageClass == NULL) return NULL; /* Find constructor */ lConstructor = (*aEnv)->GetMethodID(aEnv, lImageClass, "<init>", "(II[I)V"); if(lConstructor == NULL) return NULL; /* Get properties from image */ lW = dmtxImageGetProp(lEncoded->image, DmtxPropWidth); lH = dmtxImageGetProp(lEncoded->image, DmtxPropHeight); lBPP = dmtxImageGetProp(lEncoded->image, DmtxPropBytesPerPixel); if(lBPP != 4) return NULL; /* Copy Pixel Data */ lJavaData = (*aEnv)->NewIntArray(aEnv, lW * lH); lPixels = (*aEnv)->GetIntArrayElements(aEnv, lJavaData, NULL); memcpy(lPixels, lEncoded->image->pxl, lW * lH * 4); (*aEnv)->ReleaseIntArrayElements(aEnv, lJavaData, lPixels, 0); /* Create Image instance */ lResult = (*aEnv)->NewObject(aEnv, lImageClass, lConstructor, lW, lH, lJavaData); if(lResult == NULL) return NULL; /* Destroy original image */ dmtxEncodeDestroy(&lEncoded); /* Free local references */ (*aEnv)->DeleteLocalRef(aEnv, lJavaData); (*aEnv)->DeleteLocalRef(aEnv, lImageClass); return lResult; }
static VALUE rdmtx_encode(int argc, VALUE * argv, VALUE self) { VALUE string, margin, module, size; VALUE safeString; VALUE magickImageClass; VALUE outputImage; int safeMargin, safeModule, safeSize; int width; int height; DmtxEncode * enc; rb_scan_args(argc, argv, "13", &string, &margin, &module, &size); safeString = StringValue(string); if(NIL_P(margin)) { safeMargin = 5; } else { safeMargin = NUM2INT(margin); } if(NIL_P(module)) { safeModule = 5; } else { safeModule = NUM2INT(module); } if(NIL_P(size)) { safeSize = DmtxSymbolSquareAuto; } else { safeSize = NUM2INT(size); } // printf("Margin = %d, Module = %d, Size = %d\n", safeMargin, safeModule, safeSize); /* Create and initialize libdmtx structures */ enc = dmtxEncodeCreate(); dmtxEncodeSetProp(enc, DmtxPropPixelPacking, DmtxPack24bppRGB); dmtxEncodeSetProp(enc, DmtxPropSizeRequest, safeSize); dmtxEncodeSetProp(enc, DmtxPropMarginSize, safeMargin); dmtxEncodeSetProp(enc, DmtxPropModuleSize, safeModule); /* Create barcode image */ if (dmtxEncodeDataMatrix(enc, RSTRING_LEN(safeString), (unsigned char *)RSTRING_PTR(safeString)) == DmtxFail) { // printf("Fatal error !\n"); dmtxEncodeDestroy(&enc); return Qnil; } width = dmtxImageGetProp(enc->image, DmtxPropWidth); height = dmtxImageGetProp(enc->image, DmtxPropHeight); magickImageClass = rb_path2class("Magick::Image"); outputImage = rb_funcall(magickImageClass, rb_intern("new"), 2, INT2NUM(width), INT2NUM(height)); rb_funcall(outputImage, rb_intern("import_pixels"), 7, INT2NUM(0), INT2NUM(0), INT2NUM(width), INT2NUM(height), rb_str_new("RGB", 3), rb_str_new((char *)enc->image->pxl, 3*width*height), // rb_const_get("Magick" ,rb_intern("CharPixel")) rb_eval_string("Magick::CharPixel")); /* Clean up */ dmtxEncodeDestroy(&enc); return outputImage; }
void renderCodeDatamatrix(OROPage *page, const QRectF &qrect, const QString &qstr, ORBarcodeData * bc) { //5 pixel par carré //qreal pix = 5; //lecture du type de datamatrix QRegExp regex("[a-zA-Z]{10}_([0-9]{1,2})_([LCR]{1})"); regex.indexIn(bc->format); int type = regex.cap(1).toInt(); QString align = regex.cap(2); size_t width, height, bytesPerPixel; //pointer declaration unsigned char *pxl = NULL; DmtxEncode *enc = NULL; DmtxImage *img = NULL; ORORect *rect = NULL; int valeur = 0; /* 1) ENCODE a new Data Matrix barcode image (in memory only) */ enc = dmtxEncodeCreate(); //see DmtxSymbolSize in dmtx.h for more details enc->sizeIdxRequest = type; enc->marginSize = 0; //number of pixel for one square enc->moduleSize = 1; try { //assert(enc != NULL); dmtxEncodeDataMatrix(enc, qstr.size(), (unsigned char*)qstr.toStdString().c_str()); /* 2) COPY the new image data before releasing encoding memory */ width = dmtxImageGetProp(enc->image, DmtxPropWidth); height = dmtxImageGetProp(enc->image, DmtxPropHeight); bytesPerPixel = dmtxImageGetProp(enc->image, DmtxPropBytesPerPixel); if(width > 1000000000) { throw std::runtime_error("Code is to big for the Datamatrix"); } pxl = (unsigned char *)malloc(width * height * bytesPerPixel); //assert(pxl != NULL); memcpy(pxl, enc->image->pxl, width * height * bytesPerPixel); dmtxEncodeDestroy(&enc); /* 3) DECODE the Data Matrix barcode from the copied image */ img = dmtxImageCreate(pxl, width, height, DmtxPack24bppRGB); QPen pen(Qt::NoPen); QBrush brush(QColor("black")); qreal Xo = 0; qreal Yo = 0; //length of square qreal pas = 0; datamatrixGeometry(align,qrect,img,&Xo,&Yo,&pas); //draw the datamatrix for(int y = 0; y < img->height; y++) { for(int x = 0; x < img->width; x++) { dmtxImageGetPixelValue(img,x,y,0,&valeur); rect = new ORORect(bc); rect->setPen(pen); if(valeur == 0) { brush.setColor(Qt::black); rect->setBrush(brush); rect->setRect(QRectF( Xo + x*pas, Yo - y*pas, pas, pas)); rect->setRotationAxis(qrect.topLeft()); page->addPrimitive(rect); } } delete rect; } //memory cleanning free(pxl); dmtxEncodeDestroy(&enc); dmtxImageDestroy(&img); } catch(...) { //there is a problem with the datamatrix //RR is printed printRR(page,bc,qrect); //memory cleaning if(rect != NULL) { delete rect; } if(enc != NULL) { dmtxEncodeDestroy(&enc); } if(img != NULL) { dmtxImageDestroy(&img); } if(pxl!=NULL) { free(pxl); } } }
/** * \brief Convert message into Data Mosaic image * * 1) count how many codewords it would take to encode the whole thing * 2) take ceiling N of codeword count divided by 3 * 3) using minimum symbol size that can accomodate N codewords: * 4) create several barcodes over iterations of increasing numbers of * input codewords until you go one too far * 5) if codewords remain after filling R, G, and B barcodes then go back * to 3 and try with next larger size * 6) take the 3 different images you created and write out a new barcode * * \param enc * \param inputSize * \param inputString * \param sizeIdxRequest * \return DmtxPass | DmtxFail */ extern DmtxPassFail dmtxEncodeDataMosaic(DmtxEncode *enc, int inputSize, unsigned char *inputString) { unsigned char *inputStringR, *inputStringG, *inputStringB; int tmpInputSize; int inputSizeR, inputSizeG, inputSizeB; int sizeIdxAttempt, sizeIdxFirst, sizeIdxLast; int row, col, mappingRows, mappingCols; DmtxEncode *encR, *encG, *encB; /* Use 1/3 (ceiling) of inputSize establish input size target */ tmpInputSize = (inputSize + 2) / 3; inputSizeR = tmpInputSize; inputSizeG = tmpInputSize; inputSizeB = inputSize - (inputSizeR + inputSizeG); inputStringR = inputString; inputStringG = inputStringR + inputSizeR; inputStringB = inputStringG + inputSizeG; /* Use 1/3 (floor) of dataWordCount establish first symbol size attempt */ sizeIdxFirst = FindSymbolSize(tmpInputSize, enc->sizeIdxRequest); if(sizeIdxFirst == DmtxUndefined) return DmtxFail; /* Set the last possible symbol size for this symbol shape or specific size request */ if(enc->sizeIdxRequest == DmtxSymbolSquareAuto) sizeIdxLast = DmtxSymbolSquareCount - 1; else if(enc->sizeIdxRequest == DmtxSymbolRectAuto) sizeIdxLast = DmtxSymbolSquareCount + DmtxSymbolRectCount - 1; else sizeIdxLast = sizeIdxFirst; encR = encG = encB = NULL; /* Try increasing symbol sizes until 3 of them can hold all input values */ for(sizeIdxAttempt = sizeIdxFirst; sizeIdxAttempt <= sizeIdxLast; sizeIdxAttempt++) { dmtxEncodeDestroy(&encR); dmtxEncodeDestroy(&encG); dmtxEncodeDestroy(&encB); encR = dmtxEncodeCreate(); encG = dmtxEncodeCreate(); encB = dmtxEncodeCreate(); /* Copy all settings from master DmtxEncode, including pointer to image and message, which is initially null */ *encR = *encG = *encB = *enc; dmtxEncodeSetProp(encR, DmtxPropSizeRequest, sizeIdxAttempt); dmtxEncodeSetProp(encG, DmtxPropSizeRequest, sizeIdxAttempt); dmtxEncodeSetProp(encB, DmtxPropSizeRequest, sizeIdxAttempt); /* RED LAYER - Holds temporary copy */ dmtxEncodeDataMatrix(encR, inputSizeR, inputStringR); if(encR->region.sizeIdx != sizeIdxAttempt) continue; /* GREEN LAYER - Holds temporary copy */ dmtxEncodeDataMatrix(encG, inputSizeG, inputStringG); if(encG->region.sizeIdx != sizeIdxAttempt) continue; /* BLUE LAYER - Holds temporary copy */ dmtxEncodeDataMatrix(encB, inputSizeB, inputStringB); if(encB->region.sizeIdx != sizeIdxAttempt) continue; /* If we get this far we found a fit */ break; } if(encR == NULL || encG == NULL || encB == NULL) { dmtxEncodeDestroy(&encR); dmtxEncodeDestroy(&encG); dmtxEncodeDestroy(&encB); return DmtxFail; } /* Now we have the correct sizeIdxAttempt, and they all fit into the desired size */ /* Perform the red portion of the final encode to set internals correctly */ dmtxEncodeSetProp(enc, DmtxPropSizeRequest, sizeIdxAttempt); dmtxEncodeDataMatrix(enc, inputSizeR, inputStringR); /* Zero out the array and overwrite the bits in 3 passes */ mappingRows = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixRows, sizeIdxAttempt); mappingCols = dmtxGetSymbolAttribute(DmtxSymAttribMappingMatrixCols, sizeIdxAttempt); memset(enc->message->array, 0x00, sizeof(unsigned char) * enc->region.mappingRows * enc->region.mappingCols); ModulePlacementEcc200(enc->message->array, encR->message->code, sizeIdxAttempt, DmtxModuleOnRed); /* Reset DmtxModuleAssigned and DMX_MODULE_VISITED bits */ for(row = 0; row < mappingRows; row++) { for(col = 0; col < mappingCols; col++) { enc->message->array[row*mappingCols+col] &= (0xff ^ (DmtxModuleAssigned | DmtxModuleVisited)); } } ModulePlacementEcc200(enc->message->array, encG->message->code, sizeIdxAttempt, DmtxModuleOnGreen); /* Reset DmtxModuleAssigned and DMX_MODULE_VISITED bits */ for(row = 0; row < mappingRows; row++) { for(col = 0; col < mappingCols; col++) { enc->message->array[row*mappingCols+col] &= (0xff ^ (DmtxModuleAssigned | DmtxModuleVisited)); } } ModulePlacementEcc200(enc->message->array, encB->message->code, sizeIdxAttempt, DmtxModuleOnBlue); /* Destroy encR, encG, and encB */ dmtxEncodeDestroy(&encR); dmtxEncodeDestroy(&encG); dmtxEncodeDestroy(&encB); PrintPattern(enc); return DmtxPass; }