1use enums::{BitDepth, ImageComponent};
2use std::marker::PhantomData;
3use types::*;
4
5pub trait ChannelFormat {
6 fn range_max() -> f32;
7 fn from_f32(src: f32) -> Self;
8 fn to_f32(&self) -> f32;
9}
10
11impl ChannelFormat for f32 {
12 #[inline]
13 fn range_max() -> f32 {
14 1.0
15 }
16 #[inline]
17 fn from_f32(src: f32) -> Self {
18 src
19 }
20 #[inline]
21 fn to_f32(&self) -> f32 {
22 *self
23 }
24}
25
26impl ChannelFormat for u16 {
27 #[inline]
28 fn range_max() -> f32 {
29 f32::from(std::u16::MAX)
30 }
31 fn from_f32(src: f32) -> Self {
32 let clamp = Self::range_max();
33 clamp.min(src * clamp) as Self
34 }
35 #[inline]
36 fn to_f32(&self) -> f32 {
37 f32::from(*self) / Self::range_max()
38 }
39}
40
41impl ChannelFormat for u8 {
42 #[inline]
43 fn range_max() -> f32 {
44 f32::from(std::u8::MAX)
45 }
46 #[inline]
47 fn from_f32(src: f32) -> Self {
48 let clamp = Self::range_max();
49 clamp.min(src * clamp) as Self
50 }
51 #[inline]
52 fn to_f32(&self) -> f32 {
53 f32::from(*self) / Self::range_max()
54 }
55}
56
57pub trait PixelFormatRGB: PixelFormat {
58 fn r(&self) -> &Self::ChannelValue;
59 fn r_mut(&mut self) -> &mut Self::ChannelValue;
60 fn g(&self) -> &Self::ChannelValue;
61 fn g_mut(&mut self) -> &mut Self::ChannelValue;
62 fn b(&self) -> &Self::ChannelValue;
63 fn b_mut(&mut self) -> &mut Self::ChannelValue;
64}
65
66pub trait PixelFormatRGBA: PixelFormatRGB {
67 fn new(
68 r: Self::ChannelValue,
69 g: Self::ChannelValue,
70 b: Self::ChannelValue,
71 a: Self::ChannelValue,
72 ) -> Self;
73 fn a(&self) -> &Self::ChannelValue;
74 fn a_mut(&mut self) -> &mut Self::ChannelValue;
75}
76pub trait PixelFormatAlpha: PixelFormat + ChannelFormat {}
77
78pub trait ScaleMix {
79 fn scaled(&self, scale: &RGBAColourD) -> Self;
80 fn mix(&self, wet: &Self, mix: f32) -> Self;
81}
82
83impl<T> ScaleMix for T
84where
85 T: PixelFormatRGBA,
86{
87 fn scaled(&self, scale: &RGBAColourD) -> Self {
88 T::new(
89 T::ChannelValue::from_f32(self.r().to_f32() * scale.r as f32),
90 T::ChannelValue::from_f32(self.g().to_f32() * scale.g as f32),
91 T::ChannelValue::from_f32(self.b().to_f32() * scale.b as f32),
92 T::ChannelValue::from_f32(self.a().to_f32() * scale.a as f32),
93 )
94 }
95
96 fn mix(&self, wet: &Self, mix: f32) -> Self {
97 if mix <= 0.0 {
98 *self
99 } else if mix >= 1.0 {
100 *wet
101 } else {
102 let a0 = mix;
103 let a1 = 1.0 - a0;
104 T::new(
105 T::ChannelValue::from_f32(wet.r().to_f32() * a0 + self.r().to_f32() * a1),
106 T::ChannelValue::from_f32(wet.g().to_f32() * a0 + self.g().to_f32() * a1),
107 T::ChannelValue::from_f32(wet.b().to_f32() * a0 + self.b().to_f32() * a1),
108 T::ChannelValue::from_f32(wet.a().to_f32() * a0 + self.a().to_f32() * a1),
109 )
110 }
111 }
112}
113
114impl ScaleMix for f32 {
115 fn scaled(&self, scale: &RGBAColourD) -> Self {
116 *self * scale.a as f32
117 }
118
119 fn mix(&self, wet: &Self, mix: f32) -> Self {
120 if mix <= 0.0 {
121 *self
122 } else if mix >= 1.0 {
123 *wet
124 } else {
125 let a0 = mix;
126 let a1 = 1.0 - a0;
127 wet.to_f32() * a0 + self.to_f32() * a1
128 }
129 }
130}
131
132impl ScaleMix for u8 {
133 fn scaled(&self, scale: &RGBAColourD) -> Self {
134 u8::from_f32(self.to_f32() * scale.a as f32)
135 }
136
137 fn mix(&self, wet: &Self, mix: f32) -> Self {
138 if mix <= 0.0 {
139 *self
140 } else if mix >= 1.0 {
141 *wet
142 } else {
143 let a0 = mix;
144 let a1 = 1.0 - a0;
145 u8::from_f32(wet.to_f32() * a0 + self.to_f32() * a1)
146 }
147 }
148}
149
150impl ScaleMix for u16 {
151 fn scaled(&self, scale: &RGBAColourD) -> Self {
152 u16::from_f32(self.to_f32() * scale.a as f32)
153 }
154
155 fn mix(&self, wet: &Self, mix: f32) -> Self {
156 if mix <= 0.0 {
157 *self
158 } else if mix >= 1.0 {
159 *wet
160 } else {
161 let a0 = mix;
162 let a1 = 1.0 - a0;
163 u16::from_f32(wet.to_f32() * a0 + self.to_f32() * a1)
164 }
165 }
166}
167
168pub trait PixelFormat: Sized + Copy + Clone {
169 type ChannelValue: ChannelFormat;
170
171 #[inline]
172 fn num_components() -> usize {
173 std::mem::size_of::<Self>() / std::mem::size_of::<Self::ChannelValue>()
174 }
175
176 #[inline]
177 fn components() -> ImageComponent {
178 match Self::num_components() {
179 1 => ImageComponent::Alpha,
180 3 => ImageComponent::RGB,
181 4 => ImageComponent::RGBA,
182 _ => ImageComponent::RGBA, }
184 }
185
186 fn channel(&self, i: usize) -> &Self::ChannelValue;
187 fn channel_mut(&mut self, i: usize) -> &mut Self::ChannelValue;
188
189 #[inline]
190 fn num_bits_depth() -> usize {
191 8 * std::mem::size_of::<Self::ChannelValue>()
192 }
193
194 #[inline]
195 fn bit_depth() -> BitDepth {
196 match Self::num_bits_depth() {
197 8 => BitDepth::Byte,
198 16 => BitDepth::Short,
199 32 => BitDepth::Float,
200 _ => BitDepth::Float,
201 }
202 }
203}
204
205macro_rules! pixel_format_rgba {
206 ($rgba:ty, $channel_value:ty) => {
207 impl PixelFormat for $rgba {
208 type ChannelValue = $channel_value;
209 fn channel(&self, i: usize) -> &Self::ChannelValue {
210 match i {
211 0 => &self.r,
212 1 => &self.g,
213 2 => &self.b,
214 3 => &self.a,
215 _ => panic!("Index out of range"),
216 }
217 }
218 fn channel_mut(&mut self, i: usize) -> &mut Self::ChannelValue {
219 match i {
220 0 => &mut self.r,
221 1 => &mut self.g,
222 2 => &mut self.b,
223 3 => &mut self.a,
224 _ => panic!("Index out of range"),
225 }
226 }
227 }
228
229 impl PixelFormatRGB for $rgba {
230 #[inline]
231 fn r(&self) -> &Self::ChannelValue {
232 &self.r
233 }
234 #[inline]
235 fn r_mut(&mut self) -> &mut Self::ChannelValue {
236 &mut self.r
237 }
238 #[inline]
239 fn g(&self) -> &Self::ChannelValue {
240 &self.g
241 }
242 #[inline]
243 fn g_mut(&mut self) -> &mut Self::ChannelValue {
244 &mut self.g
245 }
246 #[inline]
247 fn b(&self) -> &Self::ChannelValue {
248 &self.b
249 }
250 #[inline]
251 fn b_mut(&mut self) -> &mut Self::ChannelValue {
252 &mut self.b
253 }
254 }
255
256 impl PixelFormatRGBA for $rgba {
257 fn new(
258 r: Self::ChannelValue,
259 g: Self::ChannelValue,
260 b: Self::ChannelValue,
261 a: Self::ChannelValue,
262 ) -> Self {
263 let mut instance: $rgba = unsafe { std::mem::uninitialized() };
264 instance.r = r;
265 instance.g = g;
266 instance.b = b;
267 instance.a = a;
268 instance
269 }
270
271 #[inline]
272 fn a(&self) -> &Self::ChannelValue {
273 &self.a
274 }
275 #[inline]
276 fn a_mut(&mut self) -> &mut Self::ChannelValue {
277 &mut self.a
278 }
279 }
280 };
281}
282
283macro_rules! pixel_format_yuva {
284 ($yuva:ty, $channel_value:ty) => {
285 impl PixelFormat for $yuva {
286 type ChannelValue = $channel_value;
287 fn channel(&self, i: usize) -> &Self::ChannelValue {
288 match i {
289 0 => &self.y,
290 1 => &self.u,
291 2 => &self.v,
292 3 => &self.a,
293 _ => panic!("Index out of range"),
294 }
295 }
296 fn channel_mut(&mut self, i: usize) -> &mut Self::ChannelValue {
297 match i {
298 0 => &mut self.y,
299 1 => &mut self.u,
300 2 => &mut self.v,
301 3 => &mut self.a,
302 _ => panic!("Index out of range"),
303 }
304 }
305 }
306 };
307}
308
309macro_rules! pixel_format_rgb {
310 ($rgb:ty, $channel_value:ty) => {
311 impl PixelFormat for $rgb {
312 type ChannelValue = $channel_value;
313 fn channel(&self, i: usize) -> &Self::ChannelValue {
314 match i {
315 0 => &self.r,
316 1 => &self.g,
317 2 => &self.b,
318 _ => panic!("Index out of range"),
319 }
320 }
321 fn channel_mut(&mut self, i: usize) -> &mut Self::ChannelValue {
322 match i {
323 0 => &mut self.r,
324 1 => &mut self.g,
325 2 => &mut self.b,
326 _ => panic!("Index out of range"),
327 }
328 }
329 }
330
331 impl PixelFormatRGB for $rgb {
332 #[inline]
333 fn r(&self) -> &Self::ChannelValue {
334 &self.r
335 }
336 #[inline]
337 fn r_mut(&mut self) -> &mut Self::ChannelValue {
338 &mut self.r
339 }
340 #[inline]
341 fn g(&self) -> &Self::ChannelValue {
342 &self.g
343 }
344 #[inline]
345 fn g_mut(&mut self) -> &mut Self::ChannelValue {
346 &mut self.g
347 }
348 #[inline]
349 fn b(&self) -> &Self::ChannelValue {
350 &self.b
351 }
352 #[inline]
353 fn b_mut(&mut self) -> &mut Self::ChannelValue {
354 &mut self.b
355 }
356 }
357 };
358}
359
360macro_rules! pixel_format_alpha {
361 ($channel_value:ty) => {
362 impl PixelFormat for $channel_value {
363 type ChannelValue = $channel_value;
364 fn channel(&self, i: usize) -> &Self::ChannelValue {
365 self
366 }
367 fn channel_mut(&mut self, i: usize) -> &mut Self::ChannelValue {
368 self
369 }
370 }
371
372 impl PixelFormatAlpha for $channel_value {}
373 };
374}
375
376pixel_format_rgba!(RGBAColourB, u8);
377pixel_format_rgba!(RGBAColourS, u16);
378pixel_format_rgba!(RGBAColourF, f32);
379pixel_format_rgb!(RGBColourB, u8);
380pixel_format_rgb!(RGBColourS, u16);
381pixel_format_rgb!(RGBColourF, f32);
382pixel_format_alpha!(u8);
383pixel_format_alpha!(u16);
384pixel_format_alpha!(f32);
385pixel_format_yuva!(YUVAColourB, u8);
386pixel_format_yuva!(YUVAColourS, u16);
387pixel_format_yuva!(YUVAColourF, f32);
388
389pub struct ImageBuffer<'a, T>
390where
391 T: PixelFormat,
392{
393 bounds: RectI,
394 row_bytes: isize,
395 t_size: usize,
396 data: &'a mut u8,
397 pixel_type: PhantomData<T>,
398}
399
400impl<'a, T> Clone for ImageBuffer<'a, T>
401where
402 T: PixelFormat,
403{
404 fn clone(&self) -> Self {
405 let data = self.data as *const u8;
407 ImageBuffer {
408 bounds: self.bounds,
409 row_bytes: self.row_bytes,
410 t_size: self.t_size,
411 data: unsafe { &mut *(data as *mut u8) },
412 pixel_type: PhantomData,
413 }
414 }
415}
416
417impl<'a, T> ImageBuffer<'a, T>
418where
419 T: PixelFormat,
420{
421 fn new(bounds: RectI, row_bytes: Int, data: *mut u8) -> Self {
422 let t_size = std::mem::size_of::<T>();
423 ImageBuffer {
424 bounds,
425 row_bytes: row_bytes as isize,
426 t_size,
427 data: unsafe { &mut *data },
428 pixel_type: PhantomData,
429 }
430 }
431
432 #[inline]
433 fn byte_offset(&self, x: Int, y: Int) -> isize {
434 (y - self.bounds.y1) as isize * self.row_bytes + (x - self.bounds.x1) as isize
435 }
436
437 fn bounds(&self) -> RectI {
438 self.bounds
439 }
440
441 fn bytes(&self) -> usize {
442 self.row_bytes.abs() as usize * (self.bounds.y2 - self.bounds.y1) as usize
443 }
444
445 fn dimensions(&self) -> (u32, u32) {
446 (
447 (self.bounds.x2 - self.bounds.x1) as u32,
448 (self.bounds.y2 - self.bounds.y1) as u32,
449 )
450 }
451
452 fn pixel_bytes(&self) -> usize {
453 self.t_size
454 }
455
456 fn ptr(&self, offset: isize) -> *const u8 {
457 unsafe {
458 let ptr: *const u8 = &*self.data;
459 ptr.offset(offset)
460 }
461 }
462
463 fn ptr_mut(&mut self, offset: isize) -> *mut u8 {
464 unsafe {
465 let ptr: *mut u8 = &mut *self.data;
466 ptr.offset(offset)
467 }
468 }
469
470 fn make_slice(&self, x: Int, y: Int, length: usize) -> &[T] {
471 let start = self.byte_offset(x, y);
472 unsafe { std::slice::from_raw_parts(self.ptr(start) as *const T, length) }
473 }
474
475 fn make_slice_mut(&mut self, x: Int, y: Int, length: usize) -> &mut [T] {
476 let start = self.byte_offset(x, y);
477 unsafe { std::slice::from_raw_parts_mut(self.ptr_mut(start) as *mut T, length) }
478 }
479
480 fn row(&self, y: Int) -> &[T] {
481 self.make_slice(
482 self.bounds.x1,
483 y,
484 (self.bounds.x2 - self.bounds.x1) as usize,
485 )
486 }
487
488 fn row_mut(&mut self, y: Int) -> &mut [T] {
489 let x1 = self.bounds.x1;
490 let x2 = self.bounds.x2;
491 self.make_slice_mut(x1, y, (x2 - x1) as usize)
492 }
493
494 fn chunk(&mut self, y1: Int, y2: Int) -> Self {
495 let y1 = y1.max(self.bounds.y1);
496 let y2 = y2.min(self.bounds.y2);
497 let bounds = RectI {
498 x1: self.bounds.x1,
499 y1,
500 x2: self.bounds.x2,
501 y2,
502 };
503 debug!("Chunk {}-{}", y1, y2);
504 let offset = self.byte_offset(self.bounds.x1, y1);
506 let ptr_mut = self.ptr_mut(offset);
507 let data = unsafe { &mut *ptr_mut };
508 ImageBuffer {
509 bounds,
510 row_bytes: self.row_bytes,
511 t_size: self.t_size,
512 data,
513 pixel_type: PhantomData,
514 }
515 }
516
517 pub fn chunks_mut(mut self, chunk_size: usize) -> impl Iterator<Item = ImageBuffer<'a, T>> {
518 let rows = (self.bounds.y2 - self.bounds.y1) as usize;
519 let n_chunks = (rows + chunk_size - 1) / chunk_size;
520 let rows_per_chunk = chunk_size;
521 let y1 = self.bounds.y1;
522 (0..n_chunks).map(move |chunk| {
523 self.chunk(
524 y1 + (chunk * rows_per_chunk) as Int,
525 y1 + ((chunk + 1) * rows_per_chunk) as Int,
526 )
527 })
528 }
529}
530
531pub struct Row<'a, T>
532where
533 T: PixelFormat,
534{
535 y: Int,
536 data: ImageBuffer<'a, T>,
537}
538
539pub struct RowWalk<'a, T>
540where
541 T: PixelFormat,
542{
543 data: ImageBuffer<'a, T>,
544 y: Int,
545 last_y: Int,
546}
547
548impl<'a, T> RowWalk<'a, T> where T: PixelFormat {}
549
550impl<'a, T> Iterator for RowWalk<'a, T>
551where
552 T: PixelFormat,
553{
554 type Item = Row<'a, T>;
555
556 fn next(&mut self) -> Option<Row<'a, T>> {
557 if self.y < self.last_y {
558 let row = Row {
559 data: self.data.clone(),
560 y: self.y,
561 };
562 self.y += 1;
563 Some(row)
564 } else {
565 None
566 }
567 }
568}
569
570#[derive(Clone)]
571pub struct ImageDescriptor<'a, T>
572where
573 T: PixelFormat,
574{
575 data: ImageBuffer<'a, T>,
576}
577
578pub struct ImageDescriptorMut<'a, T>
579where
580 T: PixelFormat,
581{
582 data: ImageBuffer<'a, T>,
583}
584
585pub struct ImageTileMut<'a, T>
586where
587 T: PixelFormat,
588{
589 pub y1: Int,
590 pub y2: Int,
591 data: ImageBuffer<'a, T>,
592}
593
594impl<'a, T> ImageDescriptor<'a, T>
595where
596 T: PixelFormat,
597{
598 pub fn new(bounds: RectI, row_bytes: Int, ptr: VoidPtrMut) -> Self {
599 ImageDescriptor {
600 data: ImageBuffer::new(bounds, row_bytes, ptr as *mut u8),
601 }
602 }
603
604 pub fn row(&self, y: Int) -> &[T] {
605 self.data.row(y)
606 }
607
608 pub fn row_range(&self, x1: Int, x2: Int, y: Int) -> &[T] {
609 let slice = self.row(y);
610 &slice[(x1 - self.data.bounds.x1) as usize..(x2 - self.data.bounds.x1) as usize]
611 }
612}
613
614impl<'a, T> ImageDescriptorMut<'a, T>
615where
616 T: PixelFormat,
617{
618 pub fn new(bounds: RectI, row_bytes: Int, ptr: VoidPtrMut) -> Self {
619 ImageDescriptorMut {
620 data: ImageBuffer::new(bounds, row_bytes, ptr as *mut u8),
621 }
622 }
623
624 pub fn row(&mut self, y: Int) -> &mut [T] {
625 self.data.row_mut(y)
626 }
627
628 pub fn row_range(&mut self, x1: Int, x2: Int, y: Int) -> &mut [T] {
629 let x0 = self.data.bounds.x1;
630 let slice = self.row(y);
631 let x1 = (x1 - x0) as usize;
632 let x2 = (x2 - x0) as usize;
633 &mut slice[x1..x2]
634 }
635
636 pub fn into_tiles(self, n_chunks: usize) -> Vec<ImageTileMut<'a, T>> {
637 let (width, height) = self.data.dimensions();
638 let rows_per_chunk = height as usize / n_chunks;
639 self.data
640 .chunks_mut(rows_per_chunk as usize)
641 .enumerate()
642 .map(|(chunk_index, chunk)| {
643 let y1 = (chunk_index * rows_per_chunk) as Int;
644 let y2 = (height as Int).min(y1 + rows_per_chunk as Int);
645 ImageTileMut::new(y1, y2, chunk)
646 })
647 .collect()
648 }
649}
650
651impl<'a, T> ImageTileMut<'a, T>
652where
653 T: PixelFormat,
654{
655 pub fn new(y1: Int, y2: Int, data: ImageBuffer<'a, T>) -> Self {
656 ImageTileMut { y1, y2, data }
657 }
658
659 pub fn row(&mut self, y: Int) -> &mut [T] {
660 self.data.row_mut(y)
661 }
662
663 pub fn row_range(&mut self, x1: Int, x2: Int, y: Int) -> &mut [T] {
664 let x0 = self.data.bounds.x1;
665 let slice = self.row(y);
666 let x1 = (x1 - x0) as usize;
667 let x2 = (x2 - x0) as usize;
668 &mut slice[x1..x2]
669 }
670}