blob: 213cda2cc443fb7871309eb2fa52721e066c707b [file] [log] [blame]
// Keeps a cache of all the source image thumbnails.
package source
import (
"bytes"
"encoding/json"
"fmt"
"image/png"
"io"
"path/filepath"
"sort"
"strconv"
"strings"
"github.com/nfnt/resize"
"go.skia.org/infra/go/sklog"
"go.skia.org/infra/go/util"
)
// Source handles the source images that may be used by fiddles.
type Source struct {
// thumbnails maps source image ids to the PNG bytes of the thumbnail.
thumbnails map[int][]byte
}
// New create a new Source.
func New(dir string) (*Source, error) {
s := &Source{
thumbnails: map[int][]byte{},
}
filenames, err := filepath.Glob(filepath.Join(dir, "*.png"))
if err != nil {
return nil, fmt.Errorf("Failed loading sources: %s", err)
}
for _, filename := range filenames {
err := util.WithReadFile(filename, func(f io.Reader) error {
img, err := png.Decode(f)
if err != nil {
return err
}
img = resize.Resize(64, 64, img, resize.NearestNeighbor)
buf := &bytes.Buffer{}
if err := png.Encode(buf, img); err != nil {
return fmt.Errorf("Failed to encode thumbnail: %s", err)
}
i, err := strconv.Atoi(strings.Split(filepath.Base(filename), ".")[0])
if err != nil {
return fmt.Errorf("Source filename isn't an integer: %s", err)
}
s.thumbnails[i] = buf.Bytes()
return nil
})
if err != nil {
return nil, fmt.Errorf("Failed to download source image: %s", err)
}
}
return s, err
}
// List returns the list of source image ids.
func (s *Source) List() []int {
ret := []int{}
for i := range s.thumbnails {
ret = append(ret, i)
}
sort.Sort(sort.IntSlice(ret))
return ret
}
// ListAsJSON return s.List() serialized as JSON.
func (s *Source) ListAsJSON() string {
b, err := json.Marshal(s.List())
if err != nil {
sklog.Errorf("Failed to encode as JSON: %s", err)
return ""
}
return string(b)
}
// Thumbnail returns the serialized PNG thumbnail for the given source id.
func (s *Source) Thumbnail(i int) ([]byte, bool) {
b, ok := s.thumbnails[i]
return b, ok
}