| 1 | use crate::frame::*; |
| 2 | |
| 3 | pub fn put_blocks(buf: &mut NAVideoBuffer<u8>, xpos: usize, ypos: usize, blk: &[[i16;64]; 6]) { |
| 4 | let stridey = buf.get_stride(0); |
| 5 | let strideu = buf.get_stride(1); |
| 6 | let stridev = buf.get_stride(2); |
| 7 | let mut idxy = buf.get_offset(0) + xpos * 16 + ypos * 16 * stridey; |
| 8 | let mut idxu = buf.get_offset(1) + xpos * 8 + ypos * 8 * strideu; |
| 9 | let mut idxv = buf.get_offset(2) + xpos * 8 + ypos * 8 * stridev; |
| 10 | |
| 11 | let data = buf.get_data_mut().unwrap(); |
| 12 | let framebuf: &mut [u8] = data.as_mut_slice(); |
| 13 | |
| 14 | for j in 0..8 { |
| 15 | for k in 0..8 { |
| 16 | let mut v = blk[0][k + j * 8]; |
| 17 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 18 | framebuf[idxy + k] = v as u8; |
| 19 | } |
| 20 | for k in 0..8 { |
| 21 | let mut v = blk[1][k + j * 8]; |
| 22 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 23 | framebuf[idxy + k + 8] = v as u8; |
| 24 | } |
| 25 | idxy += stridey; |
| 26 | } |
| 27 | for j in 0..8 { |
| 28 | for k in 0..8 { |
| 29 | let mut v = blk[2][k + j * 8]; |
| 30 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 31 | framebuf[idxy + k] = v as u8; |
| 32 | } |
| 33 | for k in 0..8 { |
| 34 | let mut v = blk[3][k + j * 8]; |
| 35 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 36 | framebuf[idxy + k + 8] = v as u8; |
| 37 | } |
| 38 | idxy += stridey; |
| 39 | } |
| 40 | |
| 41 | for j in 0..8 { |
| 42 | for k in 0..8 { |
| 43 | let mut v = blk[4][k + j * 8]; |
| 44 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 45 | framebuf[idxu + k] = v as u8; |
| 46 | } |
| 47 | for k in 0..8 { |
| 48 | let mut v = blk[5][k + j * 8]; |
| 49 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 50 | framebuf[idxv + k] = v as u8; |
| 51 | } |
| 52 | idxu += strideu; |
| 53 | idxv += stridev; |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | pub fn add_blocks(buf: &mut NAVideoBuffer<u8>, xpos: usize, ypos: usize, blk: &[[i16;64]; 6]) { |
| 58 | let stridey = buf.get_stride(0); |
| 59 | let strideu = buf.get_stride(1); |
| 60 | let stridev = buf.get_stride(2); |
| 61 | let mut idxy = buf.get_offset(0) + xpos * 16 + ypos * 16 * stridey; |
| 62 | let mut idxu = buf.get_offset(1) + xpos * 8 + ypos * 8 * strideu; |
| 63 | let mut idxv = buf.get_offset(2) + xpos * 8 + ypos * 8 * stridev; |
| 64 | |
| 65 | let data = buf.get_data_mut().unwrap(); |
| 66 | let framebuf: &mut [u8] = data.as_mut_slice(); |
| 67 | |
| 68 | for j in 0..8 { |
| 69 | for k in 0..8 { |
| 70 | let mut v = blk[0][k + j * 8] + (framebuf[idxy + k] as i16); |
| 71 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 72 | framebuf[idxy + k] = v as u8; |
| 73 | } |
| 74 | for k in 0..8 { |
| 75 | let mut v = blk[1][k + j * 8] + (framebuf[idxy + k + 8] as i16); |
| 76 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 77 | framebuf[idxy + k + 8] = v as u8; |
| 78 | } |
| 79 | idxy += stridey; |
| 80 | } |
| 81 | for j in 0..8 { |
| 82 | for k in 0..8 { |
| 83 | let mut v = blk[2][k + j * 8] + (framebuf[idxy + k] as i16); |
| 84 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 85 | framebuf[idxy + k] = v as u8; |
| 86 | } |
| 87 | for k in 0..8 { |
| 88 | let mut v = blk[3][k + j * 8] + (framebuf[idxy + k + 8] as i16); |
| 89 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 90 | framebuf[idxy + k + 8] = v as u8; |
| 91 | } |
| 92 | idxy += stridey; |
| 93 | } |
| 94 | |
| 95 | for j in 0..8 { |
| 96 | for k in 0..8 { |
| 97 | let mut v = blk[4][k + j * 8] + (framebuf[idxu + k] as i16); |
| 98 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 99 | framebuf[idxu + k] = v as u8; |
| 100 | } |
| 101 | for k in 0..8 { |
| 102 | let mut v = blk[5][k + j * 8] + (framebuf[idxv + k] as i16); |
| 103 | if v < 0 { v = 0; } if v > 255 { v = 255; } |
| 104 | framebuf[idxv + k] = v as u8; |
| 105 | } |
| 106 | idxu += strideu; |
| 107 | idxv += stridev; |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | pub fn edge_emu(src: &NAVideoBuffer<u8>, xpos: isize, ypos: isize, bw: usize, bh: usize, dst: &mut [u8], dstride: usize, comp: usize) { |
| 112 | let stride = src.get_stride(comp); |
| 113 | let offs = src.get_offset(comp); |
| 114 | let (w, h) = src.get_dimensions(comp); |
| 115 | let data = src.get_data(); |
| 116 | let framebuf: &[u8] = data.as_slice(); |
| 117 | |
| 118 | for y in 0..bh { |
| 119 | let srcy; |
| 120 | if (y as isize) + ypos < 0 { srcy = 0; } |
| 121 | else if (y as isize) + ypos >= (h as isize) { srcy = h - 1; } |
| 122 | else { srcy = ((y as isize) + ypos) as usize; } |
| 123 | |
| 124 | for x in 0..bw { |
| 125 | let srcx; |
| 126 | if (x as isize) + xpos < 0 { srcx = 0; } |
| 127 | else if (x as isize) + xpos >= (w as isize) { srcx = w - 1; } |
| 128 | else { srcx = ((x as isize) + xpos) as usize; } |
| 129 | dst[x + y * dstride] = framebuf[offs + srcx + srcy * stride]; |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | pub fn copy_blocks(dst: &mut NAVideoBuffer<u8>, src: &NAVideoBuffer<u8>, |
| 135 | dx: usize, dy: usize, sx: isize, sy: isize, bw: usize, bh: usize, |
| 136 | preborder: usize, postborder: usize, |
| 137 | mode: usize, interp: &[fn(&mut [u8], usize, &[u8], usize, usize, usize)]) |
| 138 | { |
| 139 | let pre = if mode != 0 { preborder as isize } else { 0 }; |
| 140 | let post = if mode != 0 { postborder as isize } else { 0 }; |
| 141 | let (w, h) = src.get_dimensions(0); |
| 142 | |
| 143 | if (sx - pre < 0) || ((sx >> 1) - pre < 0) || (sx + (bw as isize) + post > (w as isize)) || |
| 144 | (sy - pre < 0) || ((sy >> 1) - pre < 0) || (sy + (bh as isize) + post > (h as isize)) { |
| 145 | let ebuf_stride: usize = 32; |
| 146 | let mut ebuf: Vec<u8> = Vec::with_capacity(ebuf_stride * (bh + ((pre + post) as usize))); |
| 147 | ebuf.resize((((pre + post) as usize) + bh) * ebuf_stride, 0); |
| 148 | |
| 149 | for comp in 0..3 { |
| 150 | let dstride = dst.get_stride(comp); |
| 151 | let doff = dst.get_offset(comp); |
| 152 | let ddta = dst.get_data_mut().unwrap(); |
| 153 | let dbuf: &mut [u8] = ddta.as_mut_slice(); |
| 154 | let x = if comp > 0 { dx/2 } else { dx }; |
| 155 | let y = if comp > 0 { dy/2 } else { dy }; |
| 156 | let sx_ = (if comp > 0 { sx >> 1 } else { sx }) - pre; |
| 157 | let sy_ = (if comp > 0 { sy >> 1 } else { sy }) - pre; |
| 158 | let bw_ = (if comp > 0 { bw/2 } else { bw }) + ((pre + post) as usize); |
| 159 | let bh_ = (if comp > 0 { bh/2 } else { bh }) + ((pre + post) as usize); |
| 160 | edge_emu(src, sx_ - pre, sy_ - pre, bw_, bh_, |
| 161 | ebuf.as_mut_slice(), ebuf_stride, comp); |
| 162 | let bw_ = if comp > 0 { bw/2 } else { bw }; |
| 163 | let bh_ = if comp > 0 { bh/2 } else { bh }; |
| 164 | (interp[mode])(&mut dbuf[doff + x + y * dstride..], dstride, ebuf.as_slice(), ebuf_stride, bw_, bh_); |
| 165 | } |
| 166 | } else { |
| 167 | for comp in 0..3 { |
| 168 | let sstride = src.get_stride(comp); |
| 169 | let soff = src.get_offset(comp); |
| 170 | let sdta = src.get_data(); |
| 171 | let sbuf: &[u8] = sdta.as_slice(); |
| 172 | let dstride = dst.get_stride(comp); |
| 173 | let doff = dst.get_offset(comp); |
| 174 | let ddta = dst.get_data_mut().unwrap(); |
| 175 | let dbuf: &mut [u8] = ddta.as_mut_slice(); |
| 176 | let x = if comp > 0 { dx/2 } else { dx }; |
| 177 | let y = if comp > 0 { dy/2 } else { dy }; |
| 178 | let sx_ = ((if comp > 0 { sx >> 1 } else { sx }) - pre) as usize; |
| 179 | let sy_ = ((if comp > 0 { sy >> 1 } else { sy }) - pre) as usize; |
| 180 | let bw_ = if comp > 0 { bw/2 } else { bw }; |
| 181 | let bh_ = if comp > 0 { bh/2 } else { bh }; |
| 182 | (interp[mode])(&mut dbuf[doff + x + y * dstride..], dstride, &sbuf[(soff + sx_ + sy_ * sstride)..], sstride, bw_, bh_); |
| 183 | } |
| 184 | } |
| 185 | } |