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

BUG: fixed regression in gdcmImageCodec.cxx #165

Merged
merged 1 commit into from
Jan 9, 2024

Conversation

issakomi
Copy link
Contributor

@issakomi issakomi commented Jan 6, 2024

S. post https://sourceforge.net/p/gdcm/bugs/554/


An unexpected behavior was introduced in commit 4ecd77a, causing pixel values being all greater or equal to zero on DICOM images where negative values are expected. When trying to solve the following cppcheck issues:

shiftNegativeLHS,GDCM/Source/MediaStorageAndFileFormat/gdcmImageCodec.cxx:465,portability,Shifting a negative value is technically undefined behaviour
shiftNegativeLHS,GDCM/Source/MediaStorageAndFileFormat/gdcmImageCodec.cxx:521,portability,Shifting a negative value is technically undefined behaviour

The changes in gdcmImageCodec.cxx:465 and gdcmImageCodec.cxx:521 implies a potential difference in the sign of nmask, depending on the specific values of PF.GetBitsAllocated() and PF.GetBitsStored(). If the right shift operation in the modified version produces a non-negative value, the result will be positive, whereas the result in the non modified version will always be negative due to the initial assignment of 0x8000 as a signed integer.


I could reproduce the issue:

#include <iostream>
#include <cstdint>
#include <vector>

int main()
{
  const std::vector<unsigned short> a{ 7, 6, 5, 4, 3, 2, 1, 0 };

  std::cout << "Old:" << '\n';
  for (size_t x = 0; x < a.size(); ++x)
  {
    //////////////////////////////////////////////
    //
    //
    int16_t nmask = (int16_t)0x8000;
    nmask = (int16_t)(nmask >> a.at(x));
    //
    //
    //////////////////////////////////////////////
    std::cout << nmask << '\n';
  }

  std::cout << "New:" << '\n';
  for (size_t x = 0; x < a.size(); ++x)
  {
    //////////////////////////////////////////////
    //
    //
    int16_t nmask = (int16_t)(0x8000U >> a.at(x));
    //
    //
    //////////////////////////////////////////////
    std::cout << nmask << '\n';
  }

  return 0;
}
Old:
-256
-512
-1024
-2048
-4096
-8192
-16384
-32768
New:
256
512
1024
2048
4096
8192
16384
-32768

S. https://sourceforge.net/p/gdcm/bugs/554/
An unexpected behavior was introduced in commit malaterre@4ecd77a,
causing pixel values being all greater or equal to zero on DICOM images where negative values are expected.
When trying to solve the following cppcheck issues:
shiftNegativeLHS,GDCM/Source/MediaStorageAndFileFormat/gdcmImageCodec.cxx:465,portability,Shifting a negative value is technically undefined behaviour
shiftNegativeLHS,GDCM/Source/MediaStorageAndFileFormat/gdcmImageCodec.cxx:521,portability,Shifting a negative value is technically undefined behaviour
The changes in gdcmImageCodec.cxx:465 and gdcmImageCodec.cxx:521 implies a potential difference in the sign of nmask,
depending on the specific values of PF.GetBitsAllocated() and PF.GetBitsStored(). If the right shift operation in the
modified version produces a non-negative value, the result will be positive, whereas the result in the non modified
version will always be negative due to the initial assignment of 0x8000 as a signed integer.
@malaterre malaterre marked this pull request as ready for review January 9, 2024 13:46
@malaterre malaterre merged commit 7928ec6 into malaterre:master Jan 9, 2024
3 checks passed
@malaterre
Copy link
Owner

Thanks !

@issakomi issakomi deleted the fixreg1 branch January 9, 2024 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants