1use crate::rendering_buffer::RowAccessor;
10
11pub trait ImageSource {
20 fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8];
22
23 fn next_x(&mut self) -> &[u8];
25
26 fn next_y(&mut self) -> &[u8];
28}
29
30impl<const PIX_WIDTH: usize> ImageSource for ImageAccessorClip<'_, PIX_WIDTH> {
31 fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
32 self.span(x, y, len)
33 }
34 fn next_x(&mut self) -> &[u8] {
35 self.next_x()
36 }
37 fn next_y(&mut self) -> &[u8] {
38 self.next_y()
39 }
40}
41
42impl<const PIX_WIDTH: usize> ImageSource for ImageAccessorNoClip<'_, PIX_WIDTH> {
43 fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
44 self.span(x, y, len)
45 }
46 fn next_x(&mut self) -> &[u8] {
47 self.next_x()
48 }
49 fn next_y(&mut self) -> &[u8] {
50 self.next_y()
51 }
52}
53
54impl<const PIX_WIDTH: usize> ImageSource for ImageAccessorClone<'_, PIX_WIDTH> {
55 fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
56 self.span(x, y, len)
57 }
58 fn next_x(&mut self) -> &[u8] {
59 self.next_x()
60 }
61 fn next_y(&mut self) -> &[u8] {
62 self.next_y()
63 }
64}
65
66impl<const PIX_WIDTH: usize, WX: WrapMode, WY: WrapMode> ImageSource
67 for ImageAccessorWrap<'_, PIX_WIDTH, WX, WY>
68{
69 fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
70 self.span(x, y, len)
71 }
72 fn next_x(&mut self) -> &[u8] {
73 self.next_x()
74 }
75 fn next_y(&mut self) -> &[u8] {
76 self.next_y()
77 }
78}
79
80pub trait WrapMode {
86 fn new(size: u32) -> Self;
88
89 fn func(&mut self, v: i32) -> u32;
91
92 fn inc(&mut self) -> u32;
94}
95
96pub struct WrapModeRepeat {
104 size: u32,
105 add: u32,
106 value: u32,
107}
108
109impl WrapMode for WrapModeRepeat {
110 fn new(size: u32) -> Self {
111 Self {
112 size,
113 add: size.wrapping_mul(0x3FFF_FFFF / size),
114 value: 0,
115 }
116 }
117
118 #[inline]
119 fn func(&mut self, v: i32) -> u32 {
120 self.value = (v as u32).wrapping_add(self.add) % self.size;
121 self.value
122 }
123
124 #[inline]
125 fn inc(&mut self) -> u32 {
126 self.value += 1;
127 if self.value >= self.size {
128 self.value = 0;
129 }
130 self.value
131 }
132}
133
134pub struct WrapModeRepeatPow2 {
142 mask: u32,
143 value: u32,
144}
145
146impl WrapMode for WrapModeRepeatPow2 {
147 fn new(size: u32) -> Self {
148 let mut mask = 1u32;
149 while mask < size {
150 mask = (mask << 1) | 1;
151 }
152 mask >>= 1;
153 Self { mask, value: 0 }
154 }
155
156 #[inline]
157 fn func(&mut self, v: i32) -> u32 {
158 self.value = v as u32 & self.mask;
159 self.value
160 }
161
162 #[inline]
163 fn inc(&mut self) -> u32 {
164 self.value += 1;
165 if self.value > self.mask {
166 self.value = 0;
167 }
168 self.value
169 }
170}
171
172pub struct WrapModeRepeatAutoPow2 {
180 size: u32,
181 add: u32,
182 mask: u32,
183 value: u32,
184}
185
186impl WrapMode for WrapModeRepeatAutoPow2 {
187 fn new(size: u32) -> Self {
188 let mask = if size & (size - 1) == 0 { size - 1 } else { 0 };
189 Self {
190 size,
191 add: size.wrapping_mul(0x3FFF_FFFF / size),
192 mask,
193 value: 0,
194 }
195 }
196
197 #[inline]
198 fn func(&mut self, v: i32) -> u32 {
199 if self.mask != 0 {
200 self.value = v as u32 & self.mask;
201 } else {
202 self.value = (v as u32).wrapping_add(self.add) % self.size;
203 }
204 self.value
205 }
206
207 #[inline]
208 fn inc(&mut self) -> u32 {
209 self.value += 1;
210 if self.value >= self.size {
211 self.value = 0;
212 }
213 self.value
214 }
215}
216
217pub struct WrapModeReflect {
225 size: u32,
226 size2: u32,
227 add: u32,
228 value: u32,
229}
230
231impl WrapMode for WrapModeReflect {
232 fn new(size: u32) -> Self {
233 let size2 = size * 2;
234 Self {
235 size,
236 size2,
237 add: size2.wrapping_mul(0x3FFF_FFFF / size2),
238 value: 0,
239 }
240 }
241
242 #[inline]
243 fn func(&mut self, v: i32) -> u32 {
244 self.value = (v as u32).wrapping_add(self.add) % self.size2;
245 if self.value >= self.size {
246 self.size2 - self.value - 1
247 } else {
248 self.value
249 }
250 }
251
252 #[inline]
253 fn inc(&mut self) -> u32 {
254 self.value += 1;
255 if self.value >= self.size2 {
256 self.value = 0;
257 }
258 if self.value >= self.size {
259 self.size2 - self.value - 1
260 } else {
261 self.value
262 }
263 }
264}
265
266pub struct WrapModeReflectPow2 {
274 size: u32,
275 mask: u32,
276 value: u32,
277}
278
279impl WrapMode for WrapModeReflectPow2 {
280 fn new(size: u32) -> Self {
281 let mut mask = 1u32;
282 let mut sz = 1u32;
283 while mask < size {
284 mask = (mask << 1) | 1;
285 sz <<= 1;
286 }
287 Self {
288 size: sz,
289 mask,
290 value: 0,
291 }
292 }
293
294 #[inline]
295 fn func(&mut self, v: i32) -> u32 {
296 self.value = v as u32 & self.mask;
297 if self.value >= self.size {
298 self.mask - self.value
299 } else {
300 self.value
301 }
302 }
303
304 #[inline]
305 fn inc(&mut self) -> u32 {
306 self.value += 1;
307 self.value &= self.mask;
308 if self.value >= self.size {
309 self.mask - self.value
310 } else {
311 self.value
312 }
313 }
314}
315
316pub struct WrapModeReflectAutoPow2 {
324 size: u32,
325 size2: u32,
326 add: u32,
327 mask: u32,
328 value: u32,
329}
330
331impl WrapMode for WrapModeReflectAutoPow2 {
332 fn new(size: u32) -> Self {
333 let size2 = size * 2;
334 let mask = if size2 & (size2 - 1) == 0 {
335 size2 - 1
336 } else {
337 0
338 };
339 Self {
340 size,
341 size2,
342 add: size2.wrapping_mul(0x3FFF_FFFF / size2),
343 mask,
344 value: 0,
345 }
346 }
347
348 #[inline]
349 fn func(&mut self, v: i32) -> u32 {
350 self.value = if self.mask != 0 {
351 v as u32 & self.mask
352 } else {
353 (v as u32).wrapping_add(self.add) % self.size2
354 };
355 if self.value >= self.size {
356 self.size2 - self.value - 1
357 } else {
358 self.value
359 }
360 }
361
362 #[inline]
363 fn inc(&mut self) -> u32 {
364 self.value += 1;
365 if self.value >= self.size2 {
366 self.value = 0;
367 }
368 if self.value >= self.size {
369 self.size2 - self.value - 1
370 } else {
371 self.value
372 }
373 }
374}
375
376pub struct ImageAccessorClip<'a, const PIX_WIDTH: usize> {
384 rbuf: &'a RowAccessor,
385 bk_buf: [u8; 8], x: i32,
387 x0: i32,
388 y: i32,
389 fast_path: bool,
390 pix_off: usize,
391}
392
393impl<'a, const PIX_WIDTH: usize> ImageAccessorClip<'a, PIX_WIDTH> {
394 pub fn new(rbuf: &'a RowAccessor, bk_color: &[u8]) -> Self {
395 let mut bk_buf = [0u8; 8];
396 let len = bk_color.len().min(8);
397 bk_buf[..len].copy_from_slice(&bk_color[..len]);
398 Self {
399 rbuf,
400 bk_buf,
401 x: 0,
402 x0: 0,
403 y: 0,
404 fast_path: false,
405 pix_off: 0,
406 }
407 }
408
409 pub fn set_background(&mut self, bk_color: &[u8]) {
410 let len = bk_color.len().min(8);
411 self.bk_buf[..len].copy_from_slice(&bk_color[..len]);
412 }
413
414 fn pixel(&self) -> &[u8] {
415 if self.y >= 0
416 && self.y < self.rbuf.height() as i32
417 && self.x >= 0
418 && self.x < self.rbuf.width() as i32
419 {
420 let row = self.rbuf.row_slice(self.y as u32);
421 let off = self.x as usize * PIX_WIDTH;
422 &row[off..off + PIX_WIDTH]
423 } else {
424 &self.bk_buf[..PIX_WIDTH]
425 }
426 }
427
428 pub fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
429 self.x = x;
430 self.x0 = x;
431 self.y = y;
432 if y >= 0
433 && y < self.rbuf.height() as i32
434 && x >= 0
435 && (x + len as i32) <= self.rbuf.width() as i32
436 {
437 self.fast_path = true;
438 self.pix_off = x as usize * PIX_WIDTH;
439 let row = self.rbuf.row_slice(y as u32);
440 &row[self.pix_off..self.pix_off + PIX_WIDTH]
441 } else {
442 self.fast_path = false;
443 self.pixel()
444 }
445 }
446
447 pub fn next_x(&mut self) -> &[u8] {
448 if self.fast_path {
449 self.pix_off += PIX_WIDTH;
450 let row = self.rbuf.row_slice(self.y as u32);
451 &row[self.pix_off..self.pix_off + PIX_WIDTH]
452 } else {
453 self.x += 1;
454 self.pixel()
455 }
456 }
457
458 pub fn next_y(&mut self) -> &[u8] {
459 self.y += 1;
460 self.x = self.x0;
461 if self.fast_path && self.y >= 0 && self.y < self.rbuf.height() as i32 {
462 self.pix_off = self.x as usize * PIX_WIDTH;
463 let row = self.rbuf.row_slice(self.y as u32);
464 &row[self.pix_off..self.pix_off + PIX_WIDTH]
465 } else {
466 self.fast_path = false;
467 self.pixel()
468 }
469 }
470}
471
472pub struct ImageAccessorNoClip<'a, const PIX_WIDTH: usize> {
480 rbuf: &'a RowAccessor,
481 x: i32,
482 y: i32,
483 pix_off: usize,
484}
485
486impl<'a, const PIX_WIDTH: usize> ImageAccessorNoClip<'a, PIX_WIDTH> {
487 pub fn new(rbuf: &'a RowAccessor) -> Self {
488 Self {
489 rbuf,
490 x: 0,
491 y: 0,
492 pix_off: 0,
493 }
494 }
495
496 pub fn span(&mut self, x: i32, y: i32, _len: u32) -> &[u8] {
497 self.x = x;
498 self.y = y;
499 self.pix_off = x as usize * PIX_WIDTH;
500 let row = self.rbuf.row_slice(y as u32);
501 &row[self.pix_off..self.pix_off + PIX_WIDTH]
502 }
503
504 pub fn next_x(&mut self) -> &[u8] {
505 self.pix_off += PIX_WIDTH;
506 let row = self.rbuf.row_slice(self.y as u32);
507 &row[self.pix_off..self.pix_off + PIX_WIDTH]
508 }
509
510 pub fn next_y(&mut self) -> &[u8] {
511 self.y += 1;
512 self.pix_off = self.x as usize * PIX_WIDTH;
513 let row = self.rbuf.row_slice(self.y as u32);
514 &row[self.pix_off..self.pix_off + PIX_WIDTH]
515 }
516}
517
518pub struct ImageAccessorClone<'a, const PIX_WIDTH: usize> {
526 rbuf: &'a RowAccessor,
527 x: i32,
528 x0: i32,
529 y: i32,
530 fast_path: bool,
531 pix_off: usize,
532}
533
534impl<'a, const PIX_WIDTH: usize> ImageAccessorClone<'a, PIX_WIDTH> {
535 pub fn new(rbuf: &'a RowAccessor) -> Self {
536 Self {
537 rbuf,
538 x: 0,
539 x0: 0,
540 y: 0,
541 fast_path: false,
542 pix_off: 0,
543 }
544 }
545
546 fn pixel(&self) -> &[u8] {
547 let cx = self.x.max(0).min(self.rbuf.width() as i32 - 1);
548 let cy = self.y.max(0).min(self.rbuf.height() as i32 - 1);
549 let row = self.rbuf.row_slice(cy as u32);
550 let off = cx as usize * PIX_WIDTH;
551 &row[off..off + PIX_WIDTH]
552 }
553
554 pub fn span(&mut self, x: i32, y: i32, len: u32) -> &[u8] {
555 self.x = x;
556 self.x0 = x;
557 self.y = y;
558 if y >= 0
559 && y < self.rbuf.height() as i32
560 && x >= 0
561 && (x + len as i32) <= self.rbuf.width() as i32
562 {
563 self.fast_path = true;
564 self.pix_off = x as usize * PIX_WIDTH;
565 let row = self.rbuf.row_slice(y as u32);
566 &row[self.pix_off..self.pix_off + PIX_WIDTH]
567 } else {
568 self.fast_path = false;
569 self.pixel()
570 }
571 }
572
573 pub fn next_x(&mut self) -> &[u8] {
574 if self.fast_path {
575 self.pix_off += PIX_WIDTH;
576 let row = self.rbuf.row_slice(self.y as u32);
577 &row[self.pix_off..self.pix_off + PIX_WIDTH]
578 } else {
579 self.x += 1;
580 self.pixel()
581 }
582 }
583
584 pub fn next_y(&mut self) -> &[u8] {
585 self.y += 1;
586 self.x = self.x0;
587 if self.fast_path && self.y >= 0 && self.y < self.rbuf.height() as i32 {
588 self.pix_off = self.x as usize * PIX_WIDTH;
589 let row = self.rbuf.row_slice(self.y as u32);
590 &row[self.pix_off..self.pix_off + PIX_WIDTH]
591 } else {
592 self.fast_path = false;
593 self.pixel()
594 }
595 }
596}
597
598pub struct ImageAccessorWrap<'a, const PIX_WIDTH: usize, WX: WrapMode, WY: WrapMode> {
606 rbuf: &'a RowAccessor,
607 x: i32,
608 wrap_x: WX,
609 wrap_y: WY,
610 row_y: u32,
611}
612
613impl<'a, const PIX_WIDTH: usize, WX: WrapMode, WY: WrapMode>
614 ImageAccessorWrap<'a, PIX_WIDTH, WX, WY>
615{
616 pub fn new(rbuf: &'a RowAccessor) -> Self {
617 Self {
618 rbuf,
619 x: 0,
620 wrap_x: WX::new(rbuf.width()),
621 wrap_y: WY::new(rbuf.height()),
622 row_y: 0,
623 }
624 }
625
626 pub fn span(&mut self, x: i32, y: i32, _len: u32) -> &[u8] {
627 self.x = x;
628 self.row_y = self.wrap_y.func(y);
629 let wx = self.wrap_x.func(x) as usize * PIX_WIDTH;
630 let row = self.rbuf.row_slice(self.row_y);
631 &row[wx..wx + PIX_WIDTH]
632 }
633
634 pub fn next_x(&mut self) -> &[u8] {
635 let wx = self.wrap_x.inc() as usize * PIX_WIDTH;
636 let row = self.rbuf.row_slice(self.row_y);
637 &row[wx..wx + PIX_WIDTH]
638 }
639
640 pub fn next_y(&mut self) -> &[u8] {
641 self.row_y = self.wrap_y.inc();
642 let wx = self.wrap_x.func(self.x) as usize * PIX_WIDTH;
643 let row = self.rbuf.row_slice(self.row_y);
644 &row[wx..wx + PIX_WIDTH]
645 }
646}
647
648#[cfg(test)]
653mod tests {
654 use super::*;
655
656 fn make_rgba_buffer(width: u32, height: u32, data: &mut Vec<u8>) -> RowAccessor {
657 let stride = width as usize * 4;
658 data.resize(stride * height as usize, 0);
659 unsafe { RowAccessor::new_with_buf(data.as_mut_ptr(), width, height, stride as i32) }
660 }
661
662 fn set_rgba_pixel(data: &mut [u8], width: u32, x: u32, y: u32, rgba: [u8; 4]) {
663 let off = (y * width * 4 + x * 4) as usize;
664 data[off..off + 4].copy_from_slice(&rgba);
665 }
666
667 #[test]
670 fn test_wrap_repeat() {
671 let mut w = WrapModeRepeat::new(4);
672 assert_eq!(w.func(0), 0);
673 assert_eq!(w.func(3), 3);
674 assert_eq!(w.func(4), 0);
675 assert_eq!(w.func(5), 1);
676 assert_eq!(w.func(-1), 3);
677 }
678
679 #[test]
680 fn test_wrap_repeat_inc() {
681 let mut w = WrapModeRepeat::new(3);
682 w.func(0);
683 assert_eq!(w.inc(), 1);
684 assert_eq!(w.inc(), 2);
685 assert_eq!(w.inc(), 0); }
687
688 #[test]
689 fn test_wrap_repeat_pow2() {
690 let mut w = WrapModeRepeatPow2::new(4); assert_eq!(w.func(0), 0);
692 assert_eq!(w.func(3), 3);
693 assert_eq!(w.func(4), 0);
694 assert_eq!(w.func(7), 3);
695 }
696
697 #[test]
698 fn test_wrap_reflect() {
699 let mut w = WrapModeReflect::new(4); assert_eq!(w.func(0), 0);
701 assert_eq!(w.func(3), 3);
702 assert_eq!(w.func(4), 3); assert_eq!(w.func(7), 0); }
705
706 #[test]
707 fn test_wrap_reflect_inc() {
708 let mut w = WrapModeReflect::new(3); w.func(0);
710 assert_eq!(w.inc(), 1);
711 assert_eq!(w.inc(), 2);
712 assert_eq!(w.inc(), 2); assert_eq!(w.inc(), 1); assert_eq!(w.inc(), 0); assert_eq!(w.inc(), 0); }
717
718 #[test]
719 fn test_wrap_repeat_auto_pow2() {
720 let mut w = WrapModeRepeatAutoPow2::new(8);
722 assert_eq!(w.func(8), 0);
723 assert_eq!(w.func(9), 1);
724
725 let mut w2 = WrapModeRepeatAutoPow2::new(5);
727 assert_eq!(w2.func(5), 0);
728 assert_eq!(w2.func(7), 2);
729 }
730
731 #[test]
732 fn test_wrap_reflect_pow2() {
733 let mut w = WrapModeReflectPow2::new(4);
734 assert_eq!(w.func(0), 0);
735 assert_eq!(w.func(3), 3);
736 assert_eq!(w.func(4), 3); assert_eq!(w.func(7), 0); }
739
740 #[test]
743 fn test_clip_in_bounds() {
744 let mut data = Vec::new();
745 let rbuf = make_rgba_buffer(4, 4, &mut data);
746 set_rgba_pixel(&mut data, 4, 1, 1, [10, 20, 30, 40]);
747
748 let mut acc = ImageAccessorClip::<4>::new(&rbuf, &[0, 0, 0, 0]);
749 let pix = acc.span(1, 1, 1);
750 assert_eq!(&pix[..4], &[10, 20, 30, 40]);
751 }
752
753 #[test]
754 fn test_clip_out_of_bounds() {
755 let mut data = Vec::new();
756 let rbuf = make_rgba_buffer(4, 4, &mut data);
757
758 let mut acc = ImageAccessorClip::<4>::new(&rbuf, &[99, 88, 77, 66]);
759 let pix = acc.span(-1, 0, 1);
760 assert_eq!(&pix[..4], &[99, 88, 77, 66]);
761 }
762
763 #[test]
764 fn test_clip_span_fast_path() {
765 let mut data = Vec::new();
766 let rbuf = make_rgba_buffer(4, 4, &mut data);
767 set_rgba_pixel(&mut data, 4, 0, 0, [1, 2, 3, 4]);
768 set_rgba_pixel(&mut data, 4, 1, 0, [5, 6, 7, 8]);
769
770 let mut acc = ImageAccessorClip::<4>::new(&rbuf, &[0, 0, 0, 0]);
771 let pix = acc.span(0, 0, 2);
772 assert_eq!(&pix[..4], &[1, 2, 3, 4]);
773 let pix = acc.next_x();
774 assert_eq!(&pix[..4], &[5, 6, 7, 8]);
775 }
776
777 #[test]
780 fn test_no_clip_span() {
781 let mut data = Vec::new();
782 let rbuf = make_rgba_buffer(4, 4, &mut data);
783 set_rgba_pixel(&mut data, 4, 2, 1, [11, 22, 33, 44]);
784
785 let mut acc = ImageAccessorNoClip::<4>::new(&rbuf);
786 let pix = acc.span(2, 1, 1);
787 assert_eq!(&pix[..4], &[11, 22, 33, 44]);
788 }
789
790 #[test]
791 fn test_no_clip_next_x() {
792 let mut data = Vec::new();
793 let rbuf = make_rgba_buffer(4, 4, &mut data);
794 set_rgba_pixel(&mut data, 4, 0, 0, [10, 0, 0, 0]);
795 set_rgba_pixel(&mut data, 4, 1, 0, [20, 0, 0, 0]);
796 set_rgba_pixel(&mut data, 4, 2, 0, [30, 0, 0, 0]);
797
798 let mut acc = ImageAccessorNoClip::<4>::new(&rbuf);
799 acc.span(0, 0, 3);
800 let p1 = acc.next_x();
801 assert_eq!(p1[0], 20);
802 let p2 = acc.next_x();
803 assert_eq!(p2[0], 30);
804 }
805
806 #[test]
809 fn test_clone_in_bounds() {
810 let mut data = Vec::new();
811 let rbuf = make_rgba_buffer(4, 4, &mut data);
812 set_rgba_pixel(&mut data, 4, 1, 1, [50, 60, 70, 80]);
813
814 let mut acc = ImageAccessorClone::<4>::new(&rbuf);
815 let pix = acc.span(1, 1, 1);
816 assert_eq!(&pix[..4], &[50, 60, 70, 80]);
817 }
818
819 #[test]
820 fn test_clone_clamps_negative() {
821 let mut data = Vec::new();
822 let rbuf = make_rgba_buffer(4, 4, &mut data);
823 set_rgba_pixel(&mut data, 4, 0, 0, [10, 20, 30, 40]);
824
825 let mut acc = ImageAccessorClone::<4>::new(&rbuf);
826 let pix = acc.span(-5, -3, 1);
827 assert_eq!(&pix[..4], &[10, 20, 30, 40]);
829 }
830
831 #[test]
832 fn test_clone_clamps_overflow() {
833 let mut data = Vec::new();
834 let rbuf = make_rgba_buffer(4, 4, &mut data);
835 set_rgba_pixel(&mut data, 4, 3, 3, [99, 88, 77, 66]);
836
837 let mut acc = ImageAccessorClone::<4>::new(&rbuf);
838 let pix = acc.span(100, 100, 1);
839 assert_eq!(&pix[..4], &[99, 88, 77, 66]);
841 }
842
843 #[test]
846 fn test_wrap_repeat_access() {
847 let mut data = Vec::new();
848 let rbuf = make_rgba_buffer(2, 2, &mut data);
849 set_rgba_pixel(&mut data, 2, 0, 0, [10, 0, 0, 0]);
850 set_rgba_pixel(&mut data, 2, 1, 0, [20, 0, 0, 0]);
851 set_rgba_pixel(&mut data, 2, 0, 1, [30, 0, 0, 0]);
852 set_rgba_pixel(&mut data, 2, 1, 1, [40, 0, 0, 0]);
853
854 let mut acc = ImageAccessorWrap::<4, WrapModeRepeat, WrapModeRepeat>::new(&rbuf);
855 let pix = acc.span(2, 0, 1);
857 assert_eq!(pix[0], 10);
858 let pix = acc.next_x();
860 assert_eq!(pix[0], 20);
861 }
862
863 #[test]
864 fn test_wrap_next_y() {
865 let mut data = Vec::new();
866 let rbuf = make_rgba_buffer(2, 2, &mut data);
867 set_rgba_pixel(&mut data, 2, 0, 0, [10, 0, 0, 0]);
868 set_rgba_pixel(&mut data, 2, 0, 1, [30, 0, 0, 0]);
869
870 let mut acc = ImageAccessorWrap::<4, WrapModeRepeat, WrapModeRepeat>::new(&rbuf);
871 acc.span(0, 0, 1);
872 let pix = acc.next_y();
873 assert_eq!(pix[0], 30);
874 }
875}