swizzle_3ds/
encode.rs

1//! Module for writing .tex3ds files for consumption by e.g. citro3d
2
3use std::{io::Write, ops::Deref};
4
5use crate::pix::ImageView;
6
7#[derive(Debug, Clone, Copy)]
8enum CompressionType {
9    None,
10}
11/// Compression header bytes
12fn compression_header(ty: CompressionType, data_sz: u32) -> Vec<u8> {
13    let magic = match ty {
14        CompressionType::None => 0x0,
15    };
16    let mut buf = Vec::new();
17    buf.push(magic);
18    let sz_bytes = data_sz.to_le_bytes();
19
20    buf.extend_from_slice(&sz_bytes[0..3]);
21    if sz_bytes[3] != 0 {
22        // special case, it requires 4 bytes, set the marker that we are using it
23        buf[0] |= 0x80;
24        buf.push(sz_bytes[3]);
25        // reserved bytes
26        buf.resize(buf.len() + 3, 0);
27    }
28
29    buf
30}
31
32impl<C: Deref<Target = [u8]>> ImageView<C> {
33    /// Write image in tex3ds format into `to`
34    pub fn write_tex3ds(&self, to: &mut impl Write) -> std::io::Result<()> {
35        let buf = self.as_raw();
36        to.write_all(&compression_header(CompressionType::None, buf.len() as u32))?;
37
38        to.write_all(buf)?;
39
40        if buf.len() % 4 != 0 {
41            for _ in 0..buf.len() % 4 {
42                to.write_all(&[0; 1])?;
43            }
44        }
45        Ok(())
46    }
47}