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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
    }
  }
}
Beispiel #6
0
/**
 * \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;
}