It is currently Tue Jun 27, 2017 2:08 pm

All times are UTC - 5 hours




 Page 1 of 1 [ 3 posts ] 
Author Message
 Post subject: Unions and some of their uses.
PostPosted: Thu Apr 07, 2016 11:32 pm 

Joined: Sat Aug 16, 2008 7:58 am
Posts: 447
Let's consider different encoding techniques for the color arrangement of a Pixel:


#include <iostream>

union Pixel {
    unsigned int color;
    struct {
        unsigned char r, g, b, a;
    };
};

int main() {
    Pixel p;

    p.color = 0x44332211;
    std::cout << hex;
    std::cout << static_cast<unsigned int>( p.r ) << std::endl;
    std::cout << static_cast<unsigned int>( p.g ) << std::endl;
    std::cout << static_cast<unsigned int>( p.b ) << std::endl;
    std::cout << static_cast<unsigned int>( p.a ) << std::endl;

    p.color += 0x01010101; // ++ brightness to all 4 channels at once!
    p.g = 0x99; // Change 2nd Byte to 0x99
    std::cout << hex << p.color << std::endl; // Print Final Result -> 0x45349912
    return 0;
}


With something like this; you can quickly increase the intensity to all 4 channels at once or you are able to access individual components with ease while accounting for multiple encoding types at the same time.

Note: One thing that needs to be known ahead of time is the Endianness of the machine. Most Intel Windows Machines are Little Endian, however some machines are Big Endian and due to this this union would not be immediately portable. As an example:

   
         // short  int with a value of 0x0315 stored  Note: 100 & 101 would be the memory address to each byte of the short variable and not the bit representation.

         //  Big Endian                   Little Endian
         //  ----------------             ---------------
         //  |  100  |  101 |             | 100  |  101 |
         //  ----------------             ---------------
         //  | 0x03  | 0x15 |             | 0x15 | 0x03 |
         //  ----------------             ---------------


And due to this, you can still perform the single operation across all channels, however the union does not know if this machine is Big or Little Endian and the
difference here would be the difference between adding 0x44332211 where the byte
11 is being added to the (r) or (a) channel.


Last edited by skilz80 on Sat Apr 09, 2016 6:43 am, edited 2 times in total.

Offline
 Profile  
 
 Post subject: Re: Unions and some of their uses.
PostPosted: Sat Apr 09, 2016 6:22 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
Just notice an error in your hex to binary conversion. Hex 315 can not be stored as 6 bits. Hex 315 = binary 0011 0001 0101 in little endian or 0101 0001 0011 in big endian

You can write a function to detect endian like this :

int isBigEndian() {
    union {
        uint32_t i;
        char c[4];
    } test = {0x01000000};

    return test.c[0] == 1;
}


Offline
 Profile  
 
 Post subject: Re: Unions and some of their uses.
PostPosted: Sat Apr 09, 2016 6:40 am 

Joined: Sat Aug 16, 2008 7:58 am
Posts: 447
I think you misinterpreted my tables The 100 is memory address for left most byte, and 101 is memory for right most byte. It just shows how bytes 1 & 2 would be swapped from little to big endian. The 100 and 101 are not binary sequences here. They would be memory address or location in memory for this short.


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 3 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  

cron