下面列出了com.google.zxing.common.BitArray#reverse ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
for (Pair left : possibleLeftPairs) {
if (left.getCount() > 1) {
for (Pair right : possibleRightPairs) {
if (right.getCount() > 1 && checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
for (Pair left : possibleLeftPairs) {
if (left.getCount() > 1) {
for (Pair right : possibleRightPairs) {
if (right.getCount() > 1 && checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
for (Pair left : possibleLeftPairs) {
if (left.getCount() > 1) {
for (Pair right : possibleRightPairs) {
if (right.getCount() > 1) {
if (checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
*/
private int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
*/
private int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
public Result decodeRow(int j, BitArray bitarray, Map map)
{
a a1 = a(bitarray, false, j, map);
a(h, a1);
bitarray.reverse();
a a2 = a(bitarray, true, j, map);
a(i, a2);
bitarray.reverse();
Iterator iterator = h.iterator();
a a3;
a a4;
label0:
do
{
if (iterator.hasNext())
{
a3 = (a)iterator.next();
if (a3.b() <= 1)
{
continue;
}
Iterator iterator1 = i.iterator();
do
{
if (!iterator1.hasNext())
{
continue label0;
}
a4 = (a)iterator1.next();
} while (a4.b() <= 1 || !b(a3, a4));
break;
} else
{
throw NotFoundException.getNotFoundInstance();
}
} while (true);
return a(a3, a4);
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
*/
private int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
* @throws NotFoundException
*/
int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
int lefSize = possibleLeftPairs.size();
for (int i = 0; i < lefSize; i++) {
Pair left = possibleLeftPairs.get(i);
if (left.getCount() > 1) {
int rightSize = possibleRightPairs.size();
for (int j = 0; j < rightSize; j++) {
Pair right = possibleRightPairs.get(j);
if (right.getCount() > 1) {
if (checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
* @throws NotFoundException
*/
int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
int lefSize = possibleLeftPairs.size();
for (int i = 0; i < lefSize; i++) {
Pair left = possibleLeftPairs.get(i);
if (left.getCount() > 1) {
int rightSize = possibleRightPairs.size();
for (int j = 0; j < rightSize; j++) {
Pair right = possibleRightPairs.get(j);
if (right.getCount() > 1) {
if (checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row
* row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
* @throws NotFoundException
*/
int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone.
// This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts &
// stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
@Override
public Result decodeRow(int rowNumber,
BitArray row,
Map<DecodeHintType,?> hints) throws NotFoundException {
Pair leftPair = decodePair(row, false, rowNumber, hints);
addOrTally(possibleLeftPairs, leftPair);
row.reverse();
Pair rightPair = decodePair(row, true, rowNumber, hints);
addOrTally(possibleRightPairs, rightPair);
row.reverse();
int lefSize = possibleLeftPairs.size();
for (int i = 0; i < lefSize; i++) {
Pair left = possibleLeftPairs.get(i);
if (left.getCount() > 1) {
int rightSize = possibleRightPairs.size();
for (int j = 0; j < rightSize; j++) {
Pair right = possibleRightPairs.get(j);
if (right.getCount() > 1) {
if (checkChecksum(left, right)) {
return constructResult(left, right);
}
}
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* Identify where the end of the middle / payload section ends.
*
* @param row row of black/white values to search
* @return Array, containing index of start of 'end block' and end of 'end
* block'
*/
private int[] decodeEnd(BitArray row) throws NotFoundException {
// For convenience, reverse the row and then
// search from 'the start' for the end block
row.reverse();
try {
int endStart = skipWhiteSpace(row);
int[] endPattern = findGuardPattern(row, endStart, END_PATTERN_REVERSED);
// The start & end patterns must be pre/post fixed by a quiet zone. This
// zone must be at least 10 times the width of a narrow line.
// ref: http://www.barcode-1.net/i25code.html
validateQuietZone(row, endPattern[0]);
// Now recalculate the indices of where the 'endblock' starts & stops to
// accommodate
// the reversed nature of the search
int temp = endPattern[0];
endPattern[0] = row.getSize() - endPattern[1];
endPattern[1] = row.getSize() - temp;
return endPattern;
} finally {
// Put the row back the right way.
row.reverse();
}
}
/**
* We're going to examine rows from the middle outward, searching alternately above and below the
* middle, and farther out each time. rowStep is the number of rows between each successive
* attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc.
* rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
* image if "trying harder".
*
* @param image The image to decode
* @param hints Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image,
Map<DecodeHintType,?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
int middle = height >> 1;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
}
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
int rowStepsAboveOrBelow = (x + 1) >> 1;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException nfe) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in the life of this method
// since we want to avoid drawing the wrong points after flipping the row, and,
// don't want to clutter with noise from every single row scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType,Object> newHints = new EnumMap<DecodeHintType,Object>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* We're going to examine rows from the middle outward, searching alternately above and below the
* middle, and farther out each time. rowStep is the number of rows between each successive
* attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc.
* rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
* image if "trying harder".
*
* @param image The image to decode
* @param hints Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image,
Map<DecodeHintType,?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
}
int middle = height / 2;
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
int rowStepsAboveOrBelow = (x + 1) / 2;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException ignored) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in the life of this method
// since we want to avoid drawing the wrong points after flipping the row, and,
// don't want to clutter with noise from every single row scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType,Object> newHints = new EnumMap<>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* We're going to examine rows from the middle outward, searching alternately above and below the
* middle, and farther out each time. rowStep is the number of rows between each successive
* attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc.
* rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
* image if "trying harder".
*
* @param image The image to decode
* @param hints Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image,
Map<DecodeHintType,?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
}
int middle = height / 2;
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
int rowStepsAboveOrBelow = (x + 1) / 2;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException ignored) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in the life of this method
// since we want to avoid drawing the wrong points after flipping the row, and,
// don't want to clutter with noise from every single row scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType,Object> newHints = new EnumMap<>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* We're going to examine rows from the middle outward, searching alternately above and below the
* middle, and farther out each time. rowStep is the number of rows between each successive
* attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc.
* rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
* image if "trying harder".
*
* @param image The image to decode
* @param hints Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image,
Map<DecodeHintType,?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
int middle = height >> 1;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
}
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
int rowStepsAboveOrBelow = (x + 1) / 2;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException ignored) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in the life of this method
// since we want to avoid drawing the wrong points after flipping the row, and,
// don't want to clutter with noise from every single row scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType,Object> newHints = new EnumMap<>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* We're going to examine rows from the middle outward, searching alternately above and below the
* middle, and farther out each time. rowStep is the number of rows between each successive
* attempt above and below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc.
* rowStep is bigger as the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty good; we try more of the
* image if "trying harder".
*
* @param image The image to decode
* @param hints Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image,
Map<DecodeHintType,?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
int middle = height >> 1;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle half of the image
}
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking at next:
int rowStepsAboveOrBelow = (x + 1) / 2;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException ignored) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in the life of this method
// since we want to avoid drawing the wrong points after flipping the row, and,
// don't want to clutter with noise from every single row scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType,Object> newHints = new EnumMap<>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}
/**
* We're going to examine rows from the middle outward, searching
* alternately above and below the middle, and farther out each time.
* rowStep is the number of rows between each successive attempt above and
* below the middle. So we'd scan row middle, then middle - rowStep, then
* middle + rowStep, then middle - (2 * rowStep), etc. rowStep is bigger as
* the image is taller, but is always at least 1. We've somewhat arbitrarily
* decided that moving up and down by about 1/16 of the image is pretty
* good; we try more of the image if "trying harder".
*
* @param image
* The image to decode
* @param hints
* Any hints that were requested
* @return The contents of the decoded barcode
* @throws NotFoundException
* Any spontaneous errors which occur
*/
private Result doDecode(BinaryBitmap image, Map<DecodeHintType, ?> hints) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
BitArray row = new BitArray(width);
int middle = height >> 1;
boolean tryHarder = hints != null && hints.containsKey(DecodeHintType.TRY_HARDER);
int rowStep = Math.max(1, height >> (tryHarder ? 8 : 5));
int maxLines;
if (tryHarder) {
maxLines = height; // Look at the whole image, not just the center
} else {
maxLines = 15; // 15 rows spaced 1/32 apart is roughly the middle
// half of the image
}
for (int x = 0; x < maxLines; x++) {
// Scanning from the middle out. Determine which row we're looking
// at next:
int rowStepsAboveOrBelow = (x + 1) / 2;
boolean isAbove = (x & 0x01) == 0; // i.e. is x even?
int rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
if (rowNumber < 0 || rowNumber >= height) {
// Oops, if we run off the top or bottom, stop
break;
}
// Estimate black point for this row and load it:
try {
row = image.getBlackRow(rowNumber, row);
} catch (NotFoundException ignored) {
continue;
}
// While we have the image data in a BitArray, it's fairly cheap to
// reverse it in place to
// handle decoding upside down barcodes.
for (int attempt = 0; attempt < 2; attempt++) {
if (attempt == 1) { // trying again?
row.reverse(); // reverse the row and continue
// This means we will only ever draw result points *once* in
// the life of this method
// since we want to avoid drawing the wrong points after
// flipping the row, and,
// don't want to clutter with noise from every single row
// scan -- just the scans
// that start on the center line.
if (hints != null && hints.containsKey(DecodeHintType.NEED_RESULT_POINT_CALLBACK)) {
Map<DecodeHintType, Object> newHints = new EnumMap<>(DecodeHintType.class);
newHints.putAll(hints);
newHints.remove(DecodeHintType.NEED_RESULT_POINT_CALLBACK);
hints = newHints;
}
}
try {
// Look for a barcode
Result result = decodeRow(rowNumber, row, hints);
// We found our barcode
if (attempt == 1) {
// But it was upside down, so note that
result.putMetadata(ResultMetadataType.ORIENTATION, 180);
// And remember to flip the result points horizontally.
ResultPoint[] points = result.getResultPoints();
if (points != null) {
points[0] = new ResultPoint(width - points[0].getX() - 1, points[0].getY());
points[1] = new ResultPoint(width - points[1].getX() - 1, points[1].getY());
}
}
return result;
} catch (ReaderException re) {
// continue -- just couldn't decode this row
}
}
}
throw NotFoundException.getNotFoundInstance();
}