From 4c2aebedc2fc50bd7b38c5f2ff7c52517ddfedef Mon Sep 17 00:00:00 2001 From: Kevin Ring Date: Tue, 5 Nov 2024 18:17:34 +1100 Subject: [PATCH] Eliminate dodgy namespacing of STBIR. --- CesiumGltfContent/src/ImageManipulation.cpp | 20 +++----- .../include/CesiumGltfReader/ImageDecoder.h | 27 +++++++++++ CesiumGltfReader/src/ImageDecoder.cpp | 47 +++++++++++++------ 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/CesiumGltfContent/src/ImageManipulation.cpp b/CesiumGltfContent/src/ImageManipulation.cpp index 6a6a7c3fe..e1b368a7a 100644 --- a/CesiumGltfContent/src/ImageManipulation.cpp +++ b/CesiumGltfContent/src/ImageManipulation.cpp @@ -1,21 +1,15 @@ #include #include +#include #include -namespace Cesium { -// Use STB resize in our own namespace to avoid conflicts from other libs -#define STBIRDEF -#include -#undef STBIRDEF -} // namespace Cesium - -using namespace Cesium; - #define STB_IMAGE_WRITE_STATIC #define STB_IMAGE_WRITE_IMPLEMENTATION #include +using namespace CesiumGltfReader; + namespace CesiumGltfContent { void ImageManipulation::unsafeBlitImage( @@ -108,16 +102,16 @@ bool ImageManipulation::blitImage( } // Use STB to do the copy / scale - stbir_resize_uint8_linear( - reinterpret_cast(pSource), + ImageDecoder::unsafeResize( + pSource, sourcePixels.width, sourcePixels.height, int(bytesPerSourceRow), - reinterpret_cast(pTarget), + pTarget, targetPixels.width, targetPixels.height, int(bytesPerTargetRow), - static_cast(target.channels)); + target.channels); } return true; diff --git a/CesiumGltfReader/include/CesiumGltfReader/ImageDecoder.h b/CesiumGltfReader/include/CesiumGltfReader/ImageDecoder.h index c3bb0b300..7e50d4e08 100644 --- a/CesiumGltfReader/include/CesiumGltfReader/ImageDecoder.h +++ b/CesiumGltfReader/include/CesiumGltfReader/ImageDecoder.h @@ -68,6 +68,33 @@ class ImageDecoder { */ static std::optional generateMipMaps(CesiumGltf::ImageAsset& image); + + /** + * @brief Resize an image, without validating the provided pointers or ranges. + * + * @param inputPixels The input image. + * @param inputWidth The width of the input image, in pixels. + * @param inputHeight The height of the input image, in pixels. + * @param inputStrideBytes The stride of the input image, in bytes. Stride is + * the number of bytes between successive rows. + * @param outputPixels The buffer into which to write the output image. + * @param outputWidth The width of the output image, in pixels. + * @param outputHeight The height of the otuput image, in pixels. + * @param outputStrideBytes The stride of the output image, in bytes. Stride + * is the number of bytes between successive rows. + * @param channels The number of channels in both the input and output images. + * @return True if the resize succeeded, false if it failed. + */ + static bool unsafeResize( + const std::byte* pInputPixels, + int32_t inputWidth, + int32_t inputHeight, + int32_t inputStrideBytes, + std::byte* pOutputPixels, + int32_t outputWidth, + int32_t outputHeight, + int32_t outputStrideBytes, + int32_t channels); }; } // namespace CesiumGltfReader diff --git a/CesiumGltfReader/src/ImageDecoder.cpp b/CesiumGltfReader/src/ImageDecoder.cpp index fba65b71b..3ec7738c3 100644 --- a/CesiumGltfReader/src/ImageDecoder.cpp +++ b/CesiumGltfReader/src/ImageDecoder.cpp @@ -26,23 +26,19 @@ #define STBI_FAILURE_USERMSG -namespace Cesium { -// Use STB resize in our own namespace to avoid conflicts from other libs -#define STBIRDEF -#define STB_IMAGE_RESIZE_IMPLEMENTATION -#include -#undef STBIRDEF -}; // namespace Cesium - #define STB_IMAGE_STATIC #define STB_IMAGE_IMPLEMENTATION +#define STBI_NO_STDIO +#define STBI_ASSERT(x) CESIUM_ASSERT(x) #include -#include + +#define STB_IMAGE_RESIZE_IMPLEMENTATION +#define STB_IMAGE_RESIZE_STATIC +#include namespace CesiumGltfReader { using namespace CesiumGltf; -using namespace Cesium; namespace { @@ -436,17 +432,16 @@ std::optional ImageDecoder::generateMipMaps(ImageAsset& image) { image.mipPositions[mipIndex].byteOffset = byteOffset; image.mipPositions[mipIndex].byteSize = byteSize; - if (!stbir_resize_uint8_linear( - reinterpret_cast( - &image.pixelData[lastByteOffset]), + if (!ImageDecoder::unsafeResize( + &image.pixelData[lastByteOffset], lastWidth, lastHeight, 0, - reinterpret_cast(&image.pixelData[byteOffset]), + &image.pixelData[byteOffset], mipWidth, mipHeight, 0, - static_cast(image.channels))) { + image.channels)) { // Remove any added mipmaps. image.mipPositions.clear(); image.pixelData.resize(imageByteSize); @@ -457,4 +452,26 @@ std::optional ImageDecoder::generateMipMaps(ImageAsset& image) { return std::nullopt; } +/*static*/ bool ImageDecoder::unsafeResize( + const std::byte* pInputPixels, + int32_t inputWidth, + int32_t inputHeight, + int32_t inputStrideBytes, + std::byte* pOutputPixels, + int32_t outputWidth, + int32_t outputHeight, + int32_t outputStrideBytes, + int32_t channels) { + return stbir_resize_uint8_linear( + reinterpret_cast(pInputPixels), + inputWidth, + inputHeight, + inputStrideBytes, + reinterpret_cast(pOutputPixels), + outputWidth, + outputHeight, + outputStrideBytes, + static_cast(channels)) != nullptr; +} + } // namespace CesiumGltfReader