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

How to properly compile/decompile DirectDraw Surface [L8] files? #25

Closed
suphamster opened this issue Jun 2, 2022 · 14 comments
Closed

Comments

@suphamster
Copy link

Hi, after compile from dds to crn and back this https://workupload.com/file/rdn35kWyDTp image not the same and looks like inverted. I've tried different settings but with no luck. Is it possible to make this tool to proccess such files by default without problems plz?
image

@illwieckz
Copy link
Member

@suphamster do you have a copy of the original image? The link is now dead.

@suphamster
Copy link
Author

@suphamster do you have a copy of the original image? The link is now dead.

https://workupload.com/file/y9Nzv9TQShM

@illwieckz
Copy link
Member

OK thanks, I reproduce the issue.

If I open the DDS in GIMP, it is displayed white. If I convert it to PNG with crunch it is displayed black.

If I convert it to CRN then to DDS back and open the DDS in GIMP, it is displayed black.

I attach the file here (with a gz container to avoid extension filter):

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

How do you know the expected color on the border is white and not black? How to make sure the mistake is to render it black and not white? Do you have the non-DDS source before being converted to DDS?

I noticed that GIMP opens this DDS as white:

20240626-105353-000 gimp-dds

But I also noticed that if I do:

crunch -file 'Wipe Pattern - Circle.dds' -out new.dds

GIMP doesn't know how to render the new DDS:

20240626-103236-000 dds-to-dds

While crunch still know how to convert it to PNG. So no I don't trust GIMP anymore…

Edit: I get the same GIMP garbage if I do:

crunch -usesourceformat -file 'Wipe Pattern - Circle.dds' -out out.dds

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

XnView MP also displays the file white, but without transparency:

20240626-104316-000 xnviewmp

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

I noticed this interesting feat:

$ file 'Wipe Pattern - Circle.dds'
Wipe Pattern - Circle.dds: Microsoft DirectDraw Surface (DDS): 64 x 64, 8-bit color, alpha only

If the file is really “alpha only”, then it means there is no RGB channel, there is no black and white in color channel. All there is is black and white in alpha channel.

What produces XnView MP is that it extracts the alpha channel and write it in RGB color. This non-transparent black and white image is the alpha channel.

What produces both Crunch and GIMP is to keep the alpha channel as alpha channel, while writing a default color in RGB, Crunch writing black, GIMP writing white. Both may be wrong and it's probably an undecidable problem because you can't convert an alpha channel to an RGBA format without creating an RGB color out of nowhere.

@illwieckz
Copy link
Member

When I open both the original DDS and a conversion in GIMP, I can see the alpha layer is always correct (white around, black in center):

DDS:

20240626-105719-000 gimp-dds

Converted file:

20240626-105723-000 gimp-dds

One can see the alpha channel on the top left, it's the channel listed at the bottom of the channel list.

@illwieckz
Copy link
Member

Now if I disable the color channels (the Grayscale one created by GIMP when importing, the RGB ones created by Crunch when converting), everything looks the same:

DDS:

20240626-105727-000 gimp-dds

Converted file:

20240626-105732-000 gimp-dds

So even GIMP assumes the default color is black (greyscale value 0, or RGB value 0, 0, 0) when there is no color channel.

@illwieckz
Copy link
Member

If the original image had no color channel, or if they were irrelevant, then I assume the black image is the correct image, because if I want to do an addition with an alpha-only image with another RGBA image and then only do the addition on the alpha channel, I would get the same result of doing the addition of an RGBA image with an RGBA image if the first RGBA image has 0 RGB colors.

When an image is missing channels, the default value for RGB channels are 0 (black, no color), while the default value for Alpha channel is 1 (white, fully opaque).

So what does Crunch looks correct to me.

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

171743703-97686ddd-131a-4ce5-a6be-1fd2bfb6d7e1

On this image on the left we have the alpha channel displayed alone as a color.

On the right we have the exact same alpha channel rad the same way but rendered as a transparency, with missing RGB being set to zero because they are missing.

So basically on the left is a representation of the alpha data itself, on the right is the representation of the transparency coded by the same alpha data, applied over a default empty (zero RGB) image.

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

I guess the problem is that CRN doesn't support L8/A8 format, so converting from DDS A8 to CRN produces an RGBA8 image, and converting it back to DDS keeps the RGBA8 format, with the useless empty RGB channels.

Quote from crunch --help:

All supported texture formats (Note: .CRN only supports DXTn pixel formats):
-DXT1
-DXT2
-DXT3
-DXT4
-DXT5
-3DC
-DXN
-DXT5A
-DXT5_CCxY
-DXT5_xGxR
-DXT5_xGBR
-DXT5_AGBR
-DXT1A
-ETC1
-ETC2
-ETC2A
-ETC1S
-ETC2AS
-R8G8B8
-L8
-A8
-A8L8
-A8R8G8B8

So, to convert the image from DDS to CRN then back from CRN to DDS, one should do:

# Convert A8 DDS to RGBA8 CRN with added zero RGB
crunch -file 'Wipe Pattern - Circle.dds' -out 'out.crn'
# Convert RGBA8 CRN to A8 DDS by selecting the CRN alpha channel to be used as DDS only channel
crunch -A8 -file 'out.crn' -out 'out.dds'

Note the -A8 option when converting back from CRN to DDS.

If you don't use the -A8 option it will copies all the channels, so the empty RGB channels plus the Alpha one.

If you use the -L8 option instead, it will copy the RGB channels as a single greyscale one (I guess L is for “Level” like in “gray level”) and drop the Alpha channel, meaning the produced DDS would be fully black.

I guess Crunch could benefit from an option to automatically drop the RGB channels and write an A8 DDS when detecting all the RGB channels are set to zero (this may make them smaller), but what it does when converting from CRN to DDS is not wrong: the CRN has RGB channels for real even if empty, because CRN doesn't support the A8 format.

@illwieckz
Copy link
Member

$ crunch -file 'Wipe Pattern - Circle.dds' -out 'out.crn'
Source texture: 64x64, Levels: 1, Faces: 1, Format: A8
Apparent type: 2D map, Flags: A Non-Flipped
Writing DXT5 texture to file: "out.crn"
Input texture: 64x64, Levels: 1, Faces: 1, Format: A8
Output texture: 64x64, Levels: 1, Faces: 1, Format: DXT5

$ crunch -A8 -file 'out.crn' -out 'out.dds'
Source texture: 64x64, Levels: 1, Faces: 1, Format: DXT5
Apparent type: 2D map, Flags: R G B A Non-Flipped
Converting texture format from DXT5 to A8
Writing texture to file: "out.dds"
Input texture: 64x64, Levels: 1, Faces: 1, Format: DXT5
Output texture: 64x64, Levels: 1, Faces: 1, Format: A8

We can see that converting from DDS to CRN:

  • converts from Format: A8 (2D map, Flags: A Non-Flipped) to Format: DXT5.

While converting from CRN to DDS with -A8:

  • converts from Format: DXT5 (2D map, Flags: R G B A Non-Flipped) to Format: A8.

@illwieckz
Copy link
Member

So, for now I will consider there is no bug.

Though there are features that would be welcome:

  • An option to convert an A8 image to a greyscale image (export the alpha channel as a greyscale image);
  • An option to drop the RGB channels and store the DDS image as A8 if RGB is empty.

When converting from DDS to PNG/TGA, the first feature can be done with third-party tools once the PNG is generated, it's a matter of movng channels from Alpha to Grey (or RGB).

When converting from PNG/TGA/CRN to DDS, the second feature is doable with the explicit -A8 option.

@illwieckz
Copy link
Member

illwieckz commented Jun 26, 2024

I'll close this for now, thank you @suphamster for the feedback and providing the sample image to make the investigation possible.

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

No branches or pull requests

2 participants