Skip to content

Commit

Permalink
remove Subtitle struct,
Browse files Browse the repository at this point in the history
use tuple of time span and image instead
  • Loading branch information
gwen-lg committed Jul 12, 2024
1 parent d9da70b commit 2b0fff8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 107 deletions.
19 changes: 9 additions & 10 deletions src/vobsub/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@
//! extern crate image;
//! extern crate subtile;
//!
//! use crate::subtile::image::ImageArea;
//! use crate::subtile::image::{ImageSize, ImageArea};
//!
//! let idx = subtile::vobsub::Index::open("./fixtures/example.idx").unwrap();
//! for sub in idx.subtitles() {
//! let sub = sub.unwrap();
//! println!("Time: {:0.3}-{:0.3}", sub.start_time(), sub.end_time());
//! println!("Always show: {:?}", sub.force());
//! let raw_img = sub.raw_image();
//! let area = raw_img.area();
//! let (time_span, image) = sub.unwrap();
//! println!("Time: {:0.3}-{:0.3}", time_span.start, time_span.end);
//! //println!("Always show: {:?}", sub.force());
//! let area = image.area();
//! println!("At: {}, {}", area.left(), area.top());
//! println!("Size: {}x{}", area.width(), area.height());
//! let img: image::RgbaImage = raw_img.to_image(idx.palette());
//! println!("Size: {}x{}", image.width(), image.height());
//! let img: image::RgbaImage = image.to_image(idx.palette());
//!
//! // You can save or manipulate `img` using the APIs provided by the Rust
//! // `image` crate.
Expand Down Expand Up @@ -72,10 +71,10 @@ mod sub;

pub use self::{
idx::{read_palette, Index},
img::VobSubIndexedImage,
img::{VobSubIndexedImage, VobSubOcrImage},
palette::{palette, Palette},
probe::{is_idx_file, is_sub_file},
sub::{ErrorMissing, Subtitle},
sub::ErrorMissing,
};

use crate::content::ContentError;
Expand Down
117 changes: 20 additions & 97 deletions src/vobsub/sub.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use super::{img::VobSubIndexedImage, mpeg2::ps, VobSubError};
use crate::{
content::{Area, AreaValues},
time::{TimePoint, TimeSpan},
util::BytesFormatter,
vobsub::{
img::{VobSubRleImage, VobSubRleImageData},
Expand All @@ -27,17 +28,9 @@ use nom::{
sequence::{preceded, Tuple},
IResult,
};
use std::{
cmp::Ordering,
fmt::{self, Debug},
};
use std::{cmp::Ordering, fmt::Debug};
use thiserror::Error;

/// The default time between two adjacent subtitles if no end time is
/// provided. This is chosen to be a value that's usually representable in
/// `SRT` format, barring rounding errors.
const DEFAULT_SUBTITLE_SPACING: f64 = 0.001;

/// The default length of a subtitle if no end time is provided and no
/// subtitle follows immediately after.
const DEFAULT_SUBTITLE_LENGTH: f64 = 5.0;
Expand Down Expand Up @@ -172,77 +165,6 @@ fn control_sequence(input: &[u8]) -> IResult<&[u8], ControlSequence> {
))
}

/// A single subtitle.
#[derive(Clone, PartialEq)]
pub struct Subtitle {
/// Start time of subtitle, in seconds.
start_time: f64,
/// End time of subtitle, in seconds. This may be missing from certain
/// subtitles.
end_time: Option<f64>,
/// Should this subtitle be shown even when subtitles are off?
force: bool,
/// decompressed `VobSub` image data.
image: VobSubIndexedImage,
}

impl Subtitle {
/// Start time of subtitle, in seconds.
#[must_use]
pub const fn start_time(&self) -> f64 {
self.start_time
}

/// End time of subtitle, in seconds. This may be missing from certain
/// subtitles.
/// # Panics
/// Will panic if `end_time` is not set. As it should be set before returning subtitle.
/// If happened `end_time` is called to soon, or a change has broken the intended operation.
#[must_use]
pub fn end_time(&self) -> f64 {
self.end_time
.expect("end time should have been set before returning subtitle")
}

/// Should this subtitle be shown even when subtitles are off?
#[must_use]
pub const fn force(&self) -> bool {
self.force
}

/// Our decompressed image, stored with 2 bits per byte in row-major
/// order, that can be used as indices into `palette` and `alpha`.
#[must_use]
pub const fn raw_image(&self) -> &VobSubIndexedImage {
&self.image
}

/// Set end time of subtitle if missing
pub fn sub_fix_end_time(&mut self, next: Option<Self>) {
if self.end_time.is_none() {
self.end_time = match next {
Some(next) => {
let new_end = next.start_time - DEFAULT_SUBTITLE_SPACING;
let alt_end = self.start_time + DEFAULT_SUBTITLE_LENGTH;
Some(new_end.min(alt_end))
}
None => Some(self.start_time + DEFAULT_SUBTITLE_LENGTH),
}
}
}
}

impl fmt::Debug for Subtitle {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.debug_struct("Subtitle")
.field("start_time", &self.start_time)
.field("end_time", &self.end_time)
.field("force", &self.force)
.field("image", &self.image)
.finish_non_exhaustive()
}
}

/// Parse a single `u16` value from a buffer. We don't use `nom` for this
/// because it has an inconvenient error type.
fn parse_be_u16_as_usize(buff: &[u8]) -> Result<(&[u8], usize), VobSubError> {
Expand All @@ -265,21 +187,22 @@ trait SubDecoder<'a> {
}
//struct VobSubFullDecoder;

impl<'a> SubDecoder<'a> for Subtitle {
impl<'a> SubDecoder<'a> for (TimeSpan, VobSubIndexedImage) {
type Output = Self;

fn from_data(
start_time: f64,
end_time: Option<f64>,
force: bool,
_force: bool,
rle_image: VobSubRleImage<'a>,
) -> Self::Output {
Self {
start_time,
end_time,
force,
image: VobSubIndexedImage::from(rle_image),
}
(
TimeSpan::new(
TimePoint::from_secs(start_time),
TimePoint::from_secs(end_time.unwrap_or(DEFAULT_SUBTITLE_LENGTH)),
),
VobSubIndexedImage::from(rle_image),
)
}
}

Expand Down Expand Up @@ -510,13 +433,13 @@ impl<'a> VobsubParser<'a> {
}

impl<'a> Iterator for VobsubParser<'a> {
type Item = Result<Subtitle, VobSubError>;
type Item = Result<(TimeSpan, VobSubIndexedImage), VobSubError>;

fn next(&mut self) -> Option<Self::Item> {
profiling::scope!("VobsubParser next");

let (base_time, sub_packet) = try_iter!(self.next_sub_packet());
let subtitle = subtitle::<Subtitle, _>(&sub_packet, base_time);
let subtitle = subtitle::<(TimeSpan, VobSubIndexedImage), _>(&sub_packet, base_time);

// Parse our subtitle buffer.
Some(subtitle)
Expand Down Expand Up @@ -604,12 +527,12 @@ mod tests {
let mut buffer = vec![];
f.read_to_end(&mut buffer).unwrap();
let mut subs = VobsubParser::new(&buffer);
let sub1 = subs.next().expect("missing sub 1").unwrap();
assert!(sub1.start_time - 49.4 < 0.1);
assert!(sub1.end_time.unwrap() - 50.9 < 0.1);
assert!(!sub1.force);
let (time_span, img) = subs.next().expect("missing sub 1").unwrap();
assert!(time_span.start.to_secs() - 49.4 < 0.1);
assert!(time_span.end.to_secs() - 50.9 < 0.1);
//assert!(!sub1.force);
assert_eq!(
sub1.image.area(),
img.area(),
Area::try_from(AreaValues {
x1: 750,
y1: 916,
Expand All @@ -618,8 +541,8 @@ mod tests {
})
.unwrap()
);
assert_eq!(*sub1.image.palette(), [0, 1, 3, 0]);
assert_eq!(*sub1.image.alpha(), [0, 15, 15, 15]);
assert_eq!(*img.palette(), [0, 1, 3, 0]);
assert_eq!(*img.alpha(), [0, 15, 15, 15]);
subs.next().expect("missing sub 2").unwrap();
assert!(subs.next().is_none());
}
Expand Down

0 comments on commit 2b0fff8

Please sign in to comment.