diff options
author | Bjørn Erik Pedersen <[email protected]> | 2019-08-18 11:21:27 +0200 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2019-08-26 15:00:44 +0200 |
commit | f9978ed16476ca6d233a89669c62c798cdf9db9d (patch) | |
tree | 02edb31008b997a3e77055060a34971fe9e8c5a4 /resources/image_cache.go | |
parent | 58d4c0a8be8beefbd7437b17bf7a9a381164d09b (diff) | |
download | hugo-f9978ed16476ca6d233a89669c62c798cdf9db9d.tar.gz hugo-f9978ed16476ca6d233a89669c62c798cdf9db9d.zip |
Image resource refactor
This commit pulls most of the image related logic into its own package, to make it easier to reason about and extend.
This is also a rewrite of the transformation logic used in Hugo Pipes, mostly to allow constructs like the one below:
{{ ($myimg | fingerprint ).Width }}
Fixes #5903
Fixes #6234
Fixes #6266
Diffstat (limited to 'resources/image_cache.go')
-rw-r--r-- | resources/image_cache.go | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/resources/image_cache.go b/resources/image_cache.go index 3324e442e..3a9e3c2c5 100644 --- a/resources/image_cache.go +++ b/resources/image_cache.go @@ -20,7 +20,7 @@ import ( "strings" "sync" - "github.com/gohugoio/hugo/common/hugio" + "github.com/gohugoio/hugo/resources/images" "github.com/gohugoio/hugo/cache/filecache" "github.com/gohugoio/hugo/helpers" @@ -32,7 +32,7 @@ type imageCache struct { fileCache *filecache.Cache mu sync.RWMutex - store map[string]*Image + store map[string]*resourceAdapter } func (c *imageCache) isInCache(key string) bool { @@ -66,33 +66,34 @@ func (c *imageCache) normalizeKey(key string) string { func (c *imageCache) clear() { c.mu.Lock() defer c.mu.Unlock() - c.store = make(map[string]*Image) + c.store = make(map[string]*resourceAdapter) } func (c *imageCache) getOrCreate( - parent *Image, conf imageConfig, createImage func() (*Image, image.Image, error)) (*Image, error) { - + parent *imageResource, conf images.ImageConfig, + createImage func() (*imageResource, image.Image, error)) (*resourceAdapter, error) { relTarget := parent.relTargetPathFromConfig(conf) key := parent.relTargetPathForRel(relTarget.path(), false, false, false) // First check the in-memory store, then the disk. c.mu.RLock() - img, found := c.store[key] + cachedImage, found := c.store[key] c.mu.RUnlock() if found { - return img, nil + return cachedImage, nil } + var img *imageResource + // These funcs are protected by a named lock. // read clones the parent to its new name and copies // the content to the destinations. read := func(info filecache.ItemInfo, r io.Reader) error { - img = parent.clone() - img.relTargetDirFile.file = relTarget.file - img.sourceFilename = info.Name - // Make sure it's always loaded by sourceFilename. - img.openReadSeekerCloser = nil + img = parent.clone(nil) + rp := img.getResourcePaths() + rp.relTargetDirFile.file = relTarget.file + img.setSourceFilename(info.Name) w, err := img.openDestinationsForWriting() if err != nil { @@ -109,29 +110,20 @@ func (c *imageCache) getOrCreate( return err } - // create creates the image and encodes it to w (cache) and to its destinations. + // create creates the image and encodes it to the cache (w). create := func(info filecache.ItemInfo, w io.WriteCloser) (err error) { + defer w.Close() + var conv image.Image img, conv, err = createImage() if err != nil { - w.Close() return } - img.relTargetDirFile.file = relTarget.file - img.sourceFilename = info.Name + rp := img.getResourcePaths() + rp.relTargetDirFile.file = relTarget.file + img.setSourceFilename(info.Name) - destinations, err := img.openDestinationsForWriting() - if err != nil { - w.Close() - return err - } - - if destinations != nil { - w = hugio.NewMultiWriteCloser(w, destinations) - } - defer w.Close() - - return img.encodeTo(conf, conv, w) + return img.EncodeTo(conf, conv, w) } // Now look in the file cache. @@ -147,20 +139,21 @@ func (c *imageCache) getOrCreate( } // The file is now stored in this cache. - img.sourceFs = c.fileCache.Fs + img.setSourceFs(c.fileCache.Fs) c.mu.Lock() - if img2, found := c.store[key]; found { + if cachedImage, found = c.store[key]; found { c.mu.Unlock() - return img2, nil + return cachedImage, nil } - c.store[key] = img - c.mu.Unlock() - return img, nil + imgAdapter := newResourceAdapter(parent.getSpec(), true, img) + c.store[key] = imgAdapter + c.mu.Unlock() + return imgAdapter, nil } func newImageCache(fileCache *filecache.Cache, ps *helpers.PathSpec) *imageCache { - return &imageCache{fileCache: fileCache, pathSpec: ps, store: make(map[string]*Image)} + return &imageCache{fileCache: fileCache, pathSpec: ps, store: make(map[string]*resourceAdapter)} } |