Merge pull request #88 from image-rs/group-unsafety

Move all bytecast unsafety to one module
This commit is contained in:
HeroicKatora authored and GitHub committed 2020-08-16 18:13:28 +02:00
commit 469883aa79
4 files changed
+43 -22

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
//! Trivial, internal byte transmutation.
//!
//! A dependency like bytemuck would give us extra assurance of the safety but overall would not
//! reduce the amount of total unsafety. We don't use it in the interface where the traits would
//! really become useful.
//!
//! SAFETY: These are benign casts as we apply them to fixed size integer types only. All of them
//! are naturally aligned, valid for all bit patterns and their alignment is surely at most their
//! size (we assert the latter fact since it is 'implementation defined' if following the letter of
//! the unsafe code guidelines).
//!
//! TODO: Would like to use std-lib here.
use std::{mem, slice};
macro_rules! integral_slice_as_bytes{($int:ty, $const:ident $(,$mut:ident)*) => {
pub(crate) fn $const(slice: &[$int]) -> &[u8] {
assert!(mem::align_of::<$int>() <= mem::size_of::<$int>());
unsafe { slice::from_raw_parts(slice.as_ptr() as *const u8, mem::size_of_val(slice)) }
}
$(pub(crate) fn $mut(slice: &mut [$int]) -> &mut [u8] {
assert!(mem::align_of::<$int>() <= mem::size_of::<$int>());
unsafe { slice::from_raw_parts_mut(slice.as_mut_ptr() as *mut u8, mem::size_of_val(slice)) }
})*
}}
integral_slice_as_bytes!(i8, i8_as_ne_bytes);
integral_slice_as_bytes!(u16, u16_as_ne_bytes, u16_as_ne_mut_bytes);
integral_slice_as_bytes!(i16, i16_as_ne_bytes);
integral_slice_as_bytes!(u32, u32_as_ne_bytes, u32_as_ne_mut_bytes);
integral_slice_as_bytes!(i32, i32_as_ne_bytes);
integral_slice_as_bytes!(u64, u64_as_ne_bytes, u64_as_ne_mut_bytes);
+4 -4
View File
@@ -1,10 +1,10 @@
//! All IO functionality needed for TIFF decoding
use crate::bytecast;
use crate::error::{TiffError, TiffResult};
use lzw;
use miniz_oxide::inflate;
use std::io::{self, Read, Seek};
use std::slice;
/// Byte order of the TIFF file.
#[derive(Clone, Copy, Debug)]
@@ -33,7 +33,7 @@ pub trait EndianReader: Read {
#[inline(always)]
fn read_u16_into(&mut self, buffer: &mut [u16]) -> Result<(), io::Error> {
self.read_exact(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, buffer.len() * 2) })?;
self.read_exact(bytecast::u16_as_ne_mut_bytes(buffer))?;
match self.byte_order() {
ByteOrder::LittleEndian =>
for n in buffer {
@@ -71,7 +71,7 @@ pub trait EndianReader: Read {
#[inline(always)]
fn read_u32_into(&mut self, buffer: &mut [u32]) -> Result<(), io::Error> {
self.read_exact(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, buffer.len() * 4) })?;
self.read_exact(bytecast::u32_as_ne_mut_bytes(buffer))?;
match self.byte_order() {
ByteOrder::LittleEndian =>
for n in buffer {
@@ -109,7 +109,7 @@ pub trait EndianReader: Read {
#[inline(always)]
fn read_u64_into(&mut self, buffer: &mut [u64]) -> Result<(), io::Error> {
self.read_exact(unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, buffer.len() * 8) })?;
self.read_exact(bytecast::u64_as_ne_mut_bytes(buffer))?;
match self.byte_order() {
ByteOrder::LittleEndian =>
for n in buffer {
+7 -18
View File
@@ -3,6 +3,7 @@ use std::convert::TryFrom;
use std::io::{Seek, Write};
use std::mem;
use bytecast;
use tags::{self, ResolutionUnit, Tag, Type};
use error::{TiffError, TiffFormatError, TiffResult};
@@ -59,9 +60,7 @@ impl TiffValue for [i8] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
let slice = bytecast::i8_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
@@ -76,9 +75,7 @@ impl TiffValue for [u16] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this sould be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 2) };
let slice = bytecast::u16_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
@@ -93,9 +90,7 @@ impl TiffValue for [i16] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
let slice = bytecast::i16_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
@@ -110,9 +105,7 @@ impl TiffValue for [u32] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this sould be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 4) };
let slice = bytecast::u32_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
@@ -127,9 +120,7 @@ impl TiffValue for [i32] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this should be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
let slice = bytecast::i32_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
@@ -144,9 +135,7 @@ impl TiffValue for [u64] {
}
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
// We write using nativeedian so this sould be safe
let slice =
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 8) };
let slice = bytecast::u64_as_ne_bytes(self);
writer.write_bytes(slice)?;
Ok(())
}
+1
View File
@@ -9,6 +9,7 @@
extern crate lzw;
extern crate miniz_oxide;
mod bytecast;
pub mod decoder;
pub mod encoder;
mod error;