Skip to content
This repository was archived by the owner on May 10, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
[package]
edition = "2018"
name = "libycresources"
version = "0.1.0"
version = "0.2.0"

[[example]]
name = "undat"

[[example]]
name = "fontview"

[dev-dependencies]
clap = "3.0.0-beta.2"
76 changes: 76 additions & 0 deletions examples/fontview/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
pub(crate) mod print;

use libycresources::aaf;

use clap::Clap;
use std::fs::File;

#[derive(Clap)]
#[clap(name = "fontview", version)]
struct Options {
/// Path to the input font file (.aaf)
#[clap(short, long)]
input: String,
#[clap(subcommand)]
action: Action,
}

#[derive(Clap)]
enum Action {
/// Prints all glyphs from specified font
Dump,
/// Prints specified string with glyphs from font
Print(Print),
}

#[derive(Clap)]
struct Print {
string: String,
}

fn main() {
let options = Options::parse();

let file = match File::open(&options.input) {
Err(error) => {
eprintln!("Couldn't open input file: {:?}", error);
return;
}
Ok(value) => value,
};

let mut reader = std::io::BufReader::with_capacity(1 * 1024 * 1024, file);

let font = match aaf::parse::font(&mut reader) {
Err(error) => {
eprintln!("Error occured: {:?}", error);
return;
}
Ok(value) => value,
};

match options.action {
Action::Dump => {
println!("Line height: {:?}", font.height);
println!("Vertical spacing: {:?}", font.spacing.vertical);
println!("Horizontal spacing: {:?}", font.spacing.horizontal);

println!();

for glyph in font.glyphs {
print::glyph(&glyph);
}
}
Action::Print(arguments) => {
for char in arguments.string.chars() {
if char.is_alphanumeric() {
let glyph = &font.glyphs[char as usize];
print::glyph(&glyph);
} else {
eprintln!("Non-ASCII char found within provided string. Aborting.");
return;
}
}
}
}
}
18 changes: 18 additions & 0 deletions examples/fontview/print.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use libycresources::aaf;

pub fn glyph(glyph: &aaf::Glyph) {
if !glyph.pixels.is_empty() {
for row in 0..glyph.height {
for column in 0..glyph.width {
let pixel = &glyph.pixels[row * glyph.width + column];
let levels = [' ', '.', ':', '-', '=', '+', '*', '#', '%', '@'];

print!("{:}", levels[levels.len() * pixel.value / pixel.scale])
}

if row != glyph.height {
println!();
}
}
}
}
4 changes: 2 additions & 2 deletions examples/undat/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
pub(crate) mod extract;
pub(crate) mod tree;
pub(crate) mod print;

use libycresources::dat;

Expand Down Expand Up @@ -51,7 +51,7 @@ fn main() {
} {
match options.action {
Action::Tree => {
tree::print(&tree);
print::tree(&tree);
}
Action::Extract(arguments) => {
let result = extract::tree(&mut reader, &tree, &arguments.output);
Expand Down
4 changes: 2 additions & 2 deletions examples/undat/tree.rs → examples/undat/print.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use libycresources::dat;

pub(crate) fn print(tree: &dat::Directory) {
pub(crate) fn tree(root: &dat::Directory) {
let mut flag_path = Vec::new();

for (depth, is_last, directory) in tree.iter() {
for (depth, is_last, directory) in root.iter() {
if depth > flag_path.iter().count() {
flag_path.push((is_last, &directory.name));
} else {
Expand Down
25 changes: 25 additions & 0 deletions src/aaf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
pub mod parse;

pub struct Pixel {
pub value: usize,
pub scale: usize,
}

pub struct Glyph {
pub width: usize,
pub height: usize,

pub pixels: Vec<Pixel>,
}

pub struct Spacing {
pub vertical: usize,
pub horizontal: usize,
}

pub struct Font {
pub height: usize,
pub spacing: Spacing,

pub glyphs: [Glyph; 256],
}
134 changes: 134 additions & 0 deletions src/aaf/parse.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
use super::{Font, Glyph, Pixel, Spacing};

use std::convert::TryInto;
use std::io::{Read, Seek, SeekFrom};
use std::mem::size_of;

#[derive(Debug)]
pub enum Error {
Read(std::io::Error),
Format,
Source,
}

pub fn font<S: Read + Seek>(source: &mut S) -> Result<Font, Error> {
if let Err(error) = source.seek(SeekFrom::Start(0)) {
return Err(Error::Read(error));
}

let mut signature_bytes = vec![0u8; 4];
match source.read_exact(&mut signature_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

if signature_bytes == b"AAFF" {
let mut height_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut height_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

let height = u16::from_be_bytes(match height_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut h_spacing_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut h_spacing_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

let h_spacing = u16::from_be_bytes(match h_spacing_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut space_width_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut space_width_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

let space_width = u16::from_be_bytes(match space_width_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut v_spacing_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut v_spacing_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

let v_spacing = u16::from_be_bytes(match v_spacing_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut sizes = [(0, 0); 256];
for size in &mut sizes {
let mut width_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut width_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

size.0 = u16::from_be_bytes(match width_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut height_bytes = vec![0u8; size_of::<u16>()];
match source.read_exact(&mut height_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

size.1 = u16::from_be_bytes(match height_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as usize;

let mut _offset_bytes = vec![0u8; size_of::<u32>()];
match source.read_exact(&mut _offset_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};
}

sizes[b' ' as usize].0 = space_width;

let mut data = sizes.map(|(width, height)| (width, height, vec![0u8; width * height]));
for bytes in &mut data {
match source.read_exact(&mut bytes.2) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};
}

let glyphs = data.map(|(width, height, bytes)| Glyph {
width,
height,
pixels: bytes
.iter()
.map(|byte| Pixel {
value: *byte as usize,
scale: 10,
})
.collect(),
});

return Ok(Font {
height,
spacing: Spacing {
vertical: v_spacing,
horizontal: h_spacing,
},
glyphs,
});
}

Err(Error::Format)
}
30 changes: 12 additions & 18 deletions src/dat/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ pub enum Error {
Decompress,
}

pub fn file<S, O>(source: &mut S, file: &File, output: &mut O) -> Result<(), Error>
where
S: Read + Seek,
O: Write,
{
pub fn file<S: Read + Seek, O: Write>(
source: &mut S,
file: &File,
output: &mut O,
) -> Result<(), Error> {
let plain = file.size;
let archived = file.range.end - file.range.start;

Expand Down Expand Up @@ -92,13 +92,13 @@ where
break;
}

if (flags & 1) != 0 {
let mut byte_bytes = vec![0u8; size_of::<u8>()];
match source.read_exact(&mut byte_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};
let mut byte_bytes = vec![0u8; size_of::<u8>()];
match source.read_exact(&mut byte_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

if (flags & 1) != 0 {
let byte = u8::from_be_bytes(match byte_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
Expand All @@ -117,13 +117,7 @@ where
offset_r = 0
}
} else {
let mut offset_w_bytes = vec![0u8; size_of::<u8>()];
match source.read_exact(&mut offset_w_bytes) {
Err(error) => return Err(Error::Read(error)),
Ok(value) => value,
};

let mut offset_w = u8::from_be_bytes(match offset_w_bytes.try_into() {
let mut offset_w = u8::from_be_bytes(match byte_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) as u16;
Expand Down
18 changes: 5 additions & 13 deletions src/dat/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ pub fn tree<S: Read + Seek>(source: &mut S) -> Result<Option<Directory>, Error>
Ok(value) => value,
};

let mut path = match String::from_utf8(match path_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) {
let mut path = match String::from_utf8(path_bytes) {
Err(_) => return Err(Error::Format),
Ok(value) => value,
};
Expand Down Expand Up @@ -112,10 +109,8 @@ pub fn tree<S: Read + Seek>(source: &mut S) -> Result<Option<Directory>, Error>

for path in &tree_paths {
let mut directory = &mut tree;
for component in path {
if let Some(index) = component {
directory = &mut directory.children[*index];
}
for index in path.iter().flatten() {
directory = &mut directory.children[*index];
}

let mut file_count_bytes = vec![0u8; size_of::<u32>()];
Expand Down Expand Up @@ -152,10 +147,7 @@ pub fn tree<S: Read + Seek>(source: &mut S) -> Result<Option<Directory>, Error>
Ok(value) => value,
};

let name = match String::from_utf8(match name_bytes.try_into() {
Err(_) => return Err(Error::Source),
Ok(value) => value,
}) {
let name = match String::from_utf8(name_bytes) {
Err(_) => return Err(Error::Format),
Ok(value) => value,
};
Expand Down Expand Up @@ -200,7 +192,7 @@ pub fn tree<S: Read + Seek>(source: &mut S) -> Result<Option<Directory>, Error>
}) as usize;

directory.files.push(File {
name: name,
name,
range: start..start + {
if packed_size > 0 {
packed_size
Expand Down
Loading