1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-20 11:47:46 +00:00

Remove usage of crc crate as a main dependency

This was temporarily used for shader key hashing, but now an original
implementation using zlib's crc32 function from crcracker
(https://github.com/NotNite/crcracker/) is used instead. Tests are added
and existing ones are used to ensure it's the same.
This commit is contained in:
Joshua Goins 2024-04-29 18:57:15 -04:00
parent cd2fee1305
commit 89d026bf63
3 changed files with 93 additions and 11 deletions

View file

@ -29,6 +29,8 @@ hmac-sha512 = "1"
# used while rust doesn't have native benchmarking capability
brunch = { version = "0.5.3", default-features = false }
# used for testing our crc implementations
crc = "3"
[features]
default = ["visual_data"]
@ -66,6 +68,3 @@ bitflags = { version = "1.3", optional = true }
# needed for dxt/bc decompression
texture2ddecoder = { version = "0.0.5", optional = true }
# used for testing our jamcrc implementation and currently SHPK
crc = "3"

View file

@ -1,6 +1,10 @@
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
use std::ops::{Add, AddAssign, BitXor, BitXorAssign};
use libz_ng_sys::z_off_t;
/// CRC used for filepath hashes in index file
pub(crate) struct Jamcrc {
table: [u32; 256],
}
@ -40,12 +44,86 @@ impl Jamcrc {
}
}
fn crc32(crc: u32, s: &[u8]) -> u32 {
unsafe { libz_ng_sys::crc32(crc, s.as_ptr(), s.len() as u32) as u32 }
}
fn crc32_combine(crc1: u32, crc2: u32, len2: usize) -> u32 {
unsafe { libz_ng_sys::crc32_combine(crc1, crc2, len2 as z_off_t) as u32 }
}
/// CRC used for shader keys
/// Credit to https://github.com/NotNite/crcracker/ for the original Rust code
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default)]
pub(crate) struct XivCrc32 {
pub crc: u32,
pub len: usize,
}
impl XivCrc32 {
pub(crate) fn new(crc: u32, len: usize) -> Self {
Self {
crc,
len,
}
}
}
impl From<&[u8]> for XivCrc32 {
fn from(s: &[u8]) -> Self {
Self::new(!crc32(0xFFFFFFFF, s), s.len())
}
}
impl <const N: usize> From<&[u8; N]> for XivCrc32 {
fn from(s: &[u8; N]) -> Self {
Self::new(!crc32(0xFFFFFFFF, s), N)
}
}
impl From<&str> for XivCrc32 {
fn from(s: &str) -> Self {
Self::from(s.as_bytes())
}
}
impl Add<XivCrc32> for XivCrc32 {
type Output = XivCrc32;
fn add(self, rhs: XivCrc32) -> Self::Output {
Self::new(crc32_combine(self.crc, rhs.crc, rhs.len), self.len + rhs.len)
}
}
impl AddAssign<XivCrc32> for XivCrc32 {
fn add_assign(&mut self, rhs: XivCrc32) {
self.crc = crc32_combine(self.crc, rhs.crc, rhs.len);
self.len += rhs.len;
}
}
impl BitXor<XivCrc32> for XivCrc32 {
type Output = XivCrc32;
fn bitxor(self, rhs: XivCrc32) -> Self::Output {
Self::new(self.crc ^ rhs.crc, self.len.max(rhs.len))
}
}
impl BitXorAssign<XivCrc32> for XivCrc32 {
fn bitxor_assign(&mut self, rhs: XivCrc32) {
self.crc ^= rhs.crc;
self.len = self.len.max(rhs.len);
}
}
#[cfg(test)]
mod tests {
use crc::{Algorithm, Crc};
use super::*;
#[test]
fn check_library() {
fn check_jamcrc() {
use crc::{Crc, CRC_32_JAMCRC};
const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_JAMCRC);
@ -56,4 +134,14 @@ mod tests {
assert_eq!(JAMCR.checksum(&bytes), CRC.checksum(&bytes))
}
#[test]
fn check_xivcrc() {
const CRC_32_TEST: Algorithm<u32> = Algorithm { width: 32, poly: 0x04c11db7, init: 0x00000000, refin: true, refout: true, xorout: 0x00000000, check: 0x765e7680, residue: 0xc704dd7b };
const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_TEST);
let str = "Default";
assert_eq!(XivCrc32::from(str).crc, JAMCR.checksum(str.as_bytes()));
}
}

View file

@ -5,7 +5,7 @@ use std::io::{Cursor, SeekFrom};
use crate::ByteSpan;
use binrw::{binread, BinRead};
use crc::{Algorithm, Crc};
use crate::crc::XivCrc32;
#[binread]
#[br(little, import {
@ -209,10 +209,6 @@ pub struct ShaderPackage {
const SELECTOR_MULTIPLER: u32 = 31;
// TODO: replace use of crc crate here
const CRC_32_TEST: Algorithm<u32> = Algorithm { width: 32, poly: 0x04c11db7, init: 0x00000000, refin: true, refout: true, xorout: 0x00000000, check: 0x765e7680, residue: 0xc704dd7b };
const JAMCR: Crc<u32> = Crc::<u32>::new(&CRC_32_TEST);
impl ShaderPackage {
/// Reads an existing SHPK file
pub fn from_existing(buffer: ByteSpan) -> Option<ShaderPackage> {
@ -275,7 +271,7 @@ impl ShaderPackage {
}
pub fn crc(str: &str) -> u32 {
return JAMCR.checksum(str.as_bytes());
return XivCrc32::from(str).crc;
}
}
@ -283,7 +279,6 @@ impl ShaderPackage {
mod tests {
use std::fs::read;
use std::path::PathBuf;
use crate::repository::Category::Shader;
use super::*;