diff --git a/crates/ass-renderer/Cargo.toml b/crates/ass-renderer/Cargo.toml index 77361c5..cb7dd21 100644 --- a/crates/ass-renderer/Cargo.toml +++ b/crates/ass-renderer/Cargo.toml @@ -66,13 +66,12 @@ pkg-config = "0.3" pretty_assertions = "1.4" [features] -default = ["analysis-integration", "backend-probing", "simd", "image", "serde", "libass-compare"] +default = ["analysis-integration", "backend-probing", "simd", "image", "serde"] minimal = ["nostd", "analysis-integration"] -full = ["analysis-integration", "backend-probing", "simd", "image", "serde", "libass-compare"] +full = ["analysis-integration", "backend-probing", "simd", "image", "serde",] analysis-integration = ["ass-core/analysis"] -libass-compare = [] backend-probing = [] backend-metrics = [] diff --git a/crates/ass-renderer/build.rs b/crates/ass-renderer/build.rs deleted file mode 100644 index 2c7bba1..0000000 --- a/crates/ass-renderer/build.rs +++ /dev/null @@ -1,30 +0,0 @@ -//! Build script for ass-renderer crate -//! -//! Handles linking libass when the libass-compare feature is enabled, -//! with platform-specific fallbacks for macOS Homebrew installations. - -fn main() { - // Only link libass on native targets when the libass-compare feature is enabled - #[cfg(all(feature = "libass-compare", not(target_arch = "wasm32")))] - { - // Use pkg-config to find libass - if let Err(e) = pkg_config::Config::new() - .atleast_version("0.14.0") - .probe("libass") - { - // Fallback to manual linking for macOS with Homebrew - #[cfg(target_os = "macos")] - { - println!("cargo:warning=pkg-config failed: {e}, trying homebrew paths"); - println!("cargo:rustc-link-search=/opt/homebrew/lib"); - println!("cargo:rustc-link-search=/usr/local/lib"); - println!("cargo:rustc-link-lib=ass"); - } - - #[cfg(not(target_os = "macos"))] - { - panic!("Cannot find libass. Please install libass development files. Error: {e}"); - } - } - } -} diff --git a/crates/ass-renderer/src/backends/software.rs b/crates/ass-renderer/src/backends/software.rs index d97cda9..5d62a69 100644 --- a/crates/ass-renderer/src/backends/software.rs +++ b/crates/ass-renderer/src/backends/software.rs @@ -6,10 +6,10 @@ // a separate implementation would be required. #[cfg(feature = "nostd")] compile_error!( - "The software backend (software.rs) is not compatible with the `nostd` feature. \ + "The software backend is not compatible with the `nostd` feature. \ It uses `bytes::BytesMut`, `std::sync::Mutex`, and `bumpalo`, which all require std. \ - Either disable the software-backend feature when building with nostd, or contribute a \ - no_std-compatible alternative." + To fix: use `bytes` with default-features disabled, swap Mutex for RefCell \ + on nostd, and gate std::sync imports behind #[cfg(not(feature = \"nostd\"))]." ); #[cfg(feature = "nostd")] diff --git a/crates/ass-renderer/src/debug/analyzer.rs b/crates/ass-renderer/src/debug/analyzer.rs deleted file mode 100644 index c952753..0000000 --- a/crates/ass-renderer/src/debug/analyzer.rs +++ /dev/null @@ -1,559 +0,0 @@ -//! Frame analysis tools for detailed debugging and profiling -//! -//! This module provides in-depth analysis capabilities for rendered frames, -//! including pixel statistics, region detection, and text analysis. - -use crate::Frame; - -#[cfg(feature = "nostd")] -use alloc::vec::Vec; - -/// Frame analyzer for detailed text-based debugging -pub struct FrameAnalyzer { - enable_pixel_histogram: bool, - enable_region_analysis: bool, - enable_text_detection: bool, -} - -impl Default for FrameAnalyzer { - fn default() -> Self { - Self::new() - } -} - -impl FrameAnalyzer { - /// Create a new frame analyzer with all analysis features enabled - pub fn new() -> Self { - Self { - enable_pixel_histogram: true, - enable_region_analysis: true, - enable_text_detection: true, - } - } - - /// Analyze a frame and generate a detailed report - pub fn analyze(&self, frame: &Frame) -> AnalysisReport { - let mut report = AnalysisReport::new(frame.width(), frame.height()); - - if self.enable_pixel_histogram { - report.pixel_histogram = self.calculate_pixel_histogram(frame); - } - - if self.enable_region_analysis { - report.regions = self.detect_regions(frame); - } - - if self.enable_text_detection { - report.text_areas = self.detect_text_areas(frame); - } - - report.calculate_statistics(frame); - report - } - - fn calculate_pixel_histogram(&self, frame: &Frame) -> PixelHistogram { - let pixels = frame.pixels(); - let mut histogram = PixelHistogram::default(); - - for chunk in pixels.chunks(4) { - if chunk.len() == 4 { - let r = chunk[0]; - let g = chunk[1]; - let b = chunk[2]; - let a = chunk[3]; - - histogram.red[r as usize] += 1; - histogram.green[g as usize] += 1; - histogram.blue[b as usize] += 1; - histogram.alpha[a as usize] += 1; - - if a > 0 { - histogram.non_transparent_count += 1; - - // Classify pixel - if r == g && g == b { - if r > 200 { - histogram.white_pixels += 1; - } else if r < 50 { - histogram.black_pixels += 1; - } else { - histogram.gray_pixels += 1; - } - } else { - histogram.colored_pixels += 1; - } - } - } - } - - histogram - } - - fn detect_regions(&self, frame: &Frame) -> Vec { - let mut regions = Vec::new(); - let pixels = frame.pixels(); - let width = frame.width() as usize; - let height = frame.height() as usize; - - // Simple region detection using connected components - let mut visited = vec![false; width * height]; - - for y in 0..height { - for x in 0..width { - let idx = y * width + x; - let pixel_idx = idx * 4; - - if !visited[idx] && pixel_idx + 3 < pixels.len() && pixels[pixel_idx + 3] > 0 { - // Found a non-transparent, unvisited pixel - let region = self.flood_fill(frame, &mut visited, x, y); - if region.pixel_count > 10 { - // Filter out tiny regions - regions.push(region); - } - } - } - } - - regions - } - - fn flood_fill( - &self, - frame: &Frame, - visited: &mut [bool], - start_x: usize, - start_y: usize, - ) -> Region { - let pixels = frame.pixels(); - let width = frame.width() as usize; - let height = frame.height() as usize; - - let mut region = Region { - min_x: start_x as u32, - min_y: start_y as u32, - max_x: start_x as u32, - max_y: start_y as u32, - pixel_count: 0, - avg_color: [0, 0, 0, 0], - }; - - let mut stack = vec![(start_x, start_y)]; - let mut color_sum = [0u64; 4]; - - while let Some((x, y)) = stack.pop() { - if x >= width || y >= height { - continue; - } - - let idx = y * width + x; - if visited[idx] { - continue; - } - - let pixel_idx = idx * 4; - if pixel_idx + 3 >= pixels.len() || pixels[pixel_idx + 3] == 0 { - continue; - } - - visited[idx] = true; - region.pixel_count += 1; - - // Update bounds - region.min_x = region.min_x.min(x as u32); - region.min_y = region.min_y.min(y as u32); - region.max_x = region.max_x.max(x as u32); - region.max_y = region.max_y.max(y as u32); - - // Accumulate color - for i in 0..4 { - color_sum[i] += pixels[pixel_idx + i] as u64; - } - - // Add neighbors - if x > 0 { - stack.push((x - 1, y)); - } - if x + 1 < width { - stack.push((x + 1, y)); - } - if y > 0 { - stack.push((x, y - 1)); - } - if y + 1 < height { - stack.push((x, y + 1)); - } - } - - // Calculate average color - if region.pixel_count > 0 { - for (i, sum) in color_sum.iter().enumerate() { - region.avg_color[i] = (sum / region.pixel_count as u64) as u8; - } - } - - region - } - - fn detect_text_areas(&self, frame: &Frame) -> Vec