]> git.nihav.org Git - nihav.git/commitdiff
rawvideo{enc,dec}: support 1-4 bit paletted formats
authorKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 25 Apr 2026 16:20:18 +0000 (18:20 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Sat, 25 Apr 2026 16:20:18 +0000 (18:20 +0200)
nihav-commonfmt/src/codecs/rawvideo.rs
nihav-commonfmt/src/codecs/rawvideoenc.rs

index dd4a031338f4adb270459279ab3e6b63299c06fe..79b9f0d58bae1128129237db9d5c77b829afaa0d 100644 (file)
@@ -71,7 +71,43 @@ impl NADecoder for RawDecoder {
                     let strides = vec![stride];
                     NABufferType::VideoPacked(NAVideoBuffer::from_raw_parts(*vinfo, src, offs, strides).into_ref())
                 } else {
-                    let mut buf = src.clone();
+                    let mut buf = match vinfo.bits.min(8) {
+                            1 => {
+                                let mut buf = Vec::with_capacity(width * height + 768);
+                                for line in src.chunks_exact(width).take(height) {
+                                    for &oct in line.iter() {
+                                        for i in (0..8).rev() {
+                                            buf.push((oct >> i) & 1);
+                                        }
+                                    }
+                                }
+                                NABufferRef::new(buf)
+                            },
+                            2 => {
+                                let mut buf = Vec::with_capacity(width * height + 768);
+                                for line in src.chunks_exact(width).take(height) {
+                                    for &quad in line.iter() {
+                                        buf.push( quad >> 6);
+                                        buf.push((quad >> 4) & 0x3);
+                                        buf.push((quad >> 2) & 0x3);
+                                        buf.push( quad       & 0x3);
+                                    }
+                                }
+                                NABufferRef::new(buf)
+                            },
+                            4 => {
+                                let mut buf = Vec::with_capacity(width * height + 768);
+                                for line in src.chunks_exact(width).take(height) {
+                                    for &pair in line.iter() {
+                                        buf.push(pair >> 4);
+                                        buf.push(pair & 0xF);
+                                    }
+                                }
+                                NABufferRef::new(buf)
+                            },
+                            8 => NABufferRef::new(Vec::clone(&src)),
+                            _ => return Err(DecoderError::NotImplemented),
+                        };
                     let offs = vec![0, buf.len()];
                     let strides = vec![width, 0];
                     let mut found = false;
index ec003b0a4f6ae6d62484e76d5820463d1b677f71..6789c41428e5aca2b259a092572e85fc4a46509c 100644 (file)
@@ -69,14 +69,81 @@ impl NAEncoder for RawEncoder {
                         let sstride = vbuf.get_stride(0);
                         let dstride = width;
                         dbuf = Vec::with_capacity(dstride * height);
-                        if !vinfo.flipped {
-                            for line in src.chunks(sstride).take(height) {
-                                dbuf.extend_from_slice(&line[..dstride]);
-                            }
-                        } else {
-                            for line in src.chunks(sstride).take(height).rev() {
-                                dbuf.extend_from_slice(&line[..dstride]);
-                            }
+                        match vinfo.bits.min(8) {
+                            8 => {
+                                if !vinfo.flipped {
+                                    for line in src.chunks(sstride).take(height) {
+                                        dbuf.extend_from_slice(&line[..dstride]);
+                                    }
+                                } else {
+                                    for line in src.chunks(sstride).take(height).rev() {
+                                        dbuf.extend_from_slice(&line[..dstride]);
+                                    }
+                                }
+                            },
+                            4 => {
+                                if (vinfo.width & 1) != 0 {
+                                    return Err(EncoderError::NotImplemented);
+                                }
+                                if !vinfo.flipped {
+                                    for line in src.chunks(sstride).take(height) {
+                                        for ppair in line.chunks_exact(2) {
+                                            dbuf.push((ppair[0] << 4) | ppair[1]);
+                                        }
+                                    }
+                                } else {
+                                    for line in src.chunks(sstride).take(height).rev() {
+                                        for ppair in line.chunks_exact(2) {
+                                            dbuf.push((ppair[0] << 4) | ppair[1]);
+                                        }
+                                    }
+                                }
+                            },
+                            2 => {
+                                if (vinfo.width & 3) != 0 {
+                                    return Err(EncoderError::NotImplemented);
+                                }
+                                if !vinfo.flipped {
+                                    for line in src.chunks(sstride).take(height) {
+                                        for quad in line.chunks_exact(4) {
+                                            dbuf.push((quad[0] << 6) | (quad[1] << 4) | (quad[2] << 2) | quad[3]);
+                                        }
+                                    }
+                                } else {
+                                    for line in src.chunks(sstride).take(height).rev() {
+                                        for quad in line.chunks_exact(4) {
+                                            dbuf.push((quad[0] << 6) | (quad[1] << 4) | (quad[2] << 2) | quad[3]);
+                                        }
+                                    }
+                                }
+                            },
+                            1 => {
+                                if (vinfo.width & 8) != 0 {
+                                    return Err(EncoderError::NotImplemented);
+                                }
+                                if !vinfo.flipped {
+                                    for line in src.chunks(sstride).take(height) {
+                                        for oct in line.chunks_exact(8) {
+                                            let mut bb = 0;
+                                            for &b in oct.iter() {
+                                                bb = bb * 2 + b;
+                                            }
+                                            dbuf.push(bb);
+                                        }
+                                    }
+                                } else {
+                                    for line in src.chunks(sstride).take(height).rev() {
+                                        for oct in line.chunks_exact(8) {
+                                            let mut bb = 0;
+                                            for &b in oct.iter() {
+                                                bb = bb * 2 + b;
+                                            }
+                                            dbuf.push(bb);
+                                        }
+                                    }
+                                }
+                            },
+                            _ => return Err(EncoderError::NotImplemented),
                         }
                         let mut pkt = NAPacket::new(self.stream.clone().unwrap(), frm.ts, true, dbuf);
                         let mut npal = [0; 1024];