fuzzReadMatrix.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /*
  2. * Copyright 2023 Axel Waggershauser
  3. */
  4. // SPDX-License-Identifier: Apache-2.0
  5. #include "ReadBarcode.h"
  6. #include <csignal>
  7. #include <cstddef>
  8. #include <cstdint>
  9. #include <cstdlib>
  10. using namespace ZXing;
  11. uint64_t Expand(uint8_t b)
  12. {
  13. uint64_t shift = 0x0000040810204081ul; // bits set: 0, 7, 14, 21, 28, 35, 42
  14. uint64_t mask = 0x0001010101010101ul; // bits set: 0, 8, 16, 24, 32, 40, 48
  15. return ((uint64_t)(b & 127) * shift & mask) | (uint64_t)(b & 128) << 49;
  16. }
  17. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
  18. {
  19. if (size < 3)
  20. return 0;
  21. static auto opts = ReaderOptions()
  22. .setFormats(BarcodeFormat::MatrixCodes)
  23. .setBinarizer(Binarizer::BoolCast)
  24. .setReturnErrors(true)
  25. .setTryInvert(false)
  26. .setTryRotate(false);
  27. int ratio = data[0] + 1;
  28. int nBits = (size - 1) * 8;
  29. int width = std::clamp(nBits * ratio / 256, 1, nBits);
  30. int height = std::clamp(nBits / width, 1, nBits);
  31. assert(width * height <= nBits);
  32. ByteArray buffer(nBits);
  33. for (size_t i = 1; i < size; ++i)
  34. *reinterpret_cast<uint64_t*>(&buffer[(i - 1) * 8]) = Expand(data[i]);
  35. #ifdef PRINT_DEBUG
  36. printf("s: %zu, r: %d, n: %d -> %d x %d\n", size, ratio, nBits, width, height);
  37. #endif
  38. auto image = ImageView(buffer.data(), width, height, ImageFormat::Lum);
  39. auto res = ReadBarcodes(image, opts);
  40. #ifdef PRINT_DEBUG
  41. for (const auto& r : res)
  42. printf("%s: %s / %s\n", ToString(r.format()).c_str(), r.text().c_str(), ToString(r.error()).c_str());
  43. #endif
  44. static int detectedSybols = 0;
  45. detectedSybols += Size(res);
  46. if (!res.empty() && detectedSybols % 100 == 0)
  47. printf("detected barcode symbols: %d\n", detectedSybols);
  48. return 0;
  49. }