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
|
//! All IO functionality needed for TIFF decoding
|
||||||
|
|
||||||
|
use crate::bytecast;
|
||||||
use crate::error::{TiffError, TiffResult};
|
use crate::error::{TiffError, TiffResult};
|
||||||
use lzw;
|
use lzw;
|
||||||
use miniz_oxide::inflate;
|
use miniz_oxide::inflate;
|
||||||
use std::io::{self, Read, Seek};
|
use std::io::{self, Read, Seek};
|
||||||
use std::slice;
|
|
||||||
|
|
||||||
/// Byte order of the TIFF file.
|
/// Byte order of the TIFF file.
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
@@ -33,7 +33,7 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u16_into(&mut self, buffer: &mut [u16]) -> Result<(), io::Error> {
|
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() {
|
match self.byte_order() {
|
||||||
ByteOrder::LittleEndian =>
|
ByteOrder::LittleEndian =>
|
||||||
for n in buffer {
|
for n in buffer {
|
||||||
@@ -71,7 +71,7 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u32_into(&mut self, buffer: &mut [u32]) -> Result<(), io::Error> {
|
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() {
|
match self.byte_order() {
|
||||||
ByteOrder::LittleEndian =>
|
ByteOrder::LittleEndian =>
|
||||||
for n in buffer {
|
for n in buffer {
|
||||||
@@ -109,7 +109,7 @@ pub trait EndianReader: Read {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn read_u64_into(&mut self, buffer: &mut [u64]) -> Result<(), io::Error> {
|
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() {
|
match self.byte_order() {
|
||||||
ByteOrder::LittleEndian =>
|
ByteOrder::LittleEndian =>
|
||||||
for n in buffer {
|
for n in buffer {
|
||||||
|
|||||||
+7
-18
@@ -3,6 +3,7 @@ use std::convert::TryFrom;
|
|||||||
use std::io::{Seek, Write};
|
use std::io::{Seek, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
use bytecast;
|
||||||
use tags::{self, ResolutionUnit, Tag, Type};
|
use tags::{self, ResolutionUnit, Tag, Type};
|
||||||
use error::{TiffError, TiffFormatError, TiffResult};
|
use error::{TiffError, TiffFormatError, TiffResult};
|
||||||
|
|
||||||
@@ -59,9 +60,7 @@ impl TiffValue for [i8] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this should be safe
|
let slice = bytecast::i8_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -76,9 +75,7 @@ impl TiffValue for [u16] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this sould be safe
|
let slice = bytecast::u16_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 2) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -93,9 +90,7 @@ impl TiffValue for [i16] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this should be safe
|
let slice = bytecast::i16_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -110,9 +105,7 @@ impl TiffValue for [u32] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this sould be safe
|
let slice = bytecast::u32_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 4) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -127,9 +120,7 @@ impl TiffValue for [i32] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this should be safe
|
let slice = bytecast::i32_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * Self::BYTE_LEN as usize) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -144,9 +135,7 @@ impl TiffValue for [u64] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
fn write<W: Write>(&self, writer: &mut TiffWriter<W>) -> TiffResult<()> {
|
||||||
// We write using nativeedian so this sould be safe
|
let slice = bytecast::u64_as_ne_bytes(self);
|
||||||
let slice =
|
|
||||||
unsafe { ::std::slice::from_raw_parts(self.as_ptr() as *const u8, self.len() * 8) };
|
|
||||||
writer.write_bytes(slice)?;
|
writer.write_bytes(slice)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
extern crate lzw;
|
extern crate lzw;
|
||||||
extern crate miniz_oxide;
|
extern crate miniz_oxide;
|
||||||
|
|
||||||
|
mod bytecast;
|
||||||
pub mod decoder;
|
pub mod decoder;
|
||||||
pub mod encoder;
|
pub mod encoder;
|
||||||
mod error;
|
mod error;
|
||||||
|
|||||||
Reference in new issue
Block a user