/** * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position * of the finder patterns and estimated module size.</p> */ private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) throws NotFoundException { int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize); int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize); int dimension = ((tltrCentersDimension + tlblCentersDimension) / 2) + 7; switch (dimension & 0x03) { // mod 4 case 0: dimension++; break; // 1? do nothing case 2: dimension--; break; case 3: throw NotFoundException.getNotFoundInstance(); } return dimension; }
/** * Samples a line. * * @param p1 start point (inclusive) * @param p2 end point (exclusive) * @param size number of bits * @return the array of bits as an int (first bit is high-order bit of result) */ private int sampleLine(ResultPoint p1, ResultPoint p2, int size) { int result = 0; float d = distance(p1, p2); float moduleSize = d / size; float px = p1.getX(); float py = p1.getY(); float dx = moduleSize * (p2.getX() - p1.getX()) / d; float dy = moduleSize * (p2.getY() - p1.getY()) / d; for (int i = 0; i < size; i++) { if (image.get(MathUtils.round(px + i * dx), MathUtils.round(py + i * dy))) { result |= 1 << (size - i - 1); } } return result; }
private int sampleLine(ResultPoint p1, ResultPoint p2, int size) { int result = 0; float d = distance(p1, p2); float moduleSize = d / ((float) size); float px = p1.getX(); float py = p1.getY(); float dx = ((p2.getX() - p1.getX()) * moduleSize) / d; float dy = ((p2.getY() - p1.getY()) * moduleSize) / d; for (int i = 0; i < size; i++) { if (this.image.get(MathUtils.round((((float) i) * dx) + px), MathUtils.round((( (float) i) * dy) + py))) { result |= 1 << ((size - i) - 1); } } return result; }
private int getColor(Point p1, Point p2) { float d = distance(p1, p2); float dx = ((float) (p2.getX() - p1.getX())) / d; float dy = ((float) (p2.getY() - p1.getY())) / d; int error = 0; float px = (float) p1.getX(); float py = (float) p1.getY(); boolean colorModel = this.image.get(p1.getX(), p1.getY()); for (int i = 0; ((float) i) < d; i++) { px += dx; py += dy; if (this.image.get(MathUtils.round(px), MathUtils.round(py)) != colorModel) { error++; } } float errRatio = ((float) error) / d; if (errRatio > 0.1f && errRatio < 0.9f) { return 0; } return ((errRatio > 0.1f ? 1 : (errRatio == 0.1f ? 0 : -1)) <= 0) == colorModel ? 1 : -1; }
private static int[] sampleBitCounts(int[] moduleBitCount) { float bitCountSum = MathUtils.sum(moduleBitCount); int[] result = new int[PDF417Common.BARS_IN_MODULE]; int bitCountIndex = 0; int sumPreviousBits = 0; for (int i = 0; i < PDF417Common.MODULES_IN_CODEWORD; i++) { float sampleIndex = bitCountSum / (2 * PDF417Common.MODULES_IN_CODEWORD) + (i * bitCountSum) / PDF417Common.MODULES_IN_CODEWORD; if (sumPreviousBits + moduleBitCount[bitCountIndex] <= sampleIndex) { sumPreviousBits += moduleBitCount[bitCountIndex]; bitCountIndex++; } result[bitCountIndex]++; } return result; }
private static int getClosestDecodedValue(int[] moduleBitCount) { int bitCountSum = MathUtils.sum(moduleBitCount); float[] bitCountRatios = new float[PDF417Common.BARS_IN_MODULE]; for (int i = 0; i < bitCountRatios.length; i++) { bitCountRatios[i] = moduleBitCount[i] / (float) bitCountSum; } float bestMatchError = Float.MAX_VALUE; int bestMatch = -1; for (int j = 0; j < RATIOS_TABLE.length; j++) { float error = 0.0f; float[] ratioTableRow = RATIOS_TABLE[j]; for (int k = 0; k < PDF417Common.BARS_IN_MODULE; k++) { float diff = ratioTableRow[k] - bitCountRatios[k]; error += diff * diff; if (error >= bestMatchError) { break; } } if (error < bestMatchError) { bestMatchError = error; bestMatch = PDF417Common.SYMBOL_TABLE[j]; } } return bestMatch; }
/** * * Samples a line * * @param p1 first point * @param p2 second point * @param size number of bits * @return the array of bits */ private boolean[] sampleLine(Point p1, Point p2, int size) { boolean[] res = new boolean[size]; float d = distance(p1,p2); float moduleSize = d/(size-1); float dx = moduleSize*(p2.x - p1.x)/d; float dy = moduleSize*(p2.y - p1.y)/d; float px = p1.x; float py = p1.y; for (int i = 0; i < size; i++) { res[i] = image.get(MathUtils.round(px), MathUtils.round(py)); px+=dx; py+=dy; } return res; }
/** * <p>Computes the dimension (number of modules on a size) of the QR Code based on the position * of the finder patterns and estimated module size.</p> */ private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) throws NotFoundException { int tltrCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize); int tlblCentersDimension = MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize); int dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7; switch (dimension & 0x03) { // mod 4 case 0: dimension++; break; // 1? do nothing case 2: dimension--; break; case 3: throw NotFoundException.getNotFoundInstance(); } return dimension; }
/** * Gets the color of a segment * * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else */ private int getColor(Point p1, Point p2) { float d = distance(p1, p2); float dx = (p2.getX() - p1.getX()) / d; float dy = (p2.getY() - p1.getY()) / d; int error = 0; float px = p1.getX(); float py = p1.getY(); boolean colorModel = image.get(p1.getX(), p1.getY()); for (int i = 0; i < d; i++) { px += dx; py += dy; if (image.get(MathUtils.round(px), MathUtils.round(py)) != colorModel) { error++; } } float errRatio = error / d; if (errRatio > 0.1f && errRatio < 0.9f) { return 0; } return (errRatio <= 0.1f) == colorModel ? 1 : -1; }
private static int computeDimension(ResultPoint topLeft, ResultPoint topRight, ResultPoint bottomLeft, float moduleSize) throws NotFoundException { int dimension = ((MathUtils.round(ResultPoint.distance(topLeft, topRight) / moduleSize) + MathUtils.round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize)) / 2) + 7; switch (dimension & 3) { case 0: return dimension + 1; case 2: return dimension - 1; case 3: throw NotFoundException.getNotFoundInstance(); default: return dimension; } }
/** * Gets the color of a segment * * @return 1 if segment more than 90% black, -1 if segment is more than 90% white, 0 else */ private int getColor(Point p1, Point p2) { float d = distance(p1,p2); float dx = (p2.x - p1.x)/d; float dy = (p2.y - p1.y)/d; int error = 0; float px = p1.x; float py = p1.y; boolean colorModel = image.get(p1.x, p1.y); for (int i = 0; i < d; i++) { px+=dx; py+=dy; if (image.get(MathUtils.round(px), MathUtils.round(py)) != colorModel) { error++; } } float errRatio = (float)error/d; if (errRatio > 0.1 && errRatio < 0.9) { return 0; } if (errRatio <= 0.1) { return colorModel?1:-1; } else { return colorModel?-1:1; } }