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

IMAGING-251 support for TIFF floating-point formats #72

Closed
wants to merge 34 commits into from
Closed

IMAGING-251 support for TIFF floating-point formats #72

wants to merge 34 commits into from

Conversation

gwlucastrig
Copy link
Contributor

This change adds the ability to obtain images from TIFF files that give data in the floating-point format. It partially addresses IMAGING-251. It also adds two example applications to show how to use the Commons Imaging API for TIFF images and adds one additional small sample TIFF data file that uses the floating-point format.

I saw that the project pom.xml specified PMD, so I run PMD and made minor PMD changes. In keeping with the project guidelines, PMD changes were done only for the files that I otherwise modified.

I ran all test cases successfully.

Additional changes to support numerical access for these files will be provided in a future patch.

Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

Hi @gwlucastrig , thanks for the PR!

I think Travis is unhappy with some checkstyle issues. Take a look at its output and it should tell you the line and error it found 👍 we need this to pass before merging it. Will review it over next days.

@gwlucastrig
Copy link
Contributor Author

I ran check style and see that I introduced tabs and trailing spaces. Serves me right. I turned off the auto-format in my IDE because I didn't want to introduce white-space changes to existing code. I ran checkstyle from Maven using "mvn checkstyle:checkstyle". Is that the command the project recommends?

What should I do to address this? Submit a new PR?

@kinow
Copy link
Member

kinow commented Apr 5, 2020

I ran check style and see that I introduced tabs and trailing spaces. Serves me right. I turned off the auto-format in my IDE because I didn't want to introduce white-space changes to existing code. I ran checkstyle from Maven using "mvn checkstyle:checkstyle". Is that the command the project recommends?

You can run just mvn as Commons Imaging has a default Maven goal in its pom.xml. That's how Travis does it too.

Some developers are able to integrate the checkstyle rules in their IDE's. I am a bit behind the time, and still use the command line for most things. So my workflow is normally to change the files, have a look at the IDE warnings (Eclipse), then mvn and prepare a commit (i.e. run tests and some other checks).

Doesn't work every time as I can forget to run it too :)

What should I do to address this? Submit a new PR?

In your branch you should be able to resolve the style issues, by editing the files Travis is showing with errors. Then run mvn and once it passes prepare a new commit and push to your fork.

After this, this pull request should be automatically updated.


If you look near the PR title, where it says "gwlucastrig wants to merge 1 commit into...", you should see that this PR is supposed to merge code into apache:master.

But I can see you didn't use a branch in your fork, as it says that it would merge it from "gwlucastrig:master". It will work fine. But now this PR is "linked" to your branch master on your fork.

Which means that if you start working on another issue, and you push to your master branch, that would update this PR as well.

Furthermore, once it's merged, you may have to use something like git reset --hard to sync your fork again.

For that, I always start new work with git checkout -b name-of-my-branch (where normally I have name-of-my-branch as something like IMAGING-123, or fix-color-palette-8-bits-etc.

That way I am able to work on multiple issues 👍 just a note, as we should be able to work on IMAGING-251 just fine this way, but just in case you want to work on multiple issues, then having branches and not using master in your fork might be helpful.

@gwlucastrig
Copy link
Contributor Author

gwlucastrig commented Apr 6, 2020 via email

@gwlucastrig
Copy link
Contributor Author

gwlucastrig commented Apr 6, 2020 via email

@gwlucastrig
Copy link
Contributor Author

This time it will work, I hope. I ran mvn findbugs:findbugs and, sure enough, it found a bug. I've submitted a fix.

Unfortunately, I missed a lot of the build procedures because I have not been able to get maven to execute the site lifecycle under Windows (I do miss having a Linux computer). Apparently, it won't run if I don't have a version of subversion installed. Trying to get that set up now. Is there a recommended version that works with commons-imaging?

@kinow
Copy link
Member

kinow commented Apr 6, 2020

I am using Maven 3.5.4, with Java 8. Not sure if there's a recommended version @gwlucastrig . But you are doing just fine regarding build & git in my opinion.

The code part you are doing is really the hard part. Also, because of how GitHub and git work, I am also able to edit this branch. So if necessary I can amend the changes to help fixing issues, or edit the commits (e.g. squashing it).

So feel free to update it as much as you can, but if you get stuck you can let me know and I can try to help so that the build passes and we can focus on the new code.

@coveralls
Copy link

coveralls commented Apr 6, 2020

Coverage Status

Coverage increased (+0.8%) to 75.883% when pulling 77b5936 on gwlucastrig:master into 1397ca9 on apache:master.

Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

Few comments from a quick review Gary. Already know I will need some more time to read the code and (great) comments with calm. Will send a pull request later to update some javadocs, and will try to update the test code to use JUnit 👍

I saw you found some test data too, that's really great!

@@ -115,7 +264,7 @@ private void interpretTile(final ImageBuilder imageBuilder, final byte[] bytes,

// End of May 2012 changes

try (final BitInputStream bis = new BitInputStream(new ByteArrayInputStream(bytes), byteOrder)) {
try (BitInputStream bis = new BitInputStream(new ByteArrayInputStream(bytes), byteOrder)) {
Copy link
Member

Choose a reason for hiding this comment

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

Why did you have to remove the final here?

int yMax;

double sumFound;
int nFound;
Copy link
Member

Choose a reason for hiding this comment

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

Could we make the members above private or some other access modifier?

@gwlucastrig
Copy link
Contributor Author

gwlucastrig commented Apr 7, 2020 via email

@gwlucastrig
Copy link
Contributor Author

Let me know what you'd like me to do to with the code. Sorry if the PMD changes created more work for you than they were worth. I can back them out if you'd like.

Copy link
Member

@kinow kinow left a comment

Choose a reason for hiding this comment

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

Just to let you know I'm lurking here Gary 👋 thanks for updating the PR, I think you've done some work around the JUnit tests already, that's going to save time during the review thanks!!

.gitignore Show resolved Hide resolved
@gwlucastrig
Copy link
Contributor Author

gwlucastrig commented Apr 10, 2020

I think I will be able to improve the coverage as soon as I can get some test images to exercise the sections of code that are not currently being covered. I'm a bit confused by Coverall's results because in the last update I made no code changes, but added additional unit tests to cover more of the code. I expected that to improve the coverage rating, but it actually went down.

No luck in my search for relevant test images, so I am trying to figure out how to use the Commons Imaging API to write TIFF files that carry floating-point data. That way the project will be able to generate its own test images with the different combination of options. Most of the pieces are already present in the API. The original authors put a remarkable amount of work into the code... But figuring out how to use the API is not always easy.

At least at first, I will not create test files that use the predictor/compressors for floating-point data. The predictors have a lot of nuances and I wouldn't trust my code to produce "valid" TIFF for those combinations of options where I don't have standard samples to test against. All the samples I have so far are 32-bit tile-based files. I've found hundreds of those from the US Geological Survey. But I haven't found any strip-based files.

@gwlucastrig
Copy link
Contributor Author

The 14 April commit (e390778) concludes the preliminary work of enabling Commons Imaging to read images from TIFF files that are based on floating-point data. I am now shifting to implementing new functionality to extract floating-point raster data from the TIFF. I will be adding new blocks of code to the data-reader classes and the TiffImageParser, but do not plan on any further modifications to the existing code.

@gwlucastrig gwlucastrig marked this pull request as draft April 16, 2020 11:55
@gwlucastrig
Copy link
Contributor Author

New classes and methods for accessing floating-point data are now included.

Only a few details remain for the code is ready for review. I extended some of the unit tests, but still need to add new ones for the TiffRasterData and TiffRasterStatistics classes. I also have a new example class and want to see if I can raise the Coverall scores for a few of my changes. I hope to have it ready by the end of the weekend.

@gwlucastrig
Copy link
Contributor Author

gwlucastrig commented May 13, 2020

Had all sorts of trouble with maven reporting a Package Container issue on the verify phase. Naturally, it offered no useful information about what the problem could be. Code compiled fine. I had to back out all my changes and start over. The only thing I can think of is that it may be related to a Java versioning issue because I added lambda's to the photometric interpreters (as suggested in the code review, which I thought was a good idea). But that seems unlikely since my JDK is version 1.8.0_211. So I am puzzled.

Anyway, I am past that and will continue working to integrate the recommendations related to the photometric interpreters.

@gwlucastrig
Copy link
Contributor Author

I tracked down the change that resulted in the Maven failure. Since I haven't really studied Maven (I just treat it as a black box), I'm not really sure how to interpret this. But I am working around the problem by simply not making the change.

In PhotometricInterpreterFloat.java, line 158. I change the code from

Collections.sort(rangePaletteEntries, comparator);
Collections.sort(singleValuePaletteEntries, comparator);

to the following

rangePaletteEntries.sort(comparator);
singleValuePaletteEntries.sort(comparator);

I get a report of an API incompatibility in animal-sniffer-maven-plugin:1.17 complaining
of a NoSuchMethodError: java.nio.CharBuffer.position(I)Ljava/nio/CharBuffer;
Not sure if this is a bug in animal-sniffer (they've got a new version out). I may test that after I get my code turned in.

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  7.835 s
[INFO] Finished at: 2020-05-13T01:58:21-04:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.codehaus.mojo:animal-sniffer-maven-plugin:1.17:check (checkAPIcompatibility) on project commons-imaging: Execution checkAPIcompatibility of goal org.codehaus.mojo:animal-sniffer-maven-plugin:1.17:check failed: An API incompatibility was encountered while executing org.codehaus.mojo:animal-sniffer-maven-plugin:1.17:check: java.lang.NoSuchMethodError: java.nio.CharBuffer.position(I)Ljava/nio/CharBuffer;
[ERROR] -----------------------------------------------------
[ERROR] realm =    plugin>org.codehaus.mojo:animal-sniffer-maven-plugin:1.17
[ERROR] strategy = org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy
[ERROR] urls[0] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/mojo/animal-sniffer-maven-plugin/1.17/animal-sniffer-maven-plugin-1.17.jar
[ERROR] urls[1] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/mojo/animal-sniffer/1.17/animal-sniffer-1.17.jar
[ERROR] urls[2] = file:/C:/Users/gwluc/.m2/repository/org/ow2/asm/asm/6.2/asm-6.2.jar
[ERROR] urls[3] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/mojo/java-boot-classpath-detector/1.17/java-boot-classpath-detector-1.17.jar
[ERROR] urls[4] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/plexus/plexus-component-annotations/1.5.4/plexus-component-annotations-1.5.4.jar
[ERROR] urls[5] = file:/C:/Users/gwluc/.m2/repository/org/sonatype/sisu/sisu-inject-bean/1.4.2/sisu-inject-bean-1.4.2.jar
[ERROR] urls[6] = file:/C:/Users/gwluc/.m2/repository/org/sonatype/sisu/sisu-guice/2.1.7/sisu-guice-2.1.7-noaop.jar
[ERROR] urls[7] = file:/C:/Users/gwluc/.m2/repository/org/slf4j/slf4j-jdk14/1.5.6/slf4j-jdk14-1.5.6.jar
[ERROR] urls[8] = file:/C:/Users/gwluc/.m2/repository/org/slf4j/jcl-over-slf4j/1.5.6/jcl-over-slf4j-1.5.6.jar
[ERROR] urls[9] = file:/C:/Users/gwluc/.m2/repository/org/apache/maven/reporting/maven-reporting-api/2.2.1/maven-reporting-api-2.2.1.jar
[ERROR] urls[10] = file:/C:/Users/gwluc/.m2/repository/org/apache/maven/doxia/doxia-sink-api/1.1/doxia-sink-api-1.1.jar
[ERROR] urls[11] = file:/C:/Users/gwluc/.m2/repository/org/apache/maven/doxia/doxia-logging-api/1.1/doxia-logging-api-1.1.jar
[ERROR] urls[12] = file:/C:/Users/gwluc/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar
[ERROR] urls[13] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/plexus/plexus-interactivity-api/1.0-alpha-4/plexus-interactivity-api-1.0-alpha-4.jar
[ERROR] urls[14] = file:/C:/Users/gwluc/.m2/repository/backport-util-concurrent/backport-util-concurrent/3.1/backport-util-concurrent-3.1.jar
[ERROR] urls[15] = file:/C:/Users/gwluc/.m2/repository/org/sonatype/plexus/plexus-sec-dispatcher/1.3/plexus-sec-dispatcher-1.3.jar
[ERROR] urls[16] = file:/C:/Users/gwluc/.m2/repository/org/sonatype/plexus/plexus-cipher/1.4/plexus-cipher-1.4.jar
[ERROR] urls[17] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/plexus/plexus-interpolation/1.11/plexus-interpolation-1.11.jar
[ERROR] urls[18] = file:/C:/Users/gwluc/.m2/repository/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar
[ERROR] urls[19] = file:/C:/Users/gwluc/.m2/repository/org/apache/maven/shared/maven-common-artifact-filters/1.4/maven-common-artifact-filters-1.4.jar
[ERROR] urls[20] = file:/C:/Users/gwluc/.m2/repository/org/codehaus/plexus/plexus-utils/1.5.6/plexus-utils-1.5.6.jar
[ERROR] Number of foreign imports: 1
[ERROR] import: Entry[import  from realm ClassRealm[maven.api, parent: null]]
[ERROR]

@gwlucastrig
Copy link
Contributor Author

Found the problem. The CharBuffer.position() method appears to have been introduced in Java 9. So the Java 8 API that I build with doesn't support it.

I have been very reluctant to use more recent versions of Java because of Oracle's changes to licensing policies. I may have to revise my thinking on that one.

@kinow
Copy link
Member

kinow commented May 13, 2020

Hopefully there should be some way (maybe not as simple) to achieve the same with Java 8 @gwlucastrig . If not we can think in other alternatives.

@gwlucastrig
Copy link
Contributor Author

I believe that I have now integrated all the changes from the review comments with two exceptions.

The TiffRasterData.getData() method still exposes and internal array. However, I've added Javadoc explaining the rationale and use of the method.

The Collections.sort() methods in PhotometricInterpreterFloat are still there. When I made the recommended changes, animal-sniffer threw an exception. I then installed Java JDK 11 (picking 11 because that's what Travis uses) and the same thing happened. So I am leaving the older code in place.

My plan is to do a bit more testing over the next few days. I do not plan to make any further code changes unless I encounter an unexpected error.

@gwlucastrig gwlucastrig reopened this May 14, 2020
@kinow
Copy link
Member

kinow commented May 14, 2020

Excellent Gary! I have time to review it again this weekend. I think it should be ready to merge now if I find nothing else in the review

Should we delay mergimg until you finish your tests?

@gwlucastrig
Copy link
Contributor Author

All my tests completed successfully. I have some pretty nice pictures to show for it.

When accepted, I believe you will be able to close both JIRA item 251 and 102.

I am currently working on a tutorial showing how to use the Commons Imaging API to read elevation data. When it's done, I will be posting it on my wiki page at Gridfour Wiki. I will, of course, make sure it links to Commons Imaging.

@kinow
Copy link
Member

kinow commented May 15, 2020

Nice! Will start going through it tomorrow. Thanks!!!!

* Defines an interface for specifying color assignments to floating point
* values.
*/
public interface IPaletteEntry {
Copy link
Member

Choose a reason for hiding this comment

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

No need to have the I in interface names (there were components using I and A—for abstract— but that changed long ago).

@kinow
Copy link
Member

kinow commented May 16, 2020

No blockers so far, another 9 files to go, and then review is done. Comments added now can either be fixed before merging, or afterwards.

@gwlucastrig do you mind if when merging I squash the commits when merging?

@gwlucastrig
Copy link
Contributor Author

@kinow I would prefer that you squash the commits. I didn't know that there was a git command that allowed you to do that.

I renamed IPaletteEntry to simple PaletteEntry. I got a list of all Java files in the commons-imaging source code and saw that none of the others used the leading-I convention. So it makes sense to rename the class.

@kinow
Copy link
Member

kinow commented May 16, 2020

Brilliant! Then tomorrow I will finish the review. Final things I'm looking at are

  • test coverage of new code (I lost track of how much is covered here)
  • possible issues for security (those N/0, or loading values from the data without checking boundaries, etc)
  • how much we broke backward compatibility—if any

If nothing is wrong, then I will just squash. Several ways of doing it I think; I normally do with git rebase -i HEAD~N, where N is the number of commits I want to squash. Doesn't mean we need to squash to a single one, but we can probably combine a few ones. And add a changelog, and merge :-)

Thanks for updating it so quickly!
Bruno

@kinow
Copy link
Member

kinow commented May 17, 2020

test coverage of new code (I lost track of how much is covered here)

Some of the new code is not covered by tests. But alas I think it's quite hard to find images for these tests. Later we may look into having some sort of image generator, or try to locate more test images.

https://coveralls.io/builds/30831964

image

@kinow
Copy link
Member

kinow commented May 17, 2020

possible issues for security (those N/0, or loading values from the data without checking boundaries, etc)

Nothing obvious. A fuzzer could still find some images that could lead to exceptions, but I couldn't find a case where it would lead to DDoS attacks (:crossed_fingers:)

@kinow
Copy link
Member

kinow commented May 17, 2020

how much we broke backward compatibility—if any

Nothing too drastic—i.e. API changes OK IMHO for next alpha release (this will change once we have 1.0 out)

@kinow
Copy link
Member

kinow commented May 17, 2020

Approved. Rebasing and merging. Thanks @gwlucastrig !

@kinow kinow closed this in 63965de May 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants