Beispiel #1
0
 private DmtxEncode(DmtxEncode src)
 {
     this._scheme = src._scheme;
     this._sizeIdxRequest = src._sizeIdxRequest;
     this._marginSize = src._marginSize;
     this._moduleSize = src._moduleSize;
     this._pixelPacking = src._pixelPacking;
     this._imageFlip = src._imageFlip;
     this._rowPadBytes = src._rowPadBytes;
     this._image = src._image;
     this._message = src._message;
     this._method = src._method;
     this._region = src._region;
 }
Beispiel #2
0
        private List <string> DecodeImage(Bitmap image, int maxResultCount, TimeSpan timeOut, bool isMosaic)
        {
            List <string> result = new List <string>();
            int           stride;

            byte[]    rawImg  = ImageToByteArray(image, out stride);
            DmtxImage dmtxImg = new DmtxImage(rawImg, image.Width, image.Height, DmtxPackOrder.DmtxPack24bppRGB);

            dmtxImg.RowPadBytes = stride % 3;
            DmtxDecode decode    = new DmtxDecode(dmtxImg, 1);
            TimeSpan   timeLeft  = new TimeSpan(timeOut.Ticks);
            Stopwatch  stopWatch = new Stopwatch();

            stopWatch.Start();
            while (true)
            {
                if (stopWatch.Elapsed > timeOut)
                {
                    break;
                }
                DmtxRegion region = decode.RegionFindNext(timeOut);
                if (region != null)
                {
                    DmtxMessage msg     = isMosaic ? decode.MosaicRegion(region, -1) : decode.MatrixRegion(region, -1);
                    string      message = Encoding.ASCII.GetString(msg.Output);
                    message = message.Substring(0, message.IndexOf('\0'));
                    if (!result.Contains(message))
                    {
                        result.Add(message);
                        if (result.Count >= maxResultCount)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            return(result);
        }
Beispiel #3
0
        internal static void GenReedSolEcc(DmtxMessage message, DmtxSymbolSize sizeIdx)
        {
            byte[] g      = new byte[69];
            byte[] b      = new byte[68];
            int    bIndex = 0;;

            int symbolDataWords  = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx);
            int symbolErrorWords = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolErrorWords, sizeIdx);
            int symbolTotalWords = symbolDataWords + symbolErrorWords;
            int blockErrorWords  = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribBlockErrorWords, sizeIdx);
            int step             = GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribInterleavedBlocks, sizeIdx);

            if (blockErrorWords != symbolErrorWords / step)
            {
                throw new Exception("Error generation reed solomon error correction");
            }

            for (int gI = 0; gI < g.Length; gI++)
            {
                g[gI] = 0x01;
            }

            // Generate ECC polynomia
            for (int i = 1; i <= blockErrorWords; i++)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    g[j] = GfDoublify(g[j], i);     // g[j] *= 2**i
                    if (j > 0)
                    {
                        g[j] = GfSum(g[j], g[j - 1]);  // g[j] += g[j-1]
                    }
                }
            }

            // Populate error codeword array
            for (int block = 0; block < step; block++)
            {
                for (int bI = 0; bI < b.Length; bI++)
                {
                    b[bI] = 0;
                }

                for (int i = block; i < symbolDataWords; i += step)
                {
                    int val = GfSum(b[blockErrorWords - 1], message.Code[i]);
                    for (int j = blockErrorWords - 1; j > 0; j--)
                    {
                        b[j] = GfSum(b[j - 1], GfProduct(g[j], val));
                    }
                    b[0] = GfProduct(g[0], val);
                }

                int blockDataWords = GetBlockDataSize(sizeIdx, block);
                bIndex = blockErrorWords;

                for (int i = block + (step * blockDataWords); i < symbolTotalWords; i += step)
                {
                    message.Code[i] = b[--bIndex];
                }

                if (bIndex != 0)
                {
                    throw new Exception("Error generation error correction code!");
                }
            }
        }
Beispiel #4
0
        internal DmtxMessage MosaicRegion(DmtxRegion reg, int fix)
        {
            DmtxMessage oMsg;

            int colorPlane = reg.FlowBegin.Plane;

            reg.FlowBegin.Plane = 0; /* kind of a hack */
            DmtxMessage rMsg = MatrixRegion(reg, fix);

            reg.FlowBegin.Plane = 1; /* kind of a hack */
            DmtxMessage gMsg = MatrixRegion(reg, fix);

            reg.FlowBegin.Plane = 2; /* kind of a hack */
            DmtxMessage bMsg = MatrixRegion(reg, fix);

            reg.FlowBegin.Plane = colorPlane;

            oMsg = new DmtxMessage(reg.SizeIdx, DmtxFormat.Mosaic);

            List<byte> totalMessage = new List<byte>();
            for (int i = 0; i < bMsg.OutputSize; i++)
            {
                if (bMsg.Output[i] == 0)
                {
                    break;
                }
                totalMessage.Add(bMsg.Output[i]);
            }
            for (int i = 0; i < gMsg.OutputSize; i++)
            {
                if (gMsg.Output[i] == 0)
                {
                    break;
                }
                totalMessage.Add(gMsg.Output[i]);
            }
            for (int i = 0; i < rMsg.OutputSize; i++)
            {
                if (rMsg.Output[i] == 0)
                {
                    break;
                }
                totalMessage.Add(rMsg.Output[i]);
            }
            totalMessage.Add(0);
            oMsg.Output = totalMessage.ToArray();
            return oMsg;
        }
Beispiel #5
0
        internal DmtxMessage MatrixRegion(DmtxRegion reg, int fix)
        {
            DmtxMessage result = new DmtxMessage(reg.SizeIdx, DmtxFormat.Matrix);
            DmtxVector2 topLeft = new DmtxVector2();
            DmtxVector2 topRight = new DmtxVector2();
            DmtxVector2 bottomLeft = new DmtxVector2();
            DmtxVector2 bottomRight = new DmtxVector2();
            DmtxPixelLoc pxTopLeft = new DmtxPixelLoc();
            DmtxPixelLoc pxTopRight = new DmtxPixelLoc();
            DmtxPixelLoc pxBottomLeft = new DmtxPixelLoc();
            DmtxPixelLoc pxBottomRight = new DmtxPixelLoc();

            if (!PopulateArrayFromMatrix(reg, result))
            {
                throw new Exception("Populating Array from matrix failed!");
            }

            /* maybe place remaining logic into new dmtxDecodePopulatedArray()
               function so other people can pass in their own arrays */

            ModulePlacementEcc200(result.Array, result.Code,
                  reg.SizeIdx, DmtxConstants.DmtxModuleOnRed | DmtxConstants.DmtxModuleOnGreen | DmtxConstants.DmtxModuleOnBlue);

            if (DmtxCommon.DecodeCheckErrors(result.Code, 0, reg.SizeIdx, fix) != true)
            {
                return null;
            }

            topLeft.X = bottomLeft.X = topLeft.Y = topRight.Y = -0.1;
            topRight.X = bottomRight.X = bottomLeft.Y = bottomRight.Y = 1.1;

            topLeft *= reg.Fit2raw;
            topRight *= reg.Fit2raw;
            bottomLeft *= reg.Fit2raw;
            bottomLeft *= reg.Fit2raw;

            pxTopLeft.X = (int)(0.5 + topLeft.X);
            pxTopLeft.Y = (int)(0.5 + topLeft.Y);
            pxBottomLeft.X = (int)(0.5 + bottomLeft.X);
            pxBottomLeft.Y = (int)(0.5 + bottomLeft.Y);
            pxTopRight.X = (int)(0.5 + topRight.X);
            pxTopRight.Y = (int)(0.5 + topRight.Y);
            pxBottomRight.X = (int)(0.5 + bottomRight.X);
            pxBottomRight.Y = (int)(0.5 + bottomRight.Y);

            CacheFillQuad(pxTopLeft, pxTopRight, pxBottomRight, pxBottomLeft);

            result.DecodeDataStream(reg.SizeIdx, null);

            return result;
        }
Beispiel #6
0
        private bool PopulateArrayFromMatrix(DmtxRegion reg, DmtxMessage msg)
        {
            /* Capture number of regions present in barcode */
            int xRegionTotal = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribHorizDataRegions, reg.SizeIdx);
            int yRegionTotal = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribVertDataRegions, reg.SizeIdx);

            /* Capture region dimensions (not including border modules) */
            int mapWidth = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionCols, reg.SizeIdx);
            int mapHeight = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribDataRegionRows, reg.SizeIdx);

            int weightFactor = 2 * (mapHeight + mapWidth + 2);
            if (weightFactor <= 0)
            {
                throw new ArgumentException("PopulateArrayFromMatrix error: Weight Factor must be greater 0");
            }

            /* Tally module changes for each region in each direction */
            for (int yRegionCount = 0; yRegionCount < yRegionTotal; yRegionCount++)
            {

                /* Y location of mapping region origin in symbol coordinates */
                int yOrigin = yRegionCount * (mapHeight + 2) + 1;

                for (int xRegionCount = 0; xRegionCount < xRegionTotal; xRegionCount++)
                {
                    int[,] tally = new int[24, 24]; /* Large enough to map largest single region */
                    /* X location of mapping region origin in symbol coordinates */
                    int xOrigin = xRegionCount * (mapWidth + 2) + 1;

                    for (int i = 0; i < 24; i++)
                    {
                        for (int j = 0; j < 24; j++)
                        {
                            tally[i, j] = 0;
                        }
                    }
                    TallyModuleJumps(reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirection.DmtxDirUp);
                    TallyModuleJumps(reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirection.DmtxDirLeft);
                    TallyModuleJumps(reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirection.DmtxDirDown);
                    TallyModuleJumps(reg, tally, xOrigin, yOrigin, mapWidth, mapHeight, DmtxDirection.DmtxDirRight);

                    /* Decide module status based on final tallies */
                    for (int mapRow = 0; mapRow < mapHeight; mapRow++)
                    {
                        for (int mapCol = 0; mapCol < mapWidth; mapCol++)
                        {

                            int rowTmp = (yRegionCount * mapHeight) + mapRow;
                            rowTmp = yRegionTotal * mapHeight - rowTmp - 1;
                            int colTmp = (xRegionCount * mapWidth) + mapCol;
                            int idx = (rowTmp * xRegionTotal * mapWidth) + colTmp;

                            if (tally[mapRow, mapCol] / (double)weightFactor >= 0.5)
                                msg.Array[idx] = (byte)DmtxConstants.DmtxModuleOnRGB;
                            else
                                msg.Array[idx] = (byte)DmtxConstants.DmtxModuleOff;

                            msg.Array[idx] |= (byte)DmtxConstants.DmtxModuleAssigned;
                        }
                    }
                }
            }

            return true;
        }
Beispiel #7
0
        internal bool EncodeDataMatrix(Color? foreColor, Color? backColor, byte[] inputString)
        {
            int padCount;
            int width, height, bitsPerPixel;
            byte[] buf = new byte[4096];
            byte[] pxl;

            /* Encode input string into data codewords */
            DmtxSymbolSize sizeIdx = this._sizeIdxRequest;
            int dataWordCount = EncodeDataCodewords(buf, inputString, ref sizeIdx);
            if (dataWordCount <= 0)
            {
                return false;
            }

            /* EncodeDataCodewords() should have updated any auto sizeIdx to a real one */
            if (sizeIdx == DmtxSymbolSize.DmtxSymbolSquareAuto || sizeIdx == DmtxSymbolSize.DmtxSymbolRectAuto)
            {
                throw new Exception("Invalid symbol size for encoding!");
            }

            /* Add pad characters to match a standard symbol size (whether smallest or requested) */
            padCount = AddPadChars(buf, ref dataWordCount, DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolDataWords, sizeIdx));

            /* XXX we can remove a lot of this redundant data */
            this._region = new DmtxRegion();
            this._region.SizeIdx = sizeIdx;
            this._region.SymbolRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolRows, sizeIdx);
            this._region.SymbolCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribSymbolCols, sizeIdx);
            this._region.MappingRows = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixRows, sizeIdx);
            this._region.MappingCols = DmtxCommon.GetSymbolAttribute(DmtxSymAttribute.DmtxSymAttribMappingMatrixCols, sizeIdx);

            /* Allocate memory for message and array */
            this._message = new DmtxMessage(sizeIdx, DmtxFormat.Matrix);
            this._message.PadCount = padCount;
            for (int i = 0; i < dataWordCount; i++)
            {
                this._message.Code[i] = buf[i];
            }

            /* Generate error correction codewords */
            DmtxCommon.GenReedSolEcc(this._message, this._region.SizeIdx);

            /* Module placement in region */
            DmtxDecode.ModulePlacementEcc200(this._message.Array, this._message.Code,
                  this._region.SizeIdx, DmtxConstants.DmtxModuleOnRGB);

            width = 2 * this._marginSize + (this._region.SymbolCols * this._moduleSize);
            height = 2 * this._marginSize + (this._region.SymbolRows * this._moduleSize);
            bitsPerPixel = DmtxCommon.GetBitsPerPixel(this._pixelPacking);
            if (bitsPerPixel == DmtxConstants.DmtxUndefined)
                return false;
            if (bitsPerPixel % 8 != 0)
            {
                throw new Exception("Invalid color depth for encoding!");
            }

            /* Allocate memory for the image to be generated */
            // pxl = (unsigned char *)malloc(width * height * (bitsPerPixel/8) + enc->rowPadBytes);
            pxl = new byte[width * height * (bitsPerPixel / 8) + this._rowPadBytes];

            this._image = new DmtxImage(pxl, width, height, this._pixelPacking);
            this._image.ImageFlip = this._imageFlip;
            this._image.RowPadBytes = this._rowPadBytes;

            /* Insert finder and aligment pattern modules */
            PrintPattern(foreColor, backColor);

            return true;
        }