{"action":"created","comment":{"url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/comments/49932433","id":49932433,"diff_hunk":"@@ -0,0 +1,165 @@\n+// License: GPL. For details, see LICENSE file.\n+package org.openstreetmap.josm.plugins.mapillary.utils;\n+\n+import java.io.File;\n+import java.io.FileInputStream;\n+import java.io.FileNotFoundException;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.util.ArrayList;\n+import java.util.Arrays;\n+import java.util.List;\n+\n+import javax.swing.filechooser.FileFilter;\n+\n+import org.apache.commons.imaging.ImageReadException;\n+import org.apache.commons.imaging.Imaging;\n+import org.apache.commons.imaging.common.ImageMetadata;\n+import org.apache.commons.imaging.common.RationalNumber;\n+import org.apache.commons.imaging.formats.jpeg.JpegImageMetadata;\n+import org.apache.commons.imaging.formats.tiff.TiffField;\n+import org.apache.commons.imaging.formats.tiff.constants.ExifTagConstants;\n+import org.apache.commons.imaging.formats.tiff.constants.GpsTagConstants;\n+import org.apache.commons.imaging.formats.tiff.taginfos.TagInfo;\n+import org.openstreetmap.josm.Main;\n+import org.openstreetmap.josm.data.coor.LatLon;\n+import org.openstreetmap.josm.plugins.mapillary.MapillaryImportedImage;\n+import org.openstreetmap.josm.tools.I18n;\n+\n+public final class ImageUtil {\n+  public static final FileFilter IMAGE_FILE_FILTER = new ImageFileFilter();\n+\n+  private ImageUtil() {\n+    // Private constructor to avoid instantiation\n+  }\n+\n+  /**\n+   * Recursive method to retrieve all images inside a directory or in a single file.\n+   * @param f the file or directory from which all contained images should be read\n+   * @param defaultLL the coordinates that the images should get, if no coordinates are found in metadata\n+   * @return all images that were found within the given file or directory\n+   * @throws IOException if the content of the file could not be read\n+   */\n+  public static List<MapillaryImportedImage> readImagesFrom(final File f, final LatLon defaultLL) throws IOException {\n+    List<MapillaryImportedImage> images = new ArrayList<>();\n+    if (!f.exists() || !f.canRead()) {\n+      throw new IOException(f.getAbsolutePath() + \" not found or not readable!\");\n+    } else if (f.isDirectory()) {\n+      for (File child : f.listFiles()) {\n+        try {\n+          images.addAll(readImagesFrom(child, defaultLL));\n+        } catch (IOException e) {\n+          // Don't throw an exception here to allow other files that might be readable to be read.\n+          // Might not be the best solution, but the easiest workaround I could imagine.\n+          Main.error(f.getAbsolutePath() + \" not found or not readable!\");\n+        }\n+      }\n+    } else if (IMAGE_FILE_FILTER.accept(f)) {\n+      try (FileInputStream fis = new FileInputStream(f)) {\n+        images.add(readImageFrom(fis, f, defaultLL));\n+      }\n+    }\n+    return images;\n+  }\n+\n+  /**\n+   * @param is the input stream to read the metadata from\n+   * @param f the file that will be set as a field to the returned {@link MapillaryImportedImage}\n+   * @param defaultLL the coordinates that the image should get, if no coordinates are found in metadata\n+   * @return the {@link MapillaryImportedImage} with the read metadata and the given file set\n+   * @throws IOException if an IOException occurs while reading from the input stream\n+   */\n+  private static MapillaryImportedImage readImageFrom(\n+      final InputStream is, final File f, final LatLon defaultLL\n+  ) throws IOException {\n+    Object latRef = null;\n+    Object lonRef = null;\n+    Object lat = null;\n+    Object lon = null;\n+    Object gpsDir = null;\n+    Object dateTime = null;\n+    final ImageMetadata meta;\n+    try {\n+      meta = Imaging.getMetadata(is, null);\n+      if (meta instanceof JpegImageMetadata) {\n+        final JpegImageMetadata jpegMeta = (JpegImageMetadata) meta;\n+        latRef = getTiffFieldValue(jpegMeta, GpsTagConstants.GPS_TAG_GPS_LATITUDE_REF);\n+        lonRef = getTiffFieldValue(jpegMeta, GpsTagConstants.GPS_TAG_GPS_LONGITUDE_REF);\n+        lat = getTiffFieldValue(jpegMeta, GpsTagConstants.GPS_TAG_GPS_LATITUDE);\n+        lon = getTiffFieldValue(jpegMeta, GpsTagConstants.GPS_TAG_GPS_LONGITUDE);\n+        gpsDir = getTiffFieldValue(jpegMeta, GpsTagConstants.GPS_TAG_GPS_IMG_DIRECTION);\n+        dateTime = getTiffFieldValue(jpegMeta, ExifTagConstants.EXIF_TAG_DATE_TIME_ORIGINAL);\n+      }\n+    } catch (ImageReadException e) {","path":"src/org/openstreetmap/josm/plugins/mapillary/utils/ImageUtil.java","position":93,"original_position":93,"commit_id":"2f4f1771236d6616e40db6227fdf737d8e1d66d6","original_commit_id":"2f4f1771236d6616e40db6227fdf737d8e1d66d6","user":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"body":"![Codacy](https://www.codacy.com/versioned/images/favicon.png) Issue found: [Avoid empty catch blocks](https://www.codacy.com/app/floscher/josm-mapillary-plugin/file/1804015725/issues/source?bid=3023888&fileBranchId=3066982#l93)","created_at":"2016-01-16T14:33:21Z","updated_at":"2016-01-16T14:33:21Z","html_url":"https://github.com/floscher/josm-mapillary-plugin/pull/3#discussion_r49932433","pull_request_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3","_links":{"self":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/comments/49932433"},"html":{"href":"https://github.com/floscher/josm-mapillary-plugin/pull/3#discussion_r49932433"},"pull_request":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3"}}},"pull_request":{"url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3","id":55915162,"html_url":"https://github.com/floscher/josm-mapillary-plugin/pull/3","diff_url":"https://github.com/floscher/josm-mapillary-plugin/pull/3.diff","patch_url":"https://github.com/floscher/josm-mapillary-plugin/pull/3.patch","issue_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/3","number":3,"state":"open","locked":false,"title":"ImageUtil","user":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"body":"This changes the import of images in the following way:\r\n* the import code is in the new class `ImportUtil`\r\n* directories are imported recursively instead of only images in the top level\r\n* both imports of complete sequences as well as single images accept JPG **and** PNG\r\n* the file type of the images is no longer determined by the file extension, but by the [magic bytes](https://en.wikipedia.org/wiki/List_of_file_signatures)","created_at":"2016-01-13T15:52:23Z","updated_at":"2016-01-16T14:33:22Z","closed_at":null,"merged_at":null,"merge_commit_sha":"06d62e113d68aaf4a73ef40c7fee3d748c85a10f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3/commits","review_comments_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3/comments","review_comment_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/comments{/number}","comments_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/3/comments","statuses_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/statuses/2f4f1771236d6616e40db6227fdf737d8e1d66d6","head":{"label":"floscher:image-util","ref":"image-util","sha":"2f4f1771236d6616e40db6227fdf737d8e1d66d6","user":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"repo":{"id":38530558,"name":"josm-mapillary-plugin","full_name":"floscher/josm-mapillary-plugin","owner":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/floscher/josm-mapillary-plugin","description":"git-mirror of the mapillary plugin in the SVN-repo for JOSM-plugins","fork":false,"url":"https://api.github.com/repos/floscher/josm-mapillary-plugin","forks_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/forks","keys_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/teams","hooks_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/hooks","issue_events_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/events","assignees_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/tags","blobs_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/languages","stargazers_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/stargazers","contributors_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/contributors","subscribers_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/subscribers","subscription_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/subscription","commits_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/merges","archive_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/downloads","issues_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/labels{/name}","releases_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/releases{/id}","created_at":"2015-07-04T10:36:31Z","updated_at":"2016-01-11T19:57:10Z","pushed_at":"2016-01-16T14:27:40Z","git_url":"git://github.com/floscher/josm-mapillary-plugin.git","ssh_url":"git@github.com:floscher/josm-mapillary-plugin.git","clone_url":"https://github.com/floscher/josm-mapillary-plugin.git","svn_url":"https://github.com/floscher/josm-mapillary-plugin","homepage":"http://svn.openstreetmap.org/applications/editors/josm/plugins/mapillary","size":8324,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":3,"default_branch":"master"}},"base":{"label":"floscher:master","ref":"master","sha":"e884035eaed62e28b6b18387d9699efc8dc69f6d","user":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"repo":{"id":38530558,"name":"josm-mapillary-plugin","full_name":"floscher/josm-mapillary-plugin","owner":{"login":"floscher","id":3904348,"avatar_url":"https://avatars.githubusercontent.com/u/3904348?v=3","gravatar_id":"","url":"https://api.github.com/users/floscher","html_url":"https://github.com/floscher","followers_url":"https://api.github.com/users/floscher/followers","following_url":"https://api.github.com/users/floscher/following{/other_user}","gists_url":"https://api.github.com/users/floscher/gists{/gist_id}","starred_url":"https://api.github.com/users/floscher/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/floscher/subscriptions","organizations_url":"https://api.github.com/users/floscher/orgs","repos_url":"https://api.github.com/users/floscher/repos","events_url":"https://api.github.com/users/floscher/events{/privacy}","received_events_url":"https://api.github.com/users/floscher/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/floscher/josm-mapillary-plugin","description":"git-mirror of the mapillary plugin in the SVN-repo for JOSM-plugins","fork":false,"url":"https://api.github.com/repos/floscher/josm-mapillary-plugin","forks_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/forks","keys_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/keys{/key_id}","collaborators_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/teams","hooks_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/hooks","issue_events_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/events{/number}","events_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/events","assignees_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/assignees{/user}","branches_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/branches{/branch}","tags_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/tags","blobs_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/refs{/sha}","trees_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/trees{/sha}","statuses_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/statuses/{sha}","languages_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/languages","stargazers_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/stargazers","contributors_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/contributors","subscribers_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/subscribers","subscription_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/subscription","commits_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/commits{/sha}","git_commits_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/git/commits{/sha}","comments_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/comments{/number}","issue_comment_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/comments{/number}","contents_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/contents/{+path}","compare_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/compare/{base}...{head}","merges_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/merges","archive_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/downloads","issues_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues{/number}","pulls_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls{/number}","milestones_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/milestones{/number}","notifications_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/labels{/name}","releases_url":"https://api.github.com/repos/floscher/josm-mapillary-plugin/releases{/id}","created_at":"2015-07-04T10:36:31Z","updated_at":"2016-01-11T19:57:10Z","pushed_at":"2016-01-16T14:27:40Z","git_url":"git://github.com/floscher/josm-mapillary-plugin.git","ssh_url":"git@github.com:floscher/josm-mapillary-plugin.git","clone_url":"https://github.com/floscher/josm-mapillary-plugin.git","svn_url":"https://github.com/floscher/josm-mapillary-plugin","homepage":"http://svn.openstreetmap.org/applications/editors/josm/plugins/mapillary","size":8324,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":1,"forks":2,"open_issues":1,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3"},"html":{"href":"https://github.com/floscher/josm-mapillary-plugin/pull/3"},"issue":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/3"},"comments":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/floscher/josm-mapillary-plugin/statuses/2f4f1771236d6616e40db6227fdf737d8e1d66d6"}}}}