use std::ffi::CStr;
use crate::sys;
use crate::{make_tag, ChdError, Result};
pub const CHD_CODEC_NONE: u32 = 0;
pub const CHD_CODEC_ZLIB: u32 = make_tag(b'z', b'l', b'i', b'b');
pub const CHD_CODEC_ZSTD: u32 = make_tag(b'z', b's', b't', b'd');
pub const CHD_CODEC_LZMA: u32 = make_tag(b'l', b'z', b'm', b'a');
pub const CHD_CODEC_HUFF: u32 = make_tag(b'h', b'u', b'f', b'f');
pub const CHD_CODEC_FLAC: u32 = make_tag(b'f', b'l', b'a', b'c');
pub const CHD_CODEC_CD_ZLIB: u32 = make_tag(b'c', b'd', b'z', b'l');
pub const CHD_CODEC_CD_ZSTD: u32 = make_tag(b'c', b'd', b'z', b's');
pub const CHD_CODEC_CD_LZMA: u32 = make_tag(b'c', b'd', b'l', b'z');
pub const CHD_CODEC_CD_FLAC: u32 = make_tag(b'c', b'd', b'f', b'l');
pub const CHD_CODEC_AVHUFF: u32 = make_tag(b'a', b'v', b'h', b'u');
pub fn codec_exists(codec: u32) -> bool {
unsafe { sys::chd_shim_codec_exists(codec) != 0 }
}
pub fn codec_name(codec: u32) -> Option<&'static str> {
let p = unsafe { sys::chd_shim_codec_name(codec) };
if p.is_null() {
return None;
}
unsafe { CStr::from_ptr(p) }.to_str().ok()
}
pub fn parse_codec_spec(s: &str) -> Result<[u32; 4]> {
if s == "none" {
return Ok([CHD_CODEC_NONE; 4]);
}
if s.is_empty() {
return Err(ChdError::UnknownCompression);
}
let mut out = [CHD_CODEC_NONE; 4];
for (count, name) in s.split(',').enumerate() {
if count == 4 {
return Err(ChdError::UnknownCompression);
}
let bytes = name.as_bytes();
if bytes.len() != 4 {
return Err(ChdError::UnknownCompression);
}
let tag = make_tag(bytes[0], bytes[1], bytes[2], bytes[3]);
if !codec_exists(tag) {
return Err(ChdError::UnknownCompression);
}
out[count] = tag;
}
Ok(out)
}