jdeng / goheif

go gettable decoder/converter for HEIF/HEIC based on libde265
179 stars 66 forks source link

Issue on Ubuntu/Linux #24

Open ganeshagrawal55 opened 2 years ago

ganeshagrawal55 commented 2 years ago

Tried to convert few images in JPG but getting errors in alternative runs

import ( "bytes" "image/jpeg" "io" "io/ioutil" "log" "os" "path" "strings" "time"

"github.com/jdeng/goheif"

)

func main() { files, err := ioutil.ReadDir("input") if err != nil { log.Fatal(err) } if err := os.RemoveAll("output"); err != nil { log.Fatal(err) } if err := os.Mkdir("output", os.ModePerm); err != nil { log.Fatal(err) } for _, file := range files { if file.IsDir() { continue } if strings.HasSuffix(file.Name(), ".heic") { out := strings.TrimSuffix(file.Name(), ".heic") out = out + ".jpg" fileHandler(path.Join("input", file.Name()), path.Join("output", out)) } } log.Println("Conversion Passed") }

func fileHandler(fin string, fout string) { t0 := time.Now() b, err := ioutil.ReadFile(fin) if err != nil { log.Fatal(err) }

br := bytes.NewReader(b)

exif, err := goheif.ExtractExif(br)
if err != nil {
    log.Printf("Warning: no EXIF from %s: %v\n", fin, err)
}

img, err := goheif.Decode(br)
if err != nil {
    log.Fatalf("Failed to parse %s: %v\n", fin, err)
}

fileOutput, err := os.OpenFile(fout, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
    log.Fatal(err)
}
defer fileOutput.Close()

// Write both convert file + exif data back
w, _ := newWriterExif(fileOutput, exif)
err = jpeg.Encode(w, img, nil)
if err != nil {
    log.Fatal(err)
}
e0 := time.Since(t0)
log.Printf("Complete %s => %s in %s\n", fin, fout, e0)

}

// Skip Writer for exif writing type writerSkipper struct { w io.Writer bytesToSkip int }

func (w *writerSkipper) Write(data []byte) (int, error) { if w.bytesToSkip <= 0 { return w.w.Write(data) }

if dataLen := len(data); dataLen < w.bytesToSkip {
    w.bytesToSkip -= dataLen
    return dataLen, nil
}

if n, err := w.w.Write(data[w.bytesToSkip:]); err == nil {
    n += w.bytesToSkip
    w.bytesToSkip = 0
    return n, nil
} else {
    return n, err
}

}

func newWriterExif(w io.Writer, exif []byte) (io.Writer, error) { writer := &writerSkipper{w, 2} soi := []byte{0xff, 0xd8} if _, err := w.Write(soi); err != nil { return nil, err }

if exif != nil {
    app1Marker := 0xe1
    markerlen := 2 + len(exif)
    marker := []byte{0xff, uint8(app1Marker), uint8(markerlen >> 8), uint8(markerlen & 0xff)}
    if _, err := w.Write(marker); err != nil {
        return nil, err
    }

    if _, err := w.Write(exif); err != nil {
        return nil, err
    }
}

return writer, nil

}


- cli output
```bash
# github.com/jdeng/goheif/libde265
In file included from libde265-all.inl:37,
                 from libde265.cc:2:
../../go/pkg/mod/github.com/jdeng/goheif@v0.0.0-20200323230657-a0d6a8b3e68f/libde265/libde265/slice.cc:2447: warning: "MAX_PREFIX" redefined
 2447 | #define MAX_PREFIX 64
      | 
In file included from libde265-all.inl:13,
                 from libde265.cc:2:
../../go/pkg/mod/github.com/jdeng/goheif@v0.0.0-20200323230657-a0d6a8b3e68f/libde265/libde265/cabac.cc:419: note: this is the location of the previous definition
  419 | #define MAX_PREFIX 32
      | 
cc1plus: note: unrecognized command-line option ‘-Wno-constant-conversion’ may have been intended to silence earlier diagnostics
2022/10/04 16:11:01 Complete input/image1.heic => output/image1.jpg in 874.589691ms
2022/10/04 16:11:01 Complete input/image2.heic => output/image2.jpg in 589.208531ms
2022/10/04 16:11:02 Complete input/image3.heic => output/image3.jpg in 571.793151ms
unexpected fault address 0x7f7ca00a0010
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0x7f7ca00a0010 pc=0x49d7dc]

goroutine 1 [running]:
runtime.throw({0x541d61?, 0xc00037f298?})
        /usr/local/go/src/runtime/panic.go:1047 +0x5d fp=0xc00037f260 sp=0xc00037f230 pc=0x4472fd
runtime.sigpanic()
        /usr/local/go/src/runtime/signal_unix.go:842 +0x2c5 fp=0xc00037f2b0 sp=0xc00037f260 pc=0x45b3c5
image/jpeg.yCbCrToYCbCr(0xc00009de00, {0x605840?, 0x1?}, 0xc00037f3b8, 0xc00037f8b8, 0xc00037f4b8)
        /usr/local/go/src/image/jpeg/writer.go:461 +0x17c fp=0xc00037f330 sp=0xc00037f2b0 pc=0x49d7dc
image/jpeg.(*encoder).writeSOS(0xc00006c180, {0x567c60?, 0xc00009de00?})
        /usr/local/go/src/image/jpeg/writer.go:547 +0x485 fp=0xc00037fce8 sp=0xc00037f330 pc=0x49de45
image/jpeg.Encode({0x567880?, 0xc00009e040?}, {0x567c60, 0xc00009de00}, 0x0)
        /usr/local/go/src/image/jpeg/writer.go:634 +0x347 fp=0xc00037fd60 sp=0xc00037fce8 pc=0x49e2c7
main.fileHandler({0xc00001a228, 0x11}, {0xc00001a2a0, 0x11})
        /home/ganesh/AutoVisas/poc/main.go:69 +0x29a fp=0xc00037fe78 sp=0xc00037fd60 pc=0x4d1efa
main.main()
        /home/ganesh/AutoVisas/poc/main.go:35 +0x36f fp=0xc00037ff80 sp=0xc00037fe78 pc=0x4d1c0f
runtime.main()
        /usr/local/go/src/runtime/proc.go:250 +0x212 fp=0xc00037ffe0 sp=0xc00037ff80 pc=0x449b52
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00037ffe8 sp=0xc00037ffe0 pc=0x4731c1

goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004efb0 sp=0xc00004ef90 pc=0x449f16
runtime.goparkunlock(...)
        /usr/local/go/src/runtime/proc.go:369
runtime.forcegchelper()
        /usr/local/go/src/runtime/proc.go:302 +0xad fp=0xc00004efe0 sp=0xc00004efb0 pc=0x449dad
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004efe8 sp=0xc00004efe0 pc=0x4731c1
created by runtime.init.6
        /usr/local/go/src/runtime/proc.go:290 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x1?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004f790 sp=0xc00004f770 pc=0x449f16
runtime.goparkunlock(...)
        /usr/local/go/src/runtime/proc.go:369
runtime.bgsweep(0x0?)
        /usr/local/go/src/runtime/mgcsweep.go:297 +0xd7 fp=0xc00004f7c8 sp=0xc00004f790 pc=0x436f57
runtime.gcenable.func1()
        /usr/local/go/src/runtime/mgc.go:178 +0x26 fp=0xc00004f7e0 sp=0xc00004f7c8 pc=0x42bdc6
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004f7e8 sp=0xc00004f7e0 pc=0x4731c1
created by runtime.gcenable
        /usr/local/go/src/runtime/mgc.go:178 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0x1771f52c0f38?, 0x22cea815?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004ff70 sp=0xc00004ff50 pc=0x449f16
runtime.goparkunlock(...)
        /usr/local/go/src/runtime/proc.go:369
runtime.(*scavengerState).park(0x616ee0)
        /usr/local/go/src/runtime/mgcscavenge.go:389 +0x53 fp=0xc00004ffa0 sp=0xc00004ff70 pc=0x434fb3
runtime.bgscavenge(0x0?)
        /usr/local/go/src/runtime/mgcscavenge.go:622 +0x65 fp=0xc00004ffc8 sp=0xc00004ffa0 pc=0x4355a5
runtime.gcenable.func2()
        /usr/local/go/src/runtime/mgc.go:179 +0x26 fp=0xc00004ffe0 sp=0xc00004ffc8 pc=0x42bd66
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004ffe8 sp=0xc00004ffe0 pc=0x4731c1
created by runtime.gcenable
        /usr/local/go/src/runtime/mgc.go:179 +0xaa

goroutine 5 [finalizer wait]:
runtime.gopark(0x6172e0?, 0xc000007860?, 0x0?, 0x0?, 0xc00004e770?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004e628 sp=0xc00004e608 pc=0x449f16
runtime.goparkunlock(...)
        /usr/local/go/src/runtime/proc.go:369
runtime.runfinq()
        /usr/local/go/src/runtime/mfinal.go:180 +0x10f fp=0xc00004e7e0 sp=0xc00004e628 pc=0x42aecf
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004e7e8 sp=0xc00004e7e0 pc=0x4731c1
created by runtime.createfing
        /usr/local/go/src/runtime/mfinal.go:157 +0x45

goroutine 6 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc000050750 sp=0xc000050730 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc0000507e0 sp=0xc000050750 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc0000507e8 sp=0xc0000507e0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 7 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc000050f50 sp=0xc000050f30 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc000050fe0 sp=0xc000050f50 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc000050fe8 sp=0xc000050fe0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 8 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc000051750 sp=0xc000051730 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc0000517e0 sp=0xc000051750 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc0000517e8 sp=0xc0000517e0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 9 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc000051f50 sp=0xc000051f30 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc000051fe0 sp=0xc000051f50 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc000051fe8 sp=0xc000051fe0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 10 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004a750 sp=0xc00004a730 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc00004a7e0 sp=0xc00004a750 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004a7e8 sp=0xc00004a7e0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 11 [GC worker (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004af50 sp=0xc00004af30 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc00004afe0 sp=0xc00004af50 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004afe8 sp=0xc00004afe0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 12 [GC worker (idle)]:
runtime.gopark(0x177217fab135?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004b750 sp=0xc00004b730 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc00004b7e0 sp=0xc00004b750 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004b7e8 sp=0xc00004b7e0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25

goroutine 13 [GC worker (idle)]:
runtime.gopark(0x177217fab119?, 0x0?, 0x0?, 0x0?, 0x0?)
        /usr/local/go/src/runtime/proc.go:363 +0xd6 fp=0xc00004bf50 sp=0xc00004bf30 pc=0x449f16
runtime.gcBgMarkWorker()
        /usr/local/go/src/runtime/mgc.go:1235 +0xf1 fp=0xc00004bfe0 sp=0xc00004bf50 pc=0x42dd11
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1594 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x4731c1
created by runtime.gcBgMarkStartWorkers
        /usr/local/go/src/runtime/mgc.go:1159 +0x25
exit status 2
dracconi commented 1 year ago

Possibly related #15 ?

dev-strender commented 7 months ago

Would you add a line like this on appropriate code location?

goheif.SafeEncoding = true