turned comments into javadocs

pull/215/head
Luca Vercelli 3 months ago
parent 777682a642
commit f821db70c4

@ -40,7 +40,9 @@ final class BitBuffer {
/*---- Constructor ----*/
// Creates an empty bit buffer.
/**
* Creates an empty bit buffer.
*/
public BitBuffer() {
data = new int[64];
bitLength = 0;
@ -50,7 +52,9 @@ final class BitBuffer {
/*---- Methods ----*/
// Returns the bit at the given index, yielding 0 or 1.
/**
* Returns the bit at the given index, yielding 0 or 1.
*/
public int getBit(int index) {
if (index < 0 || index >= bitLength)
throw new IndexOutOfBoundsException();
@ -58,8 +62,10 @@ final class BitBuffer {
}
// Returns a new array representing this buffer's bits packed into
// bytes in big endian. The current bit length must be a multiple of 8.
/**
* Returns a new array representing this buffer's bits packed into
* bytes in big endian. The current bit length must be a multiple of 8.
*/
public byte[] getBytes() {
if (bitLength % 8 != 0)
throw new IllegalStateException("Data is not a whole number of bytes");
@ -70,8 +76,10 @@ final class BitBuffer {
}
// Appends the given number of low-order bits of the given value
// to this buffer. Requires 0 <= len <= 31 and 0 <= val < 2^len.
/**
* Appends the given number of low-order bits of the given value
* to this buffer. Requires <code>0 <= len <= 31</code> and <code>0 <= val < 2^len</code>.
*/
public void appendBits(int val, int len) {
if (len < 0 || len > 31 || val >>> len != 0)
throw new IllegalArgumentException("Value out of range");
@ -97,8 +105,10 @@ final class BitBuffer {
}
// Appends to this buffer the sequence of bits represented by the given
// word array and given bit length. Requires 0 <= len <= 32 * vals.length.
/**
* Appends to this buffer the sequence of bits represented by the given
* word array and given bit length. Requires 0 <= len <= 32 * vals.length.
*/
public void appendBits(int[] vals, int len) {
Objects.requireNonNull(vals);
if (len == 0)

@ -31,7 +31,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
// A thread-safe cache based on soft references.
/**
* A thread-safe cache based on soft references.
*/
final class Memoizer<T,R> {
private final Function<T,R> function;
@ -39,13 +41,17 @@ final class Memoizer<T,R> {
private Set<T> pending = new HashSet<>();
// Creates a memoizer based on the given function that takes one input to compute an output.
/**
* Creates a memoizer based on the given function that takes one input to compute an output.
*/
public Memoizer(Function<T,R> func) {
function = func;
}
// Computes function.apply(arg) or returns a cached copy of a previous call.
/**
* Computes function.apply(arg) or returns a cached copy of a previous call.
*/
public R get(T arg) {
// Non-blocking fast path
{

@ -280,8 +280,10 @@ public final class QrCode {
/*---- Private helper methods for constructor: Drawing function modules ----*/
// Draws two copies of the format bits (with its own error correction code)
// based on the given mask and this object's error correction level field.
/**
* Draws two copies of the format bits (with its own error correction code)
* based on the given mask and this object's error correction level field.
*/
private void drawFormatBits(int msk) {
// Calculate error correction code and pack bits
int data = errorCorrectionLevel.formatBits << 3 | msk; // errCorrLvl is uint2, mask is uint3
@ -309,8 +311,10 @@ public final class QrCode {
}
// Sets the module at the given coordinates to the given color.
// Only used by the constructor. Coordinates must be in bounds.
/**
* Sets the module at the given coordinates to the given color.
* Only used by the constructor. Coordinates must be in bounds.
*/
private void setModule(int x, int y, int dark) {
assert 0 <= x && x < size;
assert 0 <= y && y < size;
@ -323,8 +327,10 @@ public final class QrCode {
/*---- Private helper methods for constructor: Codewords and masking ----*/
// Returns a new byte string representing the given data with the appropriate error correction
// codewords appended to it, based on this object's version and error correction level.
/**
* Returns a new byte string representing the given data with the appropriate error correction
* codewords appended to it, based on this object's version and error correction level.
*/
private byte[] addEccAndInterleave(byte[] data) {
Objects.requireNonNull(data);
if (data.length != getNumDataCodewords(version, errorCorrectionLevel))
@ -357,8 +363,10 @@ public final class QrCode {
}
// Draws the given sequence of 8-bit codewords (data and error correction)
// onto the entire data area of this QR Code, based on the given bit indexes.
/**
* Draws the given sequence of 8-bit codewords (data and error correction)
* onto the entire data area of this QR Code, based on the given bit indexes.
*/
private void drawCodewords(int[] dataOutputBitIndexes, byte[] allCodewords) {
Objects.requireNonNull(dataOutputBitIndexes);
Objects.requireNonNull(allCodewords);
@ -372,11 +380,13 @@ public final class QrCode {
}
// XORs the codeword modules in this QR Code with the given mask pattern.
// The function modules must be marked and the codeword bits must be drawn
// before masking. Due to the arithmetic of XOR, calling applyMask() with
// the same mask value a second time will undo the mask. A final well-formed
// QR Code needs exactly one (not zero, two, etc.) mask applied.
/**
* XORs the codeword modules in this QR Code with the given mask pattern.
* The function modules must be marked and the codeword bits must be drawn
* before masking. Due to the arithmetic of XOR, calling applyMask() with
* the same mask value a second time will undo the mask. A final well-formed
* QR Code needs exactly one (not zero, two, etc.) mask applied.
*/
private void applyMask(int[] msk) {
if (msk.length != modules.length)
throw new IllegalArgumentException();
@ -385,9 +395,11 @@ public final class QrCode {
}
// A messy helper function for the constructor. This QR Code must be in an unmasked state when this
// method is called. The 'mask' argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
// This method applies and returns the actual mask chosen, from 0 to 7.
/**
* A messy helper function for the constructor. This QR Code must be in an unmasked state when this
* method is called. The 'mask' argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
* This method applies and returns the actual mask chosen, from 0 to 7.
*/
private int handleConstructorMasking(int[][] masks, int msk) {
if (msk == -1) { // Automatically choose best mask
int minPenalty = Integer.MAX_VALUE;
@ -409,8 +421,10 @@ public final class QrCode {
}
// Calculates and returns the penalty score based on state of this QR Code's current modules.
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
/**
* Calculates and returns the penalty score based on state of this QR Code's current modules.
* This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
*/
private int getPenaltyScore() {
int result = 0;
int dark = 0;
@ -486,9 +500,11 @@ public final class QrCode {
/*---- Private helper functions ----*/
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
/**
* Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
* QR Code of the given version number and error correction level, with remainder bits discarded.
* This stateless pure function could be implemented as a (40*4)-cell lookup table.
*/
static int getNumDataCodewords(int ver, Ecc ecl) {
return QrTemplate.getNumRawDataModules(ver) / 8
- ECC_CODEWORDS_PER_BLOCK [ecl.ordinal()][ver]
@ -496,8 +512,10 @@ public final class QrCode {
}
// Can only be called immediately after a light run is added, and
// returns either 0, 1, or 2. A helper function for getPenaltyScore().
/**
* Can only be called immediately after a light run is added, and
* returns either 0, 1, or 2. A helper function for <code>getPenaltyScore()</code>.
*/
private int finderPenaltyCountPatterns(int[] runHistory) {
int n = runHistory[1];
assert n <= size * 3;
@ -507,7 +525,9 @@ public final class QrCode {
}
// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
/**
* Must be called at the end of a line (row or column) of modules. A helper function for <code>getPenaltyScore()</code>.
*/
private int finderPenaltyTerminateAndCount(int currentRunColor, int currentRunLength, int[] runHistory) {
if (currentRunColor == 1) { // Terminate dark run
finderPenaltyAddHistory(currentRunLength, runHistory);
@ -519,7 +539,9 @@ public final class QrCode {
}
// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
/**
* Pushes the given value to the front and drops the last value. A helper function for <code>getPenaltyScore()</code>.
*/
private void finderPenaltyAddHistory(int currentRunLength, int[] runHistory) {
if (runHistory[0] == 0)
currentRunLength += size; // Add light border to initial run
@ -528,7 +550,9 @@ public final class QrCode {
}
// Returns 0 or 1 based on the (i mod 32)'th bit of x.
/**
* Returns 0 or 1 based on the (i mod 32)'th bit of x.
*/
static int getBit(int x, int i) {
return (x >>> i) & 1;
}

@ -221,11 +221,13 @@ public final class QrCode {
// Private grids of modules/pixels, with dimensions of size*size:
// The modules of this QR Code (false = light, true = dark).
// Immutable after constructor finishes. Accessed through getModule().
/**
* The modules of this QR Code (false = light, true = dark).<br/>
* Immutable after constructor finishes. Accessed through <code>getModule()</code>. */
private boolean[][] modules;
// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
/**
* Indicates function modules that are not subjected to masking. Discarded when constructor finishes. */
private boolean[][] isFunction;
@ -306,7 +308,9 @@ public final class QrCode {
/*---- Private helper methods for constructor: Drawing function modules ----*/
// Reads this object's version field, and draws and marks all function modules.
/**
* Reads this object's version field, and draws and marks all function modules.
*/
private void drawFunctionPatterns() {
// Draw horizontal and vertical timing patterns
for (int i = 0; i < size; i++) {
@ -336,8 +340,10 @@ public final class QrCode {
}
// Draws two copies of the format bits (with its own error correction code)
// based on the given mask and this object's error correction level field.
/**
* Draws two copies of the format bits (with its own error correction code)
* based on the given mask and this object's error correction level field.
*/
private void drawFormatBits(int msk) {
// Calculate error correction code and pack bits
int data = errorCorrectionLevel.formatBits << 3 | msk; // errCorrLvl is uint2, mask is uint3
@ -365,8 +371,10 @@ public final class QrCode {
}
// Draws two copies of the version bits (with its own error correction code),
// based on this object's version field, iff 7 <= version <= 40.
/**
* Draws two copies of the version bits (with its own error correction code),
* based on this object's version field, iff 7 <= version <= 40.
*/
private void drawVersion() {
if (version < 7)
return;
@ -389,8 +397,10 @@ public final class QrCode {
}
// Draws a 9*9 finder pattern including the border separator,
// with the center module at (x, y). Modules can be out of bounds.
/**
* Draws a 9*9 finder pattern including the border separator,
* with the center module at (x, y). Modules can be out of bounds.
*/
private void drawFinderPattern(int x, int y) {
for (int dy = -4; dy <= 4; dy++) {
for (int dx = -4; dx <= 4; dx++) {
@ -403,8 +413,10 @@ public final class QrCode {
}
// Draws a 5*5 alignment pattern, with the center module
// at (x, y). All modules must be in bounds.
/**
* Draws a 5*5 alignment pattern, with the center module
* at (x, y). All modules must be in bounds.
*/
private void drawAlignmentPattern(int x, int y) {
for (int dy = -2; dy <= 2; dy++) {
for (int dx = -2; dx <= 2; dx++)
@ -413,8 +425,10 @@ public final class QrCode {
}
// Sets the color of a module and marks it as a function module.
// Only used by the constructor. Coordinates must be in bounds.
/**
* Sets the color of a module and marks it as a function module.
* Only used by the constructor. Coordinates must be in bounds.
*/
private void setFunctionModule(int x, int y, boolean isDark) {
modules[y][x] = isDark;
isFunction[y][x] = true;
@ -423,8 +437,10 @@ public final class QrCode {
/*---- Private helper methods for constructor: Codewords and masking ----*/
// Returns a new byte string representing the given data with the appropriate error correction
// codewords appended to it, based on this object's version and error correction level.
/**
* Returns a new byte string representing the given data with the appropriate error correction
* codewords appended to it, based on this object's version and error correction level.
*/
private byte[] addEccAndInterleave(byte[] data) {
Objects.requireNonNull(data);
if (data.length != getNumDataCodewords(version, errorCorrectionLevel))
@ -464,8 +480,10 @@ public final class QrCode {
}
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
// data area of this QR Code. Function modules need to be marked off before this is called.
/**
* Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
* data area of this QR Code. Function modules need to be marked off before this is called.
*/
private void drawCodewords(byte[] data) {
Objects.requireNonNull(data);
if (data.length != getNumRawDataModules(version) / 8)
@ -494,11 +512,13 @@ public final class QrCode {
}
// XORs the codeword modules in this QR Code with the given mask pattern.
// The function modules must be marked and the codeword bits must be drawn
// before masking. Due to the arithmetic of XOR, calling applyMask() with
// the same mask value a second time will undo the mask. A final well-formed
// QR Code needs exactly one (not zero, two, etc.) mask applied.
/**
* XORs the codeword modules in this QR Code with the given mask pattern.
* The function modules must be marked and the codeword bits must be drawn
* before masking. Due to the arithmetic of XOR, calling applyMask() with
* the same mask value a second time will undo the mask. A final well-formed
* QR Code needs exactly one (not zero, two, etc.) mask applied.
*/
private void applyMask(int msk) {
if (msk < 0 || msk > 7)
throw new IllegalArgumentException("Mask value out of range");
@ -522,8 +542,10 @@ public final class QrCode {
}
// Calculates and returns the penalty score based on state of this QR Code's current modules.
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
/**
* Calculates and returns the penalty score based on state of this QR Code's current modules.
* This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
*/
private int getPenaltyScore() {
int result = 0;
@ -604,9 +626,11 @@ public final class QrCode {
/*---- Private helper functions ----*/
// Returns an ascending list of positions of alignment patterns for this version number.
// Each position is in the range [0,177), and are used on both the x and y axes.
// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
/**
* Returns an ascending list of positions of alignment patterns for this version number.
* Each position is in the range [0,177), and are used on both the x and y axes.
* This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
*/
private int[] getAlignmentPatternPositions() {
if (version == 1)
return new int[]{};
@ -622,9 +646,11 @@ public final class QrCode {
}
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
/**
* Returns the number of data bits that can be stored in a QR Code of the given version number, after
* all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
* The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
*/
private static int getNumRawDataModules(int ver) {
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw new IllegalArgumentException("Version number out of range");
@ -648,8 +674,10 @@ public final class QrCode {
}
// Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
// implemented as a lookup table over all possible parameter values, instead of as an algorithm.
/**
* Returns a Reed-Solomon ECC generator polynomial for the given degree. This could be
* implemented as a lookup table over all possible parameter values, instead of as an algorithm.
*/
private static byte[] reedSolomonComputeDivisor(int degree) {
if (degree < 1 || degree > 255)
throw new IllegalArgumentException("Degree out of range");
@ -675,7 +703,9 @@ public final class QrCode {
}
// Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
/**
* Returns the Reed-Solomon error correction codeword for the given data and divisor polynomials.
*/
private static byte[] reedSolomonComputeRemainder(byte[] data, byte[] divisor) {
Objects.requireNonNull(data);
Objects.requireNonNull(divisor);
@ -691,8 +721,10 @@ public final class QrCode {
}
// Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
// are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
/**
* Returns the product of the two given field elements modulo GF(2^8/0x11D). The arguments and result
* are unsigned 8-bit integers. This could be implemented as a lookup table of 256*256 entries of uint8.
*/
private static int reedSolomonMultiply(int x, int y) {
assert x >> 8 == 0 && y >> 8 == 0;
// Russian peasant multiplication
@ -706,9 +738,11 @@ public final class QrCode {
}
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
// QR Code of the given version number and error correction level, with remainder bits discarded.
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
/**
* Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
* QR Code of the given version number and error correction level, with remainder bits discarded.<br/>
* This stateless pure function could be implemented as a (40*4)-cell lookup table.
*/
static int getNumDataCodewords(int ver, Ecc ecl) {
return getNumRawDataModules(ver) / 8
- ECC_CODEWORDS_PER_BLOCK [ecl.ordinal()][ver]
@ -716,8 +750,10 @@ public final class QrCode {
}
// Can only be called immediately after a light run is added, and
// returns either 0, 1, or 2. A helper function for getPenaltyScore().
/**
* Can only be called immediately after a light run is added, and
* returns either 0, 1, or 2. A helper function for <code>getPenaltyScore()</code>.
*/
private int finderPenaltyCountPatterns(int[] runHistory) {
int n = runHistory[1];
assert n <= size * 3;
@ -727,7 +763,9 @@ public final class QrCode {
}
// Must be called at the end of a line (row or column) of modules. A helper function for getPenaltyScore().
/**
* Must be called at the end of a line (row or column) of modules. A helper function for <code>getPenaltyScore()</code>.
*/
private int finderPenaltyTerminateAndCount(boolean currentRunColor, int currentRunLength, int[] runHistory) {
if (currentRunColor) { // Terminate dark run
finderPenaltyAddHistory(currentRunLength, runHistory);
@ -739,7 +777,9 @@ public final class QrCode {
}
// Pushes the given value to the front and drops the last value. A helper function for getPenaltyScore().
/**
* Pushes the given value to the front and drops the last value. A helper function for <code>getPenaltyScore()</code>.
*/
private void finderPenaltyAddHistory(int currentRunLength, int[] runHistory) {
if (runHistory[0] == 0)
currentRunLength += size; // Add light border to initial run

@ -90,7 +90,9 @@ public final class QrSegmentAdvanced {
}
// Returns a new list of segments that is optimal for the given text at the given version number.
/**
* Returns a new list of segments that is optimal for the given text at the given version number.
*/
private static List<QrSegment> makeSegmentsOptimally(int[] codePoints, int version) {
if (codePoints.length == 0)
return new ArrayList<>();
@ -99,7 +101,9 @@ public final class QrSegmentAdvanced {
}
// Returns a new array representing the optimal mode per code point based on the given text and version.
/**
* Returns a new array representing the optimal mode per code point based on the given text and version.
*/
private static Mode[] computeCharacterModes(int[] codePoints, int version) {
if (codePoints.length == 0)
throw new IllegalArgumentException();
@ -189,8 +193,10 @@ public final class QrSegmentAdvanced {
}
// Returns a new list of segments based on the given text and modes, such that
// consecutive code points in the same mode are put into the same segment.
/**
* Returns a new list of segments based on the given text and modes, such that
* consecutive code points in the same mode are put into the same segment.
*/
private static List<QrSegment> splitIntoSegments(int[] codePoints, Mode[] charModes) {
if (codePoints.length == 0)
throw new IllegalArgumentException();
@ -221,8 +227,10 @@ public final class QrSegmentAdvanced {
}
// Returns a new array of Unicode code points (effectively
// UTF-32 / UCS-4) representing the given UTF-16 string.
/**
* Returns a new array of Unicode code points (effectively
* UTF-32 / UCS-4) representing the given UTF-16 string.
*/
private static int[] toCodePoints(CharSequence s) {
int[] result = s.codePoints().toArray();
for (int c : result) {
@ -233,7 +241,9 @@ public final class QrSegmentAdvanced {
}
// Returns the number of UTF-8 bytes needed to encode the given Unicode code point.
/**
* Returns the number of UTF-8 bytes needed to encode the given Unicode code point.
*/
private static int countUtf8Bytes(int cp) {
if (cp < 0) throw new IllegalArgumentException("Invalid code point");
else if (cp < 0x80) return 1;

Loading…
Cancel
Save