Skip to content

Instantly share code, notes, and snippets.

@cypres
Last active August 28, 2019 12:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cypres/fd846c0d24d0d90db60fcb1862946040 to your computer and use it in GitHub Desktop.
Save cypres/fd846c0d24d0d90db60fcb1862946040 to your computer and use it in GitHub Desktop.
libheif segfault reproduce script
package main
import (
"flag"
"image"
"io/ioutil"
"log"
"sync"
"github.com/strukturag/libheif/go/heif"
)
var (
input = flag.String("input", "", "input file")
rgb = flag.Bool("rgb", false, "decode as rgb")
)
func do() error {
flag.Parse()
if input == nil || *input == "" {
log.Fatal("input not set")
}
imgbytes, err := ioutil.ReadFile(*input)
if err != nil {
return err
}
numRequests := 100
m := sync.RWMutex{}
c := sync.NewCond(&m)
var wg sync.WaitGroup
var loadit bool
wg.Add(numRequests)
for i := 0; i < numRequests; i++ {
go func() {
c.L.Lock()
for !loadit {
c.Wait()
}
c.L.Unlock()
TransformHeif(imgbytes, *rgb)
wg.Done()
}()
}
c.L.Lock()
loadit = true
c.Broadcast()
c.L.Unlock()
wg.Wait()
return nil
}
func TransformHeif(data []byte, rgb bool) (out image.Image, width, height int, scaleFactor float64, err error) {
ctx, err := heif.NewContext()
if err != nil {
return nil, 0, 0, 0, err
}
err = ctx.ReadFromMemory(data)
if err != nil {
return nil, 0, 0, 0, err
}
imgh, err := ctx.GetPrimaryImageHandle()
if err != nil {
return nil, 0, 0, 0, err
}
width = imgh.GetWidth()
height = imgh.GetHeight()
// Calculate scaling factor
scaledW, scaledH, scaleFactor := width/2, height/2, 0.5
var img *heif.Image
if !rgb {
img, err = imgh.DecodeImage(heif.ColorspaceUndefined, heif.ChromaUndefined, nil)
} else {
img, err = imgh.DecodeImage(heif.ColorspaceRGB, heif.ChromaInterleavedRGBA, nil)
}
if err != nil {
return nil, 0, 0, 0, err
}
// Scale if required
if scaleFactor > 1.1 || scaleFactor < 0.9 {
img, err = img.ScaleImage(scaledW, scaledH)
if err != nil {
return nil, 0, 0, 0, err
}
} else {
scaleFactor = 1
}
goimg, err := img.GetImage()
if err != nil {
return nil, 0, 0, 0, err
}
return goimg, width, height, scaleFactor, nil
}
func main() {
if err := do(); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment