You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright 2012 ZXing authors
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "ZXByteArray.h"
  17. #import "ZXDecoderResult.h"
  18. #import "ZXErrors.h"
  19. #import "ZXMaxiCodeDecodedBitStreamParser.h"
  20. const unichar SHIFTA = 0xFFF0;
  21. const unichar SHIFTB = 0xFFF1;
  22. const unichar SHIFTC = 0xFFF2;
  23. const unichar SHIFTD = 0xFFF3;
  24. const unichar SHIFTE = 0xFFF4;
  25. const unichar TWOSHIFTA = 0xFFF5;
  26. const unichar THREESHIFTA = 0xFFF6;
  27. const unichar LATCHA = 0xFFF7;
  28. const unichar LATCHB = 0xFFF8;
  29. const unichar LOCK = 0xFFF9;
  30. const unichar ECI = 0xFFFA;
  31. const unichar NS = 0xFFFB;
  32. const unichar PAD = 0xFFFC;
  33. const unichar FS = 0x001C;
  34. const unichar GS = 0x001D;
  35. const unichar RS = 0x001E;
  36. const unichar SETS[1][383] = {
  37. '\n', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
  38. 'X', 'Y', 'Z', ECI, FS, GS, RS, NS, ' ', PAD, '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0',
  39. '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', SHIFTB, SHIFTC, SHIFTD, SHIFTE, LATCHB,
  40. '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' , 'q', 'r', 's', 't', 'u', 'v', 'w',
  41. 'x', 'y', 'z', ECI, FS, GS, RS, NS, '{', PAD, '}', '~', 0x007F, ';', '<', '=', '>', '?', '[', '\\', ']', '^', '_', ' ',
  42. ',', '.', '/', ':', '@', '!', '|', PAD, TWOSHIFTA, THREESHIFTA, PAD, SHIFTA, SHIFTC, SHIFTD, SHIFTE, LATCHA,
  43. 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE,
  44. 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, ECI, FS, GS, RS, 0x00DB,
  45. 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00AA, 0x00AC, 0x00B1, 0x00B2, 0x00B3, 0x00B5, 0x00B9, 0x00BA, 0x00BC, 0x00BD, 0x00BE,
  46. 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, LATCHA, ' ', LOCK, SHIFTD, SHIFTE, LATCHB,
  47. 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE,
  48. 0x00EF, 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, ECI, FS, GS, RS, NS,
  49. 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, 0x00A1, 0x00A8, 0x00AB, 0x00AF, 0x00B0, 0x00B4, 0x00B7, 0x00B8, 0x00BB, 0x00BF,
  50. 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, LATCHA, ' ', SHIFTC, LOCK, SHIFTE,
  51. LATCHB, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r',
  52. 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, ECI, PAD, PAD,
  53. 0x001B, NS, FS, GS, RS, 0x001F, 0x009F, 0x00A0, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, 0x00A9, 0x00AD, 0x00AE,
  54. 0x00B6, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, LATCHA, ' ', SHIFTC, SHIFTD, LOCK,
  55. LATCHB, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, '\n', 0x000B, 0x000C, '\r',
  56. 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001A, 0x001B, 0x001C,
  57. 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, '"', 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B,
  58. 0x002C, 0x002D, 0x002E, 0x002F, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A,
  59. 0x003B, 0x003C, 0x003D, 0x003E, 0x003F
  60. };
  61. @implementation ZXMaxiCodeDecodedBitStreamParser
  62. + (ZXDecoderResult *)decode:(ZXByteArray *)bytes mode:(int)mode {
  63. NSMutableString *result = [NSMutableString stringWithCapacity:144];
  64. switch (mode) {
  65. case 2:
  66. case 3: {
  67. NSString *postcode;
  68. if (mode == 2) {
  69. int pc = [self postCode2:bytes];
  70. postcode = [NSString stringWithFormat:@"%9d", pc];
  71. } else {
  72. postcode = [self postCode3:bytes];
  73. }
  74. NSString *country = [NSString stringWithFormat:@"%3d", [self country:bytes]];
  75. NSString *service = [NSString stringWithFormat:@"%3d", [self serviceClass:bytes]];
  76. [result appendString:[self message:bytes start:10 len:84]];
  77. if ([result hasPrefix:[NSString stringWithFormat:@"[)>%C01%C", RS, GS]]) {
  78. [result insertString:[NSString stringWithFormat:@"%@%C%@%C%@%C", postcode, GS, country, GS, service, GS] atIndex:9];
  79. } else {
  80. [result insertString:[NSString stringWithFormat:@"%@%C%@%C%@%C", postcode, GS, country, GS, service, GS] atIndex:0];
  81. }
  82. break;
  83. }
  84. case 4:
  85. [result appendString:[self message:bytes start:1 len:93]];
  86. break;
  87. case 5:
  88. [result appendString:[self message:bytes start:1 len:77]];
  89. break;
  90. }
  91. return [[ZXDecoderResult alloc] initWithRawBytes:bytes
  92. text:result
  93. byteSegments:nil
  94. ecLevel:[NSString stringWithFormat:@"%d", mode]];
  95. }
  96. + (int)bit:(int)bit bytes:(ZXByteArray *)bytes {
  97. bit--;
  98. return (bytes.array[bit / 6] & (1 << (5 - (bit % 6)))) == 0 ? 0 : 1;
  99. }
  100. + (int)integer:(ZXByteArray *)bytes x:(ZXByteArray *)x {
  101. int val = 0;
  102. for (int i = 0; i < x.length; i++) {
  103. val += [self bit:x.array[i] bytes:bytes] << (x.length - i - 1);
  104. }
  105. return val;
  106. }
  107. + (int)country:(ZXByteArray *)bytes {
  108. return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:53, 54, 43, 44, 45, 46, 47, 48, 37, 38, -1]];
  109. }
  110. + (int)serviceClass:(ZXByteArray *)bytes {
  111. return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:55, 56, 57, 58, 59, 60, 49, 50, 51, 52, -1]];
  112. }
  113. + (int)postCode2Length:(ZXByteArray *)bytes {
  114. return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:39, 40, 41, 42, 31, 32, -1]];
  115. }
  116. + (int)postCode2:(ZXByteArray *)bytes {
  117. return [self integer:bytes x:[[ZXByteArray alloc] initWithBytes:33, 34, 35, 36, 25, 26, 27, 28, 29, 30, 19,
  118. 20, 21, 22, 23, 24, 13, 14, 15, 16, 17, 18, 7, 8, 9, 10, 11, 12, 1, 2, -1]];
  119. }
  120. + (NSString *)postCode3:(ZXByteArray *)bytes {
  121. return [NSString stringWithFormat:@"%C%C%C%C%C%C",
  122. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:39, 40, 41, 42, 31, 32, -1]]],
  123. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:33, 34, 35, 36, 25, 26, -1]]],
  124. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:27, 28, 29, 30, 19, 20, -1]]],
  125. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:21, 22, 23, 24, 13, 14, -1]]],
  126. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes:15, 16, 17, 18, 7, 8, -1]]],
  127. SETS[0][[self integer:bytes x:[[ZXByteArray alloc] initWithBytes: 9, 10, 11, 12, 1, 2, -1]]]];
  128. }
  129. + (NSString *)message:(ZXByteArray *)bytes start:(int)start len:(int)len {
  130. NSMutableString *sb = [NSMutableString string];
  131. int shift = -1;
  132. int set = 0;
  133. int lastset = 0;
  134. for (int i = start; i < start + len; i++) {
  135. unichar c = SETS[set][bytes.array[i]];
  136. switch (c) {
  137. case LATCHA:
  138. set = 0;
  139. shift = -1;
  140. break;
  141. case LATCHB:
  142. set = 1;
  143. shift = -1;
  144. break;
  145. case SHIFTA:
  146. case SHIFTB:
  147. case SHIFTC:
  148. case SHIFTD:
  149. case SHIFTE:
  150. lastset = set;
  151. set = c - SHIFTA;
  152. shift = 1;
  153. break;
  154. case TWOSHIFTA:
  155. lastset = set;
  156. set = 0;
  157. shift = 2;
  158. break;
  159. case THREESHIFTA:
  160. lastset = set;
  161. set = 0;
  162. shift = 3;
  163. break;
  164. case NS: {
  165. int nsval1 = bytes.array[++i] << 24;
  166. int nsval2 = bytes.array[++i] << 18;
  167. int nsval3 = bytes.array[++i] << 12;
  168. int nsval4 = bytes.array[++i] << 6;
  169. int nsval5 = bytes.array[++i];
  170. int nsval = nsval1 + nsval2 + nsval3 + nsval4 + nsval5;
  171. [sb appendFormat:@"%9d", nsval];
  172. break;
  173. }
  174. case LOCK:
  175. shift = -1;
  176. break;
  177. default:
  178. [sb appendFormat:@"%C", c];
  179. }
  180. if (shift-- == 0) {
  181. set = lastset;
  182. }
  183. }
  184. while (sb.length > 0 && [sb characterAtIndex:sb.length - 1] == PAD) {
  185. [sb deleteCharactersInRange:NSMakeRange(sb.length - 1, 1)];
  186. }
  187. return sb;
  188. }
  189. @end