Improve hashing algorithm slightly (see credits)
This commit is contained in:
parent
52cc56381e
commit
c062c6b79b
2 changed files with 16 additions and 6 deletions
|
@ -4,6 +4,8 @@ use core::convert::TryFrom;
|
|||
#[cfg(feature = "std")]
|
||||
use std::io::Write;
|
||||
|
||||
use bytemuck::Pod;
|
||||
|
||||
use crate::consts::{QOI_HEADER_SIZE, QOI_OP_INDEX, QOI_OP_RUN, QOI_PADDING, QOI_PADDING_SIZE};
|
||||
use crate::error::{Error, Result};
|
||||
use crate::header::Header;
|
||||
|
@ -17,6 +19,7 @@ use crate::utils::{unlikely, BytesMut, Writer};
|
|||
fn encode_impl<W: Writer, const N: usize>(mut buf: W, data: &[u8]) -> Result<usize>
|
||||
where
|
||||
Pixel<N>: SupportedChannels,
|
||||
[u8; N]: Pod,
|
||||
{
|
||||
let cap = buf.capacity();
|
||||
|
||||
|
|
19
src/pixel.rs
19
src/pixel.rs
|
@ -1,6 +1,7 @@
|
|||
use crate::consts::{QOI_OP_DIFF, QOI_OP_LUMA, QOI_OP_RGB, QOI_OP_RGBA};
|
||||
use crate::error::Result;
|
||||
use crate::utils::Writer;
|
||||
use bytemuck::{cast, Pod};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
#[repr(transparent)]
|
||||
|
@ -107,12 +108,18 @@ impl<const N: usize> Pixel<N> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn hash_index(self) -> u8 {
|
||||
let r = self.r().wrapping_mul(3);
|
||||
let g = self.g().wrapping_mul(5);
|
||||
let b = self.b().wrapping_mul(7);
|
||||
let a = self.a_or(0xff).wrapping_mul(11);
|
||||
r.wrapping_add(g).wrapping_add(b).wrapping_add(a) % 64
|
||||
pub fn hash_index(self) -> u8
|
||||
where
|
||||
[u8; N]: Pod,
|
||||
{
|
||||
// credits for the initial idea: @zakarumych
|
||||
let v = if N == 4 {
|
||||
u32::from_ne_bytes(cast(self.0))
|
||||
} else {
|
||||
u32::from_ne_bytes([self.0[0], self.0[1], self.0[2], 0xff])
|
||||
} as u64;
|
||||
let s = ((v & 0xff00_ff00) << 32) | (v & 0x00ff_00ff);
|
||||
s.wrapping_mul(0x0300_0700_0005_000b_u64).to_le().swap_bytes() as u8 & 63
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Reference in a new issue