( ctx context.Context, img *vips.Image, po ProcessingOptions, )
| 374 | } |
| 375 | |
| 376 | func (p *Processor) transformAnimated( |
| 377 | ctx context.Context, |
| 378 | img *vips.Image, |
| 379 | po ProcessingOptions, |
| 380 | ) error { |
| 381 | if po.TrimEnabled() { |
| 382 | slog.Warn("Trim is not supported for animated images") |
| 383 | po.DisableTrim() |
| 384 | } |
| 385 | |
| 386 | imgWidth := img.Width() |
| 387 | frameHeight := img.PageHeight() |
| 388 | framesCount := img.PagesLoaded() |
| 389 | |
| 390 | // Get frame delays. We'll need to set them back later. |
| 391 | // If we don't have delay info, we'll set a default delay later. |
| 392 | delay, err := img.GetIntSliceDefault("delay", nil) |
| 393 | if err != nil { |
| 394 | return err |
| 395 | } |
| 396 | |
| 397 | // Get loop count. We'll need to set it back later. |
| 398 | // 0 means infinite looping. |
| 399 | loop, err := img.GetIntDefault("loop", 0) |
| 400 | if err != nil { |
| 401 | return err |
| 402 | } |
| 403 | |
| 404 | // Disable watermarking for individual frames. |
| 405 | // It's more efficient to apply watermark to all frames at once after they are processed. |
| 406 | watermarkOpacity := po.WatermarkOpacity() |
| 407 | if watermarkOpacity > 0 { |
| 408 | po.DeleteWatermarkOpacity() |
| 409 | defer func() { po.SetWatermarkOpacity(watermarkOpacity) }() |
| 410 | } |
| 411 | |
| 412 | // Make a slice to hold processed frames and ensure they are cleared on function exit |
| 413 | frames := make([]*vips.Image, 0, framesCount) |
| 414 | defer func() { |
| 415 | for _, frame := range frames { |
| 416 | if frame != nil { |
| 417 | frame.Clear() |
| 418 | } |
| 419 | } |
| 420 | }() |
| 421 | |
| 422 | for i := range framesCount { |
| 423 | frame := new(vips.Image) |
| 424 | |
| 425 | // Extract an individual frame from the image. |
| 426 | // Libvips loads animated images as a single image with frames stacked vertically. |
| 427 | if err = img.Extract(frame, 0, i*frameHeight, imgWidth, frameHeight); err != nil { |
| 428 | return err |
| 429 | } |
| 430 | |
| 431 | frames = append(frames, frame) |
| 432 | |
| 433 | // Transform the frame using the main pipeline. |
no test coverage detected