diff --git a/libs/image/include/image/ColorTransform.h b/libs/image/include/image/ColorTransform.h index 5807bd7d18..dc90f49690 100644 --- a/libs/image/include/image/ColorTransform.h +++ b/libs/image/include/image/ColorTransform.h @@ -214,8 +214,7 @@ std::unique_ptr fromLinearTosRGB(const LinearImage& image) { T* d = reinterpret_cast(dst.get()); for (size_t y = 0; y < h; ++y) { for (size_t x = 0; x < w; ++x, d += 3) { - float3 const* src = reinterpret_cast( - image.getPixelRef((uint32_t) x, (uint32_t) y)); + auto src = image.get((uint32_t) x, (uint32_t) y); float3 l(linearTosRGB(saturate(*src)) * std::numeric_limits::max()); for (size_t i = 0; i < 3; i++) { d[i] = T(l[i]); @@ -238,8 +237,7 @@ std::unique_ptr fromLinearToRGB(const LinearImage& image) { T* d = reinterpret_cast(dst.get()); for (size_t y = 0; y < h; ++y) { for (size_t x = 0; x < w; ++x, d += 3) { - float3 const* src = reinterpret_cast( - image.getPixelRef((uint32_t) x, (uint32_t) y)); + auto src = image.get((uint32_t) x, (uint32_t) y); float3 l(saturate(*src) * std::numeric_limits::max()); for (size_t i = 0; i < 3; i++) { d[i] = T(l[i]); @@ -262,8 +260,7 @@ std::unique_ptr fromLinearToRGBM(const LinearImage& image) { T* d = reinterpret_cast(dst.get()); for (size_t y = 0; y < h; ++y) { for (size_t x = 0; x < w; ++x, d += 4) { - float3 const* src = reinterpret_cast( - image.getPixelRef((uint32_t) x, (uint32_t) y)); + auto src = image.get((uint32_t) x, (uint32_t) y); float4 l(linearToRGBM(*src) * std::numeric_limits::max()); for (size_t i = 0; i < 4; i++) { d[i] = T(l[i]); @@ -299,7 +296,7 @@ template static LinearImage toLinear(size_t w, size_t h, size_t bpr, const uint8_t* src, PROCESS proc, TRANSFORM transform) { LinearImage result((uint32_t) w, (uint32_t) h, 3); - math::float3* d = reinterpret_cast(result.getPixelRef()); + auto d = result.get(); for (size_t y = 0; y < h; ++y) { T const* p = reinterpret_cast(src + y * bpr); for (size_t x = 0; x < w; ++x, p += 3) { @@ -327,7 +324,7 @@ template static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr, const uint8_t* src, PROCESS proc, TRANSFORM transform) { LinearImage result((uint32_t) w, (uint32_t) h, 4); - math::float4* d = reinterpret_cast(result.getPixelRef()); + auto d = result.get(); for (size_t y = 0; y < h; ++y) { T const* p = reinterpret_cast(src + y * bpr); for (size_t x = 0; x < w; ++x, p += 4) { @@ -351,7 +348,7 @@ static LinearImage toLinearWithAlpha(size_t w, size_t h, size_t bpr, // Constructs a 3-channel LinearImage from RGBM data. inline LinearImage toLinearFromRGBM(math::float4 const* src, uint32_t w, uint32_t h) { LinearImage result(w, h, 3); - math::float3* dst = reinterpret_cast(result.getPixelRef()); + auto dst = result.get(); for (uint32_t row = 0; row < h; ++row) { for (uint32_t col = 0; col < w; ++col, ++src, ++dst) { *dst = RGBMtoLinear(*src); diff --git a/libs/image/include/image/LinearImage.h b/libs/image/include/image/LinearImage.h index fccda01b91..13e487dfcc 100644 --- a/libs/image/include/image/LinearImage.h +++ b/libs/image/include/image/LinearImage.h @@ -17,6 +17,7 @@ #ifndef IMAGE_LINEARIMAGE_H #define IMAGE_LINEARIMAGE_H +#include #include /** @@ -64,11 +65,13 @@ public: * Gets a pointer to the underlying pixel data. */ float* getPixelRef() { return mData; } + template T* get() { return reinterpret_cast(mData); } /** * Gets a pointer to immutable pixel data. */ float const* getPixelRef() const { return mData; } + template T const* get() const { return reinterpret_cast(mData); } /** * Gets a pointer to the pixel data at the given column and row. (not bounds checked) @@ -77,6 +80,11 @@ public: return mData + (column + row * mWidth) * mChannels; } + template + T* get(uint32_t column, uint32_t row) { + return reinterpret_cast(getPixelRef(column, row)); + } + /** * Gets a pointer to the immutable pixel data at the given column and row. (not bounds checked) */ @@ -84,6 +92,11 @@ public: return mData + (column + row * mWidth) * mChannels; } + template + T const* get(uint32_t column, uint32_t row) const { + return reinterpret_cast(getPixelRef(column, row)); + } + uint32_t getWidth() const { return mWidth; } uint32_t getHeight() const { return mHeight; } uint32_t getChannels() const { return mChannels; } diff --git a/libs/image/tests/test_image.cpp b/libs/image/tests/test_image.cpp index c9865ad108..50ad9a81db 100644 --- a/libs/image/tests/test_image.cpp +++ b/libs/image/tests/test_image.cpp @@ -247,7 +247,7 @@ TEST_F(ImageTest, ColorTransformRGB) { // NOLINT LinearImage img = image::toLinear(w, h, bpr, data, [ ](uint16_t v) -> uint16_t { return v; }, sRGBToLinear); - auto pixels = reinterpret_cast(img.getPixelRef()); + auto pixels = img.get(); ASSERT_NEAR(pixels[0].x, 0.0f, 0.001f); ASSERT_NEAR(pixels[0].y, 0.0f, 0.001f); ASSERT_NEAR(pixels[0].z, 0.0f, 0.001f); diff --git a/libs/imageio/src/ImageEncoder.cpp b/libs/imageio/src/ImageEncoder.cpp index aff7a3517c..c1adf9b18f 100644 --- a/libs/imageio/src/ImageEncoder.cpp +++ b/libs/imageio/src/ImageEncoder.cpp @@ -503,7 +503,7 @@ void HDREncoder::encode(const LinearImage& image) { for (size_t y=0 ; y(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x=0 ; x(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { write32(mStream, (*data)[channel]); data++; @@ -670,7 +670,7 @@ void PSDEncoder::encode(const LinearImage& image) { } else { for (size_t channel = 0; channel < 3; channel++) { for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { write16(mStream, linearTosRGB((*data)[channel])); data++; @@ -746,7 +746,7 @@ void EXREncoder::encode(const LinearImage& image) { size_t i = 0; for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++, data++) { r[i] = data->r; g[i] = data->g; @@ -954,7 +954,7 @@ void DDSEncoder::encode(const LinearImage& image) { switch (mFormat) { case PixelFormat::sRGB: for (size_t y = 0; y < height; y++) { - const float* data = reinterpret_cast(image.getPixelRef(0, y)); + const float* data = image.getPixelRef(0, y); for (size_t x = 0; x < width; x++) { uint8_t b = (uint8_t) (linearTosRGB(saturate(*data)) * 255); mStream.write((const char*) &b, 1); @@ -964,7 +964,7 @@ void DDSEncoder::encode(const LinearImage& image) { break; case PixelFormat::LINEAR_RGB: for (size_t y = 0; y < height; y++) { - const float* data = reinterpret_cast(image.getPixelRef(0, y)); + const float* data = image.getPixelRef(0, y); for (size_t x = 0; x < width; x++) { uint8_t b = (uint8_t) (saturate(*data) * 255); mStream.write((const char*) &b, 1); @@ -977,7 +977,7 @@ void DDSEncoder::encode(const LinearImage& image) { } case DXGI_FORMAT_R16_FLOAT: { for (size_t y = 0; y < height; y++) { - const float* data = reinterpret_cast(image.getPixelRef(0, y)); + const float* data = image.getPixelRef(0, y); for (size_t x = 0; x < width; x++) { math::half p = math::half(*data); mStream.write((const char*) &p, 2); @@ -988,7 +988,7 @@ void DDSEncoder::encode(const LinearImage& image) { } case DXGI_FORMAT_R32_FLOAT: { for (size_t y = 0; y < height; y++) { - const float* data = reinterpret_cast(image.getPixelRef(0, y)); + const float* data = image.getPixelRef(0, y); mStream.write((const char*) data, width * sizeof(float)); } break; @@ -1046,7 +1046,7 @@ void DDSEncoder::encode(const LinearImage& image) { switch (mFormat) { case PixelFormat::sRGB: for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { uint8_t r = (uint8_t) (linearTosRGB(saturate(data->r)) * 255); uint8_t g = (uint8_t) (linearTosRGB(saturate(data->g)) * 255); @@ -1060,7 +1060,7 @@ void DDSEncoder::encode(const LinearImage& image) { break; case PixelFormat::LINEAR_RGB: for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { uint8_t r = (uint8_t) (saturate(data->r) * 255); uint8_t g = (uint8_t) (saturate(data->g) * 255); @@ -1076,7 +1076,7 @@ void DDSEncoder::encode(const LinearImage& image) { } case DXGI_FORMAT_R16G16B16A16_FLOAT: { for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { half4 p = half4(half3(*data), 1); mStream.write((const char*) &p, sizeof(ushort4)); @@ -1087,7 +1087,7 @@ void DDSEncoder::encode(const LinearImage& image) { } case DXGI_FORMAT_R32G32B32A32_FLOAT: { for (size_t y = 0; y < height; y++) { - const float3* data = reinterpret_cast(image.getPixelRef(0, y)); + auto data = image.get(0, y); for (size_t x = 0; x < width; x++) { float4 p = float4(3.0f, 3.0f, 3.0f, 1.0f); mStream.write((const char*) &p, sizeof(float4)); diff --git a/tools/normal-blending/src/main.cpp b/tools/normal-blending/src/main.cpp index 2df8416a52..85f2dfd7ae 100644 --- a/tools/normal-blending/src/main.cpp +++ b/tools/normal-blending/src/main.cpp @@ -217,9 +217,9 @@ void blend(const LinearImage& normal, const LinearImage& detail, LinearImage out const size_t height = output.getHeight(); for (size_t y = 0; y < height; y++) { - float3 const* normalRow = reinterpret_cast(normal.getPixelRef(0, y)); - float3 const* detailRow = reinterpret_cast(detail.getPixelRef(0, y)); - float3* outputRow = reinterpret_cast(output.getPixelRef(0, y)); + auto normalRow = normal.get(0, y); + auto detailRow = detail.get(0, y); + auto outputRow = output.get(0, y); for (size_t x = 0; x < width; x++, normalRow++, detailRow++, outputRow++) { // Reoriented Normal Mapping diff --git a/tools/roughness-prefilter/src/main.cpp b/tools/roughness-prefilter/src/main.cpp index 9b1f5adc7d..e80960b030 100644 --- a/tools/roughness-prefilter/src/main.cpp +++ b/tools/roughness-prefilter/src/main.cpp @@ -187,8 +187,7 @@ float solveVMF(const float2& pos, const size_t sampleCount, const float roughnes for (size_t x = 0; x < sampleCount; x++) { float2 offset(topLeft + float2(x, y)); float2 samplePos(floor(pos + offset) + 0.5f); - float3 sampleNormal = *reinterpret_cast( - normal.getPixelRef(size_t(samplePos.x), size_t(samplePos.y))); + float3 sampleNormal = *normal.get(size_t(samplePos.x), size_t(samplePos.y)); sampleNormal = sampleNormal * 2.0f - 1.0f; averageNormal += normalize(sampleNormal); @@ -217,7 +216,7 @@ void prefilter(const LinearImage& normal, const size_t mipLevel, LinearImage& ou const size_t sampleCount = 1u << mipLevel; for (size_t y = 0; y < height; y++) { - auto* outputRow = reinterpret_cast(output.getPixelRef(0, y)); + auto outputRow = output.get(0, y); for (size_t x = 0; x < width; x++, outputRow++) { const float2 uv = (float2(x, y) + 0.5f) / float2(width, height); const float2 pos = uv * normal.getWidth(); @@ -235,9 +234,9 @@ void prefilter(const LinearImage& normal, const LinearImage& roughness, const si const size_t sampleCount = 1u << mipLevel; for (size_t y = 0; y < height; y++) { - auto* outputRow = reinterpret_cast(output.getPixelRef(0, y)); + auto outputRow = output.get(0, y); for (size_t x = 0; x < width; x++, outputRow++) { - const float3* data = reinterpret_cast(roughness.getPixelRef(x, y)); + auto data = roughness.get(x, y); if (FIRST_MIP) { *outputRow = *data; } else { @@ -356,12 +355,12 @@ int main(int argc, char* argv[]) { LinearImage image(w, h, 3); for (size_t y = 0; y < h; y++) { - auto* dst = reinterpret_cast(image.getPixelRef(0, y)); + auto dst = image.get(0, y); for (size_t x = 0; x < w; x++, dst++) { - float3 aa = *reinterpret_cast(prevMip->getPixelRef(x * 2, y * 2)); - float3 ba = *reinterpret_cast(prevMip->getPixelRef(x * 2 + 1, y * 2)); - float3 ab = *reinterpret_cast(prevMip->getPixelRef(x * 2, y * 2 + 1)); - float3 bb = *reinterpret_cast(prevMip->getPixelRef(x * 2 + 1, y * 2 + 1)); + float3 aa = *prevMip->get(x * 2, y * 2); + float3 ba = *prevMip->get(x * 2 + 1, y * 2); + float3 ab = *prevMip->get(x * 2, y * 2 + 1); + float3 bb = *prevMip->get(x * 2 + 1, y * 2 + 1); *dst = (aa + ba + ab + bb) / 4.0f; } } @@ -392,7 +391,7 @@ int main(int argc, char* argv[]) { prefilter(normalImage, mipImages.at(0), 0, image); } } else { - std::fill_n(reinterpret_cast(image.getPixelRef()), w * h, float3(g_roughness)); + std::fill_n(image.get(), w * h, float3(g_roughness)); } } else { if (hasRoughnessMap) { diff --git a/tools/skygen/src/main.cpp b/tools/skygen/src/main.cpp index c13c39170b..433850f53e 100644 --- a/tools/skygen/src/main.cpp +++ b/tools/skygen/src/main.cpp @@ -122,7 +122,7 @@ static void generateSky(LinearImage image) { size_t y0 = size_t(d); for (size_t y = y0; y < y0 + c; y++) { - float3* UTILS_RESTRICT data = reinterpret_cast(image.getPixelRef(0, y)); + float3* UTILS_RESTRICT data = image.get(0, y); float v = (y + 0.5f) / h; float theta = float(M_PI * v); @@ -194,7 +194,7 @@ static void generateSky(LinearImage image) { const size_t h = image.getHeight(); for (size_t y = 0; y < h; y++) { - float3* UTILS_RESTRICT data = reinterpret_cast(image.getPixelRef(0, y)); + float3* UTILS_RESTRICT data = image.get(0, y); for (size_t x = 0; x < w; x++, data++) { *data *= hdrScale; if (g_tonemap) {