DataMatrix 2D code libdmtx.dll wrapper (encode only)

Share your advanced PureBasic knowledge/code with the community.
AAT
Enthusiast
Enthusiast
Posts: 256
Joined: Sun Jun 15, 2008 3:13 am
Location: Russia

DataMatrix 2D code libdmtx.dll wrapper (encode only)

Post by AAT »

Hi.
I needed to generate datamatrix codes for laser marking on steel and i found the library libdmtx.dll.
It's old, but it works fine.

DLL+LIB+example

Code: Select all

; libdmtx.dll wrapper for PureBasic (encode only)
; libdmtx home: http://libdmtx.sourceforge.net/
; AAT, 18.06.2017

#DmtxVersion            = "0.7.2"

#DmtxUndefined          = -1
#DmtxPass               = 1
#DmtxFail               = 0
#DmtxTrue               = 1
#DmtxFalse              = 0

#DmtxFormatMatrix       = 0
#DmtxFormatMosaic       = 1

#DmtxSymbolSquareCount  = 24
#DmtxSymbolRectCount    = 6

#DmtxModuleOff          = 0
#DmtxModuleOnRed        = $01
#DmtxModuleOnGreen      = $02
#DmtxModuleOnBlue       = $04
#DmtxModuleOnRGB        = $07
#DmtxModuleOn           = $07
#DmtxModuleUnsure       = $08
#DmtxModuleAssigned     = $10
#DmtxModuleVisited      = $20
#DmtxModuleData         = $40

; DmtxScheme
#DmtxSchemeAutoFast     = -2
#DmtxSchemeAutoBest     = -1
#DmtxSchemeAscii        = 0
#DmtxSchemeC40          = 1
#DmtxSchemeText         = 2
#DmtxSchemeX12          = 3
#DmtxSchemeEdifact      = 4
#DmtxSchemeBase256      = 5

#DmtxPropScheme         = 100
#DmtxPropSizeRequest    = 101
#DmtxPropMarginSize     = 102
#DmtxPropModuleSize     = 103

; Decoding properties
#DmtxPropEdgeMin        = 200
#DmtxPropEdgeMax        = 201
#DmtxPropScanGap        = 202
#DmtxPropSquareDevn     = 203
#DmtxPropSymbolSize     = 204
#DmtxPropEdgeThresh     = 205

; Image properties
#DmtxPropWidth          = 300
#DmtxPropHeight         = 301
#DmtxPropPixelPacking   = 302
#DmtxPropBitsPerPixel   = 303
#DmtxPropBytesPerPixel  = 304
#DmtxPropRowPadBytes    = 305
#DmtxPropRowSizeBytes   = 306
#DmtxPropImageFlip      = 307
#DmtxPropChannelCount   = 308

; Image modifiers
#DmtxPropXmin           = 400
#DmtxPropXmax           = 401
#DmtxPropYmin           = 402
#DmtxPropYmax           = 403
#DmtxPropScale          = 404

#DmtxSymbolRectAuto     = -3 
#DmtxSymbolSquareAuto   = -2 
#DmtxSymbolShapeAuto    = -1
Enumeration
  #DmtxSymbol10x10        
  #DmtxSymbol12x12 
  #DmtxSymbol14x14 
  #DmtxSymbol16x16 
  #DmtxSymbol18x18 
  #DmtxSymbol20x20 
  #DmtxSymbol22x22 
  #DmtxSymbol24x24 
  #DmtxSymbol26x26 
  #DmtxSymbol32x32 
  #DmtxSymbol36x36 
  #DmtxSymbol40x40 
  #DmtxSymbol44x44 
  #DmtxSymbol48x48 
  #DmtxSymbol52x52 
  #DmtxSymbol64x64 
  #DmtxSymbol72x72 
  #DmtxSymbol80x80 
  #DmtxSymbol88x88 
  #DmtxSymbol96x96 
  #DmtxSymbol104x104 
  #DmtxSymbol120x120 
  #DmtxSymbol132x132 
  #DmtxSymbol144x144 
  #DmtxSymbol8x18 
  #DmtxSymbol8x32 
  #DmtxSymbol12x26 
  #DmtxSymbol12x36 
  #DmtxSymbol16x36
  #DmtxSymbol16x48
  EndEnumeration
   
Enumeration
;Custom format
  #DmtxPackCustom      = 100
;1 bpp
  #DmtxPack1bppK       = 200
  ; 8 bpp grayscale
  #DmtxPack8bppK       = 300
;16 bpp formats 
  #DmtxPack16bppRGB    = 400
  #DmtxPack16bppRGBX
  #DmtxPack16bppXRGB
  #DmtxPack16bppBGR
  #DmtxPack16bppBGRX
  #DmtxPack16bppXBGR
  #DmtxPack16bppYCbCr
;24 bpp formats 
  #DmtxPack24bppRGB    = 500
  #DmtxPack24bppBGR
  #DmtxPack24bppYCbCr
;32 bpp formats */
  #DmtxPack32bppRGBX   = 600
  #DmtxPack32bppXRGB
  #DmtxPack32bppBGRX
  #DmtxPack32bppXBGR
  #DmtxPack32bppCMYK
EndEnumeration
 
#DmtxFlipNone           = 0
#DmtxFlipX              = 1
#DmtxFlipY              = 2

Structure DmtxMatrix3 Align #PB_Structure_AlignC
  val.d[9]
EndStructure  

Structure DmtxPixelLoc
  X.i
  Y.i
EndStructure
 
Structure DmtxMessage Align #PB_Structure_AlignC
  arraySize.i         ; unsigned int size_t
  codeSize.i          ; unsigned int size_t
  outputSize.i        ; unsigned int size_t
  outputIdx.i 
  padCount.i
  *Array
  *code
  *output
EndStructure;

Structure DmtxImage Align #PB_Structure_AlignC
  width.i
  height.i
  pixelPacking.i
  bitsPerPixel.i
  bytesPerPixel.i
  rowPadBytes.i
  rowSizeBytes.i
  imageFlip.i
  channelCount.i
  channelStart.i[4]
  bitsPerChannel.i[4]    
  *pxl 
EndStructure

Structure DmtxPointFlow Align #PB_Structure_AlignC
  plane.i 
  arrive.i
  depart.i
  mag.i
  loc.DmtxPixelLoc
EndStructure

Structure DmtxBestLine Align #PB_Structure_AlignC
  angle.i
  hOffset.i
  mag.i
  stepBeg.i
  stepPos.i
  stepNeg.i
  distSq.i
  devn.i 
  locBeg.DmtxPixelLoc
  locPos.DmtxPixelLoc
  locNeg.DmtxPixelLoc
EndStructure

Structure DmtxRegion Align #PB_Structure_AlignC
;Trail blazing values
  jumpToPos.i
  jumpToNeg.i
  stepsTotal.i
  finalPos.DmtxPixelLoc
  finalNeg.DmtxPixelLoc
  boundMin.DmtxPixelLoc 
  boundMax.DmtxPixelLoc
  flowBegin.DmtxPointFlow
;Orientation values
  polarity.i
  stepR.i
  stepT.i
  locR.DmtxPixelLoc
  locT.DmtxPixelLoc
;Region fitting values */
  leftKnown.i
  leftAngle.i 
  leftLoc.DmtxPixelLoc
  leftLine.DmtxBestLine 
  bottomKnown.i
  bottomAngle.i
  bottomLoc.DmtxPixelLoc
  bottomLine.DmtxBestLine
  topKnown.i
  topAngle.i
  topLoc.DmtxPixelLoc
  rightKnown.i
  rightAngle.i
  rightLoc.DmtxPixelLoc
;Region calibration values
  onColor.i
  offColor.i
  sizeIdx.i 
  symbolRows.i
  symbolCols.i
  mappingRows.i
  mappingCols.i
;Transform values */
  raw2fit.DmtxMatrix3
  fit2raw.DmtxMatrix3
 EndStructure

Structure DmtxEncode Align #PB_Structure_AlignC
  method.i 
  scheme.i 
  sizeIdxRequest.i 
  marginSize.i
  moduleSize.i
  pixelPacking.i
  imageFlip.i
  rowPadBytes.i
  *message.DmtxMessage
  *image.DmtxImage
  region.DmtxRegion
  xfrm.DmtxMatrix3
  rxfrm.DmtxMatrix3
EndStructure

ImportC "libdmtx.lib"
  dmtxEncodeCreate() As "dmtxEncodeCreate"
  dmtxEncodeDataMatrix(*enc, buflen.l, *bufaddr) As "dmtxEncodeDataMatrix"
  dmtxEncodeDestroy(*enc) As "dmtxEncodeDestroy"  
  dmtxEncodeGetProp(*enc, prop.l) As "dmtxEncodeGetProp"
  dmtxEncodeSetProp(*enc, prop.l, value.l) As "dmtxEncodeSetProp"   
  dmtxImageGetProp(*img.DmtxImage, prop.l) As "dmtxImageGetProp"
EndImport

Enumeration
  #BWimage
  #MosaicColor
  #MosaicGray  
  #Rainbow
EndEnumeration

message2encode.s = "libdmtx.dll wrapper for PureBasic (encode only)"
marginSize = 20;
moduleSize = 10;
save2file = #True
colored = #MosaicColor

*asciibuf = Ascii(message2encode)
*enc.DmtxEncode = dmtxEncodeCreate(); 
If *enc = #Null
  MessageRequester("Error", "DmtxEncode create error") 
Else
; Set encoding options
  err = dmtxEncodeSetProp(*enc, #DmtxPropMarginSize, marginSize);
  err = dmtxEncodeSetProp(*enc, #DmtxPropModuleSize, moduleSize);
  err = dmtxEncodeSetProp(*enc, #DmtxPropSizeRequest, #DmtxSymbolSquareAuto)  
  err = dmtxEncodeSetProp(*enc, #DmtxPropScheme, #DmtxSchemeAscii)
; Encode   
  err = dmtxEncodeDataMatrix(*enc, Len(message2encode), *asciibuf)
  If err = #DmtxTrue
    imgWidth = dmtxImageGetProp(*enc\image, #DmtxPropWidth)
    imgHeight = dmtxImageGetProp(*enc\image, #DmtxPropHeight)
    bytesPerPixel = dmtxImageGetProp(*enc\image, #DmtxPropBytesPerPixel)
    imwXbpp = imgWidth * bytesPerPixel
    dmtxImageID = CreateImage(#PB_Any, imgWidth, imgHeight, 24, $FFFFFF)     
    StartDrawing(ImageOutput(dmtxImageID))         
    DrawingMode(#PB_2DDrawing_Default)    
    y = 0
    While y < imgHeight
      x=0 : xpic=0 : yXimwXbpp = y * imwXbpp
      While x < imwXbpp
        If PeekC(*enc\image\pxl + x + yXimwXbpp)<>0       
          Plot(xpic, y, $FFFFFF)
        Else
          Select colored
            Case #BWimage
              Plot(xpic, y, $000000)
            Case #MosaicGray, #MosaicColor  
              If (y % moduleSize) = 0
                If (xpic % moduleSize) = 0  
                  If colored = #MosaicColor
                    color = RGB(Random(130), Random(130), Random(130))
                  Else
                    r = Random(120) : color = RGB(r, r, r)
                  EndIf                  
                EndIf  
              Else
                color = Point(xpic, y-1)
              EndIf         
              Plot(xpic, y, color)               
            Case #Rainbow
              Plot(xpic, y, RGB(255-y/2, 3*xpic/4, y/2))
            Default
              Plot(xpic, y, $000000)
          EndSelect 
        EndIf    
        x + bytesPerPixel : xpic + 1    
      Wend  
      y + 1  
    Wend     
    StopDrawing() 
    If save2file
      SaveImage(dmtxImageID, GetCurrentDirectory() + message2encode + ".bmp",#PB_ImagePlugin_BMP)   
    EndIf        
    err = dmtxEncodeDestroy(@*enc);    
    If OpenWindow(0, 10, 10, ImageWidth(dmtxImageID), ImageHeight(dmtxImageID)+50, "dmtxEncode", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
      TextGadget(1, 5, 10, 220, 20, message2encode)
      ImageGadget(2, 0, 50, ImageWidth(dmtxImageID), ImageHeight(dmtxImageID), ImageID(dmtxImageID))
      Repeat
        Event = WindowEvent()          
        Delay(10)
      Until Event = #PB_Event_CloseWindow
    EndIf  
  Else
    MessageRequester("Error", "Unable to encode the message (possibly too large for requested size)")     
  EndIf
EndIf
Enjoy!