Coverage Report

Created: 2026-03-07 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/image/src/images/buffer.rs
Line
Count
Source
1
//! Contains the generic `ImageBuffer` struct.
2
use num_traits::Zero;
3
use std::fmt;
4
use std::marker::PhantomData;
5
use std::ops::{Deref, DerefMut, Index, IndexMut, Range};
6
use std::path::Path;
7
use std::slice::{ChunksExact, ChunksExactMut};
8
9
use crate::color::{FromColor, FromPrimitive, Luma, LumaA, Rgb, Rgba};
10
use crate::error::{
11
    ImageResult, ParameterError, ParameterErrorKind, UnsupportedError, UnsupportedErrorKind,
12
};
13
use crate::flat::{FlatSamples, SampleLayout, ViewOfPixel};
14
use crate::math::Rect;
15
use crate::metadata::cicp::{CicpApplicable, CicpPixelCast, CicpRgb, ColorComponentForCicp};
16
use crate::traits::{EncodableLayout, Pixel, PixelWithColorType};
17
use crate::utils::expand_packed;
18
use crate::{
19
    metadata::{Cicp, CicpColorPrimaries, CicpTransferCharacteristics, CicpTransform},
20
    save_buffer, save_buffer_with_format, write_buffer_with_format, ImageError,
21
};
22
use crate::{DynamicImage, GenericImage, GenericImageView, ImageEncoder, ImageFormat};
23
24
/// Iterate over pixel refs.
25
pub struct Pixels<'a, P: Pixel + 'a>
26
where
27
    P::Subpixel: 'a,
28
{
29
    chunks: ChunksExact<'a, P::Subpixel>,
30
}
31
32
impl<'a, P: Pixel + 'a> Iterator for Pixels<'a, P>
33
where
34
    P::Subpixel: 'a,
35
{
36
    type Item = &'a P;
37
38
    #[inline(always)]
39
0
    fn next(&mut self) -> Option<&'a P> {
40
0
        self.chunks.next().map(|v| <P as Pixel>::from_slice(v))
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
41
0
    }
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next
42
43
    #[inline(always)]
44
0
    fn size_hint(&self) -> (usize, Option<usize>) {
45
0
        let len = self.len();
46
0
        (len, Some(len))
47
0
    }
48
}
49
50
impl<'a, P: Pixel + 'a> ExactSizeIterator for Pixels<'a, P>
51
where
52
    P::Subpixel: 'a,
53
{
54
0
    fn len(&self) -> usize {
55
0
        self.chunks.len()
56
0
    }
Unexecuted instantiation: <image::images::buffer::Pixels<_> as core::iter::traits::exact_size::ExactSizeIterator>::len
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgb<u8>> as core::iter::traits::exact_size::ExactSizeIterator>::len
Unexecuted instantiation: <image::images::buffer::Pixels<image::color::Rgba<u8>> as core::iter::traits::exact_size::ExactSizeIterator>::len
57
}
58
59
impl<'a, P: Pixel + 'a> DoubleEndedIterator for Pixels<'a, P>
60
where
61
    P::Subpixel: 'a,
62
{
63
    #[inline(always)]
64
0
    fn next_back(&mut self) -> Option<&'a P> {
65
0
        self.chunks.next_back().map(|v| <P as Pixel>::from_slice(v))
66
0
    }
67
}
68
69
impl<P: Pixel> Clone for Pixels<'_, P> {
70
0
    fn clone(&self) -> Self {
71
0
        Pixels {
72
0
            chunks: self.chunks.clone(),
73
0
        }
74
0
    }
75
}
76
77
impl<P: Pixel> fmt::Debug for Pixels<'_, P>
78
where
79
    P::Subpixel: fmt::Debug,
80
{
81
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82
0
        f.debug_struct("Pixels")
83
0
            .field("chunks", &self.chunks)
84
0
            .finish()
85
0
    }
86
}
87
88
/// Iterate over mutable pixel refs.
89
pub struct PixelsMut<'a, P: Pixel + 'a>
90
where
91
    P::Subpixel: 'a,
92
{
93
    chunks: ChunksExactMut<'a, P::Subpixel>,
94
}
95
96
impl<'a, P: Pixel + 'a> Iterator for PixelsMut<'a, P>
97
where
98
    P::Subpixel: 'a,
99
{
100
    type Item = &'a mut P;
101
102
    #[inline(always)]
103
3.81G
    fn next(&mut self) -> Option<&'a mut P> {
104
3.81G
        self.chunks.next().map(|v| <P as Pixel>::from_slice_mut(v))
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
<image::images::buffer::PixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Line
Count
Source
104
3.81G
        self.chunks.next().map(|v| <P as Pixel>::from_slice_mut(v))
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
105
3.81G
    }
<image::images::buffer::PixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
103
3.81G
    fn next(&mut self) -> Option<&'a mut P> {
104
3.81G
        self.chunks.next().map(|v| <P as Pixel>::from_slice_mut(v))
105
3.81G
    }
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::PixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
106
107
    #[inline(always)]
108
0
    fn size_hint(&self) -> (usize, Option<usize>) {
109
0
        let len = self.len();
110
0
        (len, Some(len))
111
0
    }
112
}
113
114
impl<'a, P: Pixel + 'a> ExactSizeIterator for PixelsMut<'a, P>
115
where
116
    P::Subpixel: 'a,
117
{
118
0
    fn len(&self) -> usize {
119
0
        self.chunks.len()
120
0
    }
121
}
122
123
impl<'a, P: Pixel + 'a> DoubleEndedIterator for PixelsMut<'a, P>
124
where
125
    P::Subpixel: 'a,
126
{
127
    #[inline(always)]
128
0
    fn next_back(&mut self) -> Option<&'a mut P> {
129
0
        self.chunks
130
0
            .next_back()
131
0
            .map(|v| <P as Pixel>::from_slice_mut(v))
132
0
    }
133
}
134
135
impl<P: Pixel> fmt::Debug for PixelsMut<'_, P>
136
where
137
    P::Subpixel: fmt::Debug,
138
{
139
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140
0
        f.debug_struct("PixelsMut")
141
0
            .field("chunks", &self.chunks)
142
0
            .finish()
143
0
    }
144
}
145
146
/// Iterate over rows of an image
147
///
148
/// This iterator is created with [`ImageBuffer::rows`]. See its document for details.
149
///
150
/// [`ImageBuffer::rows`]: ../struct.ImageBuffer.html#method.rows
151
pub struct Rows<'a, P: Pixel + 'a>
152
where
153
    <P as Pixel>::Subpixel: 'a,
154
{
155
    pixels: ChunksExact<'a, P::Subpixel>,
156
}
157
158
impl<'a, P: Pixel + 'a> Rows<'a, P> {
159
    /// Construct the iterator from image pixels. This is not public since it has a (hidden) panic
160
    /// condition. The `pixels` slice must be large enough so that all pixels are addressable.
161
0
    fn with_image(pixels: &'a [P::Subpixel], width: u32, height: u32) -> Self {
162
0
        let row_len = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
163
0
        if row_len == 0 {
164
0
            Rows {
165
0
                pixels: [].chunks_exact(1),
166
0
            }
167
        } else {
168
0
            let pixels = pixels
169
0
                .get(..row_len * height as usize)
170
0
                .expect("Pixel buffer has too few subpixels");
171
            // Rows are physically present. In particular, height is smaller than `usize::MAX` as
172
            // all subpixels can be indexed.
173
0
            Rows {
174
0
                pixels: pixels.chunks_exact(row_len),
175
0
            }
176
        }
177
0
    }
Unexecuted instantiation: <image::images::buffer::Rows<image::color::Rgba<u8>>>::with_image
Unexecuted instantiation: <image::images::buffer::Rows<image::color::Rgba<u16>>>::with_image
Unexecuted instantiation: <image::images::buffer::Rows<image::color::LumaA<u8>>>::with_image
Unexecuted instantiation: <image::images::buffer::Rows<image::color::LumaA<u16>>>::with_image
178
}
179
180
impl<'a, P: Pixel + 'a> Iterator for Rows<'a, P>
181
where
182
    P::Subpixel: 'a,
183
{
184
    type Item = Pixels<'a, P>;
185
186
    #[inline(always)]
187
0
    fn next(&mut self) -> Option<Pixels<'a, P>> {
188
0
        let row = self.pixels.next()?;
189
0
        Some(Pixels {
190
0
            // Note: this is not reached when CHANNEL_COUNT is 0.
191
0
            chunks: row.chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
192
0
        })
193
0
    }
Unexecuted instantiation: <image::images::buffer::Rows<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Rows<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Rows<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::Rows<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next
194
195
    #[inline(always)]
196
0
    fn size_hint(&self) -> (usize, Option<usize>) {
197
0
        let len = self.len();
198
0
        (len, Some(len))
199
0
    }
200
}
201
202
impl<'a, P: Pixel + 'a> ExactSizeIterator for Rows<'a, P>
203
where
204
    P::Subpixel: 'a,
205
{
206
0
    fn len(&self) -> usize {
207
0
        self.pixels.len()
208
0
    }
209
}
210
211
impl<'a, P: Pixel + 'a> DoubleEndedIterator for Rows<'a, P>
212
where
213
    P::Subpixel: 'a,
214
{
215
    #[inline(always)]
216
0
    fn next_back(&mut self) -> Option<Pixels<'a, P>> {
217
0
        let row = self.pixels.next_back()?;
218
0
        Some(Pixels {
219
0
            // Note: this is not reached when CHANNEL_COUNT is 0.
220
0
            chunks: row.chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
221
0
        })
222
0
    }
223
}
224
225
impl<P: Pixel> Clone for Rows<'_, P> {
226
0
    fn clone(&self) -> Self {
227
0
        Rows {
228
0
            pixels: self.pixels.clone(),
229
0
        }
230
0
    }
231
}
232
233
impl<P: Pixel> fmt::Debug for Rows<'_, P>
234
where
235
    P::Subpixel: fmt::Debug,
236
{
237
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
238
0
        f.debug_struct("Rows")
239
0
            .field("pixels", &self.pixels)
240
0
            .finish()
241
0
    }
242
}
243
244
/// Iterate over mutable rows of an image
245
///
246
/// This iterator is created with [`ImageBuffer::rows_mut`]. See its document for details.
247
///
248
/// [`ImageBuffer::rows_mut`]: ../struct.ImageBuffer.html#method.rows_mut
249
pub struct RowsMut<'a, P: Pixel + 'a>
250
where
251
    <P as Pixel>::Subpixel: 'a,
252
{
253
    pixels: ChunksExactMut<'a, P::Subpixel>,
254
}
255
256
impl<'a, P: Pixel + 'a> RowsMut<'a, P> {
257
    /// Construct the iterator from image pixels. This is not public since it has a (hidden) panic
258
    /// condition. The `pixels` slice must be large enough so that all pixels are addressable.
259
0
    fn with_image(pixels: &'a mut [P::Subpixel], width: u32, height: u32) -> Self {
260
0
        let row_len = (width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
261
0
        if row_len == 0 {
262
0
            RowsMut {
263
0
                pixels: [].chunks_exact_mut(1),
264
0
            }
265
        } else {
266
0
            let pixels = pixels
267
0
                .get_mut(..row_len * height as usize)
268
0
                .expect("Pixel buffer has too few subpixels");
269
            // Rows are physically present. In particular, height is smaller than `usize::MAX` as
270
            // all subpixels can be indexed.
271
0
            RowsMut {
272
0
                pixels: pixels.chunks_exact_mut(row_len),
273
0
            }
274
        }
275
0
    }
276
}
277
278
impl<'a, P: Pixel + 'a> Iterator for RowsMut<'a, P>
279
where
280
    P::Subpixel: 'a,
281
{
282
    type Item = PixelsMut<'a, P>;
283
284
    #[inline(always)]
285
0
    fn next(&mut self) -> Option<PixelsMut<'a, P>> {
286
0
        let row = self.pixels.next()?;
287
0
        Some(PixelsMut {
288
0
            // Note: this is not reached when CHANNEL_COUNT is 0.
289
0
            chunks: row.chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
290
0
        })
291
0
    }
292
293
    #[inline(always)]
294
0
    fn size_hint(&self) -> (usize, Option<usize>) {
295
0
        let len = self.len();
296
0
        (len, Some(len))
297
0
    }
298
}
299
300
impl<'a, P: Pixel + 'a> ExactSizeIterator for RowsMut<'a, P>
301
where
302
    P::Subpixel: 'a,
303
{
304
0
    fn len(&self) -> usize {
305
0
        self.pixels.len()
306
0
    }
307
}
308
309
impl<'a, P: Pixel + 'a> DoubleEndedIterator for RowsMut<'a, P>
310
where
311
    P::Subpixel: 'a,
312
{
313
    #[inline(always)]
314
0
    fn next_back(&mut self) -> Option<PixelsMut<'a, P>> {
315
0
        let row = self.pixels.next_back()?;
316
0
        Some(PixelsMut {
317
0
            // Note: this is not reached when CHANNEL_COUNT is 0.
318
0
            chunks: row.chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
319
0
        })
320
0
    }
321
}
322
323
impl<P: Pixel> fmt::Debug for RowsMut<'_, P>
324
where
325
    P::Subpixel: fmt::Debug,
326
{
327
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
328
0
        f.debug_struct("RowsMut")
329
0
            .field("pixels", &self.pixels)
330
0
            .finish()
331
0
    }
332
}
333
334
/// Enumerate the pixels of an image.
335
pub struct EnumeratePixels<'a, P: Pixel + 'a>
336
where
337
    <P as Pixel>::Subpixel: 'a,
338
{
339
    pixels: Pixels<'a, P>,
340
    x: u32,
341
    y: u32,
342
    width: u32,
343
}
344
345
impl<'a, P: Pixel + 'a> Iterator for EnumeratePixels<'a, P>
346
where
347
    P::Subpixel: 'a,
348
{
349
    type Item = (u32, u32, &'a P);
350
351
    #[inline(always)]
352
0
    fn next(&mut self) -> Option<(u32, u32, &'a P)> {
353
0
        if self.x >= self.width {
354
0
            self.x = 0;
355
0
            self.y += 1;
356
0
        }
357
0
        let (x, y) = (self.x, self.y);
358
0
        self.x += 1;
359
0
        self.pixels.next().map(|p| (x, y, p))
360
0
    }
361
362
    #[inline(always)]
363
0
    fn size_hint(&self) -> (usize, Option<usize>) {
364
0
        let len = self.len();
365
0
        (len, Some(len))
366
0
    }
367
}
368
369
impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumeratePixels<'a, P>
370
where
371
    P::Subpixel: 'a,
372
{
373
0
    fn len(&self) -> usize {
374
0
        self.pixels.len()
375
0
    }
376
}
377
378
impl<P: Pixel> Clone for EnumeratePixels<'_, P> {
379
0
    fn clone(&self) -> Self {
380
0
        EnumeratePixels {
381
0
            pixels: self.pixels.clone(),
382
0
            ..*self
383
0
        }
384
0
    }
385
}
386
387
impl<P: Pixel> fmt::Debug for EnumeratePixels<'_, P>
388
where
389
    P::Subpixel: fmt::Debug,
390
{
391
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
392
0
        f.debug_struct("EnumeratePixels")
393
0
            .field("pixels", &self.pixels)
394
0
            .field("x", &self.x)
395
0
            .field("y", &self.y)
396
0
            .field("width", &self.width)
397
0
            .finish()
398
0
    }
399
}
400
401
/// Enumerate the rows of an image.
402
pub struct EnumerateRows<'a, P: Pixel + 'a>
403
where
404
    <P as Pixel>::Subpixel: 'a,
405
{
406
    rows: Rows<'a, P>,
407
    y: u32,
408
    width: u32,
409
}
410
411
impl<'a, P: Pixel + 'a> Iterator for EnumerateRows<'a, P>
412
where
413
    P::Subpixel: 'a,
414
{
415
    type Item = (u32, EnumeratePixels<'a, P>);
416
417
    #[inline(always)]
418
0
    fn next(&mut self) -> Option<(u32, EnumeratePixels<'a, P>)> {
419
0
        let y = self.y;
420
0
        self.y += 1;
421
0
        self.rows.next().map(|r| {
422
0
            (
423
0
                y,
424
0
                EnumeratePixels {
425
0
                    x: 0,
426
0
                    y,
427
0
                    width: self.width,
428
0
                    pixels: r,
429
0
                },
430
0
            )
431
0
        })
432
0
    }
433
434
    #[inline(always)]
435
0
    fn size_hint(&self) -> (usize, Option<usize>) {
436
0
        let len = self.len();
437
0
        (len, Some(len))
438
0
    }
439
}
440
441
impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumerateRows<'a, P>
442
where
443
    P::Subpixel: 'a,
444
{
445
0
    fn len(&self) -> usize {
446
0
        self.rows.len()
447
0
    }
448
}
449
450
impl<P: Pixel> Clone for EnumerateRows<'_, P> {
451
0
    fn clone(&self) -> Self {
452
0
        EnumerateRows {
453
0
            rows: self.rows.clone(),
454
0
            ..*self
455
0
        }
456
0
    }
457
}
458
459
impl<P: Pixel> fmt::Debug for EnumerateRows<'_, P>
460
where
461
    P::Subpixel: fmt::Debug,
462
{
463
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464
0
        f.debug_struct("EnumerateRows")
465
0
            .field("rows", &self.rows)
466
0
            .field("y", &self.y)
467
0
            .field("width", &self.width)
468
0
            .finish()
469
0
    }
470
}
471
472
/// Enumerate the pixels of an image.
473
pub struct EnumeratePixelsMut<'a, P: Pixel + 'a>
474
where
475
    <P as Pixel>::Subpixel: 'a,
476
{
477
    pixels: PixelsMut<'a, P>,
478
    x: u32,
479
    y: u32,
480
    width: u32,
481
}
482
483
impl<'a, P: Pixel + 'a> Iterator for EnumeratePixelsMut<'a, P>
484
where
485
    P::Subpixel: 'a,
486
{
487
    type Item = (u32, u32, &'a mut P);
488
489
    #[inline(always)]
490
3.81G
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
491
3.81G
        if self.x >= self.width {
492
1.15M
            self.x = 0;
493
1.15M
            self.y += 1;
494
3.81G
        }
495
3.81G
        let (x, y) = (self.x, self.y);
496
3.81G
        self.x += 1;
497
3.81G
        self.pixels.next().map(|p| (x, y, p))
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
<image::images::buffer::EnumeratePixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Line
Count
Source
497
3.81G
        self.pixels.next().map(|p| (x, y, p))
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next::{closure#0}
498
3.81G
    }
<image::images::buffer::EnumeratePixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
490
3.81G
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
491
3.81G
        if self.x >= self.width {
492
1.15M
            self.x = 0;
493
1.15M
            self.y += 1;
494
3.81G
        }
495
3.81G
        let (x, y) = (self.x, self.y);
496
3.81G
        self.x += 1;
497
3.81G
        self.pixels.next().map(|p| (x, y, p))
498
3.81G
    }
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgb<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Luma<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Luma<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgba<f32>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::Rgba<u16>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::LumaA<u8>> as core::iter::traits::iterator::Iterator>::next
Unexecuted instantiation: <image::images::buffer::EnumeratePixelsMut<image::color::LumaA<u16>> as core::iter::traits::iterator::Iterator>::next
499
500
    #[inline(always)]
501
0
    fn size_hint(&self) -> (usize, Option<usize>) {
502
0
        let len = self.len();
503
0
        (len, Some(len))
504
0
    }
505
}
506
507
impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumeratePixelsMut<'a, P>
508
where
509
    P::Subpixel: 'a,
510
{
511
0
    fn len(&self) -> usize {
512
0
        self.pixels.len()
513
0
    }
514
}
515
516
impl<P: Pixel> fmt::Debug for EnumeratePixelsMut<'_, P>
517
where
518
    P::Subpixel: fmt::Debug,
519
{
520
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
521
0
        f.debug_struct("EnumeratePixelsMut")
522
0
            .field("pixels", &self.pixels)
523
0
            .field("x", &self.x)
524
0
            .field("y", &self.y)
525
0
            .field("width", &self.width)
526
0
            .finish()
527
0
    }
528
}
529
530
/// Enumerate the rows of an image.
531
pub struct EnumerateRowsMut<'a, P: Pixel + 'a>
532
where
533
    <P as Pixel>::Subpixel: 'a,
534
{
535
    rows: RowsMut<'a, P>,
536
    y: u32,
537
    width: u32,
538
}
539
540
impl<'a, P: Pixel + 'a> Iterator for EnumerateRowsMut<'a, P>
541
where
542
    P::Subpixel: 'a,
543
{
544
    type Item = (u32, EnumeratePixelsMut<'a, P>);
545
546
    #[inline(always)]
547
0
    fn next(&mut self) -> Option<(u32, EnumeratePixelsMut<'a, P>)> {
548
0
        let y = self.y;
549
0
        self.y += 1;
550
0
        self.rows.next().map(|r| {
551
0
            (
552
0
                y,
553
0
                EnumeratePixelsMut {
554
0
                    x: 0,
555
0
                    y,
556
0
                    width: self.width,
557
0
                    pixels: r,
558
0
                },
559
0
            )
560
0
        })
561
0
    }
562
563
    #[inline(always)]
564
0
    fn size_hint(&self) -> (usize, Option<usize>) {
565
0
        let len = self.len();
566
0
        (len, Some(len))
567
0
    }
568
}
569
570
impl<'a, P: Pixel + 'a> ExactSizeIterator for EnumerateRowsMut<'a, P>
571
where
572
    P::Subpixel: 'a,
573
{
574
0
    fn len(&self) -> usize {
575
0
        self.rows.len()
576
0
    }
577
}
578
579
impl<P: Pixel> fmt::Debug for EnumerateRowsMut<'_, P>
580
where
581
    P::Subpixel: fmt::Debug,
582
{
583
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
584
0
        f.debug_struct("EnumerateRowsMut")
585
0
            .field("rows", &self.rows)
586
0
            .field("y", &self.y)
587
0
            .field("width", &self.width)
588
0
            .finish()
589
0
    }
590
}
591
592
/// Generic image buffer
593
///
594
/// This is an image parameterised by its Pixel types, represented by a width and height and a
595
/// container of channel data. It provides direct access to its pixels and implements the
596
/// [`GenericImageView`] and [`GenericImage`] traits. In many ways, this is the standard buffer
597
/// implementing those traits. Using this concrete type instead of a generic type parameter has
598
/// been shown to improve performance.
599
///
600
/// The crate defines a few type aliases with regularly used pixel types for your convenience, such
601
/// as [`RgbImage`], [`GrayImage`] etc.
602
///
603
/// [`GenericImage`]: trait.GenericImage.html
604
/// [`GenericImageView`]: trait.GenericImageView.html
605
/// [`RgbImage`]: type.RgbImage.html
606
/// [`GrayImage`]: type.GrayImage.html
607
///
608
/// To convert between images of different Pixel types use [`DynamicImage`].
609
///
610
/// You can retrieve a complete description of the buffer's layout and contents through
611
/// [`as_flat_samples`] and [`as_flat_samples_mut`]. This can be handy to also use the contents in
612
/// a foreign language, map it as a GPU host buffer or other similar tasks.
613
///
614
/// [`DynamicImage`]: enum.DynamicImage.html
615
/// [`as_flat_samples`]: #method.as_flat_samples
616
/// [`as_flat_samples_mut`]: #method.as_flat_samples_mut
617
///
618
/// ## Examples
619
///
620
/// Create a simple canvas and paint a small cross.
621
///
622
/// ```
623
/// use image::{RgbImage, Rgb};
624
///
625
/// let mut img = RgbImage::new(32, 32);
626
///
627
/// for x in 15..=17 {
628
///     for y in 8..24 {
629
///         img.put_pixel(x, y, Rgb([255, 0, 0]));
630
///         img.put_pixel(y, x, Rgb([255, 0, 0]));
631
///     }
632
/// }
633
/// ```
634
///
635
/// Overlays an image on top of a larger background raster.
636
///
637
/// ```no_run
638
/// use image::{GenericImage, GenericImageView, ImageBuffer, open};
639
///
640
/// let on_top = open("path/to/some.png").unwrap().into_rgb8();
641
/// let mut img = ImageBuffer::from_fn(512, 512, |x, y| {
642
///     if (x + y) % 2 == 0 {
643
///         image::Rgb([0, 0, 0])
644
///     } else {
645
///         image::Rgb([255, 255, 255])
646
///     }
647
/// });
648
///
649
/// image::imageops::overlay(&mut img, &on_top, 128, 128);
650
/// ```
651
///
652
/// Convert an `RgbaImage` to a `GrayImage`.
653
///
654
/// ```no_run
655
/// use image::{open, DynamicImage};
656
///
657
/// let rgba = open("path/to/some.png").unwrap().into_rgba8();
658
/// let gray = DynamicImage::ImageRgba8(rgba).into_luma8();
659
/// ```
660
#[derive(Hash, PartialEq, Eq)]
661
pub struct ImageBuffer<P: Pixel, Container> {
662
    width: u32,
663
    height: u32,
664
    _phantom: PhantomData<P>,
665
    color: CicpRgb,
666
    data: Container,
667
}
668
669
// generic implementation, shared along all image buffers
670
impl<P, Container> ImageBuffer<P, Container>
671
where
672
    P: Pixel,
673
    Container: Deref<Target = [P::Subpixel]>,
674
{
675
    /// Constructs a buffer from a generic container
676
    /// (for example a `Vec` or a slice)
677
    ///
678
    /// Returns `None` if the container is not big enough (including when the image dimensions
679
    /// necessitate an allocation of more bytes than supported by the container).
680
16.4k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
16.4k
        if Self::check_image_fits(width, height, buf.len()) {
682
16.4k
            Some(ImageBuffer {
683
16.4k
                data: buf,
684
16.4k
                width,
685
16.4k
                height,
686
16.4k
                color: Cicp::SRGB.into_rgb(),
687
16.4k
                _phantom: PhantomData,
688
16.4k
            })
689
        } else {
690
0
            None
691
        }
692
16.4k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::from_raw
Line
Count
Source
680
266
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
266
        if Self::check_image_fits(width, height, buf.len()) {
682
266
            Some(ImageBuffer {
683
266
                data: buf,
684
266
                width,
685
266
                height,
686
266
                color: Cicp::SRGB.into_rgb(),
687
266
                _phantom: PhantomData,
688
266
            })
689
        } else {
690
0
            None
691
        }
692
266
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
3.55k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
3.55k
        if Self::check_image_fits(width, height, buf.len()) {
682
3.55k
            Some(ImageBuffer {
683
3.55k
                data: buf,
684
3.55k
                width,
685
3.55k
                height,
686
3.55k
                color: Cicp::SRGB.into_rgb(),
687
3.55k
                _phantom: PhantomData,
688
3.55k
            })
689
        } else {
690
0
            None
691
        }
692
3.55k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
114
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
114
        if Self::check_image_fits(width, height, buf.len()) {
682
114
            Some(ImageBuffer {
683
114
                data: buf,
684
114
                width,
685
114
                height,
686
114
                color: Cicp::SRGB.into_rgb(),
687
114
                _phantom: PhantomData,
688
114
            })
689
        } else {
690
0
            None
691
        }
692
114
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::from_raw
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
7.46k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
7.46k
        if Self::check_image_fits(width, height, buf.len()) {
682
7.46k
            Some(ImageBuffer {
683
7.46k
                data: buf,
684
7.46k
                width,
685
7.46k
                height,
686
7.46k
                color: Cicp::SRGB.into_rgb(),
687
7.46k
                _phantom: PhantomData,
688
7.46k
            })
689
        } else {
690
0
            None
691
        }
692
7.46k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
207
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
207
        if Self::check_image_fits(width, height, buf.len()) {
682
207
            Some(ImageBuffer {
683
207
                data: buf,
684
207
                width,
685
207
                height,
686
207
                color: Cicp::SRGB.into_rgb(),
687
207
                _phantom: PhantomData,
688
207
            })
689
        } else {
690
0
            None
691
        }
692
207
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::from_raw
Line
Count
Source
680
11
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
11
        if Self::check_image_fits(width, height, buf.len()) {
682
11
            Some(ImageBuffer {
683
11
                data: buf,
684
11
                width,
685
11
                height,
686
11
                color: Cicp::SRGB.into_rgb(),
687
11
                _phantom: PhantomData,
688
11
            })
689
        } else {
690
0
            None
691
        }
692
11
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
4.59k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
4.59k
        if Self::check_image_fits(width, height, buf.len()) {
682
4.59k
            Some(ImageBuffer {
683
4.59k
                data: buf,
684
4.59k
                width,
685
4.59k
                height,
686
4.59k
                color: Cicp::SRGB.into_rgb(),
687
4.59k
                _phantom: PhantomData,
688
4.59k
            })
689
        } else {
690
0
            None
691
        }
692
4.59k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::from_raw
Line
Count
Source
680
132
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
132
        if Self::check_image_fits(width, height, buf.len()) {
682
132
            Some(ImageBuffer {
683
132
                data: buf,
684
132
                width,
685
132
                height,
686
132
                color: Cicp::SRGB.into_rgb(),
687
132
                _phantom: PhantomData,
688
132
            })
689
        } else {
690
0
            None
691
        }
692
132
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
35
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
35
        if Self::check_image_fits(width, height, buf.len()) {
682
35
            Some(ImageBuffer {
683
35
                data: buf,
684
35
                width,
685
35
                height,
686
35
                color: Cicp::SRGB.into_rgb(),
687
35
                _phantom: PhantomData,
688
35
            })
689
        } else {
690
0
            None
691
        }
692
35
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::from_raw
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
41
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
41
        if Self::check_image_fits(width, height, buf.len()) {
682
41
            Some(ImageBuffer {
683
41
                data: buf,
684
41
                width,
685
41
                height,
686
41
                color: Cicp::SRGB.into_rgb(),
687
41
                _phantom: PhantomData,
688
41
            })
689
        } else {
690
0
            None
691
        }
692
41
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
34
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
34
        if Self::check_image_fits(width, height, buf.len()) {
682
34
            Some(ImageBuffer {
683
34
                data: buf,
684
34
                width,
685
34
                height,
686
34
                color: Cicp::SRGB.into_rgb(),
687
34
                _phantom: PhantomData,
688
34
            })
689
        } else {
690
0
            None
691
        }
692
34
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::from_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::from_raw
693
694
    /// Returns the underlying raw buffer
695
3.71k
    pub fn into_raw(self) -> Container {
696
3.71k
        self.data
697
3.71k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::into_raw
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::into_raw
Line
Count
Source
695
3.71k
    pub fn into_raw(self) -> Container {
696
3.71k
        self.data
697
3.71k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::into_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::into_raw
698
699
    /// Returns the underlying raw buffer
700
0
    pub fn as_raw(&self) -> &Container {
701
0
        &self.data
702
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::as_raw
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::as_raw
703
704
    /// The width and height of this image.
705
0
    pub fn dimensions(&self) -> (u32, u32) {
706
0
        (self.width, self.height)
707
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::dimensions
708
709
    /// The width of this image.
710
1.85k
    pub fn width(&self) -> u32 {
711
1.85k
        self.width
712
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::width
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::width
Line
Count
Source
710
1.85k
    pub fn width(&self) -> u32 {
711
1.85k
        self.width
712
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::width
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::width
713
714
    /// The height of this image.
715
1.85k
    pub fn height(&self) -> u32 {
716
1.85k
        self.height
717
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::height
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::height
Line
Count
Source
715
1.85k
    pub fn height(&self) -> u32 {
716
1.85k
        self.height
717
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::height
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::height
718
719
    // TODO: choose name under which to expose.
720
1.85k
    pub(crate) fn inner_pixels(&self) -> &[P::Subpixel] {
721
1.85k
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
722
1.85k
        &self.data[..len]
723
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::inner_pixels
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::inner_pixels
Line
Count
Source
720
1.85k
    pub(crate) fn inner_pixels(&self) -> &[P::Subpixel] {
721
1.85k
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
722
1.85k
        &self.data[..len]
723
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::inner_pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::inner_pixels
724
725
    /// Returns an iterator over the pixels of this image.
726
    /// The iteration order is x = 0 to width then y = 0 to height
727
0
    pub fn pixels(&self) -> Pixels<'_, P> {
728
0
        Pixels {
729
0
            chunks: self
730
0
                .inner_pixels()
731
0
                .chunks_exact(<P as Pixel>::CHANNEL_COUNT as usize),
732
0
        }
733
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::pixels
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::pixels
734
735
    /// Returns an iterator over the rows of this image.
736
    ///
737
    /// Only non-empty rows can be iterated in this manner. In particular the iterator will not
738
    /// yield any item when the width of the image is `0` or a pixel type without any channels is
739
    /// used. This ensures that its length can always be represented by `usize`.
740
0
    pub fn rows(&self) -> Rows<'_, P> {
741
0
        Rows::with_image(&self.data, self.width, self.height)
742
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::rows
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::rows
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::rows
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::rows
743
744
    /// Enumerates over the pixels of the image.
745
    /// The iterator yields the coordinates of each pixel
746
    /// along with a reference to them.
747
    /// The iteration order is x = 0 to width then y = 0 to height
748
    /// Starting from the top left.
749
0
    pub fn enumerate_pixels(&self) -> EnumeratePixels<'_, P> {
750
0
        EnumeratePixels {
751
0
            pixels: self.pixels(),
752
0
            x: 0,
753
0
            y: 0,
754
0
            width: self.width,
755
0
        }
756
0
    }
757
758
    /// Enumerates over the rows of the image.
759
    /// The iterator yields the y-coordinate of each row
760
    /// along with a reference to them.
761
0
    pub fn enumerate_rows(&self) -> EnumerateRows<'_, P> {
762
0
        EnumerateRows {
763
0
            rows: self.rows(),
764
0
            y: 0,
765
0
            width: self.width,
766
0
        }
767
0
    }
768
769
    /// Gets a reference to the pixel at location `(x, y)`
770
    ///
771
    /// # Panics
772
    ///
773
    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
774
    #[inline]
775
    #[track_caller]
776
11.8M
    pub fn get_pixel(&self, x: u32, y: u32) -> &P {
777
11.8M
        match self.pixel_indices(x, y) {
778
0
            None => panic!(
779
0
                "Image index {:?} out of bounds {:?}",
780
0
                (x, y),
781
0
                (self.width, self.height)
782
            ),
783
11.8M
            Some(pixel_indices) => <P as Pixel>::from_slice(&self.data[pixel_indices]),
784
        }
785
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::get_pixel
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::get_pixel
Line
Count
Source
776
11.8M
    pub fn get_pixel(&self, x: u32, y: u32) -> &P {
777
11.8M
        match self.pixel_indices(x, y) {
778
0
            None => panic!(
779
0
                "Image index {:?} out of bounds {:?}",
780
0
                (x, y),
781
0
                (self.width, self.height)
782
            ),
783
11.8M
            Some(pixel_indices) => <P as Pixel>::from_slice(&self.data[pixel_indices]),
784
        }
785
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::get_pixel
786
787
    /// Gets a reference to the pixel at location `(x, y)` or returns `None` if
788
    /// the index is out of the bounds `(width, height)`.
789
0
    pub fn get_pixel_checked(&self, x: u32, y: u32) -> Option<&P> {
790
0
        if x >= self.width {
791
0
            return None;
792
0
        }
793
0
        let num_channels = <P as Pixel>::CHANNEL_COUNT as usize;
794
0
        let i = (y as usize)
795
0
            .saturating_mul(self.width as usize)
796
0
            .saturating_add(x as usize)
797
0
            .saturating_mul(num_channels);
798
799
0
        self.data
800
0
            .get(i..i.checked_add(num_channels)?)
801
0
            .map(|pixel_indices| <P as Pixel>::from_slice(pixel_indices))
802
0
    }
803
804
    /// Test that the image fits inside the buffer.
805
    ///
806
    /// Verifies that the maximum image of pixels inside the bounds is smaller than the provided
807
    /// length. Note that as a corrolary we also have that the index calculation of pixels inside
808
    /// the bounds will not overflow.
809
16.4k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
16.4k
        let checked_len = Self::image_buffer_len(width, height);
811
16.4k
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::check_image_fits::{closure#0}
Line
Count
Source
811
266
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::check_image_fits::{closure#0}
Line
Count
Source
811
3.55k
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::check_image_fits::{closure#0}
Line
Count
Source
811
114
        checked_len.is_some_and(|min_len| min_len <= len)
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::check_image_fits::{closure#0}
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::check_image_fits::{closure#0}
Line
Count
Source
811
7.46k
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::check_image_fits::{closure#0}
Line
Count
Source
811
207
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::check_image_fits::{closure#0}
Line
Count
Source
811
11
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::check_image_fits::{closure#0}
Line
Count
Source
811
4.59k
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::check_image_fits::{closure#0}
Line
Count
Source
811
132
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::check_image_fits::{closure#0}
Line
Count
Source
811
35
        checked_len.is_some_and(|min_len| min_len <= len)
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::check_image_fits::{closure#0}
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::check_image_fits::{closure#0}
Line
Count
Source
811
41
        checked_len.is_some_and(|min_len| min_len <= len)
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::check_image_fits::{closure#0}
Line
Count
Source
811
34
        checked_len.is_some_and(|min_len| min_len <= len)
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::check_image_fits::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::check_image_fits::{closure#0}
812
16.4k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::check_image_fits
Line
Count
Source
809
266
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
266
        let checked_len = Self::image_buffer_len(width, height);
811
266
        checked_len.is_some_and(|min_len| min_len <= len)
812
266
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
3.55k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
3.55k
        let checked_len = Self::image_buffer_len(width, height);
811
3.55k
        checked_len.is_some_and(|min_len| min_len <= len)
812
3.55k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
114
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
114
        let checked_len = Self::image_buffer_len(width, height);
811
114
        checked_len.is_some_and(|min_len| min_len <= len)
812
114
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::check_image_fits
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
7.46k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
7.46k
        let checked_len = Self::image_buffer_len(width, height);
811
7.46k
        checked_len.is_some_and(|min_len| min_len <= len)
812
7.46k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
207
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
207
        let checked_len = Self::image_buffer_len(width, height);
811
207
        checked_len.is_some_and(|min_len| min_len <= len)
812
207
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::check_image_fits
Line
Count
Source
809
11
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
11
        let checked_len = Self::image_buffer_len(width, height);
811
11
        checked_len.is_some_and(|min_len| min_len <= len)
812
11
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
4.59k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
4.59k
        let checked_len = Self::image_buffer_len(width, height);
811
4.59k
        checked_len.is_some_and(|min_len| min_len <= len)
812
4.59k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::check_image_fits
Line
Count
Source
809
132
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
132
        let checked_len = Self::image_buffer_len(width, height);
811
132
        checked_len.is_some_and(|min_len| min_len <= len)
812
132
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
35
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
35
        let checked_len = Self::image_buffer_len(width, height);
811
35
        checked_len.is_some_and(|min_len| min_len <= len)
812
35
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::check_image_fits
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
41
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
41
        let checked_len = Self::image_buffer_len(width, height);
811
41
        checked_len.is_some_and(|min_len| min_len <= len)
812
41
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
34
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
34
        let checked_len = Self::image_buffer_len(width, height);
811
34
        checked_len.is_some_and(|min_len| min_len <= len)
812
34
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::check_image_fits
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::check_image_fits
813
814
18.4k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
18.4k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
18.4k
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
266
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
3.55k
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
114
            .and_then(|size| size.checked_mul(width as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#0}
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
7.46k
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
207
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
11
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
6.44k
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::image_buffer_len::{closure#0}
Line
Count
Source
816
264
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
35
            .and_then(|size| size.checked_mul(width as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#0}
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
41
            .and_then(|size| size.checked_mul(width as usize))
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
34
            .and_then(|size| size.checked_mul(width as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::image_buffer_len::{closure#0}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::image_buffer_len::{closure#0}
817
18.4k
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
266
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
3.55k
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
114
            .and_then(|size| size.checked_mul(height as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#1}
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
7.46k
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
207
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
11
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
6.44k
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::image_buffer_len::{closure#1}
Line
Count
Source
817
264
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
35
            .and_then(|size| size.checked_mul(height as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#1}
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
41
            .and_then(|size| size.checked_mul(height as usize))
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
34
            .and_then(|size| size.checked_mul(height as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::image_buffer_len::{closure#1}
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::image_buffer_len::{closure#1}
818
18.4k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
Line
Count
Source
814
266
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
266
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
266
            .and_then(|size| size.checked_mul(width as usize))
817
266
            .and_then(|size| size.checked_mul(height as usize))
818
266
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
3.55k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
3.55k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
3.55k
            .and_then(|size| size.checked_mul(width as usize))
817
3.55k
            .and_then(|size| size.checked_mul(height as usize))
818
3.55k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
114
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
114
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
114
            .and_then(|size| size.checked_mul(width as usize))
817
114
            .and_then(|size| size.checked_mul(height as usize))
818
114
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
7.46k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
7.46k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
7.46k
            .and_then(|size| size.checked_mul(width as usize))
817
7.46k
            .and_then(|size| size.checked_mul(height as usize))
818
7.46k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
207
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
207
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
207
            .and_then(|size| size.checked_mul(width as usize))
817
207
            .and_then(|size| size.checked_mul(height as usize))
818
207
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
Line
Count
Source
814
11
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
11
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
11
            .and_then(|size| size.checked_mul(width as usize))
817
11
            .and_then(|size| size.checked_mul(height as usize))
818
11
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
6.44k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
6.44k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
6.44k
            .and_then(|size| size.checked_mul(width as usize))
817
6.44k
            .and_then(|size| size.checked_mul(height as usize))
818
6.44k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::image_buffer_len
Line
Count
Source
814
264
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
264
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
264
            .and_then(|size| size.checked_mul(width as usize))
817
264
            .and_then(|size| size.checked_mul(height as usize))
818
264
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
35
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
35
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
35
            .and_then(|size| size.checked_mul(width as usize))
817
35
            .and_then(|size| size.checked_mul(height as usize))
818
35
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
41
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
41
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
41
            .and_then(|size| size.checked_mul(width as usize))
817
41
            .and_then(|size| size.checked_mul(height as usize))
818
41
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
34
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
34
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
34
            .and_then(|size| size.checked_mul(width as usize))
817
34
            .and_then(|size| size.checked_mul(height as usize))
818
34
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, &[u8]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &[u8]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]>>::image_buffer_len
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]>>::image_buffer_len
819
820
    #[inline(always)]
821
11.8M
    fn pixel_indices(&self, x: u32, y: u32) -> Option<Range<usize>> {
822
11.8M
        if x >= self.width || y >= self.height {
823
0
            return None;
824
11.8M
        }
825
826
11.8M
        Some(self.pixel_indices_unchecked(x, y))
827
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::pixel_indices
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::pixel_indices
Line
Count
Source
821
11.8M
    fn pixel_indices(&self, x: u32, y: u32) -> Option<Range<usize>> {
822
11.8M
        if x >= self.width || y >= self.height {
823
0
            return None;
824
11.8M
        }
825
826
11.8M
        Some(self.pixel_indices_unchecked(x, y))
827
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::pixel_indices
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::pixel_indices
828
829
    #[inline(always)]
830
11.8M
    fn pixel_indices_unchecked(&self, x: u32, y: u32) -> Range<usize> {
831
11.8M
        let no_channels = <P as Pixel>::CHANNEL_COUNT as usize;
832
        // If in bounds, this can't overflow as we have tested that at construction!
833
11.8M
        let min_index = (y as usize * self.width as usize + x as usize) * no_channels;
834
11.8M
        min_index..min_index + no_channels
835
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::pixel_indices_unchecked
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::pixel_indices_unchecked
Line
Count
Source
830
11.8M
    fn pixel_indices_unchecked(&self, x: u32, y: u32) -> Range<usize> {
831
11.8M
        let no_channels = <P as Pixel>::CHANNEL_COUNT as usize;
832
        // If in bounds, this can't overflow as we have tested that at construction!
833
11.8M
        let min_index = (y as usize * self.width as usize + x as usize) * no_channels;
834
11.8M
        min_index..min_index + no_channels
835
11.8M
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::pixel_indices_unchecked
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::pixel_indices_unchecked
836
837
    /// Get the format of the buffer when viewed as a matrix of samples.
838
0
    pub fn sample_layout(&self) -> SampleLayout {
839
        // None of these can overflow, as all our memory is addressable.
840
0
        SampleLayout::row_major_packed(<P as Pixel>::CHANNEL_COUNT, self.width, self.height)
841
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::sample_layout
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::sample_layout
842
843
    /// Return the raw sample buffer with its stride an dimension information.
844
    ///
845
    /// The returned buffer is guaranteed to be well formed in all cases. It is laid out by
846
    /// colors, width then height, meaning `channel_stride <= width_stride <= height_stride`. All
847
    /// strides are in numbers of elements but those are mostly `u8` in which case the strides are
848
    /// also byte strides.
849
0
    pub fn into_flat_samples(self) -> FlatSamples<Container>
850
0
    where
851
0
        Container: AsRef<[P::Subpixel]>,
852
    {
853
        // None of these can overflow, as all our memory is addressable.
854
0
        let layout = self.sample_layout();
855
0
        FlatSamples {
856
0
            samples: self.data,
857
0
            layout,
858
0
            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
859
0
        }
860
0
    }
861
862
    /// Return a view on the raw sample buffer.
863
    ///
864
    /// See [`into_flat_samples`](#method.into_flat_samples) for more details.
865
0
    pub fn as_flat_samples(&self) -> FlatSamples<&[P::Subpixel]> {
866
0
        let layout = self.sample_layout();
867
0
        FlatSamples {
868
0
            samples: self.data.as_ref(),
869
0
            layout,
870
0
            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
871
0
        }
872
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::as_flat_samples
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::as_flat_samples
873
874
    /// Return a mutable view on the raw sample buffer.
875
    ///
876
    /// See [`into_flat_samples`](#method.into_flat_samples) for more details.
877
0
    pub fn as_flat_samples_mut(&mut self) -> FlatSamples<&mut [P::Subpixel]>
878
0
    where
879
0
        Container: AsMut<[P::Subpixel]>,
880
    {
881
0
        let layout = self.sample_layout();
882
0
        FlatSamples {
883
0
            samples: self.data.as_mut(),
884
0
            layout,
885
0
            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
886
0
        }
887
0
    }
888
}
889
890
impl<P, Container> ImageBuffer<P, Container>
891
where
892
    P: Pixel,
893
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
894
{
895
    // TODO: choose name under which to expose.
896
132
    pub(crate) fn inner_pixels_mut(&mut self) -> &mut [P::Subpixel] {
897
132
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
898
132
        &mut self.data[..len]
899
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::inner_pixels_mut
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::inner_pixels_mut
Line
Count
Source
896
132
    pub(crate) fn inner_pixels_mut(&mut self) -> &mut [P::Subpixel] {
897
132
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
898
132
        &mut self.data[..len]
899
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::inner_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::inner_pixels_mut
900
901
    /// Returns an iterator over the mutable pixels of this image.
902
132
    pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> {
903
132
        PixelsMut {
904
132
            chunks: self
905
132
                .inner_pixels_mut()
906
132
                .chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
907
132
        }
908
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::pixels_mut
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::pixels_mut
Line
Count
Source
902
132
    pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> {
903
132
        PixelsMut {
904
132
            chunks: self
905
132
                .inner_pixels_mut()
906
132
                .chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
907
132
        }
908
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::pixels_mut
909
910
    /// Returns an iterator over the mutable rows of this image.
911
    ///
912
    /// Only non-empty rows can be iterated in this manner. In particular the iterator will not
913
    /// yield any item when the width of the image is `0` or a pixel type without any channels is
914
    /// used. This ensures that its length can always be represented by `usize`.
915
0
    pub fn rows_mut(&mut self) -> RowsMut<'_, P> {
916
0
        RowsMut::with_image(&mut self.data, self.width, self.height)
917
0
    }
918
919
    /// Enumerates over the pixels of the image.
920
    /// The iterator yields the coordinates of each pixel
921
    /// along with a mutable reference to them.
922
132
    pub fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<'_, P> {
923
132
        let width = self.width;
924
132
        EnumeratePixelsMut {
925
132
            pixels: self.pixels_mut(),
926
132
            x: 0,
927
132
            y: 0,
928
132
            width,
929
132
        }
930
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::enumerate_pixels_mut
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::enumerate_pixels_mut
Line
Count
Source
922
132
    pub fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<'_, P> {
923
132
        let width = self.width;
924
132
        EnumeratePixelsMut {
925
132
            pixels: self.pixels_mut(),
926
132
            x: 0,
927
132
            y: 0,
928
132
            width,
929
132
        }
930
132
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::enumerate_pixels_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::enumerate_pixels_mut
931
932
    /// Enumerates over the rows of the image.
933
    /// The iterator yields the y-coordinate of each row
934
    /// along with a mutable reference to them.
935
0
    pub fn enumerate_rows_mut(&mut self) -> EnumerateRowsMut<'_, P> {
936
0
        let width = self.width;
937
0
        EnumerateRowsMut {
938
0
            rows: self.rows_mut(),
939
0
            y: 0,
940
0
            width,
941
0
        }
942
0
    }
943
944
    /// Gets a reference to the mutable pixel at location `(x, y)`
945
    ///
946
    /// # Panics
947
    ///
948
    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
949
    #[inline]
950
    #[track_caller]
951
0
    pub fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
952
0
        match self.pixel_indices(x, y) {
953
0
            None => panic!(
954
0
                "Image index {:?} out of bounds {:?}",
955
0
                (x, y),
956
0
                (self.width, self.height)
957
            ),
958
0
            Some(pixel_indices) => <P as Pixel>::from_slice_mut(&mut self.data[pixel_indices]),
959
        }
960
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::get_pixel_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::get_pixel_mut
961
962
    /// Gets a reference to the mutable pixel at location `(x, y)` or returns
963
    /// `None` if the index is out of the bounds `(width, height)`.
964
0
    pub fn get_pixel_mut_checked(&mut self, x: u32, y: u32) -> Option<&mut P> {
965
0
        if x >= self.width {
966
0
            return None;
967
0
        }
968
0
        let num_channels = <P as Pixel>::CHANNEL_COUNT as usize;
969
0
        let i = (y as usize)
970
0
            .saturating_mul(self.width as usize)
971
0
            .saturating_add(x as usize)
972
0
            .saturating_mul(num_channels);
973
974
0
        self.data
975
0
            .get_mut(i..i.checked_add(num_channels)?)
976
0
            .map(|pixel_indices| <P as Pixel>::from_slice_mut(pixel_indices))
977
0
    }
978
979
    /// Puts a pixel at location `(x, y)`
980
    ///
981
    /// # Panics
982
    ///
983
    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
984
    #[inline]
985
    #[track_caller]
986
0
    pub fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
987
0
        *self.get_pixel_mut(x, y) = pixel;
988
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::put_pixel
989
990
    /// Crop this image in place, removing pixels outside of the bounding rectangle.
991
    ///
992
    /// This behaves similar to [`imageops::crop`](crate::imageops::crop) except no additional
993
    /// allocation takes place. The width and height of this buffer are adjusted as part of the
994
    /// operation. The selection is shrunk to the overlap with this image if it is out of bounds.
995
    ///
996
    /// The pixel buffer is *not* shrunk and will continue to occupy the same amount of memory as
997
    /// before. See [`ImageBuffer::shrink_to_fit`] if the container is a [`Vec`].
998
    ///
999
    /// # Examples
1000
    ///
1001
    /// ```
1002
    /// use image::{RgbImage, math::Rect};
1003
    ///
1004
    /// let mut img = RgbImage::new(128, 128);
1005
    /// img.put_pixel(64, 64, image::Rgb([255, 0, 0]));
1006
    ///
1007
    /// let selection = Rect::from_xy_ranges(64..128, 64..128);
1008
    /// img.crop_in_place(selection);
1009
    ///
1010
    /// assert_eq!(img.dimensions(), (64, 64));
1011
    /// assert_eq!(img.get_pixel(0, 0), &image::Rgb([255, 0, 0]));
1012
    /// ```
1013
    ///
1014
    /// Selections beyond the image bounds are clamped.
1015
    ///
1016
    /// ```
1017
    /// use image::{RgbImage, math::Rect};
1018
    ///
1019
    /// let mut img = RgbImage::new(32, 32);
1020
    /// let selection = Rect::from_xy_ranges(16..40, 16..24);
1021
    /// # use image::GenericImageView as _;
1022
    /// # assert_eq!(image::imageops::crop(&img, selection).dimensions(), (16, 8));
1023
    ///
1024
    /// img.crop_in_place(selection);
1025
    /// assert_eq!(img.dimensions(), (16, 8));
1026
    /// ```
1027
0
    pub fn crop_in_place(&mut self, selection: Rect) {
1028
0
        let selection = selection.crop_dimms(self);
1029
        // We're now running essentially `copy_within` with differing source and destination row
1030
        // pitches. The above ensures that the target row pitch is smaller than our current one and
1031
        // we copy to offset `0` so always all data backwards.
1032
        //
1033
        // Since `selection` describes a smaller layout than our own, all indices that are computed
1034
        // from the pitches as type `usize` are within the bounds of the type and the underlying
1035
        // storage and we assume them to be valid. (If the `DerefMut` is malicious you'll get
1036
        // panics at runtime but that is not our problem, violating the contract of the container
1037
        // type for channels).
1038
0
        let rowlen = (selection.width as usize) * usize::from(<P as Pixel>::CHANNEL_COUNT);
1039
1040
0
        for y in 0..selection.height {
1041
0
            let sy = selection.y + y;
1042
0
            let source = self.pixel_indices_unchecked(selection.x, sy).start;
1043
0
            let dst = y as usize * rowlen;
1044
0
            self.data.copy_within(source..source + rowlen, dst);
1045
0
        }
1046
1047
0
        self.width = selection.width;
1048
0
        self.height = selection.height;
1049
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::crop_in_place
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::crop_in_place
1050
}
1051
1052
impl<P: Pixel, Container> ImageBuffer<P, Container> {
1053
    /// Define the color space for the image.
1054
    ///
1055
    /// The color data is unchanged. Reinterprets the existing red, blue, green channels as points
1056
    /// in the new set of primary colors, changing the apparent shade of pixels.
1057
    ///
1058
    /// Note that the primaries also define a reference whitepoint When this buffer contains Luma
1059
    /// data, the luminance channel is interpreted as the `Y` channel of a related `YCbCr` color
1060
    /// space as if by a non-constant chromaticity derived matrix. That is, coefficients are *not*
1061
    /// applied in the linear RGB space but use encoded channel values. (In a color space with the
1062
    /// linear transfer function there is no difference).
1063
    ///
1064
    /// The default color space is [`Cicp::SRGB`].
1065
14.3k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
14.3k
        self.color.primaries = color;
1067
14.3k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_rgb_primaries
Line
Count
Source
1065
266
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
266
        self.color.primaries = color;
1067
266
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1065
3.55k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
3.55k
        self.color.primaries = color;
1067
3.55k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1065
114
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
114
        self.color.primaries = color;
1067
114
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1065
7.46k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
7.46k
        self.color.primaries = color;
1067
7.46k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1065
207
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
207
        self.color.primaries = color;
1067
207
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_rgb_primaries
Line
Count
Source
1065
11
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
11
        self.color.primaries = color;
1067
11
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1065
2.60k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
2.60k
        self.color.primaries = color;
1067
2.60k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1065
35
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
35
        self.color.primaries = color;
1067
35
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1065
41
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
41
        self.color.primaries = color;
1067
41
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1065
34
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1066
34
        self.color.primaries = color;
1067
34
    }
1068
1069
    /// Define the transfer function for the image.
1070
    ///
1071
    /// The color data is unchanged. Reinterprets all (non-alpha) components in the image,
1072
    /// potentially changing the apparent shade of pixels. Individual components are always
1073
    /// interpreted as encoded numbers. To denote numbers in a linear RGB space, use
1074
    /// [`CicpTransferCharacteristics::Linear`].
1075
    ///
1076
    /// The default color space is [`Cicp::SRGB`].
1077
14.3k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
14.3k
        self.color.transfer = tf;
1079
14.3k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_transfer_function
Line
Count
Source
1077
266
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
266
        self.color.transfer = tf;
1079
266
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1077
3.55k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
3.55k
        self.color.transfer = tf;
1079
3.55k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1077
114
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
114
        self.color.transfer = tf;
1079
114
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1077
7.46k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
7.46k
        self.color.transfer = tf;
1079
7.46k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1077
207
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
207
        self.color.transfer = tf;
1079
207
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_transfer_function
Line
Count
Source
1077
11
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
11
        self.color.transfer = tf;
1079
11
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1077
2.60k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
2.60k
        self.color.transfer = tf;
1079
2.60k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1077
35
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
35
        self.color.transfer = tf;
1079
35
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1077
41
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
41
        self.color.transfer = tf;
1079
41
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1077
34
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1078
34
        self.color.transfer = tf;
1079
34
    }
1080
1081
    /// Get the Cicp encoding of this buffer's color data.
1082
0
    pub fn color_space(&self) -> Cicp {
1083
0
        self.color.into()
1084
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::color_space
1085
1086
    /// Set primaries and transfer characteristics from a Cicp color space.
1087
    ///
1088
    /// Returns an error if `cicp` uses features that are not support with an RGB color space, e.g.
1089
    /// a matrix or narrow range (studio encoding) channels.
1090
0
    pub fn set_color_space(&mut self, cicp: Cicp) -> ImageResult<()> {
1091
0
        self.color = cicp.try_into_rgb()?;
1092
0
        Ok(())
1093
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_color_space
1094
1095
0
    pub(crate) fn set_rgb_color_space(&mut self, color: CicpRgb) {
1096
0
        self.color = color;
1097
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_rgb_color_space
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_rgb_color_space
1098
}
1099
1100
impl<P, Container> ImageBuffer<P, Container>
1101
where
1102
    P: Pixel,
1103
    [P::Subpixel]: EncodableLayout,
1104
    Container: Deref<Target = [P::Subpixel]>,
1105
{
1106
    /// Saves the buffer to a file at the path specified.
1107
    ///
1108
    /// The image format is derived from the file extension.
1109
0
    pub fn save<Q>(&self, path: Q) -> ImageResult<()>
1110
0
    where
1111
0
        Q: AsRef<Path>,
1112
0
        P: PixelWithColorType,
1113
    {
1114
0
        save_buffer(
1115
0
            path,
1116
0
            self.inner_pixels().as_bytes(),
1117
0
            self.width(),
1118
0
            self.height(),
1119
            <P as PixelWithColorType>::COLOR_TYPE,
1120
        )
1121
0
    }
1122
}
1123
1124
impl<P, Container> ImageBuffer<P, Container>
1125
where
1126
    P: Pixel,
1127
    [P::Subpixel]: EncodableLayout,
1128
    Container: Deref<Target = [P::Subpixel]>,
1129
{
1130
    /// Saves the buffer to a file at the specified path in
1131
    /// the specified format.
1132
    ///
1133
    /// See [`save_buffer_with_format`](fn.save_buffer_with_format.html) for
1134
    /// supported types.
1135
0
    pub fn save_with_format<Q>(&self, path: Q, format: ImageFormat) -> ImageResult<()>
1136
0
    where
1137
0
        Q: AsRef<Path>,
1138
0
        P: PixelWithColorType,
1139
    {
1140
        // This is valid as the subpixel is u8.
1141
0
        save_buffer_with_format(
1142
0
            path,
1143
0
            self.inner_pixels().as_bytes(),
1144
0
            self.width(),
1145
0
            self.height(),
1146
            <P as PixelWithColorType>::COLOR_TYPE,
1147
0
            format,
1148
        )
1149
0
    }
1150
}
1151
1152
impl<P, Container> ImageBuffer<P, Container>
1153
where
1154
    P: Pixel,
1155
    [P::Subpixel]: EncodableLayout,
1156
    Container: Deref<Target = [P::Subpixel]>,
1157
{
1158
    /// Writes the buffer to a writer in the specified format.
1159
    ///
1160
    /// Assumes the writer is buffered. In most cases, you should wrap your writer in a `BufWriter`
1161
    /// for best performance.
1162
1.85k
    pub fn write_to<W>(&self, writer: &mut W, format: ImageFormat) -> ImageResult<()>
1163
1.85k
    where
1164
1.85k
        W: std::io::Write + std::io::Seek,
1165
1.85k
        P: PixelWithColorType,
1166
    {
1167
        // This is valid as the subpixel is u8.
1168
1.85k
        write_buffer_with_format(
1169
1.85k
            writer,
1170
1.85k
            self.inner_pixels().as_bytes(),
1171
1.85k
            self.width(),
1172
1.85k
            self.height(),
1173
            <P as PixelWithColorType>::COLOR_TYPE,
1174
1.85k
            format,
1175
        )
1176
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<_, _>>::write_to::<_>
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::write_to::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
Line
Count
Source
1162
1.85k
    pub fn write_to<W>(&self, writer: &mut W, format: ImageFormat) -> ImageResult<()>
1163
1.85k
    where
1164
1.85k
        W: std::io::Write + std::io::Seek,
1165
1.85k
        P: PixelWithColorType,
1166
    {
1167
        // This is valid as the subpixel is u8.
1168
1.85k
        write_buffer_with_format(
1169
1.85k
            writer,
1170
1.85k
            self.inner_pixels().as_bytes(),
1171
1.85k
            self.width(),
1172
1.85k
            self.height(),
1173
            <P as PixelWithColorType>::COLOR_TYPE,
1174
1.85k
            format,
1175
        )
1176
1.85k
    }
1177
}
1178
1179
impl<P, Container> ImageBuffer<P, Container>
1180
where
1181
    P: Pixel,
1182
    [P::Subpixel]: EncodableLayout,
1183
    Container: Deref<Target = [P::Subpixel]>,
1184
{
1185
    /// Writes the buffer with the given encoder.
1186
0
    pub fn write_with_encoder<E>(&self, encoder: E) -> ImageResult<()>
1187
0
    where
1188
0
        E: ImageEncoder,
1189
0
        P: PixelWithColorType,
1190
    {
1191
        // This is valid as the subpixel is u8.
1192
0
        encoder.write_image(
1193
0
            self.inner_pixels().as_bytes(),
1194
0
            self.width(),
1195
0
            self.height(),
1196
            <P as PixelWithColorType>::COLOR_TYPE,
1197
        )
1198
0
    }
1199
}
1200
1201
impl<P, Container> Default for ImageBuffer<P, Container>
1202
where
1203
    P: Pixel,
1204
    Container: Default,
1205
{
1206
0
    fn default() -> Self {
1207
0
        Self {
1208
0
            width: 0,
1209
0
            height: 0,
1210
0
            _phantom: PhantomData,
1211
0
            color: Cicp::SRGB_LINEAR.into_rgb(),
1212
0
            data: Default::default(),
1213
0
        }
1214
0
    }
1215
}
1216
1217
impl<P, Container> Deref for ImageBuffer<P, Container>
1218
where
1219
    P: Pixel,
1220
    Container: Deref<Target = [P::Subpixel]>,
1221
{
1222
    type Target = [P::Subpixel];
1223
1224
0
    fn deref(&self) -> &<Self as Deref>::Target {
1225
0
        &self.data
1226
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as core::ops::deref::Deref>::deref
1227
}
1228
1229
impl<P, Container> DerefMut for ImageBuffer<P, Container>
1230
where
1231
    P: Pixel,
1232
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1233
{
1234
0
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
1235
0
        &mut self.data
1236
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as core::ops::deref::DerefMut>::deref_mut
1237
}
1238
1239
impl<P, Container> Index<(u32, u32)> for ImageBuffer<P, Container>
1240
where
1241
    P: Pixel,
1242
    Container: Deref<Target = [P::Subpixel]>,
1243
{
1244
    type Output = P;
1245
1246
0
    fn index(&self, (x, y): (u32, u32)) -> &P {
1247
0
        self.get_pixel(x, y)
1248
0
    }
1249
}
1250
1251
impl<P, Container> IndexMut<(u32, u32)> for ImageBuffer<P, Container>
1252
where
1253
    P: Pixel,
1254
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1255
{
1256
0
    fn index_mut(&mut self, (x, y): (u32, u32)) -> &mut P {
1257
0
        self.get_pixel_mut(x, y)
1258
0
    }
1259
}
1260
1261
impl<P, Container> Clone for ImageBuffer<P, Container>
1262
where
1263
    P: Pixel,
1264
    Container: Deref<Target = [P::Subpixel]> + Clone,
1265
{
1266
0
    fn clone(&self) -> ImageBuffer<P, Container> {
1267
0
        ImageBuffer {
1268
0
            data: self.data.clone(),
1269
0
            width: self.width,
1270
0
            height: self.height,
1271
0
            color: self.color,
1272
0
            _phantom: PhantomData,
1273
0
        }
1274
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone
1275
1276
0
    fn clone_from(&mut self, source: &Self) {
1277
0
        self.data.clone_from(&source.data);
1278
0
        self.width = source.width;
1279
0
        self.height = source.height;
1280
0
        self.color = source.color;
1281
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as core::clone::Clone>::clone_from
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as core::clone::Clone>::clone_from
1282
}
1283
1284
impl<P, Container> fmt::Debug for ImageBuffer<P, Container>
1285
where
1286
    P: Pixel + fmt::Debug,
1287
    Container: fmt::Debug,
1288
{
1289
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1290
0
        let mut pixel = std::any::type_name::<P>();
1291
0
        pixel = pixel.strip_prefix("image::color::").unwrap_or(pixel);
1292
1293
0
        let mut debug_struct = f.debug_struct(&format!("ImageBuffer::<{pixel}, _>"));
1294
0
        debug_struct.field("width", &self.width);
1295
0
        debug_struct.field("height", &self.height);
1296
1297
0
        if let Some(color_name) = self.color.known_name() {
1298
0
            debug_struct.field("color", &color_name);
1299
0
        } else {
1300
0
            debug_struct.field("color", &self.color);
1301
0
        }
1302
1303
0
        debug_struct.finish()
1304
0
    }
1305
}
1306
1307
impl<P, Container> GenericImageView for ImageBuffer<P, Container>
1308
where
1309
    P: Pixel,
1310
    Container: Deref<Target = [P::Subpixel]> + Deref,
1311
{
1312
    type Pixel = P;
1313
1314
0
    fn dimensions(&self) -> (u32, u32) {
1315
0
        self.dimensions()
1316
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::dimensions
1317
1318
0
    fn get_pixel(&self, x: u32, y: u32) -> P {
1319
0
        *self.get_pixel(x, y)
1320
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::get_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::get_pixel
1321
1322
0
    fn to_pixel_view(&self) -> Option<ViewOfPixel<'_, Self::Pixel>> {
1323
0
        self.as_flat_samples().into_view().ok()
1324
0
    }
1325
1326
    /// Returns the pixel located at (x, y), ignoring bounds checking.
1327
    #[inline(always)]
1328
0
    unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> P {
1329
0
        let indices = self.pixel_indices_unchecked(x, y);
1330
0
        *<P as Pixel>::from_slice(self.data.get_unchecked(indices))
1331
0
    }
1332
1333
0
    fn buffer_with_dimensions(&self, width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1334
0
        let mut buffer = ImageBuffer::new(width, height);
1335
0
        buffer.copy_color_space_from(self);
1336
0
        buffer
1337
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImageView>::buffer_with_dimensions
1338
}
1339
1340
impl<P, Container> GenericImage for ImageBuffer<P, Container>
1341
where
1342
    P: Pixel,
1343
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1344
{
1345
0
    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
1346
0
        self.get_pixel_mut(x, y)
1347
0
    }
1348
1349
0
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1350
0
        *self.get_pixel_mut(x, y) = pixel;
1351
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::put_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::put_pixel
1352
1353
    /// Puts a pixel at location (x, y), ignoring bounds checking.
1354
    #[inline(always)]
1355
0
    unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1356
0
        let indices = self.pixel_indices_unchecked(x, y);
1357
0
        let p = <P as Pixel>::from_slice_mut(self.data.get_unchecked_mut(indices));
1358
0
        *p = pixel;
1359
0
    }
1360
1361
    /// Put a pixel at location (x, y), taking into account alpha channels
1362
    ///
1363
    /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
1364
0
    fn blend_pixel(&mut self, x: u32, y: u32, p: P) {
1365
0
        self.get_pixel_mut(x, y).blend(&p);
1366
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>> as image::images::generic_image::GenericImage>::blend_pixel
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>> as image::images::generic_image::GenericImage>::blend_pixel
1367
1368
0
    fn copy_from_samples(
1369
0
        &mut self,
1370
0
        view: ViewOfPixel<'_, Self::Pixel>,
1371
0
        x: u32,
1372
0
        y: u32,
1373
0
    ) -> ImageResult<()> {
1374
0
        let (width, height) = view.dimensions();
1375
0
        let pix_stride = usize::from(<Self::Pixel as Pixel>::CHANNEL_COUNT);
1376
0
        Rect::from_image_at(&view, x, y).test_in_bounds(self)?;
1377
1378
0
        if width == 0 || height == 0 || pix_stride == 0 {
1379
0
            return Ok(());
1380
0
        }
1381
1382
        // Since this image is not empty, all its indices fit into `usize` as they address the
1383
        // memory resident buffer of `self`.
1384
0
        let row_len = width as usize * pix_stride;
1385
0
        let img_sh = self.width as usize;
1386
1387
0
        let (sw, sh) = view.strides_wh();
1388
0
        let view_samples: &[_] = view.samples();
1389
0
        let inner = self.inner_pixels_mut();
1390
1391
0
        let img_pixel_indices_unchecked =
1392
0
            |x: u32, y: u32| (y as usize * img_sh + x as usize) * pix_stride;
1393
1394
        // Can we use row-by-row byte copy?
1395
0
        if sw == pix_stride {
1396
0
            for j in 0..height {
1397
0
                let start = img_pixel_indices_unchecked(x, j + y);
1398
0
                let img_row = &mut inner[start..][..row_len];
1399
0
                let view_row = &view_samples[j as usize * sh..][..row_len];
1400
0
                img_row.copy_from_slice(view_row);
1401
0
            }
1402
1403
0
            return Ok(());
1404
0
        }
1405
1406
        // Fallback behavior.
1407
0
        for j in 0..height {
1408
0
            let img_start = img_pixel_indices_unchecked(x, j + y);
1409
0
            let img_row = &mut inner[img_start..][..row_len];
1410
0
            let pixels = img_row.chunks_exact_mut(pix_stride);
1411
1412
0
            let view_start = j as usize * sh;
1413
1414
0
            for (i, sp) in pixels.enumerate() {
1415
0
                let view_pixel = &view_samples[i * sw + view_start..][..pix_stride];
1416
0
                sp.copy_from_slice(view_pixel);
1417
0
            }
1418
        }
1419
1420
0
        Ok(())
1421
0
    }
1422
1423
0
    fn copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool {
1424
        let Rect {
1425
0
            x: sx,
1426
0
            y: sy,
1427
0
            width,
1428
0
            height,
1429
0
        } = source;
1430
0
        let dx = x;
1431
0
        let dy = y;
1432
0
        assert!(sx < self.width() && dx < self.width());
1433
0
        assert!(sy < self.height() && dy < self.height());
1434
0
        if self.width() - dx.max(sx) < width || self.height() - dy.max(sy) < height {
1435
0
            return false;
1436
0
        }
1437
1438
0
        if sy < dy {
1439
0
            for y in (0..height).rev() {
1440
0
                let sy = sy + y;
1441
0
                let dy = dy + y;
1442
0
                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1443
0
                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1444
0
                let dst = self.pixel_indices_unchecked(dx, dy).start;
1445
0
                self.data.copy_within(start..end, dst);
1446
0
            }
1447
        } else {
1448
0
            for y in 0..height {
1449
0
                let sy = sy + y;
1450
0
                let dy = dy + y;
1451
0
                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1452
0
                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1453
0
                let dst = self.pixel_indices_unchecked(dx, dy).start;
1454
0
                self.data.copy_within(start..end, dst);
1455
0
            }
1456
        }
1457
0
        true
1458
0
    }
1459
}
1460
1461
// concrete implementation for `Vec`-backed buffers
1462
// TODO: I think that rustc does not "see" this impl any more: the impl with
1463
// Container meets the same requirements. At least, I got compile errors that
1464
// there is no such function as `into_vec`, whereas `into_raw` did work, and
1465
// `into_vec` is redundant anyway, because `into_raw` will give you the vector,
1466
// and it is more generic.
1467
impl<P: Pixel> ImageBuffer<P, Vec<P::Subpixel>> {
1468
    /// Creates a new image buffer based on a `Vec<P::Subpixel>`.
1469
    ///
1470
    /// all the pixels of this image have a value of zero, regardless of the data type or number of channels.
1471
    ///
1472
    /// The color space is initially set to [`sRGB`][`Cicp::SRGB`].
1473
    ///
1474
    /// # Panics
1475
    ///
1476
    /// Panics when the resulting image is larger than the maximum size of a vector.
1477
    #[must_use]
1478
0
    pub fn new(width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1479
0
        let size = Self::image_buffer_len(width, height)
1480
0
            .expect("Buffer length in `ImageBuffer::new` overflows usize");
1481
0
        ImageBuffer {
1482
0
            data: vec![Zero::zero(); size],
1483
0
            width,
1484
0
            height,
1485
0
            color: Cicp::SRGB.into_rgb(),
1486
0
            _phantom: PhantomData,
1487
0
        }
1488
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::new
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::new
1489
1490
    /// Constructs a new `ImageBuffer` by copying a pixel
1491
    ///
1492
    /// # Panics
1493
    ///
1494
    /// Panics when the resulting image is larger than the maximum size of a vector.
1495
0
    pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuffer<P, Vec<P::Subpixel>> {
1496
0
        let mut buf = ImageBuffer::new(width, height);
1497
0
        for p in buf.pixels_mut() {
1498
0
            *p = pixel;
1499
0
        }
1500
0
        buf
1501
0
    }
1502
1503
    /// Constructs a new `ImageBuffer` by repeated application of the supplied function.
1504
    ///
1505
    /// The arguments to the function are the pixel's x and y coordinates.
1506
    ///
1507
    /// # Panics
1508
    ///
1509
    /// Panics when the resulting image is larger than the maximum size of a vector.
1510
0
    pub fn from_fn<F>(width: u32, height: u32, mut f: F) -> ImageBuffer<P, Vec<P::Subpixel>>
1511
0
    where
1512
0
        F: FnMut(u32, u32) -> P,
1513
    {
1514
0
        let mut buf = ImageBuffer::new(width, height);
1515
0
        for (x, y, p) in buf.enumerate_pixels_mut() {
1516
0
            *p = f(x, y);
1517
0
        }
1518
0
        buf
1519
0
    }
1520
1521
    /// Creates an image buffer out of an existing buffer.
1522
    /// Returns None if the buffer is not big enough.
1523
    #[must_use]
1524
1.85k
    pub fn from_vec(
1525
1.85k
        width: u32,
1526
1.85k
        height: u32,
1527
1.85k
        buf: Vec<P::Subpixel>,
1528
1.85k
    ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1529
1.85k
        ImageBuffer::from_raw(width, height, buf)
1530
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::from_vec
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::from_vec
Line
Count
Source
1524
1.85k
    pub fn from_vec(
1525
1.85k
        width: u32,
1526
1.85k
        height: u32,
1527
1.85k
        buf: Vec<P::Subpixel>,
1528
1.85k
    ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1529
1.85k
        ImageBuffer::from_raw(width, height, buf)
1530
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::from_vec
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::from_vec
1531
1532
    /// Consumes the image buffer and returns the underlying data
1533
    /// as an owned buffer
1534
    #[must_use]
1535
1.85k
    pub fn into_vec(self) -> Vec<P::Subpixel> {
1536
1.85k
        self.into_raw()
1537
1.85k
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<_, alloc::vec::Vec<<_ as image::traits::Pixel>::Subpixel>>>::into_vec
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::into_vec
Line
Count
Source
1535
1.85k
    pub fn into_vec(self) -> Vec<P::Subpixel> {
1536
1.85k
        self.into_raw()
1537
1.85k
    }
1538
1539
    /// Shrink the length and capacity of the data buffer to fit the image size.
1540
    ///
1541
    /// This is useful after shrinking an image in-place, e.g. via cropping, to free unused memory
1542
    /// or in case the image was created from a buffer with excess capacity.
1543
    ///
1544
    /// ```
1545
    /// use image::RgbImage;
1546
    ///
1547
    /// let data = vec![0u8; 10000];
1548
    /// // `from_raw` allows excess data
1549
    /// let mut img = RgbImage::from_raw(16, 16, data).unwrap();
1550
    /// img.shrink_to_fit();
1551
    ///
1552
    /// assert_eq!(img.into_vec().len(), 16 * 16 * 3);
1553
    /// ```
1554
0
    pub fn shrink_to_fit(&mut self) {
1555
0
        let need = self.inner_pixels().len();
1556
0
        self.data.truncate(need);
1557
0
        self.data.shrink_to_fit();
1558
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::shrink_to_fit
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::shrink_to_fit
1559
1560
    /// Transfer the meta data, not the pixel values.
1561
    ///
1562
    /// This will reinterpret all the pixels.
1563
    ///
1564
    /// We may want to export this but under what name?
1565
0
    pub(crate) fn copy_color_space_from<O: Pixel, C>(&mut self, other: &ImageBuffer<O, C>) {
1566
0
        self.color = other.color;
1567
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::LumaA<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Luma<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::copy_color_space_from::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgba<u16>, &[u16]>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Rgb<u16>, &[u16]>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u8>, &[u8]>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::Luma<u16>, &[u16]>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u8>, &[u8]>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_color_space_from::<image::color::LumaA<u16>, &[u16]>
1568
}
1569
1570
impl<S, Container> ImageBuffer<Rgb<S>, Container>
1571
where
1572
    Rgb<S>: PixelWithColorType<Subpixel = S>,
1573
    Container: DerefMut<Target = [S]>,
1574
{
1575
    /// Construct an image by swapping `Bgr` channels into an `Rgb` order.
1576
0
    pub fn from_raw_bgr(width: u32, height: u32, container: Container) -> Option<Self> {
1577
0
        let mut img = Self::from_raw(width, height, container)?;
1578
1579
0
        for pix in img.pixels_mut() {
1580
0
            pix.0.reverse();
1581
0
        }
1582
1583
0
        Some(img)
1584
0
    }
1585
1586
    /// Return the underlying raw buffer after converting it into `Bgr` channel order.
1587
0
    pub fn into_raw_bgr(mut self) -> Container {
1588
0
        for pix in self.pixels_mut() {
1589
0
            pix.0.reverse();
1590
0
        }
1591
1592
0
        self.into_raw()
1593
0
    }
1594
}
1595
1596
impl<S, Container> ImageBuffer<Rgba<S>, Container>
1597
where
1598
    Rgba<S>: PixelWithColorType<Subpixel = S>,
1599
    Container: DerefMut<Target = [S]>,
1600
{
1601
    /// Construct an image by swapping `BgrA` channels into an `RgbA` order.
1602
0
    pub fn from_raw_bgra(width: u32, height: u32, container: Container) -> Option<Self> {
1603
0
        let mut img = Self::from_raw(width, height, container)?;
1604
1605
0
        for pix in img.pixels_mut() {
1606
0
            pix.0[..3].reverse();
1607
0
        }
1608
1609
0
        Some(img)
1610
0
    }
1611
1612
    /// Return the underlying raw buffer after converting it into `BgrA` channel order.
1613
0
    pub fn into_raw_bgra(mut self) -> Container {
1614
0
        for pix in self.pixels_mut() {
1615
0
            pix.0[..3].reverse();
1616
0
        }
1617
1618
0
        self.into_raw()
1619
0
    }
1620
}
1621
1622
/// Provides color conversions for whole image buffers.
1623
pub trait ConvertBuffer<T> {
1624
    /// Converts `self` to a buffer of type T
1625
    ///
1626
    /// A generic implementation is provided to convert any image buffer to a image buffer
1627
    /// based on a `Vec<T>`.
1628
    fn convert(&self) -> T;
1629
}
1630
1631
// concrete implementation Luma -> Rgba
1632
impl GrayImage {
1633
    /// Expands a color palette by re-using the existing buffer.
1634
    /// Assumes 8 bit per pixel. Uses an optionally transparent index to
1635
    /// adjust it's alpha value accordingly.
1636
    #[must_use]
1637
0
    pub fn expand_palette(
1638
0
        self,
1639
0
        palette: &[(u8, u8, u8)],
1640
0
        transparent_idx: Option<u8>,
1641
0
    ) -> RgbaImage {
1642
0
        let (width, height) = self.dimensions();
1643
0
        let mut data = self.into_raw();
1644
0
        let entries = data.len();
1645
0
        data.resize(entries.checked_mul(4).unwrap(), 0);
1646
0
        let mut buffer = ImageBuffer::from_vec(width, height, data).unwrap();
1647
0
        expand_packed(&mut buffer, 4, 8, |idx, pixel| {
1648
0
            let (r, g, b) = palette[idx as usize];
1649
0
            let a = if let Some(t_idx) = transparent_idx {
1650
0
                if t_idx == idx {
1651
0
                    0
1652
                } else {
1653
0
                    255
1654
                }
1655
            } else {
1656
0
                255
1657
            };
1658
0
            pixel[0] = r;
1659
0
            pixel[1] = g;
1660
0
            pixel[2] = b;
1661
0
            pixel[3] = a;
1662
0
        });
1663
0
        buffer
1664
0
    }
1665
}
1666
1667
/// This copies the color space information but is somewhat wrong, in numeric terms this conversion
1668
/// fails to actually convert rgb/luma with consistent treatment. But this trait impl is too
1669
/// generic to handle it correctly (missing any CICP related parameter for the coefficients) so the
1670
/// best effort here is to copy the metadata and have slighly incorrect color. May you've only been
1671
/// adding an alpha channel or converting sample types, which is fine.
1672
///
1673
/// It will very likely be deprecated in a future release.
1674
impl<Container, FromType: Pixel, ToType: Pixel>
1675
    ConvertBuffer<ImageBuffer<ToType, Vec<ToType::Subpixel>>> for ImageBuffer<FromType, Container>
1676
where
1677
    Container: Deref<Target = [FromType::Subpixel]>,
1678
    ToType: FromColor<FromType>,
1679
{
1680
    /// # Examples
1681
    /// Convert RGB image to gray image.
1682
    /// ```no_run
1683
    /// use image::buffer::ConvertBuffer;
1684
    /// use image::GrayImage;
1685
    ///
1686
    /// let image_path = "examples/fractal.png";
1687
    /// let image = image::open(&image_path)
1688
    ///     .expect("Open file failed")
1689
    ///     .to_rgba8();
1690
    ///
1691
    /// let gray_image: GrayImage = image.convert();
1692
    /// ```
1693
0
    fn convert(&self) -> ImageBuffer<ToType, Vec<ToType::Subpixel>> {
1694
0
        let mut buffer: ImageBuffer<ToType, Vec<ToType::Subpixel>> =
1695
0
            ImageBuffer::new(self.width, self.height);
1696
0
        buffer.copy_color_space_from(self);
1697
0
        for (to, from) in buffer.pixels_mut().zip(self.pixels()) {
1698
0
            to.from_color(from);
1699
0
        }
1700
0
        buffer
1701
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<f32>, alloc::vec::Vec<f32>> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<f32>, alloc::vec::Vec<f32>> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, &[u16]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, &[u8]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, &[u16]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, &[u16]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, &[u8]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, &[u16]> as image::images::buffer::ConvertBuffer<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>>::convert
1702
}
1703
1704
/// Inputs to [`ImageBuffer::copy_from_color_space`].
1705
#[non_exhaustive]
1706
#[derive(Default)]
1707
pub struct ConvertColorOptions {
1708
    /// A pre-calculated transform. This is only used when the actual colors of the input and
1709
    /// output image match the color spaces with which the was constructed.
1710
    ///
1711
    /// FIXME: Clarify that the transform is cheap to clone, i.e. internally an Arc of precomputed
1712
    /// tables and not expensive despite having `Clone`.
1713
    pub(crate) transform: Option<CicpTransform>,
1714
    /// Make sure we can later add options that are bound to the thread. That does not mean that
1715
    /// all attributes will be bound to the thread, only that we can add `!Sync` options later. You
1716
    /// should be constructing the options at the call site with each attribute being cheap to move
1717
    /// into here.
1718
    pub(crate) _auto_traits: PhantomData<std::rc::Rc<()>>,
1719
}
1720
1721
impl ConvertColorOptions {
1722
0
    pub(crate) fn as_transform(
1723
0
        &mut self,
1724
0
        from_color: Cicp,
1725
0
        into_color: Cicp,
1726
0
    ) -> Result<&CicpTransform, ImageError> {
1727
0
        if let Some(tr) = &self.transform {
1728
0
            tr.check_applicable(from_color, into_color)?;
1729
0
        }
1730
1731
0
        if self.transform.is_none() {
1732
0
            self.transform = CicpTransform::new(from_color, into_color);
1733
0
        }
1734
1735
0
        self.transform.as_ref().ok_or_else(|| {
1736
0
            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
1737
0
                crate::error::ImageFormatHint::Unknown,
1738
                // One of them is responsible.
1739
0
                UnsupportedErrorKind::ColorspaceCicp(if from_color.qualify_stability() {
1740
0
                    into_color
1741
                } else {
1742
0
                    from_color
1743
                }),
1744
            ))
1745
0
        })
1746
0
    }
1747
1748
0
    pub(crate) fn as_transform_fn<FromType, IntoType>(
1749
0
        &mut self,
1750
0
        from_color: Cicp,
1751
0
        into_color: Cicp,
1752
0
    ) -> Result<&'_ CicpApplicable<'_, FromType::Subpixel>, ImageError>
1753
0
    where
1754
0
        FromType: PixelWithColorType,
1755
0
        IntoType: PixelWithColorType,
1756
    {
1757
0
        Ok(self
1758
0
            .as_transform(from_color, into_color)?
1759
0
            .supported_transform_fn::<FromType, IntoType>())
1760
0
    }
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<f32>, image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<f32>, image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<u8>, image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<u8>, image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<u16>, image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgb<u16>, image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<f32>, image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<f32>, image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<u8>, image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<u8>, image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<u16>, image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ConvertColorOptions>::as_transform_fn::<image::color::Rgba<u16>, image::color::Rgb<u16>>
1761
}
1762
1763
impl<C, SelfPixel: Pixel> ImageBuffer<SelfPixel, C>
1764
where
1765
    SelfPixel: PixelWithColorType,
1766
    C: Deref<Target = [SelfPixel::Subpixel]> + DerefMut,
1767
{
1768
    /// Convert the color data to another pixel type, the color space.
1769
    ///
1770
    /// This method is supposed to be called by exposed monomorphized methods, not directly by
1771
    /// users. In particular it serves to implement `DynamicImage`'s casts that go beyond those
1772
    /// offered by `PixelWithColorType` and include, e.g., `LumaAlpha<f32>`.
1773
    ///
1774
    /// Before exposing this method, decide if we want a design like [`DynamicImage::to`] (many
1775
    /// trait parameters) with color space aware `FromColor` or if we want a design that takes a
1776
    /// `ColorType` parameter / `PixelWithColorType`. The latter is not quite as flexible but
1777
    /// allows much greater internal changes that do not tie in with the _external_ stable API.
1778
0
    pub(crate) fn cast_in_color_space<IntoPixel>(
1779
0
        &self,
1780
0
    ) -> ImageBuffer<IntoPixel, Vec<IntoPixel::Subpixel>>
1781
0
    where
1782
0
        SelfPixel: Pixel,
1783
0
        IntoPixel: Pixel,
1784
0
        IntoPixel: CicpPixelCast<SelfPixel>,
1785
0
        SelfPixel::Subpixel: ColorComponentForCicp,
1786
0
        IntoPixel::Subpixel: ColorComponentForCicp + FromPrimitive<SelfPixel::Subpixel>,
1787
    {
1788
0
        let vec = self
1789
0
            .color
1790
0
            .cast_pixels::<SelfPixel, IntoPixel>(self.inner_pixels(), &|| [0.2126, 0.7152, 0.0722]);
1791
0
        let mut buffer = ImageBuffer::from_vec(self.width, self.height, vec)
1792
0
            .expect("cast_pixels returned the right number of pixels");
1793
0
        buffer.copy_color_space_from(self);
1794
0
        buffer
1795
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::cast_in_color_space::<image::color::Rgba<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::LumaA<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgb<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Luma<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::cast_in_color_space::<image::color::Rgba<u16>>
1796
1797
    /// Copy pixel data from one buffer to another, calculating equivalent color representations
1798
    /// for the target's color space.
1799
    ///
1800
    /// Returns `Ok` if:
1801
    /// - Both images to have the same dimensions, otherwise returns a [`ImageError::Parameter`].
1802
    /// - The primaries and transfer functions of both image's color spaces must be supported,
1803
    ///   otherwise returns a [`ImageError::Unsupported`].
1804
    /// - The pixel's channel layout must be supported for conversion, otherwise returns a
1805
    ///   [`ImageError::Unsupported`]. You can rely on RGB and RGBA always being supported. If a
1806
    ///   layout is supported for one color space it is supported for all of them.
1807
    ///
1808
    /// To copy color data of arbitrary channel layouts use `DynamicImage` with the overhead of
1809
    /// having data converted into and from RGB representation.
1810
0
    pub fn copy_from_color_space<FromType, D>(
1811
0
        &mut self,
1812
0
        from: &ImageBuffer<FromType, D>,
1813
0
        mut options: ConvertColorOptions,
1814
0
    ) -> ImageResult<()>
1815
0
    where
1816
0
        FromType: Pixel<Subpixel = SelfPixel::Subpixel> + PixelWithColorType,
1817
0
        D: Deref<Target = [SelfPixel::Subpixel]>,
1818
    {
1819
0
        if self.dimensions() != from.dimensions() {
1820
0
            return Err(ImageError::Parameter(ParameterError::from_kind(
1821
0
                ParameterErrorKind::DimensionMismatch,
1822
0
            )));
1823
0
        }
1824
1825
0
        let transform = options
1826
0
            .as_transform_fn::<FromType, SelfPixel>(from.color_space(), self.color_space())?;
1827
1828
0
        let from = from.inner_pixels();
1829
0
        let into = self.inner_pixels_mut();
1830
1831
0
        debug_assert_eq!(
1832
0
            from.len() / usize::from(FromType::CHANNEL_COUNT),
1833
0
            into.len() / usize::from(SelfPixel::CHANNEL_COUNT),
1834
0
            "Diverging pixel count despite same size",
1835
        );
1836
1837
0
        transform(from, into);
1838
1839
0
        Ok(())
1840
0
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_from_color_space::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::copy_from_color_space::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_from_color_space::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::copy_from_color_space::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_from_color_space::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::copy_from_color_space::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_from_color_space::<image::color::Rgba<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::copy_from_color_space::<image::color::Rgb<f32>, alloc::vec::Vec<f32>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_from_color_space::<image::color::Rgba<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::copy_from_color_space::<image::color::Rgb<u8>, alloc::vec::Vec<u8>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_from_color_space::<image::color::Rgba<u16>, alloc::vec::Vec<u16>>
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::copy_from_color_space::<image::color::Rgb<u16>, alloc::vec::Vec<u16>>
1841
1842
    /// Convert this buffer into a newly allocated buffer, changing the color representation.
1843
    ///
1844
    /// This will avoid an allocation if the target layout or the color conversion is not supported
1845
    /// (yet).
1846
    ///
1847
    /// See [`ImageBuffer::copy_from_color_space`] if you intend to assign to an existing buffer,
1848
    /// swapping the argument with `self`.
1849
0
    pub fn to_color_space<IntoType>(
1850
0
        &self,
1851
0
        color: Cicp,
1852
0
        mut options: ConvertColorOptions,
1853
0
    ) -> Result<ImageBuffer<IntoType, Vec<SelfPixel::Subpixel>>, ImageError>
1854
0
    where
1855
0
        IntoType: Pixel<Subpixel = SelfPixel::Subpixel> + PixelWithColorType,
1856
    {
1857
0
        let transform =
1858
0
            options.as_transform_fn::<SelfPixel, IntoType>(self.color_space(), color)?;
1859
1860
0
        let (width, height) = self.dimensions();
1861
0
        let mut target = ImageBuffer::new(width, height);
1862
1863
0
        let from = self.inner_pixels();
1864
0
        let into = target.inner_pixels_mut();
1865
1866
0
        transform(from, into);
1867
1868
0
        Ok(target)
1869
0
    }
1870
1871
    /// Apply a color space to an image, transforming the pixel representation.
1872
0
    pub fn apply_color_space(
1873
0
        &mut self,
1874
0
        color: Cicp,
1875
0
        mut options: ConvertColorOptions,
1876
0
    ) -> ImageResult<()> {
1877
0
        if self.color_space() == color {
1878
0
            return Ok(());
1879
0
        }
1880
1881
0
        let transform =
1882
0
            options.as_transform_fn::<SelfPixel, SelfPixel>(self.color_space(), color)?;
1883
1884
0
        let mut scratch = [<SelfPixel::Subpixel as crate::Primitive>::DEFAULT_MIN_VALUE; 1200];
1885
0
        let chunk_len = scratch.len() / usize::from(<SelfPixel as Pixel>::CHANNEL_COUNT)
1886
0
            * usize::from(<SelfPixel as Pixel>::CHANNEL_COUNT);
1887
1888
0
        for chunk in self.data.chunks_mut(chunk_len) {
1889
0
            let scratch = &mut scratch[..chunk.len()];
1890
0
            scratch.copy_from_slice(chunk);
1891
0
            transform(scratch, chunk);
1892
0
        }
1893
1894
0
        self.color = color.into_rgb();
1895
1896
0
        Ok(())
1897
0
    }
1898
}
1899
1900
/// Sendable Rgb image buffer
1901
pub type RgbImage = ImageBuffer<Rgb<u8>, Vec<u8>>;
1902
/// Sendable Rgb + alpha channel image buffer
1903
pub type RgbaImage = ImageBuffer<Rgba<u8>, Vec<u8>>;
1904
/// Sendable grayscale image buffer
1905
pub type GrayImage = ImageBuffer<Luma<u8>, Vec<u8>>;
1906
/// Sendable grayscale + alpha channel image buffer
1907
pub type GrayAlphaImage = ImageBuffer<LumaA<u8>, Vec<u8>>;
1908
/// Sendable 16-bit Rgb image buffer
1909
pub(crate) type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
1910
/// Sendable 16-bit Rgb + alpha channel image buffer
1911
pub(crate) type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
1912
/// Sendable 16-bit grayscale image buffer
1913
pub(crate) type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
1914
/// Sendable 16-bit grayscale + alpha channel image buffer
1915
pub(crate) type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;
1916
1917
/// An image buffer for 32-bit float RGB pixels,
1918
/// where the backing container is a flattened vector of floats.
1919
pub type Rgb32FImage = ImageBuffer<Rgb<f32>, Vec<f32>>;
1920
1921
/// An image buffer for 32-bit float RGBA pixels,
1922
/// where the backing container is a flattened vector of floats.
1923
pub type Rgba32FImage = ImageBuffer<Rgba<f32>, Vec<f32>>;
1924
1925
impl From<DynamicImage> for RgbImage {
1926
0
    fn from(value: DynamicImage) -> Self {
1927
0
        value.into_rgb8()
1928
0
    }
1929
}
1930
1931
impl From<DynamicImage> for RgbaImage {
1932
0
    fn from(value: DynamicImage) -> Self {
1933
0
        value.into_rgba8()
1934
0
    }
1935
}
1936
1937
impl From<DynamicImage> for GrayImage {
1938
0
    fn from(value: DynamicImage) -> Self {
1939
0
        value.into_luma8()
1940
0
    }
1941
}
1942
1943
impl From<DynamicImage> for GrayAlphaImage {
1944
0
    fn from(value: DynamicImage) -> Self {
1945
0
        value.into_luma_alpha8()
1946
0
    }
1947
}
1948
1949
impl From<DynamicImage> for Rgb16Image {
1950
0
    fn from(value: DynamicImage) -> Self {
1951
0
        value.into_rgb16()
1952
0
    }
1953
}
1954
1955
impl From<DynamicImage> for Rgba16Image {
1956
0
    fn from(value: DynamicImage) -> Self {
1957
0
        value.into_rgba16()
1958
0
    }
1959
}
1960
1961
impl From<DynamicImage> for Gray16Image {
1962
0
    fn from(value: DynamicImage) -> Self {
1963
0
        value.into_luma16()
1964
0
    }
1965
}
1966
1967
impl From<DynamicImage> for GrayAlpha16Image {
1968
0
    fn from(value: DynamicImage) -> Self {
1969
0
        value.into_luma_alpha16()
1970
0
    }
1971
}
1972
1973
impl From<DynamicImage> for Rgba32FImage {
1974
0
    fn from(value: DynamicImage) -> Self {
1975
0
        value.into_rgba32f()
1976
0
    }
1977
}
1978
1979
#[cfg(test)]
1980
mod test {
1981
    use super::{GrayImage, ImageBuffer, RgbImage};
1982
    use crate::math::Rect;
1983
    use crate::metadata::Cicp;
1984
    use crate::metadata::CicpMatrixCoefficients;
1985
    use crate::metadata::CicpTransform;
1986
    use crate::metadata::CicpVideoFullRangeFlag;
1987
    use crate::ImageFormat;
1988
    use crate::{GenericImage as _, GenericImageView as _};
1989
    use crate::{Luma, LumaA, Pixel, Rgb, Rgba};
1990
    use num_traits::Zero;
1991
1992
    #[test]
1993
    /// Tests if image buffers from slices work
1994
    fn slice_buffer() {
1995
        let data = [0; 9];
1996
        let buf: ImageBuffer<Luma<u8>, _> = ImageBuffer::from_raw(3, 3, &data[..]).unwrap();
1997
        assert_eq!(&*buf, &data[..]);
1998
    }
1999
2000
    macro_rules! new_buffer_zero_test {
2001
        ($test_name:ident, $pxt:ty) => {
2002
            #[test]
2003
            fn $test_name() {
2004
                let buffer = ImageBuffer::<$pxt, Vec<<$pxt as Pixel>::Subpixel>>::new(2, 2);
2005
                assert!(buffer
2006
                    .iter()
2007
                    .all(|p| *p == <$pxt as Pixel>::Subpixel::zero()));
2008
            }
2009
        };
2010
    }
2011
2012
    new_buffer_zero_test!(luma_u8_zero_test, Luma<u8>);
2013
    new_buffer_zero_test!(luma_u16_zero_test, Luma<u16>);
2014
    new_buffer_zero_test!(luma_f32_zero_test, Luma<f32>);
2015
    new_buffer_zero_test!(luma_a_u8_zero_test, LumaA<u8>);
2016
    new_buffer_zero_test!(luma_a_u16_zero_test, LumaA<u16>);
2017
    new_buffer_zero_test!(luma_a_f32_zero_test, LumaA<f32>);
2018
    new_buffer_zero_test!(rgb_u8_zero_test, Rgb<u8>);
2019
    new_buffer_zero_test!(rgb_u16_zero_test, Rgb<u16>);
2020
    new_buffer_zero_test!(rgb_f32_zero_test, Rgb<f32>);
2021
    new_buffer_zero_test!(rgb_a_u8_zero_test, Rgba<u8>);
2022
    new_buffer_zero_test!(rgb_a_u16_zero_test, Rgba<u16>);
2023
    new_buffer_zero_test!(rgb_a_f32_zero_test, Rgba<f32>);
2024
2025
    #[test]
2026
    fn get_pixel() {
2027
        let mut a: RgbImage = ImageBuffer::new(10, 10);
2028
        {
2029
            let b = a.get_mut(3 * 10).unwrap();
2030
            *b = 255;
2031
        }
2032
        assert_eq!(a.get_pixel(0, 1)[0], 255);
2033
    }
2034
2035
    #[test]
2036
    fn get_pixel_checked() {
2037
        let mut a: RgbImage = ImageBuffer::new(10, 10);
2038
        a.get_pixel_mut_checked(0, 1).unwrap()[0] = 255;
2039
2040
        assert_eq!(a.get_pixel_checked(0, 1), Some(&Rgb([255, 0, 0])));
2041
        assert_eq!(a.get_pixel_checked(0, 1).unwrap(), a.get_pixel(0, 1));
2042
        assert_eq!(a.get_pixel_checked(10, 0), None);
2043
        assert_eq!(a.get_pixel_checked(0, 10), None);
2044
        assert_eq!(a.get_pixel_mut_checked(10, 0), None);
2045
        assert_eq!(a.get_pixel_mut_checked(0, 10), None);
2046
2047
        // From image/issues/1672
2048
        const WHITE: Rgb<u8> = Rgb([255_u8, 255, 255]);
2049
        let mut a = RgbImage::new(2, 1);
2050
        a.put_pixel(1, 0, WHITE);
2051
2052
        assert_eq!(a.get_pixel_checked(1, 0), Some(&WHITE));
2053
        assert_eq!(a.get_pixel_checked(1, 0).unwrap(), a.get_pixel(1, 0));
2054
    }
2055
2056
    #[test]
2057
    fn mut_iter() {
2058
        let mut a: RgbImage = ImageBuffer::new(10, 10);
2059
        {
2060
            let val = a.pixels_mut().next().unwrap();
2061
            *val = Rgb([42, 0, 0]);
2062
        }
2063
        assert_eq!(a.data[0], 42);
2064
    }
2065
2066
    #[test]
2067
    fn zero_width_zero_height() {
2068
        let mut image = RgbImage::new(0, 0);
2069
2070
        assert_eq!(image.rows_mut().count(), 0);
2071
        assert_eq!(image.pixels_mut().count(), 0);
2072
        assert_eq!(image.rows().count(), 0);
2073
        assert_eq!(image.pixels().count(), 0);
2074
    }
2075
2076
    #[test]
2077
    fn zero_width_nonzero_height() {
2078
        let mut image = RgbImage::new(0, 2);
2079
2080
        assert_eq!(image.rows_mut().count(), 0);
2081
        assert_eq!(image.pixels_mut().count(), 0);
2082
        assert_eq!(image.rows().count(), 0);
2083
        assert_eq!(image.pixels().count(), 0);
2084
    }
2085
2086
    #[test]
2087
    fn nonzero_width_zero_height() {
2088
        let mut image = RgbImage::new(2, 0);
2089
2090
        assert_eq!(image.rows_mut().count(), 0);
2091
        assert_eq!(image.pixels_mut().count(), 0);
2092
        assert_eq!(image.rows().count(), 0);
2093
        assert_eq!(image.pixels().count(), 0);
2094
    }
2095
2096
    #[test]
2097
    fn pixels_on_large_buffer() {
2098
        let mut image = RgbImage::from_raw(1, 1, vec![0; 6]).unwrap();
2099
2100
        assert_eq!(image.pixels().count(), 1);
2101
        assert_eq!(image.enumerate_pixels().count(), 1);
2102
        assert_eq!(image.pixels_mut().count(), 1);
2103
        assert_eq!(image.enumerate_pixels_mut().count(), 1);
2104
2105
        assert_eq!(image.rows().count(), 1);
2106
        assert_eq!(image.rows_mut().count(), 1);
2107
    }
2108
2109
    #[test]
2110
    fn default() {
2111
        let image = ImageBuffer::<Rgb<u8>, Vec<u8>>::default();
2112
        assert_eq!(image.dimensions(), (0, 0));
2113
    }
2114
2115
    #[test]
2116
    #[rustfmt::skip]
2117
    fn test_image_buffer_copy_within_oob() {
2118
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, vec![0u8; 16]).unwrap();
2119
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 5, height: 4 }, 0, 0));
2120
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 5 }, 0, 0));
2121
        assert!(!image.copy_within(Rect { x: 1, y: 0, width: 4, height: 4 }, 0, 0));
2122
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 1, 0));
2123
        assert!(!image.copy_within(Rect { x: 0, y: 1, width: 4, height: 4 }, 0, 0));
2124
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 0, 1));
2125
        assert!(!image.copy_within(Rect { x: 1, y: 1, width: 4, height: 4 }, 0, 0));
2126
    }
2127
2128
    #[test]
2129
    fn test_image_buffer_copy_within_tl() {
2130
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
2131
        let expected = [0, 1, 2, 3, 4, 0, 1, 2, 8, 4, 5, 6, 12, 8, 9, 10];
2132
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
2133
        assert!(image.copy_within(
2134
            Rect {
2135
                x: 0,
2136
                y: 0,
2137
                width: 3,
2138
                height: 3
2139
            },
2140
            1,
2141
            1
2142
        ));
2143
        assert_eq!(&image.into_raw(), &expected);
2144
    }
2145
2146
    #[test]
2147
    fn test_image_buffer_copy_within_tr() {
2148
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
2149
        let expected = [0, 1, 2, 3, 1, 2, 3, 7, 5, 6, 7, 11, 9, 10, 11, 15];
2150
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
2151
        assert!(image.copy_within(
2152
            Rect {
2153
                x: 1,
2154
                y: 0,
2155
                width: 3,
2156
                height: 3
2157
            },
2158
            0,
2159
            1
2160
        ));
2161
        assert_eq!(&image.into_raw(), &expected);
2162
    }
2163
2164
    #[test]
2165
    fn test_image_buffer_copy_within_bl() {
2166
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
2167
        let expected = [0, 4, 5, 6, 4, 8, 9, 10, 8, 12, 13, 14, 12, 13, 14, 15];
2168
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
2169
        assert!(image.copy_within(
2170
            Rect {
2171
                x: 0,
2172
                y: 1,
2173
                width: 3,
2174
                height: 3
2175
            },
2176
            1,
2177
            0
2178
        ));
2179
        assert_eq!(&image.into_raw(), &expected);
2180
    }
2181
2182
    #[test]
2183
    fn test_image_buffer_copy_within_br() {
2184
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
2185
        let expected = [5, 6, 7, 3, 9, 10, 11, 7, 13, 14, 15, 11, 12, 13, 14, 15];
2186
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
2187
        assert!(image.copy_within(
2188
            Rect {
2189
                x: 1,
2190
                y: 1,
2191
                width: 3,
2192
                height: 3
2193
            },
2194
            0,
2195
            0
2196
        ));
2197
        assert_eq!(&image.into_raw(), &expected);
2198
    }
2199
2200
    #[test]
2201
    #[cfg(feature = "png")]
2202
    fn write_to_with_large_buffer() {
2203
        // A buffer of 1 pixel, padded to 4 bytes as would be common in, e.g. BMP.
2204
2205
        let img: GrayImage = ImageBuffer::from_raw(1, 1, vec![0u8; 4]).unwrap();
2206
        let mut buffer = std::io::Cursor::new(vec![]);
2207
        assert!(img.write_to(&mut buffer, ImageFormat::Png).is_ok());
2208
    }
2209
2210
    #[test]
2211
    fn exact_size_iter_size_hint() {
2212
        // The docs for `std::iter::ExactSizeIterator` requires that the implementation of
2213
        // `size_hint` on the iterator returns the same value as the `len` implementation.
2214
2215
        // This test should work for any size image.
2216
        const N: u32 = 10;
2217
2218
        let mut image = RgbImage::from_raw(N, N, vec![0; (N * N * 3) as usize]).unwrap();
2219
2220
        let iter = image.pixels();
2221
        let exact_len = ExactSizeIterator::len(&iter);
2222
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2223
2224
        let iter = image.pixels_mut();
2225
        let exact_len = ExactSizeIterator::len(&iter);
2226
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2227
2228
        let iter = image.rows();
2229
        let exact_len = ExactSizeIterator::len(&iter);
2230
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2231
2232
        let iter = image.rows_mut();
2233
        let exact_len = ExactSizeIterator::len(&iter);
2234
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2235
2236
        let iter = image.enumerate_pixels();
2237
        let exact_len = ExactSizeIterator::len(&iter);
2238
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2239
2240
        let iter = image.enumerate_rows();
2241
        let exact_len = ExactSizeIterator::len(&iter);
2242
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2243
2244
        let iter = image.enumerate_pixels_mut();
2245
        let exact_len = ExactSizeIterator::len(&iter);
2246
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2247
2248
        let iter = image.enumerate_rows_mut();
2249
        let exact_len = ExactSizeIterator::len(&iter);
2250
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2251
    }
2252
2253
    #[test]
2254
    fn color_conversion() {
2255
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgb([255, 0, 0]));
2256
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2257
2258
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2259
        source.set_transfer_function(Cicp::SRGB.transfer);
2260
2261
        target.set_rgb_primaries(Cicp::DISPLAY_P3.primaries);
2262
        target.set_transfer_function(Cicp::DISPLAY_P3.transfer);
2263
2264
        let result = target.copy_from_color_space(&source, Default::default());
2265
2266
        assert!(result.is_ok(), "{result:?}");
2267
        assert_eq!(target[(0, 0)], Rgba([234u8, 51, 35, 255]));
2268
    }
2269
2270
    #[test]
2271
    fn gray_conversions() {
2272
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Luma([255u8]));
2273
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2274
2275
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2276
        source.set_transfer_function(Cicp::SRGB.transfer);
2277
2278
        target.set_rgb_primaries(Cicp::SRGB.primaries);
2279
        target.set_transfer_function(Cicp::SRGB.transfer);
2280
2281
        let result = target.copy_from_color_space(&source, Default::default());
2282
2283
        assert!(result.is_ok(), "{result:?}");
2284
        assert_eq!(target[(0, 0)], Rgba([u8::MAX; 4]));
2285
    }
2286
2287
    #[test]
2288
    fn rgb_to_gray_conversion() {
2289
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgb([128u8; 3]));
2290
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Luma(Default::default()));
2291
2292
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2293
        source.set_transfer_function(Cicp::SRGB.transfer);
2294
2295
        target.set_rgb_primaries(Cicp::SRGB.primaries);
2296
        target.set_transfer_function(Cicp::SRGB.transfer);
2297
2298
        let result = target.copy_from_color_space(&source, Default::default());
2299
2300
        assert!(result.is_ok(), "{result:?}");
2301
        assert_eq!(target[(0, 0)], Luma([128u8]));
2302
    }
2303
2304
    #[test]
2305
    fn apply_color() {
2306
        let mut buffer = ImageBuffer::from_fn(128, 128, |_, _| Rgb([255u8, 0, 0]));
2307
2308
        buffer.set_rgb_primaries(Cicp::SRGB.primaries);
2309
        buffer.set_transfer_function(Cicp::SRGB.transfer);
2310
2311
        buffer
2312
            .apply_color_space(Cicp::DISPLAY_P3, Default::default())
2313
            .expect("supported transform");
2314
2315
        buffer.pixels().for_each(|&p| {
2316
            assert_eq!(p, Rgb([234u8, 51, 35]));
2317
        });
2318
    }
2319
2320
    #[test]
2321
    fn to_color() {
2322
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgba([255u8, 0, 0, 255]));
2323
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2324
        source.set_transfer_function(Cicp::SRGB.transfer);
2325
2326
        let target = source
2327
            .to_color_space::<Rgb<u8>>(Cicp::DISPLAY_P3, Default::default())
2328
            .expect("supported transform");
2329
2330
        assert_eq!(target[(0, 0)], Rgb([234u8, 51, 35]));
2331
    }
2332
2333
    #[test]
2334
    fn transformation_mismatch() {
2335
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Luma([255u8]));
2336
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2337
2338
        source.set_color_space(Cicp::SRGB).unwrap();
2339
        target.set_color_space(Cicp::DISPLAY_P3).unwrap();
2340
2341
        let options = super::ConvertColorOptions {
2342
            transform: CicpTransform::new(Cicp::SRGB, Cicp::SRGB),
2343
            ..super::ConvertColorOptions::default()
2344
        };
2345
2346
        let result = target.copy_from_color_space(&source, options);
2347
        assert!(matches!(result, Err(crate::ImageError::Parameter(_))));
2348
    }
2349
2350
    #[test]
2351
    fn pleasant_debug() {
2352
        use super::*;
2353
2354
        assert_eq!(
2355
            format!("{:?}", GrayImage::new(100, 100)),
2356
            "ImageBuffer::<Luma<u8>, _> { width: 100, height: 100, color: \"sRGB\" }"
2357
        );
2358
        assert_eq!(
2359
            format!("{:?}", GrayAlphaImage::new(100, 100)),
2360
            "ImageBuffer::<LumaA<u8>, _> { width: 100, height: 100, color: \"sRGB\" }"
2361
        );
2362
        assert_eq!(
2363
            format!("{:?}", RgbImage::new(100, 100)),
2364
            "ImageBuffer::<Rgb<u8>, _> { width: 100, height: 100, color: \"sRGB\" }"
2365
        );
2366
        assert_eq!(
2367
            format!("{:?}", RgbaImage::new(100, 100)),
2368
            "ImageBuffer::<Rgba<u8>, _> { width: 100, height: 100, color: \"sRGB\" }"
2369
        );
2370
        assert_eq!(
2371
            format!("{:?}", Gray16Image::new(100, 100)),
2372
            "ImageBuffer::<Luma<u16>, _> { width: 100, height: 100, color: \"sRGB\" }"
2373
        );
2374
        assert_eq!(
2375
            format!("{:?}", GrayAlpha16Image::new(100, 100)),
2376
            "ImageBuffer::<LumaA<u16>, _> { width: 100, height: 100, color: \"sRGB\" }"
2377
        );
2378
        assert_eq!(
2379
            format!("{:?}", Rgb16Image::new(100, 100)),
2380
            "ImageBuffer::<Rgb<u16>, _> { width: 100, height: 100, color: \"sRGB\" }"
2381
        );
2382
        assert_eq!(
2383
            format!("{:?}", Rgba16Image::new(100, 100)),
2384
            "ImageBuffer::<Rgba<u16>, _> { width: 100, height: 100, color: \"sRGB\" }"
2385
        );
2386
        assert_eq!(
2387
            format!("{:?}", Rgb32FImage::new(100, 100)),
2388
            "ImageBuffer::<Rgb<f32>, _> { width: 100, height: 100, color: \"sRGB\" }"
2389
        );
2390
        assert_eq!(
2391
            format!("{:?}", Rgba32FImage::new(100, 100)),
2392
            "ImageBuffer::<Rgba<f32>, _> { width: 100, height: 100, color: \"sRGB\" }"
2393
        );
2394
2395
        let gray8 = ImageBuffer::from_pixel(16, 16, Luma([255u8]));
2396
        assert_eq!(
2397
            format!("{:?}", gray8),
2398
            "ImageBuffer::<Luma<u8>, _> { width: 16, height: 16, color: \"sRGB\" }"
2399
        );
2400
        assert_eq!(
2401
            format!("{:#?}", gray8),
2402
           "ImageBuffer::<Luma<u8>, _> {\n    width: 16,\n    height: 16,\n    color: \"sRGB\",\n}"
2403
        );
2404
2405
        let mut rgba32f = ImageBuffer::from_pixel(16, 16, Rgba([0.0_f32; 4]));
2406
        rgba32f.set_color_space(Cicp::DISPLAY_P3).unwrap();
2407
        assert_eq!(
2408
            format!("{:?}", rgba32f),
2409
            "ImageBuffer::<Rgba<f32>, _> { width: 16, height: 16, color: \"Display P3\" }"
2410
        );
2411
2412
        let mut custom_color_space = ImageBuffer::from_pixel(16, 16, Rgba([0.0_f32; 4]));
2413
        custom_color_space
2414
            .set_color_space(Cicp {
2415
                primaries: CicpColorPrimaries::Rgb240m,
2416
                transfer: CicpTransferCharacteristics::LogSqrt,
2417
                matrix: CicpMatrixCoefficients::Identity,
2418
                full_range: CicpVideoFullRangeFlag::FullRange,
2419
            })
2420
            .unwrap();
2421
        assert_eq!(
2422
            format!("{:?}", custom_color_space),
2423
            "ImageBuffer::<Rgba<f32>, _> { width: 16, height: 16, color: CicpRgb { primaries: Rgb240m, transfer: LogSqrt, luminance: NonConstant } }"
2424
        );
2425
    }
2426
2427
    /// We specialize copy_from on types that provide `as_samples` so test that.
2428
    #[test]
2429
    fn copy_from_subimage_to_middle() {
2430
        let mut source = RgbImage::new(16, 16);
2431
        let mut target = RgbImage::new(16, 16);
2432
2433
        source.put_pixel(8, 8, Rgb([255, 8, 8]));
2434
        source.put_pixel(9, 8, Rgb([255, 9, 8]));
2435
        source.put_pixel(9, 9, Rgb([255, 9, 9]));
2436
2437
        let view = source.view(Rect::from_xy_ranges(8..10, 8..10));
2438
        assert!(target.copy_from(&*view, 4, 4).is_ok());
2439
2440
        // Check the pixel was copied.
2441
        assert_eq!(*target.get_pixel(4, 4), Rgb([255, 8, 8]));
2442
        assert_eq!(*target.get_pixel(5, 4), Rgb([255, 9, 8]));
2443
        assert_eq!(*target.get_pixel(5, 5), Rgb([255, 9, 9]));
2444
2445
        // Check that were the only copied pixel.
2446
        assert_eq!(
2447
            target.iter().copied().map(usize::from).sum::<usize>(),
2448
            3 * (255 + 8 + 9)
2449
        );
2450
    }
2451
2452
    #[test]
2453
    fn copy_from_band() {
2454
        let source = RgbImage::from_fn(16, 8, |x, y| Rgb([x as u8, y as u8, 0]));
2455
        let mut target = RgbImage::new(16, 16);
2456
2457
        assert!(target.copy_from(&source, 0, 4).is_ok());
2458
2459
        let lhs = source.chunks_exact(48);
2460
        let rhs = target.chunks_exact(48).skip(4).take(8);
2461
2462
        assert!(lhs.eq(rhs));
2463
    }
2464
2465
    #[test]
2466
    fn copy_from_pixel() {
2467
        let bg = Rgb([255, 0, 128]);
2468
        let samples = crate::flat::FlatSamples::with_monocolor(&bg, 4, 4);
2469
        let source = samples.as_view().unwrap();
2470
2471
        let mut target = RgbImage::new(16, 16);
2472
        assert!(target.copy_from(&source, 4, 4).is_ok());
2473
2474
        for i in 4..8 {
2475
            for j in 4..8 {
2476
                assert_eq!(*target.get_pixel(i, j), bg);
2477
            }
2478
        }
2479
2480
        assert_eq!(
2481
            target.iter().copied().map(usize::from).sum::<usize>(),
2482
            16 * (255 + 128)
2483
        );
2484
    }
2485
2486
    #[test]
2487
    fn copy_from_strided() {
2488
        #[rustfmt::skip]
2489
        let sample_data = [
2490
            1, 0xff, 0, 0, 2, 0xff,
2491
            3, 0xff, 0, 0, 4, 0xff
2492
        ];
2493
2494
        let samples = crate::flat::FlatSamples {
2495
            samples: &sample_data,
2496
            layout: crate::flat::SampleLayout {
2497
                channels: 2,
2498
                channel_stride: 1,
2499
                width: 2,
2500
                width_stride: 4,
2501
                height: 2,
2502
                height_stride: 6,
2503
            },
2504
            color_hint: None,
2505
        };
2506
2507
        let source = samples.as_view::<LumaA<u8>>().unwrap();
2508
        let mut target = crate::GrayAlphaImage::new(16, 16);
2509
        assert!(target.copy_from(&source, 4, 4).is_ok());
2510
2511
        assert_eq!(*target.get_pixel(4, 4), LumaA([1, 0xff]));
2512
        assert_eq!(*target.get_pixel(5, 4), LumaA([2, 0xff]));
2513
        assert_eq!(*target.get_pixel(4, 5), LumaA([3, 0xff]));
2514
        assert_eq!(*target.get_pixel(5, 5), LumaA([4, 0xff]));
2515
2516
        assert_eq!(
2517
            target.iter().copied().map(usize::from).sum::<usize>(),
2518
            sample_data.iter().copied().map(usize::from).sum::<usize>(),
2519
        );
2520
    }
2521
2522
    #[test]
2523
    fn copy_from_strided_subimage() {
2524
        #[rustfmt::skip]
2525
        let sample_data = [
2526
            1, 0xff, 0, 0, 2, 0xff,
2527
            3, 0xff, 0, 0, 4, 0xff
2528
        ];
2529
2530
        let samples = crate::flat::FlatSamples {
2531
            samples: &sample_data,
2532
            layout: crate::flat::SampleLayout {
2533
                channels: 2,
2534
                channel_stride: 1,
2535
                width: 2,
2536
                width_stride: 4,
2537
                height: 2,
2538
                height_stride: 6,
2539
            },
2540
            color_hint: None,
2541
        };
2542
2543
        let view = samples.as_view::<LumaA<u8>>().unwrap();
2544
        let source = view.view(Rect::from_xy_ranges(1..2, 0..2));
2545
2546
        let mut target = crate::GrayAlphaImage::new(16, 16);
2547
        assert!(target.copy_from(&*source, 4, 4).is_ok());
2548
2549
        assert_eq!(*target.get_pixel(4, 4), LumaA([2, 0xff]));
2550
        assert_eq!(*target.get_pixel(4, 5), LumaA([4, 0xff]));
2551
2552
        assert_eq!(
2553
            target.iter().copied().map(usize::from).sum::<usize>(),
2554
            2usize + 0xff + 4 + 0xff
2555
        );
2556
    }
2557
2558
    #[test]
2559
    fn copy_from_subimage_subimage() {
2560
        let mut source = RgbImage::new(16, 16);
2561
        let mut target = RgbImage::new(16, 16);
2562
2563
        source.put_pixel(8, 8, Rgb([255, 8, 8]));
2564
        source.put_pixel(9, 8, Rgb([255, 9, 8]));
2565
        source.put_pixel(9, 9, Rgb([255, 9, 9]));
2566
2567
        let view = source.view(Rect::from_xy_ranges(8..10, 8..10));
2568
        let view = view.view(Rect::from_xy_ranges(1..2, 0..1));
2569
        assert!(target.copy_from(&*view, 4, 4).is_ok());
2570
2571
        // Check the pixel was copied.
2572
        assert_eq!(*target.get_pixel(4, 4), Rgb([255, 9, 8]));
2573
2574
        // Check that was the only copied pixel.
2575
        assert_eq!(
2576
            target.iter().copied().map(usize::from).sum::<usize>(),
2577
            255 + 9 + 8
2578
        );
2579
    }
2580
}
2581
2582
#[cfg(test)]
2583
#[cfg(feature = "benchmarks")]
2584
mod benchmarks {
2585
    use super::{ConvertBuffer, GrayImage, ImageBuffer, Pixel, RgbImage};
2586
2587
    #[bench]
2588
    fn conversion(b: &mut test::Bencher) {
2589
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2590
        for p in a.pixels_mut() {
2591
            let rgb = p.channels_mut();
2592
            rgb[0] = 255;
2593
            rgb[1] = 23;
2594
            rgb[2] = 42;
2595
        }
2596
2597
        assert!(a.data[0] != 0);
2598
        b.iter(|| {
2599
            let b: GrayImage = a.convert();
2600
            assert!(0 != b.data[0]);
2601
            assert!(a.data[0] != b.data[0]);
2602
            test::black_box(b);
2603
        });
2604
        b.bytes = 1000 * 1000 * 3;
2605
    }
2606
2607
    #[bench]
2608
    fn image_access_row_by_row(b: &mut test::Bencher) {
2609
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2610
        for p in a.pixels_mut() {
2611
            let rgb = p.channels_mut();
2612
            rgb[0] = 255;
2613
            rgb[1] = 23;
2614
            rgb[2] = 42;
2615
        }
2616
2617
        b.iter(move || {
2618
            let image: &RgbImage = test::black_box(&a);
2619
            let mut sum: usize = 0;
2620
            for y in 0..1000 {
2621
                for x in 0..1000 {
2622
                    let pixel = image.get_pixel(x, y);
2623
                    sum = sum.wrapping_add(pixel[0] as usize);
2624
                    sum = sum.wrapping_add(pixel[1] as usize);
2625
                    sum = sum.wrapping_add(pixel[2] as usize);
2626
                }
2627
            }
2628
            test::black_box(sum)
2629
        });
2630
2631
        b.bytes = 1000 * 1000 * 3;
2632
    }
2633
2634
    #[bench]
2635
    fn image_access_col_by_col(b: &mut test::Bencher) {
2636
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2637
        for p in a.pixels_mut() {
2638
            let rgb = p.channels_mut();
2639
            rgb[0] = 255;
2640
            rgb[1] = 23;
2641
            rgb[2] = 42;
2642
        }
2643
2644
        b.iter(move || {
2645
            let image: &RgbImage = test::black_box(&a);
2646
            let mut sum: usize = 0;
2647
            for x in 0..1000 {
2648
                for y in 0..1000 {
2649
                    let pixel = image.get_pixel(x, y);
2650
                    sum = sum.wrapping_add(pixel[0] as usize);
2651
                    sum = sum.wrapping_add(pixel[1] as usize);
2652
                    sum = sum.wrapping_add(pixel[2] as usize);
2653
                }
2654
            }
2655
            test::black_box(sum)
2656
        });
2657
2658
        b.bytes = 1000 * 1000 * 3;
2659
    }
2660
}