@@ -58,46 +58,27 @@ pub fn write_yuv_scalar(rgb: impl RGB8Source, dimensions: (usize, usize), y_buf:
5858
5959 let dimensions_padded = rgb. dimensions_padded ( ) ;
6060 let width = dimensions. 0 ;
61- let height = dimensions . 1 ;
61+
6262 let half_width = width / 2 ;
6363 let rgb8_data = rgb. rgb8_data ( ) ;
6464
65- // y is full size, u, v is quarter size
66- let mut write_y = |x : usize , y : usize , rgb : & [ u8 ] | {
67- let ( r, g, b) = ( f32:: from ( rgb[ 0 ] ) , f32:: from ( rgb[ 1 ] ) , f32:: from ( rgb[ 2 ] ) ) ;
68- y_buf[ x + y * width] = ( 0.09765625f32 . mul_add ( b, 0.2578125f32 . mul_add ( r, 0.50390625 * g) ) + 16.0 ) as u8 ;
69- } ;
70-
71- let mut write_u = |x : usize , y : usize , rgb : & [ u8 ] | {
72- let ( r, g, b) = ( f32:: from ( rgb[ 0 ] ) , f32:: from ( rgb[ 1 ] ) , f32:: from ( rgb[ 2 ] ) ) ;
73- u_buf[ x + y * half_width] = ( 0.4375f32 . mul_add ( b, ( -0.1484375f32 ) . mul_add ( r, -0.2890625 * g) ) + 128.0 ) as u8 ;
74- } ;
65+ for ( pix, y) in rgb8_data. chunks_exact ( 3 ) . zip ( y_buf. iter_mut ( ) ) {
66+ * y = ( ( ( 66 * u32:: from ( pix[ 0 ] ) + 129 * u32:: from ( pix[ 1 ] ) + 25 * u32:: from ( pix[ 2 ] ) ) >> 8 ) + 16 ) as u8 ;
67+ }
7568
76- let mut write_v = |x : usize , y : usize , rgb : & [ u8 ] | {
77- let ( r, g, b) = ( f32:: from ( rgb[ 0 ] ) , f32:: from ( rgb[ 1 ] ) , f32:: from ( rgb[ 2 ] ) ) ;
78- v_buf[ x + y * half_width] = ( ( -0.0703125f32 ) . mul_add ( b, 0.4375f32 . mul_add ( r, -0.3671875 * g) ) + 128.0 ) as u8 ;
79- } ;
69+ let r1 = rgb8_data. chunks_exact ( dimensions_padded. 0 * 3 ) . step_by ( 2 ) ;
70+ let r2 = rgb8_data. chunks_exact ( dimensions_padded. 0 * 3 ) . skip ( 1 ) . step_by ( 2 ) ;
8071
81- for i in 0 ..width / 2 {
82- for j in 0 ..height / 2 {
83- let px = i * 2 ;
84- let py = j * 2 ;
85- let pix0x0 = & rgb8_data[ ( px + py * dimensions_padded. 0 ) * 3 ..] [ ..3 ] ;
86- let pix0x1 = & rgb8_data[ ( px + ( py + 1 ) * dimensions_padded. 0 ) * 3 ..] [ ..3 ] ;
87- let pix1x0 = & rgb8_data[ ( px + 1 + ( py) * dimensions_padded. 0 ) * 3 ..] [ ..3 ] ;
88- let pix1x1 = & rgb8_data[ ( px + 1 + ( py + 1 ) * dimensions_padded. 0 ) * 3 ..] [ ..3 ] ;
89- let avg_pix = [
90- ( ( u32:: from ( pix0x0[ 0 ] ) + u32:: from ( pix0x1[ 0 ] ) + u32:: from ( pix1x0[ 0 ] ) + u32:: from ( pix1x1[ 0 ] ) ) / 4 ) as u8 ,
91- ( ( u32:: from ( pix0x0[ 1 ] ) + u32:: from ( pix0x1[ 1 ] ) + u32:: from ( pix1x0[ 1 ] ) + u32:: from ( pix1x1[ 1 ] ) ) / 4 ) as u8 ,
92- ( ( u32:: from ( pix0x0[ 2 ] ) + u32:: from ( pix0x1[ 2 ] ) + u32:: from ( pix1x0[ 2 ] ) + u32:: from ( pix1x1[ 2 ] ) ) / 4 ) as u8 ,
93- ] ;
72+ let u_rows = u_buf. chunks_exact_mut ( half_width) ;
73+ let v_rows = v_buf. chunks_exact_mut ( half_width) ;
74+ for ( ( ( r1, r2) , u) , v) in r1. zip ( r2) . zip ( u_rows) . zip ( v_rows) {
75+ for ( ( ( pix0, pix1) , u) , v) in r1. chunks_exact ( 2 * 3 ) . zip ( r2. chunks_exact ( 2 * 3 ) ) . zip ( u) . zip ( v) {
76+ let r = ( i16:: from ( pix0[ 0 ] ) + i16:: from ( pix0[ 3 ] ) + i16:: from ( pix1[ 0 ] ) + i16:: from ( pix1[ 3 ] ) + 2 ) / 4 ;
77+ let g = ( i16:: from ( pix0[ 1 ] ) + i16:: from ( pix0[ 4 ] ) + i16:: from ( pix1[ 1 ] ) + i16:: from ( pix1[ 4 ] ) + 2 ) / 4 ;
78+ let b = ( i16:: from ( pix0[ 2 ] ) + i16:: from ( pix0[ 5 ] ) + i16:: from ( pix1[ 2 ] ) + i16:: from ( pix1[ 5 ] ) + 2 ) / 4 ;
9479
95- write_y ( px, py, pix0x0) ;
96- write_y ( px, py + 1 , pix0x1) ;
97- write_y ( px + 1 , py, pix1x0) ;
98- write_y ( px + 1 , py + 1 , pix1x1) ;
99- write_u ( i, j, & avg_pix) ;
100- write_v ( i, j, & avg_pix) ;
80+ * u = ( ( ( -38 * r + 112 * b - 74 * g) >> 8 ) + 128 ) as u8 ;
81+ * v = ( ( ( 112 * r - 18 * b - 94 * g) >> 8 ) + 128 ) as u8 ;
10182 }
10283 }
10384}
0 commit comments