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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
// Copyright (c) 2023 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
// Use of this source is governed by Lesser General Public License that can be found
// in the LICENSE file.
use std::rc::Rc;
use crate::core::alpha_type::AlphaType;
use crate::core::color_space::ColorSpace;
use crate::core::color_type::ColorType;
use crate::core::image_info::ImageInfo;
use crate::core::mipmap::Mipmap;
use crate::core::pixel_ref::PixelRef;
use crate::core::pixmap::Pixmap;
/// Bitmap describes a two-dimensional raster pixel array.
///
/// Bitmap is built on `ImageInfo`, containing integer width and height, `ColorType`
/// and `AlphaType` describing the pixel format, and `ColorSpace` describing
/// the range of colors.
///
/// Bitmap points to `PixelRef`, which describes the physical array of pixels.
/// `ImageInfo` bounds may be located anywhere fully inside `PixelRef` bounds.
///
/// Bitmap can be drawn using Canvas. Bitmap can be a drawing destination for Canvas
/// draw member functions. Bitmap flexibility as a pixel container limits some
/// optimizations available to the target platform.
///
/// If pixel array is primarily read-only, use `Image` for better performance.
/// If pixel array is primarily written to, use `Surface` for better performance.
///
/// Declaring `Bitmap` const prevents altering `ImageInfo`: the Bitmap height, width,
/// and so on cannot change.
/// It does not affect `PixelRef`: a caller may write its pixels.
/// Declaring Bitmap const affects Bitmap configuration, not its contents.
///
/// Bitmap is not thread safe. Each thread must have its own copy of Bitmap fields,
/// although threads may share the underlying pixel array.
pub struct Bitmap {
pixel_ref: Option<PixelRef>,
pixmap: Pixmap,
mips: Mipmap,
}
impl Default for Bitmap {
fn default() -> Self {
Self::new()
}
}
impl Bitmap {
/// Creates an empty Bitmap without pixels, with `ColorType::Unknown`,
/// `AlphaType::Unknown`, and with a width and height of zero.
///
/// `PixelRef` origin is set to (0, 0).
///
/// Use `set_info()` to associate `ColorType`, `AlphaType`, width, and height
/// after Bitmap has been created.
#[must_use]
pub fn new() -> Self {
unimplemented!()
}
/// Swaps the fields of the two bitmaps.
///
/// # Parameters
/// - `other` - Bitmap exchanged with original
pub fn swap(&mut self, _other: &mut Self) {
unimplemented!()
}
/// Returns a constant reference to the Pixmap holding the Bitmap pixel
/// address, row bytes, and `ImageInfo`.
///
/// Returns reference to Pixmap describing this Bitmap.
#[must_use]
pub const fn pixmap(&self) -> &Pixmap {
&self.pixmap
}
/// Returns width, height, `AlphaType`, `ColorType`, and `ColorSpace`.
///
/// Returns reference to `ImageInfo`
#[must_use]
pub const fn info(&self) -> &ImageInfo {
self.pixmap.info()
}
/// Returns pixel count in each row.
///
/// Should be equal or less than `row_bytes() / info().bytes_per_pixel()`.
///
/// May be less than `pixel_ref().width()`.
/// Will not exceed `pixel_ref().width() - pixel_ref_origin().x()`.
///
/// Returns pixel width in `ImageInfo`.
#[must_use]
pub const fn width(&self) -> i32 {
self.pixmap.width()
}
/// Returns pixel row count.
///
/// Maybe be less than `pixel_ref().height()`.
/// Will not exceed `pixel_ref().height() - pixel_ref_origin().y()`.
///
/// Returns pixel height in `ImageInfo`.
#[must_use]
pub const fn height(&self) -> i32 {
self.pixmap.height()
}
#[must_use]
pub const fn color_type(&self) -> ColorType {
self.pixmap.color_type()
}
#[must_use]
pub const fn alpha_type(&self) -> AlphaType {
self.pixmap.alpha_type()
}
/// Returns `ColorSpace`, the range of colors, associated with `ImageInfo`.
///
/// The reference count of `ColorSpace` is unchanged.
/// The returned `ColorSpace` is immutable.
///
/// Returns `ColorSpace` in `ImageInfo`, or None.
pub const fn color_space(&self) -> &Option<ColorSpace> {
unimplemented!()
}
/// Returns smart pointer to `ColorSpace`, the range of colors, associated with
/// `ImageInfo`.
///
/// The smart pointer tracks the number of objects sharing this `ColorSpace`
/// reference so the memory is released when the owners destruct.
///
/// The returned `ColorSpace` is immutable.
pub fn ref_color_space(&self) -> Rc<ColorSpace> {
unimplemented!()
}
/// Returns number of bytes per pixel required by `ColorType`.
///
/// Returns zero if color type is Unknown.
///
/// Returns bytes in pixel
#[must_use]
pub const fn bytes_per_pixel(&self) -> i32 {
self.pixmap.info().bytes_per_pixel()
}
/// Returns number of pixels that fit on row.
///
/// Should be greater than or equal to `width()`.
///
/// Returns maximum pixels per row.
#[must_use]
pub const fn row_bytes_as_pixels(&self) -> i32 {
self.pixmap.row_bytes_as_pixels()
}
/// Returns bit shift converting row bytes to row pixels.
///
/// Returns zero for Unknown.
///
/// Returns one of: 0, 1, 2, 3; left shift to convert pixels to bytes.
#[must_use]
pub const fn shift_per_pixel(&self) -> i32 {
self.pixmap.shift_per_pixel()
}
/// Returns true if either `width()` or `height()` are zero.
///
/// Does not check if `PixelRef` is nullptr; call `draws_nothing()` to check `width()`,
/// `height()`, and `PixelRef`.
///
/// Returns true if dimensions do not enclose area.
#[must_use]
pub const fn is_empty(&self) -> bool {
self.pixmap.info().is_empty()
}
/// Returns true if `PixelRef` is nullptr.
///
/// Does not check if `width()` or `height()` are zero; call `draws_nothing()` to check
/// `width()`, `height()`, and `PixelRef`.
///
/// Returns true if no `PixelRef` is associated
#[must_use]
pub const fn is_null(&self) -> bool {
self.pixel_ref.is_none()
}
/// Returns true if `width()` or `height()` are zero, or if `PixelRef` is nullptr.
///
/// If true, Bitmap has no effect when drawn or drawn into.
///
/// Returns true if drawing has no effect
#[must_use]
pub const fn draws_nothing(&self) -> bool {
self.is_empty() || self.is_null()
}
/// Returns row bytes, the interval from one pixel row to the next.
///
/// Row bytes is at least as large as: `width() * info().bytes_per_pixel()`.
///
/// Returns zero if `color_type()` is Unknown, or if row bytes supplied to
/// `set_info()` is not large enough to hold a row of pixels.
///
/// Returns byte length of pixel row.
#[must_use]
pub const fn row_bytes(&self) -> usize {
self.pixmap.row_bytes()
}
/// Sets `AlphaType`, if `alpha_type` is compatible with `ColorType`.
///
/// Returns true unless `alpha_type` is Unknown and current `AlphaType`
/// is not Unknown.
///
/// Returns true if `ColorType` is Unknown. `alpha_type` is ignored, and
/// `AlphaType` remains Unknown.
///
/// Returns true if `ColorType` is Rgb565 or Gray8.
/// `alpha_type` is ignored, and `AlphaType` remains Opaque.
///
/// If `ColorType` is Argb4444, Rgba8888, Bgra8888, or `RgbaF16`: returns true unless
/// `alpha_type` is Unknown and `AlphaType` is not Unknown.
/// If `AlphaType` is Unknown, `alpha_type` is ignored.
///
/// If `ColorType` is Alpha8, returns true unless `alpha_type` is Unknown and
/// `AlphaType` is not Unknown. If `AlphaType` is Unknown, `alpha_type` is ignored.
/// If `alpha_type` is Unpremul, it is treated as Premul.
///
/// This changes `AlphaType` in `PixelRef`; all bitmaps sharing `PixelRef`
/// are affected.
///
/// Returns true if `AlphaType` is set
pub fn set_alpha_type(&mut self, _alpha_type: AlphaType) -> bool {
unimplemented!()
}
/// Returns pixel address, the base address corresponding to the pixel origin.
///
/// Returns pixel address.
pub fn get_pixels(&self) -> &[u8] {
self.pixmap.pixels()
}
/// Returns minimum memory required for pixel storage.
///
/// - Does not include unused memory on last row when `row_bytes_as_pixels()` exceeds `width()`.
/// - Returns `usize::MAX` if result does not fit in usize.
/// - Returns zero if `height()` or `width()` is 0.
/// - Returns `height() times row_bytes()` if `color_type()` is Unknown.
///
/// Returns size in bytes of image buffer.
#[must_use]
pub const fn compute_byte_size(&self) -> usize {
self.pixmap.compute_byte_size()
}
/// Returns true if pixels can not change.
///
/// Most immutable Bitmap checks trigger an assert only on debug builds.
///
/// Returns true if pixels are immutable.
#[must_use]
pub const fn is_immutable(&self) -> bool {
unimplemented!()
}
/// Sets internal flag to mark Bitmap as immutable.
///
/// Once set, pixels can not change.
/// Any other bitmap sharing the same `PixelRef` are also marked as immutable.
/// Once `PixelRef` is marked immutable, the setting cannot be cleared.
///
/// Writing to immutable Bitmap pixels triggers an assert on debug builds.
pub fn set_immutable(&mut self) {
unimplemented!()
}
/// Returns true if `AlphaType` is set to hint that all pixels are opaque; their
/// alpha value is implicitly or explicitly 1.0.
///
/// If true, and all pixels are not opaque, it may draw incorrectly.
///
/// Does not check if `ColorType` allows alpha, or if any pixel value has
/// transparency.
///
/// @return true if `ImageInfo` `AlphaType` is Opaque.
#[must_use]
pub fn is_opaque(&self) -> bool {
self.alpha_type().is_opaque()
}
/// Resets to its initial state; all fields are set to zero, as if Bitmap had
/// been initialized by `new()`.
///
/// Sets width, height, row bytes to zero; pixel address to nullptr;
/// `ColorType` to Unknown; and `AlphaType` to Unknown.
///
/// If `PixelRef` is allocated, its reference count is decreased by one,
/// releasing its memory if Bitmap is the sole owner.
pub fn reset(&mut self) {
unimplemented!()
}
#[must_use]
pub fn addr8_at(&self, x: i32, y: i32) -> Option<&[u8]> {
self.pixmap.addr8_at(x, y)
}
}