Fixup the worst of ripping

This commit is contained in:
Andreas Molzer 2020-09-12 17:15:27 +02:00
parent 068a8696e7
commit ff0722af0d
2 changed files with 43 additions and 17 deletions

View File

@ -10,7 +10,6 @@ mod reader;
use std::cmp;
use std::mem;
use std::ptr;
use std::boxed;
use std::fs::File;
use std::ffi::CStr;
use std::str;
@ -20,7 +19,7 @@ use std::panic;
use libc::{free, c_int, c_uint, c_char, c_uchar, c_void};
use crate::c_api_utils::{CInterface, CFile, FnInputFile};
use gif::{Decoder, Reader, Decoded};
use gif::{Decoder, Decoded};
/// NOTE As of rust issue #954 `bool` is compatible with c_bool.
pub type c_bool = bool;
@ -157,6 +156,10 @@ pub const D_GIF_ERR_EOF_TOO_SOON : c_int = 113;
const GIF_ERROR: c_int = 0;
const GIF_OK : c_int = 1;
trait IntoCInterface {
fn into_c_interface(self) -> Box<dyn CInterface>;
}
impl GifFileType {
fn zeroed_box() -> Box<Self> {
// SAFETY: GifFileType is zeroable.

View File

@ -1,49 +1,72 @@
use std::io::prelude::*;
use std::borrow::Cow;
use crate::{GifWord, GifFileType};
use crate::{IntoCInterface, GifWord, GifFileType};
use crate::c_api_utils::{CInterface, copy_colormap, copy_data, saved_images_new};
use gif::{Block, Decoded, DecodingError, Reader};
impl<R> From<Reader<R>> for Box<dyn CInterface>
impl<R> IntoCInterface for Reader<R>
where
R: Read + 'static
{
/// Converts `Reader` into `CInterface`.
fn from(reader: Reader<R>) -> Box<dyn CInterface> {
Box::new(reader)
fn into_c_interface(self: Reader<R>) -> Box<dyn CInterface> {
Box::new(TrackingReader {
inner: self,
offset: 0,
buffer: vec![],
last_ext: None,
})
}
}
/// The c-interface expects us to store more state.
///
/// This wraps the gif crate to do just that.
struct<R: Read + 'static> TrackingReader<R> {
struct TrackingReader<R: Read + 'static> {
inner: Reader<R>,
/// Offset within the frame for reading chunks.
offset: usize,
/// Buffer for the current frame.
buffer: Vec<u8>,
/// The last extension we read.
last_ext: Option<Extension>,
}
impl<R: Read> CInterface for Reader<R> {
struct Extension {
kind: u8,
data: Vec<u8>,
}
impl<R: Read> CInterface for TrackingReader<R> {
fn read_screen_desc(&mut self, this: &mut GifFileType) {
this.SWidth = self.width() as GifWord;
this.SHeight = self.height() as GifWord;
this.SWidth = self.inner.width() as GifWord;
this.SHeight = self.inner.height() as GifWord;
this.SColorResolution = 255;//self.global_palette().len() as GifWord;
this.SBackGroundColor = self.bg_color().unwrap_or(0) as GifWord;
this.SBackGroundColor = self.inner.bg_color().unwrap_or(0) as GifWord;
this.AspectByte = 0;
self.offset = 0;
}
fn current_image_buffer(&mut self) -> Result<(&[u8], &mut usize), DecodingError> {
if let Cow::Borrowed(_) = self.current_frame.buffer {
self.read_next_frame()?;
if self.offset >= self.buffer.len() {
self.inner.next_frame_info()?;
self.buffer.resize(self.inner.buffer_size(), 0u8);
self.offset = self.buffer.len();
self.inner.read_into_buffer(&mut self.buffer)?;
self.offset = 0;
}
Ok((&self.current_frame.buffer, &mut self.offset))
Ok((&self.buffer, &mut self.offset))
}
fn last_ext(&self) -> (u8, &[u8], bool) {
self.decoder.decoder.last_ext()
match &self.last_ext {
Some(Extension { kind, data}) => (*kind, data, true),
None => (0, &[], false),
}
}
fn next_record_type(&mut self) -> Result<Block, DecodingError> {
@ -57,7 +80,7 @@ impl<R: Read> CInterface for Reader<R> {
}
fn decode_next(&mut self) -> Result<Option<Decoded>, DecodingError> {
self.decode_next()
self.inner.decode_next()
}
/*