private void Fail(List <object> output, Exception cause)
        {
            if (!(cause is DecoderException))
            {
                cause = new DecoderException(cause);
            }

            Checkpoint(EState.Failure);

            ISocks5Message m = new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.Failure);

            m.SetDecoderResult(DecoderResult.Failure(cause));
            output.Add(m);
        }
Example #2
0
        IHttpContent InvalidChunk(IByteBuffer buf, Exception cause)
        {
            this.currentState = State.BadMessage;

            // Advance the readerIndex so that ByteToMessageDecoder does not complain
            // when we produced an invalid message without consuming anything.
            buf.SkipBytes(buf.ReadableBytes);

            IHttpContent chunk = new DefaultLastHttpContent(Unpooled.Empty);

            chunk.Result = DecoderResult.Failure(cause);
            this.message = null;
            this.trailer = null;
            return(chunk);
        }
Example #3
0
        public void ResponseWithBadHeader()
        {
            var ch = new EmbeddedChannel(new HttpResponseDecoder());

            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("HTTP/1.0 200 Maybe OK\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("Good_Name: Good Value\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("Bad=Name: Bad Value\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("\r\n")));
            var           res = ch.ReadInbound <IHttpResponse>();
            DecoderResult dr  = res.Result;

            Assert.NotNull(dr);
            Assert.False(dr.IsSuccess);
            Assert.True(dr.IsFailure);
            Assert.Equal("Maybe OK", res.Status.ReasonPhrase);
            Assert.Equal("Good Value", res.Headers.Get((AsciiString)"Good_Name", null).ToString());
            this.EnsureInboundTrafficDiscarded(ch);
        }
Example #4
0
        public void RequestWithBadHeader()
        {
            var ch = new EmbeddedChannel(new HttpRequestDecoder());

            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("GET /maybe-something HTTP/1.0\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("Good_Name: Good Value\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("Bad=Name: Bad Value\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("\r\n")));
            var           req = ch.ReadInbound <IHttpRequest>();
            DecoderResult dr  = req.Result;

            Assert.NotNull(dr);
            Assert.False(dr.IsSuccess);
            Assert.True(dr.IsFailure);
            Assert.Equal("Good Value", req.Headers.Get((AsciiString)"Good_Name", null).ToString());
            Assert.Equal("/maybe-something", req.Uri);
            this.EnsureInboundTrafficDiscarded(ch);
        }
Example #5
0
        private void Fail(List <object> output, Exception cause)
        {
            if (!(cause is DecoderException))
            {
                cause = new DecoderException(cause);
            }

            Checkpoint(Socks5CommandRequestDecoderState.Failure);

            ISocks5Message m = new DefaultSocks5CommandRequest(
                Socks5CommandType.Connect,
                Socks5AddressType.Pv4,
                "0.0.0.0",
                1);

            m.SetDecoderResult(DecoderResult.Failure(cause));
            output.Add(m);
        }
Example #6
0
        public void ReplaceAggregatedResponse()
        {
            var ch = new EmbeddedChannel(new HttpObjectAggregator(1024 * 1024));

            var boom = new Exception("boom");
            var rep  = new DefaultHttpResponse(HttpVersion.Http11, HttpResponseStatus.OK);

            rep.Result = DecoderResult.Failure(boom);

            Assert.True(ch.WriteInbound(rep) && ch.Finish());

            var aggregatedRep = ch.ReadInbound <IFullHttpResponse>();
            var replacedRep   = (IFullHttpResponse)aggregatedRep.Replace(Unpooled.Empty);

            Assert.Equal(replacedRep.Result, aggregatedRep.Result);
            aggregatedRep.Release();
            replacedRep.Release();
        }
Example #7
0
        public void ReplaceAggregatedRequest()
        {
            var ch = new EmbeddedChannel(new HttpObjectAggregator(1024 * 1024));

            var boom = new Exception("boom");
            var req  = new DefaultHttpRequest(HttpVersion.Http11, HttpMethod.Get, "http://localhost");

            req.Result = DecoderResult.Failure(boom);

            Assert.True(ch.WriteInbound(req) && ch.Finish());

            var aggregatedReq = ch.ReadInbound <IFullHttpRequest>();
            var replacedReq   = (IFullHttpRequest)aggregatedReq.Replace(Unpooled.Empty);

            Assert.Equal(replacedReq.Result, aggregatedReq.Result);
            aggregatedReq.Release();
            replacedReq.Release();
        }
        private void Fail(List <object> output, Exception cause)
        {
            if (!(cause is DecoderException))
            {
                cause = new DecoderException(cause);
            }

            Checkpoint(Socks5CommandResponseDecoderState.Failure);

            ISocks5Message m = new DefaultSocks5CommandResponse(
                Socks5CommandStatus.Failure,
                Socks5AddressType.Pv4,
                null,
                0);

            m.SetDecoderResult(DecoderResult.Failure(cause));
            output.Add(m);
        }
Example #9
0
        public void BadChunk()
        {
            var ch = new EmbeddedChannel(new HttpRequestDecoder());

            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("GET / HTTP/1.0\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("Transfer-Encoding: chunked\r\n\r\n")));
            ch.WriteInbound(Unpooled.CopiedBuffer(Encoding.UTF8.GetBytes("BAD_LENGTH\r\n")));
            var           req = ch.ReadInbound <IHttpRequest>();
            DecoderResult dr  = req.Result;

            Assert.NotNull(dr);
            Assert.True(dr.IsSuccess);
            var chunk = ch.ReadInbound <ILastHttpContent>();

            dr = chunk.Result;
            Assert.False(dr.IsSuccess);
            Assert.True(dr.IsFailure);
            this.EnsureInboundTrafficDiscarded(ch);
        }
Example #10
0
        IHttpMessage InvalidMessage(IByteBuffer buf, Exception cause)
        {
            _currentState = State.BadMessage;

            // Advance the readerIndex so that ByteToMessageDecoder does not complain
            // when we produced an invalid message without consuming anything.
            _ = buf.SkipBytes(buf.ReadableBytes);

            if (_message is null)
            {
                _message = CreateInvalidMessage();
            }
            _message.Result = DecoderResult.Failure(cause);

            IHttpMessage ret = _message;

            _message = null;
            return(ret);
        }
        public override string ToString()
        {
            var buf = new StringBuilder(StringUtil.SimpleClassName(this));

            if (!DecoderResult.IsSuccess())
            {
                buf.Append("(decoderResult: ");
                buf.Append(DecoderResult);
                buf.Append(", username: "******"(username: "******", password: ****)");

            return(buf.ToString());
        }
Example #12
0
        public override string ToString()
        {
            var buf = new StringBuilder(StringUtil.SimpleClassName(this));

            if (!DecoderResult.IsSuccess())
            {
                buf.Append("(decoderResult: ");
                buf.Append(DecoderResult);
                buf.Append(", authMethods: ");
            }
            else
            {
                buf.Append("(authMethods: ");
            }

            buf.Append(AuthMethods);
            buf.Append(')');

            return(buf.ToString());
        }
        private void Fail(List <object> output, Exception cause)
        {
            if (!(cause is DecoderException))
            {
                cause = new DecoderException(cause);
            }

            ISocks4CommandRequest m = new DefaultSocks4CommandRequest(
                _type ?? Socks4CommandType.Connect,
                _dstAddr ?? "",
                _dstPort != 0
                    ? _dstPort
                    : 65535,
                _userId ?? "");

            m.SetDecoderResult(DecoderResult.Failure(cause));
            output.Add(m);

            Checkpoint(Socks4ServerDecoderState.Failure);
        }
Example #14
0
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public com.google.zxing.Result[] decodeMultiple(com.google.zxing.BinaryBitmap image, java.util.Map<com.google.zxing.DecodeHintType,?> hints) throws com.google.zxing.NotFoundException
        public Result[] decodeMultiple(BinaryBitmap image, IDictionary <DecodeHintType, object> hints)
        {
            List <Result> results = new List <Result>();

            DetectorResult[] detectorResults = (new MultiDetector(image.BlackMatrix)).detectMulti(hints);
            foreach (DetectorResult detectorResult in detectorResults)
            {
                try
                {
                    DecoderResult   decoderResult = Decoder.decode(detectorResult.Bits, hints);
                    ResultPoint[]   points        = detectorResult.Points;
                    Result          result        = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.QR_CODE);
                    IList <sbyte[]> byteSegments  = decoderResult.ByteSegments;
                    if (byteSegments != null)
                    {
                        result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
                    }
                    string ecLevel = decoderResult.ECLevel;
                    if (ecLevel != null)
                    {
                        result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
                    }
                    results.Add(result);
                }
                catch (ReaderException re)
                {
                    // ignore and continue
                }
            }
            if (results.Count == 0)
            {
                return(EMPTY_RESULT_ARRAY);
            }
            else
            {
                return(results.ToArray());
            }
        }
        /// <summary>
        /// Decodes the codewords.
        /// </summary>
        /// <returns>The codewords.</returns>
        /// <param name="codewords">Codewords.</param>
        /// <param name="ecLevel">Ec level.</param>
        /// <param name="erasures">Erasures.</param>
        private static DecoderResult DecodeCodewords(int[] codewords, int ecLevel, int[] erasures)
        {
            if (codewords.Length == 0)
            {
                throw ReaderException.Instance;
            }

            int numECCodewords = 1 << (ecLevel + 1);

            Log.WriteLine("EC level: " + ecLevel + ", ec codewords: " + numECCodewords);

            int correctedErrorsCount = CorrectErrors(codewords, erasures, numECCodewords);

            Log.WriteLine("Corrected errors: " + correctedErrorsCount);
            VerifyCodewordCount(codewords, numECCodewords);

            // Decode the codewords
            DecoderResult decoderResult = DecodedBitStreamParser.Decode(codewords);

            decoderResult.ErrorsCorrected = (correctedErrorsCount >= 0) ? correctedErrorsCount : 0;
            decoderResult.Erasures        = erasures.Length;
            return(decoderResult);
        }
        public void testStandardSample3()
        {
            PDF417ResultMetadata resultMetadata = new PDF417ResultMetadata();

            int[] sampleCodes = { 7, 928, 111, 100, 100, 200, 300,
                                  0 }; // Final dummy ECC codeword required to avoid ArrayIndexOutOfBounds

            DecodedBitStreamParser.decodeMacroBlock(sampleCodes, 2, resultMetadata);

            Assert.AreEqual(0, resultMetadata.SegmentIndex);
            Assert.AreEqual("100200300", resultMetadata.FileId);
            Assert.False(resultMetadata.IsLastSegment);
            Assert.AreEqual(-1, resultMetadata.SegmentCount);
            Assert.IsNull(resultMetadata.Addressee);
            Assert.IsNull(resultMetadata.Sender);
            Assert.IsNull(resultMetadata.OptionalData);

            // Check that symbol containing no data except Macro is accepted (see note in Annex H.2)
            DecoderResult decoderResult = DecodedBitStreamParser.decode(sampleCodes, "0");

            Assert.AreEqual("", decoderResult.Text);
            Assert.IsNotNull(decoderResult.Other);
        }
Example #17
0
        public override string ToString()
        {
            var buf = new StringBuilder(96);

            buf.Append(StringUtil.SimpleClassName(this));

            if (!DecoderResult.IsSuccess())
            {
                buf.Append("(decoderResult: ");
                buf.Append(DecoderResult);
                buf.Append(", dstAddr: ");
            }
            else
            {
                buf.Append("(dstAddr: ");
            }

            buf.Append(DstAddr);
            buf.Append(", dstPort: ");
            buf.Append(DstPort);
            buf.Append(')');

            return(buf.ToString());
        }
Example #18
0
        /// <summary>
        /// Decode the specified image, with the hints and optionally multiple barcodes.
        /// Based on Owen's Comments in <see cref="ZXing.ReaderException"/>, this method has been modified to continue silently
        /// if a barcode was not decoded where it was detected instead of throwing a new exception object.
        /// </summary>
        /// <param name="image">Image.</param>
        /// <param name="hints">Hints.</param>
        /// <param name="multiple">If set to <c>true</c> multiple.</param>
        private static Result[] decode(BinaryBitmap image, IDictionary <DecodeHintType, object> hints, bool multiple)
        {
            List <Result>        results        = new List <Result>();
            PDF417DetectorResult detectorResult = Detector.detect(image, hints, multiple);

            foreach (ResultPoint[] points in detectorResult.Points)
            {
                DecoderResult decoderResult = PDF417ScanningDecoder.decode(detectorResult.Bits, points[4], points[5],
                                                                           points[6], points[7], getMinCodewordWidth(points), getMaxCodewordWidth(points));
                if (decoderResult == null)
                {
                    continue;
                }
                Result result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.PDF_417);
                result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, decoderResult.ECLevel);
                PDF417ResultMetadata pdf417ResultMetadata = (PDF417ResultMetadata)decoderResult.Other;
                if (pdf417ResultMetadata != null)
                {
                    result.putMetadata(ResultMetadataType.PDF417_EXTRA_METADATA, pdf417ResultMetadata);
                }
                results.Add(result);
            }
            return(results.ToArray());
        }
Example #19
0
        internal static DecoderResult decode(int[] codewords, String ecLevel)
        {
            var result = new StringBuilder(codewords.Length * 2);
            // Get compaction mode
            int      codeIndex      = 1;
            int      code           = codewords[codeIndex++];
            var      resultMetadata = new PDF417ResultMetadata();
            Encoding encoding       = null;

            while (codeIndex < codewords[0])
            {
                switch (code)
                {
                case TEXT_COMPACTION_MODE_LATCH:
                    codeIndex = textCompaction(codewords, codeIndex, result);
                    break;

                case BYTE_COMPACTION_MODE_LATCH:
                case BYTE_COMPACTION_MODE_LATCH_6:
                    codeIndex = byteCompaction(code, codewords, encoding ?? (encoding = getEncoding(PDF417HighLevelEncoder.DEFAULT_ENCODING_NAME)), codeIndex, result);
                    break;

                case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
                    result.Append((char)codewords[codeIndex++]);
                    break;

                case NUMERIC_COMPACTION_MODE_LATCH:
                    codeIndex = numericCompaction(codewords, codeIndex, result);
                    break;

                case ECI_CHARSET:
                    var charsetECI = CharacterSetECI.getCharacterSetECIByValue(codewords[codeIndex++]);
                    encoding = getEncoding(charsetECI.EncodingName);
                    break;

                case ECI_GENERAL_PURPOSE:
                    // Can't do anything with generic ECI; skip its 2 characters
                    codeIndex += 2;
                    break;

                case ECI_USER_DEFINED:
                    // Can't do anything with user ECI; skip its 1 character
                    codeIndex++;
                    break;

                case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
                    codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata);
                    break;

                case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
                case MACRO_PDF417_TERMINATOR:
                    // Should not see these outside a macro block
                    return(null);

                default:
                    // Default to text compaction. During testing numerous barcodes
                    // appeared to be missing the starting mode. In these cases defaulting
                    // to text compaction seems to work.
                    codeIndex--;
                    codeIndex = textCompaction(codewords, codeIndex, result);
                    break;
                }
                if (codeIndex < 0)
                {
                    return(null);
                }
                if (codeIndex < codewords.Length)
                {
                    code = codewords[codeIndex++];
                }
                else
                {
                    return(null);
                }
            }

            if (result.Length == 0)
            {
                return(null);
            }

            var decoderResult = new DecoderResult(null, result.ToString(), null, ecLevel);

            decoderResult.Other = resultMetadata;
            return(decoderResult);
        }
Example #20
0
 public void SetDecoderResult(DecoderResult decoderResult)
 {
     DecoderResult = decoderResult;
 }
Example #21
0
        /// <summary>
        ///  Locates and decodes a Data Matrix code in an image.
        /// </summary>
        /// <param name="image">image of barcode to decode</param>
        /// <param name="hints">passed as a {@link java.util.Hashtable} from {@link com.google.zxing.DecodeHintType}
        /// to arbitrary data. The
        /// meaning of the data depends upon the hint type. The implementation may or may not do
        /// anything with these hints.</param>
        /// <returns>
        /// String which the barcode encodes
        /// </returns>
        public Result decode(BinaryBitmap image, IDictionary <DecodeHintType, object> hints)
        {
            var blackmatrix = image.BlackMatrix;

            if (blackmatrix == null)
            {
                return(null);
            }

            Detector detector = new Detector(blackmatrix);

            ResultPoint[] points        = null;
            DecoderResult decoderResult = null;

            var detectorResult = detector.detect(false);

            if (detectorResult != null)
            {
                points = detectorResult.Points;

                decoderResult = new Decoder().decode(detectorResult);
            }
            if (decoderResult == null)
            {
                detectorResult = detector.detect(true);
                if (detectorResult == null)
                {
                    return(null);
                }

                points        = detectorResult.Points;
                decoderResult = new Decoder().decode(detectorResult);
                if (decoderResult == null)
                {
                    return(null);
                }
            }

            if (hints != null &&
                hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
            {
                var rpcb = (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
                if (rpcb != null)
                {
                    foreach (var point in points)
                    {
                        rpcb(point);
                    }
                }
            }

            var result = new Result(decoderResult.Text, decoderResult.RawBytes, points, BarcodeFormat.AZTEC);

            IList <byte[]> byteSegments = decoderResult.ByteSegments;

            if (byteSegments != null)
            {
                result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
            }
            var ecLevel = decoderResult.ECLevel;

            if (ecLevel != null)
            {
                result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
            }

            result.putMetadata(ResultMetadataType.AZTEC_EXTRA_METADATA,
                               new AztecResultMetadata(detectorResult.Compact, detectorResult.NbDatablocks, detectorResult.NbLayers));

            return(result);
        }
        internal static DecoderResult decode(int[] codewords, String ecLevel)
        {
            var result = new StringBuilder(codewords.Length * 2);
            // Get compaction mode
            int codeIndex      = 1;
            int code           = codewords[codeIndex++];
            var resultMetadata = new PDF417ResultMetadata();

            while (codeIndex < codewords[0])
            {
                switch (code)
                {
                case TEXT_COMPACTION_MODE_LATCH:
                    codeIndex = textCompaction(codewords, codeIndex, result);
                    break;

                case BYTE_COMPACTION_MODE_LATCH:
                    codeIndex = byteCompaction(code, codewords, codeIndex, result);
                    break;

                case NUMERIC_COMPACTION_MODE_LATCH:
                    codeIndex = numericCompaction(codewords, codeIndex, result);
                    break;

                case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
                    codeIndex = byteCompaction(code, codewords, codeIndex, result);
                    break;

                case BYTE_COMPACTION_MODE_LATCH_6:
                    codeIndex = byteCompaction(code, codewords, codeIndex, result);
                    break;

                case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
                    codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata);
                    break;

                case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
                case MACRO_PDF417_TERMINATOR:
                    // Should not see these outside a macro block
                    return(null);

                default:
                    // Default to text compaction. During testing numerous barcodes
                    // appeared to be missing the starting mode. In these cases defaulting
                    // to text compaction seems to work.
                    codeIndex--;
                    codeIndex = textCompaction(codewords, codeIndex, result);
                    break;
                }
                if (codeIndex < 0)
                {
                    return(null);
                }
                if (codeIndex < codewords.Length)
                {
                    code = codewords[codeIndex++];
                }
                else
                {
                    return(null);
                }
            }

            if (result.Length == 0)
            {
                return(null);
            }

            var decoderResult = new DecoderResult(null, result.ToString(), null, ecLevel);

            decoderResult.Other = resultMetadata;
            return(decoderResult);
        }
 internal ComposedLastHttpContent(HttpHeaders trailingHeaders, DecoderResult result)
     : this(trailingHeaders)
 {
     this.result = result;
 }
Example #24
0
        /// <summary>
        ///  Locates and decodes a Data Matrix code in an image.
        /// </summary>
        /// <param name="image">image of barcode to decode</param>
        /// <param name="hints">passed as a {@link java.util.Hashtable} from {@link com.google.zxing.DecodeHintType}
        /// to arbitrary data. The
        /// meaning of the data depends upon the hint type. The implementation may or may not do
        /// anything with these hints.</param>
        /// <returns>
        /// String which the barcode encodes
        /// </returns>
        public Result decode(BinaryBitmap image, IDictionary <DecodeHintType, object> hints)
        {
            var blackmatrix = image.BlackMatrix;

            if (blackmatrix == null)
            {
                return(null);
            }

            Detector detector = new Detector(blackmatrix);

            ResultPoint[] points        = null;
            DecoderResult decoderResult = null;

            var detectorResult = detector.detect(false);

            if (detectorResult != null)
            {
                points = detectorResult.Points;

                decoderResult = new Decoder().decode(detectorResult);
            }
            if (detectorResult != null && decoderResult == null)
            {
                // errors in (known) alignment lines
                var matrix               = detectorResult.Bits;
                int alignmentErrors      = 0;
                int totalAlignmentPoints = 0;
                for (int y = (matrix.Height >> 1) & 0xf; y < matrix.Height; y += 16)
                {
                    for (int x = 0; x < matrix.Width; ++x)
                    {
                        bool correctVal = ((matrix.Width >> 1) & 1) == (x & 1);
                        if (matrix[x, y] != correctVal)
                        {
                            alignmentErrors++;
                        }
                        if (matrix[y, x] != correctVal)
                        {
                            alignmentErrors++;
                        }
                        totalAlignmentPoints += 2;
                    }
                }
                float alignmentErorRatio = ((float)alignmentErrors / totalAlignmentPoints);
                System.Diagnostics.Debug.WriteLine("alignment errors: " + alignmentErorRatio.ToString());

                // this is the best improvement in algorithm: !!!
                // split scanned matrix into areas divided by alignment lines,
                // collect best areas from multiple camera shots (best - scoring by calculating
                // how good the alignment lines around the area are), and compile the entire matrix
                // from all best areas
                var areaBorders = new List <int> {
                    0
                };                                 // inclusive values
                for (int y = (matrix.Height >> 1) & 0xf; y < matrix.Height; y += 16)
                {
                    areaBorders.Add(y);
                }
                areaBorders.Add(matrix.Height - 1);
                var areas = new List <Tuple <Detector.Point, Detector.Point, Detector.Point, Detector.Point, float> >();
                for (int i = 0; i + 1 < areaBorders.Count; ++i)
                {
                    for (int j = 0; j + 1 < areaBorders.Count; ++j)
                    {
                        var p1 = new Detector.Point(areaBorders[i], areaBorders[j]);
                        var p2 = new Detector.Point(areaBorders[i + 1], areaBorders[j]);
                        var p3 = new Detector.Point(areaBorders[i + 1], areaBorders[j + 1]);
                        var p4 = new Detector.Point(areaBorders[i], areaBorders[j + 1]);

                        int numErrors = 0;
                        int numTotal  = 0;
                        if (areaBorders[i] != 0)
                        {
                            for (int y = areaBorders[j]; y <= areaBorders[j + 1]; ++y)
                            {
                                numTotal++;
                                bool correctVal = ((matrix.Height >> 1) & 1) == (y & 1);
                                if (matrix[areaBorders[i], y] != correctVal)
                                {
                                    numErrors++;
                                }
                            }
                        }
                        if (areaBorders[i + 1] != matrix.Width)
                        {
                            for (int y = areaBorders[j]; y <= areaBorders[j + 1]; ++y)
                            {
                                numTotal++;
                                bool correctVal = ((matrix.Height >> 1) & 1) == (y & 1);
                                if (matrix[areaBorders[i + 1], y] != correctVal)
                                {
                                    numErrors++;
                                }
                            }
                        }
                        if (areaBorders[j] != 0)
                        {
                            for (int x = areaBorders[i]; x <= areaBorders[i + 1]; ++x)
                            {
                                numTotal++;
                                bool correctVal = ((matrix.Width >> 1) & 1) == (x & 1);
                                if (matrix[x, areaBorders[j]] != correctVal)
                                {
                                    numErrors++;
                                }
                            }
                        }
                        if (areaBorders[j + 1] != matrix.Height)
                        {
                            for (int x = areaBorders[i]; x <= areaBorders[i + 1]; ++x)
                            {
                                numTotal++;
                                bool correctVal = ((matrix.Width >> 1) & 1) == (x & 1);
                                if (matrix[x, areaBorders[j + 1]] != correctVal)
                                {
                                    numErrors++;
                                }
                            }
                        }

                        float errorRatio = (float)numErrors / numTotal;
                        areas.Add(Tuple.Create(p1, p2, p3, p4, errorRatio));
                    }
                }

                if (bestAreas == null)
                {
                    bestAreas = new Dictionary <string, Tuple <BitMatrix, float> >();
                }

                bool hasBetterBest = false;
                foreach (var area in areas)
                {
                    var ar        = Tuple.Create(area.Item1, area.Item2, area.Item3, area.Item4).ToString();
                    var errorRate = area.Item5;
                    if (bestAreas.ContainsKey(ar) == false || bestAreas[ar].Item2 >= errorRate)
                    {
                        var areaMatrix = new BitMatrix(area.Item2.X - area.Item1.X + 1, area.Item3.Y - area.Item2.Y + 1);
                        for (int xp = 0; xp < areaMatrix.Width; ++xp)
                        {
                            for (int yp = 0; yp < areaMatrix.Height; ++yp)
                            {
                                areaMatrix[xp, yp] = matrix[xp + area.Item1.X, yp + area.Item1.Y];
                            }
                        }
                        if (bestAreas.ContainsKey(ar) == true)
                        {
                            hasBetterBest = true;
                        }
                        bestAreas[ar] = Tuple.Create(areaMatrix, errorRate);
                    }
                }

                if (hasBetterBest)
                {
                    var matrixFromBestAreas = new BitMatrix(matrix.Dimension);
                    foreach (var area in areas)
                    {
                        var p1         = area.Item1;
                        var areaMatrix = bestAreas[Tuple.Create(area.Item1, area.Item2, area.Item3, area.Item4).ToString()].Item1;
                        for (int xp = 0; xp < areaMatrix.Width; ++xp)
                        {
                            for (int yp = 0; yp < areaMatrix.Height; ++yp)
                            {
                                matrixFromBestAreas[xp + p1.X, yp + p1.Y] = areaMatrix[xp, yp];
                            }
                        }
                    }
                    var composedResult = new AztecDetectorResult(matrixFromBestAreas, detectorResult.Points, detectorResult.Compact, detectorResult.NbDatablocks, detectorResult.NbLayers);
                    decoderResult = new Decoder().decode(composedResult);
                    if (decoderResult != null)
                    {
                        bestAreas = null;
                        System.Diagnostics.Debug.WriteLine("got from composed");
                    }
                }
            }
            if (decoderResult == null)
            {
                // I don't need mirrors
                //detectorResult = detector.detect(true);
                //if (detectorResult == null)
                //   return null;

                //points = detectorResult.Points;
                //decoderResult = new Decoder().decode(detectorResult);
                //if (decoderResult == null)
                return(null);
            }

            if (hints != null &&
                hints.ContainsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK))
            {
                var rpcb = (ResultPointCallback)hints[DecodeHintType.NEED_RESULT_POINT_CALLBACK];
                if (rpcb != null)
                {
                    foreach (var point in points)
                    {
                        rpcb(point);
                    }
                }
            }

            var result = new Result(decoderResult.Text, decoderResult.RawBytes, decoderResult.NumBits, points, BarcodeFormat.AZTEC);

            IList <byte[]> byteSegments = decoderResult.ByteSegments;

            if (byteSegments != null)
            {
                result.putMetadata(ResultMetadataType.BYTE_SEGMENTS, byteSegments);
            }
            var ecLevel = decoderResult.ECLevel;

            if (ecLevel != null)
            {
                result.putMetadata(ResultMetadataType.ERROR_CORRECTION_LEVEL, ecLevel);
            }

            result.putMetadata(ResultMetadataType.AZTEC_EXTRA_METADATA,
                               new AztecResultMetadata(detectorResult.Compact, detectorResult.NbDatablocks, detectorResult.NbLayers));

            return(result);
        }