File: ImageLoader.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 (69 lines) | stat: -rw-r--r-- 1,762 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
64
65
66
67
68
69
/*
* Copyright 2016 Nu-book Inc.
* Copyright 2019 Axel Waggersauser.
*/
// SPDX-License-Identifier: Apache-2.0

#include "ImageLoader.h"

#include "BinaryBitmap.h"
#include "ImageView.h"

#include <array>
#include <map>
#include <memory>
#include <stdexcept>

#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>

namespace ZXing::Test {

class STBImage : public ImageView
{
	std::unique_ptr<stbi_uc[], void (*)(void*)> _memory;

public:
	STBImage() : ImageView(), _memory(nullptr, stbi_image_free) {}

	void load(const fs::path& imgPath)
	{
		int width, height, channels;
		_memory.reset(stbi_load(imgPath.string().c_str(), &width, &height, &channels, 0));
		if (_memory == nullptr)
			throw std::runtime_error("Failed to read image: " + imgPath.string() + " (" + stbi_failure_reason() + ")");

		auto ImageFormatFromChannels = std::array{ImageFormat::None, ImageFormat::Lum, ImageFormat::LumA, ImageFormat::RGB, ImageFormat::RGBA};
		ImageView::operator=({_memory.get(), width, height, ImageFormatFromChannels.at(channels)});

		// preconvert from RGB -> Lum to do this only once instead of for each rotation
		if (_format == ImageFormat::RGB) {
			auto* img = _memory.get();
			for (int i = 0; i < width * height; ++i)
				img[i] = RGBToLum(img[3 * i + 0], img[3 * i + 1], img[3 * i + 2]);
			ImageView::operator=({_memory.get(), width, height, ImageFormat::Lum});
		}
	}

	operator bool() const { return _data; }
};

std::map<fs::path, STBImage> cache;

void ImageLoader::clearCache()
{
	cache.clear();
}

const ImageView& ImageLoader::load(const fs::path& imgPath)
{
	thread_local std::unique_ptr<BinaryBitmap> localAverage, threshold;

	auto& binImg = cache[imgPath];
	if (!binImg)
		binImg.load(imgPath);

	return binImg;
}

} // namespace ZXing::Test