Closed imarko closed 11 years ago
Would you mind sending a sample file that isn't working right (or maybe a string of bytes representing the IFD) and what you expect the output to be? Indeed - you are correct - the Varint and Uvarint functions do not work like I thought they did.
Actually Uvarint and Varint stop processing if any byte is less than 0x80. I'm not sure why they were written this way - strange.
The varint thing confused me too for a while. It appears to be some kind of a 7 bit encoding so it's not right for reading raw 32 bit values. It just happens to work for big endian if all octets are less than 0x80.
Sample image:
http://kismala.com/exif-little-endian.jpg
Test program below.
Expected output:
0 0 0 37 0 0 0 1 0 0 0 22 0 0 0 1 0 0 9 224 0 0 0 100
37/1 22/1 2528/100
Actual output:
0 0 0 37 0 0 0 1 0 0 0 22 0 0 0 1 0 0 9 224 0 0 0 100
0/0 0/0 0/0
package main
import (
"fmt"
"github.com/rwcarlsen/goexif/exif"
"log"
"os"
)
func decodefile(fname string) {
f, err := os.Open(fname)
if err != nil {
log.Fatal(err)
}
defer f.Close()
x, err := exif.Decode(f)
if err != nil {
fmt.Printf("%s: failed to decode \n", fname)
return
}
lat := x.Get("GPSLatitude")
for _, b := range lat.Val {
fmt.Printf("%d ", b)
}
fmt.Println()
latdeg_numer, latdeg_denom := lat.Rat2(0)
latmin_numer, latmin_denom := lat.Rat2(1)
latsec_numer, latsec_denom := lat.Rat2(2)
fmt.Printf("%d/%d %d/%d %d/%d\n",
latdeg_numer, latdeg_denom,
latmin_numer, latmin_denom,
latsec_numer, latsec_denom)
}
func main() {
for _, f := range os.Args[1:] {
decodefile(f)
}
}
I am trying to use goexif to grab and decode GPS location exif tags in jpeg images. This doesn't seem to work, I always get 0 rather than the actual values.
I think the problem is in the interaction of the DecodeTag() and Rat2() logic in tiff.go. The GPSLatitude and GPSLongitude tags are made up of 3 rational values. This puts valLen over 4 so DecodeTag sets Val to the raw bytes rather than using PutUvarint. The Rat2 method on the other hand tries to interpret Val as a varint and because the high byte of the GPS coordinates tends to be 0 binary.Uvarint stops processing when it encounters this initial 0 and returns 0.