#![allow(non_upper_case_globals)]
use std::convert::TryFrom;
use std::io::{self, Read, Seek, SeekFrom};
use std::ffi::{NulError, c_void};
mod jpegxr_sys;
use jpegxr_sys::*;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, JXRError>;
#[derive(Error, Debug)]
pub enum JXRError {
#[error("I/O error: {0}")]
IoError(#[from] io::Error),
#[error("null byte in string: {0}")]
NulError(#[from] NulError),
#[error("numeric conversion error: {0}")]
TryFromIntError(#[from] std::num::TryFromIntError),
#[error("invalid data")]
InvalidData,
#[error("unrecognized pixel format GUID")]
UnrecognizedPixelFormat,
#[error("unrecognized color format")]
UnrecognizedColorFormat,
#[error("unrecognized photometric interpretation")]
UnrecognizedInterpretation,
#[error("unrecognized bit depth")]
UnrecognizedBitDepth,
#[error("unknown error")]
UnknownError,
#[error("fail")]
Fail,
#[error("not yet implemented")]
NotYetImplemented,
#[error("abstract method")]
AbstractMethod,
#[error("out of memory")]
OutOfMemory,
#[error("file I/O")]
FileIO,
#[error("buffer overflow")]
BufferOverflow,
#[error("invalid parameter")]
InvalidParameter,
#[error("invalid argument")]
InvalidArgument,
#[error("unsupported format")]
UnsupportedFormat,
#[error("incorrect codec version")]
IncorrectCodecVersion,
#[error("index not found")]
IndexNotFound,
#[error("out of sequence")]
OutOfSequence,
#[error("not initialized")]
NotInitialized,
#[error("must be multiple of 16 lines until last call")]
MustBeMultipleOf16LinesUntilLastCall,
#[error("planar alpha banded enc requires temp file")]
PlanarAlphaBandedEncRequiresTempFile,
#[error("alpha mode cannot be transcoded")]
AlphaModeCannotBeTranscoded,
#[error("incorrect codec sub-version")]
IncorrectCodecSubVersion
}
use JXRError::*;
fn call(err: ERR) -> Result<()> {
if err >= 0 {
return Ok(());
}
return Err(match err {
WMP_errFail => Fail,
WMP_errNotYetImplemented => NotYetImplemented,
WMP_errAbstractMethod => AbstractMethod,
WMP_errOutOfMemory => OutOfMemory,
WMP_errFileIO => FileIO,
WMP_errBufferOverflow => BufferOverflow,
WMP_errInvalidParameter => InvalidParameter,
WMP_errInvalidArgument => InvalidArgument,
WMP_errUnsupportedFormat => UnsupportedFormat,
WMP_errIncorrectCodecVersion => IncorrectCodecVersion,
WMP_errIndexNotFound => IndexNotFound,
WMP_errOutOfSequence => OutOfSequence,
WMP_errNotInitialized => NotInitialized,
WMP_errMustBeMultipleOf16LinesUntilLastCall => MustBeMultipleOf16LinesUntilLastCall,
WMP_errPlanarAlphaBandedEncRequiresTempFile => PlanarAlphaBandedEncRequiresTempFile,
WMP_errAlphaModeCannotBeTranscoded => AlphaModeCannotBeTranscoded,
WMP_errIncorrectCodecSubVersion => IncorrectCodecSubVersion,
_ => UnknownError
});
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum PixelFormat {
PixelFormatDontCare,
PixelFormatBlackWhite,
PixelFormat8bppGray,
PixelFormat16bppRGB555,
PixelFormat16bppRGB565,
PixelFormat16bppGray,
PixelFormat24bppBGR,
PixelFormat24bppRGB,
PixelFormat32bppBGR,
PixelFormat32bppBGRA,
PixelFormat32bppPBGRA,
PixelFormat32bppGrayFloat,
PixelFormat32bppRGB,
PixelFormat32bppRGBA,
PixelFormat32bppPRGBA,
PixelFormat48bppRGBFixedPoint,
PixelFormat16bppGrayFixedPoint,
PixelFormat32bppRGB101010,
PixelFormat48bppRGB,
PixelFormat64bppRGBA,
PixelFormat64bppPRGBA,
PixelFormat96bppRGBFixedPoint,
PixelFormat96bppRGBFloat,
PixelFormat128bppRGBAFloat, PixelFormat128bppPRGBAFloat,
PixelFormat128bppRGBFloat,
PixelFormat32bpp,
PixelFormat64bppRGBAFixedPoint,
PixelFormat64bppRGBFixedPoint,
PixelFormat128bppRGBAFixedPoint,
PixelFormat128bppRGBFixedPoint,
PixelFormat64bppRGBAHalf,
PixelFormat64bppRGBHalf,
PixelFormat48bppRGBHalf,
PixelFormat32bppRGBE,
PixelFormat16bppGrayHalf,
PixelFormat32bppGrayFixedPoint,
PixelFormat64bppCMYK,
PixelFormat24bpp3Channels,
PixelFormat32bpp4Channels,
PixelFormat40bpp5Channels,
PixelFormat48bpp6Channels,
PixelFormat56bpp7Channels,
PixelFormat64bpp8Channels,
PixelFormat48bpp3Channels,
PixelFormat64bpp4Channels,
PixelFormat80bpp5Channels,
PixelFormat96bpp6Channels,
PixelFormat112bpp7Channels,
PixelFormat128bpp8Channels,
PixelFormat40bppCMYKAlpha,
PixelFormat80bppCMYKAlpha,
PixelFormat32bpp3ChannelsAlpha,
PixelFormat40bpp4ChannelsAlpha,
PixelFormat48bpp5ChannelsAlpha,
PixelFormat56bpp6ChannelsAlpha,
PixelFormat64bpp7ChannelsAlpha,
PixelFormat72bpp8ChannelsAlpha,
PixelFormat64bpp3ChannelsAlpha,
PixelFormat80bpp4ChannelsAlpha,
PixelFormat96bpp5ChannelsAlpha,
PixelFormat112bpp6ChannelsAlpha,
PixelFormat128bpp7ChannelsAlpha,
PixelFormat144bpp8ChannelsAlpha,
PixelFormat12bppYCC420,
PixelFormat16bppYCC422,
PixelFormat20bppYCC422,
PixelFormat32bppYCC422,
PixelFormat24bppYCC444,
PixelFormat30bppYCC444,
PixelFormat48bppYCC444,
PixelFormat16bpp48bppYCC444FixedPoint,
PixelFormat20bppYCC420Alpha,
PixelFormat24bppYCC422Alpha,
PixelFormat30bppYCC422Alpha,
PixelFormat48bppYCC422Alpha,
PixelFormat32bppYCC444Alpha,
PixelFormat40bppYCC444Alpha,
PixelFormat64bppYCC444Alpha,
PixelFormat64bppYCC444AlphaFixedPoint,
PixelFormat32bppCMYKDIRECT,
PixelFormat64bppCMYKDIRECT,
PixelFormat40bppCMYKDIRECTAlpha,
PixelFormat80bppCMYKDIRECTAlpha,
}
use PixelFormat::*;
static GUID_MAP: &[(&GUID, PixelFormat)] = unsafe {
&[
(&GUID_PKPixelFormatDontCare, PixelFormatDontCare),
(&GUID_PKPixelFormatBlackWhite, PixelFormatBlackWhite),
(&GUID_PKPixelFormat8bppGray, PixelFormat8bppGray),
(&GUID_PKPixelFormat16bppRGB555, PixelFormat16bppRGB555),
(&GUID_PKPixelFormat16bppRGB565, PixelFormat16bppRGB565),
(&GUID_PKPixelFormat16bppGray, PixelFormat16bppGray),
(&GUID_PKPixelFormat24bppBGR, PixelFormat24bppBGR),
(&GUID_PKPixelFormat24bppRGB, PixelFormat24bppRGB),
(&GUID_PKPixelFormat32bppBGR, PixelFormat32bppBGR),
(&GUID_PKPixelFormat32bppBGRA, PixelFormat32bppBGRA),
(&GUID_PKPixelFormat32bppPBGRA, PixelFormat32bppPBGRA),
(&GUID_PKPixelFormat32bppGrayFloat, PixelFormat32bppGrayFloat),
(&GUID_PKPixelFormat32bppRGB, PixelFormat32bppRGB),
(&GUID_PKPixelFormat32bppRGBA, PixelFormat32bppRGBA),
(&GUID_PKPixelFormat32bppPRGBA, PixelFormat32bppPRGBA),
(&GUID_PKPixelFormat48bppRGBFixedPoint, PixelFormat48bppRGBFixedPoint),
(&GUID_PKPixelFormat16bppGrayFixedPoint, PixelFormat16bppGrayFixedPoint),
(&GUID_PKPixelFormat32bppRGB101010, PixelFormat32bppRGB101010),
(&GUID_PKPixelFormat48bppRGB, PixelFormat48bppRGB),
(&GUID_PKPixelFormat64bppRGBA, PixelFormat64bppRGBA),
(&GUID_PKPixelFormat64bppPRGBA, PixelFormat64bppPRGBA),
(&GUID_PKPixelFormat96bppRGBFixedPoint, PixelFormat96bppRGBFixedPoint),
(&GUID_PKPixelFormat96bppRGBFloat, PixelFormat96bppRGBFloat),
(&GUID_PKPixelFormat128bppRGBAFloat, PixelFormat128bppRGBAFloat),
(&GUID_PKPixelFormat128bppPRGBAFloat, PixelFormat128bppPRGBAFloat),
(&GUID_PKPixelFormat128bppRGBFloat, PixelFormat128bppRGBFloat),
(&GUID_PKPixelFormat32bppCMYK, PixelFormat32bpp),
(&GUID_PKPixelFormat64bppRGBAFixedPoint, PixelFormat64bppRGBAFixedPoint),
(&GUID_PKPixelFormat64bppRGBFixedPoint, PixelFormat64bppRGBFixedPoint),
(&GUID_PKPixelFormat128bppRGBAFixedPoint, PixelFormat128bppRGBAFixedPoint),
(&GUID_PKPixelFormat128bppRGBFixedPoint, PixelFormat128bppRGBFixedPoint),
(&GUID_PKPixelFormat64bppRGBAHalf, PixelFormat64bppRGBAHalf),
(&GUID_PKPixelFormat64bppRGBHalf, PixelFormat64bppRGBHalf),
(&GUID_PKPixelFormat48bppRGB, PixelFormat48bppRGBHalf),
(&GUID_PKPixelFormat32bppRGBE, PixelFormat32bppRGBE),
(&GUID_PKPixelFormat16bppGrayHalf, PixelFormat16bppGrayHalf),
(&GUID_PKPixelFormat32bppGrayFixedPoint, PixelFormat32bppGrayFixedPoint),
(&GUID_PKPixelFormat64bppCMYK, PixelFormat64bppCMYK),
(&GUID_PKPixelFormat24bpp3Channels, PixelFormat24bpp3Channels),
(&GUID_PKPixelFormat32bpp4Channels, PixelFormat32bpp4Channels),
(&GUID_PKPixelFormat40bpp5Channels, PixelFormat40bpp5Channels),
(&GUID_PKPixelFormat48bpp6Channels, PixelFormat48bpp6Channels),
(&GUID_PKPixelFormat56bpp7Channels, PixelFormat56bpp7Channels),
(&GUID_PKPixelFormat64bpp8Channels, PixelFormat64bpp8Channels),
(&GUID_PKPixelFormat48bpp3Channels, PixelFormat48bpp3Channels),
(&GUID_PKPixelFormat64bpp4Channels, PixelFormat64bpp4Channels),
(&GUID_PKPixelFormat80bpp5Channels, PixelFormat80bpp5Channels),
(&GUID_PKPixelFormat96bpp6Channels, PixelFormat96bpp6Channels),
(&GUID_PKPixelFormat112bpp7Channels, PixelFormat112bpp7Channels),
(&GUID_PKPixelFormat128bpp8Channels, PixelFormat128bpp8Channels),
(&GUID_PKPixelFormat40bppCMYKAlpha, PixelFormat40bppCMYKAlpha),
(&GUID_PKPixelFormat80bppCMYKAlpha, PixelFormat80bppCMYKAlpha),
(&GUID_PKPixelFormat32bpp3ChannelsAlpha, PixelFormat32bpp3ChannelsAlpha),
(&GUID_PKPixelFormat40bpp4ChannelsAlpha, PixelFormat40bpp4ChannelsAlpha),
(&GUID_PKPixelFormat48bpp5ChannelsAlpha, PixelFormat48bpp5ChannelsAlpha),
(&GUID_PKPixelFormat56bpp6ChannelsAlpha, PixelFormat56bpp6ChannelsAlpha),
(&GUID_PKPixelFormat64bpp7ChannelsAlpha, PixelFormat64bpp7ChannelsAlpha),
(&GUID_PKPixelFormat72bpp8ChannelsAlpha, PixelFormat72bpp8ChannelsAlpha),
(&GUID_PKPixelFormat64bpp3ChannelsAlpha, PixelFormat64bpp3ChannelsAlpha),
(&GUID_PKPixelFormat80bpp4ChannelsAlpha, PixelFormat80bpp4ChannelsAlpha),
(&GUID_PKPixelFormat96bpp5ChannelsAlpha, PixelFormat96bpp5ChannelsAlpha),
(&GUID_PKPixelFormat112bpp6ChannelsAlpha, PixelFormat112bpp6ChannelsAlpha),
(&GUID_PKPixelFormat128bpp7ChannelsAlpha, PixelFormat128bpp7ChannelsAlpha),
(&GUID_PKPixelFormat144bpp8ChannelsAlpha, PixelFormat144bpp8ChannelsAlpha),
(&GUID_PKPixelFormat12bppYCC420, PixelFormat12bppYCC420),
(&GUID_PKPixelFormat16bppYCC422, PixelFormat16bppYCC422),
(&GUID_PKPixelFormat20bppYCC422, PixelFormat20bppYCC422),
(&GUID_PKPixelFormat32bppYCC422, PixelFormat32bppYCC422),
(&GUID_PKPixelFormat24bppYCC444, PixelFormat24bppYCC444),
(&GUID_PKPixelFormat30bppYCC444, PixelFormat30bppYCC444),
(&GUID_PKPixelFormat48bppYCC444, PixelFormat48bppYCC444),
(&GUID_PKPixelFormat16bpp48bppYCC444FixedPoint, PixelFormat16bpp48bppYCC444FixedPoint),
(&GUID_PKPixelFormat20bppYCC420Alpha, PixelFormat20bppYCC420Alpha),
(&GUID_PKPixelFormat24bppYCC422Alpha, PixelFormat24bppYCC422Alpha),
(&GUID_PKPixelFormat30bppYCC422Alpha, PixelFormat30bppYCC422Alpha),
(&GUID_PKPixelFormat48bppYCC422Alpha, PixelFormat48bppYCC422Alpha),
(&GUID_PKPixelFormat32bppYCC444Alpha, PixelFormat32bppYCC444Alpha),
(&GUID_PKPixelFormat40bppYCC444Alpha, PixelFormat40bppYCC444Alpha),
(&GUID_PKPixelFormat64bppYCC444Alpha, PixelFormat64bppYCC444Alpha),
(&GUID_PKPixelFormat64bppYCC444AlphaFixedPoint, PixelFormat64bppYCC444AlphaFixedPoint),
(&GUID_PKPixelFormat32bppCMYKDIRECT, PixelFormat32bppCMYKDIRECT),
(&GUID_PKPixelFormat64bppCMYKDIRECT, PixelFormat64bppCMYKDIRECT),
(&GUID_PKPixelFormat40bppCMYKDIRECTAlpha, PixelFormat40bppCMYKDIRECTAlpha),
(&GUID_PKPixelFormat80bppCMYKDIRECTAlpha, PixelFormat80bppCMYKDIRECTAlpha),
]
};
impl PixelFormat {
fn from_guid(&guid: &GUID) -> Result<Self> {
for (&map_guid, map_val) in GUID_MAP {
if guid == map_guid {
return Ok(*map_val);
}
}
Err(UnrecognizedPixelFormat)
}
}
pub enum ColorFormat {
YOnly,
YUV420,
YUV422,
YUV444,
CMYK,
NComponent,
RGB,
RGBE
}
impl ColorFormat {
pub fn from_raw(raw: COLORFORMAT) -> Result<ColorFormat> {
match raw {
COLORFORMAT_Y_ONLY => Ok(ColorFormat::YOnly),
COLORFORMAT_YUV_420 => Ok(ColorFormat::YUV420),
COLORFORMAT_YUV_422 => Ok(ColorFormat::YUV422),
COLORFORMAT_YUV_444 => Ok(ColorFormat::YUV444),
COLORFORMAT_CMYK => Ok(ColorFormat::CMYK),
COLORFORMAT_NCOMPONENT => Ok(ColorFormat::NComponent),
COLORFORMAT_CF_RGB => Ok(ColorFormat::RGB),
COLORFORMAT_CF_RGBE => Ok(ColorFormat::RGBE),
_ => Err(UnrecognizedColorFormat)
}
}
}
pub enum PhotometricInterpretation {
WhiteIsZero,
BlackIsZero,
RGB,
RGBPalette,
TransparencyMask,
CMYK,
YCbCr,
CIELab,
NCH,
RGBE, }
impl PhotometricInterpretation {
pub fn from_raw(raw: u32) -> Result<PhotometricInterpretation> {
use PhotometricInterpretation::*;
match raw {
PK_PI_W0 => Ok(WhiteIsZero),
PK_PI_B0 => Ok(BlackIsZero),
PK_PI_RGB => Ok(RGB),
PK_PI_RGBPalette => Ok(RGBPalette),
PK_PI_TransparencyMask => Ok(TransparencyMask),
PK_PI_CMYK => Ok(CMYK),
PK_PI_YCbCr => Ok(YCbCr),
PK_PI_CIELab => Ok(CIELab),
PK_PI_NCH => Ok(NCH),
PK_PI_RGBE => Ok(RGBE),
_ => Err(UnrecognizedInterpretation)
}
}
}
pub enum BitDepthBits {
One, Eight,
Sixteen,
SixteenS,
SixteenF,
ThirtyTwo,
ThirtyTwoS,
ThirtyTwoF,
Five,
Ten,
FiveSixFive,
OneAlt, }
impl BitDepthBits {
pub fn from_raw(raw: i32) -> Result<BitDepthBits> {
use BitDepthBits::*;
match raw {
BITDEPTH_BITS_BD_1 => Ok(One),
BITDEPTH_BITS_BD_8 => Ok(Eight),
BITDEPTH_BITS_BD_16 => Ok(Sixteen),
BITDEPTH_BITS_BD_16S => Ok(SixteenS),
BITDEPTH_BITS_BD_16F => Ok(SixteenF),
BITDEPTH_BITS_BD_32 => Ok(ThirtyTwo),
BITDEPTH_BITS_BD_32S => Ok(ThirtyTwoS),
BITDEPTH_BITS_BD_32F => Ok(ThirtyTwoF),
BITDEPTH_BITS_BD_5 => Ok(Five),
BITDEPTH_BITS_BD_10 => Ok(Ten),
BITDEPTH_BITS_BD_565 => Ok(FiveSixFive),
BITDEPTH_BITS_BD_1alt => Ok(OneAlt),
_ => Err(UnrecognizedBitDepth)
}
}
}
pub struct PixelInfo {
raw: PKPixelInfo
}
impl PixelInfo {
pub fn from_guid(guid: &GUID) -> Result<PixelInfo> {
unsafe {
let mut info = PixelInfo {
raw: std::mem::zeroed()
};
info.raw.pGUIDPixFmt = guid;
call(PixelFormatLookup(&mut info.raw, LOOKUP_FORWARD as u8))?;
Ok(info)
}
}
pub fn format(&self) -> &GUID {
unsafe {
&*self.raw.pGUIDPixFmt
}
}
pub fn channels(&self) -> usize {
self.raw.cChannel
}
pub fn color_format(&self) -> ColorFormat {
ColorFormat::from_raw(self.raw.cfColorFormat).unwrap()
}
pub fn bit_depth(&self) -> BitDepthBits {
BitDepthBits::from_raw(self.raw.bdBitDepth).unwrap()
}
}
struct InputStream<R: Read + Seek> {
raw: Box<WMPStream>,
reader: Option<Box<R>>
}
impl<R> InputStream<R> where R: Read + Seek {
fn new(reader: R) -> Self {
let mut boxed_reader = Box::new(reader);
let stream = Self {
raw: Box::new(WMPStream {
state: WMPStream__bindgen_ty_1 {
pvObj: unsafe {
std::mem::transmute(boxed_reader.as_mut())
},
},
fMem: 0,
Close: Some(Self::input_stream_close),
EOS: None, Read: Some(Self::input_stream_read),
Write: Some(Self::input_stream_write),
SetPos: Some(Self::input_stream_set_pos),
GetPos: Some(Self::input_stream_get_pos)
}),
reader: Some(boxed_reader)
};
stream
}
pub fn into_reader(mut self) -> R {
let mut reader: Option<Box<R>> = None;
std::mem::swap(&mut reader, &mut self.reader);
*reader.unwrap()
}
unsafe fn get_reader(me: *mut WMPStream) -> *mut R {
std::mem::transmute((*me).state.pvObj)
}
unsafe extern "C" fn input_stream_close(_me: *mut *mut WMPStream) -> ERR {
WMP_errSuccess as ERR
}
unsafe extern "C" fn input_stream_read(me: *mut WMPStream, dest: *mut c_void, cb: usize) -> ERR {
let reader = Self::get_reader(me);
let bytes: *mut u8 = std::mem::transmute(dest);
let dest_slice = std::slice::from_raw_parts_mut(bytes, cb);
match (*reader).read_exact(dest_slice) {
Ok(_) => WMP_errSuccess as ERR,
Err(_) => WMP_errFileIO as ERR
}
}
unsafe extern "C" fn input_stream_write(_me: *mut WMPStream, _dest: *const c_void, _cb: usize) -> ERR {
WMP_errFileIO as ERR
}
unsafe extern "C" fn input_stream_set_pos(me: *mut WMPStream, off_pos: usize) -> ERR {
let reader = Self::get_reader(me);
match (*reader).seek(SeekFrom::Start(off_pos as u64)) {
Ok(_) => WMP_errSuccess as ERR,
Err(_) => WMP_errFileIO as ERR
}
}
unsafe extern "C" fn input_stream_get_pos(me: *mut WMPStream, off_pos: *mut usize) -> ERR {
let reader = Self::get_reader(me);
match (*reader).stream_position() {
Ok(pos) => {
match usize::try_from(pos) {
Ok(out) => {
*off_pos = out;
WMP_errSuccess as ERR
},
Err(_) => WMP_errFileIO as ERR
}
},
Err(_) => WMP_errFileIO as ERR
}
}
}
pub struct Rect {
raw: PKRect
}
impl Rect {
pub fn new(x: i32, y: i32, width: i32, height: i32) -> Self {
Self {
raw: PKRect {
X: x,
Y: y,
Width: width,
Height: height
}
}
}
pub fn get_x(&self) -> i32 {
return self.raw.X;
}
pub fn get_y(&self) -> i32 {
return self.raw.Y;
}
pub fn get_width(&self) -> i32 {
return self.raw.Width;
}
pub fn get_height(&self) -> i32 {
return self.raw.Height;
}
}
pub struct ImageDecode<R: Read + Seek> {
raw: *mut PKImageDecode,
stream: Option<InputStream<R>>,
}
impl<R> ImageDecode<R> where R: Read + Seek {
pub fn with_reader(reader: R) -> Result<Self> {
unsafe {
let mut stream = InputStream::new(reader);
let mut codec: *mut PKImageDecode = std::ptr::null_mut();
call(PKImageDecode_Create_WMP(std::mem::transmute(&mut codec)))?;
call((*codec).Initialize.unwrap()(codec, stream.raw.as_mut()))?;
Ok(Self {
raw: codec,
stream: Some(stream)
})
}
}
pub fn get_pixel_format(&self) -> Result<PixelFormat> {
unsafe {
let mut guid: GUID = std::mem::zeroed();
call((*self.raw).GetPixelFormat.unwrap()(self.raw, &mut guid))?;
PixelFormat::from_guid(&guid)
}
}
pub fn get_size(&self) -> Result<(i32, i32)> {
unsafe {
let mut width: i32 = 0;
let mut height: i32 = 0;
call((*self.raw).GetSize.unwrap()(self.raw, &mut width, &mut height))?;
Ok((width, height))
}
}
pub fn get_resolution(&self) -> Result<(f32, f32)> {
unsafe {
let mut horiz: f32 = 0.0;
let mut vert: f32 = 0.0;
call((*self.raw).GetResolution.unwrap()(self.raw, &mut horiz, &mut vert))?;
Ok((horiz, vert))
}
}
pub fn copy(&mut self, rect: &Rect, dest: &mut [u8], stride: usize) -> Result<()> {
let stride_u32 = u32::try_from(stride)?;
unsafe {
call((*self.raw).Copy.unwrap()(self.raw, &rect.raw, dest.as_mut_ptr(), stride_u32))?;
Ok(())
}
}
pub fn copy_all(&mut self, dest: &mut [u8], stride: usize) -> Result<()> {
let (width, height) = self.get_size()?;
let rect = Rect::new(0, 0, width, height);
self.copy(&rect, dest, stride)
}
pub fn into_reader(mut self) -> R {
let mut stream: Option<InputStream<R>> = None;
std::mem::swap(&mut stream, &mut self.stream);
stream.unwrap().into_reader()
}
}
impl<R> Drop for ImageDecode<R> where R: Read + Seek {
fn drop(&mut self) {
unsafe {
(*self.raw).Release.unwrap()(&mut self.raw);
}
}
}