From 2044474549a4a218a9e335acdd1aa384efdb8ec5 Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Mon, 16 Nov 2020 15:55:27 +0000
Subject: [PATCH] Zxing: Update to 3.4.1 (2020-09-29) Merge in javadoc fixes

---
 LICENSE.txt                                   |  2 +-
 apps/imagegen/zxing/AUTHORS                   |  1 +
 apps/imagegen/zxing/CHANGES                   | 38 ++++++++++-
 apps/imagegen/zxing/README-i2p.txt            |  2 +-
 apps/imagegen/zxing/README.md                 | 67 ++++++++++++-------
 .../java/com/google/zxing/EncodeHintType.java | 16 ++++-
 .../com/google/zxing/FormatException.java     |  4 +-
 .../com/google/zxing/WriterException.java     |  2 +-
 .../com/google/zxing/common/BitArray.java     | 10 +--
 .../com/google/zxing/common/BitMatrix.java    | 52 +++++++++++---
 .../google/zxing/common/CharacterSetECI.java  |  2 +-
 .../zxing/common/reedsolomon/GenericGF.java   |  6 +-
 .../common/reedsolomon/GenericGFPoly.java     |  9 ++-
 .../reedsolomon/ReedSolomonEncoder.java       |  2 +-
 .../google/zxing/qrcode/decoder/Version.java  |  7 +-
 .../zxing/qrcode/encoder/ByteMatrix.java      | 11 +--
 .../google/zxing/qrcode/encoder/Encoder.java  | 35 ++++++++--
 .../google/zxing/qrcode/encoder/MaskUtil.java |  5 +-
 .../zxing/qrcode/encoder/MatrixUtil.java      | 61 ++++++++---------
 19 files changed, 227 insertions(+), 105 deletions(-)

diff --git a/LICENSE.txt b/LICENSE.txt
index 9fdc6285c0..acf7e24362 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -255,7 +255,7 @@ Applications:
        Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
        Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
        See licenses/LICENSE-BSD.txt
-     Zxing 3.3.0:
+     Zxing 3.4.1:
        See licenses/LICENSE-Apache2.0.txt
 
    Jetty 9.3.28.v20191105 (jetty-*.jar, org.mortbay.*.jar):
diff --git a/apps/imagegen/zxing/AUTHORS b/apps/imagegen/zxing/AUTHORS
index d6aeafeef2..85099ebfb0 100644
--- a/apps/imagegen/zxing/AUTHORS
+++ b/apps/imagegen/zxing/AUTHORS
@@ -23,6 +23,7 @@ Chang Hyun Park
 Christian Brunschen (Google)
 Christoph Schulz (creatale GmbH)
 crowdin.net
+Daisuke Makiuchi
 Daniel Switkin (Google)
 Dave MacLachlan (Google)
 David Phillip Oster (Google)
diff --git a/apps/imagegen/zxing/CHANGES b/apps/imagegen/zxing/CHANGES
index c9e46ec050..7608df6997 100644
--- a/apps/imagegen/zxing/CHANGES
+++ b/apps/imagegen/zxing/CHANGES
@@ -303,7 +303,7 @@
   - Many small updates to the Android app, Barcode Scanner, including rare bug fixes and translation updates.
     The 2.1 release corresponds substantially to v4.3.1.
   - Many ports of Java updates to C++ port
-  
+
 2.2 (14 May 2013)
 
   - Retire Symbian port
@@ -363,3 +363,39 @@
   - BS 4.7.6 release with Android API 23 support
   - TIFF support in online decoder
   - Many small bug fixes, typo fixes and project build improvements
+
+3.3.1 (26 Oct 2017)
+
+  - Various fixes to Code 128, 39 encoding; DataMatrix decoding
+  - Improvements to speed and robustness of zxing.org decoder
+  - Java 9 support
+  - Various translation updates for Barcode Scanner
+  - Removed Google Glass, ZXing Test apps
+
+3.3.2 (31 Jan 2018)
+
+  - Add workaround for Gradle + Android build issues
+  - Minor DataMatrix bug fixes
+  - Improve WPA2 wi-fi configuration support in Barcode Scanner
+  - Various translation updates and minor improvements
+
+3.3.3 (30 May 2018)
+
+  - Minor fixes and improvements
+  - Java 9+ support
+
+3.4.0 (19 May 2019)
+
+  - Requires Java 8+
+  - core, javase modules declare a Java 9+ module
+  - HtmlAssetTranslator and StringsResourceTranslator legacy utilities are moved to a .client.j2se subpackage
+  - No more releases of the Barcode Scanner app
+  - Minor bug fixes to Code93Writer
+  - Minor improvements to QR code detection
+
+3.4.1 (30 Sep 2020)
+
+  - Wifi QR codes now recognize PH2:, not H:, for phase 2 method
+  - Minor bug fixes and improvements
+
+Note that further release notes will be published at https://github.com/zxing/zxing/releases
diff --git a/apps/imagegen/zxing/README-i2p.txt b/apps/imagegen/zxing/README-i2p.txt
index 1adad5ff8f..5a1d3189b3 100644
--- a/apps/imagegen/zxing/README-i2p.txt
+++ b/apps/imagegen/zxing/README-i2p.txt
@@ -2,4 +2,4 @@ This is a small portion of zxing, including only what's required
 to generate QR codes. There are no modifications.
 We've added a build.xml for ant.
 
-https://github.com/zxing/zxing/releases Version 3.3.0 Sept. 16, 2016
+https://github.com/zxing/zxing/releases Version 3.4.1 Sept. 29, 2020
diff --git a/apps/imagegen/zxing/README.md b/apps/imagegen/zxing/README.md
index a0c5dac9e8..64ef0475c0 100644
--- a/apps/imagegen/zxing/README.md
+++ b/apps/imagegen/zxing/README.md
@@ -1,6 +1,14 @@
 <img align="right" src="https://raw.github.com/wiki/zxing/zxing/zxing-logo.png"/>
 
-##Get Started Developing
+## Project in Maintenance Mode Only
+
+The project is in maintenance mode, meaning, changes are driven by contributed patches.
+Only bug fixes and minor enhancements will be considered. The Barcode Scanner app can
+no longer be published, so it's unlikely any changes will be accepted for it.
+There is otherwise no active development or roadmap for this project. It is "DIY".
+
+## Get Started Developing
+
 To get started, please visit: https://github.com/zxing/zxing/wiki/Getting-Started-Developing
 
 ZXing ("zebra crossing") is an open-source, multi-format 1D/2D barcode image processing
@@ -8,15 +16,15 @@ library implemented in Java, with ports to other languages.
 
 ## Supported Formats
 
-| 1D product | 1D industrial | 2D
-| ---------- | ------------- | --------------
-| UPC-A      | Code 39       | QR Code
-| UPC-E      | Code 93       | Data Matrix
-| EAN-8      | Code 128      | Aztec (beta)
-| EAN-13     | Codabar       | PDF 417 (beta)
-|            | ITF           |
-|            | RSS-14        |
-|            | RSS-Expanded  |
+| 1D product            | 1D industrial | 2D             |
+|:----------------------|:--------------|:---------------|
+| UPC-A                 | Code 39       | QR Code        |
+| UPC-E                 | Code 93       | Data Matrix    |
+| EAN-8                 | Code 128      | Aztec          |
+| EAN-13                | Codabar       | PDF 417        |
+| UPC/EAN Extension 2/5 | ITF           | MaxiCode       |
+|                       |               | RSS-14         |
+|                       |               | RSS-Expanded   |
 
 ## Components
 
@@ -26,11 +34,9 @@ library implemented in Java, with ports to other languages.
 | ------------------- | -----------
 | core                | The core image decoding library, and test code
 | javase              | JavaSE-specific client code
-| android             | Android client Barcode Scanner [![Barcode Scanner](http://www.android.com/images/brand/android_app_on_play_logo_small.png)](https://play.google.com/store/apps/details?id=com.google.zxing.client.android)
-| androidtest         | Android test app, ZXing Test
+| android             | Android client Barcode Scanner [<img height='62' width='161' src='https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png'/>](https://play.google.com/store/apps/details?id=com.google.zxing.client.android)
 | android-integration | Supports integration with Barcode Scanner via `Intent`
-| android-core        | Android-related code shared among `android`, `androidtest`, `glass`
-| glass               | Simple Google Glass application
+| android-core        | Android-related code shared among `android`, other Android apps
 | zxingorg            | The source behind `zxing.org`
 | zxing.appspot.com   | The source behind web-based barcode generator at `zxing.appspot.com`
 
@@ -46,14 +52,22 @@ library implemented in Java, with ports to other languages.
 
 ### ZXing-based third-party open source projects
 
-| Module                                                          | Description
-| --------------------------------------------------------------- | -----------
-| [QZXing](https://sourceforge.net/projects/qzxing)               | port to Qt framework
-| [zxing-cpp](https://github.com/glassechidna/zxing-cpp)          | port to C++ (forked from the [deprecated official C++ port](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/cpp))
-| [zxing_cpp.rb](https://github.com/glassechidna/zxing_cpp.rb)    | bindings for Ruby (not just JRuby), powered by [zxing-cpp](https://github.com/glassechidna/zxing-cpp)
-| [python-zxing](https://github.com/oostendo/python-zxing)        | bindings for Python
-| [ZXing .NET](http://zxingnet.codeplex.com/)                     | port to .NET and C#, and related Windows platform
-| [php-qrcode-detector-decoder](https://github.com/khanamiryan/php-qrcode-detector-decoder)                     | port to PHP
+| Module                                                                                    | Description
+| ----------------------------------------------------------------------------------------- | -----------
+| [QZXing](https://github.com/ftylitak/qzxing)                                              | port to Qt framework
+| [glassechidna/zxing-cpp](https://github.com/glassechidna/zxing-cpp)                       | port to C++ (forked from the [deprecated official C++ port](https://github.com/zxing/zxing/tree/00f634024ceeee591f54e6984ea7dd666fab22ae/cpp))
+| [nu-book/zxing-cpp](https://github.com/nu-book/zxing-cpp)                                 | recent port to C++
+| [zxing_cpp.rb](https://github.com/glassechidna/zxing_cpp.rb)                              | bindings for Ruby (not just JRuby), powered by [zxing-cpp](https://github.com/glassechidna/zxing-cpp)
+| [jsqrcode](https://github.com/LazarSoft/jsqrcode)                                         | port to JavaScript
+| [python-zxing](https://github.com/oostendo/python-zxing)                                  | bindings for Python
+| [ZXing .NET](https://github.com/micjahn/ZXing.Net)                                        | port to .NET and C#, and related Windows platform
+| [php-qrcode-detector-decoder](https://github.com/khanamiryan/php-qrcode-detector-decoder) | port to PHP
+| [ZXing Delphi](https://github.com/Spelt/ZXing.Delphi)                                     | Port to native Delphi object pascal, targeted at Firemonkey compatible devices (IOS/Android/Win/OSX) and VCL.
+| [ZXingObjC](https://github.com/TheLevelUp/ZXingObjC)                                      | Port to Objective-C
+| [php-zxing](https://github.com/dsiddharth2/php-zxing)                                     | PHP wrapper to Zxing Java library
+| [zxing-js/library](https://github.com/zxing-js/library)                                   | TypeScript port of ZXing library
+| [pyzxing](https://github.com/ChenjieXu/pyzxing)                                           | Python wrapper to ZXing library
+
 
 ### Other related third-party open source projects
 
@@ -61,7 +75,7 @@ library implemented in Java, with ports to other languages.
 | ---------------------------------------------- | -----------
 | [Barcode4J](http://barcode4j.sourceforge.net/) | Generator library in Java
 | [ZBar](http://zbar.sourceforge.net/)           | Reader library in C99
-| [OkapiBarcode](https://github.com/woo-j/OkapiBarcode)  | 
+| [OkapiBarcode](https://github.com/woo-j/OkapiBarcode)  | |
 
 ## Links
 
@@ -73,14 +87,15 @@ library implemented in Java, with ports to other languages.
 ## Contacting
 
 Post to the [discussion forum](https://groups.google.com/group/zxing) or tag a question with [`zxing`
-on StackOverflow](http://stackoverflow.com/questions/tagged/zxing).
+on StackOverflow](https://stackoverflow.com/questions/tagged/zxing).
 
 ## Etcetera
 
-[![Build Status](https://travis-ci.org/zxing/zxing.png?branch=master)](https://travis-ci.org/zxing/zxing)
+[![Build Status](https://travis-ci.org/zxing/zxing.svg?branch=master)](https://travis-ci.org/zxing/zxing)
 [![Coverity Status](https://scan.coverity.com/projects/1924/badge.svg)](https://scan.coverity.com/projects/1924)
 [![codecov.io](https://codecov.io/github/zxing/zxing/coverage.svg?branch=master)](https://codecov.io/github/zxing/zxing?branch=master)
+[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7270e4b57c50483699448bf32721ab10)](https://www.codacy.com/app/srowen/zxing?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=zxing/zxing&amp;utm_campaign=Badge_Grade)
 
 QR code is trademarked by Denso Wave, inc. Thanks to Haase & Martin OHG for contributing the logo.
 
-Optimized with [![JProfiler](http://www.ej-technologies.com/images/banners/jprofiler_small.png)](http://www.ej-technologies.com/products/jprofiler/overview.html)
+Optimized with [![JProfiler](https://www.ej-technologies.com/images/banners/jprofiler_small.png)](https://www.ej-technologies.com/products/jprofiler/overview.html)
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/EncodeHintType.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/EncodeHintType.java
index f380d42514..12f8e7a3b6 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/EncodeHintType.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/EncodeHintType.java
@@ -95,10 +95,24 @@ public enum EncodeHintType {
    * (Type {@link Integer}, or {@link String} representation of the integer value).
    */
    AZTEC_LAYERS,
-   
+
    /**
     * Specifies the exact version of QR code to be encoded.
     * (Type {@link Integer}, or {@link String} representation of the integer value).
     */
    QR_VERSION,
+
+  /**
+   * Specifies the QR code mask pattern to be used. Allowed values are
+   * 0..QRCode.NUM_MASK_PATTERNS-1. By default the code will automatically select
+   * the optimal mask pattern.
+   * * (Type {@link Integer}, or {@link String} representation of the integer value).
+   */
+  QR_MASK_PATTERN,
+
+  /**
+   * Specifies whether the data should be encoded to the GS1 standard (type {@link Boolean}, or "true" or "false"
+   * {@link String } value).
+   */
+  GS1_FORMAT,
 }
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/FormatException.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/FormatException.java
index b046b822d3..ebd800862a 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/FormatException.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/FormatException.java
@@ -40,8 +40,8 @@ public final class FormatException extends ReaderException {
   public static FormatException getFormatInstance() {
     return isStackTrace ? new FormatException() : INSTANCE;
   }
-  
+
   public static FormatException getFormatInstance(Throwable cause) {
     return isStackTrace ? new FormatException(cause) : INSTANCE;
   }
-}
\ No newline at end of file
+}
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/WriterException.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/WriterException.java
index c61800b93a..d2a37bc528 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/WriterException.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/WriterException.java
@@ -30,7 +30,7 @@ public final class WriterException extends Exception {
   public WriterException(String message) {
     super(message);
   }
-  
+ 
   public WriterException(Throwable cause) {
     super(cause);
   }
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitArray.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitArray.java
index 421f2dfbdb..19f0c99fd1 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitArray.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitArray.java
@@ -99,7 +99,7 @@ public final class BitArray implements Cloneable {
     int bitsOffset = from / 32;
     int currentBits = bits[bitsOffset];
     // mask off lesser bits first
-    currentBits &= ~((1 << (from & 0x1F)) - 1);
+    currentBits &= -(1 << (from & 0x1F));
     while (currentBits == 0) {
       if (++bitsOffset == bits.length) {
         return size;
@@ -107,7 +107,7 @@ public final class BitArray implements Cloneable {
       currentBits = bits[bitsOffset];
     }
     int result = (bitsOffset * 32) + Integer.numberOfTrailingZeros(currentBits);
-    return result > size ? size : result;
+    return Math.min(result, size);
   }
 
   /**
@@ -122,7 +122,7 @@ public final class BitArray implements Cloneable {
     int bitsOffset = from / 32;
     int currentBits = ~bits[bitsOffset];
     // mask off lesser bits first
-    currentBits &= ~((1 << (from & 0x1F)) - 1);
+    currentBits &= -(1 << (from & 0x1F));
     while (currentBits == 0) {
       if (++bitsOffset == bits.length) {
         return size;
@@ -130,7 +130,7 @@ public final class BitArray implements Cloneable {
       currentBits = ~bits[bitsOffset];
     }
     int result = (bitsOffset * 32) + Integer.numberOfTrailingZeros(currentBits);
-    return result > size ? size : result;
+    return Math.min(result, size);
   }
 
   /**
@@ -339,7 +339,7 @@ public final class BitArray implements Cloneable {
 
   @Override
   public String toString() {
-    StringBuilder result = new StringBuilder(size);
+    StringBuilder result = new StringBuilder(size + (size / 8) + 1);
     for (int i = 0; i < size; i++) {
       if ((i & 0x07) == 0) {
         result.append(' ');
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitMatrix.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitMatrix.java
index 45528e8e3b..1648e20cbc 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitMatrix.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/BitMatrix.java
@@ -40,11 +40,21 @@ public final class BitMatrix implements Cloneable {
   private final int rowSize;
   private final int[] bits;
 
-  // A helper to construct a square matrix.
+  /**
+   * Creates an empty square {@code BitMatrix}.
+   *
+   * @param dimension height and width
+   */
   public BitMatrix(int dimension) {
     this(dimension, dimension);
   }
 
+  /**
+   * Creates an empty {@code BitMatrix}.
+   *
+   * @param width bit matrix width
+   * @param height bit matrix height
+   */
   public BitMatrix(int width, int height) {
     if (width < 1 || height < 1) {
       throw new IllegalArgumentException("Both dimensions must be greater than 0");
@@ -62,6 +72,27 @@ public final class BitMatrix implements Cloneable {
     this.bits = bits;
   }
 
+  /**
+   * Interprets a 2D array of booleans as a {@code BitMatrix}, where "true" means an "on" bit.
+   *
+   * @param image bits of the image, as a row-major 2D array. Elements are arrays representing rows
+   * @return {@code BitMatrix} representation of image
+   */
+  public static BitMatrix parse(boolean[][] image) {
+    int height = image.length;
+    int width = image[0].length;
+    BitMatrix bits = new BitMatrix(width, height);
+    for (int i = 0; i < height; i++) {
+      boolean[] imageI = image[i];
+      for (int j = 0; j < width; j++) {
+        if (imageI[j]) {
+          bits.set(j, i);
+        }
+      }
+    }
+    return bits;
+  }
+
   public static BitMatrix parse(String stringRepresentation, String setString, String unsetString) {
     if (stringRepresentation == null) {
       throw new IllegalArgumentException();
@@ -86,11 +117,11 @@ public final class BitMatrix implements Cloneable {
           nRows++;
         }
         pos++;
-      }  else if (stringRepresentation.substring(pos, pos + setString.length()).equals(setString)) {
+      }  else if (stringRepresentation.startsWith(setString, pos)) {
         pos += setString.length();
         bits[bitsPos] = true;
         bitsPos++;
-      } else if (stringRepresentation.substring(pos, pos + unsetString.length()).equals(unsetString)) {
+      } else if (stringRepresentation.startsWith(unsetString, pos)) {
         pos += unsetString.length();
         bits[bitsPos] = false;
         bitsPos++;
@@ -165,11 +196,10 @@ public final class BitMatrix implements Cloneable {
    * @param mask XOR mask
    */
   public void xor(BitMatrix mask) {
-    if (width != mask.getWidth() || height != mask.getHeight()
-        || rowSize != mask.getRowSize()) {
+    if (width != mask.width || height != mask.height || rowSize != mask.rowSize) {
       throw new IllegalArgumentException("input matrix dimensions do not match");
     }
-    BitArray rowArray = new BitArray(width / 32 + 1);
+    BitArray rowArray = new BitArray(width);
     for (int y = 0; y < height; y++) {
       int offset = y * rowSize;
       int[] row = mask.getRow(y, rowArray).getBitArray();
@@ -250,17 +280,17 @@ public final class BitMatrix implements Cloneable {
    * Modifies this {@code BitMatrix} to represent the same but rotated 180 degrees
    */
   public void rotate180() {
-    int width = getWidth();
-    int height = getHeight();
     BitArray topRow = new BitArray(width);
     BitArray bottomRow = new BitArray(width);
-    for (int i = 0; i < (height + 1) / 2; i++) {
+    int maxHeight = (height + 1) / 2;
+    for (int i = 0; i < maxHeight; i++) {
       topRow = getRow(i, topRow);
-      bottomRow = getRow(height - 1 - i, bottomRow);
+      int bottomRowIndex = height - 1 - i;
+      bottomRow = getRow(bottomRowIndex, bottomRow);
       topRow.reverse();
       bottomRow.reverse();
       setRow(i, bottomRow);
-      setRow(height - 1 - i, topRow);
+      setRow(bottomRowIndex, topRow);
     }
   }
 
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/CharacterSetECI.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/CharacterSetECI.java
index 7c3853ca89..4be90c2347 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/CharacterSetECI.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/CharacterSetECI.java
@@ -78,7 +78,7 @@ public enum CharacterSetECI {
   CharacterSetECI(int value) {
     this(new int[] {value});
   }
-  
+
   CharacterSetECI(int value, String... otherEncodingNames) {
     this.values = new int[] {value};
     this.otherEncodingNames = otherEncodingNames;
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java
index c0146bb1f1..2b32566c02 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGF.java
@@ -153,14 +153,14 @@ public final class GenericGF {
   public int getSize() {
     return size;
   }
-  
+
   public int getGeneratorBase() {
     return generatorBase;
   }
-  
+
   @Override
   public String toString() {
     return "GF(0x" + Integer.toHexString(primitive) + ',' + size + ')';
   }
-  
+
 }
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java
index ddad9823d6..03f67430d6 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/GenericGFPoly.java
@@ -225,12 +225,19 @@ final class GenericGFPoly {
 
   @Override
   public String toString() {
+    if (isZero()) {
+      return "0";
+    }
     StringBuilder result = new StringBuilder(8 * getDegree());
     for (int degree = getDegree(); degree >= 0; degree--) {
       int coefficient = getCoefficient(degree);
       if (coefficient != 0) {
         if (coefficient < 0) {
-          result.append(" - ");
+          if (degree == getDegree()) {
+            result.append("-");
+          } else {
+            result.append(" - ");
+          }
           coefficient = -coefficient;
         } else {
           if (result.length() > 0) {
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/ReedSolomonEncoder.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/ReedSolomonEncoder.java
index ff813cb1ff..2e2b2f0a67 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/ReedSolomonEncoder.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/common/reedsolomon/ReedSolomonEncoder.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
- * <p>Implements Reed-Solomon enbcoding, as the name implies.</p>
+ * <p>Implements Reed-Solomon encoding, as the name implies.</p>
  *
  * @author Sean Owen
  * @author William Rucklidge
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/decoder/Version.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/decoder/Version.java
index 98a6850f08..169e3fd369 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/decoder/Version.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/decoder/Version.java
@@ -152,11 +152,10 @@ public final class Version {
     for (int x = 0; x < max; x++) {
       int i = alignmentPatternCenters[x] - 2;
       for (int y = 0; y < max; y++) {
-        if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
-          // No alignment patterns near the three finder patterns
-          continue;
+        if ((x != 0 || (y != 0 && y != max - 1)) && (x != max - 1 || y != 0)) {
+          bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
         }
-        bitMatrix.setRegion(alignmentPatternCenters[y] - 2, i, 5, 5);
+        // else no o alignment patterns near the three finder patterns
       }
     }
 
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/ByteMatrix.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/ByteMatrix.java
index d7fef0601a..35f344ca38 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/ByteMatrix.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/ByteMatrix.java
@@ -16,6 +16,8 @@
 
 package com.google.zxing.qrcode.encoder;
 
+import java.util.Arrays;
+
 /**
  * JAVAPORT: The original code was a 2D array of ints, but since it only ever gets assigned
  * -1, 0, and 1, I'm going to use less memory and go with bytes.
@@ -66,10 +68,8 @@ public final class ByteMatrix {
   }
 
   public void clear(byte value) {
-    for (int y = 0; y < height; ++y) {
-      for (int x = 0; x < width; ++x) {
-        bytes[y][x] = value;
-      }
+    for (byte[] aByte : bytes) {
+      Arrays.fill(aByte, value);
     }
   }
 
@@ -77,8 +77,9 @@ public final class ByteMatrix {
   public String toString() {
     StringBuilder result = new StringBuilder(2 * width * height + 2);
     for (int y = 0; y < height; ++y) {
+      byte[] bytesY = bytes[y];
       for (int x = 0; x < width; ++x) {
-        switch (bytes[y][x]) {
+        switch (bytesY[x]) {
           case 0:
             result.append(" 0");
             break;
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java
index 90d6517ce8..3a80c70696 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/Encoder.java
@@ -78,7 +78,8 @@ public final class Encoder {
 
     // Determine what character encoding has been specified by the caller, if any
     String encoding = DEFAULT_BYTE_MODE_ENCODING;
-    if (hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET)) {
+    boolean hasEncodingHint = hints != null && hints.containsKey(EncodeHintType.CHARACTER_SET);
+    if (hasEncodingHint) {
       encoding = hints.get(EncodeHintType.CHARACTER_SET).toString();
     }
 
@@ -91,13 +92,20 @@ public final class Encoder {
     BitArray headerBits = new BitArray();
 
     // Append ECI segment if applicable
-    if (mode == Mode.BYTE && !DEFAULT_BYTE_MODE_ENCODING.equals(encoding)) {
+    if (mode == Mode.BYTE && hasEncodingHint) {
       CharacterSetECI eci = CharacterSetECI.getCharacterSetECIByName(encoding);
       if (eci != null) {
         appendECI(eci, headerBits);
       }
     }
 
+    // Append the FNC1 mode header for GS1 formatted data if applicable
+    boolean hasGS1FormatHint = hints != null && hints.containsKey(EncodeHintType.GS1_FORMAT);
+    if (hasGS1FormatHint && Boolean.parseBoolean(hints.get(EncodeHintType.GS1_FORMAT).toString())) {
+      // GS1 formatted codes are prefixed with a FNC1 in first position mode header
+      appendModeInfo(Mode.FNC1_FIRST_POSITION, headerBits);
+    }
+
     // (With ECI in place,) Write the mode marker
     appendModeInfo(mode, headerBits);
 
@@ -147,7 +155,17 @@ public final class Encoder {
     //  Choose the mask pattern and set to "qrCode".
     int dimension = version.getDimensionForVersion();
     ByteMatrix matrix = new ByteMatrix(dimension, dimension);
-    int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
+
+    // Enable manual selection of the pattern to be used via hint
+    int maskPattern = -1;
+    if (hints != null && hints.containsKey(EncodeHintType.QR_MASK_PATTERN)) {
+      int hintMaskPattern = Integer.parseInt(hints.get(EncodeHintType.QR_MASK_PATTERN).toString());
+      maskPattern = QRCode.isValidMaskPattern(hintMaskPattern) ? hintMaskPattern : -1;
+    }
+
+    if (maskPattern == -1) {
+      maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
+    }
     qrCode.setMaskPattern(maskPattern);
 
     // Build the matrix and set it to "qrCode".
@@ -277,7 +295,7 @@ public final class Encoder {
     }
     throw new WriterException("Data too big");
   }
-  
+
   /**
    * @return true if the number of input bits will fit in a code with the specified version and
    * error correction level.
@@ -309,7 +327,7 @@ public final class Encoder {
     }
     // Append termination bits. See 8.4.8 of JISX0510:2004 (p.24) for details.
     // If the last byte isn't 8-bit aligned, we'll add padding bits.
-    int numBitsInLastByte = bits.getSize() & 0x07;    
+    int numBitsInLastByte = bits.getSize() & 0x07;
     if (numBitsInLastByte > 0) {
       for (int i = numBitsInLastByte; i < 8; i++) {
         bits.appendBit(false);
@@ -581,8 +599,11 @@ public final class Encoder {
     } catch (UnsupportedEncodingException uee) {
       throw new WriterException(uee);
     }
-    int length = bytes.length;
-    for (int i = 0; i < length; i += 2) {
+    if (bytes.length % 2 != 0) {
+      throw new WriterException("Kanji byte size not even");
+    }
+    int maxI = bytes.length - 1; // bytes.length must be even
+    for (int i = 0; i < maxI; i += 2) {
       int byte1 = bytes[i] & 0xFF;
       int byte2 = bytes[i + 1] & 0xFF;
       int code = (byte1 << 8) | byte2;
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java
index 1c25d0a5ea..11d7804694 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MaskUtil.java
@@ -52,9 +52,10 @@ final class MaskUtil {
     int width = matrix.getWidth();
     int height = matrix.getHeight();
     for (int y = 0; y < height - 1; y++) {
+      byte[] arrayY = array[y];
       for (int x = 0; x < width - 1; x++) {
-        int value = array[y][x];
-        if (value == array[y][x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1]) {
+        int value = arrayY[x];
+        if (value == arrayY[x + 1] && value == array[y + 1][x] && value == array[y + 1][x + 1]) {
           penalty++;
         }
       }
diff --git a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java
index 9e2345e61c..7bac2d8128 100644
--- a/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java
+++ b/apps/imagegen/zxing/core/src/main/java/com/google/zxing/qrcode/encoder/MatrixUtil.java
@@ -27,11 +27,7 @@ import com.google.zxing.qrcode.decoder.Version;
  */
 final class MatrixUtil {
 
-  private MatrixUtil() {
-    // do nothing
-  }
-
-  private static final int[][] POSITION_DETECTION_PATTERN =  {
+  private static final int[][] POSITION_DETECTION_PATTERN = {
       {1, 1, 1, 1, 1, 1, 1},
       {1, 0, 0, 0, 0, 0, 1},
       {1, 0, 1, 1, 1, 0, 1},
@@ -119,6 +115,10 @@ final class MatrixUtil {
   private static final int TYPE_INFO_POLY = 0x537;
   private static final int TYPE_INFO_MASK_PATTERN = 0x5412;
 
+  private MatrixUtil() {
+    // do nothing
+  }
+
   // Set all cells to -1.  -1 means that the cell is empty (not set yet).
   //
   // JAVAPORT: We shouldn't need to do this at all. The code should be rewritten to begin encoding
@@ -174,21 +174,23 @@ final class MatrixUtil {
       boolean bit = typeInfoBits.get(typeInfoBits.getSize() - 1 - i);
 
       // Type info bits at the left top corner. See 8.9 of JISX0510:2004 (p.46).
-      int x1 = TYPE_INFO_COORDINATES[i][0];
-      int y1 = TYPE_INFO_COORDINATES[i][1];
+      int[] coordinates = TYPE_INFO_COORDINATES[i];
+      int x1 = coordinates[0];
+      int y1 = coordinates[1];
       matrix.set(x1, y1, bit);
 
+      int x2;
+      int y2;
       if (i < 8) {
         // Right top corner.
-        int x2 = matrix.getWidth() - i - 1;
-        int y2 = 8;
-        matrix.set(x2, y2, bit);
+        x2 = matrix.getWidth() - i - 1;
+        y2 = 8;
       } else {
         // Left bottom corner.
-        int x2 = 8;
-        int y2 = matrix.getHeight() - 7 + (i - 8);
-        matrix.set(x2, y2, bit);
+        x2 = 8;
+        y2 = matrix.getHeight() - 7 + (i - 8);
       }
+      matrix.set(x2, y2, bit);
     }
   }
 
@@ -298,7 +300,7 @@ final class MatrixUtil {
   // The return value is 0xc94 (1100 1001 0100)
   //
   // Since all coefficients in the polynomials are 1 or 0, we can do the calculation by bit
-  // operations. We don't care if cofficients are positive or negative.
+  // operations. We don't care if coefficients are positive or negative.
   static int calculateBCHCode(int value, int poly) {
     if (poly == 0) {
       throw new IllegalArgumentException("0 polynomial");
@@ -401,21 +403,20 @@ final class MatrixUtil {
     }
   }
 
-  // Note that we cannot unify the function with embedPositionDetectionPattern() despite they are
-  // almost identical, since we cannot write a function that takes 2D arrays in different sizes in
-  // C/C++. We should live with the fact.
   private static void embedPositionAdjustmentPattern(int xStart, int yStart, ByteMatrix matrix) {
     for (int y = 0; y < 5; ++y) {
+      int[] patternY = POSITION_ADJUSTMENT_PATTERN[y];
       for (int x = 0; x < 5; ++x) {
-        matrix.set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
+        matrix.set(xStart + x, yStart + y, patternY[x]);
       }
     }
   }
 
   private static void embedPositionDetectionPattern(int xStart, int yStart, ByteMatrix matrix) {
     for (int y = 0; y < 7; ++y) {
+      int[] patternY = POSITION_DETECTION_PATTERN[y];
       for (int x = 0; x < 7; ++x) {
-        matrix.set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
+        matrix.set(xStart + x, yStart + y, patternY[x]);
       }
     }
   }
@@ -459,19 +460,15 @@ final class MatrixUtil {
     }
     int index = version.getVersionNumber() - 1;
     int[] coordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index];
-    int numCoordinates = POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index].length;
-    for (int i = 0; i < numCoordinates; ++i) {
-      for (int j = 0; j < numCoordinates; ++j) {
-        int y = coordinates[i];
-        int x = coordinates[j];
-        if (x == -1 || y == -1) {
-          continue;
-        }
-        // If the cell is unset, we embed the position adjustment pattern here.
-        if (isEmpty(matrix.get(x, y))) {
-          // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
-          // left top corner.
-          embedPositionAdjustmentPattern(x - 2, y - 2, matrix);
+    for (int y : coordinates) {
+      if (y >= 0) {
+        for (int x : coordinates) {
+          if (x >= 0 && isEmpty(matrix.get(x, y))) {
+            // If the cell is unset, we embed the position adjustment pattern here.
+            // -2 is necessary since the x/y coordinates point to the center of the pattern, not the
+            // left top corner.
+            embedPositionAdjustmentPattern(x - 2, y - 2, matrix);
+          }
         }
       }
     }
-- 
GitLab