microsoft / DirectXTex

DirectXTex texture processing library
https://walbourn.github.io/directxtex/
MIT License
1.82k stars 447 forks source link

Saving R8_UNORM as a BMP fails #55

Closed walbourn closed 7 years ago

walbourn commented 7 years ago

If you attempt to write a BMP file using the WIC code starting with a DXGI_FORMAT_R8_UNORM image, it fails with an 'invalid argument' error.

walbourn commented 7 years ago

When you attempt to write the BMP, the WIC BMP native codec can't directly support GUID_WICPixelFormat8bppGray (the WIC format that maps from DXGI_FORMAT_R8_UNORM). Instead, it returns that it can support GUID_WICPixelFormat8bppIndexed. This is expected and supported (to need a format conversion to write), but it ultimately fails on this line of code:

hr = FC->Initialize(frame, convertGUID, _GetWICDither(flags), nullptr, 0,
    WICBitmapPaletteTypeCustom);

The problem is that WICBitmapPaletteTypeCustom means "use the palette object passed in the fourth parameter" which is always nullptr. The fix is to change it to:

hr = FC->Initialize(frame, convertGUID, _GetWICDither(flags), nullptr, 0,
    WICBitmapPaletteTypeMedianCut);

This pattern is used in many places in DirectXTex but it turns out that there's almost no case where it actually tries to convert to a paletted format--DXGI doesn't support them. It only comes up in the case where a WIC codec writer maps the input format to an indexed format. It also turned out that this isn't hit by my test code either.

walbourn commented 7 years ago

Cleaned up all of DirectXTex (and DirectXTK/DirectXTK12) to use WICBitmapPaletteTypeMedianCut instead of WICBitmapPaletteTypeCustom. Fixed in commit 0a85ac75a04dc02d29d7a658b6f985efeb81dd3c.

Also updated the test suite to do an exhaustive 'transcode' test to exercise more target pixel formats for the WIC writer.

walbourn commented 7 years ago

Fix included in the July 2017 release