#[macro_export]
macro_rules! debug_print {
($($arg:tt)*) => {
let message = format!($($arg)*);
$crate::utils::debug_print_impl(&message);
};
}
#[macro_export]
macro_rules! odbg {
() => {
$crate::debug_print!("[{}:{}:{}]", ::std::file!(), ::std::line!(), ::std::column!());
};
($val:expr $(,)?) => {
match $val {
tmp => {
$crate::debug_print!("[{}:{}:{}] {} = {:#?}",
::std::file!(),
::std::line!(),
::std::column!(),
::std::stringify!($val),
&&tmp as &dyn ::std::fmt::Debug,
);
tmp
}
}
};
($($val:expr),+ $(,)?) => {
($($crate::odbg!($val)),+,)
};
}
#[doc(hidden)]
pub fn debug_print_impl(message: &str) {
let mut cstr = message.encode_utf16().collect::<Vec<u16>>();
cstr.push(0); unsafe {
let ptr = cstr.as_ptr();
windows::Win32::System::Diagnostics::Debug::OutputDebugStringW(
windows::core::PCWSTR::from_raw(ptr),
);
}
}
pub fn flip_vertical<T>(data: &mut [T], width: usize, height: usize) {
assert!(data.len() == width * height);
let row_size = width;
for y in 0..(height / 2) {
let top_row_start = y * row_size;
let bottom_row_start = (height - 1 - y) * row_size;
for x in 0..width {
data.swap(top_row_start + x, bottom_row_start + x);
}
}
}
pub fn bgr_to_rgb(data: &mut [(u8, u8, u8)]) {
for pixel in data.iter_mut() {
let (b, g, r) = *pixel;
*pixel = (r, g, b);
}
}
#[inline]
pub fn rgb_to_bgr(data: &mut [(u8, u8, u8)]) {
bgr_to_rgb(data);
}
pub fn rgba_to_bgra(data: &mut [(u8, u8, u8, u8)]) {
for pixel in data.iter_mut() {
let (b, g, r, a) = *pixel;
*pixel = (r, g, b, a);
}
}
#[inline]
pub fn bgra_to_rgba(data: &mut [(u8, u8, u8, u8)]) {
rgba_to_bgra(data);
}
#[cfg(feature = "env_logger")]
mod ods_logger {
pub fn debug_logger_target() -> env_logger::fmt::Target {
let write_target = OdsWriter::new();
env_logger::fmt::Target::Pipe(Box::new(write_target))
}
struct OdsWriter {
buffer: Vec<u8>,
}
impl OdsWriter {
pub fn new() -> Self {
Self { buffer: Vec::new() }
}
}
impl std::io::Write for OdsWriter {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
while let Some(pos) = self.buffer.iter().position(|&b| b == b'\n') {
let line = &self.buffer[..=pos];
if let Ok(line_str) = std::str::from_utf8(line) {
super::debug_print_impl(line_str);
}
self.buffer.drain(..=pos);
}
Ok(())
}
}
}
#[doc(inline)]
#[cfg(feature = "env_logger")]
pub use ods_logger::debug_logger_target;