Unify handling of EC level between encoder and decoder
[zxing.git] / core / src / com / google / zxing / qrcode / decoder / DataBlock.java
index 2737d80..259a8ac 100755 (executable)
@@ -1,5 +1,5 @@
 /*\r
- * Copyright 2007 Google Inc.\r
+ * Copyright 2007 ZXing authors\r
  *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
 package com.google.zxing.qrcode.decoder;\r
 \r
 /**\r
- * @author srowen@google.com (Sean Owen)\r
+ * <p>Encapsulates a block of data within a QR Code. QR Codes may split their data into\r
+ * multiple blocks, each of which is a unit of data and error-correction codewords. Each\r
+ * is represented by an instance of this class.</p>\r
+ *\r
+ * @author Sean Owen\r
  */\r
 final class DataBlock {\r
 \r
@@ -29,15 +33,32 @@ final class DataBlock {
     this.codewords = codewords;\r
   }\r
 \r
+  /**\r
+   * <p>When QR Codes use multiple data blocks, they are actually interleave the bytes of each of them.\r
+   * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This\r
+   * method will separate the data into original blocks.</p>\r
+   *\r
+   * @param rawCodewords bytes as read directly from the QR Code\r
+   * @param version version of the QR Code\r
+   * @param ecLevel error-correction level of the QR Code\r
+   * @return {@link DataBlock}s containing original bytes, "de-interleaved" from representation in the\r
+   *         QR Code\r
+   */\r
   static DataBlock[] getDataBlocks(byte[] rawCodewords,\r
                                    Version version,\r
                                    ErrorCorrectionLevel ecLevel) {\r
+    // Figure out the number and size of data blocks used by this version and\r
+    // error correction level\r
     Version.ECBlocks ecBlocks = version.getECBlocksForLevel(ecLevel);\r
+\r
+    // First count the total number of data blocks\r
     int totalBlocks = 0;\r
     Version.ECB[] ecBlockArray = ecBlocks.getECBlocks();\r
     for (int i = 0; i < ecBlockArray.length; i++) {\r
       totalBlocks += ecBlockArray[i].getCount();\r
     }\r
+\r
+    // Now establish DataBlocks of the appropriate size and number of data codewords\r
     DataBlock[] result = new DataBlock[totalBlocks];\r
     int numResultBlocks = 0;\r
     for (int j = 0; j < ecBlockArray.length; j++) {\r
@@ -45,8 +66,7 @@ final class DataBlock {
       for (int i = 0; i < ecBlock.getCount(); i++) {\r
         int numDataCodewords = ecBlock.getDataCodewords();\r
         int numBlockCodewords = ecBlocks.getECCodewords() + numDataCodewords;\r
-        result[numResultBlocks++] =\r
-            new DataBlock(numDataCodewords, new byte[numBlockCodewords]);\r
+        result[numResultBlocks++] = new DataBlock(numDataCodewords, new byte[numBlockCodewords]);\r
       }\r
     }\r
 \r
@@ -55,21 +75,18 @@ final class DataBlock {
     int shorterBlocksTotalCodewords = result[0].codewords.length;\r
     int longerBlocksStartAt = result.length - 1;\r
     while (longerBlocksStartAt >= 0) {\r
-      int numCodewords =\r
-          result[longerBlocksStartAt].codewords.length;\r
+      int numCodewords = result[longerBlocksStartAt].codewords.length;\r
       if (numCodewords == shorterBlocksTotalCodewords) {\r
         break;\r
       }\r
       if (numCodewords != shorterBlocksTotalCodewords + 1) {\r
-        throw new IllegalStateException(\r
-            "Data block sizes differ by more than 1");\r
+        throw new IllegalArgumentException("Data block sizes differ by more than 1");\r
       }\r
       longerBlocksStartAt--;\r
     }\r
     longerBlocksStartAt++;\r
 \r
-    int shorterBlocksNumDataCodewords =\r
-        shorterBlocksTotalCodewords - ecBlocks.getECCodewords();\r
+    int shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.getECCodewords();\r
     // The last elements of result may be 1 element longer;\r
     // first fill out as many elements as all of them have\r
     int rawCodewordsOffset = 0;\r
@@ -80,8 +97,7 @@ final class DataBlock {
     }\r
     // Fill out the last data block in the longer ones\r
     for (int j = longerBlocksStartAt; j < numResultBlocks; j++) {\r
-      result[j].codewords[shorterBlocksNumDataCodewords] =\r
-          rawCodewords[rawCodewordsOffset++];\r
+      result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];\r
     }\r
     // Now add in error correction blocks\r
     int max = result[0].codewords.length;\r
@@ -93,7 +109,7 @@ final class DataBlock {
     }\r
 \r
     if (rawCodewordsOffset != rawCodewords.length) {\r
-      throw new IllegalStateException();\r
+      throw new IllegalArgumentException();\r
     }\r
 \r
     return result;\r