Skip to content

Commit

Permalink
Common/Image: Add resize methods
Browse files Browse the repository at this point in the history
  • Loading branch information
stenzek committed Sep 26, 2022
1 parent e3a327f commit 84917ec
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 10 deletions.
41 changes: 39 additions & 2 deletions src/common/image.cpp
Expand Up @@ -5,6 +5,7 @@
#include "path.h"
#include "scoped_guard.h"
#include "stb_image.h"
#include "stb_image_resize.h"
#include "stb_image_write.h"
#include "string_util.h"
Log_SetChannel(Image);
Expand Down Expand Up @@ -167,6 +168,42 @@ std::optional<std::vector<u8>> RGBA8Image::SaveToBuffer(const char* filename, in
return ret;
}

void RGBA8Image::Resize(u32 new_width, u32 new_height)
{
if (m_width == new_width && m_height == new_height)
return;

std::vector<u32> resized_texture_data(new_width * new_height);
u32 resized_texture_stride = sizeof(u32) * new_width;
if (!stbir_resize_uint8(reinterpret_cast<u8*>(m_pixels.data()), m_width, m_height, GetPitch(),
reinterpret_cast<u8*>(resized_texture_data.data()), new_width, new_height,
resized_texture_stride, 4))
{
Panic("stbir_resize_uint8 failed");
return;
}

SetPixels(new_width, new_height, std::move(resized_texture_data));
}

void RGBA8Image::Resize(const RGBA8Image* src_image, u32 new_width, u32 new_height)
{
if (src_image->m_width == new_width && src_image->m_height == new_height)
{
SetPixels(src_image->m_width, src_image->m_height, src_image->m_pixels.data());
return;
}

SetSize(new_width, new_height);
if (!stbir_resize_uint8(reinterpret_cast<const u8*>(src_image->m_pixels.data()), src_image->m_width,
src_image->m_height, src_image->GetPitch(), reinterpret_cast<u8*>(m_pixels.data()), new_width,
new_height, GetPitch(), 4))
{
Panic("stbir_resize_uint8 failed");
return;
}
}

#if 0

static bool PNGCommonLoader(RGBA8Image* image, png_structp png_ptr, png_infop info_ptr, std::vector<u32>& new_data,
Expand Down Expand Up @@ -567,7 +604,7 @@ bool STBBufferSaverPNG(const RGBA8Image& image, std::vector<u8>* buffer, int qua
};

return (stbi_write_png_to_func(write_func, buffer, image.GetWidth(), image.GetHeight(), 4, image.GetPixels(),
image.GetByteStride()) != 0);
image.GetPitch()) != 0);
}

bool STBBufferSaverJPEG(const RGBA8Image& image, std::vector<u8>* buffer, int quality)
Expand All @@ -590,7 +627,7 @@ bool STBFileSaverPNG(const RGBA8Image& image, const char* filename, std::FILE* f
};

return (stbi_write_png_to_func(write_func, fp, image.GetWidth(), image.GetHeight(), 4, image.GetPixels(),
image.GetByteStride()) != 0);
image.GetPitch()) != 0);
}

bool STBFileSaverJPEG(const RGBA8Image& image, const char* filename, std::FILE* fp, int quality)
Expand Down
5 changes: 4 additions & 1 deletion src/common/image.h
Expand Up @@ -49,7 +49,7 @@ class Image
ALWAYS_INLINE bool IsValid() const { return (m_width > 0 && m_height > 0); }
ALWAYS_INLINE u32 GetWidth() const { return m_width; }
ALWAYS_INLINE u32 GetHeight() const { return m_height; }
ALWAYS_INLINE u32 GetByteStride() const { return (sizeof(PixelType) * m_width); }
ALWAYS_INLINE u32 GetPitch() const { return (sizeof(PixelType) * m_width); }
ALWAYS_INLINE const PixelType* GetPixels() const { return m_pixels.data(); }
ALWAYS_INLINE PixelType* GetPixels() { return m_pixels.data(); }
ALWAYS_INLINE const PixelType* GetRowPixels(u32 y) const { return &m_pixels[y * m_width]; }
Expand Down Expand Up @@ -125,6 +125,9 @@ class RGBA8Image : public Image<u32>
bool SaveToFile(const char* filename, int quality = DEFAULT_SAVE_QUALITY) const;
bool SaveToFile(const char* filename, std::FILE* fp, int quality = DEFAULT_SAVE_QUALITY) const;
std::optional<std::vector<u8>> SaveToBuffer(const char* filename, int quality = DEFAULT_SAVE_QUALITY) const;

void Resize(u32 new_width, u32 new_height);
void Resize(const RGBA8Image* src_image, u32 new_width, u32 new_height);
};

} // namespace Common
6 changes: 3 additions & 3 deletions src/core/gpu_hw_d3d11.cpp
Expand Up @@ -752,7 +752,7 @@ bool GPU_HW_D3D11::BlitVRAMReplacementTexture(const TextureReplacementTexture* t
{
if (!m_vram_replacement_texture.Create(m_device.Get(), tex->GetWidth(), tex->GetHeight(), 1, 1, 1,
DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_BIND_SHADER_RESOURCE, tex->GetPixels(),
tex->GetByteStride(), true))
tex->GetPitch(), true))
{
return false;
}
Expand All @@ -767,13 +767,13 @@ bool GPU_HW_D3D11::BlitVRAMReplacementTexture(const TextureReplacementTexture* t
return false;
}

const u32 copy_size = std::min(tex->GetByteStride(), sr.RowPitch);
const u32 copy_size = std::min(tex->GetPitch(), sr.RowPitch);
const u8* src_ptr = reinterpret_cast<const u8*>(tex->GetPixels());
u8* dst_ptr = static_cast<u8*>(sr.pData);
for (u32 i = 0; i < tex->GetHeight(); i++)
{
std::memcpy(dst_ptr, src_ptr, copy_size);
src_ptr += tex->GetByteStride();
src_ptr += tex->GetPitch();
dst_ptr += sr.RowPitch;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/gpu_hw_d3d12.cpp
Expand Up @@ -800,7 +800,7 @@ bool GPU_HW_D3D12::BlitVRAMReplacementTexture(const TextureReplacementTexture* t

// buffer -> texture
const u32 sb_offset = m_texture_replacment_stream_buffer.GetCurrentOffset();
D3D12::Texture::CopyToUploadBuffer(tex->GetPixels(), tex->GetByteStride(), tex->GetHeight(),
D3D12::Texture::CopyToUploadBuffer(tex->GetPixels(), tex->GetPitch(), tex->GetHeight(),
m_texture_replacment_stream_buffer.GetCurrentHostPointer(), copy_pitch);
m_texture_replacment_stream_buffer.CommitMemory(required_size);
m_vram_write_replacement_texture.CopyFromBuffer(0, 0, tex->GetWidth(), tex->GetHeight(), copy_pitch,
Expand Down
2 changes: 1 addition & 1 deletion src/core/gpu_hw_vulkan.cpp
Expand Up @@ -1831,7 +1831,7 @@ bool GPU_HW_Vulkan::BlitVRAMReplacementTexture(const TextureReplacementTexture*
}

m_vram_write_replacement_texture.Update(0, 0, tex->GetWidth(), tex->GetHeight(), 0, 0, tex->GetPixels(),
tex->GetByteStride());
tex->GetPitch());

// texture -> vram
const VkImageBlit blit = {
Expand Down
2 changes: 1 addition & 1 deletion src/core/system.cpp
Expand Up @@ -4217,7 +4217,7 @@ void System::UpdateSoftwareCursor()

if (image && image->IsValid())
{
g_host_display->SetSoftwareCursor(image->GetPixels(), image->GetWidth(), image->GetHeight(), image->GetByteStride(),
g_host_display->SetSoftwareCursor(image->GetPixels(), image->GetWidth(), image->GetHeight(), image->GetPitch(),
image_scale);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/frontend-common/imgui_fullscreen.cpp
Expand Up @@ -266,7 +266,7 @@ std::shared_ptr<HostDisplayTexture> ImGuiFullscreen::UploadTexture(const char* p
{
std::unique_ptr<HostDisplayTexture> texture =
g_host_display->CreateTexture(image.GetWidth(), image.GetHeight(), 1, 1, 1, HostDisplayPixelFormat::RGBA8,
image.GetPixels(), image.GetByteStride());
image.GetPixels(), image.GetPitch());
if (!texture)
{
Log_ErrorPrintf("failed to create %ux%u texture for resource", image.GetWidth(), image.GetHeight());
Expand Down

0 comments on commit 84917ec

Please sign in to comment.