Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/zxing-cpp/core/src/GTIN.cpp @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 /* | |
| 2 * Copyright 2016 Nu-book Inc. | |
| 3 * Copyright 2016 ZXing authors | |
| 4 */ | |
| 5 // SPDX-License-Identifier: Apache-2.0 | |
| 6 | |
| 7 #include "GTIN.h" | |
| 8 | |
| 9 #include "Barcode.h" | |
| 10 | |
| 11 #include <algorithm> | |
| 12 #include <iomanip> | |
| 13 #include <iterator> | |
| 14 #include <sstream> | |
| 15 #include <string> | |
| 16 | |
| 17 namespace ZXing::GTIN { | |
| 18 | |
| 19 struct CountryId | |
| 20 { | |
| 21 uint16_t first; | |
| 22 uint16_t last; | |
| 23 const char id[3]; | |
| 24 }; | |
| 25 | |
| 26 bool operator<(const CountryId& lhs, const CountryId& rhs) | |
| 27 { | |
| 28 return lhs.last < rhs.last; | |
| 29 } | |
| 30 | |
| 31 // https://www.gs1.org/standards/id-keys/company-prefix (as of 7 Feb 2022) | |
| 32 // and https://en.wikipedia.org/wiki/List_of_GS1_country_codes | |
| 33 static const CountryId COUNTRIES[] = { | |
| 34 // clang-format off | |
| 35 {1, 19, "US"}, | |
| 36 {30, 39, "US"}, | |
| 37 {60, 99, "US"}, // Note 99 coupon identification | |
| 38 {100, 139, "US"}, | |
| 39 {300, 379, "FR"}, // France (and Monaco according to Wikipedia) | |
| 40 {380, 380, "BG"}, // Bulgaria | |
| 41 {383, 383, "SI"}, // Slovenia | |
| 42 {385, 385, "HR"}, // Croatia | |
| 43 {387, 387, "BA"}, // Bosnia and Herzegovina | |
| 44 {389, 389, "ME"}, // Montenegro | |
| 45 //{390, 390, "XK"}, // (Kosovo according to Wikipedia, unsourced) | |
| 46 {400, 440, "DE"}, // Germany | |
| 47 {450, 459, "JP"}, // Japan | |
| 48 {460, 469, "RU"}, // Russia | |
| 49 {470, 470, "KG"}, // Kyrgyzstan | |
| 50 {471, 471, "TW"}, // Taiwan | |
| 51 {474, 474, "EE"}, // Estonia | |
| 52 {475, 475, "LV"}, // Latvia | |
| 53 {476, 476, "AZ"}, // Azerbaijan | |
| 54 {477, 477, "LT"}, // Lithuania | |
| 55 {478, 478, "UZ"}, // Uzbekistan | |
| 56 {479, 479, "LK"}, // Sri Lanka | |
| 57 {480, 480, "PH"}, // Philippines | |
| 58 {481, 481, "BY"}, // Belarus | |
| 59 {482, 482, "UA"}, // Ukraine | |
| 60 {483, 483, "TM"}, // Turkmenistan | |
| 61 {484, 484, "MD"}, // Moldova | |
| 62 {485, 485, "AM"}, // Armenia | |
| 63 {486, 486, "GE"}, // Georgia | |
| 64 {487, 487, "KZ"}, // Kazakhstan | |
| 65 {488, 488, "TJ"}, // Tajikistan | |
| 66 {489, 489, "HK"}, // Hong Kong | |
| 67 {490, 499, "JP"}, // Japan | |
| 68 {500, 509, "GB"}, // UK | |
| 69 {520, 521, "GR"}, // Greece | |
| 70 {528, 528, "LB"}, // Lebanon | |
| 71 {529, 529, "CY"}, // Cyprus | |
| 72 {530, 530, "AL"}, // Albania | |
| 73 {531, 531, "MK"}, // North Macedonia | |
| 74 {535, 535, "MT"}, // Malta | |
| 75 {539, 539, "IE"}, // Ireland | |
| 76 {540, 549, "BE"}, // Belgium & Luxembourg | |
| 77 {560, 560, "PT"}, // Portugal | |
| 78 {569, 569, "IS"}, // Iceland | |
| 79 {570, 579, "DK"}, // Denmark (and Faroe Islands and Greenland according to Wikipedia) | |
| 80 {590, 590, "PL"}, // Poland | |
| 81 {594, 594, "RO"}, // Romania | |
| 82 {599, 599, "HU"}, // Hungary | |
| 83 {600, 601, "ZA"}, // South Africa | |
| 84 {603, 603, "GH"}, // Ghana | |
| 85 {604, 604, "SN"}, // Senegal | |
| 86 {608, 608, "BH"}, // Bahrain | |
| 87 {609, 609, "MU"}, // Mauritius | |
| 88 {611, 611, "MA"}, // Morocco | |
| 89 {613, 613, "DZ"}, // Algeria | |
| 90 {615, 615, "NG"}, // Nigeria | |
| 91 {616, 616, "KE"}, // Kenya | |
| 92 {617, 617, "CM"}, // Cameroon | |
| 93 {618, 618, "CI"}, // Côte d'Ivoire | |
| 94 {619, 619, "TN"}, // Tunisia | |
| 95 {620, 620, "TZ"}, // Tanzania | |
| 96 {621, 621, "SY"}, // Syria | |
| 97 {622, 622, "EG"}, // Egypt | |
| 98 {623, 623, "BN"}, // Brunei | |
| 99 {624, 624, "LY"}, // Libya | |
| 100 {625, 625, "JO"}, // Jordan | |
| 101 {626, 626, "IR"}, // Iran | |
| 102 {627, 627, "KW"}, // Kuwait | |
| 103 {628, 628, "SA"}, // Saudi Arabia | |
| 104 {629, 629, "AE"}, // United Arab Emirates | |
| 105 {630, 630, "QA"}, // Qatar | |
| 106 {631, 631, "NA"}, // Namibia | |
| 107 {640, 649, "FI"}, // Finland | |
| 108 {690, 699, "CN"}, // China | |
| 109 {700, 709, "NO"}, // Norway | |
| 110 {729, 729, "IL"}, // Israel | |
| 111 {730, 739, "SE"}, // Sweden | |
| 112 {740, 740, "GT"}, // Guatemala | |
| 113 {741, 741, "SV"}, // El Salvador | |
| 114 {742, 742, "HN"}, // Honduras | |
| 115 {743, 743, "NI"}, // Nicaragua | |
| 116 {744, 744, "CR"}, // Costa Rica | |
| 117 {745, 745, "PA"}, // Panama | |
| 118 {746, 746, "DO"}, // Dominican Republic | |
| 119 {750, 750, "MX"}, // Mexico | |
| 120 {754, 755, "CA"}, // Canada | |
| 121 {759, 759, "VE"}, // Venezuela | |
| 122 {760, 769, "CH"}, // Switzerland (and Liechtenstein according to Wikipedia) | |
| 123 {770, 771, "CO"}, // Colombia | |
| 124 {773, 773, "UY"}, // Uruguay | |
| 125 {775, 775, "PE"}, // Peru | |
| 126 {777, 777, "BO"}, // Bolivia | |
| 127 {778, 779, "AR"}, // Argentina | |
| 128 {780, 780, "CL"}, // Chile | |
| 129 {784, 784, "PY"}, // Paraguay | |
| 130 {786, 786, "EC"}, // Ecuador | |
| 131 {789, 790, "BR"}, // Brazil | |
| 132 {800, 839, "IT"}, // Italy (and San Marino and Vatican City according to Wikipedia) | |
| 133 {840, 849, "ES"}, // Spain (and Andorra according to Wikipedia) | |
| 134 {850, 850, "CU"}, // Cuba | |
| 135 {858, 858, "SK"}, // Slovakia | |
| 136 {859, 859, "CZ"}, // Czechia | |
| 137 {860, 860, "RS"}, // Serbia | |
| 138 {865, 865, "MN"}, // Mongolia | |
| 139 {867, 867, "KP"}, // North Korea | |
| 140 {868, 869, "TR"}, // Turkey | |
| 141 {870, 879, "NL"}, // Netherlands | |
| 142 {880, 880, "KR"}, // South Korea | |
| 143 {883, 883, "MM"}, // Myanmar | |
| 144 {884, 884, "KH"}, // Cambodia | |
| 145 {885, 885, "TH"}, // Thailand | |
| 146 {888, 888, "SG"}, // Singapore | |
| 147 {890, 890, "IN"}, // India | |
| 148 {893, 893, "VN"}, // Vietnam | |
| 149 {896, 896, "PK"}, // Pakistan | |
| 150 {899, 899, "ID"}, // Indonesia | |
| 151 {900, 919, "AT"}, // Austria | |
| 152 {930, 939, "AU"}, // Australia | |
| 153 {940, 949, "NZ"}, // New Zealand | |
| 154 {955, 955, "MY"}, // Malaysia | |
| 155 {958, 958, "MO"}, // Macao | |
| 156 //{960, 961, "GB"}, // Global Office - assigned to GS1 UK for GTIN-8 allocations (also 9620-9624999) | |
| 157 // clang-format on | |
| 158 }; | |
| 159 | |
| 160 std::string LookupCountryIdentifier(const std::string& GTIN, const BarcodeFormat format) | |
| 161 { | |
| 162 // Ignore add-on if any | |
| 163 const auto space = GTIN.find(' '); | |
| 164 const std::string::size_type size = space != std::string::npos ? space : GTIN.size(); | |
| 165 | |
| 166 if (size != 14 && size != 13 && size != 12 && size != 8) | |
| 167 return {}; | |
| 168 | |
| 169 // GTIN-14 leading packaging level indicator | |
| 170 const int first = size == 14 ? 1 : 0; | |
| 171 // UPC-A/E implicit leading 0 | |
| 172 const int implicitZero = size == 12 || (size == 8 && format != BarcodeFormat::EAN8) ? 1 : 0; | |
| 173 | |
| 174 if (size != 8 || format != BarcodeFormat::EAN8) { // Assuming following doesn't apply to EAN-8 | |
| 175 // 0000000 Restricted Circulation Numbers; 0000001-0000099 unused to avoid collision with GTIN-8 | |
| 176 int prefix = std::stoi(GTIN.substr(first, 7 - implicitZero)); | |
| 177 if (prefix >= 0 && prefix <= 99) | |
| 178 return {}; | |
| 179 | |
| 180 // 00001-00009 US | |
| 181 prefix = std::stoi(GTIN.substr(first, 5 - implicitZero)); | |
| 182 if (prefix >= 1 && prefix <= 9) | |
| 183 return "US"; | |
| 184 | |
| 185 // 0001-0009 US | |
| 186 prefix = std::stoi(GTIN.substr(first, 4 - implicitZero)); | |
| 187 if (prefix >= 1 && prefix <= 9) | |
| 188 return "US"; | |
| 189 } | |
| 190 | |
| 191 const int prefix = std::stoi(GTIN.substr(first, 3 - implicitZero)); | |
| 192 | |
| 193 // Special case EAN-8 for prefix < 100 (GS1 General Specifications Figure 1.4.3-1) | |
| 194 if (size == 8 && format == BarcodeFormat::EAN8 && prefix <= 99) // Restricted Circulation Numbers | |
| 195 return {}; | |
| 196 | |
| 197 const auto it = std::lower_bound(std::begin(COUNTRIES), std::end(COUNTRIES), CountryId{0, narrow_cast<uint16_t>(prefix), ""}); | |
| 198 | |
| 199 return it != std::end(COUNTRIES) && prefix >= it->first && prefix <= it->last ? it->id : std::string(); | |
| 200 } | |
| 201 | |
| 202 std::string EanAddOn(const Barcode& barcode) | |
| 203 { | |
| 204 if (!(BarcodeFormat::EAN13 | BarcodeFormat::UPCA | BarcodeFormat::UPCE | BarcodeFormat::EAN8).testFlag(barcode.format())) | |
| 205 return {}; | |
| 206 auto txt = barcode.bytes().asString(); | |
| 207 auto pos = txt.find(' '); | |
| 208 return pos != std::string::npos ? std::string(txt.substr(pos + 1)) : std::string(); | |
| 209 } | |
| 210 | |
| 211 std::string IssueNr(const std::string& ean2AddOn) | |
| 212 { | |
| 213 if (ean2AddOn.size() != 2) | |
| 214 return {}; | |
| 215 | |
| 216 return std::to_string(std::stoi(ean2AddOn)); | |
| 217 } | |
| 218 | |
| 219 std::string Price(const std::string& ean5AddOn) | |
| 220 { | |
| 221 if (ean5AddOn.size() != 5) | |
| 222 return {}; | |
| 223 | |
| 224 std::string currency; | |
| 225 switch (ean5AddOn.front()) { | |
| 226 case '0': [[fallthrough]]; | |
| 227 case '1': currency = "GBP £"; break; // UK | |
| 228 case '3': currency = "AUD $"; break; // AUS | |
| 229 case '4': currency = "NZD $"; break; // NZ | |
| 230 case '5': currency = "USD $"; break; // US | |
| 231 case '6': currency = "CAD $"; break; // CA | |
| 232 case '9': | |
| 233 // Reference: http://www.jollytech.com | |
| 234 if (ean5AddOn == "90000") // No suggested retail price | |
| 235 return {}; | |
| 236 if (ean5AddOn == "99991") // Complementary | |
| 237 return "0.00"; | |
| 238 if (ean5AddOn == "99990") | |
| 239 return "Used"; | |
| 240 | |
| 241 // Otherwise... unknown currency? | |
| 242 currency = ""; | |
| 243 break; | |
| 244 default: currency = ""; break; | |
| 245 } | |
| 246 | |
| 247 int rawAmount = std::stoi(ean5AddOn.substr(1)); | |
| 248 std::stringstream buf; | |
| 249 buf << currency << std::fixed << std::setprecision(2) << (float(rawAmount) / 100); | |
| 250 return buf.str(); | |
| 251 } | |
| 252 | |
| 253 } // namespace ZXing::GTIN |
