exif: Return the proper exposure time value in some special cases
Return value in float64 if exposure time is int or greater than 1, otherwise return in fraction. Fixes #10738
|
@ -173,11 +173,12 @@ func decodeTag(x *_exif.Exif, f _exif.FieldName, t *tiff.Tag) (any, error) {
|
|||
case tiff.RatVal:
|
||||
n, d, _ := t.Rat2(i)
|
||||
rat := big.NewRat(n, d)
|
||||
if n == 1 {
|
||||
rv = append(rv, rat)
|
||||
} else {
|
||||
// if t is int or t > 1, use float64
|
||||
if rat.IsInt() || rat.Cmp(big.NewRat(1, 1)) == 1 {
|
||||
f, _ := rat.Float64()
|
||||
rv = append(rv, f)
|
||||
} else {
|
||||
rv = append(rv, rat)
|
||||
}
|
||||
|
||||
case tiff.FloatVal:
|
||||
|
|
|
@ -133,3 +133,183 @@ var eq = qt.CmpEquals(
|
|||
return v1.Unix() == v2.Unix()
|
||||
}),
|
||||
)
|
||||
|
||||
func TestIssue10738(t *testing.T) {
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
testFunc := func(path, include string) any {
|
||||
f, err := os.Open(filepath.FromSlash(path))
|
||||
c.Assert(err, qt.IsNil)
|
||||
defer f.Close()
|
||||
|
||||
d, err := NewDecoder(IncludeFields(include))
|
||||
c.Assert(err, qt.IsNil)
|
||||
x, err := d.Decode(f)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
// Verify that it survives a round-trip to JSON and back.
|
||||
data, err := json.Marshal(x)
|
||||
c.Assert(err, qt.IsNil)
|
||||
x2 := &ExifInfo{}
|
||||
err = json.Unmarshal(data, x2)
|
||||
|
||||
c.Assert(x2, eq, x)
|
||||
|
||||
v, found := x.Tags["ExposureTime"]
|
||||
c.Assert(found, qt.Equals, true)
|
||||
return v
|
||||
}
|
||||
|
||||
type args struct {
|
||||
path string // imagePath
|
||||
include string // includeFields
|
||||
}
|
||||
|
||||
type want struct {
|
||||
vN int64 // numerator
|
||||
vD int64 // denominator
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
name string
|
||||
args args
|
||||
want want
|
||||
}
|
||||
|
||||
tests := []testCase{
|
||||
{
|
||||
"canon_cr2_fraction", args{
|
||||
path: "../../testdata/issue10738/canon_cr2_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
500,
|
||||
},
|
||||
},
|
||||
{
|
||||
"canon_cr2_integer", args{
|
||||
path: "../../testdata/issue10738/canon_cr2_integer.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
10,
|
||||
0,
|
||||
},
|
||||
},
|
||||
{
|
||||
"dji_dng_fraction", args{
|
||||
path: "../../testdata/issue10738/dji_dng_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
4000,
|
||||
},
|
||||
},
|
||||
{
|
||||
"fuji_raf_fraction", args{
|
||||
path: "../../testdata/issue10738/fuji_raf_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
250,
|
||||
},
|
||||
},
|
||||
{
|
||||
"fuji_raf_integer", args{
|
||||
path: "../../testdata/issue10738/fuji_raf_integer.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
0,
|
||||
},
|
||||
},
|
||||
{
|
||||
"leica_dng_fraction", args{
|
||||
path: "../../testdata/issue10738/leica_dng_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
100,
|
||||
},
|
||||
},
|
||||
{
|
||||
"lumix_rw2_fraction", args{
|
||||
path: "../../testdata/issue10738/lumix_rw2_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
400,
|
||||
},
|
||||
},
|
||||
{
|
||||
"nikon_nef_d5600", args{
|
||||
path: "../../testdata/issue10738/nikon_nef_d5600.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
1000,
|
||||
},
|
||||
},
|
||||
{
|
||||
"nikon_nef_fraction", args{
|
||||
path: "../../testdata/issue10738/nikon_nef_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
640,
|
||||
},
|
||||
},
|
||||
{
|
||||
"nikon_nef_integer", args{
|
||||
path: "../../testdata/issue10738/nikon_nef_integer.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
30,
|
||||
0,
|
||||
},
|
||||
},
|
||||
{
|
||||
"nikon_nef_fraction_2", args{
|
||||
path: "../../testdata/issue10738/nikon_nef_fraction_2.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
6400,
|
||||
},
|
||||
},
|
||||
{
|
||||
"sony_arw_fraction", args{
|
||||
path: "../../testdata/issue10738/sony_arw_fraction.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
1,
|
||||
160,
|
||||
},
|
||||
},
|
||||
{
|
||||
"sony_arw_integer", args{
|
||||
path: "../../testdata/issue10738/sony_arw_integer.jpg",
|
||||
include: "Lens|Date|ExposureTime",
|
||||
}, want{
|
||||
4,
|
||||
0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
c.Run(tt.name, func(c *qt.C) {
|
||||
got := testFunc(tt.args.path, tt.args.include)
|
||||
switch got.(type) {
|
||||
case float64:
|
||||
eTime, ok := got.(float64)
|
||||
c.Assert(ok, qt.Equals, true)
|
||||
c.Assert(eTime, qt.Equals, float64(tt.want.vN))
|
||||
case *big.Rat:
|
||||
eTime, ok := got.(*big.Rat)
|
||||
c.Assert(ok, qt.Equals, true)
|
||||
c.Assert(eTime, eq, big.NewRat(tt.want.vN, tt.want.vD))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
BIN
resources/testdata/issue10738/canon_cr2_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
resources/testdata/issue10738/canon_cr2_integer.jpg
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
resources/testdata/issue10738/dji_dng_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
resources/testdata/issue10738/fuji_raf_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
resources/testdata/issue10738/fuji_raf_integer.jpg
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
resources/testdata/issue10738/leica_dng_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
resources/testdata/issue10738/lumix_rw2_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
resources/testdata/issue10738/nikon_nef_d5600.jpg
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
resources/testdata/issue10738/nikon_nef_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
resources/testdata/issue10738/nikon_nef_fraction_2.jpg
vendored
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
resources/testdata/issue10738/nikon_nef_integer.jpg
vendored
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
resources/testdata/issue10738/sony_arw_fraction.jpg
vendored
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
resources/testdata/issue10738/sony_arw_integer.jpg
vendored
Normal file
After Width: | Height: | Size: 23 KiB |