• Advertisement
Sign in to follow this  

decompositing and recompositing color (pixel)

This topic is 1391 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In my kind of app i quite often need to do that, color of the pixel is usually unsigned value in the format of ARGB so to do something with it (like dimming color mixling, adding etc) I need to decomposite it something like that

 

int red = (color >> 16) & 0xff;

int green = (color >> 8) & 0xff;

int blue = (color ) & 0xff;

 

then do something with this then recomposite this like

 

if(red<0) red = 0;

if(green<0) green = 0;

if(blue<0) blue = 0;

 
if(red>255) red = 255;
if(green>255) green = 255;
if(blue>255) blue = 255;
 
color = (red <<16) + (green<<8) + blue;
 
this strikes me both as an ugly and probably inefficient.. is there maybe some
way to make this better? (this decomposition and recomposition )
 

yet if doing this what should i use for this intermediate values (I mark bold up there)

should it be int or maybe unsigned char?

 

Share this post


Link to post
Share on other sites
Advertisement
int red = (color >> 16) & 0xff;
int green = (color >> 8) & 0xff;
int blue = (color ) & 0xff;

 

Why store them in a int? Use a BYTE instead(or even better, a struct of 3 bytes), which make this

 

Ex: BYTE red = (BYTE)((color >> 16) & 0xff);

 


if(red<0) red = 0;
if(green<0) green = 0;
if(blue<0) blue = 0;

if(red>255) red = 255;
if(green>255) green = 255;
if(blue>255) blue = 255;

 

totally unnecessary.

 

When "recomposing", use a DWORD or UINT instead of a int, no need for a signed variable in this code.

Edited by Vortez

Share this post


Link to post
Share on other sites

 

Why store them in a int? 

 

some operations on such r g b are making overflow (for example adding on ergb to another) often i need a saturation there so need to use int and yet clip it with ifs - though such ynpacking and repacking seem overhead to me but i dont know what to do with that

 

also for cases when unsigned char would suffice im not sure if stating unsigned char, r, g, b will not do paradoxally things slower as compiler would need to do such arithmetic constrained to unsigned char where

it may be easier to him operate on processor words - hard to say,

 

in general passing color as one unsigned int is more handy to me but it seem (though not sure if it has some "> 0" effect on real efficiency) that passing this as separate three values and thus avoiding some of this unpackin/packing could be (theoretically) a bit quicker- but as i said

im not quite sure

Share this post


Link to post
Share on other sites

I agree with Vortez. Optimize it when it becomes a problem. Unless you are doing some serious image processing it shouldn't be a big problem.

 

I would also recommend packing the color in struct

struct Color
{
    unsigned char r, g, b, a;

    // constructors, operators, ect
};

Behind the scenes, the compiler will be doing the bit mask and bit shifts for you but with much cleaner code.

 

EDIT: I assumed you are using c++. Is that correct?

Edited by HappyCoder

Share this post


Link to post
Share on other sites

EDIT: It's late...

 

Like everyone else in this thread, I think these kinds of micro-optimizations are usually wasted effort. If I were you, I would try to determine if I was performing more decomposition/recompositions than I needed to and try to minimize that, first. I usually find way bigger performance gains by making my code do less stuff than I do by trying to make my code do more stuff quickly.

Edited by Samith

Share this post


Link to post
Share on other sites

I agree with Vortez. Optimize it when it becomes a problem. Unless you are doing some serious image processing it shouldn't be a big problem.

 

I would also recommend packing the color in struct

struct Color
{
    unsigned char r, g, b, a;

    // constructors, operators, ect
};

Behind the scenes, the compiler will be doing the bit mask and bit shifts for you but with much cleaner code.

 

EDIT: I assumed you are using c++. Is that correct?

 

im using c [but compile in c++ mode ]

 

this with struct is maybe a good hint, tnx, i forgot this option

 

1) if my color mode is ARGB , i mean blue is lowest bits (0-7)

shouldnt it be 

 

struct Color { unsigned char b, g, r, a};

 

 

Im not sure if such structs are organized in the endiann of machine

 or endian independant 

 

then i could probably use it the way with casting

 

though Im not shure if I would use it how it would be passed and hold in the memory and code (if in one register or if in 4?) - if i just will pass this by value foo(Color color) will it be passed just like 32bit unsigned int

or in some other way?

 

 

As to "advices" dont do that - I was writing about this before - this is not an answer but the thing i call "propaganda" (this is more trashing this forum (with unvaluable propaganda that is repeated with no change) than proper technical speakin), also this "profile your code to find if this is a bottleneck" is a propaganda - i hear it 20-th time here (literrally! or close about) so no need to repeating 60-th 70-th time

- specifically as im doing proffiling propably 100X more than those propaganda givers 

 

((1)accidentally this is in my bottleneck code of some shading /coloring 100k triangles per frame (even if it would be not i just like to understand some code so propaganda is not suitable for this attitude (2) as to such optymizations i often profile and optymize and find in group all this kind or microoptymizations speeds up my code on the contrary to the propaganda people here say

(recent case i started with frame time nearly 35 ms when searching hardly for any case of microoptymizations i could use in my mind droppeddown to 16.5 ms )

Edited by fir

Share this post


Link to post
Share on other sites

Not really an optimization, but I'd like to throw a little fuel on the fire...

union uColor {
  struct {unsigned char blue, green, red, alpha;};
  unsigned int uint;
  unsigned char channels[4];
};

More importantly, take my advice and use a profiler on your code before you try to optimize it.

Share this post


Link to post
Share on other sites

As to "advices" dont do that - I was writing about this before - this is not an answer but the thing i call "propaganda" (this is more trashing this forum (with unvaluable propaganda that is repeated with no change) than proper technical speakin), also this "profile your code to find if this is a bottleneck" is a propaganda - i hear it 20-th time here (literrally! or close about) so no need to repeating 60-th 70-th time


You know, I was about to give you a code snippet that shows, how this can be done in SSE using pack/unpack instructions, but man, you really have a way of discouraging people from helping you.

Share this post


Link to post
Share on other sites

 

As to "advices" dont do that - I was writing about this before - this is not an answer but the thing i call "propaganda" (this is more trashing this forum (with unvaluable propaganda that is repeated with no change) than proper technical speakin), also this "profile your code to find if this is a bottleneck" is a propaganda - i hear it 20-th time here (literrally! or close about) so no need to repeating 60-th 70-th time


You know, I was about to give you a code snippet that shows, how this can be done in SSE using pack/unpack instructions, but man, you really have a way of discouraging people from helping you.

 

heh, if you are interested in such optymizations i think you should better understand what im saying about this antyoptymizing (and mertithoricaly invaluable propaganda that is so often repeated here) - but you seem not - but imo you should

what is so hard to understand here - those propaganda is realy invaluable for someone who want to do this anyway ;\

 

sse intrinsics? ye i forgot i had to learn it ;k

Edited by fir

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement