diff --git a/Source/FreeImage/SimpleTools.cpp b/Source/FreeImage/SimpleTools.cpp index ab43980..91b3a8e 100644 --- a/Source/FreeImage/SimpleTools.cpp +++ b/Source/FreeImage/SimpleTools.cpp @@ -7,7 +7,104 @@ #include "SimpleTools.h" #include #include +#include "yato/types.h" +namespace { + +struct YuvBrightness +{ + template + inline + auto operator()(const Ty_& p, std::enable_if_t::value, void*> = nullptr) + { + return p.red; + } +}; + +template +std::tuple FindMinMax(FIBITMAP* src, BrightnessOp_ brightnessOp = BrightnessOp_{}) +{ + PixelTy_* minIt{}, * maxIt{}; + double minVal = 0.0, maxVal = 0.0; + if (src) { + const unsigned h = FreeImage_GetHeight(src); + const unsigned w = FreeImage_GetWidth(src); + const unsigned pitch = FreeImage_GetPitch(src); + uint8_t *srcLine = FreeImage_GetBits(src); + for (unsigned j = 0; j < h; ++j, srcLine += pitch) { + auto pixIt = yato::pointer_cast(srcLine); + for (unsigned i = 0; i < w; ++i, ++pixIt) { + if (IsNan(*pixIt)) { + continue; + } + const auto b = static_cast(brightnessOp(*pixIt)); + if (!minIt || !maxIt) { + minIt = maxIt = pixIt; + minVal = maxVal = b; + } + else { + if (b < minVal) { + minIt = pixIt; + minVal = b; + } + if (maxVal < b) { + maxIt = pixIt; + maxVal = b; + } + } + } + } + } + return std::make_tuple(minIt, maxIt, minVal, maxVal); +} + +template +inline constexpr +void PixelFill(PixelType_& p, const ToValueType& v) +{ + SetChannel<0>(p, v); + SetChannel<1>(p, v); + SetChannel<2>(p, v); + SetChannel<3>(p, v); +} + +template +void FindMinMaxValueImpl(FIBITMAP* src, void* out_min_value, void* out_max_value) +{ + PixelType_ minVal, maxVal; + PixelFill(minVal, std::numeric_limits>::max()); + PixelFill(maxVal, std::numeric_limits>::lowest()); + + const unsigned width = FreeImage_GetWidth(src); + const unsigned height = FreeImage_GetHeight(src); + const unsigned src_pitch = FreeImage_GetPitch(src); + + const uint8_t* src_bits = FreeImage_GetBits(src); + for (unsigned y = 0; y < height; ++y) { + auto src_pixel = yato::pointer_cast(src_bits); + for (unsigned x = 0; x < width; ++x) { + const PixelType_ val = src_pixel[x]; + SetChannel<0>(minVal, std::min(GetChannel<0>(minVal), GetChannel<0>(val))); + SetChannel<1>(minVal, std::min(GetChannel<1>(minVal), GetChannel<1>(val))); + SetChannel<2>(minVal, std::min(GetChannel<2>(minVal), GetChannel<2>(val))); + SetChannel<3>(minVal, std::min(GetChannel<3>(minVal), GetChannel<3>(val))); + SetChannel<0>(maxVal, std::max(GetChannel<0>(maxVal), GetChannel<0>(val))); + SetChannel<1>(maxVal, std::max(GetChannel<1>(maxVal), GetChannel<1>(val))); + SetChannel<2>(maxVal, std::max(GetChannel<2>(maxVal), GetChannel<2>(val))); + SetChannel<3>(maxVal, std::max(GetChannel<3>(maxVal), GetChannel<3>(val))); + } + src_bits += src_pitch; + } + + if (out_min_value) { + *static_cast(out_min_value) = minVal; + } + if (out_max_value) { + *static_cast(out_max_value) = maxVal; + } +} + +} // unnamed namespace FIBOOL DLL_CALLCONV FreeImage_FindMinMax(FIBITMAP* dib, double* min_brightness, double* max_brightness, void** min_ptr, void** max_ptr) @@ -134,47 +231,6 @@ FreeImage_FindMinMax(FIBITMAP* dib, double* min_brightness, double* max_brightne return success ? TRUE : FALSE; } -namespace -{ - - template - void FindMinMaxValueImpl(FIBITMAP* src, void* out_min_value, void* out_max_value) - { - PixelType_ minVal, maxVal; - PixelFill(minVal, std::numeric_limits>::max()); - PixelFill(maxVal, std::numeric_limits>::lowest()); - - const unsigned width = FreeImage_GetWidth(src); - const unsigned height = FreeImage_GetHeight(src); - const unsigned src_pitch = FreeImage_GetPitch(src); - - uint8_t* src_bits = FreeImage_GetBits(src); - for (unsigned y = 0; y < height; ++y) { - auto src_pixel = static_cast(static_cast(src_bits)); - for (unsigned x = 0; x < width; ++x) { - const PixelType_ val = src_pixel[x]; - SetChannel<0>(minVal, std::min(GetChannel<0>(minVal), GetChannel<0>(val))); - SetChannel<1>(minVal, std::min(GetChannel<1>(minVal), GetChannel<1>(val))); - SetChannel<2>(minVal, std::min(GetChannel<2>(minVal), GetChannel<2>(val))); - SetChannel<3>(minVal, std::min(GetChannel<3>(minVal), GetChannel<3>(val))); - SetChannel<0>(maxVal, std::max(GetChannel<0>(maxVal), GetChannel<0>(val))); - SetChannel<1>(maxVal, std::max(GetChannel<1>(maxVal), GetChannel<1>(val))); - SetChannel<2>(maxVal, std::max(GetChannel<2>(maxVal), GetChannel<2>(val))); - SetChannel<3>(maxVal, std::max(GetChannel<3>(maxVal), GetChannel<3>(val))); - } - src_bits += src_pitch; - } - - if (out_min_value) { - *static_cast(out_min_value) = minVal; - } - if (out_max_value) { - *static_cast(out_max_value) = maxVal; - } - } - -} // namespace - FIBOOL DLL_CALLCONV FreeImage_FindMinMaxValue(FIBITMAP* dib, void* min_value, void* max_value) { diff --git a/Source/FreeImage/SimpleTools.h b/Source/FreeImage/SimpleTools.h index db420ed..d912d58 100644 --- a/Source/FreeImage/SimpleTools.h +++ b/Source/FreeImage/SimpleTools.h @@ -55,7 +55,6 @@ void BitmapTransform(FIBITMAP* dst, FIBITMAP* src, UnaryOperation_ unary_op) } } - template using IsIntPixelType = std::integral_constant || @@ -102,46 +101,6 @@ namespace details template using ToValueType = typename details::ToValueTypeImpl::type; - -namespace details -{ - template - struct ToWiderTypeImpl {}; - - template <> struct ToWiderTypeImpl { using type = uint64_t; }; - template <> struct ToWiderTypeImpl { using type = int64_t; }; - template <> struct ToWiderTypeImpl { using type = uint64_t; }; - template <> struct ToWiderTypeImpl { using type = int64_t; }; - template <> struct ToWiderTypeImpl { using type = uint32_t; }; - template <> struct ToWiderTypeImpl { using type = int32_t; }; - template <> struct ToWiderTypeImpl { using type = uint32_t; }; - template <> struct ToWiderTypeImpl { using type = int32_t; }; -} - -template -using ToWiderType = typename details::ToWiderTypeImpl::type; - - -namespace details -{ - template - struct ToUnsignedTypeImpl {}; - - template <> struct ToUnsignedTypeImpl { using type = uint64_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint64_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint32_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint32_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint16_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint16_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint8_t; }; - template <> struct ToUnsignedTypeImpl { using type = uint8_t; }; -} - -template -using ToUnsignedType = typename details::ToUnsignedTypeImpl::type; - - - template using uint32_constant = std::integral_constant; @@ -159,26 +118,6 @@ template <> struct PixelChannelsNumber : public uint32_constant<3> {}; template <> struct PixelChannelsNumber : public uint32_constant<2> {}; template <> struct PixelChannelsNumber : public uint32_constant<2> {}; -namespace details -{ - template - struct ToNoAlphaTypeImpl - { - using type = PixelType_; - }; - - template <> struct ToNoAlphaTypeImpl { using type = FIRGBF; }; - template <> struct ToNoAlphaTypeImpl { using type = FIRGB32; }; - template <> struct ToNoAlphaTypeImpl { using type = FIRGB16; }; - template <> struct ToNoAlphaTypeImpl { using type = FIRGB8; }; - -} - -template -using ToNoAlphaType = typename details::ToNoAlphaTypeImpl::type; - - - template inline constexpr void SetChannel(PixelType_& p, ToValueType v) @@ -200,61 +139,6 @@ ToValueType GetChannel(const PixelType_& p, ToValueType } } -template -inline constexpr -void PixelFill(PixelType_& p, const ToValueType& v) -{ - SetChannel<0>(p, v); - SetChannel<1>(p, v); - SetChannel<2>(p, v); - SetChannel<3>(p, v); -} - -template -inline constexpr -auto PixelReduce(const PixelType_& p, ToValueType init, BinaryOperation_&& op) -{ - constexpr uint32_t channelsNumber = PixelChannelsNumber::value; - if constexpr (channelsNumber > 0) { - init = op(std::move(init), GetChannel<0>(p)); - } - if constexpr (channelsNumber > 1) { - init = op(std::move(init), GetChannel<1>(p)); - } - if constexpr (channelsNumber > 2) { - init = op(std::move(init), GetChannel<2>(p)); - } - if constexpr (channelsNumber > 3) { - init = op(std::move(init), GetChannel<3>(p)); - } - return init; -} - -template -inline constexpr -auto PixelMin(const PixelType_& p, ToValueType init = std::numeric_limits>::max()) -{ - return PixelReduce(p, init, [](const auto& lhs, const auto& rhs) { return std::min(lhs, rhs); }); -} - -template -inline constexpr -auto PixelMax(const PixelType_& p, ToValueType init = std::numeric_limits>::lowest()) -{ - return PixelReduce(p, init, [](const auto& lhs, const auto& rhs) { return std::max(lhs, rhs); }); -} - -template -inline constexpr -auto StripAlpha(PixelType_&& p) -{ - return ToNoAlphaType(std::forward(p)); -} - - - - - inline bool IsNan(float p) { return std::isnan(p); @@ -283,8 +167,6 @@ std::enable_if_t || IsIntPixelType::value, bool> Is return false; } - - struct Brightness { template @@ -302,54 +184,4 @@ struct Brightness } }; -struct YuvBrightness -{ - template - inline - auto operator()(const Ty_& p, std::enable_if_t::value, void*> = nullptr) - { - return p.red; - } -}; - - -template -std::tuple FindMinMax(FIBITMAP* src, BrightnessOp_ brightnessOp = BrightnessOp_{}) -{ - PixelTy_* minIt{}, * maxIt{}; - double minVal = 0.0, maxVal = 0.0; - if (src) { - const unsigned h = FreeImage_GetHeight(src); - const unsigned w = FreeImage_GetWidth(src); - const unsigned pitch = FreeImage_GetPitch(src); - auto srcLine = static_cast(static_cast(FreeImage_GetBits(src))); - for (unsigned j = 0; j < h; ++j, srcLine += pitch) { - auto pixIt = static_cast(static_cast(srcLine)); - for (unsigned i = 0; i < w; ++i, ++pixIt) { - if (IsNan(*pixIt)) { - continue; - } - const auto b = static_cast(brightnessOp(*pixIt)); - if (!minIt || !maxIt) { - minIt = maxIt = pixIt; - minVal = maxVal = b; - } - else { - if (b < minVal) { - minIt = pixIt; - minVal = b; - } - if (maxVal < b) { - maxIt = pixIt; - maxVal = b; - } - } - } - } - } - return std::make_tuple(minIt, maxIt, minVal, maxVal); -} - - - #endif //FREEIMAGE_SIMPLE_TOOLS_H_ diff --git a/Source/FreeImage/tmoColorConvert.cpp b/Source/FreeImage/tmoColorConvert.cpp index 993b555..ddbb80b 100644 --- a/Source/FreeImage/tmoColorConvert.cpp +++ b/Source/FreeImage/tmoColorConvert.cpp @@ -23,7 +23,6 @@ #include "FreeImage.h" #include "Utilities.h" #include "ToneMapping.h" -#include // ---------------------------------------------------------- // Convert RGB to and from Yxy, same as in Reinhard et al. SIGGRAPH 2002 diff --git a/Source/FreeImage/tmoReinhard05.cpp b/Source/FreeImage/tmoReinhard05.cpp index 6309867..2cae33d 100644 --- a/Source/FreeImage/tmoReinhard05.cpp +++ b/Source/FreeImage/tmoReinhard05.cpp @@ -23,7 +23,6 @@ #include "FreeImage.h" #include "Utilities.h" #include "ToneMapping.h" -#include // ---------------------------------------------------------- // Global and/or local tone mapping operator diff --git a/Source/FreeImageToolkit/Colors.cpp b/Source/FreeImageToolkit/Colors.cpp index d102bed..0e39f9e 100644 --- a/Source/FreeImageToolkit/Colors.cpp +++ b/Source/FreeImageToolkit/Colors.cpp @@ -41,6 +41,95 @@ // ---------------------------------------------------------- +namespace { + +template +inline constexpr +auto PixelReduce(const PixelType_& p, ToValueType init, BinaryOperation_&& op) +{ + constexpr uint32_t channelsNumber = PixelChannelsNumber::value; + if constexpr (channelsNumber > 0) { + init = op(std::move(init), GetChannel<0>(p)); + } + if constexpr (channelsNumber > 1) { + init = op(std::move(init), GetChannel<1>(p)); + } + if constexpr (channelsNumber > 2) { + init = op(std::move(init), GetChannel<2>(p)); + } + if constexpr (channelsNumber > 3) { + init = op(std::move(init), GetChannel<3>(p)); + } + return init; +} + +template +inline constexpr +auto PixelMin(const PixelType_& p, ToValueType init = std::numeric_limits>::max()) +{ + return PixelReduce(p, init, [](const auto& lhs, const auto& rhs) { return std::min(lhs, rhs); }); +} + +template +inline constexpr +auto PixelMax(const PixelType_& p, ToValueType init = std::numeric_limits>::lowest()) +{ + return PixelReduce(p, init, [](const auto& lhs, const auto& rhs) { return std::max(lhs, rhs); }); +} + +template +struct ToNoAlphaTypeImpl +{ + using type = PixelType_; +}; + +template <> struct ToNoAlphaTypeImpl { using type = FIRGBF; }; +template <> struct ToNoAlphaTypeImpl { using type = FIRGB32; }; +template <> struct ToNoAlphaTypeImpl { using type = FIRGB16; }; +template <> struct ToNoAlphaTypeImpl { using type = FIRGB8; }; + +template +using ToNoAlphaType = typename ToNoAlphaTypeImpl::type; + +template +inline constexpr +auto StripAlpha(PixelType_&& p) +{ + return ToNoAlphaType(std::forward(p)); +} + +template +struct ToWiderTypeImpl {}; + +template <> struct ToWiderTypeImpl { using type = uint64_t; }; +template <> struct ToWiderTypeImpl { using type = int64_t; }; +template <> struct ToWiderTypeImpl { using type = uint64_t; }; +template <> struct ToWiderTypeImpl { using type = int64_t; }; +template <> struct ToWiderTypeImpl { using type = uint32_t; }; +template <> struct ToWiderTypeImpl { using type = int32_t; }; +template <> struct ToWiderTypeImpl { using type = uint32_t; }; +template <> struct ToWiderTypeImpl { using type = int32_t; }; + +template +using ToWiderType = typename ToWiderTypeImpl::type; + +template +struct ToUnsignedTypeImpl {}; + +template <> struct ToUnsignedTypeImpl { using type = uint64_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint64_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint32_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint32_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint16_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint16_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint8_t; }; +template <> struct ToUnsignedTypeImpl { using type = uint8_t; }; + +template +using ToUnsignedType = typename ToUnsignedTypeImpl::type; + +} // unnamed namespace + /** @brief Inverts each pixel data. @param src Input image to be processed. diff --git a/Source/Plugins/J2KHelper.cpp b/Source/Plugins/J2KHelper.cpp index d90dd0c..a1e284c 100644 --- a/Source/Plugins/J2KHelper.cpp +++ b/Source/Plugins/J2KHelper.cpp @@ -73,15 +73,15 @@ opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, FIBOOL bRead) { if (!handle) { return nullptr; } - auto *fio = (J2KFIO_t*)malloc(sizeof(J2KFIO_t)); + std::unique_ptr fio{ new(std::nothrow) J2KFIO_t }; if (fio) { fio->io = io; fio->handle = handle; opj_stream_t *l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, bRead ? OPJ_TRUE : OPJ_FALSE); if (l_stream) { - opj_stream_set_user_data(l_stream, fio, nullptr); - opj_stream_set_user_data_length(l_stream, _LengthProc(fio)); + opj_stream_set_user_data(l_stream, fio.get(), nullptr); + opj_stream_set_user_data_length(l_stream, _LengthProc(fio.get())); opj_stream_set_read_function(l_stream, (opj_stream_read_fn)_ReadProc); opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_WriteProc); opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn)_SkipProc); @@ -89,12 +89,11 @@ opj_freeimage_stream_create(FreeImageIO *io, fi_handle handle, FIBOOL bRead) { fio->stream = l_stream; } else { - free(fio); - fio = nullptr; + fio.reset(); } } - return fio; + return fio.release(); } void @@ -103,7 +102,7 @@ opj_freeimage_stream_destroy(J2KFIO_t* fio) { if (fio->stream) { opj_stream_destroy(fio->stream); } - free(fio); + delete fio; } } diff --git a/Source/Plugins/PluginDDS.cpp b/Source/Plugins/PluginDDS.cpp index 72bbb6b..cfb52ca 100644 --- a/Source/Plugins/PluginDDS.cpp +++ b/Source/Plugins/PluginDDS.cpp @@ -23,6 +23,7 @@ #include "FreeImage.h" #include "Utilities.h" +#include "yato/types.h" // ---------------------------------------------------------- // Definitions for the RGB 444 format @@ -632,16 +633,16 @@ LoadRGB(const DDSURFACEDESC2 *desc, FreeImageIO *io, fi_handle handle) { const long delta = (long)filePitch - (long)line; if (bpp == 16) { - std::unique_ptr safePixels(malloc(line * sizeof(uint8_t)), &free); + std::unique_ptr safePixels(new(std::nothrow) uint8_t[line]); if (safePixels) { - auto *pixels = static_cast(safePixels.get()); + auto *pixels = safePixels.get(); for (int y = 0; y < height; y++) { uint8_t *dst_bits = FreeImage_GetScanLine(dib.get(), height - y - 1); // get the 16-bit RGB pixels io->read_proc(pixels, 1, line, handle); io->seek_proc(handle, delta, SEEK_CUR); // convert to 24-bit - ConvertLine16To24(dst_bits, (const uint16_t*)pixels, format16, width); + ConvertLine16To24(dst_bits, yato::pointer_cast(pixels), format16, width); } } } diff --git a/Source/Plugins/PluginHDR.cpp b/Source/Plugins/PluginHDR.cpp index ec4dd26..44bfc4e 100644 --- a/Source/Plugins/PluginHDR.cpp +++ b/Source/Plugins/PluginHDR.cpp @@ -363,7 +363,7 @@ rgbe_WritePixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpi static FIBOOL rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanline_width, unsigned num_scanlines) { - uint8_t rgbe[4], *scanline_buffer{}, *ptr, *ptr_end; + uint8_t rgbe[4]; int i, count; uint8_t buf[2]; @@ -371,7 +371,7 @@ rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanlin // run length encoding is not allowed so read flat return rgbe_ReadPixels(io, handle, data, scanline_width * num_scanlines); } - std::unique_ptr safeScanlineBuffer(nullptr, &free); + std::unique_ptr scanline_buffer; // read in each successive scanline while (num_scanlines > 0) { if (io->read_proc(rgbe, 1, sizeof(rgbe), handle) < 1) { @@ -387,17 +387,16 @@ rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanlin return rgbe_Error(rgbe_format_error,"wrong scanline width"); } if (!scanline_buffer) { - safeScanlineBuffer.reset(malloc(sizeof(uint8_t) * 4 * scanline_width)); - if (!safeScanlineBuffer) { + scanline_buffer.reset(new(std::nothrow) uint8_t[4 * scanline_width]); + if (!scanline_buffer) { return rgbe_Error(rgbe_memory_error, "unable to allocate buffer space"); } - scanline_buffer = static_cast(safeScanlineBuffer.get()); } - ptr = &scanline_buffer[0]; + uint8_t *ptr{ scanline_buffer.get() }; // read each of the four channels for the scanline into the buffer for (i = 0; i < 4; i++) { - ptr_end = &scanline_buffer[(i+1)*scanline_width]; + uint8_t *ptr_end{ &scanline_buffer[(i+1)*scanline_width] }; while (ptr < ptr_end) { if (io->read_proc(buf, 1, 2 * sizeof(uint8_t), handle) < 1) { return rgbe_Error(rgbe_read_error, nullptr); @@ -516,12 +515,11 @@ rgbe_WritePixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned s // run length encoding is not allowed so write flat return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines); } - std::unique_ptr safeBuffer(malloc(sizeof(uint8_t) * 4 * scanline_width), &free);; - if (!safeBuffer) { + std::unique_ptr buffer(new(std::nothrow) uint8_t[4 * scanline_width]);; + if (!buffer) { // no buffer space so write flat return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines); } - auto *buffer = static_cast(safeBuffer.get()); while (num_scanlines-- > 0) { rgbe[0] = (uint8_t)2; diff --git a/Source/Plugins/PluginICO.cpp b/Source/Plugins/PluginICO.cpp index 254a3f7..c40438a 100644 --- a/Source/Plugins/PluginICO.cpp +++ b/Source/Plugins/PluginICO.cpp @@ -235,21 +235,20 @@ SupportsNoPixels() { static void * DLL_CALLCONV Open(FreeImageIO *io, fi_handle handle, FIBOOL read) { // Allocate memory for the header structure - auto *lpIH = (ICONHEADER*)malloc(sizeof(ICONHEADER)); + std::unique_ptr lpIH(new(std::nothrow) ICONHEADER); if (!lpIH) { return nullptr; } if (read) { // Read in the header - io->read_proc(lpIH, 1, sizeof(ICONHEADER), handle); + io->read_proc(lpIH.get(), 1, sizeof(ICONHEADER), handle); #ifdef FREEIMAGE_BIGENDIAN - SwapIconHeader(lpIH); + SwapIconHeader(lpIH.get()); #endif if (!(lpIH->idReserved == 0) || !(lpIH->idType == 1)) { // Not an ICO file - free(lpIH); return nullptr; } } @@ -260,14 +259,14 @@ Open(FreeImageIO *io, fi_handle handle, FIBOOL read) { lpIH->idCount = 0; } - return lpIH; + return lpIH.release(); } static void DLL_CALLCONV Close(FreeImageIO *io, fi_handle handle, void *data) { // free the header structure ICONHEADER *lpIH = (ICONHEADER*)data; - free(lpIH); + delete lpIH; } // ---------------------------------------------------------- @@ -368,16 +367,15 @@ LoadStandardIcon(FreeImageIO *io, fi_handle handle, int flags, FIBOOL header_onl } int width_and = WidthBytes(width); - std::unique_ptrsafeLine(malloc(width_and), &free); - if (!safeLine) { + std::unique_ptrline_and(new(std::nothrow) uint8_t[width_and]); + if (!line_and) { return nullptr; } - auto *line_and = static_cast(safeLine.get()); //loop through each line of the AND-mask generating the alpha channel, invert XOR-mask for (int y = 0; y < height; y++) { FIRGBA8 *quad = (FIRGBA8 *)FreeImage_GetScanLine(dib.get(), y); - io->read_proc(line_and, width_and, 1, handle); + io->read_proc(line_and.get(), width_and, 1, handle); for (int x = 0; x < width; x++) { quad->alpha = (line_and[x>>3] & (0x80 >> (x & 0x07))) != 0 ? 0 : 0xFF; if ( quad->alpha == 0 ) { @@ -407,15 +405,14 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { if (icon_header) { // load the icon descriptions - std::unique_ptr safeList(malloc(icon_header->idCount * sizeof(ICONDIRENTRY)), &free); - if (!safeList) { + std::unique_ptr icon_list(new(std::nothrow) ICONDIRENTRY[icon_header->idCount]); + if (!icon_list) { return nullptr; } - auto *icon_list = static_cast(safeList.get()); io->seek_proc(handle, sizeof(ICONHEADER), SEEK_SET); - io->read_proc(icon_list, icon_header->idCount * sizeof(ICONDIRENTRY), 1, handle); + io->read_proc(icon_list.get(), icon_header->idCount * sizeof(ICONDIRENTRY), 1, handle); #ifdef FREEIMAGE_BIGENDIAN - SwapIconDirEntries(icon_list, icon_header->idCount); + SwapIconDirEntries(icon_list.get(), icon_header->idCount); #endif // load the requested icon @@ -540,12 +537,11 @@ SaveStandardIcon(FreeImageIO *io, FIBITMAP *dib, fi_handle handle) { #if defined(FREEIMAGE_BIGENDIAN) || FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_RGB } #endif - // AND mask - std::unique_ptrsafeMask(malloc(size_and), &free); - if (!safeMask) { + // empty AND mask + std::unique_ptrand_mask(new(std::nothrow) uint8_t[size_and]()); + if (!and_mask) { return FALSE; } - auto *and_mask = static_cast(safeMask.get()); if (FreeImage_IsTransparent(dib)) { @@ -553,10 +549,7 @@ SaveStandardIcon(FreeImageIO *io, FIBITMAP *dib, fi_handle handle) { // create the AND mask from the alpha channel int width_and = WidthBytes(width); - uint8_t *and_bits = and_mask; - - // clear the mask - memset(and_mask, 0, size_and); + uint8_t *and_bits = and_mask.get(); for (int y = 0; y < height; y++) { FIRGBA8 *bits = (FIRGBA8*)FreeImage_GetScanLine(dib, y); @@ -577,10 +570,7 @@ SaveStandardIcon(FreeImageIO *io, FIBITMAP *dib, fi_handle handle) { uint8_t *trns = FreeImage_GetTransparencyTable(dib); int width_and = WidthBytes(width); - uint8_t *and_bits = and_mask; - - // clear the mask - memset(and_mask, 0, size_and); + uint8_t *and_bits = and_mask.get(); switch (FreeImage_GetBPP(dib)) { case 1: @@ -638,12 +628,8 @@ SaveStandardIcon(FreeImageIO *io, FIBITMAP *dib, fi_handle handle) { } } } - else { - // empty AND mask - memset(and_mask, 0, size_and); - } - io->write_proc(and_mask, size_and, 1, handle); + io->write_proc(and_mask.get(), size_and, 1, handle); return TRUE; } @@ -705,11 +691,10 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void // save the icon descriptions - std::unique_ptr safeList(calloc(icon_header->idCount, sizeof(ICONDIRENTRY)), &free); - if (!safeList) { + std::unique_ptr icon_list(new(std::nothrow) ICONDIRENTRY[icon_header->idCount]); + if (!icon_list) { throw FI_MSG_ERROR_MEMORY; } - auto *icon_list = static_cast(safeList.get()); for (k = 0; k < icon_header->idCount; k++) { icon_dib = vPages[k].get(); @@ -734,7 +719,7 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void // make a room for icon dir entries, until later update const long directory_start = io->tell_proc(handle); - io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle); + io->write_proc(icon_list.get(), sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle); // write the image bits for each image @@ -764,9 +749,9 @@ Save(FreeImageIO *io, FIBITMAP *dib, fi_handle handle, int page, int flags, void const long current_pos = io->tell_proc(handle); io->seek_proc(handle, directory_start, SEEK_SET); #ifdef FREEIMAGE_BIGENDIAN - SwapIconDirEntries(icon_list, icon_header->idCount); + SwapIconDirEntries(icon_list.get(), icon_header->idCount); #endif - io->write_proc(icon_list, sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle); + io->write_proc(icon_list.get(), sizeof(ICONDIRENTRY) * icon_header->idCount, 1, handle); io->seek_proc(handle, current_pos, SEEK_SET); return TRUE; diff --git a/Source/Plugins/PluginJXR.cpp b/Source/Plugins/PluginJXR.cpp index e58a21d..bf8d23f 100644 --- a/Source/Plugins/PluginJXR.cpp +++ b/Source/Plugins/PluginJXR.cpp @@ -1052,7 +1052,7 @@ CopyPixels(PKImageDecode *pDecoder, PKPixelFormatGUID out_guid_format, FIBITMAP unsigned cbStrideFrom = ((pPIFrom.cbitUnit + 7) >> 3) * width; unsigned cbStrideTo = ((pPITo.cbitUnit + 7) >> 3) * width; - cbStride = MAX(cbStrideFrom, cbStrideTo); + cbStride = (std::max)(cbStrideFrom, cbStrideTo); } // allocate a local decoder / encoder buffer diff --git a/Source/Plugins/PluginPCX.cpp b/Source/Plugins/PluginPCX.cpp index aee163c..bcd15cd 100644 --- a/Source/Plugins/PluginPCX.cpp +++ b/Source/Plugins/PluginPCX.cpp @@ -454,11 +454,11 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { if (palette_id == 0x0C) { - if (std::unique_ptr cmap(malloc(768 * sizeof(uint8_t)), &free); cmap) { + if (std::unique_ptr cmap(new(std::nothrow) uint8_t[768]); cmap) { io->read_proc(cmap.get(), 768, 1, handle); pal = FreeImage_GetPalette(dib.get()); - auto *pColormap = static_cast(cmap.get()); + const auto *pColormap = cmap.get(); for (int i = 0; i < 256; i++) { pal[i].red = pColormap[0]; diff --git a/Source/Plugins/PluginPICT.cpp b/Source/Plugins/PluginPICT.cpp index 84d517c..a9e7a76 100644 --- a/Source/Plugins/PluginPICT.cpp +++ b/Source/Plugins/PluginPICT.cpp @@ -594,7 +594,7 @@ Unpack32Bits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds, } // Let's allocate enough for 4 bit planes - if (std::unique_ptr pLineBuf(malloc(rowBytes), &free); pLineBuf) { + if (std::unique_ptr pLineBuf(new(std::nothrow) uint8_t[rowBytes]); pLineBuf) { for ( int i = 0; i < height; i++ ) { // for each line do... int linelen; // length of source line in bytes. @@ -604,7 +604,7 @@ Unpack32Bits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds, linelen = Read8( io, handle); } - uint8_t* pBuf = UnpackPictRow( io, handle, static_cast(pLineBuf.get()), width, rowBytes, linelen ); + uint8_t* pBuf = UnpackPictRow( io, handle, pLineBuf.get(), width, rowBytes, linelen ); // Convert plane-oriented data into pixel-oriented data & // copy into destination bitmap. diff --git a/Source/Plugins/PluginPNG.cpp b/Source/Plugins/PluginPNG.cpp index 65f206a..6609e13 100644 --- a/Source/Plugins/PluginPNG.cpp +++ b/Source/Plugins/PluginPNG.cpp @@ -716,11 +716,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { // set the individual row_pointers to point at the correct offsets - std::unique_ptr safeRowPointers(malloc(height * sizeof(png_bytep)), &free); - if (!safeRowPointers) { + std::unique_ptr row_pointers(new(std::nothrow) png_bytep[height]); + if (!row_pointers) { return nullptr; } - auto **row_pointers = static_cast(safeRowPointers.get()); // read in the bitmap bits via the pointer table // allow loading of PNG with minor errors (such as images with several IDAT chunks) @@ -730,7 +729,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { } png_set_benign_errors(png_ptr.get(), 1); - png_read_image(png_ptr.get(), row_pointers); + png_read_image(png_ptr.get(), row_pointers.get()); // check if the bitmap contains transparency, if so enable it in the header @@ -740,8 +739,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { // cleanup - safeRowPointers.reset(); - row_pointers = nullptr; + row_pointers.reset(); // read the rest of the file, getting any additional chunks in info_ptr diff --git a/Source/Plugins/PluginTARGA.cpp b/Source/Plugins/PluginTARGA.cpp index 7aab0f8..29d13bf 100644 --- a/Source/Plugins/PluginTARGA.cpp +++ b/Source/Plugins/PluginTARGA.cpp @@ -107,7 +107,7 @@ static const char *FI_MSG_ERROR_CORRUPTED = "Image data corrupted"; class TargaThumbnail { public: - TargaThumbnail() : _data(nullptr, &free), _w(0), _h(0), _depth(0) { + TargaThumbnail() : _w(0), _h(0), _depth(0) { } FIBOOL isNull() const { @@ -119,7 +119,7 @@ class TargaThumbnail io->read_proc(&_h, 1, 1, handle); const size_t sizeofData = size - 2; - _data.reset(malloc(sizeofData)); + _data.reset(new(std::nothrow) uint8_t[sizeofData]); if (_data) { return (io->read_proc(_data.get(), 1, (unsigned)sizeofData, handle) == sizeofData); } @@ -133,7 +133,7 @@ class TargaThumbnail FIBITMAP* toFIBITMAP(); private: - std::unique_ptr _data; + std::unique_ptr _data; uint8_t _w; uint8_t _h; uint8_t _depth; @@ -175,7 +175,7 @@ FIBITMAP* TargaThumbnail::toFIBITMAP() { return nullptr; } - auto *line = static_cast(_data.get()); + auto *line = _data.get(); const uint8_t height = _h; for (uint8_t h = 0; h < height; ++h, line += line_size) { uint8_t* dst_line = FreeImage_GetScanLine(dib, height - 1 - h); diff --git a/Source/Plugins/PluginTIFF.cpp b/Source/Plugins/PluginTIFF.cpp index 9b093fe..675bf3a 100644 --- a/Source/Plugins/PluginTIFF.cpp +++ b/Source/Plugins/PluginTIFF.cpp @@ -1023,32 +1023,31 @@ SupportsNoPixels() { static void * DLL_CALLCONV Open(FreeImageIO *io, fi_handle handle, FIBOOL read) { // wrapper for TIFF I/O - auto *fio = static_cast(malloc(sizeof(fi_TIFFIO))); + auto fio{ std::make_unique() }; if (!fio) return nullptr; fio->io = io; fio->handle = handle; if (read) { - fio->tif = TIFFFdOpen((thandle_t)fio, "", "r"); + fio->tif = TIFFFdOpen((thandle_t)fio.get(), "", "r"); } else { // mode = "w" : write Classic TIFF // mode = "w8" : write Big TIFF - fio->tif = TIFFFdOpen((thandle_t)fio, "", "w"); + fio->tif = TIFFFdOpen((thandle_t)fio.get(), "", "w"); } if (!fio->tif) { - free(fio); - fio = nullptr; + fio.reset(); FreeImage_OutputMessageProc(s_format_id, "Error while opening TIFF: data is invalid"); } - return fio; + return fio.release(); } static void DLL_CALLCONV Close(FreeImageIO *io, fi_handle handle, void *data) { if (data) { - fi_TIFFIO *fio = (fi_TIFFIO*)data; + fi_TIFFIO *fio = static_cast(data); TIFFClose(fio->tif); - free(fio); + delete fio; } } diff --git a/Source/Plugins/PluginXBM.cpp b/Source/Plugins/PluginXBM.cpp index b761903..204c980 100644 --- a/Source/Plugins/PluginXBM.cpp +++ b/Source/Plugins/PluginXBM.cpp @@ -92,9 +92,9 @@ Read an XBM file into a buffer @return Returns NULL if OK, returns an error message otherwise */ static const char* -readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::unique_ptr &dataP) { +readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::unique_ptr &dataP) { std::string line(MAX_LINE, '\0'), name(MAX_LINE + 1, '\0'); - char *ptr{}; + uint8_t *ptr{}; int version = 0; size_t bytes, bytes_per_line, raster_length; int c1, c2, value1, value2; @@ -162,7 +162,7 @@ readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::u bytes_per_line = (*widthP + 7) / 8 + padding; raster_length = bytes_per_line * *heightP; - dataP.reset(malloc(raster_length)); + dataP.reset(new(std::nothrow) uint8_t[raster_length]); if (!dataP) { return ERR_XBM_MEMORY; } @@ -195,7 +195,7 @@ readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::u hex_table['f'] = 15; if (version == 10) { - for (bytes = 0, ptr = static_cast(dataP.get()); bytes < raster_length; bytes += 2) { + for (bytes = 0, ptr = dataP.get(); bytes < raster_length; bytes += 2) { while (( c1 = readChar(io, handle) ) != 'x') { if (c1 == EOF) return( ERR_XBM_EOFREAD ); @@ -215,13 +215,13 @@ readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::u value2 = ( hex_table[c1] << 4 ) + hex_table[c2]; if (value2 >= 256) return( ERR_XBM_SYNTAX ); - *ptr++ = (char)value2; + *ptr++ = (uint8_t)value2; if ((!padding) || (( bytes + 2 ) % bytes_per_line)) - *ptr++ = (char)value1; + *ptr++ = (uint8_t)value1; } } else { - for (bytes = 0, ptr = static_cast(dataP.get()); bytes < raster_length; bytes++) { + for (bytes = 0, ptr = dataP.get(); bytes < raster_length; bytes++) { /* ** skip until digit is found */ @@ -253,7 +253,7 @@ readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, std::u } else break; } - *ptr++ = (char)value1; + *ptr++ = (uint8_t)value1; } } @@ -322,7 +322,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { int width, height; try { - std::unique_ptr buffer(nullptr, &free); + std::unique_ptr buffer; // load the bitmap data const char* error = readXBMFile(io, handle, &width, &height, buffer); // Microsoft doesn't implement throw between functions :( @@ -339,7 +339,7 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { pal[1].red = pal[1].green = pal[1].blue = 255; // copy the bitmap - auto *bP = static_cast(buffer.get()); + auto *bP = buffer.get(); for (int y = 0; y < height; y++) { uint8_t count = 0; uint8_t mask = 1; diff --git a/Source/Utilities.h b/Source/Utilities.h index cbee6fb..da4c08a 100644 --- a/Source/Utilities.h +++ b/Source/Utilities.h @@ -139,11 +139,6 @@ typedef struct tagFILE_BGR { // Template utility functions // ========================================================== -/// Max function -template T MAX(const T &a, const T &b) { - return (a > b) ? a: b; -} - /** This procedure computes minimum min and maximum max of n numbers using only (3n/2) - 2 comparisons. min = L[i1] and max = L[i2].