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
/**
 * \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;
}