-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Overhaul GD test helpers and affected tests #17309
base: master
Are you sure you want to change the base?
Conversation
libgd stores the pixel as an array of rows, so we should use row-major- order traversal to improve caching.
The assertion regarding the image dimensions won't break any tests, and we had it already as a comment. However, asserting that the images are truecolor images is important for `calc_image_dissimilarity()` which otherwise would calculate nonsense, and not unreasonable for `test_image_equals_image()` which otherwise is overspecified (for our purposes, it doesn't matter which palette entry a pixel refers to, but rather whether the actual colors referred by a palette color match). Since the truecolor assertions break two tests, we fix these by converting to truecolor. That should likely be backported to lower branches.
Conversion to truecolor is a relatively expensive operation, and as such should not be implicit; instead test authors are encouraged to use truecolor images in the first place where possible, or to even find better ways to verify expectations than doing a full image comparison.
There is no particular reason to have a separate file for similarity comparisons.
`calc_image_dissimilarity()` calculates the sum of the euclidean distance of the RGB channels of all pixels. The euclidean distance is either zero or greater than or equal to one (but never in ]0, 1[). The sum of these values also has this property, so it doesn't make sense to check for less than 1e-5. Thus we just call `test_image_equals_file()` instead.
`calc_image_dissimilarity()` has the drawback that it did sum up the pixel differences, so for large images the result could be way larger than for small images. It also has the drawback that it likely is not as well understood as the mean squared error. Thus we replace it with the latter, and calculate the mean squared error of the individual RGB channels (to be precise). The result is always in range 0..255**2 what makes reasoning about thresholds easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes make sense to me. :)
$e += ((($c1 >> 16) & 255) - (($c2 >> 16) & 255)) ** 2 | ||
+ ((($c1 >> 8) & 255) - (($c2 >> 8) & 255)) ** 2 | ||
+ ((($c1 >> 0) & 255) - (($c2 >> 0) & 255)) ** 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just stumbled upon libgd/libgd#751, where the differences are divided by the maximum value, thus yielding values in range [0, 1] (instead of [0, 255]), so the squares would stay in range [0, 1] (instead of [0, 65025]), as would the final result of mse()
. That might be even better (at least wrt possibly adding alpha support later).
See individual commit messages for details. TL;DR: this cleans up/modernizes the test helpers a bit (including some minor speed-ups), fixes/improves/simplifies a couple of related test cases, and maybe most importantly replaces the somewhat obsure
calc_image_dissimilarity()
with the well-know mean squared error.