-
Notifications
You must be signed in to change notification settings - Fork 597
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
fix implicit 64 to 32 bit conversion warnings #3955
base: main
Are you sure you want to change the base?
fix implicit 64 to 32 bit conversion warnings #3955
Conversation
Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
@@ -86,15 +86,15 @@ inline char SwapBytes( char& value ) | |||
|
|||
|
|||
template <typename T> | |||
void SwapBuffer(T *buf, unsigned int len) | |||
void SwapBuffer(T *buf, size_t len) |
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 understand what's going on here. The parameter was unsigned int, and the loop variable below is also unsigned int. Why change to size_t? And if the param is size_t, doesn't it just make a new potential problem or warning in the loop below that still is unsigned int?
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.
SwapBuffer gets called from EndianSwapImageBuffer, passing the length parameter. EndianSwapImageBuffer in turn is called from multiple places with size_t as the length parameter. Changing the param type seemed more logical to me. I have indeed overlooked the int in the loop.
Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
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.
Meta comment / battle for another day: What style of casts are preferred? Functional int(x)
or c-style (int)x
-- both are used in this PR, sometimes even within the same file.
I tried to look over things carefully but will want to take another fresh look tomorrow just in case.
@@ -48,7 +48,7 @@ class HdrInput final : public ImageInput { | |||
bool read_native_scanline(int subimage, int miplevel, int y, int z, | |||
void* data) override; | |||
bool close() override; | |||
int current_subimage(void) const override { return m_subimage; } | |||
int current_subimage(void) const override { return (int)m_subimage; } |
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.
Unintentional change? m_subimage
is already an int
?
@@ -91,7 +91,7 @@ class DeepData::Impl { // holds all the nontrivial stuff | |||
spin_lock lock(m_mutex); | |||
if (!m_allocated) { | |||
// m_cumcapacity.resize (npixels); | |||
size_t totalcapacity = 0; | |||
int totalcapacity = 0; |
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.
Seems odd to use int
here for a total when the items added are each uint32_t
themselves.
imagesize_t tile_pixels = m_spec.tile_pixels(); | ||
imagesize_t nvals = tile_pixels * m_inputchannels; | ||
int tile_pixels = (int)m_spec.tile_pixels(); | ||
int nvals = tile_pixels * m_inputchannels; |
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 believe large tiles would be broken with this. tile_pixels * m_inputchannels
can overflow 2billion here e.g. a 24k, 4-channel image, with 1 tile
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 2 values get passed to palette_to_rgb
and bit_convert
which take ints. If int overflows for large tiles, the issue is already there. We may want to modify those two to take a larger type.
This is actually a good example why this work is worth doing.
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.
Although each dimension of an image (width, height, depth, nchannels, subimages, etc) are usually declared as int for simplicity (and the fact that at this point, we don't imagine any of those being > 2^31), we use imagesize_t
(a.k.a. uint64_t) when we have to talk about the number of pixels or values in a tile or images (because those other dimensions may multiply).
So I think in this case, you want to keep tile_pixels and nvals as imagesize_t. It's the count parameters in palette_to_rgb and bit_convert that should probably should be upgraded to imagesize_t rather than int.
@@ -28,7 +28,7 @@ namespace fits_pvt { | |||
// struct in which we store information about one subimage. This information | |||
// allow us to set up pointer at the beginning of given subimage | |||
struct Subimage { | |||
int number; | |||
size_t number; |
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.
Why the change here? Subimages in OIIO are ints and other formats store their equivalent as an int. Actually is this even used? I see one line that sets this value but nothing ever reads from it; maybe remove it entirely.
@@ -21,7 +21,7 @@ static std::string | |||
test_numeric(T* data, int num_elements, TypeDesc type) | |||
{ | |||
ParamValue p("name", type, num_elements, data); | |||
int n = type.numelements() * num_elements; | |||
int n = (int)type.numelements() * num_elements; |
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 is opposite of what was done inside src/libutil/paramlist.cpp
where size_t
was kept.
@@ -1243,7 +1243,7 @@ TIFFOutput::write_scanline(int y, int z, TypeDesc format, const void* data, | |||
std::vector<unsigned char> cmyk; | |||
if (m_photometric == PHOTOMETRIC_SEPARATED && m_convert_rgb_to_cmyk) | |||
data = convert_to_cmyk(spec().width, data, cmyk); | |||
size_t scanline_vals = size_t(spec().width) * m_outputchans; | |||
int scanline_vals = spec().width * m_outputchans; |
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.
While this won't overflow because TIFF has a width restriction of 1048576, a calculation a few lines below this keeps the size_t
for a similar multiplication against the format size.
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.
Yeah, this is another one that definitely should stay size_t (or even more explicitly be imagesize_t, though those are the same thing on 64 bit platforms).
I'm worried that this is a rathole that's just going to waste a lot of Anton's time and will touch lots of things that have been working for a long time, possibly introducing subtle bugs if we aren't very careful. Before continuing to fix these individually, let's step back and think about a few things:
|
Larry, doing Xcode enables |
Sorry, my bad. We always enable -Wall. What I meant is -Wextra, which is turned on by the EXTRA_WARNINGS cmake variable. I guess "all" isn't really "all"! Here's what I think we should do:
|
Sounds good. Larry, while we are looking at warnings, could you check this one. Shouldn't there be logical and, not bitwise? Am I missing something? |
That one is intentionally bitwise, for performance reasons. ( |
By the way, a lot of what you did on this PR is just fine. Part of asking to step back and turn them into smaller PRs is to cleave off the good ones from the ones that require some more thought. For example, all the ones of this nature:
changing to size_t, those are fine and good to change since obviously vector::size() returns size_t and so it's weird that we ever assigned that to an int. |
Description
Enabling the implicit 64 to 32 bit conversion warnings shows several hundreds of them. This is my attempt to fix them all.
Tests
I have built the code on an Apple silicon Mac (both command line and Xcode), and an x64 linux machine, and have run the tests. I have not tested on Windows, or any 32-bit hardware.
I'm not familiar with the project enough to say that my testing was adequate. Any help would be appreciated.
Checklist:
(adding new test cases if necessary).
corresponding Python bindings (and if altering ImageBufAlgo functions, also
exposed the new functionality as oiiotool options).
already run clang-format before submitting, I definitely will look at the CI
test that runs clang-format and fix anything that it highlights as being
nonconforming.