-3

I have packed data of rgba values in an 16 bit short, so for each channel goes 4bit, how can I change specific channel only, lets say I want to change red channel to it's value devided by two. I know how to change specific bits in an int but changing bit by bit would be very slow and tiresome.

So in code First I save RGBA values in a short:

RGBA = R | (G << 4) | (B << 8) | (A << 12)

Then I want to change 'A' part of the RGBA short to A / 2.

G.Azma
  • 37
  • 9
  • 4
    how did you get the rgba values into the short in the first place? It is unclear why you got that but don't know how to modify the values. Perhaps some code would help to clarify – 463035818_is_not_an_ai Aug 17 '21 at 13:32
  • Show us your attempt so we can help you. Writing your code from scratch isn't what we do here. – nicomp Aug 17 '21 at 13:32
  • I am making minecraft clone, where I need to save as much memory as possible, so am saving light red, green, blue and intensity values in a short – G.Azma Aug 17 '21 at 13:34
  • Most likely [bit manipulation - How to replace bits in a bitfield without affecting other bits using c - Stack Overflow](https://stackoverflow.com/questions/5925755/how-to-replace-bits-in-a-bitfield-without-affecting-other-bits-using-c) (that one is for C not C++) – user202729 Aug 17 '21 at 13:35
  • Please include a [mcve] of your code in the question. You are asking to avoid something "slow and tiresome" but it is unclear what that something is exactly – 463035818_is_not_an_ai Aug 17 '21 at 13:36

2 Answers2

3

If you don't care about the order of the bits (for example, don't need that for serialisation purposes), then this is a good use case for bitfields. Example:

struct RGBA {
    std::uint16_t r : 4;
    std::uint16_t g : 4;
    std::uint16_t b : 4;
    std::uint16_t a : 4;
};
RGBA rgba = {r, g, b, a};
a = rgba.a; // read a from rgba

If you do need to have a std::uint16_t with the bits in particular order, then you can use the bitwise operators instead.


So in code First I save RGBA values in a short:

 RGBA = R | (G << 4) | (B << 8) | (A << 12)

Then I want to 'A' part of the RGBA short

Like this:

A = (RGBA >> 12) && 0xF;

You technically don't need the masking in the case of A because it's going to be zeroes, but you do need it for all others to mask out the higher bits.

eerorika
  • 232,697
  • 12
  • 197
  • 326
-1

Sorry I was unclear what I was asking, I figured it out, I just have to get A value from RGBA as eerorika said and save it to another short called Aval:

unsigned short Aval = RGBA >> 12;

then reset A part of RGBA to 0 so:

RGBA &= (0xF << 12); 

and then change Aval to whatever you want and then save it to RGBA short's A part:

RGBA |= Aval << 12;
G.Azma
  • 37
  • 9