Kha
Kha copied to clipboard
kha.Image.at returns incorrect color on Kore targets
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.
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.
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.

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)?
Android-native appears to be affected as well. Updating title of this issue accordingly.
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;
}
@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...