Coverage Report

Created: 2025-11-24 07:30

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};
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::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::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::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
4.17G
    fn next(&mut self) -> Option<&'a mut P> {
104
4.17G
        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
4.17G
        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
4.17G
    }
<image::images::buffer::PixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
103
4.17G
    fn next(&mut self) -> Option<&'a mut P> {
104
4.17G
        self.chunks.next().map(|v| <P as Pixel>::from_slice_mut(v))
105
4.17G
    }
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
4.17G
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
491
4.17G
        if self.x >= self.width {
492
1.25M
            self.x = 0;
493
1.25M
            self.y += 1;
494
4.17G
        }
495
4.17G
        let (x, y) = (self.x, self.y);
496
4.17G
        self.x += 1;
497
4.17G
        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
4.17G
        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
4.17G
    }
<image::images::buffer::EnumeratePixelsMut<image::color::Rgba<u8>> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
490
4.17G
    fn next(&mut self) -> Option<(u32, u32, &'a mut P)> {
491
4.17G
        if self.x >= self.width {
492
1.25M
            self.x = 0;
493
1.25M
            self.y += 1;
494
4.17G
        }
495
4.17G
        let (x, y) = (self.x, self.y);
496
4.17G
        self.x += 1;
497
4.17G
        self.pixels.next().map(|p| (x, y, p))
498
4.17G
    }
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(Debug, 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
10.5k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
10.5k
        if Self::check_image_fits(width, height, buf.len()) {
682
10.5k
            Some(ImageBuffer {
683
10.5k
                data: buf,
684
10.5k
                width,
685
10.5k
                height,
686
10.5k
                color: Cicp::SRGB.into_rgb(),
687
10.5k
                _phantom: PhantomData,
688
10.5k
            })
689
        } else {
690
0
            None
691
        }
692
10.5k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::from_raw
Line
Count
Source
680
263
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
263
        if Self::check_image_fits(width, height, buf.len()) {
682
263
            Some(ImageBuffer {
683
263
                data: buf,
684
263
                width,
685
263
                height,
686
263
                color: Cicp::SRGB.into_rgb(),
687
263
                _phantom: PhantomData,
688
263
            })
689
        } else {
690
0
            None
691
        }
692
263
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
2.42k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
2.42k
        if Self::check_image_fits(width, height, buf.len()) {
682
2.42k
            Some(ImageBuffer {
683
2.42k
                data: buf,
684
2.42k
                width,
685
2.42k
                height,
686
2.42k
                color: Cicp::SRGB.into_rgb(),
687
2.42k
                _phantom: PhantomData,
688
2.42k
            })
689
        } else {
690
0
            None
691
        }
692
2.42k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
104
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
104
        if Self::check_image_fits(width, height, buf.len()) {
682
104
            Some(ImageBuffer {
683
104
                data: buf,
684
104
                width,
685
104
                height,
686
104
                color: Cicp::SRGB.into_rgb(),
687
104
                _phantom: PhantomData,
688
104
            })
689
        } else {
690
0
            None
691
        }
692
104
    }
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
3.18k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
3.18k
        if Self::check_image_fits(width, height, buf.len()) {
682
3.18k
            Some(ImageBuffer {
683
3.18k
                data: buf,
684
3.18k
                width,
685
3.18k
                height,
686
3.18k
                color: Cicp::SRGB.into_rgb(),
687
3.18k
                _phantom: PhantomData,
688
3.18k
            })
689
        } else {
690
0
            None
691
        }
692
3.18k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
168
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
168
        if Self::check_image_fits(width, height, buf.len()) {
682
168
            Some(ImageBuffer {
683
168
                data: buf,
684
168
                width,
685
168
                height,
686
168
                color: Cicp::SRGB.into_rgb(),
687
168
                _phantom: PhantomData,
688
168
            })
689
        } else {
690
0
            None
691
        }
692
168
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::from_raw
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::from_raw
Line
Count
Source
680
4.25k
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
4.25k
        if Self::check_image_fits(width, height, buf.len()) {
682
4.25k
            Some(ImageBuffer {
683
4.25k
                data: buf,
684
4.25k
                width,
685
4.25k
                height,
686
4.25k
                color: Cicp::SRGB.into_rgb(),
687
4.25k
                _phantom: PhantomData,
688
4.25k
            })
689
        } else {
690
0
            None
691
        }
692
4.25k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::from_raw
Line
Count
Source
680
91
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
91
        if Self::check_image_fits(width, height, buf.len()) {
682
91
            Some(ImageBuffer {
683
91
                data: buf,
684
91
                width,
685
91
                height,
686
91
                color: Cicp::SRGB.into_rgb(),
687
91
                _phantom: PhantomData,
688
91
            })
689
        } else {
690
0
            None
691
        }
692
91
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
30
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
30
        if Self::check_image_fits(width, height, buf.len()) {
682
30
            Some(ImageBuffer {
683
30
                data: buf,
684
30
                width,
685
30
                height,
686
30
                color: Cicp::SRGB.into_rgb(),
687
30
                _phantom: PhantomData,
688
30
            })
689
        } else {
690
0
            None
691
        }
692
30
    }
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
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
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::from_raw
Line
Count
Source
680
24
    pub fn from_raw(width: u32, height: u32, buf: Container) -> Option<ImageBuffer<P, Container>> {
681
24
        if Self::check_image_fits(width, height, buf.len()) {
682
24
            Some(ImageBuffer {
683
24
                data: buf,
684
24
                width,
685
24
                height,
686
24
                color: Cicp::SRGB.into_rgb(),
687
24
                _phantom: PhantomData,
688
24
            })
689
        } else {
690
0
            None
691
        }
692
24
    }
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.62k
    pub fn into_raw(self) -> Container {
696
3.62k
        self.data
697
3.62k
    }
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.62k
    pub fn into_raw(self) -> Container {
696
3.62k
        self.data
697
3.62k
    }
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.81k
    pub fn width(&self) -> u32 {
711
1.81k
        self.width
712
1.81k
    }
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.81k
    pub fn width(&self) -> u32 {
711
1.81k
        self.width
712
1.81k
    }
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.81k
    pub fn height(&self) -> u32 {
716
1.81k
        self.height
717
1.81k
    }
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.81k
    pub fn height(&self) -> u32 {
716
1.81k
        self.height
717
1.81k
    }
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.81k
    pub(crate) fn inner_pixels(&self) -> &[P::Subpixel] {
721
1.81k
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
722
1.81k
        &self.data[..len]
723
1.81k
    }
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.81k
    pub(crate) fn inner_pixels(&self) -> &[P::Subpixel] {
721
1.81k
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
722
1.81k
        &self.data[..len]
723
1.81k
    }
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.7M
    pub fn get_pixel(&self, x: u32, y: u32) -> &P {
777
11.7M
        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.7M
            Some(pixel_indices) => <P as Pixel>::from_slice(&self.data[pixel_indices]),
784
        }
785
11.7M
    }
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.7M
    pub fn get_pixel(&self, x: u32, y: u32) -> &P {
777
11.7M
        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.7M
            Some(pixel_indices) => <P as Pixel>::from_slice(&self.data[pixel_indices]),
784
        }
785
11.7M
    }
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
10.5k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
10.5k
        let checked_len = Self::image_buffer_len(width, height);
811
10.5k
        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
263
        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
2.42k
        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
104
        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
3.18k
        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
168
        checked_len.is_some_and(|min_len| min_len <= len)
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::check_image_fits::{closure#0}
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::check_image_fits::{closure#0}
Line
Count
Source
811
4.25k
        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
91
        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
30
        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
35
        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
24
        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
10.5k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::check_image_fits
Line
Count
Source
809
263
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
263
        let checked_len = Self::image_buffer_len(width, height);
811
263
        checked_len.is_some_and(|min_len| min_len <= len)
812
263
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
2.42k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
2.42k
        let checked_len = Self::image_buffer_len(width, height);
811
2.42k
        checked_len.is_some_and(|min_len| min_len <= len)
812
2.42k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
104
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
104
        let checked_len = Self::image_buffer_len(width, height);
811
104
        checked_len.is_some_and(|min_len| min_len <= len)
812
104
    }
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
3.18k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
3.18k
        let checked_len = Self::image_buffer_len(width, height);
811
3.18k
        checked_len.is_some_and(|min_len| min_len <= len)
812
3.18k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
168
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
168
        let checked_len = Self::image_buffer_len(width, height);
811
168
        checked_len.is_some_and(|min_len| min_len <= len)
812
168
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::check_image_fits
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::check_image_fits
Line
Count
Source
809
4.25k
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
4.25k
        let checked_len = Self::image_buffer_len(width, height);
811
4.25k
        checked_len.is_some_and(|min_len| min_len <= len)
812
4.25k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::check_image_fits
Line
Count
Source
809
91
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
91
        let checked_len = Self::image_buffer_len(width, height);
811
91
        checked_len.is_some_and(|min_len| min_len <= len)
812
91
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
30
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
30
        let checked_len = Self::image_buffer_len(width, height);
811
30
        checked_len.is_some_and(|min_len| min_len <= len)
812
30
    }
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
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
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::check_image_fits
Line
Count
Source
809
24
    fn check_image_fits(width: u32, height: u32, len: usize) -> bool {
810
24
        let checked_len = Self::image_buffer_len(width, height);
811
24
        checked_len.is_some_and(|min_len| min_len <= len)
812
24
    }
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
12.4k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
12.4k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
12.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
263
            .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
2.42k
            .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
104
            .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
3.18k
            .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
168
            .and_then(|size| size.checked_mul(width as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#0}
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#0}
Line
Count
Source
816
6.06k
            .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
182
            .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
30
            .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
35
            .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
24
            .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
12.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
263
            .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
2.42k
            .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
104
            .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
3.18k
            .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
168
            .and_then(|size| size.checked_mul(height as usize))
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len::{closure#1}
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len::{closure#1}
Line
Count
Source
817
6.06k
            .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
182
            .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
30
            .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
35
            .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
24
            .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
12.4k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
Line
Count
Source
814
263
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
263
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
263
            .and_then(|size| size.checked_mul(width as usize))
817
263
            .and_then(|size| size.checked_mul(height as usize))
818
263
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
2.42k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
2.42k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
2.42k
            .and_then(|size| size.checked_mul(width as usize))
817
2.42k
            .and_then(|size| size.checked_mul(height as usize))
818
2.42k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
104
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
104
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
104
            .and_then(|size| size.checked_mul(width as usize))
817
104
            .and_then(|size| size.checked_mul(height as usize))
818
104
    }
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
3.18k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
3.18k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
3.18k
            .and_then(|size| size.checked_mul(width as usize))
817
3.18k
            .and_then(|size| size.checked_mul(height as usize))
818
3.18k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
168
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
168
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
168
            .and_then(|size| size.checked_mul(width as usize))
817
168
            .and_then(|size| size.checked_mul(height as usize))
818
168
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::image_buffer_len
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::image_buffer_len
Line
Count
Source
814
6.06k
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
6.06k
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
6.06k
            .and_then(|size| size.checked_mul(width as usize))
817
6.06k
            .and_then(|size| size.checked_mul(height as usize))
818
6.06k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, &mut [u8]>>::image_buffer_len
Line
Count
Source
814
182
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
182
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
182
            .and_then(|size| size.checked_mul(width as usize))
817
182
            .and_then(|size| size.checked_mul(height as usize))
818
182
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
30
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
30
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
30
            .and_then(|size| size.checked_mul(width as usize))
817
30
            .and_then(|size| size.checked_mul(height as usize))
818
30
    }
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
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
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::image_buffer_len
Line
Count
Source
814
24
    fn image_buffer_len(width: u32, height: u32) -> Option<usize> {
815
24
        Some(<P as Pixel>::CHANNEL_COUNT as usize)
816
24
            .and_then(|size| size.checked_mul(width as usize))
817
24
            .and_then(|size| size.checked_mul(height as usize))
818
24
    }
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.7M
    fn pixel_indices(&self, x: u32, y: u32) -> Option<Range<usize>> {
822
11.7M
        if x >= self.width || y >= self.height {
823
0
            return None;
824
11.7M
        }
825
826
11.7M
        Some(self.pixel_indices_unchecked(x, y))
827
11.7M
    }
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.7M
    fn pixel_indices(&self, x: u32, y: u32) -> Option<Range<usize>> {
822
11.7M
        if x >= self.width || y >= self.height {
823
0
            return None;
824
11.7M
        }
825
826
11.7M
        Some(self.pixel_indices_unchecked(x, y))
827
11.7M
    }
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.7M
    fn pixel_indices_unchecked(&self, x: u32, y: u32) -> Range<usize> {
831
11.7M
        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.7M
        let min_index = (y as usize * self.width as usize + x as usize) * no_channels;
834
11.7M
        min_index..min_index + no_channels
835
11.7M
    }
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.7M
    fn pixel_indices_unchecked(&self, x: u32, y: u32) -> Range<usize> {
831
11.7M
        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.7M
        let min_index = (y as usize * self.width as usize + x as usize) * no_channels;
834
11.7M
        min_index..min_index + no_channels
835
11.7M
    }
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
    where
867
0
        Container: AsRef<[P::Subpixel]>,
868
    {
869
0
        let layout = self.sample_layout();
870
0
        FlatSamples {
871
0
            samples: self.data.as_ref(),
872
0
            layout,
873
0
            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
874
0
        }
875
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
876
877
    /// Return a mutable view on the raw sample buffer.
878
    ///
879
    /// See [`into_flat_samples`](#method.into_flat_samples) for more details.
880
0
    pub fn as_flat_samples_mut(&mut self) -> FlatSamples<&mut [P::Subpixel]>
881
0
    where
882
0
        Container: AsMut<[P::Subpixel]>,
883
    {
884
0
        let layout = self.sample_layout();
885
0
        FlatSamples {
886
0
            samples: self.data.as_mut(),
887
0
            layout,
888
0
            color_hint: None, // TODO: the pixel type might contain P::COLOR_TYPE if it satisfies PixelWithColorType
889
0
        }
890
0
    }
891
}
892
893
impl<P, Container> ImageBuffer<P, Container>
894
where
895
    P: Pixel,
896
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
897
{
898
    // TODO: choose name under which to expose.
899
91
    pub(crate) fn inner_pixels_mut(&mut self) -> &mut [P::Subpixel] {
900
91
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
901
91
        &mut self.data[..len]
902
91
    }
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
899
91
    pub(crate) fn inner_pixels_mut(&mut self) -> &mut [P::Subpixel] {
900
91
        let len = Self::image_buffer_len(self.width, self.height).unwrap();
901
91
        &mut self.data[..len]
902
91
    }
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
903
904
    /// Returns an iterator over the mutable pixels of this image.
905
91
    pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> {
906
91
        PixelsMut {
907
91
            chunks: self
908
91
                .inner_pixels_mut()
909
91
                .chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
910
91
        }
911
91
    }
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
905
91
    pub fn pixels_mut(&mut self) -> PixelsMut<'_, P> {
906
91
        PixelsMut {
907
91
            chunks: self
908
91
                .inner_pixels_mut()
909
91
                .chunks_exact_mut(<P as Pixel>::CHANNEL_COUNT as usize),
910
91
        }
911
91
    }
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
912
913
    /// Returns an iterator over the mutable rows of this image.
914
    ///
915
    /// Only non-empty rows can be iterated in this manner. In particular the iterator will not
916
    /// yield any item when the width of the image is `0` or a pixel type without any channels is
917
    /// used. This ensures that its length can always be represented by `usize`.
918
0
    pub fn rows_mut(&mut self) -> RowsMut<'_, P> {
919
0
        RowsMut::with_image(&mut self.data, self.width, self.height)
920
0
    }
921
922
    /// Enumerates over the pixels of the image.
923
    /// The iterator yields the coordinates of each pixel
924
    /// along with a mutable reference to them.
925
91
    pub fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<'_, P> {
926
91
        let width = self.width;
927
91
        EnumeratePixelsMut {
928
91
            pixels: self.pixels_mut(),
929
91
            x: 0,
930
91
            y: 0,
931
91
            width,
932
91
        }
933
91
    }
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
925
91
    pub fn enumerate_pixels_mut(&mut self) -> EnumeratePixelsMut<'_, P> {
926
91
        let width = self.width;
927
91
        EnumeratePixelsMut {
928
91
            pixels: self.pixels_mut(),
929
91
            x: 0,
930
91
            y: 0,
931
91
            width,
932
91
        }
933
91
    }
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
934
935
    /// Enumerates over the rows of the image.
936
    /// The iterator yields the y-coordinate of each row
937
    /// along with a mutable reference to them.
938
0
    pub fn enumerate_rows_mut(&mut self) -> EnumerateRowsMut<'_, P> {
939
0
        let width = self.width;
940
0
        EnumerateRowsMut {
941
0
            rows: self.rows_mut(),
942
0
            y: 0,
943
0
            width,
944
0
        }
945
0
    }
946
947
    /// Gets a reference to the mutable pixel at location `(x, y)`
948
    ///
949
    /// # Panics
950
    ///
951
    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
952
    #[inline]
953
    #[track_caller]
954
0
    pub fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
955
0
        match self.pixel_indices(x, y) {
956
0
            None => panic!(
957
0
                "Image index {:?} out of bounds {:?}",
958
0
                (x, y),
959
0
                (self.width, self.height)
960
            ),
961
0
            Some(pixel_indices) => <P as Pixel>::from_slice_mut(&mut self.data[pixel_indices]),
962
        }
963
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
964
965
    /// Gets a reference to the mutable pixel at location `(x, y)` or returns
966
    /// `None` if the index is out of the bounds `(width, height)`.
967
0
    pub fn get_pixel_mut_checked(&mut self, x: u32, y: u32) -> Option<&mut P> {
968
0
        if x >= self.width {
969
0
            return None;
970
0
        }
971
0
        let num_channels = <P as Pixel>::CHANNEL_COUNT as usize;
972
0
        let i = (y as usize)
973
0
            .saturating_mul(self.width as usize)
974
0
            .saturating_add(x as usize)
975
0
            .saturating_mul(num_channels);
976
977
0
        self.data
978
0
            .get_mut(i..i.checked_add(num_channels)?)
979
0
            .map(|pixel_indices| <P as Pixel>::from_slice_mut(pixel_indices))
980
0
    }
981
982
    /// Puts a pixel at location `(x, y)`
983
    ///
984
    /// # Panics
985
    ///
986
    /// Panics if `(x, y)` is out of the bounds `(width, height)`.
987
    #[inline]
988
    #[track_caller]
989
0
    pub fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
990
0
        *self.get_pixel_mut(x, y) = pixel;
991
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
992
}
993
994
impl<P: Pixel, Container> ImageBuffer<P, Container> {
995
    /// Define the color space for the image.
996
    ///
997
    /// The color data is unchanged. Reinterprets the existing red, blue, green channels as points
998
    /// in the new set of primary colors, changing the apparent shade of pixels.
999
    ///
1000
    /// Note that the primaries also define a reference whitepoint When this buffer contains Luma
1001
    /// data, the luminance channel is interpreted as the `Y` channel of a related `YCbCr` color
1002
    /// space as if by a non-constant chromaticity derived matrix. That is, coefficients are *not*
1003
    /// applied in the linear RGB space but use encoded channel values. (In a color space with the
1004
    /// linear transfer function there is no difference).
1005
    ///
1006
    /// The default color space is [`Cicp::SRGB`].
1007
8.58k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
8.58k
        self.color.primaries = color;
1009
8.58k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_rgb_primaries
Line
Count
Source
1007
263
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
263
        self.color.primaries = color;
1009
263
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1007
2.42k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
2.42k
        self.color.primaries = color;
1009
2.42k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1007
104
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
104
        self.color.primaries = color;
1009
104
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1007
3.18k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
3.18k
        self.color.primaries = color;
1009
3.18k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1007
168
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
168
        self.color.primaries = color;
1009
168
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_rgb_primaries
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1007
2.35k
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
2.35k
        self.color.primaries = color;
1009
2.35k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1007
30
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
30
        self.color.primaries = color;
1009
30
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_rgb_primaries
Line
Count
Source
1007
35
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
35
        self.color.primaries = color;
1009
35
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_rgb_primaries
Line
Count
Source
1007
24
    pub fn set_rgb_primaries(&mut self, color: CicpColorPrimaries) {
1008
24
        self.color.primaries = color;
1009
24
    }
1010
1011
    /// Define the transfer function for the image.
1012
    ///
1013
    /// The color data is unchanged. Reinterprets all (non-alpha) components in the image,
1014
    /// potentially changing the apparent shade of pixels. Individual components are always
1015
    /// interpreted as encoded numbers. To denote numbers in a linear RGB space, use
1016
    /// [`CicpTransferCharacteristics::Linear`].
1017
    ///
1018
    /// The default color space is [`Cicp::SRGB`].
1019
8.58k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
8.58k
        self.color.transfer = tf;
1021
8.58k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<f32>, alloc::vec::Vec<f32>>>::set_transfer_function
Line
Count
Source
1019
263
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
263
        self.color.transfer = tf;
1021
263
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1019
2.42k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
2.42k
        self.color.transfer = tf;
1021
2.42k
    }
<image::images::buffer::ImageBuffer<image::color::Rgb<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1019
104
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
104
        self.color.transfer = tf;
1021
104
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1019
3.18k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
3.18k
        self.color.transfer = tf;
1021
3.18k
    }
<image::images::buffer::ImageBuffer<image::color::Luma<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1019
168
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
168
        self.color.transfer = tf;
1021
168
    }
Unexecuted instantiation: <image::images::buffer::ImageBuffer<image::color::Rgba<f32>, alloc::vec::Vec<f32>>>::set_transfer_function
<image::images::buffer::ImageBuffer<image::color::Rgba<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1019
2.35k
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
2.35k
        self.color.transfer = tf;
1021
2.35k
    }
<image::images::buffer::ImageBuffer<image::color::Rgba<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1019
30
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
30
        self.color.transfer = tf;
1021
30
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u8>, alloc::vec::Vec<u8>>>::set_transfer_function
Line
Count
Source
1019
35
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
35
        self.color.transfer = tf;
1021
35
    }
<image::images::buffer::ImageBuffer<image::color::LumaA<u16>, alloc::vec::Vec<u16>>>::set_transfer_function
Line
Count
Source
1019
24
    pub fn set_transfer_function(&mut self, tf: CicpTransferCharacteristics) {
1020
24
        self.color.transfer = tf;
1021
24
    }
1022
1023
    /// Get the Cicp encoding of this buffer's color data.
1024
0
    pub fn color_space(&self) -> Cicp {
1025
0
        self.color.into()
1026
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
1027
1028
    /// Set primaries and transfer characteristics from a Cicp color space.
1029
    ///
1030
    /// Returns an error if `cicp` uses features that are not support with an RGB color space, e.g.
1031
    /// a matrix or narrow range (studio encoding) channels.
1032
0
    pub fn set_color_space(&mut self, cicp: Cicp) -> ImageResult<()> {
1033
0
        self.color = cicp.try_into_rgb()?;
1034
0
        Ok(())
1035
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
1036
1037
0
    pub(crate) fn set_rgb_color_space(&mut self, color: CicpRgb) {
1038
0
        self.color = color;
1039
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
1040
}
1041
1042
impl<P, Container> ImageBuffer<P, Container>
1043
where
1044
    P: Pixel,
1045
    [P::Subpixel]: EncodableLayout,
1046
    Container: Deref<Target = [P::Subpixel]>,
1047
{
1048
    /// Saves the buffer to a file at the path specified.
1049
    ///
1050
    /// The image format is derived from the file extension.
1051
0
    pub fn save<Q>(&self, path: Q) -> ImageResult<()>
1052
0
    where
1053
0
        Q: AsRef<Path>,
1054
0
        P: PixelWithColorType,
1055
    {
1056
0
        save_buffer(
1057
0
            path,
1058
0
            self.inner_pixels().as_bytes(),
1059
0
            self.width(),
1060
0
            self.height(),
1061
            <P as PixelWithColorType>::COLOR_TYPE,
1062
        )
1063
0
    }
1064
}
1065
1066
impl<P, Container> ImageBuffer<P, Container>
1067
where
1068
    P: Pixel,
1069
    [P::Subpixel]: EncodableLayout,
1070
    Container: Deref<Target = [P::Subpixel]>,
1071
{
1072
    /// Saves the buffer to a file at the specified path in
1073
    /// the specified format.
1074
    ///
1075
    /// See [`save_buffer_with_format`](fn.save_buffer_with_format.html) for
1076
    /// supported types.
1077
0
    pub fn save_with_format<Q>(&self, path: Q, format: ImageFormat) -> ImageResult<()>
1078
0
    where
1079
0
        Q: AsRef<Path>,
1080
0
        P: PixelWithColorType,
1081
    {
1082
        // This is valid as the subpixel is u8.
1083
0
        save_buffer_with_format(
1084
0
            path,
1085
0
            self.inner_pixels().as_bytes(),
1086
0
            self.width(),
1087
0
            self.height(),
1088
            <P as PixelWithColorType>::COLOR_TYPE,
1089
0
            format,
1090
        )
1091
0
    }
1092
}
1093
1094
impl<P, Container> ImageBuffer<P, Container>
1095
where
1096
    P: Pixel,
1097
    [P::Subpixel]: EncodableLayout,
1098
    Container: Deref<Target = [P::Subpixel]>,
1099
{
1100
    /// Writes the buffer to a writer in the specified format.
1101
    ///
1102
    /// Assumes the writer is buffered. In most cases, you should wrap your writer in a `BufWriter`
1103
    /// for best performance.
1104
1.81k
    pub fn write_to<W>(&self, writer: &mut W, format: ImageFormat) -> ImageResult<()>
1105
1.81k
    where
1106
1.81k
        W: std::io::Write + std::io::Seek,
1107
1.81k
        P: PixelWithColorType,
1108
    {
1109
        // This is valid as the subpixel is u8.
1110
1.81k
        write_buffer_with_format(
1111
1.81k
            writer,
1112
1.81k
            self.inner_pixels().as_bytes(),
1113
1.81k
            self.width(),
1114
1.81k
            self.height(),
1115
            <P as PixelWithColorType>::COLOR_TYPE,
1116
1.81k
            format,
1117
        )
1118
1.81k
    }
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
1104
1.81k
    pub fn write_to<W>(&self, writer: &mut W, format: ImageFormat) -> ImageResult<()>
1105
1.81k
    where
1106
1.81k
        W: std::io::Write + std::io::Seek,
1107
1.81k
        P: PixelWithColorType,
1108
    {
1109
        // This is valid as the subpixel is u8.
1110
1.81k
        write_buffer_with_format(
1111
1.81k
            writer,
1112
1.81k
            self.inner_pixels().as_bytes(),
1113
1.81k
            self.width(),
1114
1.81k
            self.height(),
1115
            <P as PixelWithColorType>::COLOR_TYPE,
1116
1.81k
            format,
1117
        )
1118
1.81k
    }
1119
}
1120
1121
impl<P, Container> ImageBuffer<P, Container>
1122
where
1123
    P: Pixel,
1124
    [P::Subpixel]: EncodableLayout,
1125
    Container: Deref<Target = [P::Subpixel]>,
1126
{
1127
    /// Writes the buffer with the given encoder.
1128
0
    pub fn write_with_encoder<E>(&self, encoder: E) -> ImageResult<()>
1129
0
    where
1130
0
        E: ImageEncoder,
1131
0
        P: PixelWithColorType,
1132
    {
1133
        // This is valid as the subpixel is u8.
1134
0
        encoder.write_image(
1135
0
            self.inner_pixels().as_bytes(),
1136
0
            self.width(),
1137
0
            self.height(),
1138
            <P as PixelWithColorType>::COLOR_TYPE,
1139
        )
1140
0
    }
1141
}
1142
1143
impl<P, Container> Default for ImageBuffer<P, Container>
1144
where
1145
    P: Pixel,
1146
    Container: Default,
1147
{
1148
0
    fn default() -> Self {
1149
0
        Self {
1150
0
            width: 0,
1151
0
            height: 0,
1152
0
            _phantom: PhantomData,
1153
0
            color: Cicp::SRGB_LINEAR.into_rgb(),
1154
0
            data: Default::default(),
1155
0
        }
1156
0
    }
1157
}
1158
1159
impl<P, Container> Deref for ImageBuffer<P, Container>
1160
where
1161
    P: Pixel,
1162
    Container: Deref<Target = [P::Subpixel]>,
1163
{
1164
    type Target = [P::Subpixel];
1165
1166
0
    fn deref(&self) -> &<Self as Deref>::Target {
1167
0
        &self.data
1168
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
1169
}
1170
1171
impl<P, Container> DerefMut for ImageBuffer<P, Container>
1172
where
1173
    P: Pixel,
1174
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1175
{
1176
0
    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
1177
0
        &mut self.data
1178
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
1179
}
1180
1181
impl<P, Container> Index<(u32, u32)> for ImageBuffer<P, Container>
1182
where
1183
    P: Pixel,
1184
    Container: Deref<Target = [P::Subpixel]>,
1185
{
1186
    type Output = P;
1187
1188
0
    fn index(&self, (x, y): (u32, u32)) -> &P {
1189
0
        self.get_pixel(x, y)
1190
0
    }
1191
}
1192
1193
impl<P, Container> IndexMut<(u32, u32)> for ImageBuffer<P, Container>
1194
where
1195
    P: Pixel,
1196
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1197
{
1198
0
    fn index_mut(&mut self, (x, y): (u32, u32)) -> &mut P {
1199
0
        self.get_pixel_mut(x, y)
1200
0
    }
1201
}
1202
1203
impl<P, Container> Clone for ImageBuffer<P, Container>
1204
where
1205
    P: Pixel,
1206
    Container: Deref<Target = [P::Subpixel]> + Clone,
1207
{
1208
0
    fn clone(&self) -> ImageBuffer<P, Container> {
1209
0
        ImageBuffer {
1210
0
            data: self.data.clone(),
1211
0
            width: self.width,
1212
0
            height: self.height,
1213
0
            color: self.color,
1214
0
            _phantom: PhantomData,
1215
0
        }
1216
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
1217
1218
0
    fn clone_from(&mut self, source: &Self) {
1219
0
        self.data.clone_from(&source.data);
1220
0
        self.width = source.width;
1221
0
        self.height = source.height;
1222
0
        self.color = source.color;
1223
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
1224
}
1225
1226
impl<P, Container> GenericImageView for ImageBuffer<P, Container>
1227
where
1228
    P: Pixel,
1229
    Container: Deref<Target = [P::Subpixel]> + Deref,
1230
{
1231
    type Pixel = P;
1232
1233
0
    fn dimensions(&self) -> (u32, u32) {
1234
0
        self.dimensions()
1235
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
1236
1237
0
    fn get_pixel(&self, x: u32, y: u32) -> P {
1238
0
        *self.get_pixel(x, y)
1239
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
1240
1241
    /// Returns the pixel located at (x, y), ignoring bounds checking.
1242
    #[inline(always)]
1243
0
    unsafe fn unsafe_get_pixel(&self, x: u32, y: u32) -> P {
1244
0
        let indices = self.pixel_indices_unchecked(x, y);
1245
0
        *<P as Pixel>::from_slice(self.data.get_unchecked(indices))
1246
0
    }
1247
1248
0
    fn buffer_with_dimensions(&self, width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1249
0
        let mut buffer = ImageBuffer::new(width, height);
1250
0
        buffer.copy_color_space_from(self);
1251
0
        buffer
1252
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
1253
}
1254
1255
impl<P, Container> GenericImage for ImageBuffer<P, Container>
1256
where
1257
    P: Pixel,
1258
    Container: Deref<Target = [P::Subpixel]> + DerefMut,
1259
{
1260
0
    fn get_pixel_mut(&mut self, x: u32, y: u32) -> &mut P {
1261
0
        self.get_pixel_mut(x, y)
1262
0
    }
1263
1264
0
    fn put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1265
0
        *self.get_pixel_mut(x, y) = pixel;
1266
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
1267
1268
    /// Puts a pixel at location (x, y), ignoring bounds checking.
1269
    #[inline(always)]
1270
0
    unsafe fn unsafe_put_pixel(&mut self, x: u32, y: u32, pixel: P) {
1271
0
        let indices = self.pixel_indices_unchecked(x, y);
1272
0
        let p = <P as Pixel>::from_slice_mut(self.data.get_unchecked_mut(indices));
1273
0
        *p = pixel;
1274
0
    }
1275
1276
    /// Put a pixel at location (x, y), taking into account alpha channels
1277
    ///
1278
    /// DEPRECATED: This method will be removed. Blend the pixel directly instead.
1279
0
    fn blend_pixel(&mut self, x: u32, y: u32, p: P) {
1280
0
        self.get_pixel_mut(x, y).blend(&p);
1281
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
1282
1283
0
    fn copy_within(&mut self, source: Rect, x: u32, y: u32) -> bool {
1284
        let Rect {
1285
0
            x: sx,
1286
0
            y: sy,
1287
0
            width,
1288
0
            height,
1289
0
        } = source;
1290
0
        let dx = x;
1291
0
        let dy = y;
1292
0
        assert!(sx < self.width() && dx < self.width());
1293
0
        assert!(sy < self.height() && dy < self.height());
1294
0
        if self.width() - dx.max(sx) < width || self.height() - dy.max(sy) < height {
1295
0
            return false;
1296
0
        }
1297
1298
0
        if sy < dy {
1299
0
            for y in (0..height).rev() {
1300
0
                let sy = sy + y;
1301
0
                let dy = dy + y;
1302
0
                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1303
0
                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1304
0
                let dst = self.pixel_indices_unchecked(dx, dy).start;
1305
0
                self.data.copy_within(start..end, dst);
1306
0
            }
1307
        } else {
1308
0
            for y in 0..height {
1309
0
                let sy = sy + y;
1310
0
                let dy = dy + y;
1311
0
                let Range { start, .. } = self.pixel_indices_unchecked(sx, sy);
1312
0
                let Range { end, .. } = self.pixel_indices_unchecked(sx + width - 1, sy);
1313
0
                let dst = self.pixel_indices_unchecked(dx, dy).start;
1314
0
                self.data.copy_within(start..end, dst);
1315
0
            }
1316
        }
1317
0
        true
1318
0
    }
1319
}
1320
1321
// concrete implementation for `Vec`-backed buffers
1322
// TODO: I think that rustc does not "see" this impl any more: the impl with
1323
// Container meets the same requirements. At least, I got compile errors that
1324
// there is no such function as `into_vec`, whereas `into_raw` did work, and
1325
// `into_vec` is redundant anyway, because `into_raw` will give you the vector,
1326
// and it is more generic.
1327
impl<P: Pixel> ImageBuffer<P, Vec<P::Subpixel>> {
1328
    /// Creates a new image buffer based on a `Vec<P::Subpixel>`.
1329
    ///
1330
    /// all the pixels of this image have a value of zero, regardless of the data type or number of channels.
1331
    ///
1332
    /// The color space is initially set to [`sRGB`][`Cicp::SRGB`].
1333
    ///
1334
    /// # Panics
1335
    ///
1336
    /// Panics when the resulting image is larger than the maximum size of a vector.
1337
    #[must_use]
1338
0
    pub fn new(width: u32, height: u32) -> ImageBuffer<P, Vec<P::Subpixel>> {
1339
0
        let size = Self::image_buffer_len(width, height)
1340
0
            .expect("Buffer length in `ImageBuffer::new` overflows usize");
1341
0
        ImageBuffer {
1342
0
            data: vec![Zero::zero(); size],
1343
0
            width,
1344
0
            height,
1345
0
            color: Cicp::SRGB.into_rgb(),
1346
0
            _phantom: PhantomData,
1347
0
        }
1348
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
1349
1350
    /// Constructs a new `ImageBuffer` by copying a pixel
1351
    ///
1352
    /// # Panics
1353
    ///
1354
    /// Panics when the resulting image is larger than the maximum size of a vector.
1355
0
    pub fn from_pixel(width: u32, height: u32, pixel: P) -> ImageBuffer<P, Vec<P::Subpixel>> {
1356
0
        let mut buf = ImageBuffer::new(width, height);
1357
0
        for p in buf.pixels_mut() {
1358
0
            *p = pixel;
1359
0
        }
1360
0
        buf
1361
0
    }
1362
1363
    /// Constructs a new `ImageBuffer` by repeated application of the supplied function.
1364
    ///
1365
    /// The arguments to the function are the pixel's x and y coordinates.
1366
    ///
1367
    /// # Panics
1368
    ///
1369
    /// Panics when the resulting image is larger than the maximum size of a vector.
1370
0
    pub fn from_fn<F>(width: u32, height: u32, mut f: F) -> ImageBuffer<P, Vec<P::Subpixel>>
1371
0
    where
1372
0
        F: FnMut(u32, u32) -> P,
1373
    {
1374
0
        let mut buf = ImageBuffer::new(width, height);
1375
0
        for (x, y, p) in buf.enumerate_pixels_mut() {
1376
0
            *p = f(x, y);
1377
0
        }
1378
0
        buf
1379
0
    }
1380
1381
    /// Creates an image buffer out of an existing buffer.
1382
    /// Returns None if the buffer is not big enough.
1383
    #[must_use]
1384
1.81k
    pub fn from_vec(
1385
1.81k
        width: u32,
1386
1.81k
        height: u32,
1387
1.81k
        buf: Vec<P::Subpixel>,
1388
1.81k
    ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1389
1.81k
        ImageBuffer::from_raw(width, height, buf)
1390
1.81k
    }
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
1384
1.81k
    pub fn from_vec(
1385
1.81k
        width: u32,
1386
1.81k
        height: u32,
1387
1.81k
        buf: Vec<P::Subpixel>,
1388
1.81k
    ) -> Option<ImageBuffer<P, Vec<P::Subpixel>>> {
1389
1.81k
        ImageBuffer::from_raw(width, height, buf)
1390
1.81k
    }
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
1391
1392
    /// Consumes the image buffer and returns the underlying data
1393
    /// as an owned buffer
1394
    #[must_use]
1395
1.81k
    pub fn into_vec(self) -> Vec<P::Subpixel> {
1396
1.81k
        self.into_raw()
1397
1.81k
    }
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
1395
1.81k
    pub fn into_vec(self) -> Vec<P::Subpixel> {
1396
1.81k
        self.into_raw()
1397
1.81k
    }
1398
1399
    /// Transfer the meta data, not the pixel values.
1400
    ///
1401
    /// This will reinterpret all the pixels.
1402
    ///
1403
    /// We may want to export this but under what name?
1404
0
    pub(crate) fn copy_color_space_from<O: Pixel, C>(&mut self, other: &ImageBuffer<O, C>) {
1405
0
        self.color = other.color;
1406
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]>
1407
}
1408
1409
/// Provides color conversions for whole image buffers.
1410
pub trait ConvertBuffer<T> {
1411
    /// Converts `self` to a buffer of type T
1412
    ///
1413
    /// A generic implementation is provided to convert any image buffer to a image buffer
1414
    /// based on a `Vec<T>`.
1415
    fn convert(&self) -> T;
1416
}
1417
1418
// concrete implementation Luma -> Rgba
1419
impl GrayImage {
1420
    /// Expands a color palette by re-using the existing buffer.
1421
    /// Assumes 8 bit per pixel. Uses an optionally transparent index to
1422
    /// adjust it's alpha value accordingly.
1423
    #[must_use]
1424
0
    pub fn expand_palette(
1425
0
        self,
1426
0
        palette: &[(u8, u8, u8)],
1427
0
        transparent_idx: Option<u8>,
1428
0
    ) -> RgbaImage {
1429
0
        let (width, height) = self.dimensions();
1430
0
        let mut data = self.into_raw();
1431
0
        let entries = data.len();
1432
0
        data.resize(entries.checked_mul(4).unwrap(), 0);
1433
0
        let mut buffer = ImageBuffer::from_vec(width, height, data).unwrap();
1434
0
        expand_packed(&mut buffer, 4, 8, |idx, pixel| {
1435
0
            let (r, g, b) = palette[idx as usize];
1436
0
            let a = if let Some(t_idx) = transparent_idx {
1437
0
                if t_idx == idx {
1438
0
                    0
1439
                } else {
1440
0
                    255
1441
                }
1442
            } else {
1443
0
                255
1444
            };
1445
0
            pixel[0] = r;
1446
0
            pixel[1] = g;
1447
0
            pixel[2] = b;
1448
0
            pixel[3] = a;
1449
0
        });
1450
0
        buffer
1451
0
    }
1452
}
1453
1454
/// This copies the color space information but is somewhat wrong, in numeric terms this conversion
1455
/// fails to actually convert rgb/luma with consistent treatment. But this trait impl is too
1456
/// generic to handle it correctly (missing any CICP related parameter for the coefficients) so the
1457
/// best effort here is to copy the metadata and have slighly incorrect color. May you've only been
1458
/// adding an alpha channel or converting sample types, which is fine.
1459
///
1460
/// It will very likely be deprecated in a future release.
1461
impl<Container, FromType: Pixel, ToType: Pixel>
1462
    ConvertBuffer<ImageBuffer<ToType, Vec<ToType::Subpixel>>> for ImageBuffer<FromType, Container>
1463
where
1464
    Container: Deref<Target = [FromType::Subpixel]>,
1465
    ToType: FromColor<FromType>,
1466
{
1467
    /// # Examples
1468
    /// Convert RGB image to gray image.
1469
    /// ```no_run
1470
    /// use image::buffer::ConvertBuffer;
1471
    /// use image::GrayImage;
1472
    ///
1473
    /// let image_path = "examples/fractal.png";
1474
    /// let image = image::open(&image_path)
1475
    ///     .expect("Open file failed")
1476
    ///     .to_rgba8();
1477
    ///
1478
    /// let gray_image: GrayImage = image.convert();
1479
    /// ```
1480
0
    fn convert(&self) -> ImageBuffer<ToType, Vec<ToType::Subpixel>> {
1481
0
        let mut buffer: ImageBuffer<ToType, Vec<ToType::Subpixel>> =
1482
0
            ImageBuffer::new(self.width, self.height);
1483
0
        buffer.copy_color_space_from(self);
1484
0
        for (to, from) in buffer.pixels_mut().zip(self.pixels()) {
1485
0
            to.from_color(from);
1486
0
        }
1487
0
        buffer
1488
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
1489
}
1490
1491
/// Inputs to [`ImageBuffer::copy_from_color_space`].
1492
#[non_exhaustive]
1493
#[derive(Default)]
1494
pub struct ConvertColorOptions {
1495
    /// A pre-calculated transform. This is only used when the actual colors of the input and
1496
    /// output image match the color spaces with which the was constructed.
1497
    ///
1498
    /// FIXME: Clarify that the transform is cheap to clone, i.e. internally an Arc of precomputed
1499
    /// tables and not expensive despite having `Clone`.
1500
    pub(crate) transform: Option<CicpTransform>,
1501
    /// Make sure we can later add options that are bound to the thread. That does not mean that
1502
    /// all attributes will be bound to the thread, only that we can add `!Sync` options later. You
1503
    /// should be constructing the options at the call site with each attribute being cheap to move
1504
    /// into here.
1505
    pub(crate) _auto_traits: PhantomData<std::rc::Rc<()>>,
1506
}
1507
1508
impl ConvertColorOptions {
1509
0
    pub(crate) fn as_transform(
1510
0
        &mut self,
1511
0
        from_color: Cicp,
1512
0
        into_color: Cicp,
1513
0
    ) -> Result<&CicpTransform, ImageError> {
1514
0
        if let Some(tr) = &self.transform {
1515
0
            tr.check_applicable(from_color, into_color)?;
1516
0
        }
1517
1518
0
        if self.transform.is_none() {
1519
0
            self.transform = CicpTransform::new(from_color, into_color);
1520
0
        }
1521
1522
0
        self.transform.as_ref().ok_or_else(|| {
1523
0
            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
1524
0
                crate::error::ImageFormatHint::Unknown,
1525
                // One of them is responsible.
1526
0
                UnsupportedErrorKind::ColorspaceCicp(if from_color.qualify_stability() {
1527
0
                    into_color
1528
                } else {
1529
0
                    from_color
1530
                }),
1531
            ))
1532
0
        })
1533
0
    }
1534
1535
0
    pub(crate) fn as_transform_fn<FromType, IntoType>(
1536
0
        &mut self,
1537
0
        from_color: Cicp,
1538
0
        into_color: Cicp,
1539
0
    ) -> Result<&'_ CicpApplicable<'_, FromType::Subpixel>, ImageError>
1540
0
    where
1541
0
        FromType: PixelWithColorType,
1542
0
        IntoType: PixelWithColorType,
1543
    {
1544
0
        Ok(self
1545
0
            .as_transform(from_color, into_color)?
1546
0
            .supported_transform_fn::<FromType, IntoType>())
1547
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>>
1548
}
1549
1550
impl<C, SelfPixel: Pixel> ImageBuffer<SelfPixel, C>
1551
where
1552
    SelfPixel: PixelWithColorType,
1553
    C: Deref<Target = [SelfPixel::Subpixel]> + DerefMut,
1554
{
1555
    /// Convert the color data to another pixel type, the color space.
1556
    ///
1557
    /// This method is supposed to be called by exposed monomorphized methods, not directly by
1558
    /// users. In particular it serves to implement `DynamicImage`'s casts that go beyond those
1559
    /// offered by `PixelWithColorType` and include, e.g., `LumaAlpha<f32>`.
1560
    ///
1561
    /// Before exposing this method, decide if we want a design like [`DynamicImage::to`] (many
1562
    /// trait parameters) with color space aware `FromColor` or if we want a design that takes a
1563
    /// `ColorType` parameter / `PixelWithColorType`. The latter is not quite as flexible but
1564
    /// allows much greater internal changes that do not tie in with the _external_ stable API.
1565
0
    pub(crate) fn cast_in_color_space<IntoPixel>(
1566
0
        &self,
1567
0
    ) -> ImageBuffer<IntoPixel, Vec<IntoPixel::Subpixel>>
1568
0
    where
1569
0
        SelfPixel: Pixel,
1570
0
        IntoPixel: Pixel,
1571
0
        IntoPixel: CicpPixelCast<SelfPixel>,
1572
0
        SelfPixel::Subpixel: ColorComponentForCicp,
1573
0
        IntoPixel::Subpixel: ColorComponentForCicp + FromPrimitive<SelfPixel::Subpixel>,
1574
    {
1575
0
        let vec = self
1576
0
            .color
1577
0
            .cast_pixels::<SelfPixel, IntoPixel>(self.inner_pixels(), &|| [0.2126, 0.7152, 0.0722]);
1578
0
        let mut buffer = ImageBuffer::from_vec(self.width, self.height, vec)
1579
0
            .expect("cast_pixels returned the right number of pixels");
1580
0
        buffer.copy_color_space_from(self);
1581
0
        buffer
1582
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>>
1583
1584
    /// Copy pixel data from one buffer to another, calculating equivalent color representations
1585
    /// for the target's color space.
1586
    ///
1587
    /// Returns `Ok` if:
1588
    /// - Both images to have the same dimensions, otherwise returns a [`ImageError::Parameter`].
1589
    /// - The primaries and transfer functions of both image's color spaces must be supported,
1590
    ///   otherwise returns a [`ImageError::Unsupported`].
1591
    /// - The pixel's channel layout must be supported for conversion, otherwise returns a
1592
    ///   [`ImageError::Unsupported`]. You can rely on RGB and RGBA always being supported. If a
1593
    ///   layout is supported for one color space it is supported for all of them.
1594
    ///
1595
    /// To copy color data of arbitrary channel layouts use `DynamicImage` with the overhead of
1596
    /// having data converted into and from RGB representation.
1597
0
    pub fn copy_from_color_space<FromType, D>(
1598
0
        &mut self,
1599
0
        from: &ImageBuffer<FromType, D>,
1600
0
        mut options: ConvertColorOptions,
1601
0
    ) -> ImageResult<()>
1602
0
    where
1603
0
        FromType: Pixel<Subpixel = SelfPixel::Subpixel> + PixelWithColorType,
1604
0
        D: Deref<Target = [SelfPixel::Subpixel]>,
1605
    {
1606
0
        if self.dimensions() != from.dimensions() {
1607
0
            return Err(ImageError::Parameter(ParameterError::from_kind(
1608
0
                ParameterErrorKind::DimensionMismatch,
1609
0
            )));
1610
0
        }
1611
1612
0
        let transform = options
1613
0
            .as_transform_fn::<FromType, SelfPixel>(from.color_space(), self.color_space())?;
1614
1615
0
        let from = from.inner_pixels();
1616
0
        let into = self.inner_pixels_mut();
1617
1618
0
        debug_assert_eq!(
1619
0
            from.len() / usize::from(FromType::CHANNEL_COUNT),
1620
0
            into.len() / usize::from(SelfPixel::CHANNEL_COUNT),
1621
0
            "Diverging pixel count despite same size",
1622
        );
1623
1624
0
        transform(from, into);
1625
1626
0
        Ok(())
1627
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>>
1628
1629
    /// Convert this buffer into a newly allocated buffer, changing the color representation.
1630
    ///
1631
    /// This will avoid an allocation if the target layout or the color conversion is not supported
1632
    /// (yet).
1633
    ///
1634
    /// See [`ImageBuffer::copy_from_color_space`] if you intend to assign to an existing buffer,
1635
    /// swapping the argument with `self`.
1636
0
    pub fn to_color_space<IntoType>(
1637
0
        &self,
1638
0
        color: Cicp,
1639
0
        mut options: ConvertColorOptions,
1640
0
    ) -> Result<ImageBuffer<IntoType, Vec<SelfPixel::Subpixel>>, ImageError>
1641
0
    where
1642
0
        IntoType: Pixel<Subpixel = SelfPixel::Subpixel> + PixelWithColorType,
1643
    {
1644
0
        let transform =
1645
0
            options.as_transform_fn::<SelfPixel, IntoType>(self.color_space(), color)?;
1646
1647
0
        let (width, height) = self.dimensions();
1648
0
        let mut target = ImageBuffer::new(width, height);
1649
1650
0
        let from = self.inner_pixels();
1651
0
        let into = target.inner_pixels_mut();
1652
1653
0
        transform(from, into);
1654
1655
0
        Ok(target)
1656
0
    }
1657
1658
    /// Apply a color space to an image, transforming the pixel representation.
1659
0
    pub fn apply_color_space(
1660
0
        &mut self,
1661
0
        color: Cicp,
1662
0
        mut options: ConvertColorOptions,
1663
0
    ) -> ImageResult<()> {
1664
0
        if self.color_space() == color {
1665
0
            return Ok(());
1666
0
        }
1667
1668
0
        let transform =
1669
0
            options.as_transform_fn::<SelfPixel, SelfPixel>(self.color_space(), color)?;
1670
1671
0
        let mut scratch = [<SelfPixel::Subpixel as crate::Primitive>::DEFAULT_MIN_VALUE; 1200];
1672
0
        let chunk_len = scratch.len() / usize::from(<SelfPixel as Pixel>::CHANNEL_COUNT)
1673
0
            * usize::from(<SelfPixel as Pixel>::CHANNEL_COUNT);
1674
1675
0
        for chunk in self.data.chunks_mut(chunk_len) {
1676
0
            let scratch = &mut scratch[..chunk.len()];
1677
0
            scratch.copy_from_slice(chunk);
1678
0
            transform(scratch, chunk);
1679
0
        }
1680
1681
0
        self.color = color.into_rgb();
1682
1683
0
        Ok(())
1684
0
    }
1685
}
1686
1687
/// Sendable Rgb image buffer
1688
pub type RgbImage = ImageBuffer<Rgb<u8>, Vec<u8>>;
1689
/// Sendable Rgb + alpha channel image buffer
1690
pub type RgbaImage = ImageBuffer<Rgba<u8>, Vec<u8>>;
1691
/// Sendable grayscale image buffer
1692
pub type GrayImage = ImageBuffer<Luma<u8>, Vec<u8>>;
1693
/// Sendable grayscale + alpha channel image buffer
1694
pub type GrayAlphaImage = ImageBuffer<LumaA<u8>, Vec<u8>>;
1695
/// Sendable 16-bit Rgb image buffer
1696
pub(crate) type Rgb16Image = ImageBuffer<Rgb<u16>, Vec<u16>>;
1697
/// Sendable 16-bit Rgb + alpha channel image buffer
1698
pub(crate) type Rgba16Image = ImageBuffer<Rgba<u16>, Vec<u16>>;
1699
/// Sendable 16-bit grayscale image buffer
1700
pub(crate) type Gray16Image = ImageBuffer<Luma<u16>, Vec<u16>>;
1701
/// Sendable 16-bit grayscale + alpha channel image buffer
1702
pub(crate) type GrayAlpha16Image = ImageBuffer<LumaA<u16>, Vec<u16>>;
1703
1704
/// An image buffer for 32-bit float RGB pixels,
1705
/// where the backing container is a flattened vector of floats.
1706
pub type Rgb32FImage = ImageBuffer<Rgb<f32>, Vec<f32>>;
1707
1708
/// An image buffer for 32-bit float RGBA pixels,
1709
/// where the backing container is a flattened vector of floats.
1710
pub type Rgba32FImage = ImageBuffer<Rgba<f32>, Vec<f32>>;
1711
1712
impl From<DynamicImage> for RgbImage {
1713
0
    fn from(value: DynamicImage) -> Self {
1714
0
        value.into_rgb8()
1715
0
    }
1716
}
1717
1718
impl From<DynamicImage> for RgbaImage {
1719
0
    fn from(value: DynamicImage) -> Self {
1720
0
        value.into_rgba8()
1721
0
    }
1722
}
1723
1724
impl From<DynamicImage> for GrayImage {
1725
0
    fn from(value: DynamicImage) -> Self {
1726
0
        value.into_luma8()
1727
0
    }
1728
}
1729
1730
impl From<DynamicImage> for GrayAlphaImage {
1731
0
    fn from(value: DynamicImage) -> Self {
1732
0
        value.into_luma_alpha8()
1733
0
    }
1734
}
1735
1736
impl From<DynamicImage> for Rgb16Image {
1737
0
    fn from(value: DynamicImage) -> Self {
1738
0
        value.into_rgb16()
1739
0
    }
1740
}
1741
1742
impl From<DynamicImage> for Rgba16Image {
1743
0
    fn from(value: DynamicImage) -> Self {
1744
0
        value.into_rgba16()
1745
0
    }
1746
}
1747
1748
impl From<DynamicImage> for Gray16Image {
1749
0
    fn from(value: DynamicImage) -> Self {
1750
0
        value.into_luma16()
1751
0
    }
1752
}
1753
1754
impl From<DynamicImage> for GrayAlpha16Image {
1755
0
    fn from(value: DynamicImage) -> Self {
1756
0
        value.into_luma_alpha16()
1757
0
    }
1758
}
1759
1760
impl From<DynamicImage> for Rgba32FImage {
1761
0
    fn from(value: DynamicImage) -> Self {
1762
0
        value.into_rgba32f()
1763
0
    }
1764
}
1765
1766
#[cfg(test)]
1767
mod test {
1768
    use super::{GrayImage, ImageBuffer, RgbImage};
1769
    use crate::math::Rect;
1770
    use crate::metadata::Cicp;
1771
    use crate::metadata::CicpTransform;
1772
    use crate::GenericImage as _;
1773
    use crate::ImageFormat;
1774
    use crate::{Luma, LumaA, Pixel, Rgb, Rgba};
1775
    use num_traits::Zero;
1776
1777
    #[test]
1778
    /// Tests if image buffers from slices work
1779
    fn slice_buffer() {
1780
        let data = [0; 9];
1781
        let buf: ImageBuffer<Luma<u8>, _> = ImageBuffer::from_raw(3, 3, &data[..]).unwrap();
1782
        assert_eq!(&*buf, &data[..]);
1783
    }
1784
1785
    macro_rules! new_buffer_zero_test {
1786
        ($test_name:ident, $pxt:ty) => {
1787
            #[test]
1788
            fn $test_name() {
1789
                let buffer = ImageBuffer::<$pxt, Vec<<$pxt as Pixel>::Subpixel>>::new(2, 2);
1790
                assert!(buffer
1791
                    .iter()
1792
                    .all(|p| *p == <$pxt as Pixel>::Subpixel::zero()));
1793
            }
1794
        };
1795
    }
1796
1797
    new_buffer_zero_test!(luma_u8_zero_test, Luma<u8>);
1798
    new_buffer_zero_test!(luma_u16_zero_test, Luma<u16>);
1799
    new_buffer_zero_test!(luma_f32_zero_test, Luma<f32>);
1800
    new_buffer_zero_test!(luma_a_u8_zero_test, LumaA<u8>);
1801
    new_buffer_zero_test!(luma_a_u16_zero_test, LumaA<u16>);
1802
    new_buffer_zero_test!(luma_a_f32_zero_test, LumaA<f32>);
1803
    new_buffer_zero_test!(rgb_u8_zero_test, Rgb<u8>);
1804
    new_buffer_zero_test!(rgb_u16_zero_test, Rgb<u16>);
1805
    new_buffer_zero_test!(rgb_f32_zero_test, Rgb<f32>);
1806
    new_buffer_zero_test!(rgb_a_u8_zero_test, Rgba<u8>);
1807
    new_buffer_zero_test!(rgb_a_u16_zero_test, Rgba<u16>);
1808
    new_buffer_zero_test!(rgb_a_f32_zero_test, Rgba<f32>);
1809
1810
    #[test]
1811
    fn get_pixel() {
1812
        let mut a: RgbImage = ImageBuffer::new(10, 10);
1813
        {
1814
            let b = a.get_mut(3 * 10).unwrap();
1815
            *b = 255;
1816
        }
1817
        assert_eq!(a.get_pixel(0, 1)[0], 255);
1818
    }
1819
1820
    #[test]
1821
    fn get_pixel_checked() {
1822
        let mut a: RgbImage = ImageBuffer::new(10, 10);
1823
        a.get_pixel_mut_checked(0, 1).unwrap()[0] = 255;
1824
1825
        assert_eq!(a.get_pixel_checked(0, 1), Some(&Rgb([255, 0, 0])));
1826
        assert_eq!(a.get_pixel_checked(0, 1).unwrap(), a.get_pixel(0, 1));
1827
        assert_eq!(a.get_pixel_checked(10, 0), None);
1828
        assert_eq!(a.get_pixel_checked(0, 10), None);
1829
        assert_eq!(a.get_pixel_mut_checked(10, 0), None);
1830
        assert_eq!(a.get_pixel_mut_checked(0, 10), None);
1831
1832
        // From image/issues/1672
1833
        const WHITE: Rgb<u8> = Rgb([255_u8, 255, 255]);
1834
        let mut a = RgbImage::new(2, 1);
1835
        a.put_pixel(1, 0, WHITE);
1836
1837
        assert_eq!(a.get_pixel_checked(1, 0), Some(&WHITE));
1838
        assert_eq!(a.get_pixel_checked(1, 0).unwrap(), a.get_pixel(1, 0));
1839
    }
1840
1841
    #[test]
1842
    fn mut_iter() {
1843
        let mut a: RgbImage = ImageBuffer::new(10, 10);
1844
        {
1845
            let val = a.pixels_mut().next().unwrap();
1846
            *val = Rgb([42, 0, 0]);
1847
        }
1848
        assert_eq!(a.data[0], 42);
1849
    }
1850
1851
    #[test]
1852
    fn zero_width_zero_height() {
1853
        let mut image = RgbImage::new(0, 0);
1854
1855
        assert_eq!(image.rows_mut().count(), 0);
1856
        assert_eq!(image.pixels_mut().count(), 0);
1857
        assert_eq!(image.rows().count(), 0);
1858
        assert_eq!(image.pixels().count(), 0);
1859
    }
1860
1861
    #[test]
1862
    fn zero_width_nonzero_height() {
1863
        let mut image = RgbImage::new(0, 2);
1864
1865
        assert_eq!(image.rows_mut().count(), 0);
1866
        assert_eq!(image.pixels_mut().count(), 0);
1867
        assert_eq!(image.rows().count(), 0);
1868
        assert_eq!(image.pixels().count(), 0);
1869
    }
1870
1871
    #[test]
1872
    fn nonzero_width_zero_height() {
1873
        let mut image = RgbImage::new(2, 0);
1874
1875
        assert_eq!(image.rows_mut().count(), 0);
1876
        assert_eq!(image.pixels_mut().count(), 0);
1877
        assert_eq!(image.rows().count(), 0);
1878
        assert_eq!(image.pixels().count(), 0);
1879
    }
1880
1881
    #[test]
1882
    fn pixels_on_large_buffer() {
1883
        let mut image = RgbImage::from_raw(1, 1, vec![0; 6]).unwrap();
1884
1885
        assert_eq!(image.pixels().count(), 1);
1886
        assert_eq!(image.enumerate_pixels().count(), 1);
1887
        assert_eq!(image.pixels_mut().count(), 1);
1888
        assert_eq!(image.enumerate_pixels_mut().count(), 1);
1889
1890
        assert_eq!(image.rows().count(), 1);
1891
        assert_eq!(image.rows_mut().count(), 1);
1892
    }
1893
1894
    #[test]
1895
    fn default() {
1896
        let image = ImageBuffer::<Rgb<u8>, Vec<u8>>::default();
1897
        assert_eq!(image.dimensions(), (0, 0));
1898
    }
1899
1900
    #[test]
1901
    #[rustfmt::skip]
1902
    fn test_image_buffer_copy_within_oob() {
1903
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, vec![0u8; 16]).unwrap();
1904
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 5, height: 4 }, 0, 0));
1905
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 5 }, 0, 0));
1906
        assert!(!image.copy_within(Rect { x: 1, y: 0, width: 4, height: 4 }, 0, 0));
1907
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 1, 0));
1908
        assert!(!image.copy_within(Rect { x: 0, y: 1, width: 4, height: 4 }, 0, 0));
1909
        assert!(!image.copy_within(Rect { x: 0, y: 0, width: 4, height: 4 }, 0, 1));
1910
        assert!(!image.copy_within(Rect { x: 1, y: 1, width: 4, height: 4 }, 0, 0));
1911
    }
1912
1913
    #[test]
1914
    fn test_image_buffer_copy_within_tl() {
1915
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1916
        let expected = [0, 1, 2, 3, 4, 0, 1, 2, 8, 4, 5, 6, 12, 8, 9, 10];
1917
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1918
        assert!(image.copy_within(
1919
            Rect {
1920
                x: 0,
1921
                y: 0,
1922
                width: 3,
1923
                height: 3
1924
            },
1925
            1,
1926
            1
1927
        ));
1928
        assert_eq!(&image.into_raw(), &expected);
1929
    }
1930
1931
    #[test]
1932
    fn test_image_buffer_copy_within_tr() {
1933
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1934
        let expected = [0, 1, 2, 3, 1, 2, 3, 7, 5, 6, 7, 11, 9, 10, 11, 15];
1935
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1936
        assert!(image.copy_within(
1937
            Rect {
1938
                x: 1,
1939
                y: 0,
1940
                width: 3,
1941
                height: 3
1942
            },
1943
            0,
1944
            1
1945
        ));
1946
        assert_eq!(&image.into_raw(), &expected);
1947
    }
1948
1949
    #[test]
1950
    fn test_image_buffer_copy_within_bl() {
1951
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1952
        let expected = [0, 4, 5, 6, 4, 8, 9, 10, 8, 12, 13, 14, 12, 13, 14, 15];
1953
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1954
        assert!(image.copy_within(
1955
            Rect {
1956
                x: 0,
1957
                y: 1,
1958
                width: 3,
1959
                height: 3
1960
            },
1961
            1,
1962
            0
1963
        ));
1964
        assert_eq!(&image.into_raw(), &expected);
1965
    }
1966
1967
    #[test]
1968
    fn test_image_buffer_copy_within_br() {
1969
        let data = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
1970
        let expected = [5, 6, 7, 3, 9, 10, 11, 7, 13, 14, 15, 11, 12, 13, 14, 15];
1971
        let mut image: GrayImage = ImageBuffer::from_raw(4, 4, Vec::from(&data[..])).unwrap();
1972
        assert!(image.copy_within(
1973
            Rect {
1974
                x: 1,
1975
                y: 1,
1976
                width: 3,
1977
                height: 3
1978
            },
1979
            0,
1980
            0
1981
        ));
1982
        assert_eq!(&image.into_raw(), &expected);
1983
    }
1984
1985
    #[test]
1986
    #[cfg(feature = "png")]
1987
    fn write_to_with_large_buffer() {
1988
        // A buffer of 1 pixel, padded to 4 bytes as would be common in, e.g. BMP.
1989
1990
        let img: GrayImage = ImageBuffer::from_raw(1, 1, vec![0u8; 4]).unwrap();
1991
        let mut buffer = std::io::Cursor::new(vec![]);
1992
        assert!(img.write_to(&mut buffer, ImageFormat::Png).is_ok());
1993
    }
1994
1995
    #[test]
1996
    fn exact_size_iter_size_hint() {
1997
        // The docs for `std::iter::ExactSizeIterator` requires that the implementation of
1998
        // `size_hint` on the iterator returns the same value as the `len` implementation.
1999
2000
        // This test should work for any size image.
2001
        const N: u32 = 10;
2002
2003
        let mut image = RgbImage::from_raw(N, N, vec![0; (N * N * 3) as usize]).unwrap();
2004
2005
        let iter = image.pixels();
2006
        let exact_len = ExactSizeIterator::len(&iter);
2007
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2008
2009
        let iter = image.pixels_mut();
2010
        let exact_len = ExactSizeIterator::len(&iter);
2011
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2012
2013
        let iter = image.rows();
2014
        let exact_len = ExactSizeIterator::len(&iter);
2015
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2016
2017
        let iter = image.rows_mut();
2018
        let exact_len = ExactSizeIterator::len(&iter);
2019
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2020
2021
        let iter = image.enumerate_pixels();
2022
        let exact_len = ExactSizeIterator::len(&iter);
2023
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2024
2025
        let iter = image.enumerate_rows();
2026
        let exact_len = ExactSizeIterator::len(&iter);
2027
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2028
2029
        let iter = image.enumerate_pixels_mut();
2030
        let exact_len = ExactSizeIterator::len(&iter);
2031
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2032
2033
        let iter = image.enumerate_rows_mut();
2034
        let exact_len = ExactSizeIterator::len(&iter);
2035
        assert_eq!(iter.size_hint(), (exact_len, Some(exact_len)));
2036
    }
2037
2038
    #[test]
2039
    fn color_conversion() {
2040
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgb([255, 0, 0]));
2041
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2042
2043
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2044
        source.set_transfer_function(Cicp::SRGB.transfer);
2045
2046
        target.set_rgb_primaries(Cicp::DISPLAY_P3.primaries);
2047
        target.set_transfer_function(Cicp::DISPLAY_P3.transfer);
2048
2049
        let result = target.copy_from_color_space(&source, Default::default());
2050
2051
        assert!(result.is_ok(), "{result:?}");
2052
        assert_eq!(target[(0, 0)], Rgba([234u8, 51, 35, 255]));
2053
    }
2054
2055
    #[test]
2056
    fn gray_conversions() {
2057
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Luma([255u8]));
2058
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2059
2060
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2061
        source.set_transfer_function(Cicp::SRGB.transfer);
2062
2063
        target.set_rgb_primaries(Cicp::SRGB.primaries);
2064
        target.set_transfer_function(Cicp::SRGB.transfer);
2065
2066
        let result = target.copy_from_color_space(&source, Default::default());
2067
2068
        assert!(result.is_ok(), "{result:?}");
2069
        assert_eq!(target[(0, 0)], Rgba([u8::MAX; 4]));
2070
    }
2071
2072
    #[test]
2073
    fn rgb_to_gray_conversion() {
2074
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgb([128u8; 3]));
2075
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Luma(Default::default()));
2076
2077
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2078
        source.set_transfer_function(Cicp::SRGB.transfer);
2079
2080
        target.set_rgb_primaries(Cicp::SRGB.primaries);
2081
        target.set_transfer_function(Cicp::SRGB.transfer);
2082
2083
        let result = target.copy_from_color_space(&source, Default::default());
2084
2085
        assert!(result.is_ok(), "{result:?}");
2086
        assert_eq!(target[(0, 0)], Luma([128u8]));
2087
    }
2088
2089
    #[test]
2090
    fn apply_color() {
2091
        let mut buffer = ImageBuffer::from_fn(128, 128, |_, _| Rgb([255u8, 0, 0]));
2092
2093
        buffer.set_rgb_primaries(Cicp::SRGB.primaries);
2094
        buffer.set_transfer_function(Cicp::SRGB.transfer);
2095
2096
        buffer
2097
            .apply_color_space(Cicp::DISPLAY_P3, Default::default())
2098
            .expect("supported transform");
2099
2100
        buffer.pixels().for_each(|&p| {
2101
            assert_eq!(p, Rgb([234u8, 51, 35]));
2102
        });
2103
    }
2104
2105
    #[test]
2106
    fn to_color() {
2107
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Rgba([255u8, 0, 0, 255]));
2108
        source.set_rgb_primaries(Cicp::SRGB.primaries);
2109
        source.set_transfer_function(Cicp::SRGB.transfer);
2110
2111
        let target = source
2112
            .to_color_space::<Rgb<u8>>(Cicp::DISPLAY_P3, Default::default())
2113
            .expect("supported transform");
2114
2115
        assert_eq!(target[(0, 0)], Rgb([234u8, 51, 35]));
2116
    }
2117
2118
    #[test]
2119
    fn transformation_mismatch() {
2120
        let mut source = ImageBuffer::from_fn(128, 128, |_, _| Luma([255u8]));
2121
        let mut target = ImageBuffer::from_fn(128, 128, |_, _| Rgba(Default::default()));
2122
2123
        source.set_color_space(Cicp::SRGB).unwrap();
2124
        target.set_color_space(Cicp::DISPLAY_P3).unwrap();
2125
2126
        let options = super::ConvertColorOptions {
2127
            transform: CicpTransform::new(Cicp::SRGB, Cicp::SRGB),
2128
            ..super::ConvertColorOptions::default()
2129
        };
2130
2131
        let result = target.copy_from_color_space(&source, options);
2132
        assert!(matches!(result, Err(crate::ImageError::Parameter(_))));
2133
    }
2134
}
2135
2136
#[cfg(test)]
2137
#[cfg(feature = "benchmarks")]
2138
mod benchmarks {
2139
    use super::{ConvertBuffer, GrayImage, ImageBuffer, Pixel, RgbImage};
2140
2141
    #[bench]
2142
    fn conversion(b: &mut test::Bencher) {
2143
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2144
        for p in a.pixels_mut() {
2145
            let rgb = p.channels_mut();
2146
            rgb[0] = 255;
2147
            rgb[1] = 23;
2148
            rgb[2] = 42;
2149
        }
2150
2151
        assert!(a.data[0] != 0);
2152
        b.iter(|| {
2153
            let b: GrayImage = a.convert();
2154
            assert!(0 != b.data[0]);
2155
            assert!(a.data[0] != b.data[0]);
2156
            test::black_box(b);
2157
        });
2158
        b.bytes = 1000 * 1000 * 3;
2159
    }
2160
2161
    #[bench]
2162
    fn image_access_row_by_row(b: &mut test::Bencher) {
2163
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2164
        for p in a.pixels_mut() {
2165
            let rgb = p.channels_mut();
2166
            rgb[0] = 255;
2167
            rgb[1] = 23;
2168
            rgb[2] = 42;
2169
        }
2170
2171
        b.iter(move || {
2172
            let image: &RgbImage = test::black_box(&a);
2173
            let mut sum: usize = 0;
2174
            for y in 0..1000 {
2175
                for x in 0..1000 {
2176
                    let pixel = image.get_pixel(x, y);
2177
                    sum = sum.wrapping_add(pixel[0] as usize);
2178
                    sum = sum.wrapping_add(pixel[1] as usize);
2179
                    sum = sum.wrapping_add(pixel[2] as usize);
2180
                }
2181
            }
2182
            test::black_box(sum)
2183
        });
2184
2185
        b.bytes = 1000 * 1000 * 3;
2186
    }
2187
2188
    #[bench]
2189
    fn image_access_col_by_col(b: &mut test::Bencher) {
2190
        let mut a: RgbImage = ImageBuffer::new(1000, 1000);
2191
        for p in a.pixels_mut() {
2192
            let rgb = p.channels_mut();
2193
            rgb[0] = 255;
2194
            rgb[1] = 23;
2195
            rgb[2] = 42;
2196
        }
2197
2198
        b.iter(move || {
2199
            let image: &RgbImage = test::black_box(&a);
2200
            let mut sum: usize = 0;
2201
            for x in 0..1000 {
2202
                for y in 0..1000 {
2203
                    let pixel = image.get_pixel(x, y);
2204
                    sum = sum.wrapping_add(pixel[0] as usize);
2205
                    sum = sum.wrapping_add(pixel[1] as usize);
2206
                    sum = sum.wrapping_add(pixel[2] as usize);
2207
                }
2208
            }
2209
            test::black_box(sum)
2210
        });
2211
2212
        b.bytes = 1000 * 1000 * 3;
2213
    }
2214
}