Skip to main content

singe_npp/image/
exchange_channels.rs

1use super::*;
2
3pub(crate) fn extract_channel_u8_c3(
4    stream_context: &StreamContext,
5    source: &ImageView<'_, u8, C3>,
6    destination: &mut ImageViewMut<'_, u8, C1>,
7    channel: usize,
8) -> Result<()> {
9    validate_same_size(source.size(), destination.size())?;
10    validate_channel_index(channel, 3)?;
11
12    unsafe {
13        try_ffi!(sys::nppiCopy_8u_C3C1R_Ctx(
14            source.as_ptr().add(channel),
15            source.step(),
16            destination.as_mut_ptr().cast(),
17            destination.step(),
18            source.size().into(),
19            stream_context.as_raw(),
20        ))?;
21    }
22    Ok(())
23}
24
25pub(crate) fn extract_channel_u8_c4(
26    stream_context: &StreamContext,
27    source: &ImageView<'_, u8, C4>,
28    destination: &mut ImageViewMut<'_, u8, C1>,
29    channel: usize,
30) -> Result<()> {
31    validate_same_size(source.size(), destination.size())?;
32    validate_channel_index(channel, 4)?;
33
34    unsafe {
35        try_ffi!(sys::nppiCopy_8u_C4C1R_Ctx(
36            source.as_ptr().add(channel),
37            source.step(),
38            destination.as_mut_ptr().cast(),
39            destination.step(),
40            source.size().into(),
41            stream_context.as_raw(),
42        ))?;
43    }
44    Ok(())
45}
46
47impl_extract_channel!(extract_channel_u16_c3, u16, C3, 3, nppiCopy_16u_C3C1R_Ctx);
48impl_extract_channel!(extract_channel_u16_c4, u16, C4, 4, nppiCopy_16u_C4C1R_Ctx);
49impl_extract_channel!(extract_channel_i16_c3, i16, C3, 3, nppiCopy_16s_C3C1R_Ctx);
50impl_extract_channel!(extract_channel_i16_c4, i16, C4, 4, nppiCopy_16s_C4C1R_Ctx);
51impl_extract_channel!(extract_channel_i32_c3, i32, C3, 3, nppiCopy_32s_C3C1R_Ctx);
52impl_extract_channel!(extract_channel_i32_c4, i32, C4, 4, nppiCopy_32s_C4C1R_Ctx);
53impl_extract_channel!(extract_channel_f32_c2, f32, C2, 2, nppiCopy_32f_C2C1R_Ctx);
54impl_extract_channel!(extract_channel_f32_c3, f32, C3, 3, nppiCopy_32f_C3C1R_Ctx);
55impl_extract_channel!(extract_channel_f32_c4, f32, C4, 4, nppiCopy_32f_C4C1R_Ctx);
56impl_generic_extract_channel_operation!(
57    ExtractChannelC2,
58    extract_channel_c2,
59    C2,
60    [f32 => extract_channel_f32_c2]
61);
62impl_generic_extract_channel_operation!(
63    ExtractChannelC3,
64    extract_channel_c3,
65    C3,
66    [
67        u8 => extract_channel_u8_c3,
68        u16 => extract_channel_u16_c3,
69        i16 => extract_channel_i16_c3,
70        i32 => extract_channel_i32_c3,
71        f32 => extract_channel_f32_c3,
72    ]
73);
74impl_generic_extract_channel_operation!(
75    ExtractChannelC4,
76    extract_channel_c4,
77    C4,
78    [
79        u8 => extract_channel_u8_c4,
80        u16 => extract_channel_u16_c4,
81        i16 => extract_channel_i16_c4,
82        i32 => extract_channel_i32_c4,
83        f32 => extract_channel_f32_c4,
84    ]
85);
86
87pub(crate) fn set_channel_u8_c3(
88    stream_context: &StreamContext,
89    destination: &mut ImageViewMut<'_, u8, C3>,
90    value: u8,
91    channel: usize,
92) -> Result<()> {
93    validate_channel_index(channel, 3)?;
94
95    unsafe {
96        try_ffi!(sys::nppiSet_8u_C3CR_Ctx(
97            value,
98            destination.as_mut_ptr().add(channel),
99            destination.step(),
100            destination.size().into(),
101            stream_context.as_raw(),
102        ))?;
103    }
104    Ok(())
105}
106
107pub(crate) fn set_channel_u8_c4(
108    stream_context: &StreamContext,
109    destination: &mut ImageViewMut<'_, u8, C4>,
110    value: u8,
111    channel: usize,
112) -> Result<()> {
113    validate_channel_index(channel, 4)?;
114
115    unsafe {
116        try_ffi!(sys::nppiSet_8u_C4CR_Ctx(
117            value,
118            destination.as_mut_ptr().add(channel),
119            destination.step(),
120            destination.size().into(),
121            stream_context.as_raw(),
122        ))?;
123    }
124    Ok(())
125}
126
127pub(crate) fn set_channel_u16_c3(
128    stream_context: &StreamContext,
129    destination: &mut ImageViewMut<'_, u16, C3>,
130    value: u16,
131    channel: usize,
132) -> Result<()> {
133    validate_channel_index(channel, 3)?;
134
135    unsafe {
136        try_ffi!(sys::nppiSet_16u_C3CR_Ctx(
137            value,
138            destination.as_mut_ptr().add(channel),
139            destination.step(),
140            destination.size().into(),
141            stream_context.as_raw(),
142        ))?;
143    }
144    Ok(())
145}
146
147pub(crate) fn set_channel_u16_c4(
148    stream_context: &StreamContext,
149    destination: &mut ImageViewMut<'_, u16, C4>,
150    value: u16,
151    channel: usize,
152) -> Result<()> {
153    validate_channel_index(channel, 4)?;
154
155    unsafe {
156        try_ffi!(sys::nppiSet_16u_C4CR_Ctx(
157            value,
158            destination.as_mut_ptr().add(channel),
159            destination.step(),
160            destination.size().into(),
161            stream_context.as_raw(),
162        ))?;
163    }
164    Ok(())
165}
166
167pub(crate) fn set_channel_i16_c3(
168    stream_context: &StreamContext,
169    destination: &mut ImageViewMut<'_, i16, C3>,
170    value: i16,
171    channel: usize,
172) -> Result<()> {
173    validate_channel_index(channel, 3)?;
174
175    unsafe {
176        try_ffi!(sys::nppiSet_16s_C3CR_Ctx(
177            value,
178            destination.as_mut_ptr().add(channel),
179            destination.step(),
180            destination.size().into(),
181            stream_context.as_raw(),
182        ))?;
183    }
184    Ok(())
185}
186
187pub(crate) fn set_channel_i16_c4(
188    stream_context: &StreamContext,
189    destination: &mut ImageViewMut<'_, i16, C4>,
190    value: i16,
191    channel: usize,
192) -> Result<()> {
193    validate_channel_index(channel, 4)?;
194
195    unsafe {
196        try_ffi!(sys::nppiSet_16s_C4CR_Ctx(
197            value,
198            destination.as_mut_ptr().add(channel),
199            destination.step(),
200            destination.size().into(),
201            stream_context.as_raw(),
202        ))?;
203    }
204    Ok(())
205}
206
207pub(crate) fn set_channel_i32_c3(
208    stream_context: &StreamContext,
209    destination: &mut ImageViewMut<'_, i32, C3>,
210    value: i32,
211    channel: usize,
212) -> Result<()> {
213    validate_channel_index(channel, 3)?;
214
215    unsafe {
216        try_ffi!(sys::nppiSet_32s_C3CR_Ctx(
217            value,
218            destination.as_mut_ptr().add(channel),
219            destination.step(),
220            destination.size().into(),
221            stream_context.as_raw(),
222        ))?;
223    }
224    Ok(())
225}
226
227pub(crate) fn set_channel_i32_c4(
228    stream_context: &StreamContext,
229    destination: &mut ImageViewMut<'_, i32, C4>,
230    value: i32,
231    channel: usize,
232) -> Result<()> {
233    validate_channel_index(channel, 4)?;
234
235    unsafe {
236        try_ffi!(sys::nppiSet_32s_C4CR_Ctx(
237            value,
238            destination.as_mut_ptr().add(channel),
239            destination.step(),
240            destination.size().into(),
241            stream_context.as_raw(),
242        ))?;
243    }
244    Ok(())
245}
246
247pub(crate) fn set_channel_f32_c3(
248    stream_context: &StreamContext,
249    destination: &mut ImageViewMut<'_, f32, C3>,
250    value: f32,
251    channel: usize,
252) -> Result<()> {
253    validate_channel_index(channel, 3)?;
254
255    unsafe {
256        try_ffi!(sys::nppiSet_32f_C3CR_Ctx(
257            value,
258            destination.as_mut_ptr().add(channel),
259            destination.step(),
260            destination.size().into(),
261            stream_context.as_raw(),
262        ))?;
263    }
264    Ok(())
265}
266
267pub(crate) fn set_channel_f32_c4(
268    stream_context: &StreamContext,
269    destination: &mut ImageViewMut<'_, f32, C4>,
270    value: f32,
271    channel: usize,
272) -> Result<()> {
273    validate_channel_index(channel, 4)?;
274
275    unsafe {
276        try_ffi!(sys::nppiSet_32f_C4CR_Ctx(
277            value,
278            destination.as_mut_ptr().add(channel),
279            destination.step(),
280            destination.size().into(),
281            stream_context.as_raw(),
282        ))?;
283    }
284    Ok(())
285}
286impl_generic_set_channel_operation!(
287    SetChannelC3,
288    set_channel_c3,
289    C3,
290    [
291        u8 => set_channel_u8_c3,
292        u16 => set_channel_u16_c3,
293        i16 => set_channel_i16_c3,
294        i32 => set_channel_i32_c3,
295        f32 => set_channel_f32_c3,
296    ]
297);
298impl_generic_set_channel_operation!(
299    SetChannelC4,
300    set_channel_c4,
301    C4,
302    [
303        u8 => set_channel_u8_c4,
304        u16 => set_channel_u16_c4,
305        i16 => set_channel_i16_c4,
306        i32 => set_channel_i32_c4,
307        f32 => set_channel_f32_c4,
308    ]
309);
310
311pub(crate) fn insert_channel_u8_c3(
312    stream_context: &StreamContext,
313    source: &ImageView<'_, u8, C1>,
314    destination: &mut ImageViewMut<'_, u8, C3>,
315    channel: usize,
316) -> Result<()> {
317    validate_same_size(source.size(), destination.size())?;
318    validate_channel_index(channel, 3)?;
319
320    unsafe {
321        try_ffi!(sys::nppiCopy_8u_C1C3R_Ctx(
322            source.as_ptr().cast(),
323            source.step(),
324            destination.as_mut_ptr().add(channel),
325            destination.step(),
326            source.size().into(),
327            stream_context.as_raw(),
328        ))?;
329    }
330    Ok(())
331}
332
333pub(crate) fn insert_channel_u8_c4(
334    stream_context: &StreamContext,
335    source: &ImageView<'_, u8, C1>,
336    destination: &mut ImageViewMut<'_, u8, C4>,
337    channel: usize,
338) -> Result<()> {
339    validate_same_size(source.size(), destination.size())?;
340    validate_channel_index(channel, 4)?;
341
342    unsafe {
343        try_ffi!(sys::nppiCopy_8u_C1C4R_Ctx(
344            source.as_ptr().cast(),
345            source.step(),
346            destination.as_mut_ptr().add(channel),
347            destination.step(),
348            source.size().into(),
349            stream_context.as_raw(),
350        ))?;
351    }
352    Ok(())
353}
354
355impl_insert_channel!(insert_channel_u16_c3, u16, C3, 3, nppiCopy_16u_C1C3R_Ctx);
356impl_insert_channel!(insert_channel_u16_c4, u16, C4, 4, nppiCopy_16u_C1C4R_Ctx);
357impl_insert_channel!(insert_channel_i16_c3, i16, C3, 3, nppiCopy_16s_C1C3R_Ctx);
358impl_insert_channel!(insert_channel_i16_c4, i16, C4, 4, nppiCopy_16s_C1C4R_Ctx);
359impl_insert_channel!(insert_channel_i32_c3, i32, C3, 3, nppiCopy_32s_C1C3R_Ctx);
360impl_insert_channel!(insert_channel_i32_c4, i32, C4, 4, nppiCopy_32s_C1C4R_Ctx);
361impl_insert_channel!(insert_channel_f32_c2, f32, C2, 2, nppiCopy_32f_C1C2R_Ctx);
362impl_insert_channel!(insert_channel_f32_c3, f32, C3, 3, nppiCopy_32f_C1C3R_Ctx);
363impl_insert_channel!(insert_channel_f32_c4, f32, C4, 4, nppiCopy_32f_C1C4R_Ctx);
364impl_generic_insert_channel_operation!(
365    InsertChannelC2,
366    insert_channel_c2,
367    C2,
368    [f32 => insert_channel_f32_c2]
369);
370impl_generic_insert_channel_operation!(
371    InsertChannelC3,
372    insert_channel_c3,
373    C3,
374    [
375        u8 => insert_channel_u8_c3,
376        u16 => insert_channel_u16_c3,
377        i16 => insert_channel_i16_c3,
378        i32 => insert_channel_i32_c3,
379        f32 => insert_channel_f32_c3,
380    ]
381);
382impl_generic_insert_channel_operation!(
383    InsertChannelC4,
384    insert_channel_c4,
385    C4,
386    [
387        u8 => insert_channel_u8_c4,
388        u16 => insert_channel_u16_c4,
389        i16 => insert_channel_i16_c4,
390        i32 => insert_channel_i32_c4,
391        f32 => insert_channel_f32_c4,
392    ]
393);
394
395pub(crate) fn duplicate_channel_u8_c1_to_c3(
396    stream_context: &StreamContext,
397    source: &ImageView<'_, u8, C1>,
398    destination: &mut ImageViewMut<'_, u8, C3>,
399) -> Result<()> {
400    validate_same_size(source.size(), destination.size())?;
401
402    unsafe {
403        try_ffi!(sys::nppiDup_8u_C1C3R_Ctx(
404            source.as_ptr().cast(),
405            source.step(),
406            destination.as_mut_ptr().cast(),
407            destination.step(),
408            destination.size().into(),
409            stream_context.as_raw(),
410        ))?;
411    }
412    Ok(())
413}
414
415pub(crate) fn duplicate_channel_u8_c1_to_c4(
416    stream_context: &StreamContext,
417    source: &ImageView<'_, u8, C1>,
418    destination: &mut ImageViewMut<'_, u8, C4>,
419) -> Result<()> {
420    validate_same_size(source.size(), destination.size())?;
421
422    unsafe {
423        try_ffi!(sys::nppiDup_8u_C1C4R_Ctx(
424            source.as_ptr().cast(),
425            source.step(),
426            destination.as_mut_ptr().cast(),
427            destination.step(),
428            destination.size().into(),
429            stream_context.as_raw(),
430        ))?;
431    }
432    Ok(())
433}
434
435pub(crate) fn duplicate_channel_u8_c1_to_ac4(
436    stream_context: &StreamContext,
437    source: &ImageView<'_, u8, C1>,
438    destination: &mut ImageViewMut<'_, u8, AC4>,
439) -> Result<()> {
440    validate_same_size(source.size(), destination.size())?;
441
442    unsafe {
443        try_ffi!(sys::nppiDup_8u_C1AC4R_Ctx(
444            source.as_ptr().cast(),
445            source.step(),
446            destination.as_mut_ptr().cast(),
447            destination.step(),
448            destination.size().into(),
449            stream_context.as_raw(),
450        ))?;
451    }
452    Ok(())
453}
454
455pub(crate) fn duplicate_channel_u16_c1_to_c3(
456    stream_context: &StreamContext,
457    source: &ImageView<'_, u16, C1>,
458    destination: &mut ImageViewMut<'_, u16, C3>,
459) -> Result<()> {
460    validate_same_size(source.size(), destination.size())?;
461
462    unsafe {
463        try_ffi!(sys::nppiDup_16u_C1C3R_Ctx(
464            source.as_ptr().cast(),
465            source.step(),
466            destination.as_mut_ptr().cast(),
467            destination.step(),
468            destination.size().into(),
469            stream_context.as_raw(),
470        ))?;
471    }
472    Ok(())
473}
474
475pub(crate) fn duplicate_channel_u16_c1_to_c4(
476    stream_context: &StreamContext,
477    source: &ImageView<'_, u16, C1>,
478    destination: &mut ImageViewMut<'_, u16, C4>,
479) -> Result<()> {
480    validate_same_size(source.size(), destination.size())?;
481
482    unsafe {
483        try_ffi!(sys::nppiDup_16u_C1C4R_Ctx(
484            source.as_ptr().cast(),
485            source.step(),
486            destination.as_mut_ptr().cast(),
487            destination.step(),
488            destination.size().into(),
489            stream_context.as_raw(),
490        ))?;
491    }
492    Ok(())
493}
494
495pub(crate) fn duplicate_channel_u16_c1_to_ac4(
496    stream_context: &StreamContext,
497    source: &ImageView<'_, u16, C1>,
498    destination: &mut ImageViewMut<'_, u16, AC4>,
499) -> Result<()> {
500    validate_same_size(source.size(), destination.size())?;
501
502    unsafe {
503        try_ffi!(sys::nppiDup_16u_C1AC4R_Ctx(
504            source.as_ptr().cast(),
505            source.step(),
506            destination.as_mut_ptr().cast(),
507            destination.step(),
508            destination.size().into(),
509            stream_context.as_raw(),
510        ))?;
511    }
512    Ok(())
513}
514
515macro_rules! impl_duplicate_channel {
516    ($name:ident, $ty:ty, $layout:ty, $ffi:ident) => {
517        pub(crate) fn $name(
518            stream_context: &StreamContext,
519            source: &ImageView<'_, $ty, C1>,
520            destination: &mut ImageViewMut<'_, $ty, $layout>,
521        ) -> Result<()> {
522            validate_same_size(source.size(), destination.size())?;
523
524            unsafe {
525                try_ffi!(sys::$ffi(
526                    source.as_ptr().cast(),
527                    source.step(),
528                    destination.as_mut_ptr().cast(),
529                    destination.step(),
530                    destination.size().into(),
531                    stream_context.as_raw(),
532                ))?;
533            }
534            Ok(())
535        }
536    };
537}
538
539macro_rules! impl_generic_duplicate_channel_operation {
540    ($trait:ident, $function:ident, $layout:ty, [$($ty:ty => $direct:ident),+ $(,)?]) => {
541        pub trait $trait<Layout>: DataTypeLike + Sized {
542            fn dispatch(
543                stream_context: &StreamContext,
544                source: &ImageView<'_, Self, C1>,
545                destination: &mut ImageViewMut<'_, Self, Layout>,
546            ) -> Result<()>;
547        }
548
549        $(
550            impl $trait<$layout> for $ty {
551                fn dispatch(
552                    stream_context: &StreamContext,
553                    source: &ImageView<'_, Self, C1>,
554                    destination: &mut ImageViewMut<'_, Self, $layout>,
555                ) -> Result<()> {
556                    $direct(stream_context, source, destination)
557                }
558            }
559        )+
560
561        pub fn $function<T>(
562            stream_context: &StreamContext,
563            source: &ImageView<'_, T, C1>,
564            destination: &mut ImageViewMut<'_, T, $layout>,
565        ) -> Result<()>
566        where
567            T: $trait<$layout>,
568        {
569            T::dispatch(stream_context, source, destination)
570        }
571    };
572}
573
574impl_duplicate_channel!(
575    duplicate_channel_i16_c1_to_c3,
576    i16,
577    C3,
578    nppiDup_16s_C1C3R_Ctx
579);
580impl_duplicate_channel!(
581    duplicate_channel_i16_c1_to_c4,
582    i16,
583    C4,
584    nppiDup_16s_C1C4R_Ctx
585);
586impl_duplicate_channel!(
587    duplicate_channel_i16_c1_to_ac4,
588    i16,
589    AC4,
590    nppiDup_16s_C1AC4R_Ctx
591);
592impl_duplicate_channel!(
593    duplicate_channel_i32_c1_to_c3,
594    i32,
595    C3,
596    nppiDup_32s_C1C3R_Ctx
597);
598impl_duplicate_channel!(
599    duplicate_channel_i32_c1_to_c4,
600    i32,
601    C4,
602    nppiDup_32s_C1C4R_Ctx
603);
604impl_duplicate_channel!(
605    duplicate_channel_i32_c1_to_ac4,
606    i32,
607    AC4,
608    nppiDup_32s_C1AC4R_Ctx
609);
610impl_duplicate_channel!(
611    duplicate_channel_f32_c1_to_c3,
612    f32,
613    C3,
614    nppiDup_32f_C1C3R_Ctx
615);
616impl_duplicate_channel!(
617    duplicate_channel_f32_c1_to_c4,
618    f32,
619    C4,
620    nppiDup_32f_C1C4R_Ctx
621);
622impl_duplicate_channel!(
623    duplicate_channel_f32_c1_to_ac4,
624    f32,
625    AC4,
626    nppiDup_32f_C1AC4R_Ctx
627);
628impl_generic_duplicate_channel_operation!(
629    DuplicateChannelC1ToC3,
630    duplicate_channel_c1_to_c3,
631    C3,
632    [
633        u8 => duplicate_channel_u8_c1_to_c3,
634        u16 => duplicate_channel_u16_c1_to_c3,
635        i16 => duplicate_channel_i16_c1_to_c3,
636        i32 => duplicate_channel_i32_c1_to_c3,
637        f32 => duplicate_channel_f32_c1_to_c3,
638    ]
639);
640impl_generic_duplicate_channel_operation!(
641    DuplicateChannelC1ToC4,
642    duplicate_channel_c1_to_c4,
643    C4,
644    [
645        u8 => duplicate_channel_u8_c1_to_c4,
646        u16 => duplicate_channel_u16_c1_to_c4,
647        i16 => duplicate_channel_i16_c1_to_c4,
648        i32 => duplicate_channel_i32_c1_to_c4,
649        f32 => duplicate_channel_f32_c1_to_c4,
650    ]
651);
652impl_generic_duplicate_channel_operation!(
653    DuplicateChannelC1ToAC4,
654    duplicate_channel_c1_to_ac4,
655    AC4,
656    [
657        u8 => duplicate_channel_u8_c1_to_ac4,
658        u16 => duplicate_channel_u16_c1_to_ac4,
659        i16 => duplicate_channel_i16_c1_to_ac4,
660        i32 => duplicate_channel_i32_c1_to_ac4,
661        f32 => duplicate_channel_f32_c1_to_ac4,
662    ]
663);
664
665pub(crate) fn copy_channel_u8_c3(
666    stream_context: &StreamContext,
667    source: &ImageView<'_, u8, C3>,
668    source_channel: usize,
669    destination: &mut ImageViewMut<'_, u8, C3>,
670    destination_channel: usize,
671) -> Result<()> {
672    validate_same_size(source.size(), destination.size())?;
673    validate_channel_index(source_channel, 3)?;
674    validate_channel_index(destination_channel, 3)?;
675
676    unsafe {
677        try_ffi!(sys::nppiCopy_8u_C3CR_Ctx(
678            source.as_ptr().add(source_channel),
679            source.step(),
680            destination.as_mut_ptr().add(destination_channel),
681            destination.step(),
682            source.size().into(),
683            stream_context.as_raw(),
684        ))?;
685    }
686    Ok(())
687}
688
689pub(crate) fn copy_channel_u8_c4(
690    stream_context: &StreamContext,
691    source: &ImageView<'_, u8, C4>,
692    source_channel: usize,
693    destination: &mut ImageViewMut<'_, u8, C4>,
694    destination_channel: usize,
695) -> Result<()> {
696    validate_same_size(source.size(), destination.size())?;
697    validate_channel_index(source_channel, 4)?;
698    validate_channel_index(destination_channel, 4)?;
699
700    unsafe {
701        try_ffi!(sys::nppiCopy_8u_C4CR_Ctx(
702            source.as_ptr().add(source_channel),
703            source.step(),
704            destination.as_mut_ptr().add(destination_channel),
705            destination.step(),
706            source.size().into(),
707            stream_context.as_raw(),
708        ))?;
709    }
710    Ok(())
711}
712
713impl_copy_channel!(copy_channel_u16_c3, u16, C3, 3, nppiCopy_16u_C3CR_Ctx);
714impl_copy_channel!(copy_channel_u16_c4, u16, C4, 4, nppiCopy_16u_C4CR_Ctx);
715impl_copy_channel!(copy_channel_i16_c3, i16, C3, 3, nppiCopy_16s_C3CR_Ctx);
716impl_copy_channel!(copy_channel_i16_c4, i16, C4, 4, nppiCopy_16s_C4CR_Ctx);
717impl_copy_channel!(copy_channel_i32_c3, i32, C3, 3, nppiCopy_32s_C3CR_Ctx);
718impl_copy_channel!(copy_channel_i32_c4, i32, C4, 4, nppiCopy_32s_C4CR_Ctx);
719impl_copy_channel!(copy_channel_f32_c3, f32, C3, 3, nppiCopy_32f_C3CR_Ctx);
720impl_copy_channel!(copy_channel_f32_c4, f32, C4, 4, nppiCopy_32f_C4CR_Ctx);
721impl_generic_copy_channel_operation!(
722    CopyChannelC3,
723    copy_channel_c3,
724    C3,
725    [
726        u8 => copy_channel_u8_c3,
727        u16 => copy_channel_u16_c3,
728        i16 => copy_channel_i16_c3,
729        i32 => copy_channel_i32_c3,
730        f32 => copy_channel_f32_c3,
731    ]
732);
733impl_generic_copy_channel_operation!(
734    CopyChannelC4,
735    copy_channel_c4,
736    C4,
737    [
738        u8 => copy_channel_u8_c4,
739        u16 => copy_channel_u16_c4,
740        i16 => copy_channel_i16_c4,
741        i32 => copy_channel_i32_c4,
742        f32 => copy_channel_f32_c4,
743    ]
744);