/// <summary> /// Gets the decoded codeword value. /// </summary> /// <returns>The decoded codeword value.</returns> /// <param name="moduleBitCount">Module bit count.</param> private static int GetDecodedCodewordValue(int[] moduleBitCount) { int decodedValue = GetBitValue(moduleBitCount); return(PDF417Common.GetCodeword(decodedValue) == PDF417Common.INVALID_CODEWORD ? PDF417Common.INVALID_CODEWORD : decodedValue); }
/// <summary> /// Detects the codeword. /// </summary> /// <returns>The codeword.</returns> /// <param name="image">Image.</param> /// <param name="minColumn">Minimum column.</param> /// <param name="maxColumn">Max column.</param> /// <param name="leftToRight">If set to <c>true</c> left to right.</param> /// <param name="startColumn">Start column.</param> /// <param name="imageRow">Image row.</param> /// <param name="minCodewordWidth">Minimum codeword width.</param> /// <param name="maxCodewordWidth">Max codeword width.</param> private static Codeword DetectCodeword(BitMatrix image, int minColumn, int maxColumn, bool leftToRight, int startColumn, int imageRow, int minCodewordWidth, int maxCodewordWidth) { startColumn = AdjustCodewordStartColumn(image, minColumn, maxColumn, leftToRight, startColumn, imageRow); // we usually know fairly exact now how long a codeword is. We should provide minimum and maximum expected Length // and try to adjust the read pixels, e.g. remove single pixel errors or try to cut off exceeding pixels. // min and maxCodewordWidth should not be used as they are calculated for the whole barcode an can be inaccurate // for the current position int[] moduleBitCount = GetModuleBitCount(image, minColumn, maxColumn, leftToRight, startColumn, imageRow); if (moduleBitCount == null) { return(null); } int endColumn; int codewordBitCount = PDF417Common.GetBitCountSum(moduleBitCount); if (leftToRight) { endColumn = startColumn + codewordBitCount; } else { for (int i = 0; i < moduleBitCount.Length >> 1; i++) { int tmpCount = moduleBitCount[i]; moduleBitCount[i] = moduleBitCount[moduleBitCount.Length - 1 - i]; moduleBitCount[moduleBitCount.Length - 1 - i] = tmpCount; } endColumn = startColumn; startColumn = endColumn - codewordBitCount; } // TODO implement check for width and correction of black and white bars // use start (and maybe stop pattern) to determine if blackbars are wider than white bars. If so, adjust. // should probably done only for codewords with a lot more than 17 bits. // The following fixes 10-1.png, which has wide black bars and small white bars // for (int i = 0; i < moduleBitCount.Length; i++) { // if (i % 2 == 0) { // moduleBitCount[i]--; // } else { // moduleBitCount[i]++; // } // } // We could also use the width of surrounding codewords for more accurate results, but this seems // sufficient for now if (!CheckCodewordSkew(codewordBitCount, minCodewordWidth, maxCodewordWidth)) { // We could try to use the startX and endX position of the codeword in the same column in the previous row, // create the bit count from it and normalize it to 8. This would help with single pixel errors. return(null); } int decodedValue = PDF417CodewordDecoder.GetDecodedValue(moduleBitCount); int codeword = PDF417Common.GetCodeword(decodedValue); if (codeword == -1) { return(null); } return(new Codeword(startColumn, endColumn, GetCodewordBucketNumber(decodedValue), codeword)); }