diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/rendutil.cpp | 231 | ||||
-rw-r--r-- | src/emu/rendutil.h | 10 | ||||
-rw-r--r-- | src/frontend/mame/luaengine_render.cpp | 36 | ||||
-rw-r--r-- | src/lib/util/hash.cpp | 25 | ||||
-rw-r--r-- | src/lib/util/hash.h | 21 | ||||
-rw-r--r-- | src/lib/util/hashing.cpp | 98 | ||||
-rw-r--r-- | src/lib/util/hashing.h | 124 | ||||
-rw-r--r-- | src/lib/util/md5.cpp | 3 | ||||
-rw-r--r-- | src/lib/util/msdib.cpp | 22 | ||||
-rw-r--r-- | src/lib/util/msdib.h | 6 | ||||
-rw-r--r-- | src/lib/util/png.cpp | 170 | ||||
-rw-r--r-- | src/lib/util/png.h | 24 | ||||
-rw-r--r-- | src/osd/modules/lib/osdlib_win32.cpp | 4 |
13 files changed, 415 insertions, 359 deletions
diff --git a/src/emu/rendutil.cpp b/src/emu/rendutil.cpp index cffef8263d7..db7220351b8 100644 --- a/src/emu/rendutil.cpp +++ b/src/emu/rendutil.cpp @@ -26,18 +26,18 @@ namespace { struct jpeg_corefile_source : public jpeg_source_mgr { - static void source(j_decompress_ptr cinfo, util::random_read &file); + static void source(j_decompress_ptr cinfo, util::random_read &file) noexcept; private: static constexpr unsigned INPUT_BUF_SIZE = 4096; - static void do_init(j_decompress_ptr cinfo) + static void do_init(j_decompress_ptr cinfo) noexcept { jpeg_corefile_source &src = *static_cast<jpeg_corefile_source *>(cinfo->src); src.start_of_file = true; } - static boolean do_fill(j_decompress_ptr cinfo) + static boolean do_fill(j_decompress_ptr cinfo) noexcept { jpeg_corefile_source &src = *static_cast<jpeg_corefile_source *>(cinfo->src); @@ -61,7 +61,7 @@ private: return TRUE; } - static void do_skip(j_decompress_ptr cinfo, long num_bytes) + static void do_skip(j_decompress_ptr cinfo, long num_bytes) noexcept { jpeg_corefile_source &src = *static_cast<jpeg_corefile_source *>(cinfo->src); @@ -70,14 +70,14 @@ private: while (long(src.bytes_in_buffer) < num_bytes) { num_bytes -= long(src.bytes_in_buffer); - (void)(*src.fill_input_buffer)(cinfo); + std::ignore = (*src.fill_input_buffer)(cinfo); } src.next_input_byte += size_t(num_bytes); src.bytes_in_buffer -= size_t(num_bytes); } } - static void do_term(j_decompress_ptr cinfo) + static void do_term(j_decompress_ptr cinfo) noexcept { } @@ -86,7 +86,7 @@ private: bool start_of_file; }; -void jpeg_corefile_source::source(j_decompress_ptr cinfo, util::random_read &file) +void jpeg_corefile_source::source(j_decompress_ptr cinfo, util::random_read &file) noexcept { jpeg_corefile_source *src; if (!cinfo->src) @@ -121,7 +121,7 @@ void jpeg_corefile_source::source(j_decompress_ptr cinfo, util::random_read &fil struct jpeg_setjmp_error_mgr : public jpeg_error_mgr { - jpeg_setjmp_error_mgr() + jpeg_setjmp_error_mgr() noexcept { jpeg_std_error(this); error_exit = [] (j_common_ptr cinfo) { std::longjmp(static_cast<jpeg_setjmp_error_mgr *>(cinfo->err)->m_jump_buffer, 1); }; @@ -138,9 +138,9 @@ struct jpeg_setjmp_error_mgr : public jpeg_error_mgr ***************************************************************************/ /* utilities */ -static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy); -static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy); -static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info &png); +static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) noexcept; +static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) noexcept; +static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info &png) noexcept; @@ -153,15 +153,15 @@ static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info quality resampling of a texture -------------------------------------------------*/ -void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force) +void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force) noexcept { if (dest.width() == 0 || dest.height() == 0) return; - /* adjust the source base */ + // adjust the source base const u32 *sbase = &source.pix(0); - /* determine the steppings */ + // determine the steppings u32 swidth = source.width(); u32 sheight = source.height(); u32 dwidth = dest.width(); @@ -169,7 +169,7 @@ void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, u32 dx = (swidth << 12) / dwidth; u32 dy = (sheight << 12) / dheight; - /* if the source is higher res than the target, use full averaging */ + // if the source is higher res than the target, use full averaging if (dx > 0x1000 || dy > 0x1000 || force) resample_argb_bitmap_average(&dest.pix(0), dest.rowpixels(), dwidth, dheight, sbase, source.rowpixels(), swidth, sheight, color, dx, dy); else @@ -183,62 +183,58 @@ void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, all contributing pixels -------------------------------------------------*/ -static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) +static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) noexcept { - u64 sumscale = u64(dx) * u64(dy); - u32 r, g, b, a; - u32 x, y; - - /* precompute premultiplied R/G/B/A factors */ - r = color.r * color.a * 256.0f; - g = color.g * color.a * 256.0f; - b = color.b * color.a * 256.0f; - a = color.a * 256.0f; - - /* loop over the target vertically */ - for (y = 0; y < dheight; y++) + u64 const sumscale = u64(dx) * u64(dy); + + // precompute premultiplied R/G/B/A factors + u32 const r = color.r * color.a * 256.0f; + u32 const g = color.g * color.a * 256.0f; + u32 const b = color.b * color.a * 256.0f; + u32 const a = color.a * 256.0f; + + // loop over the target vertically + for (u32 y = 0; y < dheight; y++) { - u32 starty = y * dy; + u32 const starty = y * dy; - /* loop over the target horizontally */ - for (x = 0; x < dwidth; x++) + // loop over the target horizontally + for (u32 x = 0; x < dwidth; x++) { u64 sumr = 0, sumg = 0, sumb = 0, suma = 0; - u32 startx = x * dx; - u32 xchunk, ychunk; - u32 curx, cury; + u32 const startx = x * dx; u32 yremaining = dy; + u32 ychunk; - /* accumulate all source pixels that contribute to this pixel */ - for (cury = starty; yremaining; cury += ychunk) + // accumulate all source pixels that contribute to this pixel + for (u32 cury = starty; yremaining; cury += ychunk) { u32 xremaining = dx; + u32 xchunk; - /* determine the Y contribution, clamping to the amount remaining */ + // determine the Y contribution, clamping to the amount remaining ychunk = 0x1000 - (cury & 0xfff); if (ychunk > yremaining) ychunk = yremaining; yremaining -= ychunk; - /* loop over all source pixels in the X direction */ - for (curx = startx; xremaining; curx += xchunk) + // loop over all source pixels in the X direction + for (u32 curx = startx; xremaining; curx += xchunk) { - u32 factor; - - /* determine the X contribution, clamping to the amount remaining */ + // determine the X contribution, clamping to the amount remaining xchunk = 0x1000 - (curx & 0xfff); if (xchunk > xremaining) xchunk = xremaining; xremaining -= xchunk; - /* total contribution = x * y */ - factor = xchunk * ychunk; + // total contribution = x * y + u32 const factor = xchunk * ychunk; - /* fetch the source pixel */ - rgb_t pix = source[(cury >> 12) * srowpixels + (curx >> 12)]; + // fetch the source pixel + rgb_t const pix = source[(cury >> 12) * srowpixels + (curx >> 12)]; - /* accumulate the RGBA values */ + // accumulate the RGBA values sumr += factor * pix.r(); sumg += factor * pix.g(); sumb += factor * pix.b(); @@ -246,23 +242,23 @@ static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, } } - /* apply scaling */ + // apply scaling suma = (suma / sumscale) * a / 256; sumr = (sumr / sumscale) * r / 256; sumg = (sumg / sumscale) * g / 256; sumb = (sumb / sumscale) * b / 256; - /* if we're translucent, add in the destination pixel contribution */ + // if we're translucent, add in the destination pixel contribution if (a < 256) { - rgb_t dpix = dest[y * drowpixels + x]; + rgb_t const dpix = dest[y * drowpixels + x]; suma += dpix.a() * (256 - a); sumr += dpix.r() * (256 - a); sumg += dpix.g() * (256 - a); sumb += dpix.b() * (256 - a); } - /* store the target pixel, dividing the RGBA values by the overall scale factor */ + // store the target pixel, dividing the RGBA values by the overall scale factor dest[y * drowpixels + x] = rgb_t(suma, sumr, sumg, sumb); } } @@ -274,44 +270,37 @@ static void resample_argb_bitmap_average(u32 *dest, u32 drowpixels, u32 dwidth, sampling via a bilinear filter -------------------------------------------------*/ -static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) +static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, u32 dheight, const u32 *source, u32 srowpixels, u32 swidth, u32 sheight, const render_color &color, u32 dx, u32 dy) noexcept { - u32 maxx = swidth << 12, maxy = sheight << 12; - u32 r, g, b, a; - u32 x, y; - - /* precompute premultiplied R/G/B/A factors */ - r = color.r * color.a * 256.0f; - g = color.g * color.a * 256.0f; - b = color.b * color.a * 256.0f; - a = color.a * 256.0f; - - /* loop over the target vertically */ - for (y = 0; y < dheight; y++) + u32 const maxx = swidth << 12, maxy = sheight << 12; + + // precompute premultiplied R/G/B/A factors + u32 const r = color.r * color.a * 256.0f; + u32 const g = color.g * color.a * 256.0f; + u32 const b = color.b * color.a * 256.0f; + u32 const a = color.a * 256.0f; + + // loop over the target vertically + for (u32 y = 0; y < dheight; y++) { - u32 starty = y * dy; + u32 const starty = y * dy; - /* loop over the target horizontally */ - for (x = 0; x < dwidth; x++) + // loop over the target horizontally + for (u32 x = 0; x < dwidth; x++) { - u32 startx = x * dx; - rgb_t pix0, pix1, pix2, pix3; - u32 sumr, sumg, sumb, suma; - u32 nextx, nexty; - u32 curx, cury; - u32 factor; + u32 const startx = x * dx; - /* adjust start to the center; note that this math will tend to produce */ - /* negative results on the first pixel, which is why we clamp below */ - curx = startx + dx / 2 - 0x800; - cury = starty + dy / 2 - 0x800; + // adjust start to the center; note that this math will tend to produce + // negative results on the first pixel, which is why we clamp below + u32 curx = startx + dx / 2 - 0x800; + u32 cury = starty + dy / 2 - 0x800; - /* compute the neighboring pixel */ - nextx = curx + 0x1000; - nexty = cury + 0x1000; + // compute the neighboring pixel + u32 const nextx = curx + 0x1000; + u32 const nexty = cury + 0x1000; - /* fetch the four relevant pixels */ - pix0 = pix1 = pix2 = pix3 = 0; + // fetch the four relevant pixels + rgb_t pix0 = 0, pix1 = 0, pix2 = 0, pix3 = 0; if (s32(cury) >= 0 && cury < maxy && s32(curx) >= 0 && curx < maxx) pix0 = source[(cury >> 12) * srowpixels + (curx >> 12)]; if (s32(cury) >= 0 && cury < maxy && s32(nextx) >= 0 && nextx < maxx) @@ -321,55 +310,58 @@ static void resample_argb_bitmap_bilinear(u32 *dest, u32 drowpixels, u32 dwidth, if (s32(nexty) >= 0 && nexty < maxy && s32(nextx) >= 0 && nextx < maxx) pix3 = source[(nexty >> 12) * srowpixels + (nextx >> 12)]; - /* compute the x/y scaling factors */ + // compute the x/y scaling factors curx &= 0xfff; cury &= 0xfff; - /* contributions from pixel 0 (top,left) */ + u32 factor; + u32 sumr, sumg, sumb, suma; + + // contributions from pixel 0 (top,left) factor = (0x1000 - curx) * (0x1000 - cury); sumr = factor * pix0.r(); sumg = factor * pix0.g(); sumb = factor * pix0.b(); suma = factor * pix0.a(); - /* contributions from pixel 1 (top,right) */ + // contributions from pixel 1 (top,right) factor = curx * (0x1000 - cury); sumr += factor * pix1.r(); sumg += factor * pix1.g(); sumb += factor * pix1.b(); suma += factor * pix1.a(); - /* contributions from pixel 2 (bottom,left) */ + // contributions from pixel 2 (bottom,left) factor = (0x1000 - curx) * cury; sumr += factor * pix2.r(); sumg += factor * pix2.g(); sumb += factor * pix2.b(); suma += factor * pix2.a(); - /* contributions from pixel 3 (bottom,right) */ + // contributions from pixel 3 (bottom,right) factor = curx * cury; sumr += factor * pix3.r(); sumg += factor * pix3.g(); sumb += factor * pix3.b(); suma += factor * pix3.a(); - /* apply scaling */ + // apply scaling suma = (suma >> 24) * a / 256; sumr = (sumr >> 24) * r / 256; sumg = (sumg >> 24) * g / 256; sumb = (sumb >> 24) * b / 256; - /* if we're translucent, add in the destination pixel contribution */ + // if we're translucent, add in the destination pixel contribution if (a < 256) { - rgb_t dpix = dest[y * drowpixels + x]; + rgb_t const dpix = dest[y * drowpixels + x]; suma += dpix.a() * (256 - a); sumr += dpix.r() * (256 - a); sumg += dpix.g() * (256 - a); sumb += dpix.b() * (256 - a); } - /* store the target pixel, dividing the RGBA values by the overall scale factor */ + // store the target pixel, dividing the RGBA values by the overall scale factor dest[y * drowpixels + x] = rgb_t(suma, sumr, sumg, sumb); } } @@ -653,7 +645,7 @@ std::pair<render_bounds, render_bounds> render_line_to_quad(const render_bounds into a bitmap -------------------------------------------------*/ -void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file) +void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file) noexcept { // deallocate previous bitmap bitmap.reset(); @@ -673,7 +665,7 @@ void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file) bitmap -------------------------------------------------*/ -void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file) +void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file) noexcept { // deallocate previous bitmap bitmap.reset(); @@ -711,30 +703,39 @@ void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file) // allocates a buffer to receive the information and copy them into the bitmap row_stride = cinfo.output_width * cinfo.output_components; buffer = reinterpret_cast<JSAMPARRAY>(std::malloc(sizeof(JSAMPROW))); - buffer[0] = reinterpret_cast<JSAMPROW>(std::malloc(sizeof(JSAMPLE) * row_stride)); + if (buffer) + buffer[0] = reinterpret_cast<JSAMPROW>(std::malloc(sizeof(JSAMPLE) * row_stride)); - while (cinfo.output_scanline < cinfo.output_height) + if (bitmap.valid() && buffer && buffer[0]) { - j = cinfo.output_scanline; - jpeg_read_scanlines(&cinfo, buffer, 1); - - if (s == 1) + while (cinfo.output_scanline < cinfo.output_height) { - for (i = 0; i < w; ++i) - bitmap.pix(j, i) = rgb_t(0xff, buffer[0][i], buffer[0][i], buffer[0][i]); + j = cinfo.output_scanline; + jpeg_read_scanlines(&cinfo, buffer, 1); + if (s == 1) + { + for (i = 0; i < w; ++i) + bitmap.pix(j, i) = rgb_t(0xff, buffer[0][i], buffer[0][i], buffer[0][i]); + + } + else if (s == 3) + { + for (i = 0; i < w; ++i) + bitmap.pix(j, i) = rgb_t(0xff, buffer[0][i * s], buffer[0][i * s + 1], buffer[0][i * s + 2]); + } + else + { + osd_printf_error("Cannot read JPEG data from file.\n"); + bitmap.reset(); + break; + } } - else if (s == 3) - { - for (i = 0; i < w; ++i) - bitmap.pix(j, i) = rgb_t(0xff, buffer[0][i * s], buffer[0][i * s + 1], buffer[0][i * s + 2]); - } - else - { - osd_printf_error("Cannot read JPEG data from file.\n"); - bitmap.reset(); - break; - } + } + else + { + osd_printf_error("Error allocating memory for JPEG image.\n"); + bitmap.reset(); } // finish decompression and free the memory @@ -755,7 +756,7 @@ cleanup: bitmap -------------------------------------------------*/ -bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_as_alpha_to_existing) +bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_as_alpha_to_existing) noexcept { // deallocate if we're not overlaying alpha if (!load_as_alpha_to_existing) @@ -810,7 +811,7 @@ bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_a to the alpha channel of a bitmap -------------------------------------------------*/ -static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info &png) +static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info &png) noexcept { // FIXME: this function is basically copy/pasted from the PNG code in util, and should be unified with it u8 accumalpha = 0xff; @@ -921,7 +922,7 @@ static bool copy_png_alpha_to_bitmap(bitmap_argb32 &bitmap, const util::png_info render_detect_image - detect image format -------------------------------------------------*/ -ru_imgformat render_detect_image(util::random_read &file) +ru_imgformat render_detect_image(util::random_read &file) noexcept { // PNG: check for valid header { diff --git a/src/emu/rendutil.h b/src/emu/rendutil.h index de29ed64d2a..71e5bdc95c3 100644 --- a/src/emu/rendutil.h +++ b/src/emu/rendutil.h @@ -42,14 +42,14 @@ enum ru_imgformat /* ----- render utilities ----- */ -void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force = false); +void render_resample_argb_bitmap_hq(bitmap_argb32 &dest, bitmap_argb32 &source, const render_color &color, bool force = false) noexcept; bool render_clip_line(render_bounds &bounds, const render_bounds &clip); bool render_clip_quad(render_bounds &bounds, const render_bounds &clip, render_quad_texuv *texcoords); std::pair<render_bounds, render_bounds> render_line_to_quad(const render_bounds &bounds, float width, float length_extension); -void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file); -void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file); -bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_as_alpha_to_existing = false); -ru_imgformat render_detect_image(util::random_read &file); +void render_load_msdib(bitmap_argb32 &bitmap, util::random_read &file) noexcept; +void render_load_jpeg(bitmap_argb32 &bitmap, util::random_read &file) noexcept; +bool render_load_png(bitmap_argb32 &bitmap, util::random_read &file, bool load_as_alpha_to_existing = false) noexcept; +ru_imgformat render_detect_image(util::random_read &file) noexcept; diff --git a/src/frontend/mame/luaengine_render.cpp b/src/frontend/mame/luaengine_render.cpp index 903db9acaa1..e4286a2493f 100644 --- a/src/frontend/mame/luaengine_render.cpp +++ b/src/frontend/mame/luaengine_render.cpp @@ -16,6 +16,9 @@ #include "render.h" #include "rendlay.h" +#include "rendutil.h" + +#include "ioprocs.h" #include <algorithm> #include <atomic> @@ -733,7 +736,38 @@ void lua_engine::initialize_render(sol::table &emu) bitmap_helper<bitmap_yuy16>::make_type<bitmap16_t>(emu, "bitmap_yuy16"); bitmap_helper<bitmap_rgb32>::make_type<bitmap32_t>(emu, "bitmap_rgb32"); - bitmap_helper<bitmap_argb32>::make_type<bitmap32_t>(emu, "bitmap_argb32"); + + // ARGB32 bitmaps get extra functionality + auto bitmap_argb32_type = bitmap_helper<bitmap_argb32>::make_type<bitmap32_t>(emu, "bitmap_argb32"); + bitmap_argb32_type.set_function("load", + [] (sol::this_state s, std::string_view data) + { + auto stream(util::ram_read(data.data(), data.size())); + if (!stream) + luaL_error(s, "Error allocating stream wrapper"); + auto b = std::make_shared<bitmap_helper<bitmap_argb32> >(s, 0, 0, 0, 0); + switch (render_detect_image(*stream)) + { + case RENDUTIL_IMGFORMAT_PNG: + render_load_png(*b, *stream); + if (!b->valid()) + luaL_error(s, "Invalid or unsupported PNG data"); + break; + case RENDUTIL_IMGFORMAT_JPEG: + render_load_jpeg(*b, *stream); + if (!b->valid()) + luaL_error(s, "Invalid or unsupported PNG data"); + break; + case RENDUTIL_IMGFORMAT_MSDIB: + render_load_msdib(*b, *stream); + if (!b->valid()) + luaL_error(s, "Invalid or unsupported Microsoft DIB data"); + break; + default: + luaL_error(s, "Unsupported bitmap data format"); + } + return b; + }); auto render_texture_type = emu.new_usertype<render_texture_helper>("render_texture", sol::no_constructor); render_texture_type.set_function("free", &render_texture_helper::free); diff --git a/src/lib/util/hash.cpp b/src/lib/util/hash.cpp index 8cdf41ba0e9..9100ff6abde 100644 --- a/src/lib/util/hash.cpp +++ b/src/lib/util/hash.cpp @@ -38,7 +38,7 @@ class hash_collection::hash_creator { public: // constructor - hash_creator(bool doing_crc32, bool doing_sha1) + hash_creator(bool doing_crc32, bool doing_sha1) noexcept { if (doing_crc32) m_crc32_creator.emplace(); @@ -47,7 +47,7 @@ public: } // add the given buffer to the hash - void append(void const *buffer, std::size_t length) + void append(void const *buffer, std::size_t length) noexcept { // append to each active hash if (m_crc32_creator) @@ -57,7 +57,7 @@ public: } // stop hashing - void finish(hash_collection &hashes) + void finish(hash_collection &hashes) noexcept { // finish up the CRC32 if (m_crc32_creator) @@ -112,15 +112,16 @@ hash_collection &hash_collection::operator=(const hash_collection &src) // operator== - test for equality //------------------------------------------------- -bool hash_collection::operator==(const hash_collection &rhs) const +bool hash_collection::operator==(const hash_collection &rhs) const noexcept { + bool matches = false; + // match CRCs - int matches = 0; if (m_has_crc32 && rhs.m_has_crc32) { if (m_crc32 != rhs.m_crc32) return false; - matches++; + matches = true; } // match SHA1s @@ -128,11 +129,11 @@ bool hash_collection::operator==(const hash_collection &rhs) const { if (m_sha1 != rhs.m_sha1) return false; - matches++; + matches = true; } - // if all shared hashes match, return true - return (matches > 0); + // if at least one type is shared and matches, return true + return matches; } @@ -157,7 +158,7 @@ std::string hash_collection::hash_types() const // set of hashes and flags //------------------------------------------------- -void hash_collection::reset() +void hash_collection::reset() noexcept { m_flags.clear(); m_has_crc32 = m_has_sha1 = false; @@ -169,7 +170,7 @@ void hash_collection::reset() // from a string //------------------------------------------------- -bool hash_collection::add_from_string(char type, std::string_view string) +bool hash_collection::add_from_string(char type, std::string_view string) noexcept { // handle CRCs if (type == HASH_CRC) @@ -187,7 +188,7 @@ bool hash_collection::add_from_string(char type, std::string_view string) // remove - remove a hash of the given type //------------------------------------------------- -bool hash_collection::remove(char type) +bool hash_collection::remove(char type) noexcept { bool result = false; diff --git a/src/lib/util/hash.h b/src/lib/util/hash.h index 5fa4f787097..bd111224e6f 100644 --- a/src/lib/util/hash.h +++ b/src/lib/util/hash.h @@ -34,6 +34,7 @@ namespace util { + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -68,25 +69,25 @@ public: // operators hash_collection &operator=(const hash_collection &src); - bool operator==(const hash_collection &rhs) const; - bool operator!=(const hash_collection &rhs) const { return !(*this == rhs); } + bool operator==(const hash_collection &rhs) const noexcept; + bool operator!=(const hash_collection &rhs) const noexcept { return !(*this == rhs); } // getters - bool flag(char flag) const { return (m_flags.find_first_of(flag) != std::string::npos); } + bool flag(char flag) const noexcept { return (m_flags.find_first_of(flag) != std::string::npos); } std::string hash_types() const; // hash manipulators - void reset(); - bool add_from_string(char type, std::string_view string); - bool remove(char type); + void reset() noexcept; + bool add_from_string(char type, std::string_view string) noexcept; + bool remove(char type) noexcept; // CRC-specific helpers - bool crc(uint32_t &result) const { result = m_crc32; return m_has_crc32; } - void add_crc(uint32_t crc) { m_crc32 = crc; m_has_crc32 = true; } + bool crc(uint32_t &result) const noexcept { result = m_crc32; return m_has_crc32; } + void add_crc(uint32_t crc) noexcept { m_crc32 = crc; m_has_crc32 = true; } // SHA1-specific helpers - bool sha1(sha1_t &result) const { result = m_sha1; return m_has_sha1; } - void add_sha1(sha1_t sha1) { m_has_sha1 = true; m_sha1 = sha1; } + bool sha1(sha1_t &result) const noexcept { result = m_sha1; return m_has_sha1; } + void add_sha1(sha1_t sha1) noexcept { m_has_sha1 = true; m_sha1 = sha1; } // string conversion std::string internal_string() const; diff --git a/src/lib/util/hashing.cpp b/src/lib/util/hashing.cpp index 62447c7b6c0..3410389fdc8 100644 --- a/src/lib/util/hashing.cpp +++ b/src/lib/util/hashing.cpp @@ -9,12 +9,14 @@ ***************************************************************************/ #include "hashing.h" + #include "strformat.h" #include "eminline.h" #include <zlib.h> +#include <algorithm> #include <iomanip> #include <sstream> @@ -42,7 +44,7 @@ constexpr int char_to_hex(char c) } -inline uint32_t sha1_b(uint32_t *data, unsigned i) +inline uint32_t sha1_b(uint32_t *data, unsigned i) noexcept { uint32_t r = data[(i + 13) & 15U]; r ^= data[(i + 8) & 15U]; @@ -53,37 +55,37 @@ inline uint32_t sha1_b(uint32_t *data, unsigned i) return r; } -inline void sha1_r0(const uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r0(const uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + ((d[(i + 3) % 5] & (d[(i + 2) % 5] ^ d[(i + 1) % 5])) ^ d[(i + 1) % 5]) + data[i] + 0x5a827999U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r1(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r1(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + ((d[(i + 3) % 5] & (d[(i + 2) % 5] ^ d[(i + 1) % 5])) ^ d[(i + 1) % 5])+ sha1_b(data, i) + 0x5a827999U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r2(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r2(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (d[(i + 3) % 5] ^ d[(i + 2) % 5] ^ d[(i + 1) % 5]) + sha1_b(data, i) + 0x6ed9eba1U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r3(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r3(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (((d[(i + 3) % 5] | d[(i + 2) % 5]) & d[(i + 1) % 5]) | (d[(i + 3) % 5] & d[(i + 2) % 5])) + sha1_b(data, i) + 0x8f1bbcdcU + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r4(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r4(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (d[(i + 3) % 5] ^ d[(i + 2) % 5] ^ d[(i + 1) % 5]) + sha1_b(data, i) + 0xca62c1d6U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_process(std::array<uint32_t, 5> &st, uint32_t *data) +inline void sha1_process(std::array<uint32_t, 5> &st, uint32_t *data) noexcept { std::array<uint32_t, 5> d = st; unsigned i = 0U; @@ -125,18 +127,18 @@ const sum16_t sum16_t::null = { 0 }; // from_string - convert from a string //------------------------------------------------- -bool sha1_t::from_string(std::string_view string) +bool sha1_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything - memset(m_raw, 0, sizeof(m_raw)); + std::fill(std::begin(m_raw), std::end(m_raw), 0); if (string.length() < 2 * sizeof(m_raw)) return false; // iterate through our raw buffer - for (auto & elem : m_raw) + for (auto &elem : m_raw) { - int upper = char_to_hex(string[0]); - int lower = char_to_hex(string[1]); + int const upper = char_to_hex(string[0]); + int const lower = char_to_hex(string[1]); if (upper == -1 || lower == -1) return false; elem = (upper << 4) | lower; @@ -152,12 +154,16 @@ bool sha1_t::from_string(std::string_view string) std::string sha1_t::as_string() const { - std::ostringstream buffer; - buffer.fill('0'); - buffer << std::hex; - for (auto & elem : m_raw) - buffer << std::setw(2) << unsigned(elem); - return buffer.str(); + std::string result(2 * std::size(m_raw), ' '); + auto it = result.begin(); + for (auto const &elem : m_raw) + { + auto const upper = elem >> 4; + auto const lower = elem & 0x0f; + *it++ = ((10 > upper) ? '0' : ('a' - 10)) + upper; + *it++ = ((10 > lower) ? '0' : ('a' - 10)) + lower; + } + return result; } @@ -165,7 +171,7 @@ std::string sha1_t::as_string() const // reset - prepare to digest a block of data //------------------------------------------------- -void sha1_creator::reset() +void sha1_creator::reset() noexcept { m_cnt = 0U; m_st[0] = 0xc3d2e1f0U; @@ -180,7 +186,7 @@ void sha1_creator::reset() // append - digest a block of data //------------------------------------------------- -void sha1_creator::append(const void *data, uint32_t length) +void sha1_creator::append(const void *data, uint32_t length) noexcept { #ifdef LSB_FIRST constexpr unsigned swizzle = 3U; @@ -215,7 +221,7 @@ void sha1_creator::append(const void *data, uint32_t length) // finish - compute final hash //------------------------------------------------- -sha1_t sha1_creator::finish() +sha1_t sha1_creator::finish() noexcept { const unsigned padlen = 64U - (63U & ((unsigned(m_cnt) >> 3) + 8U)); uint8_t padbuf[64]; @@ -243,18 +249,18 @@ sha1_t sha1_creator::finish() // from_string - convert from a string //------------------------------------------------- -bool md5_t::from_string(std::string_view string) +bool md5_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything - memset(m_raw, 0, sizeof(m_raw)); + std::fill(std::begin(m_raw), std::end(m_raw), 0); if (string.length() < 2 * sizeof(m_raw)) return false; // iterate through our raw buffer - for (auto & elem : m_raw) + for (auto &elem : m_raw) { - int upper = char_to_hex(string[0]); - int lower = char_to_hex(string[1]); + int const upper = char_to_hex(string[0]); + int const lower = char_to_hex(string[1]); if (upper == -1 || lower == -1) return false; elem = (upper << 4) | lower; @@ -270,12 +276,16 @@ bool md5_t::from_string(std::string_view string) std::string md5_t::as_string() const { - std::ostringstream buffer; - buffer.fill('0'); - buffer << std::hex; - for (auto & elem : m_raw) - buffer << std::setw(2) << unsigned(elem); - return buffer.str(); + std::string result(2 * std::size(m_raw), ' '); + auto it = result.begin(); + for (auto const &elem : m_raw) + { + auto const upper = elem >> 4; + auto const lower = elem & 0x0f; + *it++ = ((10 > upper) ? '0' : ('a' - 10)) + upper; + *it++ = ((10 > lower) ? '0' : ('a' - 10)) + lower; + } + return result; } @@ -288,18 +298,18 @@ std::string md5_t::as_string() const // from_string - convert from a string //------------------------------------------------- -bool crc32_t::from_string(std::string_view string) +bool crc32_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -324,7 +334,7 @@ std::string crc32_t::as_string() const // the currently-accumulated value //------------------------------------------------- -void crc32_creator::append(const void *data, uint32_t length) +void crc32_creator::append(const void *data, uint32_t length) noexcept { m_accum.m_raw = crc32(m_accum, reinterpret_cast<const Bytef *>(data), length); } @@ -339,18 +349,18 @@ void crc32_creator::append(const void *data, uint32_t length) // from_string - convert from a string //------------------------------------------------- -bool crc16_t::from_string(std::string_view string) +bool crc16_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -385,7 +395,7 @@ std::string crc16_t::as_string() const * @param length The length. */ -void crc16_creator::append(const void *data, uint32_t length) +void crc16_creator::append(const void *data, uint32_t length) noexcept { static const uint16_t s_table[256] = { @@ -442,18 +452,18 @@ void crc16_creator::append(const void *data, uint32_t length) // from_string - convert from a string //------------------------------------------------- -bool sum16_t::from_string(std::string_view string) +bool sum16_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -488,7 +498,7 @@ std::string sum16_t::as_string() const * @param length The length. */ -void sum16_creator::append(const void *data, uint32_t length) +void sum16_creator::append(const void *data, uint32_t length) noexcept { const auto *src = reinterpret_cast<const uint8_t *>(data); diff --git a/src/lib/util/hashing.h b/src/lib/util/hashing.h index 6cd73ac1846..c57d403de1b 100644 --- a/src/lib/util/hashing.h +++ b/src/lib/util/hashing.h @@ -34,10 +34,10 @@ namespace util { // final digest struct sha1_t { - bool operator==(const sha1_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; } - bool operator!=(const sha1_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } - operator uint8_t *() { return m_raw; } - bool from_string(std::string_view string); + bool operator==(const sha1_t &rhs) const noexcept { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; } + bool operator!=(const sha1_t &rhs) const noexcept { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } + operator uint8_t *() noexcept { return m_raw; } + bool from_string(std::string_view string) noexcept; std::string as_string() const; uint8_t m_raw[20]; static const sha1_t null; @@ -48,19 +48,19 @@ class sha1_creator { public: // construction/destruction - sha1_creator() { reset(); } + sha1_creator() noexcept { reset(); } // reset - void reset(); + void reset() noexcept; // append data - void append(const void *data, uint32_t length); + void append(const void *data, uint32_t length) noexcept; // finalize and compute the final digest - sha1_t finish(); + sha1_t finish() noexcept; // static wrapper to just get the digest from a block - static sha1_t simple(const void *data, uint32_t length) + static sha1_t simple(const void *data, uint32_t length) noexcept { sha1_creator creator; creator.append(data, length); @@ -80,10 +80,10 @@ protected: // final digest struct md5_t { - bool operator==(const md5_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; } - bool operator!=(const md5_t &rhs) const { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } - operator uint8_t *() { return m_raw; } - bool from_string(std::string_view string); + bool operator==(const md5_t &rhs) const noexcept { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) == 0; } + bool operator!=(const md5_t &rhs) const noexcept { return memcmp(m_raw, rhs.m_raw, sizeof(m_raw)) != 0; } + operator uint8_t *() noexcept { return m_raw; } + bool from_string(std::string_view string) noexcept; std::string as_string() const; uint8_t m_raw[16]; static const md5_t null; @@ -94,16 +94,16 @@ class md5_creator { public: // construction/destruction - md5_creator() { reset(); } + md5_creator() noexcept { reset(); } // reset - void reset() { MD5Init(&m_context); } + void reset() noexcept { MD5Init(&m_context); } // append data - void append(const void *data, uint32_t length) { MD5Update(&m_context, reinterpret_cast<const unsigned char *>(data), length); } + void append(const void *data, uint32_t length) noexcept { MD5Update(&m_context, reinterpret_cast<const unsigned char *>(data), length); } // finalize and compute the final digest - md5_t finish() + md5_t finish() noexcept { md5_t result; MD5Final(result.m_raw, &m_context); @@ -111,7 +111,7 @@ public: } // static wrapper to just get the digest from a block - static md5_t simple(const void *data, uint32_t length) + static md5_t simple(const void *data, uint32_t length) noexcept { md5_creator creator; creator.append(data, length); @@ -130,19 +130,19 @@ protected: // final digest struct crc32_t { - crc32_t() { } - constexpr crc32_t(const crc32_t &rhs) = default; - constexpr crc32_t(const uint32_t crc) : m_raw(crc) { } + crc32_t() noexcept { } + constexpr crc32_t(const crc32_t &rhs) noexcept = default; + constexpr crc32_t(const uint32_t crc) noexcept : m_raw(crc) { } - constexpr bool operator==(const crc32_t &rhs) const { return m_raw == rhs.m_raw; } - constexpr bool operator!=(const crc32_t &rhs) const { return m_raw != rhs.m_raw; } + constexpr bool operator==(const crc32_t &rhs) const noexcept { return m_raw == rhs.m_raw; } + constexpr bool operator!=(const crc32_t &rhs) const noexcept { return m_raw != rhs.m_raw; } - crc32_t &operator=(const crc32_t &rhs) = default; - crc32_t &operator=(const uint32_t crc) { m_raw = crc; return *this; } + crc32_t &operator=(const crc32_t &rhs) noexcept = default; + crc32_t &operator=(const uint32_t crc) noexcept { m_raw = crc; return *this; } - constexpr operator uint32_t() const { return m_raw; } + constexpr operator uint32_t() const noexcept { return m_raw; } - bool from_string(std::string_view string); + bool from_string(std::string_view string) noexcept; std::string as_string() const; uint32_t m_raw; @@ -155,19 +155,19 @@ class crc32_creator { public: // construction/destruction - crc32_creator() { reset(); } + crc32_creator() noexcept { reset(); } // reset - void reset() { m_accum.m_raw = 0; } + void reset() noexcept { m_accum.m_raw = 0; } // append data - void append(const void *data, uint32_t length); + void append(const void *data, uint32_t length) noexcept; // finalize and compute the final digest - crc32_t finish() { return m_accum; } + crc32_t finish() noexcept { return m_accum; } // static wrapper to just get the digest from a block - static crc32_t simple(const void *data, uint32_t length) + static crc32_t simple(const void *data, uint32_t length) noexcept { crc32_creator creator; creator.append(data, length); @@ -186,19 +186,19 @@ protected: // final digest struct crc16_t { - crc16_t() { } - constexpr crc16_t(const crc16_t &rhs) = default; - constexpr crc16_t(const uint16_t crc) : m_raw(crc) { } + crc16_t() noexcept { } + constexpr crc16_t(const crc16_t &rhs) noexcept = default; + constexpr crc16_t(const uint16_t crc) noexcept : m_raw(crc) { } - constexpr bool operator==(const crc16_t &rhs) const { return m_raw == rhs.m_raw; } - constexpr bool operator!=(const crc16_t &rhs) const { return m_raw != rhs.m_raw; } + constexpr bool operator==(const crc16_t &rhs) const noexcept { return m_raw == rhs.m_raw; } + constexpr bool operator!=(const crc16_t &rhs) const noexcept { return m_raw != rhs.m_raw; } - crc16_t &operator=(const crc16_t &rhs) = default; - crc16_t &operator=(const uint16_t crc) { m_raw = crc; return *this; } + crc16_t &operator=(const crc16_t &rhs) noexcept = default; + crc16_t &operator=(const uint16_t crc) noexcept { m_raw = crc; return *this; } - constexpr operator uint16_t() const { return m_raw; } + constexpr operator uint16_t() const noexcept { return m_raw; } - bool from_string(std::string_view string); + bool from_string(std::string_view string) noexcept; std::string as_string() const; uint16_t m_raw; @@ -211,19 +211,19 @@ class crc16_creator { public: // construction/destruction - crc16_creator() { reset(); } + crc16_creator() noexcept { reset(); } // reset - void reset() { m_accum.m_raw = 0xffff; } + void reset() noexcept { m_accum.m_raw = 0xffff; } // append data - void append(const void *data, uint32_t length); + void append(const void *data, uint32_t length) noexcept; // finalize and compute the final digest - crc16_t finish() { return m_accum; } + crc16_t finish() noexcept { return m_accum; } // static wrapper to just get the digest from a block - static crc16_t simple(const void *data, uint32_t length) + static crc16_t simple(const void *data, uint32_t length) noexcept { crc16_creator creator; creator.append(data, length); @@ -242,19 +242,19 @@ protected: // final digest struct sum16_t { - sum16_t() { } - constexpr sum16_t(const sum16_t &rhs) = default; - constexpr sum16_t(const uint16_t sum) : m_raw(sum) { } + sum16_t() noexcept { } + constexpr sum16_t(const sum16_t &rhs) noexcept = default; + constexpr sum16_t(const uint16_t sum) noexcept : m_raw(sum) { } - constexpr bool operator==(const sum16_t &rhs) const { return m_raw == rhs.m_raw; } - constexpr bool operator!=(const sum16_t &rhs) const { return m_raw != rhs.m_raw; } + constexpr bool operator==(const sum16_t &rhs) const noexcept { return m_raw == rhs.m_raw; } + constexpr bool operator!=(const sum16_t &rhs) const noexcept { return m_raw != rhs.m_raw; } - sum16_t &operator=(const sum16_t &rhs) = default; - sum16_t &operator=(const uint16_t sum) { m_raw = sum; return *this; } + sum16_t &operator=(const sum16_t &rhs) noexcept = default; + sum16_t &operator=(const uint16_t sum) noexcept { m_raw = sum; return *this; } - constexpr operator uint16_t() const { return m_raw; } + constexpr operator uint16_t() const noexcept { return m_raw; } - bool from_string(std::string_view string); + bool from_string(std::string_view string) noexcept; std::string as_string() const; uint16_t m_raw; @@ -267,19 +267,19 @@ class sum16_creator { public: // construction/destruction - sum16_creator() { reset(); } + sum16_creator() noexcept { reset(); } // reset - void reset() { m_accum.m_raw = 0; } + void reset() noexcept { m_accum.m_raw = 0; } // append data - void append(const void *data, uint32_t length); + void append(const void *data, uint32_t length) noexcept; // finalize and compute the final digest - sum16_t finish() { return m_accum; } + sum16_t finish() noexcept { return m_accum; } // static wrapper to just get the digest from a block - static sum16_t simple(const void *data, uint32_t length) + static sum16_t simple(const void *data, uint32_t length) noexcept { sum16_creator creator; creator.append(data, length); @@ -299,14 +299,14 @@ template <> struct hash<::util::crc32_t> { typedef ::util::crc32_t argument_type; typedef std::size_t result_type; - result_type operator()(argument_type const & s) const { return std::hash<std::uint32_t>()(s); } + result_type operator()(argument_type const &s) const noexcept { return std::hash<std::uint32_t>()(s); } }; template <> struct hash<::util::crc16_t> { typedef ::util::crc16_t argument_type; typedef std::size_t result_type; - result_type operator()(argument_type const & s) const { return std::hash<std::uint16_t>()(s); } + result_type operator()(argument_type const &s) const noexcept { return std::hash<std::uint16_t>()(s); } }; } // namespace std diff --git a/src/lib/util/md5.cpp b/src/lib/util/md5.cpp index 3e26d0c5b07..ca36792220e 100644 --- a/src/lib/util/md5.cpp +++ b/src/lib/util/md5.cpp @@ -22,9 +22,10 @@ * Still in the public domain. */ +#include "md5.h" + #include <cstring> /* for memcpy() */ -#include "md5.h" #ifndef LSB_FIRST void diff --git a/src/lib/util/msdib.cpp b/src/lib/util/msdib.cpp index 6ce0e0fd990..7b537fdae61 100644 --- a/src/lib/util/msdib.cpp +++ b/src/lib/util/msdib.cpp @@ -93,7 +93,7 @@ union bitmap_headers }; -bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits) +bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits) noexcept { shift = count_leading_zeros_32(mask); mask <<= shift; @@ -104,7 +104,7 @@ bool dib_parse_mask(std::uint32_t mask, unsigned &shift, unsigned &bits) } -void dib_truncate_channel(unsigned &shift, unsigned &bits) +void dib_truncate_channel(unsigned &shift, unsigned &bits) noexcept { if (8U < bits) { @@ -115,7 +115,7 @@ void dib_truncate_channel(unsigned &shift, unsigned &bits) } -std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits) +std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits) noexcept { assert(8U >= bits); for (val <<= (8U - bits); bits && (8U > bits); bits <<= 1) @@ -124,7 +124,7 @@ std::uint8_t dib_splat_sample(std::uint8_t val, unsigned bits) } -msdib_error dib_read_file_header(read_stream &fp, std::uint32_t &filelen) +msdib_error dib_read_file_header(read_stream &fp, std::uint32_t &filelen) noexcept { std::size_t actual; @@ -172,7 +172,7 @@ msdib_error dib_read_bitmap_header( std::size_t &palette_entries, std::size_t &palette_size, std::size_t &row_bytes, - std::uint32_t length) + std::uint32_t length) noexcept { std::size_t actual; @@ -397,7 +397,7 @@ msdib_error dib_read_bitmap_header( -msdib_error msdib_verify_header(random_read &fp) +msdib_error msdib_verify_header(random_read &fp) noexcept { msdib_error err; @@ -438,7 +438,7 @@ msdib_error msdib_verify_header(random_read &fp) } -msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) +msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) noexcept { std::uint32_t file_length; msdib_error const headerr(dib_read_file_header(fp, file_length)); @@ -449,7 +449,7 @@ msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) } -msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight) +msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight) noexcept { // read the bitmap header std::size_t actual; @@ -570,11 +570,15 @@ msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std:: dib_truncate_channel(alpha_shift, alpha_bits); } - // allocate the bitmap and process row data + // allocate a row buffer as well as the destination bitmap std::unique_ptr<std::uint8_t []> row_data(new (std::nothrow) std::uint8_t [row_bytes]); if (!row_data) return msdib_error::OUT_OF_MEMORY; bitmap.allocate(header.info.width, header.info.height); + if (!bitmap.valid()) + return msdib_error::OUT_OF_MEMORY; + + // process row data int const y_inc(top_down ? 1 : -1); for (std::int32_t i = 0, y = top_down ? 0 : (header.info.height - 1); header.info.height > i; ++i, y += y_inc) { diff --git a/src/lib/util/msdib.h b/src/lib/util/msdib.h index 8d8a9078c5b..fb6697c2eb6 100644 --- a/src/lib/util/msdib.h +++ b/src/lib/util/msdib.h @@ -36,9 +36,9 @@ enum class msdib_error UNSUPPORTED_FORMAT }; -msdib_error msdib_verify_header(random_read &fp); -msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap); -msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight = 0U); +msdib_error msdib_verify_header(random_read &fp) noexcept; +msdib_error msdib_read_bitmap(random_read &fp, bitmap_argb32 &bitmap) noexcept; +msdib_error msdib_read_bitmap_data(random_read &fp, bitmap_argb32 &bitmap, std::uint32_t length, std::uint32_t dirheight = 0U) noexcept; } // namespace util diff --git a/src/lib/util/png.cpp b/src/lib/util/png.cpp index e2fc9aecfe7..8e077f92114 100644 --- a/src/lib/util/png.cpp +++ b/src/lib/util/png.cpp @@ -37,7 +37,7 @@ namespace util { pnginfo structure -------------------------------------------------*/ -void png_info::free_data() +void png_info::free_data() noexcept { textlist.clear(); palette.reset(); @@ -94,15 +94,15 @@ constexpr std::uint8_t PNG_PF_Paeth = 4; INLINE FUNCTIONS ***************************************************************************/ -inline int compute_rowbytes(const png_info &pnginfo) { return (pnginfo.width * samples[pnginfo.color_type] * pnginfo.bit_depth + 7) / 8; } +inline int compute_rowbytes(const png_info &pnginfo) noexcept { return (pnginfo.width * samples[pnginfo.color_type] * pnginfo.bit_depth + 7) / 8; } -inline uint8_t fetch_8bit(uint8_t const *v) { return *v; } -inline uint16_t fetch_16bit(uint8_t const *v) { return big_endianize_int16(*reinterpret_cast<uint16_t const *>(v)); } -inline uint32_t fetch_32bit(uint8_t const *v) { return big_endianize_int32(*reinterpret_cast<uint32_t const *>(v)); } +inline uint8_t fetch_8bit(uint8_t const *v) noexcept { return *v; } +inline uint16_t fetch_16bit(uint8_t const *v) noexcept { return big_endianize_int16(*reinterpret_cast<uint16_t const *>(v)); } +inline uint32_t fetch_32bit(uint8_t const *v) noexcept { return big_endianize_int32(*reinterpret_cast<uint32_t const *>(v)); } -inline void put_8bit(uint8_t *v, uint8_t data) { *v = data; } -inline void put_16bit(uint8_t *v, uint16_t data) { *reinterpret_cast<uint16_t *>(v) = big_endianize_int16(data); } -inline void put_32bit(uint8_t *v, uint32_t data) { *reinterpret_cast<uint32_t *>(v) = big_endianize_int32(data); } +inline void put_8bit(uint8_t *v, uint8_t data) noexcept { *v = data; } +inline void put_16bit(uint8_t *v, uint16_t data) noexcept { *reinterpret_cast<uint16_t *>(v) = big_endianize_int16(data); } +inline void put_32bit(uint8_t *v, uint32_t data) noexcept { *reinterpret_cast<uint32_t *>(v) = big_endianize_int32(data); } /*************************************************************************** @@ -149,13 +149,13 @@ private: struct image_data_chunk { - image_data_chunk(std::uint32_t l, std::unique_ptr<std::uint8_t []> &&d) : length(l), data(std::move(d)) { } + image_data_chunk(std::uint32_t l, std::unique_ptr<std::uint8_t []> &&d) noexcept : length(l), data(std::move(d)) { } std::uint32_t length; std::unique_ptr<std::uint8_t []> data; }; - std::error_condition process(std::list<image_data_chunk> const &idata) + std::error_condition process(std::list<image_data_chunk> const &idata) noexcept { // do some basic checks for unsupported images if (!pnginfo.bit_depth || (std::size(samples) <= pnginfo.color_type) || !samples[pnginfo.color_type]) @@ -206,7 +206,7 @@ private: return error; } - std::error_condition decompress(std::list<image_data_chunk> const &idata, std::uint32_t expected) + std::error_condition decompress(std::list<image_data_chunk> const &idata, std::uint32_t expected) noexcept { // only deflate is permitted if (0 != pnginfo.compression_method) @@ -254,7 +254,7 @@ private: return png_error::DECOMPRESS_ERROR; // TODO: refactor this function for more fine-grained error reporting? } - std::error_condition unfilter_row(std::uint8_t type, uint8_t const *src, uint8_t *dst, uint8_t const *dstprev, int bpp, std::uint32_t rowbytes) + std::error_condition unfilter_row(std::uint8_t type, uint8_t const *src, uint8_t *dst, uint8_t const *dstprev, int bpp, std::uint32_t rowbytes) noexcept { if (0 != pnginfo.filter_method) return png_error::UNKNOWN_FILTER; @@ -320,7 +320,7 @@ private: } } - std::error_condition process_chunk(std::list<image_data_chunk> &idata, std::unique_ptr<std::uint8_t []> &&data, uint32_t type, uint32_t length) + std::error_condition process_chunk(std::list<image_data_chunk> &idata, std::unique_ptr<std::uint8_t []> &&data, uint32_t type, uint32_t length) noexcept { switch (type) { @@ -406,12 +406,12 @@ private: return std::error_condition(); } - unsigned get_pass_count() const + unsigned get_pass_count() const noexcept { return (1 == pnginfo.interlace_method) ? 7 : 1; } - std::pair<uint32_t, uint32_t> get_pass_dimensions(unsigned pass) const + std::pair<uint32_t, uint32_t> get_pass_dimensions(unsigned pass) const noexcept { if (0 == pnginfo.interlace_method) return std::make_pair(pnginfo.width, pnginfo.height); @@ -419,39 +419,39 @@ private: return std::make_pair((pnginfo.width + ADAM7_X_BIAS[pass]) >> ADAM7_X_SHIFT[pass], (pnginfo.height + ADAM7_Y_BIAS[pass]) >> ADAM7_Y_SHIFT[pass]); } - std::uint32_t get_pass_bytes(unsigned pass) const + std::uint32_t get_pass_bytes(unsigned pass) const noexcept { return get_pass_bytes(pass, pnginfo.bit_depth); } - std::uint32_t get_pass_bytes(unsigned pass, uint8_t bit_depth) const + std::uint32_t get_pass_bytes(unsigned pass, uint8_t bit_depth) const noexcept { std::pair<std::uint32_t, std::uint32_t> const dimensions(get_pass_dimensions(pass)); return (get_row_bytes(dimensions.first, bit_depth) + 1) * dimensions.second; } - std::uint32_t get_row_bytes(std::uint32_t width) const + std::uint32_t get_row_bytes(std::uint32_t width) const noexcept { return get_row_bytes(width, pnginfo.bit_depth); } - std::uint32_t get_row_bytes(std::uint32_t width, uint8_t bit_depth) const + std::uint32_t get_row_bytes(std::uint32_t width, uint8_t bit_depth) const noexcept { return ((width * samples[pnginfo.color_type] * bit_depth) + 7) >> 3; } - std::uint32_t get_bytes_per_pixel() const + std::uint32_t get_bytes_per_pixel() const noexcept { return ((samples[pnginfo.color_type] * pnginfo.bit_depth) + 7) >> 3; } - static std::error_condition read_chunk(read_stream &fp, std::unique_ptr<std::uint8_t []> &data, std::uint32_t &type, std::uint32_t &length) + static std::error_condition read_chunk(read_stream &fp, std::unique_ptr<std::uint8_t []> &data, std::uint32_t &type, std::uint32_t &length) noexcept { std::error_condition err; std::size_t actual; std::uint8_t tempbuff[4]; - /* fetch the length of this chunk */ + // fetch the length of this chunk err = fp.read(tempbuff, 4, actual); if (err) return err; @@ -459,7 +459,7 @@ private: return png_error::FILE_TRUNCATED; length = fetch_32bit(tempbuff); - /* fetch the type of this chunk */ + // fetch the type of this chunk err = fp.read(tempbuff, 4, actual); if (err) return err; @@ -467,22 +467,22 @@ private: return png_error::FILE_TRUNCATED; type = fetch_32bit(tempbuff); - /* stop when we hit an IEND chunk */ + // stop when we hit an IEND chunk if (type == PNG_CN_IEND) return std::error_condition(); - /* start the CRC with the chunk type (but not the length) */ + // start the CRC with the chunk type (but not the length) std::uint32_t crc = crc32(0, tempbuff, 4); - /* read the chunk itself into an allocated memory buffer */ + // read the chunk itself into an allocated memory buffer if (length) { - /* allocate memory for this chunk */ + // allocate memory for this chunk data.reset(new (std::nothrow) std::uint8_t [length]); if (!data) return std::errc::not_enough_memory; - /* read the data from the file */ + // read the data from the file err = fp.read(data.get(), length, actual); if (err) { @@ -495,11 +495,11 @@ private: return png_error::FILE_TRUNCATED; } - /* update the CRC */ + // update the CRC crc = crc32(crc, data.get(), length); } - /* read the CRC */ + // read the CRC err = fp.read(tempbuff, 4, actual); if (err) { @@ -513,7 +513,7 @@ private: } std::uint32_t const chunk_crc = fetch_32bit(tempbuff); - /* validate the CRC */ + // validate the CRC if (crc != chunk_crc) { data.reset(); @@ -526,11 +526,11 @@ private: png_info & pnginfo; public: - png_private(png_info &info) : pnginfo(info) + png_private(png_info &info) noexcept : pnginfo(info) { } - std::error_condition copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha) const + std::error_condition copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha) const noexcept { // do some basic checks for unsupported images if ((8 > pnginfo.bit_depth) || (pnginfo.bit_depth % 8)) @@ -542,8 +542,12 @@ public: if ((3 == pnginfo.color_type) && (8 != pnginfo.bit_depth)) return png_error::UNSUPPORTED_FORMAT; // indexed colour must be exactly 8bpp - // everything looks sane, allocate the bitmap and deinterlace into it + // try to allocate the bitmap bitmap.allocate(pnginfo.width, pnginfo.height); + if (!bitmap.valid()) + return std::errc::not_enough_memory; + + // everything looks sane, deinterlace into the bitmap std::uint8_t accumalpha(0xff); uint32_t const bps(pnginfo.bit_depth >> 3); uint32_t const bpp(bps * samples[pnginfo.color_type]); @@ -659,7 +663,7 @@ public: return std::error_condition(); } - std::error_condition expand_buffer_8bit() + std::error_condition expand_buffer_8bit() noexcept { // nothing to do if we're at 8 or greater already if (pnginfo.bit_depth >= 8) @@ -743,7 +747,7 @@ public: return std::error_condition(); } - std::error_condition read_file(read_stream &fp) + std::error_condition read_file(read_stream &fp) noexcept { // initialize the data structures std::error_condition error; @@ -780,7 +784,7 @@ public: return error; } - static std::error_condition verify_header(read_stream &fp) + static std::error_condition verify_header(read_stream &fp) noexcept { std::uint8_t signature[sizeof(PNG_SIGNATURE)]; @@ -817,7 +821,7 @@ constexpr unsigned png_private::ADAM7_Y_OFFS[7]; core stream -------------------------------------------------*/ -std::error_condition png_info::verify_header(read_stream &fp) +std::error_condition png_info::verify_header(read_stream &fp) noexcept { return png_private::verify_header(fp); } @@ -827,7 +831,7 @@ std::error_condition png_info::verify_header(read_stream &fp) read_file - read a PNG from a core stream -------------------------------------------------*/ -std::error_condition png_info::read_file(read_stream &fp) +std::error_condition png_info::read_file(read_stream &fp) noexcept { return png_private(*this).read_file(fp); } @@ -838,7 +842,7 @@ std::error_condition png_info::read_file(read_stream &fp) bitmap -------------------------------------------------*/ -std::error_condition png_read_bitmap(read_stream &fp, bitmap_argb32 &bitmap) +std::error_condition png_read_bitmap(read_stream &fp, bitmap_argb32 &bitmap) noexcept { std::error_condition result; png_info pnginfo; @@ -868,7 +872,7 @@ std::error_condition png_read_bitmap(read_stream &fp, bitmap_argb32 &bitmap) bitmap -------------------------------------------------*/ -std::error_condition png_info::copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha) +std::error_condition png_info::copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha) noexcept { return png_private(*this).copy_to_bitmap(bitmap, hasalpha); } @@ -879,7 +883,7 @@ std::error_condition png_info::copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasal sub 8-bit to 8-bit -------------------------------------------------*/ -std::error_condition png_info::expand_buffer_8bit() +std::error_condition png_info::expand_buffer_8bit() noexcept { return png_private(*this).expand_buffer_8bit(); } @@ -894,7 +898,7 @@ std::error_condition png_info::expand_buffer_8bit() add_text - add a text entry to the png_info -------------------------------------------------*/ -std::error_condition png_info::add_text(std::string_view keyword, std::string_view text) +std::error_condition png_info::add_text(std::string_view keyword, std::string_view text) noexcept { // apply rules to keyword char32_t prev(0); @@ -934,26 +938,26 @@ std::error_condition png_info::add_text(std::string_view keyword, std::string_vi the given file -------------------------------------------------*/ -static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, uint32_t type, uint32_t length) +static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, uint32_t type, uint32_t length) noexcept { std::error_condition err; std::size_t written; std::uint8_t tempbuff[8]; std::uint32_t crc; - /* stuff the length/type into the buffer */ + // stuff the length/type into the buffer put_32bit(tempbuff + 0, length); put_32bit(tempbuff + 4, type); crc = crc32(0, tempbuff + 4, 4); - /* write that data */ + // write that data err = fp.write(tempbuff, 8, written); if (err) return err; else if (8 != written) return std::errc::io_error; - /* append the actual data */ + // append the actual data if (length > 0) { err = fp.write(data, length, written); @@ -964,7 +968,7 @@ static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, u crc = crc32(crc, data, length); } - /* write the CRC */ + // write the CRC put_32bit(tempbuff, crc); err = fp.write(tempbuff, 4, written); if (err) @@ -981,7 +985,7 @@ static std::error_condition write_chunk(write_stream &fp, const uint8_t *data, u chunk to the given file by deflating it -------------------------------------------------*/ -static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data, uint32_t type, uint32_t length) +static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data, uint32_t type, uint32_t length) noexcept { std::error_condition err; std::uint64_t lengthpos; @@ -996,19 +1000,19 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data std::uint32_t crc; int zerr; - /* stuff the length/type into the buffer */ + // stuff the length/type into the buffer put_32bit(tempbuff + 0, length); put_32bit(tempbuff + 4, type); crc = crc32(0, tempbuff + 4, 4); - /* write that data */ + // write that data err = fp.write(tempbuff, 8, written); if (err) return err; else if (8 != written) return std::errc::io_error; - /* initialize the stream */ + // initialize the stream memset(&stream, 0, sizeof(stream)); stream.next_in = data; stream.avail_in = length; @@ -1020,7 +1024,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data else if (Z_OK != zerr) return png_error::COMPRESS_ERROR; - /* now loop until we run out of data */ + // now loop until we run out of data for ( ; ; ) { /* compress this chunk */ @@ -1028,7 +1032,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data stream.avail_out = sizeof(tempbuff); zerr = deflate(&stream, Z_FINISH); - /* if there's data to write, do it */ + // if there's data to write, do it if (stream.avail_out < sizeof(tempbuff)) { int bytes = sizeof(tempbuff) - stream.avail_out; @@ -1047,11 +1051,11 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data zlength += bytes; } - /* stop at the end of the stream */ + // stop at the end of the stream if (zerr == Z_STREAM_END) break; - /* other errors are fatal */ + // other errors are fatal if (zerr != Z_OK) { deflateEnd(&stream); @@ -1064,7 +1068,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data } } - /* clean up deflater(maus) */ + // clean up deflater zerr = deflateEnd(&stream); if (Z_ERRNO == zerr) return std::error_condition(errno, std::generic_category()); @@ -1073,7 +1077,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data else if (Z_OK != zerr) return png_error::COMPRESS_ERROR; - /* write the CRC */ + // write the CRC put_32bit(tempbuff, crc); err = fp.write(tempbuff, 4, written); if (err) @@ -1081,7 +1085,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data else if (4 != written) return std::errc::io_error; - /* seek back and update the length */ + // seek back and update the length err = fp.seek(lengthpos, SEEK_SET); if (err) return err; @@ -1092,7 +1096,7 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data else if (4 != written) return std::errc::io_error; - /* return to the end */ + // return to the end return fp.seek(lengthpos + 8 + zlength + 4, SEEK_SET); } @@ -1102,9 +1106,9 @@ static std::error_condition write_deflated_chunk(random_write &fp, uint8_t *data bitmap to a palettized image -------------------------------------------------*/ -static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) +static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) noexcept { - /* set the common info */ + // set the common info pnginfo.width = bitmap.width(); pnginfo.height = bitmap.height(); pnginfo.bit_depth = 8; @@ -1112,12 +1116,12 @@ static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, b pnginfo.num_palette = 256; int const rowbytes = pnginfo.width; - /* allocate memory for the palette */ + // allocate memory for the palette pnginfo.palette.reset(new (std::nothrow) std::uint8_t [3 * 256]); if (!pnginfo.palette) return std::errc::not_enough_memory; - /* build the palette */ + // build the palette std::fill_n(pnginfo.palette.get(), 3 * 256, 0); for (int x = 0; x < palette_length; x++) { @@ -1127,7 +1131,7 @@ static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, b pnginfo.palette[3 * x + 2] = color.b(); } - /* allocate memory for the image */ + // allocate memory for the image pnginfo.image.reset(new (std::nothrow) std::uint8_t [pnginfo.height * (rowbytes + 1)]); if (!pnginfo.image) { @@ -1135,13 +1139,13 @@ static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, b return std::errc::not_enough_memory; } - /* copy in the pixels, specifying a nullptr filter */ + // copy in the pixels, specifying a nullptr filter for (int y = 0; y < pnginfo.height; y++) { uint16_t const *src = reinterpret_cast<uint16_t const *>(bitmap.raw_pixptr(y)); uint8_t *dst = &pnginfo.image[y * (rowbytes + 1)]; - /* store the filter byte, then copy the data */ + // store the filter byte, then copy the data *dst++ = 0; for (int x = 0; x < pnginfo.width; x++) *dst++ = *src++; @@ -1156,33 +1160,33 @@ static std::error_condition convert_bitmap_to_image_palette(png_info &pnginfo, b bitmap to an RGB image -------------------------------------------------*/ -static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) +static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) noexcept { bool const alpha = (bitmap.format() == BITMAP_FORMAT_ARGB32); - /* set the common info */ + // set the common info pnginfo.width = bitmap.width(); pnginfo.height = bitmap.height(); pnginfo.bit_depth = 8; pnginfo.color_type = alpha ? 6 : 2; int const rowbytes = pnginfo.width * (alpha ? 4 : 3); - /* allocate memory for the image */ + // allocate memory for the image pnginfo.image.reset(new (std::nothrow) std::uint8_t [pnginfo.height * (rowbytes + 1)]); if (!pnginfo.image) return std::errc::not_enough_memory; - /* copy in the pixels, specifying a nullptr filter */ + // copy in the pixels, specifying a nullptr filter for (int y = 0; y < pnginfo.height; y++) { uint8_t *dst = &pnginfo.image[y * (rowbytes + 1)]; - /* store the filter byte, then copy the data */ + // store the filter byte, then copy the data *dst++ = 0; if (bitmap.format() == BITMAP_FORMAT_IND16) { - /* 16bpp palettized format */ + // 16bpp palettized format uint16_t const *src16 = reinterpret_cast<uint16_t const *>(bitmap.raw_pixptr(y)); for (int x = 0; x < pnginfo.width; x++) { @@ -1194,7 +1198,7 @@ static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitma } else if (bitmap.format() == BITMAP_FORMAT_RGB32) { - /* 32-bit RGB direct */ + // 32-bit RGB direct uint32_t const *src32 = reinterpret_cast<uint32_t const *>(bitmap.raw_pixptr(y)); for (int x = 0; x < pnginfo.width; x++) { @@ -1206,7 +1210,7 @@ static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitma } else if (bitmap.format() == BITMAP_FORMAT_ARGB32) { - /* 32-bit ARGB direct */ + // 32-bit ARGB direct uint32_t const *src32 = reinterpret_cast<uint32_t const *>(bitmap.raw_pixptr(y)); for (int x = 0; x < pnginfo.width; x++) { @@ -1219,7 +1223,7 @@ static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitma } else { - /* unsupported format */ + // unsupported format return png_error::UNSUPPORTED_FORMAT; } } @@ -1233,7 +1237,7 @@ static std::error_condition convert_bitmap_to_image_rgb(png_info &pnginfo, bitma chunks to the given file -------------------------------------------------*/ -static std::error_condition write_png_stream(random_write &fp, png_info &pnginfo, const bitmap_t &bitmap, int palette_length, const rgb_t *palette) +static std::error_condition write_png_stream(random_write &fp, png_info &pnginfo, const bitmap_t &bitmap, int palette_length, const rgb_t *palette) noexcept { uint8_t tempbuff[16]; std::error_condition error; @@ -1290,7 +1294,7 @@ static std::error_condition write_png_stream(random_write &fp, png_info &pnginfo src.remove_prefix(len); } - // NUL separator between keword and text + // NUL separator between keyword and text *dst++ = 0; // convert text to ISO-8859-1 @@ -1314,7 +1318,7 @@ static std::error_condition write_png_stream(random_write &fp, png_info &pnginfo } -std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) +std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) noexcept { // use a dummy pnginfo if none passed to us png_info pnginfo; @@ -1329,7 +1333,7 @@ std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t else if (sizeof(PNG_SIGNATURE) != written) return std::errc::io_error; - /* write the rest of the PNG data */ + // write the rest of the PNG data return write_png_stream(fp, *info, bitmap, palette_length, palette); } @@ -1341,7 +1345,7 @@ std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t ********************************************************************************/ -std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, unsigned rate) +std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, unsigned rate) noexcept { std::size_t written; std::error_condition err = fp.write(MNG_Signature, 8, written); @@ -1360,13 +1364,13 @@ std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, } -std::error_condition mng_capture_frame(random_write &fp, png_info &info, bitmap_t const &bitmap, int palette_length, rgb_t const *palette) +std::error_condition mng_capture_frame(random_write &fp, png_info &info, bitmap_t const &bitmap, int palette_length, rgb_t const *palette) noexcept { return write_png_stream(fp, info, bitmap, palette_length, palette); } -std::error_condition mng_capture_stop(random_write &fp) +std::error_condition mng_capture_stop(random_write &fp) noexcept { return write_chunk(fp, nullptr, MNG_CN_MEND, 0); } diff --git a/src/lib/util/png.h b/src/lib/util/png.h index d802c1a5a82..2f9b7ac29cb 100644 --- a/src/lib/util/png.h +++ b/src/lib/util/png.h @@ -60,16 +60,16 @@ public: ~png_info() { free_data(); } - std::error_condition read_file(read_stream &fp); - std::error_condition copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha); - std::error_condition expand_buffer_8bit(); + std::error_condition read_file(read_stream &fp) noexcept; + std::error_condition copy_to_bitmap(bitmap_argb32 &bitmap, bool &hasalpha) noexcept; + std::error_condition expand_buffer_8bit() noexcept; - std::error_condition add_text(std::string_view keyword, std::string_view text); + std::error_condition add_text(std::string_view keyword, std::string_view text) noexcept; - void free_data(); - void reset() { free_data(); operator=(png_info()); } + void free_data() noexcept; + void reset() noexcept { free_data(); operator=(png_info()); } - static std::error_condition verify_header(read_stream &fp); + static std::error_condition verify_header(read_stream &fp) noexcept; std::unique_ptr<std::uint8_t []> image; std::uint32_t width, height; @@ -102,13 +102,13 @@ private: FUNCTION PROTOTYPES ***************************************************************************/ -std::error_condition png_read_bitmap(read_stream &fp, bitmap_argb32 &bitmap); +std::error_condition png_read_bitmap(read_stream &fp, bitmap_argb32 &bitmap) noexcept; -std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t const &bitmap, int palette_length, const rgb_t *palette); +std::error_condition png_write_bitmap(random_write &fp, png_info *info, bitmap_t const &bitmap, int palette_length, const rgb_t *palette) noexcept; -std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, unsigned rate); -std::error_condition mng_capture_frame(random_write &fp, png_info &info, bitmap_t const &bitmap, int palette_length, rgb_t const *palette); -std::error_condition mng_capture_stop(random_write &fp); +std::error_condition mng_capture_start(random_write &fp, bitmap_t const &bitmap, unsigned rate) noexcept; +std::error_condition mng_capture_frame(random_write &fp, png_info &info, bitmap_t const &bitmap, int palette_length, rgb_t const *palette) noexcept; +std::error_condition mng_capture_stop(random_write &fp) noexcept; } // namespace util diff --git a/src/osd/modules/lib/osdlib_win32.cpp b/src/osd/modules/lib/osdlib_win32.cpp index 067fbd1224f..23e75bf9dc2 100644 --- a/src/osd/modules/lib/osdlib_win32.cpp +++ b/src/osd/modules/lib/osdlib_win32.cpp @@ -356,12 +356,12 @@ void virtual_memory_allocation::do_free(void *start, std::size_t size) bool virtual_memory_allocation::do_set_access(void *start, std::size_t size, unsigned access) { - DWORD p, o; + DWORD p; if (access & EXECUTE) p = (access & WRITE) ? PAGE_EXECUTE_READWRITE : (access & READ) ? PAGE_EXECUTE_READ : PAGE_EXECUTE; else p = (access & WRITE) ? PAGE_READWRITE : (access & READ) ? PAGE_READONLY : PAGE_NOACCESS; - return VirtualProtect(start, size, p, &o) != 0; + return VirtualAlloc(start, size, MEM_COMMIT, p) != nullptr; } |