Skip to content

Add .webp support - #5167

Open
Pieter-Dewachter wants to merge 2 commits into
multitheftauto:masterfrom
Pieter-Dewachter:feature/webp
Open

Add .webp support#5167
Pieter-Dewachter wants to merge 2 commits into
multitheftauto:masterfrom
Pieter-Dewachter:feature/webp

Conversation

@Pieter-Dewachter

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for the WebP image format to the MTA client's texture pipeline. Scripts can now pass .webp files (and in-memory WebP byte buffers) to dxCreateTexture, and they will be decoded and uploaded just like PNG/JPG.

Motivation

WebP typically produces 25–35% smaller files than PNG at equivalent visual quality, with full alpha-channel support. For resources with a lot of images, this can reduce download size without sacrificing quality. It's also quickly becoming the default for web-based applications, which means we can use the same images for our website as well as our MTA server in-game.

Test plan

I have attached a small test resource that displays two .webp images, one using dxCreateTexture and one using dxDrawImage directly with the file path. The two images are drawn one over another, to showcase the transparancy working for the second image.

webp.zip

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

Copilot AI lite review requested due to automatic review settings August 9, 2026 19:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds WebP image decoding support to the MTA client texture pipeline so .webp files (and in-memory WebP byte buffers) can be used with dxCreateTexture and related paths.

Changes:

  • Vendors and builds a decoder-only subset of libwebp and wires it into the Windows/x86 client build.
  • Extends CPixelsManager to detect WebP, read its dimensions, and decode it into PLAIN pixels.
  • Uploads decoded WebP pixels into a D3D texture when D3DX cannot decode the source format.

Note for commit hygiene (to help future maintainers): please ensure the final commit message(s) include the motivation for adding WebP, what scenarios were tested (e.g., the attached resource), and any relevant build/upgrade steps (e.g., running install_libwebp).

Reviewed changes

Copilot reviewed 9 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
win-create-projects.bat Adds install_libwebp step to the Windows project generation workflow.
vendor/libwebp/README.md Adds vendored library readme/scaffold documentation.
vendor/libwebp/premake5.lua Defines a decoder-only static library build for libwebp (Windows/x86 scoped).
vendor/libwebp/.gitignore Ignores extracted vendor contents while keeping scaffolding files tracked.
utils/buildactions/install_libwebp.lua Adds an auto-download/install action for libwebp with hash verification.
premake5.lua Requires the new install action and includes the vendor/libwebp project in the workspace.
Client/sdk/core/CPixelsManagerInterface.h Extends pixel format enum to include WEBP.
Client/core/premake5.lua Adds libwebp include paths and links libwebp into the Client Core.
Client/core/Graphics/CRenderItem.FileTexture.cpp Adds a WebP decode+manual upload path for file- and memory-backed textures.
Client/core/Graphics/CPixelsManager.cpp Adds WebP detection, size queries, and decode-to-PLAIN conversion.
Client/core/CFileFormatWebP.cpp Implements WebP magic detection, dimension parsing, and BGRA decode helpers.
Client/core/CFileFormat.h Exposes the WebP helper function declarations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Client/core/Graphics/CRenderItem.FileTexture.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 9, 2026 19:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 9 out of 12 changed files in this pull request and generated no new comments.

Suppressed comments (5)

utils/buildactions/install_libwebp.lua:100

  • This prompt uses "(Y/n)" but empty input is treated as "no". Consider changing it to "(y/N)" to match the behavior.
		io.write("Update `install_libwebp.lua` file? (Y/n) ")
		local input = io.read():lower()
		if (input == "y" or input == "yes") then
			update_install_libwebp("LIBWEBP", LIBWEBP_VERSION, downloaded_hash)

Client/core/Graphics/CRenderItem.FileTexture.cpp:144

  • The .webp fast-path bypasses the usual D3DXCreate*FromFileEx flow, so requested sizing (uiSizeX/uiSizeY) and the requested texture format (the format parameter) are ignored. This means .webp textures are always created at their native decoded size in A8R8G8B8, which is a behavioral difference vs PNG/JPG where size/format are honored.
    // D3DX cannot decode every format we support, so we need to perform the following steps:
    // Load the file, ask CPixelsManager what it is, and if it's not something D3DX can handle, convert to PLAIN and upload manually
    if (strFilename.EndsWithI(".webp"))
    {
        std::vector<char> fileBytes;

Client/core/Graphics/CRenderItem.FileTexture.cpp:260

  • In the in-memory pixels path, the WEBP branch uploads decoded pixels as a new A8R8G8B8 texture and returns early, so the format argument is ignored for WEBP buffers. If callers request a different render/texture format, behavior will differ from the D3DXCreateTextureFromFileInMemoryEx path.
    else if (inFormat == EPixelsFormat::WEBP)  // any format that D3DX cannot decode itself
    {
        CPixels plainPixels;
        if (!pPixelsManager->ChangePixelsFormat(*pPixels, plainPixels, EPixelsFormat::PLAIN))
            return;

utils/buildactions/install_libwebp.lua:145

  • When reinstalling/upgrading, the extracted libwebp sources are copied into vendor/libwebp/ without first removing previously extracted directories. This can leave stale files behind across upgrades (e.g., files removed upstream), which can cause confusing build issues.
	-- Move all files from _extract/libwebp*/* to vendor/libwebp/
	os.expanddir_wildcard(extract_dir .. "libwebp*", LIBWEBP_PATH)

	-- Clean up scratch folder
	os.rmdir(extract_dir)

utils/buildactions/install_libwebp.lua:67

  • The prompt says "(Y/n)", but the code aborts unless the user explicitly types "y"/"yes". Either accept empty input as "yes" or change the prompt to reflect that the default is "no".

This issue also appears on line 97 of the same file.

	io.write(("Does version '%s' look OK to you? (Y/n) "):format(meta["tag_name"]))
	local input = io.read():lower()
	if not (input == "y" or input == "yes") then
		errormsg("Aborting due to user request.")
		return false

@FileEX FileEX added the enhancement New feature or request label Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants