boostorg / gil

Boost.GIL - Generic Image Library | Requires C++14 since Boost 1.80
https://boostorg.github.io/gil
Boost Software License 1.0
178 stars 164 forks source link

Overflow in channel convertion #730

Open tanguimorvan opened 1 year ago

tanguimorvan commented 1 year ago

Actual behavior

Channel conversion from boost::gil::packed_channel_value to uint16_t fails due to integer overflow in channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false> .

Expected behavior

The value should not overflow, producing correct results.

C++ Minimal Working Example

#include <boost/gil.hpp>
namespace gil = boost::gil;
int main
{
    boost::gil::packed_channel_value<10> packedChannelValue(3);
    //Expected 192, got 64
    uint16_t convertedValue = boost::gil::channel_convert<uint16_t>(packedChannelValue);
}

Environment

tanguimorvan commented 1 year ago
Index: channel_algorithm.hpp
===================================================================
--- channel_algorithm.hpp   (revision 56209)
+++ channel_algorithm.hpp   (working copy)
@@ -237,7 +237,7 @@
 struct channel_converter_unsigned_integral_nondivisible<SrcChannelV,DstChannelV,true,false> {
     DstChannelV operator()(SrcChannelV src) const {
         typedef typename base_channel_type<DstChannelV>::type dest_t;
-        return DstChannelV(static_cast<dest_t>( src * unsigned_integral_max_value<DstChannelV>::value) / unsigned_integral_max_value<SrcChannelV>::value);
+        return DstChannelV(static_cast<dest_t>( src ) * unsigned_integral_max_value<DstChannelV>::value / unsigned_integral_max_value<SrcChannelV>::value);
     }
 };
mloskot commented 1 year ago

@tanguimorvan Thanks, feel free to open PR with your changes