Merge pull request #88 from image-rs/group-unsafety
Move all bytecast unsafety to one module
This commit is contained in:
4 files changed
+43
-22
No files matched your search
@@ -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);
|
||||
@@ -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
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
extern crate lzw;
|
||||
extern crate miniz_oxide;
|
||||
|
||||
mod bytecast;
|
||||
pub mod decoder;
|
||||
pub mod encoder;
|
||||
mod error;
|
||||
|
||||
Reference in new issue
Block a user