DMDecodedBitStreamParserTest.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /*
  2. * Copyright 2017 Huy Cuong Nguyen
  3. * Copyright 2008 ZXing authors
  4. */
  5. // SPDX-License-Identifier: Apache-2.0
  6. #include "ByteArray.h"
  7. #include "DecoderResult.h"
  8. #include "gtest/gtest.h"
  9. #include <utility>
  10. namespace ZXing::DataMatrix::DecodedBitStreamParser {
  11. DecoderResult Decode(ByteArray&& bytes, const bool isDMRE);
  12. }
  13. using namespace ZXing;
  14. // Helper to call Decode()
  15. static DecoderResult parse(ByteArray bytes, const bool isDMRE = false)
  16. {
  17. return DataMatrix::DecodedBitStreamParser::Decode(std::move(bytes), isDMRE);
  18. }
  19. // Shorthand to return text
  20. static std::wstring decode(ByteArray bytes, const bool isDMRE = false)
  21. {
  22. return parse(std::move(bytes), isDMRE).text();
  23. }
  24. // Shorthand to return symbology identifier
  25. static std::string id(ByteArray bytes, const bool isDMRE = false)
  26. {
  27. return parse(std::move(bytes), isDMRE).symbologyIdentifier();
  28. }
  29. // Shorthand to return Structured Append
  30. static StructuredAppendInfo info(ByteArray bytes, const bool isDMRE = false)
  31. {
  32. return parse(std::move(bytes), isDMRE).structuredAppend();
  33. }
  34. TEST(DMDecodeTest, Ascii)
  35. {
  36. // ASCII characters 0-127 are encoded as the value + 1
  37. EXPECT_EQ(decode({'b', 'c', 'd', 'B', 'C', 'D'}), L"abcABC");
  38. // ASCII double digit (00 - 99) Numeric Value + 130
  39. EXPECT_EQ(decode({130, 131, 228, 229}), L"00019899");
  40. }
  41. TEST(DMDecodeTest, AsciiError)
  42. {
  43. // ASCII err on invalid code word
  44. EXPECT_EQ(parse({66, 250, 68}).error(), Error::Format);
  45. // ASCII err on invalid code word at end (currently failing)
  46. EXPECT_EQ(parse({66, 67, 68, 250}).error(), Error::Format);
  47. // ASCII accept extra (illegal) unlatch at end
  48. EXPECT_FALSE(parse({66, 67, 68, 254}).error());
  49. }
  50. // Most of the following examples are taken from the DMHighLevelEncodeTest.cpp tests.
  51. // For an explanation of the different cases, see there.
  52. TEST(DMDecodeTest, C40)
  53. {
  54. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 254}), L"AIMAIMAIM");
  55. EXPECT_EQ(decode({66, 74, 78, 66, 74, 66, 99, 129}), L"AIMAIAb");
  56. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 254, 235, 76}), L"AIMAIMAIM\xCB");
  57. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 254, 235, 108}), L"AIMAIMAIM\xEB");
  58. EXPECT_EQ(decode({230, 88, 88, 40, 8, 107, 147, 59, 67, 126, 206, 78, 126, 144, 121, 35, 47, 254}), L"A1B2C3D4E5F6G7H8I9J0K1L2");
  59. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11}), L"AIMAIMAIMAIMAIMAIM");
  60. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 90, 241}), L"AIMAIMAIMAIMAIMAI");
  61. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 254, 66}), L"AIMAIMAIMAIMAIMA");
  62. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 254, 66, 74, 129, 237}), L"AIMAIMAIMAIMAIMAI");
  63. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 66}), L"AIMAIMAIMA");
  64. EXPECT_EQ(decode({230, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 91, 11, 254, 66, 74}), L"AIMAIMAIMAIMAIMAIMAI");
  65. }
  66. TEST(DMDecodeTest, Text)
  67. {
  68. EXPECT_EQ(decode({239, 91, 11, 91, 11, 91, 11, 254}), L"aimaimaim");
  69. EXPECT_EQ(decode({239, 91, 11, 91, 11, 91, 11, 254, 40, 129}), L"aimaimaim'");
  70. EXPECT_EQ(decode({239, 91, 11, 91, 11, 87, 218, 110}), L"aimaimaIm");
  71. EXPECT_EQ(decode({239, 91, 11, 91, 11, 91, 11, 254, 67, 129}), L"aimaimaimB");
  72. EXPECT_EQ(decode({239, 91, 11, 91, 11, 91, 11, 16, 218, 236, 107, 181, 69, 254, 129, 237}), L"aimaimaim{txt}\x04");
  73. }
  74. TEST(DMDecodeTest, C40AndTextShiftUpper)
  75. {
  76. // additional shiftUpper test: (1->shift 2, 30->upperShift, 3->' '+128==0xa0) == 2804 == 0x0af4
  77. EXPECT_EQ(decode({230, 0x0a, 0xf4}), L"\xA0"); // C40
  78. EXPECT_EQ(decode({239, 0x0a, 0xf4}), L"\xA0"); // Text
  79. }
  80. TEST(DMDecodeTest, X12)
  81. {
  82. EXPECT_EQ(decode({238, 89, 233, 14, 192, 100, 207, 44, 31, 67}), L"ABC>ABC123>AB");
  83. EXPECT_EQ(decode({238, 89, 233, 14, 192, 100, 207, 44, 31, 254, 67, 68}), L"ABC>ABC123>ABC");
  84. EXPECT_EQ(decode({238, 89, 233, 14, 192, 100, 207, 44, 31, 96, 82, 254}), L"ABC>ABC123>ABCD");
  85. EXPECT_EQ(decode({238, 89, 233, 14, 192, 100, 207, 44, 31, 96, 82, 70}), L"ABC>ABC123>ABCDE");
  86. EXPECT_EQ(decode({238, 89, 233, 14, 192, 100, 207, 44, 31, 96, 82, 254, 70, 71, 129, 237}), L"ABC>ABC123>ABCDEF");
  87. // EXPECT_EQ(decode({}), L"");
  88. }
  89. TEST(DMDecodeTest, SymbologyIdentifier)
  90. {
  91. // Plain
  92. EXPECT_EQ(id({50}), "]d1");
  93. EXPECT_EQ(decode({50}), L"1");
  94. // GS1 "FNC1 (20)01"
  95. EXPECT_EQ(id({232, 150, 131}), "]d2");
  96. EXPECT_EQ(decode({232, 150, 131}), L"2001");
  97. // "LatchC40 Shift2 FNC1 LatchASCII 2001" not recognized as FNC1 in first position
  98. EXPECT_EQ(id({230, 0x0A, 0x79, 254, 150, 131}), "]d1"); // shift2FNC1 = (1600 * 1) + (40 * 27) + 0 + 1 == 0x0A79
  99. EXPECT_EQ(decode({230, 0x0A, 0x79, 254, 150, 131}), L"\u001D2001");
  100. // AIM "A FNC1 B"
  101. EXPECT_EQ(id({66, 232, 67}), "]d3");
  102. EXPECT_EQ(decode({66, 232, 67}), L"AB");
  103. // AIM "9 FNC1 A"
  104. EXPECT_EQ(id({58, 232, 66}), "]d3");
  105. EXPECT_EQ(decode({58, 232, 66}), L"9A");
  106. // AIM "99 FNC1 A" (double digit + 130)
  107. EXPECT_EQ(id({99 + 130, 232, 66}), "]d3");
  108. EXPECT_EQ(decode({99 + 130, 232, 66}), L"99A");
  109. // AIM "? FNC1 A" (ISO/IEC 16022:2006 11.2 does not specify any restrictions on single first character)
  110. EXPECT_EQ(id({64, 232, 66}), "]d3");
  111. EXPECT_EQ(decode({64, 232, 66}), L"?A");
  112. // "LatchC40 A Shift2 FNC1 B" not recognized as FNC1 in second position
  113. EXPECT_EQ(id({230, 0x57, 0xC4, 254, 67}), "]d1"); // shift2FNC1 = 1600 * 14 + (40 * 1) + 27 + 1 == 0x57C4
  114. EXPECT_EQ(decode({230, 0x57, 0xC4, 254, 67}), L"A\u001DB");
  115. // "99 FNC1 A" (2 single digits before FNC1 not recognized as AIM)
  116. EXPECT_EQ(id({58, 58, 232, 66}), "]d1");
  117. EXPECT_EQ(decode({58, 58, 232, 66}), L"99\u001DA");
  118. // GS1 "StructuredAppend FNC1 (20)01"
  119. EXPECT_EQ(id({233, 42, 1, 1, 232, 150, 131}), "]d2");
  120. EXPECT_EQ(decode({233, 42, 1, 1, 232, 150, 131}), L"2001");
  121. // AIM "StructuredAppend A FNC1 B"
  122. EXPECT_EQ(id({233, 42, 1, 1, 66, 232, 67}), "]d3");
  123. EXPECT_EQ(decode({233, 42, 1, 1, 66, 232, 67}), L"AB");
  124. }
  125. TEST(DMDecodeTest, DMRESymbologyIdentifier)
  126. {
  127. // Plain
  128. EXPECT_EQ(id({50}, true /*isDMRE*/), "]d7");
  129. EXPECT_EQ(decode({50}, true /*isDMRE*/), L"1");
  130. // GS1 "FNC1 (20)01"
  131. EXPECT_EQ(id({232, 150, 131}, true /*isDMRE*/), "]d8");
  132. EXPECT_EQ(decode({232, 150, 131}, true /*isDMRE*/), L"2001");
  133. // AIM "A FNC1 B"
  134. EXPECT_EQ(id({66, 232, 67}, true /*isDMRE*/), "]d9");
  135. EXPECT_EQ(decode({66, 232, 67}, true /*isDMRE*/), L"AB");
  136. // AIM "9 FNC1 A"
  137. EXPECT_EQ(id({58, 232, 66}, true /*isDMRE*/), "]d9");
  138. EXPECT_EQ(decode({58, 232, 66}, true /*isDMRE*/), L"9A");
  139. // AIM "99 FNC1 A" (double digit + 130)
  140. EXPECT_EQ(id({99 + 130, 232, 66}, true /*isDMRE*/), "]d9");
  141. EXPECT_EQ(decode({99 + 130, 232, 66}, true /*isDMRE*/), L"99A");
  142. // AIM "? FNC1 A" (ISO/IEC 16022:2006 11.2 does not specify any restrictions on single first character)
  143. EXPECT_EQ(id({64, 232, 66}, true /*isDMRE*/), "]d9");
  144. EXPECT_EQ(decode({64, 232, 66}, true /*isDMRE*/), L"?A");
  145. // "99 FNC1 A" (2 single digits before FNC1 not recognized as AIM)
  146. EXPECT_EQ(id({58, 58, 232, 66}, true /*isDMRE*/), "]d7");
  147. EXPECT_EQ(decode({58, 58, 232, 66}, true /*isDMRE*/), L"99\u001DA");
  148. // GS1 "StructuredAppend FNC1 (20)01"
  149. EXPECT_EQ(id({233, 42, 1, 1, 232, 150, 131}, true /*isDMRE*/), "]d8");
  150. EXPECT_EQ(decode({233, 42, 1, 1, 232, 150, 131}, true /*isDMRE*/), L"2001");
  151. // AIM "StructuredAppend A FNC1 B"
  152. EXPECT_EQ(id({233, 42, 1, 1, 66, 232, 67}, true /*isDMRE*/), "]d9");
  153. EXPECT_EQ(decode({233, 42, 1, 1, 66, 232, 67}, true /*isDMRE*/), L"AB");
  154. }
  155. TEST(DMDecodeTest, StructuredAppend)
  156. {
  157. // Null
  158. EXPECT_EQ(info({50}).index, -1);
  159. EXPECT_EQ(info({50}).count, -1);
  160. EXPECT_TRUE(info({50}).id.empty());
  161. EXPECT_EQ(id({50}), "]d1");
  162. // Structured Append "233" must be first ISO 16022:2006 5.6.1
  163. EXPECT_FALSE(parse({50, 233, 42, 1, 1}).isValid());
  164. // ISO/IEC 16022:2006 5.6.2 sequence indicator example
  165. EXPECT_TRUE(parse({233, 42, 1, 1, 50}).isValid());
  166. EXPECT_EQ(info({233, 42, 1, 1, 50}).index, 2); // 1-based position 3 == index 2
  167. EXPECT_EQ(info({233, 42, 1, 1, 50}).count, 7);
  168. EXPECT_EQ(info({233, 42, 1, 1, 50}).id, "257");
  169. EXPECT_EQ(id({233, 42, 1, 1, 50}), "]d1");
  170. // Sequence indicator
  171. EXPECT_EQ(info({233, 0, 1, 1, 50}).index, 0);
  172. EXPECT_EQ(info({233, 0, 1, 1, 50}).count, 0); // Count 17 set to 0
  173. EXPECT_EQ(info({233, 1, 1, 1, 50}).index, 0);
  174. EXPECT_EQ(info({233, 1, 1, 1, 50}).count, 16);
  175. EXPECT_EQ(info({233, 0x81, 1, 1, 50}).index, 8);
  176. EXPECT_EQ(info({233, 0x81, 1, 1, 50}).count, 16);
  177. EXPECT_EQ(info({233, 0xFF, 1, 1, 50}).index, 15);
  178. EXPECT_EQ(info({233, 0xFF, 1, 1, 50}).count, 0); // Count 2 <= index so set to 0
  179. EXPECT_EQ(info({233, 0xF1, 1, 1, 50}).index, 15);
  180. EXPECT_EQ(info({233, 0xF1, 1, 1, 50}).count, 16);
  181. // File identification
  182. EXPECT_EQ(info({233, 42, 1, 12, 50}).id, "268");
  183. EXPECT_EQ(info({233, 42, 12, 34, 50}).id, "3106");
  184. EXPECT_EQ(info({233, 42, 12, 123, 50}).id, "3195");
  185. EXPECT_EQ(info({233, 42, 254, 254, 50}).id, "65278");
  186. // Values outside 1-254 allowed (i.e. tolerated)
  187. EXPECT_EQ(info({233, 42, 0, 0, 50}).id, "0");
  188. EXPECT_EQ(info({233, 42, 0, 255, 50}).id, "255");
  189. EXPECT_EQ(info({233, 42, 255, 0, 50}).id, "65280");
  190. EXPECT_EQ(info({233, 42, 255, 255, 50}).id, "65535");
  191. }
  192. TEST(DMDecodeTest, ReaderInit)
  193. {
  194. // Null
  195. EXPECT_FALSE(parse({50}).readerInit());
  196. EXPECT_TRUE(parse({50}).isValid());
  197. // Reader Programming "234" must be first ISO 16022:2006 5.2.4.9
  198. EXPECT_FALSE(parse({50, 234}).isValid());
  199. // Set
  200. EXPECT_TRUE(parse({234, 50}).isValid());
  201. EXPECT_TRUE(parse({234, 50}).readerInit());
  202. EXPECT_FALSE(parse({235, 234, 50}).isValid());
  203. // Can't be used with Structured Append "233"
  204. EXPECT_TRUE(parse({233, 42, 1, 1, 50}).isValid()); // Null
  205. EXPECT_FALSE(parse({233, 42, 1, 1, 234, 50}).isValid());
  206. }