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

iOS 17 ImageIO indexed color png decode problem #3648

Closed
a1003625282 opened this issue Dec 7, 2023 · 27 comments
Closed

iOS 17 ImageIO indexed color png decode problem #3648

a1003625282 opened this issue Dec 7, 2023 · 27 comments
Labels
apple bug apple's bug cause our framework author's pain discussion

Comments

@a1003625282
Copy link

switch (byteOrderInfo) {
    case kCGBitmapByteOrderDefault: {
        byteOrderNormal = YES;  // why is not set to NO?
    } break;
    case kCGBitmapByteOrder16Little:
    case kCGBitmapByteOrder32Little: {
    } break;
    case kCGBitmapByteOrder16Big:
    case kCGBitmapByteOrder32Big: {
        byteOrderNormal = YES;
    } break;
    default: break;
}

In kCGBitmapByteOrderDefault IOS is a Little-endian, why byteOrderNormal is it not set to NO?
The modified code is as follows
switch (byteOrderInfo) {
case kCGBitmapByteOrderDefault: {
byteOrderNormal = NO; //set to NO
} break;
case kCGBitmapByteOrder16Little:
case kCGBitmapByteOrder32Little: {
} break;
case kCGBitmapByteOrder16Big:
case kCGBitmapByteOrder32Big: {
byteOrderNormal = YES;
} break;
default: break;
}

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

You misunderstand that code. The endian is about whether the order of pixel array UInt[] is the same as CGAlphaInfo order. The non-defaults means we need when we see .alphaLast,it's ABGR not RGBA, we need to use RGBA[3] to the first R.

It's not about the memory order to read bytes.


Any real problem about this ? I don't understand why you only pick these line of code snippet. Like bug report ?

For example, if you want to know the https://github.com/dreampiggy/iOS17IndexedPNGDecodeBug solution, check #3605 and use v5.18.5+

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

If you'd like, I can rename this local variable into alphaOrderIsNormal or pixelOrderIsNormal, or garden PR is welcomed.

@dreampiggy dreampiggy added the apple bug apple's bug cause our framework author's pain label Dec 8, 2023
@a1003625282
Copy link
Author

I'm not saying there's a problem with the variable name, I'm saying that kCGBitmapByteOrderDefault is supposed to correspond to Little-endian in IOS, meaning that RGB is inverted. Your fetch should be inverted. So the byteOrderNormal variable should be set to NO for kCGBitmapByteOrderDefault.

@dreampiggy
Copy link
Contributor

I'm saying that kCGBitmapByteOrderDefault is supposed to correspond to Little-endian in IOS

Do you, actually see, any CGImageGetByteOrderInfo, return kCGImageByteOrderDefault ?

I assume this is set-only enum, when you get from the CGImage from anywhere, it can never return the enum case.

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

Just to clarify:

Read code and report issue about code style or function is meaningless for most cases....

Is there any bug or runtime issue because of this line ?

I want to knwo what's your actual propose (feature request or bug report)

@a1003625282
Copy link
Author

runDemo

@a1003625282
Copy link
Author

I run your demo and it returns kCGImageByteOrderDefault.

@dreampiggy
Copy link
Contributor

So, you means when see kCGImageByteOrderDefault

And alphaInfo is kCGImageAlphaLast

I should assume the UInt8[4] to be ABGR but not RGBA?

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

Wrong. See:

image

This PNG is created by me. It's rgba(50, 50, 50, 50/255)

So, the alpha should always be 50. The R/G/B is premultiplied to be 10

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

So your guess that when see kCGImageByteOrderDefault, we should treat the RGBA to be ABGR is wrong.

It's should be when see kCGImageByteOrderDefault, we should treat the RGBA to be RGBA

@a1003625282
Copy link
Author

Indeed, my guess is wrong.

@dreampiggy
Copy link
Contributor

Read code and report issue about code style or function is meaningless for most cases....

@a1003625282
Copy link
Author

So kCGImageByteOrderDefault in IOS we can consider it big-endian right?

@a1003625282
Copy link
Author

Thank you for your answer

@dreampiggy
Copy link
Contributor

This enum does never represent indian or byte order

@a1003625282
Copy link
Author

So what does it stand for? I was just trying to figure out what it meant by naming it byteOrderInfo.

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

This only a hint because Apple, can not extend the CGBitmapInfo to introduce more color format, like BGRA instead of RGBA

They want to represent this. So a clever people introduce a new enum CGBitmapByteOrder. Which by combine the both original alphaInfo and byteOrderInfo, you get the final color format.

For example:

  • alphaInfoLast + none => RGBA
  • alphaInfoFirst + none => ARGB
  • alphaInfoLast + little32 => ABGR
  • alphaInfoLast + little16 => ABGR16161616 (UInt16 instead of UInt8)

default order means little32 in practice, though they don't have official documentation. (https://developer.apple.com/forums/thread/95790)


I remember when I firstly see this enum, I read another image processing library and they alias to little32, so I just use that code. It seems to be correct.

@dreampiggy
Copy link
Contributor

Just to be simple:

CGBitmapInfo can represent kCVPixelFormatType

CGBitmapInfo use alphaInfo + byteOrderInfo + floatMask 3 combination to repsent the complicated color format

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

You can also run SDWebImage's SDImageTransformerTests test22CGImageCreateScaledWithSize and SDAssertCGImageFirstComponentWhite and debug with the behavior. (

)

Which test the RGB888, RGB16161616, ARGB8888, RGBA16161616, RGBAFFFF combination of color format

@a1003625282
Copy link
Author

That's awesome

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

Actually, on Apple's platform (without the old history PowerPC (big endian)), all Intel/M1 Mac/iPhone... are little indian

You just read the pixel in bytes in memory (using little-endian if you use debugger or dump RAM into disk), force-cast into uint8_t * or uint16_t * or float * and loop pixels.

It's about image processing I guess and Apple already provide many utils like vImage to handle this, the 99% people don't need to write code about this.

@dreampiggy
Copy link
Contributor

When you see CGImageByteOrder it DOES NOT means when you want to read uint16_t, you should read first 8 bytes (HEX value) from left to right, and next 8 bytes from left to right.

You always need to read first 8 bytes from right to left, then 8 bytes from right to left. No matter what CGImageByteOrder is.

And then, you need to translate the Meaning of bytes into Color pixel. You need that CGImageByteOrder for help.

Assume you get uint16_t to be 65535, you need to convert to Color pixel number. When you see CGImageByteOrder16Little + AlphaLast, it's Red color.

When you see CGImageByteOrder16Little + AlphaFirst, it's Alpha color

When you see CGImageByteOrder16Big + AlphaLast, it's Alpha color

When you see CGImageByteOrder16Big + AlphaFirst, it's Red color

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

So this is why I say It's not about indian, it's about pixel order...

It's not about How you read bytes, but actually How that represent the color pixel format

@a1003625282
Copy link
Author

Your answer is very good, I am a junior IOS developer from Beijing (just graduated 5 months ago), I want to learn SDWebImage, I hope to become a SDWebImage Maintainer in the future, I don't have any image rendering basics, do you have any learning suggestions?

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

Misunderstand your question. The below it's SDWebImage's design, not Image Processing


See this:
https://github.com/SDWebImage/SDWebImage/wiki/5.6-Code-Architecture-Analysis

Chinese version:
https://looseyi.github.io/post/sourcecode-ios/source-code-sdweb-1/

@dreampiggy
Copy link
Contributor

dreampiggy commented Dec 8, 2023

For Image Processing, maybe my blog can help for you ? It's all about something on Apple's platform (not about DSP, but the API and knowledge before you write code)

https://dreampiggy.com/tags/Image/

There are 3 blogs about Apple's ImageIO/vImage/libwebp

And some other blogs about other thing like SF symbols, lottie...

@a1003625282
Copy link
Author

Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apple bug apple's bug cause our framework author's pain discussion
Projects
None yet
Development

No branches or pull requests

2 participants