Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stb_image: support horizontally flipped TGA images #1667

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

illwieckz
Copy link

The TGA format is a bottom-left format by default: the first byte of the first column is expected to be displayed at the bottom-left of the screen, this behavior is inherited from devices painting the screen from the bottom left to the top right.

The TGA format provides two bits in the image descriptor byte to paint the data from other sides. The 4th bit tells the device to paint the screen from right-to left and the 5th bit tells the device to paint the screen from top to bottom.

So basically:

  • 00: from bottom-left to top-right
  • 01: from top-left to bottom-right
  • 10: from bottom-right to top-left
  • 11: from top-right to bottom-left

Previously stb_image only read the 5th bit and then only supported the loading of vertically flipped images, stb_image was ignoring the 4th bit coding the horizontal flip. Now both flipping directions are supported for both raw and RLE storage.

The TGA format is a bottom-left format by default: the first byte
of the first column is expected to be displayed at the bottom-left
of the screen, this behavior is inherited from devices painting the
screen from the bottom left to the top right.

The TGA format provides two bits in the image descriptor byte to paint
the data from other sides. The 4th bit tells the device to paint the
screen from right-to left and the 5th bit tells the device to paint
the screen from top to bottom.

So basically:

- 00: from bottom-left to top-right
- 01: from top-left to bottom-right
- 10: from bottom-right to top-left
- 11: from top-right to bottom-left

Previously stb_image only read the 5th bit and then only supported the
loading of vertically flipped images, stb_image was ignoring the 4th bit
coding the horizontal flip. Now both flipping directions are supported
for both raw and RLE storage.
@illwieckz
Copy link
Author

This patch was first implemented in DaemonEngine/crunch#68 for usage in Dæmon Crunch and crnlib.

This was tested against existing raw TGA test files already provided in that other Crunch repository, and additional RLE TGA test files provided with that PR on Crunch side. The raw TGA ones are from:

They are generated with a script I wrote for the only purpose of generating those reference images for debugging image libraries and tools. The RLE TGA images were converted from the raw TGA ones using GIMP and some tweaks, as the GIMP exporter only supports bottom-left and top-left:

  • Left ones are unmodified GIMP export.
  • Right ones are in-GIMP horizontally flipped images exported as left ones then the TGA X flip bit was modified by hand in a hex editor.

The Dæmon Crunch CI tests the consistency of the conversion of those files using stb_image on every PR and master branch push. So this code was not only tested before submission but is expected to be kept as part of out standard tests in the future.

When testing the patch I noticed my TGA test images were not catching all the possible mistakes, so I used more random images to check for consistency and I may update the test TGA images from my test image gitlab repo one day. Anyway, this code is now strongly tested with the Dæmon Crunch CI, and other test images from that repository already fill the remaining need for testing what the TGA test files were not complete for.

For the own usage of the free open-source Unvanquished game, We are in need for a reliable tool we can recommend to our contributors, such a tool should be able to convert TGA to PNG, as TGA is the de-facto legacy idTech3 lossless image format and we prefer to store PNG or WebP images in repository (and cwebp expects PNG as input), so we need to reliably convert TGA files to PNG.

We used to use ImageMagick convert in the past but it is not reliable anymore and may never be: 1. it is known to be buggy for years. 2. It is also well known that there is no way to know if a given ImageMagick convert version is affected or not¹. 3. The bug is considered to not be a bug by the maintainer despite countless reports by many different people and a still considered not a bug after a complete study having been published with an alternate from-scratch implementation² written against the specifications to compare, and this verifying the bug.

The Dæmon Crunch repository being a required dependency of our game engine and a required component of our data production pipeline, that crunch tool is for us the best candidate for a recommended tool for converting TGA files to PNG, as we already maintain it and make sure it works and is available to contributors.

Since Crunch relies on stb_image for reading TGA files, by improving stb_image we hope to get a reliable image conversion tool we can trust and recommend.

For reference, here are the TGA specifications this patch has been written against:

@nothings
Copy link
Owner

Given that it sounds like this literally never occurs in the wild, it would be better to make the change as small as possible. Is it possible to use the second loop which swaps the pixels for all cases, instead of having two versions?

Repository owner deleted a comment from Ernesto-Alves67 Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants