diff options
Diffstat (limited to 'vendor/github.com/sizeofint/webpanimation/webpanimation.go')
-rw-r--r-- | vendor/github.com/sizeofint/webpanimation/webpanimation.go | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/vendor/github.com/sizeofint/webpanimation/webpanimation.go b/vendor/github.com/sizeofint/webpanimation/webpanimation.go new file mode 100644 index 00000000..b8a2adeb --- /dev/null +++ b/vendor/github.com/sizeofint/webpanimation/webpanimation.go @@ -0,0 +1,109 @@ +package webpanimation + +import ( + "errors" + "fmt" + "image" + "image/draw" + "io" +) + +type WebpAnimation struct { + WebPAnimEncoderOptions *WebPAnimEncoderOptions + Width int + Height int + loopCount int + AnimationEncoder *WebPAnimEncoder + WebPData *WebPData + WebPMux *WebPMux + WebPPictures []*WebPPicture +} + +// NewWebpAnimation Initialize animation +func NewWebpAnimation(width, height, loopCount int) *WebpAnimation { + webpAnimation := &WebpAnimation{loopCount: loopCount, Width: width, Height: height} + webpAnimation.WebPAnimEncoderOptions = &WebPAnimEncoderOptions{} + + WebPAnimEncoderOptionsInitInternal(webpAnimation.WebPAnimEncoderOptions) + + webpAnimation.AnimationEncoder = WebPAnimEncoderNewInternal(width, height, webpAnimation.WebPAnimEncoderOptions) + return webpAnimation +} + +// ReleaseMemory release memory +func (wpa *WebpAnimation) ReleaseMemory() { + WebPDataClear(wpa.WebPData) + WebPMuxDelete(wpa.WebPMux) + for _, webpPicture := range wpa.WebPPictures { + WebPPictureFree(webpPicture) + } + WebPAnimEncoderDelete(wpa.AnimationEncoder) +} + +// AddFrame add frame to animation +func (wpa *WebpAnimation) AddFrame(img image.Image, timestamp int, webpcfg WebPConfig) error { + var webPPicture *WebPPicture = nil + var m *image.RGBA + if img != nil { + if v, ok := img.(*image.RGBA); ok { + m = v + } else { + b := img.Bounds() + m = image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) + draw.Draw(m, m.Bounds(), img, b.Min, draw.Src) + } + + webPPicture = &WebPPicture{} + wpa.WebPPictures = append(wpa.WebPPictures, webPPicture) + webPPicture.SetUseArgb(1) + webPPicture.SetHeight(wpa.Height) + webPPicture.SetWidth(wpa.Width) + err := WebPPictureImportRGBA(m.Pix, m.Stride, webPPicture) + if err != nil { + return err + } + } + + res := WebPAnimEncoderAdd(wpa.AnimationEncoder, webPPicture, timestamp, webpcfg) + if res == 0 { + return errors.New("Failed to add frame in animation ecoder") + } + return nil +} + +// Encode encode animation +func (wpa *WebpAnimation) Encode(w io.Writer) error { + wpa.WebPData = &WebPData{} + + WebPDataInit(wpa.WebPData) + + WebPAnimEncoderAssemble(wpa.AnimationEncoder, wpa.WebPData) + + if wpa.loopCount > 0 { + wpa.WebPMux = WebPMuxCreateInternal(wpa.WebPData, 1) + if wpa.WebPMux == nil { + return errors.New("ERROR: Could not re-mux to add loop count/metadata.") + } + WebPDataClear(wpa.WebPData) + + webPMuxAnimNewParams := WebPMuxAnimParams{} + muxErr := WebPMuxGetAnimationParams(wpa.WebPMux, &webPMuxAnimNewParams) + if muxErr != WebpMuxOk { + return errors.New("Could not fetch loop count") + } + webPMuxAnimNewParams.SetLoopCount(wpa.loopCount) + + muxErr = WebPMuxSetAnimationParams(wpa.WebPMux, &webPMuxAnimNewParams) + if muxErr != WebpMuxOk { + return errors.New(fmt.Sprint("Could not update loop count, code:", muxErr)) + } + + muxErr = WebPMuxAssemble(wpa.WebPMux, wpa.WebPData) + if muxErr != WebpMuxOk { + return errors.New("Could not assemble when re-muxing to add") + } + + } + _, err := w.Write(wpa.WebPData.GetBytes()) + return err +} |