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; }
/** * \brief Initialize decode struct with default values * \param img * \return Initialized DmtxDecode struct */ extern DmtxDecode * dmtxDecodeCreate(DmtxImage *img, int scale) { DmtxDecode *dec; int width, height; dec = (DmtxDecode *)calloc(1, sizeof(DmtxDecode)); if(dec == NULL) return NULL; width = dmtxImageGetProp(img, DmtxPropWidth) / scale; height = dmtxImageGetProp(img, DmtxPropHeight) / scale; dec->edgeMin = DmtxUndefined; dec->edgeMax = DmtxUndefined; dec->scanGap = 1; dec->squareDevn = cos(50 * (M_PI/180)); dec->sizeIdxExpected = DmtxSymbolShapeAuto; dec->edgeThresh = 10; dec->xMin = 0; dec->xMax = width - 1; dec->yMin = 0; dec->yMax = height - 1; dec->scale = scale; dec->cache = (unsigned char *)calloc(width * height, sizeof(unsigned char)); if(dec->cache == NULL) { free(dec); return NULL; } dec->image = img; dec->grid = InitScanGrid(dec); return dec; }
/** * \brief Get decoding behavior property * \param dec * \param prop * \return value */ extern int dmtxDecodeGetProp(DmtxDecode *dec, int prop) { switch(prop) { case DmtxPropEdgeMin: return dec->edgeMin; case DmtxPropEdgeMax: return dec->edgeMax; case DmtxPropScanGap: return dec->scanGap; case DmtxPropSquareDevn: return (int)(acos(dec->squareDevn) * 180.0/M_PI); case DmtxPropSymbolSize: return dec->sizeIdxExpected; case DmtxPropEdgeThresh: return dec->edgeThresh; case DmtxPropXmin: return dec->xMin; case DmtxPropXmax: return dec->xMax; case DmtxPropYmin: return dec->yMin; case DmtxPropYmax: return dec->yMax; case DmtxPropScale: return dec->scale; case DmtxPropWidth: return dmtxImageGetProp(dec->image, DmtxPropWidth) / dec->scale; case DmtxPropHeight: return dmtxImageGetProp(dec->image, DmtxPropHeight) / dec->scale; default: break; } return DmtxUndefined; }
/** * 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; }
extern unsigned char * dmtxDecodeCreateDiagnostic(DmtxDecode *dec, int *totalBytes, int *headerBytes, int style) { int i, row, col; int width, height; int widthDigits, heightDigits; int count, channelCount; int rgb[3]; double shade; unsigned char *pnm, *output, *cache; width = dmtxDecodeGetProp(dec, DmtxPropWidth); height = dmtxDecodeGetProp(dec, DmtxPropHeight); channelCount = dmtxImageGetProp(dec->image, DmtxPropChannelCount); style = 1; /* this doesn't mean anything yet */ /* Count width digits */ for(widthDigits = 0, i = width; i > 0; i /= 10) widthDigits++; /* Count height digits */ for(heightDigits = 0, i = height; i > 0; i /= 10) heightDigits++; *headerBytes = widthDigits + heightDigits + 9; *totalBytes = *headerBytes + width * height * 3; pnm = (unsigned char *)malloc(*totalBytes); if(pnm == NULL) return NULL; #ifdef _VISUALC_ count = sprintf_s((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); #else //count = snprintf((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); count = sprintf_s((char *)pnm, *headerBytes + 1, "P6\n%d %d\n255\n", width, height); #endif if(count != *headerBytes) { free(pnm); return NULL; } output = pnm + (*headerBytes); for(row = height - 1; row >= 0; row--) { for(col = 0; col < width; col++) { cache = dmtxDecodeGetCache(dec, col, row); if(cache == NULL) { rgb[0] = 0; rgb[1] = 0; rgb[2] = 128; } else if(*cache & 0x40) { rgb[0] = 255; rgb[1] = 0; rgb[2] = 0; } else { shade = (*cache & 0x80) ? 0.0 : 0.7; for(i = 0; i < 3; i++) { if(i < channelCount) dmtxDecodeGetPixelValue(dec, col, row, i, &rgb[i]); else dmtxDecodeGetPixelValue(dec, col, row, 0, &rgb[i]); rgb[i] += (int)(shade * (double)(255 - rgb[i]) + 0.5); if(rgb[i] > 255) rgb[i] = 255; } } *(output++) = (unsigned char)rgb[0]; *(output++) = (unsigned char)rgb[1]; *(output++) = (unsigned char)rgb[2]; } } assert(output == pnm + *totalBytes); return pnm; }
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 Write encoded message to image * \param enc * \return void */ static void PrintPattern(DmtxEncode *enc) { int i, j; int symbolRow, symbolCol; int pixelRow, pixelCol; int moduleStatus; size_t rowSize, height; int rgb[3]; double sxy, txy; DmtxMatrix3 m1, m2; DmtxVector2 vIn, vOut; txy = enc->marginSize; sxy = 1.0/enc->moduleSize; dmtxMatrix3Translate(m1, -txy, -txy); dmtxMatrix3Scale(m2, sxy, -sxy); dmtxMatrix3Multiply(enc->xfrm, m1, m2); dmtxMatrix3Translate(m1, txy, txy); dmtxMatrix3Scale(m2, enc->moduleSize, enc->moduleSize); dmtxMatrix3Multiply(enc->rxfrm, m2, m1); rowSize = dmtxImageGetProp(enc->image, DmtxPropRowSizeBytes); height = dmtxImageGetProp(enc->image, DmtxPropHeight); memset(enc->image->pxl, 0xff, rowSize * height); for(symbolRow = 0; symbolRow < enc->region.symbolRows; symbolRow++) { for(symbolCol = 0; symbolCol < enc->region.symbolCols; symbolCol++) { vIn.X = symbolCol; vIn.Y = symbolRow; dmtxMatrix3VMultiply(&vOut, &vIn, enc->rxfrm); pixelCol = (int)(vOut.X); pixelRow = (int)(vOut.Y); moduleStatus = dmtxSymbolModuleStatus(enc->message, enc->region.sizeIdx, symbolRow, symbolCol); if (enc->image->bytesPerPixel == 1) { for(i = pixelRow; i < pixelRow + enc->moduleSize; i++) { for(j = pixelCol; j < pixelCol + enc->moduleSize; j++) { rgb[0] = ((moduleStatus & DmtxModuleOnRed) != 0x00) ? 0 : 255; dmtxImageSetPixelValue(enc->image, j, i, 0, rgb[0]); } } } else { for(i = pixelRow; i < pixelRow + enc->moduleSize; i++) { for(j = pixelCol; j < pixelCol + enc->moduleSize; j++) { rgb[0] = ((moduleStatus & DmtxModuleOnRed) != 0x00) ? 0 : 255; rgb[1] = ((moduleStatus & DmtxModuleOnGreen) != 0x00) ? 0 : 255; rgb[2] = ((moduleStatus & DmtxModuleOnBlue) != 0x00) ? 0 : 255; /* dmtxImageSetRgb(enc->image, j, i, rgb); */ dmtxImageSetPixelValue(enc->image, j, i, 0, rgb[0]); dmtxImageSetPixelValue(enc->image, j, i, 1, rgb[1]); dmtxImageSetPixelValue(enc->image, j, i, 2, rgb[2]); } } } } } }