Advertisement

How to convert RGB to ARGB

Started by August 23, 2019 06:06 AM
13 comments, last by Zakwayda 5 years, 5 months ago
12 minutes ago, hoahong said:

rgbP[i * 4]

You need to multiply by 3 for RGB because there are only 3 channels.

 

12 minutes ago, hoahong said:

it does not display anything

Can't tell why without seeing more of your code.

There's been some discussion here of the original code being incorrect. I'm not saying it's not, but some of the specific things that have been mentioned about it seem possibly mistaken to me. So I'll just point out here that the original code a) interprets blocks of bytes as multi-byte integers, and b) unrolls the loop to process 4 pixels at a time. It might be worth taking another look at the code with those things in mind to see if it is in fact incorrect as claimed.

Quote

Why is your pixelCount 800*600 but in RGB2RGBA you check that it is divisible by 3 while in the loop...

I believe it's checking that it's divisible by 4, not 3 (4 would make sense in the given context).

As for assuming little endian, both that and the size of unsigned integers are assumed, but it seems possible the OP could be working in an environment where these parameters are known.

Quote

Label your data properly (r,g,b,a instead of c1-c4) to understand what you are doing and to figure out whether you are swapping channels accidentally.

If I'm reading the code correctly, c1-c4 is in fact appropriate/correct in that those values refer to pixel/color values and not color components.

@The OP: It's possible that the other posters are correct here and I'm wrong. In any case, an underlying issue here may be that you've gotten the code from somewhere else and don't fully understand it yourself. I mention this not to criticize but, I hope, to be helpful, in that if you were to figure out the code in detail yourself, you could determine both whether it's correct or (as some here have claimed) incorrect, and also how to adapt it for ARGB.

Advertisement

Oh, yeah. The original code was confusing me (guess I was too tired). It actually checks that the pixelCount is divisible by 4, not 3. And it actually copies the RGB color for 4 pixels and adds 255 as alpha value. But the problem with little endian and reading after the allocated memory still exists. It's just one byte over but that still may make the app crash. And it's reading and potentially writing uint unaligned (normally alignment should be 4 bytes for 4 byte data types) which might not be supported on all CPUs, especially some embedded processors.

6 minutes ago, Magogan said:

Oh, yeah. The original code is confusing me. It actually checks that the pixelCount is divisible by 4, not 3. And it actually copies the RGB color for 4 pixels and adds 255 as alpha value. But the problem with little endian and reading after the allocated memory still exists.

It does seem like the very last pixel read will read one byte past the end of the input data (I assume this is what you're referring to).

In terms of the actual result, it seems like this doesn't matter because that value is going to be overwritten. As for safety, I don't know what the potential implications of an out-of-range read are in C#, so I can't comment on that. It does seem like a conceptual error though, at the very least.

Possible solutions might be to add an additional byte to the input data, or to process the last four pixels using different code. (I'm sure there are other ways the problem could be addressed as well.)

I gather from the original Stack Overflow thread that the goal here is optimization, and I don't know enough about the context to know if the strategy being employed here is sound overall. Maybe a more straightforward implementation would be sufficient (perhaps along with multithreading).

I mentioned earlier that integer size was assumed, but since this is C# presumably that's not an issue. Endianness could be an issue, as you mention, although again it seems possible the OP is working in an environment in which endianness is known. (Don't get me wrong - I'm all for portability. I'm just saying it may or may not be a problem in the given context.) In any case, it's certainly something that should be taken into consideration.

This topic is closed to new replies.

Advertisement