File: fuzzReadMatrix.cpp

package info (click to toggle)
zxing-cpp 2.3.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 26,832 kB
  • sloc: cpp: 32,803; ansic: 18,360; php: 1,156; python: 215; makefile: 25; sh: 3
file content (63 lines) | stat: -rw-r--r-- 1,701 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
 * Copyright 2023 Axel Waggershauser
 */
// SPDX-License-Identifier: Apache-2.0

#include "ReadBarcode.h"

#include <csignal>
#include <cstddef>
#include <cstdint>
#include <cstdlib>

using namespace ZXing;

uint64_t Expand(uint8_t b)
{
    uint64_t shift = 0x0000040810204081ul; // bits set: 0, 7, 14, 21, 28, 35, 42
    uint64_t mask = 0x0001010101010101ul; // bits set: 0, 8, 16, 24, 32, 40, 48
    return ((uint64_t)(b & 127) * shift & mask) | (uint64_t)(b & 128) << 49;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
	if (size < 3)
		return 0;

	static auto opts = ReaderOptions()
						   .setFormats(BarcodeFormat::MatrixCodes)
						   .setBinarizer(Binarizer::BoolCast)
						   .setReturnErrors(true)
						   .setTryInvert(false)
						   .setTryRotate(false);

	int ratio = data[0] + 1;
	int nBits = (size - 1) * 8;
	int width = std::clamp(nBits * ratio / 256, 1, nBits);
	int height = std::clamp(nBits / width, 1, nBits);

	assert(width * height <= nBits);

	ByteArray buffer(nBits);
	for (size_t i = 1; i < size; ++i)
		*reinterpret_cast<uint64_t*>(&buffer[(i - 1) * 8]) = Expand(data[i]);

#ifdef PRINT_DEBUG
	printf("s: %zu, r: %d, n: %d -> %d x %d\n", size, ratio, nBits, width, height);
#endif

	auto image = ImageView(buffer.data(), width, height, ImageFormat::Lum);
	auto res = ReadBarcodes(image, opts);

#ifdef PRINT_DEBUG
	for (const auto& r : res)
		printf("%s: %s / %s\n", ToString(r.format()).c_str(), r.text().c_str(), ToString(r.error()).c_str());
#endif

	static int detectedSybols = 0;
	detectedSybols += Size(res);
	if (!res.empty() && detectedSybols % 100 == 0)
		printf("detected barcode symbols: %d\n", detectedSybols);

	return 0;
}