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
This commit is contained in:
WaltCuller 2023-02-26 18:19:49 +08:00 committed by GitHub
parent ce524d0b5e
commit 39cc3a2a7e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 184 additions and 3 deletions

View file

@ -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:

View file

@ -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))
}
})
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB