thumbnail/Thumbnailer.go

94 lines
1.6 KiB
Go
Raw Normal View History

2016-11-18 06:44:27 +00:00
package thumbnail
import (
"fmt"
"image"
"image/jpeg"
"image/png"
"os"
"strings"
"sync"
)
type Thumbnailer struct {
Width int
Height int
MaxCacheSize int
cacheMtx sync.RWMutex
thumbCache map[string][]byte
}
func NewThumbnailer() *Thumbnailer {
return &Thumbnailer{
Width: 100,
Height: 100,
MaxCacheSize: 10,
thumbCache: make(map[string][]byte, 0),
}
}
func (this *Thumbnailer) RenderFile(absPath string) ([]byte, error) {
this.cacheMtx.RLock()
tcache, ok := this.thumbCache[absPath]
this.cacheMtx.RUnlock()
if ok {
return tcache, nil
}
// Add to cache
tcache, err := this.RenderFile_NoCache(absPath)
if err != nil {
return nil, err
}
this.cacheMtx.Lock()
// FIXME prune old cached thumbnails
this.thumbCache[absPath] = tcache
this.cacheMtx.Unlock()
return tcache, nil
}
func (this *Thumbnailer) RenderFile_NoCache(absPath string) ([]byte, error) {
fh, err := os.OpenFile(absPath, os.O_RDONLY, 0400)
if err != nil {
return nil, err
}
defer fh.Close()
if len(absPath) < 4 {
return nil, fmt.Errorf("No extension on filename")
}
extension := strings.ToLower(absPath[len(absPath)-4:])
2016-11-18 06:44:27 +00:00
switch extension {
case ".jpg", "jpeg":
src, err := jpeg.Decode(fh)
if err != nil {
return nil, err
}
2016-11-18 06:44:27 +00:00
return this.RenderScaledImage(src)
2016-11-18 06:44:27 +00:00
case ".png":
src, err := png.Decode(fh)
if err != nil {
return nil, err
}
2016-11-18 06:44:27 +00:00
return this.RenderScaledImage(src)
case ".avi", ".mkv", ".mp4", ".ogm", ".wmv":
return this.RenderScaledFfmpeg(absPath)
default:
return nil, fmt.Errorf("No thumbnailer for file type")
2016-11-18 06:44:27 +00:00
}
}