-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
.stats() implementation #915
Conversation
Pull from sharp / master
Looks great, and with lots of tests too, thank you very much Rahul! In terms of the sporadically failing values, perhaps there should be a margin of error for these? For example the difference in the sum of pixel values appears to be <0.1% across all platforms. I realise the min and max coords will vary across test runs. Perhaps we could verify their values are positive integers that fall within the bounds of the image? |
test/unit/stats.js
Outdated
readable.pipe(pipeline); | ||
}); | ||
|
||
it('Stream in, Promise out', function (done) { |
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.
This test should be able to return the Promise instance, which will then remove the need to use done
and catch
.
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.
.stats()
does return a promise in this test. I am not sure if I got your point. A similar test exists for metadata()
as well.
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.
mocha deals with tests that return (and reject) a Promise
, e.g.:
it('Stream in, Promise out', function () {
const pipeline = sharp();
fs
.createReadStream(fixtures.inputJpg)
.pipe(pipeline);
return pipeline
.stats()
.then(function (stats) {
...
});
});
src/stats.cc
Outdated
(baton->err).append(err.what()); | ||
} | ||
if (imageType != sharp::ImageType::UNKNOWN) { | ||
stats = image.stats(); |
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.
Can stats()
throw? This might need to live inside the try/catch block.
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.
I don't think stats()
throws
https://github.com/jcupitt/libvips/blob/master/libvips/arithmetic/stats.c
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.
libvips' C++ wrapper passes through call_option_string that can throw.
test/unit/stats.js
Outdated
readable.pipe(pipeline); | ||
}); | ||
|
||
it('Stream in, Promise out', function (done) { |
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.
mocha deals with tests that return (and reject) a Promise
, e.g.:
it('Stream in, Promise out', function () {
const pipeline = sharp();
fs
.createReadStream(fixtures.inputJpg)
.pipe(pipeline);
return pipeline
.stats()
.then(function (stats) {
...
});
});
src/stats.cc
Outdated
(baton->err).append(err.what()); | ||
} | ||
if (imageType != sharp::ImageType::UNKNOWN) { | ||
stats = image.stats(); |
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.
libvips' C++ wrapper passes through call_option_string that can throw.
Merge from lovell/sharp
Is there anything I can do to fix this build? |
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.
Hello, thanks for all the updates to this PR, I've added a few comments inline that should hopefully solve that final test failure.
src/stats.cc
Outdated
sharp::ImageType imageType = sharp::ImageType::UNKNOWN; | ||
|
||
try { | ||
std::tie(image, imageType) = OpenInput(baton->input, VIPS_ACCESS_SEQUENTIAL); |
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.
Probably best to use the configured baton->accessMode
instead of VIPS_ACCESS_SEQUENTIAL
as this defaults to random, which avoids over-computation from the source decoder (and should fix those libtiff test errors).
src/stats.cc
Outdated
int bands = image.bands(); | ||
double const max = MaximumImageAlpha(image.interpretation()); | ||
for (int b = 1; b <= bands; b++) { | ||
ChannelStats cStats(stats.getpoint(STAT_MIN_INDEX, b).front(), stats.getpoint(STAT_MAX_INDEX, b).front(), |
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.
I think the values returned by getpoint
are double
precision so some of these will require static_cast<int>
conversion.
test/unit/stats.js
Outdated
|
||
const fs = require('fs'); | ||
const assert = require('assert'); | ||
// const exifReader = require('exif-reader'); |
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.
These unused imports can be removed.
test/unit/stats.js
Outdated
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['squaresSum'], 83061892917)); | ||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['mean'], 101.44954540768993)); | ||
assert.strictEqual(true, isInAcceptableRange(stats.channels[0]['stdev'], 58.373870588815414)); | ||
assert.strictEqual(true, isInteger(stats.channels[0]['minX']) && isInRange(stats.channels[0]['minX'], 0, 2725)); |
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.
Perhaps split these assert(true, x && y)
statements into two separate assert
statements to aid debugging and remove conditional logic from tests.
docs/api-input.md
Outdated
@@ -4,6 +4,7 @@ | |||
|
|||
- [clone](#clone) | |||
- [metadata](#metadata) | |||
- [stats](#stats) |
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 docs/api-*.md
files are autogenerated so this content needs to live in the jsdocs above the new stats
function.
This all looks great, thank you for the updates Rahul. As soon as the |
Merged to master, thanks Rahul, this will be in v0.19.0. |
Hi. I'm having issues getting the stats from a PNG image converted to LCH space.
This returns the same stats, whether I convert to Thanks |
Please review the code. Especially the C++ part as I am not very confident with the language. Let me know if something else or some other helper value like
isOpaque
needs to be exposed in the output.