From a5f66f0a177362cc5bc7a67a238fd2a08777b285 Mon Sep 17 00:00:00 2001 From: ftiercelin Date: Wed, 23 Oct 2024 17:13:03 +0100 Subject: [PATCH 1/2] fix issue #1831 make PDF417#determineDimensions to enable finer UT add UT coverage to validate fix for #1831 --- .../google/zxing/pdf417/encoder/PDF417.java | 18 ++++++-- .../pdf417/encoder/PDF417EncoderTestCase.java | 45 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java b/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java index a9d63dc23..363c9bf10 100644 --- a/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java +++ b/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java @@ -659,7 +659,8 @@ public final class PDF417 { String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction, encoding, autoECI); int sourceCodeWords = highLevel.length(); - int[] dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords); + int[] dimension = determineDimensions(minCols, maxCols, minRows, maxRows, + sourceCodeWords, errorCorrectionCodeWords); int cols = dimension[0]; int rows = dimension[1]; @@ -694,14 +695,23 @@ public final class PDF417 { * * @param sourceCodeWords number of code words * @param errorCorrectionCodeWords number of error correction code words + * @param minCols minimum number of columns + * @param maxCols maximum number of columns + * @param minRows minimum number of rows + * @param maxRows maximum number of rows * @return dimension object containing cols as width and rows as height + * @throws WriterException when dimensions can't be determined */ - private int[] determineDimensions(int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException { + protected static int[] determineDimensions(int minCols, int maxCols, + int minRows, int maxRows, + int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException { float ratio = 0.0f; int[] dimension = null; + int currentCol = minCols; for (int cols = minCols; cols <= maxCols; cols++) { - + currentCol = cols; + int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols); if (rows < minRows) { @@ -725,7 +735,7 @@ public final class PDF417 { // Handle case when min values were larger than necessary if (dimension == null) { - int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, minCols); + int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, currentCol); if (rows < minRows) { dimension = new int[]{minCols, minRows}; } diff --git a/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java b/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java index 2f582b901..9adcc16fc 100644 --- a/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java +++ b/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java @@ -23,7 +23,10 @@ import java.util.UUID; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; +import com.google.zxing.Writer; import com.google.zxing.WriterException; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.pdf417.PDF417Writer; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -161,4 +164,46 @@ public final class PDF417EncoderTestCase extends Assert { public void testEncodeEmptyString() throws Exception { PDF417HighLevelEncoder.encodeHighLevel("", Compaction.AUTO, null, false); } + + @Test + public void testDimensions() throws Exception { + // test https://github.com/zxing/zxing/issues/1831 + String input = "0000000001000000022200000003330444400888888881010101010"; + testDimensions(input, new Dimensions(1, 30, 7, 10)); + testDimensions(input, new Dimensions(1, 40, 1, 7)); + testDimensions(input, new Dimensions(10, 30, 1, 5)); + testDimensions(input, new Dimensions(1, 3, 1, 15)); + testDimensions(input, new Dimensions(5, 30, 7, 7)); + testDimensions(input, new Dimensions(12, 12, 1, 17)); + testDimensions(input, new Dimensions(1, 30, 7, 7)); + } + + public static void testDimensions(String input, Dimensions dimensions) throws Exception { + int sourceCodeWords = 20; + int errorCorrectionCodeWords = 8; + try { + int[] calculated = PDF417.determineDimensions(dimensions.getMinCols(), dimensions.getMaxCols(), + dimensions.getMinRows(), dimensions.getMaxRows(), + sourceCodeWords, errorCorrectionCodeWords); + assertNotNull(calculated); + assertEquals(2,calculated.length); + assertTrue(dimensions.getMinCols() <= calculated[0]); + assertTrue(dimensions.getMaxCols() >= calculated[0]); + assertTrue(dimensions.getMinRows() <= calculated[1]); + assertTrue(dimensions.getMaxRows() >= calculated[1]); + assertNotNull(generatePDF417BitMatrix(input, 371, null, dimensions)); + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + + public static BitMatrix generatePDF417BitMatrix(final String barcodeText, final int width, + final Integer heightRequested, final Dimensions dimensions) throws WriterException { + final Writer barcodeWriter = new PDF417Writer(); + final int height = heightRequested == null ? width / 4 : heightRequested; + final Map hints = Map.of(EncodeHintType.MARGIN, 0, + EncodeHintType.PDF417_DIMENSIONS, dimensions); + return barcodeWriter.encode(barcodeText, BarcodeFormat.PDF_417, width, height, hints); + } } From 068f67c52950eb07ee2ff77977ef0ec011e0a9f9 Mon Sep 17 00:00:00 2001 From: ftiercelin Date: Wed, 23 Oct 2024 17:20:00 +0100 Subject: [PATCH 2/2] fix javadoc for PDF417#determineDimensions remove stacktrace when UT fails --- .../google/zxing/pdf417/encoder/PDF417.java | 4 ++-- .../pdf417/encoder/PDF417EncoderTestCase.java | 23 ++++++++----------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java b/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java index 363c9bf10..3402bb3d1 100644 --- a/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java +++ b/core/src/main/java/com/google/zxing/pdf417/encoder/PDF417.java @@ -693,12 +693,12 @@ public final class PDF417 { * Determine optimal nr of columns and rows for the specified number of * codewords. * - * @param sourceCodeWords number of code words - * @param errorCorrectionCodeWords number of error correction code words * @param minCols minimum number of columns * @param maxCols maximum number of columns * @param minRows minimum number of rows * @param maxRows maximum number of rows + * @param sourceCodeWords number of code words + * @param errorCorrectionCodeWords number of error correction code words * @return dimension object containing cols as width and rows as height * @throws WriterException when dimensions can't be determined */ diff --git a/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java b/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java index 9adcc16fc..5374877a6 100644 --- a/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java +++ b/core/src/test/java/com/google/zxing/pdf417/encoder/PDF417EncoderTestCase.java @@ -181,21 +181,18 @@ public final class PDF417EncoderTestCase extends Assert { public static void testDimensions(String input, Dimensions dimensions) throws Exception { int sourceCodeWords = 20; int errorCorrectionCodeWords = 8; - try { - int[] calculated = PDF417.determineDimensions(dimensions.getMinCols(), dimensions.getMaxCols(), + + int[] calculated = PDF417.determineDimensions(dimensions.getMinCols(), dimensions.getMaxCols(), dimensions.getMinRows(), dimensions.getMaxRows(), sourceCodeWords, errorCorrectionCodeWords); - assertNotNull(calculated); - assertEquals(2,calculated.length); - assertTrue(dimensions.getMinCols() <= calculated[0]); - assertTrue(dimensions.getMaxCols() >= calculated[0]); - assertTrue(dimensions.getMinRows() <= calculated[1]); - assertTrue(dimensions.getMaxRows() >= calculated[1]); - assertNotNull(generatePDF417BitMatrix(input, 371, null, dimensions)); - } catch (Exception e) { - e.printStackTrace(); - throw e; - } + + assertNotNull(calculated); + assertEquals(2,calculated.length); + assertTrue(dimensions.getMinCols() <= calculated[0]); + assertTrue(dimensions.getMaxCols() >= calculated[0]); + assertTrue(dimensions.getMinRows() <= calculated[1]); + assertTrue(dimensions.getMaxRows() >= calculated[1]); + assertNotNull(generatePDF417BitMatrix(input, 371, null, dimensions)); } public static BitMatrix generatePDF417BitMatrix(final String barcodeText, final int width,