From 3b262c456a24e7ee38d5c5971cb829ac9cde5c2a Mon Sep 17 00:00:00 2001 From: MajorMurphy Date: Fri, 29 May 2026 20:30:22 -0400 Subject: [PATCH 1/3] Fix MSVC narrowing conversion warnings (C4244, C4267, C4305, C4838) - icc.cpp: use float literals in Matrix3x3 aggregate initializer (C4838) - icc.cpp: explicit cast for strlen result assigned to uint32_t (C4267) - jpegdecoderhelper.cpp: explicit cast for std::ceil result assigned to unsigned int (C4244) - jpegencoderhelper.cpp: explicit casts for std::ceil and strlen results assigned to unsigned int (C4244, C4267) - CMakeLists.txt: remove /wd4244, /wd4267, /wd4305, /wd4838 suppressions --- CMakeLists.txt | 7 ------- lib/src/icc.cpp | 4 ++-- lib/src/jpegdecoderhelper.cpp | 10 ++++++---- lib/src/jpegencoderhelper.cpp | 11 ++++++----- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16771bfb..b427d8d0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,13 +251,6 @@ endif() set(UHDR_WERROR_FLAGS "") if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) - # Disable specific warnings - # TODO: None of these should be disabled, but for now, for a warning-free msvc build these are - # added. fix the warnings and remove these filters - add_compile_options(/wd4244) # conversion from 'type1' to 'type2', possible loss of data - add_compile_options(/wd4267) # conversion from 'size_t' to 'type' possible loss of data - add_compile_options(/wd4305) # truncation from 'double' to 'float' - add_compile_options(/wd4838) # conversion from 'type1' to 'type2' requires a narrowing conversion add_compile_options(/wd26812) # Prefer enum class over enum elseif(EMSCRIPTEN) if(NOT UHDR_BUILD_DEPS) diff --git a/lib/src/icc.cpp b/lib/src/icc.cpp index 607f21d0..f89a706b 100644 --- a/lib/src/icc.cpp +++ b/lib/src/icc.cpp @@ -81,7 +81,7 @@ bool Matrix3x3_invert(const Matrix3x3* src, Matrix3x3* dst) { } static Matrix3x3 Matrix3x3_concat(const Matrix3x3* A, const Matrix3x3* B) { - Matrix3x3 m = {{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}}; + Matrix3x3 m = {{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}}; for (int r = 0; r < 3; r++) for (int c = 0; c < 3; c++) { m.vals[r][c] = A->vals[r][0] * B->vals[0][c] + A->vals[r][1] * B->vals[1][c] + @@ -156,7 +156,7 @@ std::string IccHelper::get_desc_string(const uhdr_color_transfer_t tf, } std::shared_ptr IccHelper::write_text_tag(const char* text) { - uint32_t text_length = strlen(text); + uint32_t text_length = static_cast(strlen(text)); uint32_t header[] = { Endian_SwapBE32(kTAG_TextType), // Type signature 0, // Reserved diff --git a/lib/src/jpegdecoderhelper.cpp b/lib/src/jpegdecoderhelper.cpp index bfd7e8be..18e89134 100644 --- a/lib/src/jpegdecoderhelper.cpp +++ b/lib/src/jpegdecoderhelper.cpp @@ -308,11 +308,13 @@ uhdr_error_info_t JpegDecoderHelper::decode(const void* image, size_t length, de mNumComponents = cinfo.num_components; for (int i = 0; i < cinfo.num_components; i++) { - mPlaneWidth[i] = std::ceil(((float)cinfo.image_width * cinfo.comp_info[i].h_samp_factor) / - cinfo.max_h_samp_factor); + mPlaneWidth[i] = static_cast( + std::ceil(((float)cinfo.image_width * cinfo.comp_info[i].h_samp_factor) / + cinfo.max_h_samp_factor)); mPlaneHStride[i] = mPlaneWidth[i]; - mPlaneHeight[i] = std::ceil(((float)cinfo.image_height * cinfo.comp_info[i].v_samp_factor) / - cinfo.max_v_samp_factor); + mPlaneHeight[i] = static_cast( + std::ceil(((float)cinfo.image_height * cinfo.comp_info[i].v_samp_factor) / + cinfo.max_v_samp_factor)); mPlaneVStride[i] = mPlaneHeight[i]; } diff --git a/lib/src/jpegencoderhelper.cpp b/lib/src/jpegencoderhelper.cpp index b06b2db6..998180ed 100644 --- a/lib/src/jpegencoderhelper.cpp +++ b/lib/src/jpegencoderhelper.cpp @@ -189,10 +189,10 @@ uhdr_error_info_t JpegEncoderHelper::encode(const uint8_t* planes[3], const unsi for (int i = 0; i < cinfo.num_components; i++) { cinfo.comp_info[i].h_samp_factor = factors[i * 2]; cinfo.comp_info[i].v_samp_factor = factors[i * 2 + 1]; - mPlaneWidth[i] = - std::ceil(((float)cinfo.image_width * cinfo.comp_info[i].h_samp_factor) / factors[6]); - mPlaneHeight[i] = - std::ceil(((float)cinfo.image_height * cinfo.comp_info[i].v_samp_factor) / factors[7]); + mPlaneWidth[i] = static_cast( + std::ceil(((float)cinfo.image_width * cinfo.comp_info[i].h_samp_factor) / factors[6])); + mPlaneHeight[i] = static_cast( + std::ceil(((float)cinfo.image_height * cinfo.comp_info[i].v_samp_factor) / factors[7])); } if (format != UHDR_IMG_FMT_24bppRGB888) cinfo.raw_data_in = TRUE; cinfo.dct_method = JDCT_ISLOW; @@ -207,7 +207,8 @@ uhdr_error_info_t JpegEncoderHelper::encode(const uint8_t* planes[3], const unsi snprintf(comment, sizeof comment, "Source: google libuhdr v%s, Coder: libjpeg v%d, Attrib: GainMap Image", UHDR_LIB_VERSION_STR, JPEG_LIB_VERSION); - jpeg_write_marker(&cinfo, JPEG_COM, reinterpret_cast(comment), strlen(comment)); + jpeg_write_marker(&cinfo, JPEG_COM, reinterpret_cast(comment), + static_cast(strlen(comment))); } if (format == UHDR_IMG_FMT_24bppRGB888) { while (cinfo.next_scanline < cinfo.image_height) { From ea5a3ff9333bee5b74d2545f0af6f6b47ad0e0af Mon Sep 17 00:00:00 2001 From: MajorMurphy Date: Fri, 29 May 2026 20:53:26 -0400 Subject: [PATCH 2/3] Update build.md to include clang requirement --- docs/building.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/building.md b/docs/building.md index 755502fb..c2b6ed1e 100644 --- a/docs/building.md +++ b/docs/building.md @@ -90,7 +90,7 @@ cd build_directory Install the prerequisite packages before building: ```sh -sudo apt install cmake pkg-config libjpeg-dev ninja-build +sudo apt install clang cmake pkg-config libjpeg-dev ninja-build ``` Compile and Test: From 154127aec5aa18f05ca37fa63caf3460d32954df Mon Sep 17 00:00:00 2001 From: MajorMurphy Date: Sat, 30 May 2026 07:55:22 -0400 Subject: [PATCH 3/3] Fix MSVC build warnings at warning level 3 including: C4244, C4267, C4305, C4838 --- CMakeLists.txt | 5 +++-- lib/include/ultrahdr/gainmapmath.h | 7 ++++--- lib/src/gainmapmath.cpp | 22 +++++++++++----------- lib/src/icc.cpp | 24 ++++++++++++------------ lib/src/jpegdecoderhelper.cpp | 4 ++-- lib/src/jpegencoderhelper.cpp | 7 ++++--- lib/src/jpegr.cpp | 8 ++++---- lib/src/multipictureformat.cpp | 8 ++++---- 8 files changed, 44 insertions(+), 41 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b427d8d0..1a30fc60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,7 +251,6 @@ endif() set(UHDR_WERROR_FLAGS "") if(MSVC) add_definitions(-D_CRT_SECURE_NO_WARNINGS) - add_compile_options(/wd26812) # Prefer enum class over enum elseif(EMSCRIPTEN) if(NOT UHDR_BUILD_DEPS) include(CheckCSourceCompiles) @@ -613,7 +612,9 @@ target_compile_options(${UHDR_CORE_LIB_NAME} PRIVATE ${UHDR_WERROR_FLAGS}) if(NOT JPEG_FOUND) add_dependencies(${UHDR_CORE_LIB_NAME} ${JPEGTURBO_TARGET_NAME}) endif() -if(NOT MSVC) +if(MSVC) + target_compile_options(${UHDR_CORE_LIB_NAME} PRIVATE /W3) +else() target_compile_options(${UHDR_CORE_LIB_NAME} PRIVATE -Wall -Wextra -Wshadow) endif() if(DEFINED UHDR_MAX_DIMENSION) diff --git a/lib/include/ultrahdr/gainmapmath.h b/lib/include/ultrahdr/gainmapmath.h index 885f8e34..167f705e 100644 --- a/lib/include/ultrahdr/gainmapmath.h +++ b/lib/include/ultrahdr/gainmapmath.h @@ -167,9 +167,10 @@ inline uint16_t floatToHalf(float f) { const uint32_t m = b & 0x007FFFFF; // mantissa // sign : normalized : denormalized : saturate - return (b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) | - ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | - (e > 143) * 0x7FFF; + return static_cast( + (b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) | + ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | + (e > 143) * 0x7FFF); } // Taken from frameworks/base/libs/hwui/jni/android_graphics_ColorSpace.cpp diff --git a/lib/src/gainmapmath.cpp b/lib/src/gainmapmath.cpp index 7e01077a..dcd17a3c 100644 --- a/lib/src/gainmapmath.cpp +++ b/lib/src/gainmapmath.cpp @@ -45,11 +45,11 @@ void ShepardsIDW::fillShepardsIDW(float* weights, int incR, int incB) { for (int x = 0; x < mMapScaleFactor; x++) { float pos_x = ((float)x) / mMapScaleFactor; float pos_y = ((float)y) / mMapScaleFactor; - int curr_x = floor(pos_x); - int curr_y = floor(pos_y); + int curr_x = static_cast(floor(pos_x)); + int curr_y = static_cast(floor(pos_y)); int next_x = curr_x + incR; int next_y = curr_y + incB; - float e1_distance = euclideanDistance(pos_x, curr_x, pos_y, curr_y); + float e1_distance = euclideanDistance(pos_x, (float)curr_x, pos_y, (float)curr_y); int index = y * mMapScaleFactor * 4 + x * 4; if (e1_distance == 0) { weights[index++] = 1.f; @@ -59,13 +59,13 @@ void ShepardsIDW::fillShepardsIDW(float* weights, int incR, int incB) { } else { float e1_weight = 1.f / e1_distance; - float e2_distance = euclideanDistance(pos_x, curr_x, pos_y, next_y); + float e2_distance = euclideanDistance(pos_x, (float)curr_x, pos_y, (float)next_y); float e2_weight = 1.f / e2_distance; - float e3_distance = euclideanDistance(pos_x, next_x, pos_y, curr_y); + float e3_distance = euclideanDistance(pos_x, (float)next_x, pos_y, (float)curr_y); float e3_weight = 1.f / e3_distance; - float e4_distance = euclideanDistance(pos_x, next_x, pos_y, next_y); + float e4_distance = euclideanDistance(pos_x, (float)next_x, pos_y, (float)next_y); float e4_weight = 1.f / e4_distance; float total_weight = e1_weight + e2_weight + e3_weight + e4_weight; @@ -657,7 +657,7 @@ const std::array kYuvBt601ToBt709 = { // U' = (0.0 * Y) + ( 1.010016 * U) + ( 0.061592 * V) // V' = (0.0 * Y) + ( 0.086969 * U) + ( 1.029350 * V) const std::array kYuvBt601ToBt2100 = { - 1.0f, -0.128245f, -0.115879, 0.0f, 1.010016f, 0.061592f, 0.0f, 0.086969f, 1.029350f}; + 1.0f, -0.128245f, -0.115879f, 0.0f, 1.010016f, 0.061592f, 0.0f, 0.086969f, 1.029350f}; // Yuv Bt2100 -> Yuv Bt709 // Y' = (1.0 * Y) + ( 0.018149 * U) + (-0.095132 * V) @@ -785,7 +785,7 @@ uint8_t affineMapGain(float gainlog2, float mingainlog2, float maxgainlog2, floa float mappedVal = (gainlog2 - mingainlog2) / (maxgainlog2 - mingainlog2); if (gamma != 1.0f) mappedVal = pow(mappedVal, gamma); mappedVal *= 255; - return CLIP3(mappedVal + 0.5f, 0, 255); + return static_cast(CLIP3(mappedVal + 0.5f, 0.0f, 255.0f)); } Color applyGain(Color e, float gain, uhdr_gainmap_metadata_ext_t* metadata) { @@ -1277,9 +1277,9 @@ bool isPixelFormatRgb(uhdr_img_fmt_t format) { } uint32_t colorToRgba1010102(Color e_gamma) { - uint32_t r = CLIP3((e_gamma.r * 1023 + 0.5f), 0.0f, 1023.0f); - uint32_t g = CLIP3((e_gamma.g * 1023 + 0.5f), 0.0f, 1023.0f); - uint32_t b = CLIP3((e_gamma.b * 1023 + 0.5f), 0.0f, 1023.0f); + uint32_t r = static_cast(CLIP3((e_gamma.r * 1023 + 0.5f), 0.0f, 1023.0f)); + uint32_t g = static_cast(CLIP3((e_gamma.g * 1023 + 0.5f), 0.0f, 1023.0f)); + uint32_t b = static_cast(CLIP3((e_gamma.b * 1023 + 0.5f), 0.0f, 1023.0f)); return (r | (g << 10) | (b << 20) | (0x3 << 30)); // Set alpha to 1.0 } diff --git a/lib/src/icc.cpp b/lib/src/icc.cpp index f89a706b..a4225cfe 100644 --- a/lib/src/icc.cpp +++ b/lib/src/icc.cpp @@ -270,8 +270,8 @@ std::shared_ptr IccHelper::write_cicp_tag(uint32_t color_primaries, std::shared_ptr dataStruct = std::make_shared(kCicpTagSize); dataStruct->write32(Endian_SwapBE32(kTAG_cicp)); // Type signature dataStruct->write32(0); // Reserved - dataStruct->write8(color_primaries); // Color primaries - dataStruct->write8(transfer_characteristics); // Transfer characteristics + dataStruct->write8(static_cast(color_primaries)); // Color primaries + dataStruct->write8(static_cast(transfer_characteristics)); // Transfer characteristics dataStruct->write8(0); // RGB matrix dataStruct->write8(1); // Full range return dataStruct; @@ -366,7 +366,7 @@ std::shared_ptr IccHelper::write_mAB_or_mBA_tag(uint32_t type, bool } } - int total_length = b_curves_offset; + size_t total_length = b_curves_offset; for (size_t i = 0; i < kNumChannels; ++i) { total_length += b_curves_data[i]->getLength(); } @@ -382,11 +382,11 @@ std::shared_ptr IccHelper::write_mAB_or_mBA_tag(uint32_t type, bool dataStruct->write8(kNumChannels); // Input channels dataStruct->write8(kNumChannels); // Output channels dataStruct->write16(0); // Reserved - dataStruct->write32(Endian_SwapBE32(b_curves_offset)); // B curve offset - dataStruct->write32(Endian_SwapBE32(0)); // Matrix offset (ignored) - dataStruct->write32(Endian_SwapBE32(0)); // M curve offset (ignored) - dataStruct->write32(Endian_SwapBE32(clut_offset)); // CLUT offset - dataStruct->write32(Endian_SwapBE32(a_curves_offset)); // A curve offset + dataStruct->write32(Endian_SwapBE32(static_cast(b_curves_offset))); // B curve offset + dataStruct->write32(Endian_SwapBE32(0)); // Matrix offset (ignored) + dataStruct->write32(Endian_SwapBE32(0)); // M curve offset (ignored) + dataStruct->write32(Endian_SwapBE32(static_cast(clut_offset))); // CLUT offset + dataStruct->write32(Endian_SwapBE32(static_cast(a_curves_offset))); // A curve offset for (size_t i = 0; i < kNumChannels; ++i) { if (dataStruct->write(b_curves_data[i]->getData(), b_curves_data[i]->getLength())) { return dataStruct; @@ -560,8 +560,8 @@ std::shared_ptr IccHelper::writeIccProfile(uhdr_color_transfer_t tf, // Write the header. header.data_color_space = Endian_SwapBE32(Signature_RGB); header.pcs = Endian_SwapBE32(tf == UHDR_CT_PQ ? Signature_Lab : Signature_XYZ); - header.size = Endian_SwapBE32(profile_size); - header.tag_count = Endian_SwapBE32(tags.size()); + header.size = Endian_SwapBE32(static_cast(profile_size)); + header.tag_count = Endian_SwapBE32(static_cast(tags.size())); if (!dataStruct->write(&header, sizeof(header))) { ALOGE("writeIccProfile(): error in header"); @@ -571,11 +571,11 @@ std::shared_ptr IccHelper::writeIccProfile(uhdr_color_transfer_t tf, // Write the tag table. Track the offset and size of the previous tag to // compute each tag's offset. An empty SkData indicates that the previous // tag is to be reused. - uint32_t last_tag_offset = sizeof(header) + tag_table_size; + uint32_t last_tag_offset = static_cast(sizeof(header) + tag_table_size); uint32_t last_tag_size = 0; for (const auto& tag : tags) { last_tag_offset = last_tag_offset + last_tag_size; - last_tag_size = tag.second->getLength(); + last_tag_size = static_cast(tag.second->getLength()); uint32_t tag_table_entry[3] = { Endian_SwapBE32(tag.first), Endian_SwapBE32(last_tag_offset), diff --git a/lib/src/jpegdecoderhelper.cpp b/lib/src/jpegdecoderhelper.cpp index 18e89134..1c4181c3 100644 --- a/lib/src/jpegdecoderhelper.cpp +++ b/lib/src/jpegdecoderhelper.cpp @@ -496,9 +496,9 @@ uhdr_error_info_t JpegDecoderHelper::decodeToCSYCbCr(jpeg_decompress_struct* cin JDIMENSION mcu_scanline_start[kMaxNumComponents]; for (int i = 0; i < cinfo->num_components; i++) { - mcu_scanline_start[i] = + mcu_scanline_start[i] = static_cast( std::ceil(((float)cinfo->output_scanline * cinfo->comp_info[i].v_samp_factor) / - cinfo->max_v_samp_factor); + cinfo->max_v_samp_factor)); for (int j = 0; j < cinfo->comp_info[i].v_samp_factor * DCTSIZE; j++) { JDIMENSION scanline = mcu_scanline_start[i] + j; diff --git a/lib/src/jpegencoderhelper.cpp b/lib/src/jpegencoderhelper.cpp index 998180ed..824720a9 100644 --- a/lib/src/jpegencoderhelper.cpp +++ b/lib/src/jpegencoderhelper.cpp @@ -200,7 +200,8 @@ uhdr_error_info_t JpegEncoderHelper::encode(const uint8_t* planes[3], const unsi // start compress jpeg_start_compress(&cinfo, TRUE); if (iccBuffer != nullptr && iccSize > 0) { - jpeg_write_marker(&cinfo, JPEG_APP0 + 2, static_cast(iccBuffer), iccSize); + jpeg_write_marker(&cinfo, JPEG_APP0 + 2, static_cast(iccBuffer), + static_cast(iccSize)); } if (isGainMapImg) { char comment[255]; @@ -278,9 +279,9 @@ uhdr_error_info_t JpegEncoderHelper::compressYCbCr(jpeg_compress_struct* cinfo, JDIMENSION mcu_scanline_start[kMaxNumComponents]; for (int i = 0; i < cinfo->num_components; i++) { - mcu_scanline_start[i] = + mcu_scanline_start[i] = static_cast( std::ceil(((float)cinfo->next_scanline * cinfo->comp_info[i].v_samp_factor) / - cinfo->max_v_samp_factor); + cinfo->max_v_samp_factor)); for (int j = 0; j < cinfo->comp_info[i].v_samp_factor * DCTSIZE; j++) { JDIMENSION scanline = mcu_scanline_start[i] + j; diff --git a/lib/src/jpegr.cpp b/lib/src/jpegr.cpp index 2d5d3353..e0e3d5c4 100644 --- a/lib/src/jpegr.cpp +++ b/lib/src/jpegr.cpp @@ -1603,7 +1603,7 @@ uhdr_error_info_t JpegR::applyGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_ima if (map_scale_factor != floorf(map_scale_factor)) { gain = sampleMap(gainmap_img, map_scale_factor, x, y); } else { - gain = sampleMap(gainmap_img, map_scale_factor, x, y, idwTable); + gain = sampleMap(gainmap_img, static_cast(map_scale_factor), x, y, idwTable); } #if USE_APPLY_GAIN_LUT @@ -1618,8 +1618,8 @@ uhdr_error_info_t JpegR::applyGainMap(uhdr_raw_image_t* sdr_intent, uhdr_raw_ima gain = sampleMap3Channel(gainmap_img, map_scale_factor, x, y, gainmap_img->fmt == UHDR_IMG_FMT_32bppRGBA8888); } else { - gain = sampleMap3Channel(gainmap_img, map_scale_factor, x, y, idwTable, - gainmap_img->fmt == UHDR_IMG_FMT_32bppRGBA8888); + gain = sampleMap3Channel(gainmap_img, static_cast(map_scale_factor), x, y, + idwTable, gainmap_img->fmt == UHDR_IMG_FMT_32bppRGBA8888); } #if USE_APPLY_GAIN_LUT @@ -1845,7 +1845,7 @@ GlobalTonemapOutputs globalTonemap(const std::array& rgb_in, float hea uint8_t ScaleTo8Bit(float value) { constexpr float kMaxValFloat = 255.0f; constexpr int kMaxValInt = 255; - return std::clamp(static_cast(std::round(value * kMaxValFloat)), 0, kMaxValInt); + return static_cast(std::clamp(static_cast(std::round(value * kMaxValFloat)), 0, kMaxValInt)); } uhdr_error_info_t JpegR::toneMap(uhdr_raw_image_t* hdr_intent, uhdr_raw_image_t* sdr_intent) { diff --git a/lib/src/multipictureformat.cpp b/lib/src/multipictureformat.cpp index b92b0b44..4127701e 100644 --- a/lib/src/multipictureformat.cpp +++ b/lib/src/multipictureformat.cpp @@ -69,15 +69,15 @@ std::shared_ptr generateMpf(size_t primary_image_size, size_t primar // Write the MP entries for primary image dataStruct->write32(Endian_SwapBE32(kMPEntryAttributeFormatJpeg | kMPEntryAttributeTypePrimary)); - dataStruct->write32(Endian_SwapBE32(primary_image_size)); - dataStruct->write32(Endian_SwapBE32(primary_image_offset)); + dataStruct->write32(Endian_SwapBE32(static_cast(primary_image_size))); + dataStruct->write32(Endian_SwapBE32(static_cast(primary_image_offset))); dataStruct->write16(0); dataStruct->write16(0); // Write the MP entries for secondary image dataStruct->write32(Endian_SwapBE32(kMPEntryAttributeFormatJpeg)); - dataStruct->write32(Endian_SwapBE32(secondary_image_size)); - dataStruct->write32(Endian_SwapBE32(secondary_image_offset)); + dataStruct->write32(Endian_SwapBE32(static_cast(secondary_image_size))); + dataStruct->write32(Endian_SwapBE32(static_cast(secondary_image_offset))); dataStruct->write16(0); dataStruct->write16(0);