Skip to content

Implement FlipRotate without WIC for non-Windows platforms - #746

Open
Joel Kiptoo (Kiptoo-Deus) wants to merge 1 commit into
microsoft:mainfrom
Kiptoo-Deus:fliprotate-non-wic
Open

Joel Kiptoo (Kiptoo-Deus) wants to merge 1 commit into
microsoft:mainfrom
Kiptoo-Deus:fliprotate-non-wic

Conversation

@Kiptoo-Deus

Copy link
Copy Markdown

Fixes #350.

FlipRotate was the only image operation that always used WIC, so DirectXTexFlipRotate.cpp was only built on Windows and the functions were declared under #ifdef _WIN32.

This builds it on all platforms. On Windows nothing changes: the WIC path and the float16/float32 conversion path are the same code, now inside #ifdef _WIN32. On other platforms, a new PerformFlipRotate moves whole pixels directly:

  • Supported: formats that are not compressed, packed, planar or palettized and have a whole number of bytes per pixel (8 to 128 bits). Other formats return HRESULT_E_NOT_SUPPORTED, checked before the result is allocated.
  • Rows are copied with a single memcpy when there's no horizontal flip and no 90/270 rotation.
  • Combining a rotation with a flip: the WIC documentation doesn't say which is applied first. I followed Wine's IWICBitmapFlipRotator (dlls/windowscodecs/fliprotate.c), where the flip is applied to the source before the rotation (e.g. TEX_FR_ROTATE90 | TEX_FR_FLIP_HORIZONTAL is an anti-transpose). I couldn't check this against WIC itself, so it would be worth confirming on Windows. It only matters for a 90/270 rotation combined with exactly one flip.

Testing on macOS (arm64, Apple clang), building DirectXTex with its own CMake against the vcpkg directx-headers and directxmath ports:

  • The library builds with DirectXTexFlipRotate.cpp included, with no new warnings.
  • A test compares both FlipRotate overloads against a straightforward reference (flip the source, then rotate clockwise in 90 degree steps) for every rotation/flip combination, on a 7x5 image with 3 array slices, in R8_UNORM, R16_UNORM, R8G8B8A8_UNORM, R16G16B16A16_FLOAT, R32G32B32_FLOAT and R32G32B32A32_UINT (1 to 16 bytes per pixel). It also checks that BC1_UNORM, NV12, YUY2, R1_UNORM, P8 and R8G8_B8G8_UNORM return HRESULT_E_NOT_SUPPORTED, and that null pixels return E_POINTER. 187 checks pass.
  • Making the reference rotate first and flip second fails exactly the 48 cases combining a 90/270 rotation with a single flip, so the test does pin down the order.

I haven't built the Windows configurations. The only change there is the added #ifdef _WIN32 guards around the existing code.

FlipRotate was the only image operation that always needed WIC, so it
was not available when building for Linux / WSL.

On non-Windows platforms it now moves whole pixels directly, for any
format with a whole number of bytes per pixel that is not compressed,
packed, planar or palettized (others return HRESULT_E_NOT_SUPPORTED).
Flips are applied to the source before the rotation, which is how WIC
combines WICBitmapTransformOptions. The Windows code paths are unchanged.

Fixes microsoft#350
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@walbourn Chuck Walbourn (walbourn) added the wsl Related to Windows Subsystem for Linux support label Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wsl Related to Windows Subsystem for Linux support

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FlipRotate not supported for the Linux platform

2 participants