Documentation
¶
Overview ¶
Package art contains WaxBin's pure-Go image handling for the read-side art resolver: content hashing for the content-addressed store, format and dimension probing, thumbnail generation (decode, scale to fit, re-encode), and folding a caller-supplied format name to the short token the store holds. JPEG/PNG/GIF use standard library decoders; WebP, BMP and TIFF use x/image. Formats without a registered decoder, such as AVIF or HEIC, are stored and served unscaled by the resolver, and Displayable names the formats a resolver may hand back as stored rather than re-encoding. No CGO is used.
Index ¶
- func Displayable(format string) bool
- func Hash(data []byte) string
- func NormalizeFormat(s string) string
- func Probe(data []byte) (format string, width, height int, err error)
- func Rung(size int) int
- func Rungs() []int
- func SniffExotic(data []byte) (format string, ok bool)
- func Thumbnail(src []byte, maxDim int) (out []byte, format string, w, h int, err error)
- type Info
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Displayable ¶
Displayable reports whether a format is one every mainstream client, browser and native toolkit alike, has decoded for years. A positive size in a resolve consults it before answering with the stored source unscaled, so a cover that fits the rung that size rounds to (Rung) but is held in a format outside the set is re-encoded at its own size rather than handed back as stored. The rung and not the raw size is what it is measured against, so a consumer predicting the answer rounds first.
The set is a conservative floor rather than an exhaustive claim about what any given client can paint. A consumer with a wider decoder is free to ignore it and read ArtBlob.Format instead. TIFF is the one format WaxBin decodes today that is outside it, which makes it the case a sized resolve re-encodes; a cover in a format nothing here decodes cannot be re-encoded at all, so it is served as stored and the consumer decides what to draw with it. That residual is why this is exported rather than kept private to the store: the consumer holding it should not have to keep a second list beside this one.
It folds its argument first, so a caller holding a transport's Content-Type gets the same answer as one holding a stored token.
func Hash ¶
Hash returns the content-address key for image bytes: the hex SHA-256. Two files with identical bytes, such as the same cover embedded in every track of an album, produce the same hash and are stored once.
func NormalizeFormat ¶
NormalizeFormat folds a caller-supplied image format to the short token ArtImage.Format holds. It accepts the token itself ("jpeg"), a bare extension ("jpg"), or a media type from a transport ("image/jpeg; charset=binary"), and falls back to an image media type's subtype for a format WaxBin has no decoder for, since that is still the only description the stored cover will ever have.
Anything it cannot read as a format normalizes to "", which every caller reads as "the caller named nothing" and answers with its own policy. That covers a media type naming something other than an image, and any subtype outside the token shape below: what reaches here is a header a remote server chose or a flag a person typed, and the result is stored, reported over the proxy, and printed, so an unbounded string has no business becoming a format. Its own output always normalizes to itself.
func Probe ¶
Probe reports an image's format and pixel dimensions without decoding the whole image. It returns an error for an unrecognized or truncated image.
func Rung ¶
Rung rounds a requested box up to the smallest rung that holds it, and to the floor for anything under the ladder. A box past the top rung is bespoke rather than a layout size, so it is served as asked: clamping it would silently downscale a caller that budgeted for a full-size image, and a request that large is not the churn the ladder exists to bound. A non-positive size asks for no box and rounds to zero.
func Rungs ¶
func Rungs() []int
Rungs returns the ladder, smallest first, which is the opposite of the census in model.ThumbCacheReport.Rungs. It is exported so a client sizing to a layout box can ask at a rung directly instead of keeping a second copy of the list beside this one.
func SniffExotic ¶
SniffExotic recognizes an ISOBMFF-based image WaxBin has no pure-Go decoder for (AVIF, HEIC/HEIF) by its `ftyp` brand, returning the short format token. Such an image is still stored, deduped, and served, but always at full size, since it cannot be thumbnailed. Which route it takes there depends on whether anything else supplied its dimensions: with none it never reaches a decoder, while a container that declared them (a FLAC picture block, say) sends the first resolve at each box through a decode that fails and falls back. It reports false for anything the standard decoders already handle or do not recognize.
func Thumbnail ¶
Thumbnail decodes src and produces a thumbnail scaled to fit within a maxDim x maxDim box, preserving aspect ratio. It never upscales: a source already within the box is returned re-encoded at its own size. The output is JPEG for a JPEG source and PNG otherwise, so PNG/GIF/WebP transparency survives. It returns the encoded bytes, the output format, and the output dimensions.
Types ¶
type Info ¶
Info is what the store needs to know about an image it is about to hold: the content address, the format it was recognized as, and its pixel dimensions.
func Describe ¶
Describe reports an image's Info: the content address always, and the format and dimensions when the bytes decode, or the magic-sniffed format alone for an exotic AVIF/HEIC image whose dimensions stay unknown. It never fails, because an unrecognized image still has a content address and the resolver already serves such a source unscaled. An empty Format is the single signal that the bytes neither decoded nor were recognized, which each caller answers with its own policy.