comparison mupdf-source/thirdparty/zxing-cpp/core/src/ImageView.h @ 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 2019 Axel Waggershauser
3 */
4 // SPDX-License-Identifier: Apache-2.0
5
6 #pragma once
7
8 #include <algorithm>
9 #include <cstdint>
10 #include <cstdio>
11 #include <memory>
12 #include <stdexcept>
13
14 namespace ZXing {
15
16 enum class ImageFormat : uint32_t
17 {
18 None = 0,
19 Lum = 0x01000000,
20 LumA = 0x02000000,
21 RGB = 0x03000102,
22 BGR = 0x03020100,
23 RGBA = 0x04000102,
24 ARGB = 0x04010203,
25 BGRA = 0x04020100,
26 ABGR = 0x04030201,
27 RGBX [[deprecated("use RGBA")]] = RGBA,
28 XRGB [[deprecated("use ARGB")]] = ARGB,
29 BGRX [[deprecated("use BGRA")]] = BGRA,
30 XBGR [[deprecated("use ABGR")]] = ABGR,
31 };
32
33 constexpr inline int PixStride(ImageFormat format) { return (static_cast<uint32_t>(format) >> 3*8) & 0xFF; }
34 constexpr inline int RedIndex(ImageFormat format) { return (static_cast<uint32_t>(format) >> 2*8) & 0xFF; }
35 constexpr inline int GreenIndex(ImageFormat format) { return (static_cast<uint32_t>(format) >> 1*8) & 0xFF; }
36 constexpr inline int BlueIndex(ImageFormat format) { return (static_cast<uint32_t>(format) >> 0*8) & 0xFF; }
37
38 constexpr inline uint8_t RGBToLum(unsigned r, unsigned g, unsigned b)
39 {
40 // .299R + 0.587G + 0.114B (YUV/YIQ for PAL and NTSC),
41 // (306*R) >> 10 is approximately equal to R*0.299, and so on.
42 // 0x200 >> 10 is 0.5, it implements rounding.
43 return static_cast<uint8_t>((306 * r + 601 * g + 117 * b + 0x200) >> 10);
44 }
45
46 /**
47 * Simple class that stores a non-owning const pointer to image data plus layout and format information.
48 */
49 class ImageView
50 {
51 protected:
52 const uint8_t* _data = nullptr;
53 ImageFormat _format = ImageFormat::None;
54 int _width = 0, _height = 0, _pixStride = 0, _rowStride = 0;
55
56 public:
57 /** ImageView default constructor creates a 'null' image view
58 */
59 ImageView() = default;
60
61 /**
62 * ImageView constructor
63 *
64 * @param data pointer to image buffer
65 * @param width image width in pixels
66 * @param height image height in pixels
67 * @param format image/pixel format
68 * @param rowStride optional row stride in bytes, default is width * pixStride
69 * @param pixStride optional pixel stride in bytes, default is calculated from format
70 */
71 ImageView(const uint8_t* data, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0)
72 : _data(data),
73 _format(format),
74 _width(width),
75 _height(height),
76 _pixStride(pixStride ? pixStride : PixStride(format)),
77 _rowStride(rowStride ? rowStride : width * _pixStride)
78 {
79 // TODO: [[deprecated]] this check is to prevent exising code from suddenly throwing, remove in 3.0
80 if (_data == nullptr && _width == 0 && _height == 0 && rowStride == 0 && pixStride == 0) {
81 fprintf(stderr, "zxing-cpp deprecation warning: ImageView(nullptr, ...) will throw in the future, use ImageView()\n");
82 return;
83 }
84
85 if (_data == nullptr)
86 throw std::invalid_argument("Can not construct an ImageView from a NULL pointer");
87
88 if (_width <= 0 || _height <= 0)
89 throw std::invalid_argument("Neither width nor height of ImageView can be less or equal to 0");
90 }
91
92 /**
93 * ImageView constructor with bounds checking
94 */
95 ImageView(const uint8_t* data, int size, int width, int height, ImageFormat format, int rowStride = 0, int pixStride = 0)
96 : ImageView(data, width, height, format, rowStride, pixStride)
97 {
98 if (_rowStride < 0 || _pixStride < 0 || size < _height * _rowStride)
99 throw std::invalid_argument("ImageView parameters are inconsistent (out of bounds)");
100 }
101
102 int width() const { return _width; }
103 int height() const { return _height; }
104 int pixStride() const { return _pixStride; }
105 int rowStride() const { return _rowStride; }
106 ImageFormat format() const { return _format; }
107
108 const uint8_t* data() const { return _data; }
109 const uint8_t* data(int x, int y) const { return _data + y * _rowStride + x * _pixStride; }
110
111 ImageView cropped(int left, int top, int width, int height) const
112 {
113 left = std::clamp(left, 0, _width - 1);
114 top = std::clamp(top, 0, _height - 1);
115 width = width <= 0 ? (_width - left) : std::min(_width - left, width);
116 height = height <= 0 ? (_height - top) : std::min(_height - top, height);
117 return {data(left, top), width, height, _format, _rowStride, _pixStride};
118 }
119
120 ImageView rotated(int degree) const
121 {
122 switch ((degree + 360) % 360) {
123 case 90: return {data(0, _height - 1), _height, _width, _format, _pixStride, -_rowStride};
124 case 180: return {data(_width - 1, _height - 1), _width, _height, _format, -_rowStride, -_pixStride};
125 case 270: return {data(_width - 1, 0), _height, _width, _format, -_pixStride, _rowStride};
126 }
127 return *this;
128 }
129
130 ImageView subsampled(int scale) const
131 {
132 return {_data, _width / scale, _height / scale, _format, _rowStride * scale, _pixStride * scale};
133 }
134
135 };
136
137 class Image : public ImageView
138 {
139 std::unique_ptr<uint8_t[]> _memory;
140 Image(std::unique_ptr<uint8_t[]>&& data, int w, int h, ImageFormat f) : ImageView(data.get(), w, h, f), _memory(std::move(data)) {}
141
142 public:
143 Image() = default;
144 Image(int w, int h, ImageFormat f = ImageFormat::Lum) : Image(std::make_unique<uint8_t[]>(w * h * PixStride(f)), w, h, f) {}
145 };
146
147 } // ZXing
148