diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk1.java b/java/src/main/java/io/nayuki/qrcodegen/Msk1.java new file mode 100644 index 0000000..f9f92e3 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk1.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk1 { + public boolean operation(int y, int x, int msk) { + return (y % 2 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk2.java b/java/src/main/java/io/nayuki/qrcodegen/Msk2.java new file mode 100644 index 0000000..42c145e --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk2.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk2 { + public boolean operation(int y, int x, int msk) { + return (x % 3 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk3.java b/java/src/main/java/io/nayuki/qrcodegen/Msk3.java new file mode 100644 index 0000000..45064c0 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk3.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk3 { + public boolean operation(int y, int x, int msk) { + return ((x + y) % 3 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk4.java b/java/src/main/java/io/nayuki/qrcodegen/Msk4.java new file mode 100644 index 0000000..d0b13a1 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk4.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk4 { + public boolean operation(int y, int x, int msk) { + return ((x / 3 + y / 2) % 2 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk5.java b/java/src/main/java/io/nayuki/qrcodegen/Msk5.java new file mode 100644 index 0000000..decc5df --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk5.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk5 { + public boolean operation(int y, int x, int msk) { + return (x * y % 2 + x * y % 3 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk6.java b/java/src/main/java/io/nayuki/qrcodegen/Msk6.java new file mode 100644 index 0000000..555fb64 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk6.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk6 { + public boolean operation(int y, int x, int msk) { + return ((x * y % 2 + x * y % 3) % 2 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/Msk7.java b/java/src/main/java/io/nayuki/qrcodegen/Msk7.java new file mode 100644 index 0000000..7d98190 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/Msk7.java @@ -0,0 +1,7 @@ +package io.nayuki.qrcodegen; + +public class Msk7 { + public boolean operation(int y, int x, int msk) { + return (((x + y) % 2 + x * y % 3) % 2 == 0); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/MskCommandFactory.java b/java/src/main/java/io/nayuki/qrcodegen/MskCommandFactory.java new file mode 100644 index 0000000..93bc177 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/MskCommandFactory.java @@ -0,0 +1,46 @@ +package io.nayuki.qrcodegen; + +public class MskCommandFactory { + public static Command getCommand(int msk) { + Command theCommand = null; + + Msk0 msk0 = new Msk0(); + Msk1 msk1 = new Msk1(); + Msk2 msk2 = new Msk2(); + Msk3 msk3 = new Msk3(); + Msk4 msk4 = new Msk4(); + Msk5 msk5 = new Msk5(); + Msk6 msk6 = new Msk6(); + Msk7 msk7 = new Msk7(); + + switch (msk) { + case 0: + theCommand = new msk0Command(msk0); + break; + case 1: + theCommand = new msk1Command(msk1); + break; + case 2: + theCommand = new msk2Command(msk2); + break; + case 3: + theCommand = new msk3Command(msk3); + break; + case 4: + theCommand = new msk4Command(msk4); + break; + case 5: + theCommand = new msk5Command(msk5); + break; + case 6: + theCommand = new msk6Command(msk6); + break; + case 7: + theCommand = new msk7Command(msk7); + break; + default: + throw new AssertionError(); + } + return theCommand; + } +} \ No newline at end of file diff --git a/java/src/main/java/io/nayuki/qrcodegen/QrCode.java b/java/src/main/java/io/nayuki/qrcodegen/QrCode.java index a2cdbc2..9d4002d 100644 --- a/java/src/main/java/io/nayuki/qrcodegen/QrCode.java +++ b/java/src/main/java/io/nayuki/qrcodegen/QrCode.java @@ -542,35 +542,24 @@ public final class QrCode { // 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. Command pattern + // 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"); - for (int y = 0; y < size; y++) { + for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { boolean invert; - Msk0 msk0 = new Msk0(); - Command mskCommand = new msk0Command(msk0); - + + Command mskCommand = MskCommandFactory.getCommand(msk); Button button = new Button(mskCommand); invert = button.pressed(y, x, msk); - /* - switch (msk) { - case 0: invert = (x + y) % 2 == 0; break; - case 1: invert = y % 2 == 0; break; - case 2: invert = x % 3 == 0; break; - case 3: invert = (x + y) % 3 == 0; break; - case 4: invert = (x / 3 + y / 2) % 2 == 0; break; - case 5: invert = x * y % 2 + x * y % 3 == 0; break; - case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break; - case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; - default: throw new AssertionError(); - } - */ + modules[y][x] ^= invert & !isFunction[y][x]; } } } + // A messy helper function for the constructor. This QR Code must be in an unmasked state when this @@ -619,21 +608,6 @@ public final class QrCode { return result; } - private int twobytwoHavingSameColor(boolean[][] modules) { - int result = 0; - // 2*2 blocks of modules having same color - for (int y = 0; y < size - 1; y++) { - for (int x = 0; x < size - 1; x++) { - boolean color = modules[y][x]; - if ( color == modules[y][x + 1] && - color == modules[y + 1][x] && - color == modules[y + 1][x + 1]) - result += PENALTY_N2; - } - } - return result; - } - // 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() { @@ -679,6 +653,21 @@ public final class QrCode { return result; } + private int twobytwoHavingSameColor(boolean[][] modules) { + int result = 0; + // 2*2 blocks of modules having same color. + for (int y = 0; y < size - 1; y++) { + for (int x = 0; x < size - 1; x++) { + boolean color = modules[y][x]; + if ( color == modules[y][x + 1] && + color == modules[y + 1][x] && + color == modules[y + 1][x + 1]) + result += PENALTY_N2; + } + } + return result; + } + /*---- Private helper functions ----*/ // Returns an ascending list of positions of alignment patterns for this version number. diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk1Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk1Command.java new file mode 100644 index 0000000..a503249 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk1Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk1Command implements Command { + private Msk1 theMsk1; + + public msk1Command(Msk1 theMsk1) { + this.theMsk1 = theMsk1; + } + + public boolean excute(int y, int x, int msk) { + return theMsk1.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk2Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk2Command.java new file mode 100644 index 0000000..d62f58e --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk2Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk2Command implements Command { + private Msk2 theMsk2; + + public msk2Command(Msk2 theMsk2) { + this.theMsk2 = theMsk2; + } + + public boolean excute(int y, int x, int msk) { + return theMsk2.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk3Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk3Command.java new file mode 100644 index 0000000..402f2a2 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk3Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk3Command implements Command { + private Msk3 theMsk3; + + public msk3Command(Msk3 theMsk3) { + this.theMsk3 = theMsk3; + } + + public boolean excute(int y, int x, int msk) { + return theMsk3.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk4Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk4Command.java new file mode 100644 index 0000000..ca755fc --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk4Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk4Command implements Command { + private Msk4 theMsk4; + + public msk4Command(Msk4 theMsk4) { + this.theMsk4 = theMsk4; + } + + public boolean excute(int y, int x, int msk) { + return theMsk4.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk5Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk5Command.java new file mode 100644 index 0000000..7a6f4b1 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk5Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk5Command implements Command { + private Msk5 theMsk5; + + public msk5Command(Msk5 theMsk5) { + this.theMsk5 = theMsk5; + } + + public boolean excute(int y, int x, int msk) { + return theMsk5.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk6Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk6Command.java new file mode 100644 index 0000000..078c270 --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk6Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk6Command implements Command { + private Msk6 theMsk6; + + public msk6Command(Msk6 theMsk6) { + this.theMsk6 = theMsk6; + } + + public boolean excute(int y, int x, int msk) { + return theMsk6.operation(y, x, msk); + } +} diff --git a/java/src/main/java/io/nayuki/qrcodegen/msk7Command.java b/java/src/main/java/io/nayuki/qrcodegen/msk7Command.java new file mode 100644 index 0000000..b5c9e2c --- /dev/null +++ b/java/src/main/java/io/nayuki/qrcodegen/msk7Command.java @@ -0,0 +1,13 @@ +package io.nayuki.qrcodegen; + +public class msk7Command implements Command { + private Msk7 theMsk7; + + public msk7Command(Msk7 theMsk7) { + this.theMsk7 = theMsk7; + } + + public boolean excute(int y, int x, int msk) { + return theMsk7.operation(y, x, msk); + } +}