Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace underlying rwcarlsen/goexif with dsoprea/go-exif #8606

Closed

Conversation

danedavid
Copy link

Fixes #8586

  • Replace underlying EXIF library (rwcarlsen/goexif) with an actively developed one (dsoprea/go-exif)
  • Add tests for disable options (date & location) while decoding EXIF.

@danedavid
Copy link
Author

Couple of questions:

  1. In the body of Decode method, there are many calls to goexif code that return an error object as a second value. Being new to Go, I was wondering if we need to add the following after each assignment to err? Is there a better, idiomatic way?
if err != nil {
  return
}
  1. As the values of the Tags map are of type interface{}, there is no guarantee that a particular tag value has the same type as when we were using the previous library, except the tags (DateTime, LatLong) that are handled specifically. Do we need to add any type specific tests there?

  2. The API of exif module is unchanged, but would you recommend adding more tests? If so, what parts need to be tested? Have added one new test to check for disable LatLong & Date options at the module level. I believe it's already being tested in the image module.

  3. Should the old library be removed from dependency list in README?

  4. The unexported exifWalker struct & its Walk method may not be needed as such because the new library doesn't require a walker function. However, have maintained the same signatures for brevity. Let me know if those need to be changed.

resources/images/exif/exif.go Show resolved Hide resolved
@bep
Copy link
Member

bep commented Jun 3, 2021

  1. No, but I prefer
if err != nil {
  return err
}

A common pattern to make the above a little more compact is to do:

if val, err := foo(); err != nil {
  return err
}

As in, I almost never used named return values (or whatever they're called).

  1. That is a good question. The one I would be curious about, which I don't see a particulary good test for, is that the old library returned Rat values for some floats (e.g. f-stop)
  2. The test coverage looks fine to me.
  3. I'll update the dependency list in README.
  4. You're welcome to simplify/remove the Walker struct if its not needed.

@danedavid danedavid requested a review from bep June 4, 2021 12:45
@danedavid
Copy link
Author

@bep Made a few changes. Fixed the build issue when file has no Exif data. Also, added type assertions & type-based test cases for tag values.


func processRational(n int64, d int64) interface{} {
rat := big.NewRat(n, d)
if n != 1 {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bep This logic existed in the previous code, making the value of rational exif tags either float64 or big.Rat type depending on the numerator. Have copied the logic as such and added corresponding tests; however, let me know if returning just one of the types (float64 or big.Rat) all the time makes more sense.

@bep
Copy link
Member

bep commented Jun 6, 2021

Hey,

It still fails for me in the case of an image with no Exif.

What I suggest is that you make:

Decode(r io.Reader) (ex *Exif, err error)

Into

Decode(r io.Reader) (*Exif, error)

And remove the panic recovery at the top.

And then you need to explicitly handle all errors, including NewIfdMappingWithStandard. I'm not sure where to set the line between "no exif data" and a real error that the user should/could do something about.

The above also suggests that we miss out on a test case for a JPG without Exif metadata ...

@danedavid
Copy link
Author

Hi @bep
I'd run hugo on the project you'd mentioned and verified, but apparently I seem to have made a mistake while building. Apologies for that.

I've added a new test case by stripping sunset.jpg of its EXIF data (using https://www.verexif.com/en/). I had to add a PNG check & extra dependancy to satisfy the new test case AND this one:

func TestExifPNG(t *testing.T) {

Hope it doesn't look clumsy.

@danedavid
Copy link
Author

Hi @bep, were you able to look into this?

Replace underlying EXIF library (rwcarlsen/goexif) with an actively developed one(dsoprea/go-exif). Add tests for disable options (date & location) while decoding EXIF.
Fixes gohugoio#8586
@bep
Copy link
Member

bep commented Jul 15, 2021

@danedavid looking at it now ...

@bep
Copy link
Member

bep commented Jul 15, 2021

This works great now; I'm going to rebase and merge this in #8761 -- thanks!

@bep bep closed this Jul 15, 2021
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Replace underlying Exif library
2 participants