Kha icon indicating copy to clipboard operation
Kha copied to clipboard

kha.Image.at returns incorrect color on Kore targets

Open Joncom opened this issue 6 years ago • 6 comments
trafficstars

When reading from a 0x016F52 colored image using kha.Image.at, I expect the result to be 0xFF016F52. However, I'm getting 0xFF526F01 instead. It would appear the 1st and 3rd least significant bytes (the red and blue bytes) are getting swapped for some reason.

Joncom avatar Feb 26 '19 09:02 Joncom

I wonder if this is related (quote from https://bjango.com/articles/pngcompression/):

In an effort to dramatically increase drawing performance of iOS apps, Xcode re-compresses PNG files as it builds. It premultiplies the alpha channel and byte swaps the red, green and blue channels to be sequenced blue, green and red.

Seems this could possibly explain why the RGB bytes are now ordered BGR.

Joncom avatar Feb 27 '19 09:02 Joncom

No, it isn't, khamake prevents that png madness which Xcode tries to do. https://github.com/Kode/Kore/blob/master/Sources/Kore/Graphics1/Image.cpp#L325 just needs some more logic for different formats.

RobDangerous avatar Feb 27 '19 09:02 RobDangerous

screen shot 2019-02-27 at 5 10 46 pm

The format is RGBA32 and pulls the correct bytes, but in the wrong order (~~order appears to be ABGR instead of RGBA~~).

@RobDangerous, what king of logic are you suggesting? Could it be as simple as reversing the byte order before returning?

I wonder if all Kore targets have this issue (not just iOS)?

Joncom avatar Feb 27 '19 10:02 Joncom

Android-native appears to be affected as well. Updating title of this issue accordingly.

Joncom avatar Feb 28 '19 11:02 Joncom

The following patch fixed the issue for me on both iOS and android-native:

diff --git a/Kha/Backends/Kore/kha/Image.hx b/Kha/Backends/Kore/kha/Image.hx
index b011dd1a..d67a3c98 100644
--- a/Kha/Backends/Kore/kha/Image.hx
+++ b/Kha/Backends/Kore/kha/Image.hx
@@ -292,7 +292,21 @@ class Image implements Canvas implements Resource {
                return true;
        }

-       @:functionCode('return texture->at(x, y);')
+       @:functionCode('
+               int color = texture->at(x, y);
+
+               unsigned char *r = (unsigned char *)&color;
+               // unsigned char *g = (unsigned char *)&color + 1;
+               unsigned char *b = (unsigned char *)&color + 2;
+               // unsigned char *a = (unsigned char *)&color + 3;
+
+               // Not sure why, but red and blue bytes are swapped, so swap them back.
+               unsigned char temp = *r;
+               *r = *b;
+               *b = temp;
+
+               return color;
+       ')
        private function atInternal(x: Int, y: Int): Int {
                return 0;
        }

Joncom avatar Mar 01 '19 12:03 Joncom

@RobDangerous, would it be OK to send this up as a pull-request? I'm still not really sure about this issue as a whole. I have no idea why the red and blue bytes are swapped...

Joncom avatar Mar 01 '19 12:03 Joncom