@@ -192,21 +192,6 @@ impl MediaCache {
192192 Ok ( ( ) )
193193 }
194194
195- /// Writes WebP images (static or animated) to the cache
196- ///
197- /// This function handles both static (single-frame) and animated (multi-frame)
198- /// WebP images using the webp crate. For static images, it uses lossless encoding.
199- /// For animated images, it encodes all frames with their respective delays.
200- ///
201- /// # Arguments
202- ///
203- /// * `cache_dir` - The cache directory path
204- /// * `url` - The URL of the image (used for cache key generation)
205- /// * `data` - Vector of image frames with delay information
206- ///
207- /// # Returns
208- ///
209- /// Returns `Ok(())` on success or an `Error` on failure.
210195 pub fn write_webp ( cache_dir : & path:: Path , url : & str , data : Vec < ImageFrame > ) -> Result < ( ) > {
211196 if data. is_empty ( ) {
212197 return Err ( crate :: Error :: Generic (
@@ -219,46 +204,28 @@ impl MediaCache {
219204 create_dir_all ( p) ?;
220205 }
221206
222- if data. len ( ) == 1 {
223- // Static WebP - use lossless encoding
224- let frame = & data[ 0 ] ;
207+ let mut config = webp:: WebPConfig :: new ( ) . or ( Err ( crate :: Error :: Generic (
208+ "Failed to configure webp encoder" . to_owned ( ) ,
209+ ) ) ) ?;
210+ config. lossless = 1 ;
211+ config. alpha_compression = 0 ;
212+
213+ let reference_frame = data. first ( ) . expect ( "Data is not empty" ) ;
214+ let mut encoder = webp:: AnimEncoder :: new (
215+ reference_frame. image . size [ 0 ] as u32 ,
216+ reference_frame. image . size [ 1 ] as u32 ,
217+ & config
218+ ) ;
219+
220+ for frame in & data {
225221 let width = frame. image . size [ 0 ] as u32 ;
226222 let height = frame. image . size [ 1 ] as u32 ;
227-
228223 let encoder = webp:: Encoder :: from_rgba ( frame. image . as_raw ( ) , width, height) ;
229224 let encoded = encoder. encode_lossless ( ) ;
230-
231- std:: fs:: write ( file_path, & * encoded) ?;
232- } else {
233- // Animated WebP - encode all frames
234- // Note: The webp crate's animation encoding API is limited
235- // For now, we'll fall back to writing individual frames as a sequence
236- // or use the image crate's approach
237-
238- // Create an animated WebP using the webp crate
239- // First, we need to encode each frame
240- let mut encoded_frames = Vec :: new ( ) ;
241-
242- for frame_data in & data {
243- let width = frame_data. image . size [ 0 ] as u32 ;
244- let height = frame_data. image . size [ 1 ] as u32 ;
245- let encoder = webp:: Encoder :: from_rgba ( frame_data. image . as_raw ( ) , width, height) ;
246- let encoded = encoder. encode_lossless ( ) ;
247- encoded_frames. push ( ( encoded, frame_data. delay ) ) ;
248- }
249-
250- // For animated WebP, we'll use a simple approach:
251- // Write the frames as a GIF-style animation format that browsers support
252- // Unfortunately, the webp crate doesn't have a high-level animated encoder
253- // So we'll fall back to just writing the first frame for now
254- // TODO: Implement proper animated WebP encoding when the crate supports it
255-
256- if let Some ( ( first_encoded, _) ) = encoded_frames. first ( ) {
257- std:: fs:: write ( file_path, & * * first_encoded) ?;
258- }
225+ encoded_frames. push ( ( encoded, frame. delay ) ) ;
259226 }
260227
261- Ok ( ( ) )
228+ std :: fs :: write ( file_path , & * * first_encoded ) ?
262229 }
263230
264231 pub fn key ( url : & str ) -> String {
0 commit comments