A tool for archiving & converting scans of postcards, and information about them.

fix: svg decoding

There's an occasional bug with the JPEGs within SVGs, in that they don't decode properly. I need to write tests and investigate.

+51 -3
+1 -1
formats/web/postcard.svg.qtpl
··· 1 - {% func SVG(v svgVars) %} 1 + {%- func SVG(v svgVars) -%} 2 2 <svg 3 3 xmlns="http://www.w3.org/2000/svg" 4 4 {%- code
+1 -2
formats/web/postcard.svg.qtpl.go
··· 20 20 //line postcard.svg.qtpl:1 21 21 func StreamSVG(qw422016 *qt422016.Writer, v svgVars) { 22 22 //line postcard.svg.qtpl:1 23 - qw422016.N().S(` 24 - <svg 23 + qw422016.N().S(`<svg 25 24 xmlns="http://www.w3.org/2000/svg" 26 25 `) 27 26 //line postcard.svg.qtpl:5
+1
internal/images/decode.go
··· 29 29 {"\xff\xd8", ReadJPEG}, 30 30 {"\x89PNG\r\n\x1a\n", ReadPNG}, 31 31 {"RIFF????WEBPVP8", ReadWebP}, 32 + {"<svg", ReadSVG}, 32 33 } 33 34 34 35 type readPeeker interface {
+48
internal/images/svg.go
··· 1 + package images 2 + 3 + import ( 4 + "bytes" 5 + "encoding/base64" 6 + "encoding/xml" 7 + "fmt" 8 + "image" 9 + "io" 10 + "strings" 11 + ) 12 + 13 + func ReadSVG(r io.Reader) (image.Image, []byte, error) { 14 + imgBytes, err := extractImageHref(r) 15 + if err != nil { 16 + return nil, nil, err 17 + } 18 + return ReadJPEG(bytes.NewReader(imgBytes)) 19 + } 20 + 21 + const base64prefix = "data:image/jpeg;base64," 22 + 23 + func extractImageHref(r io.Reader) ([]byte, error) { 24 + decoder := xml.NewDecoder(r) 25 + 26 + for { 27 + tok, err := decoder.Token() 28 + if err == io.EOF { 29 + return nil, fmt.Errorf("no postcard image found in SVG") 30 + } else if err != nil { 31 + return nil, fmt.Errorf("unable to parse SVG: %w", err) 32 + } 33 + 34 + switch se := tok.(type) { 35 + case xml.StartElement: 36 + if se.Name.Local == "image" { 37 + for _, attr := range se.Attr { 38 + if attr.Name.Local == "href" { 39 + if strings.HasPrefix(attr.Value, base64prefix) { 40 + b64 := attr.Value[len(base64prefix):] 41 + return base64.StdEncoding.DecodeString(b64) 42 + } 43 + } 44 + } 45 + } 46 + } 47 + } 48 + }