datablock.js 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. Ported to JavaScript by Lazar Laszlo 2011
  3. lazarsoft@gmail.com, www.lazarsoft.info
  4. */
  5. /*
  6. *
  7. * Copyright 2007 ZXing authors
  8. *
  9. * Licensed under the Apache License, Version 2.0 (the "License");
  10. * you may not use this file except in compliance with the License.
  11. * You may obtain a copy of the License at
  12. *
  13. * http://www.apache.org/licenses/LICENSE-2.0
  14. *
  15. * Unless required by applicable law or agreed to in writing, software
  16. * distributed under the License is distributed on an "AS IS" BASIS,
  17. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18. * See the License for the specific language governing permissions and
  19. * limitations under the License.
  20. */
  21. export default function DataBlock(numDataCodewords, codewords) {
  22. this.numDataCodewords = numDataCodewords;
  23. this.codewords = codewords;
  24. }
  25. DataBlock.getDataBlocks = function(rawCodewords, version, ecLevel) {
  26. if (rawCodewords.length != version.totalCodewords) {
  27. throw "ArgumentException";
  28. }
  29. // Figure out the number and size of data blocks used by this version and
  30. // error correction level
  31. var ecBlocks = version.getECBlocksForLevel(ecLevel);
  32. // First count the total number of data blocks
  33. var totalBlocks = 0;
  34. var ecBlockArray = ecBlocks.getECBlocks();
  35. for (var i = 0; i < ecBlockArray.length; i++) {
  36. totalBlocks += ecBlockArray[i].count;
  37. }
  38. // Now establish DataBlocks of the appropriate size and number of data codewords
  39. var result = new Array(totalBlocks);
  40. var numResultBlocks = 0;
  41. for (var j = 0; j < ecBlockArray.length; j++) {
  42. var ecBlock = ecBlockArray[j];
  43. for (var i = 0; i < ecBlock.count; i++) {
  44. var numDataCodewords = ecBlock.dataCodewords;
  45. var numBlockCodewords = ecBlocks.ecCodewordsPerBlock + numDataCodewords;
  46. result[numResultBlocks++] = new DataBlock(numDataCodewords, new Array(numBlockCodewords));
  47. }
  48. }
  49. // All blocks have the same amount of data, except that the last n
  50. // (where n may be 0) have 1 more byte. Figure out where these start.
  51. var shorterBlocksTotalCodewords = result[0].codewords.length;
  52. var longerBlocksStartAt = result.length - 1;
  53. while (longerBlocksStartAt >= 0) {
  54. var numCodewords = result[longerBlocksStartAt].codewords.length;
  55. if (numCodewords == shorterBlocksTotalCodewords) {
  56. break;
  57. }
  58. longerBlocksStartAt--;
  59. }
  60. longerBlocksStartAt++;
  61. var shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ecCodewordsPerBlock;
  62. // The last elements of result may be 1 element longer;
  63. // first fill out as many elements as all of them have
  64. var rawCodewordsOffset = 0;
  65. for (var i = 0; i < shorterBlocksNumDataCodewords; i++) {
  66. for (var j = 0; j < numResultBlocks; j++) {
  67. result[j].codewords[i] = rawCodewords[rawCodewordsOffset++];
  68. }
  69. }
  70. // Fill out the last data block in the longer ones
  71. for (var j = longerBlocksStartAt; j < numResultBlocks; j++) {
  72. result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++];
  73. }
  74. // Now add in error correction blocks
  75. var max = result[0].codewords.length;
  76. for (var i = shorterBlocksNumDataCodewords; i < max; i++) {
  77. for (var j = 0; j < numResultBlocks; j++) {
  78. var iOffset = j < longerBlocksStartAt ? i : i + 1;
  79. result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++];
  80. }
  81. }
  82. return result;
  83. };