Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have a raw12 file(4096 * 3072 ) where RGGB(odd rows RGRG..And even GBGB...) Pixels are stored ,12 bit for each .I have to  use only 5 bit MSB data from each 12 bit data , I have to take 64 bit at a time for cache optimization and use bit manipulation to get 5 MSB bits for each 12 bit pixel,I am not getting , How should I achieve this ? 
 This is code I wrote and working properly but rather than taking 8 bit at a time(buffer is 8bit pointer) I have to take 64 bits .  In buffer I have pointed complete file. *This code is to make a histogram.

Taking LITTLE ENDIAN into consideration

code is in C .


What I have tried:

for(int i = 0; i < length; i += 3){
       if (i % (3 * 2 * num_cols / 2) < num_cols * (3) / 2) {       /* ODD ROW */
          hist[0][buffer[i] >> 3]++;                                /* CH[0] */
          hist[1][buffer[i+1] & 0x0F << 1 |                         /* CH[1] */
                   buffer[i+2] >> 7]++;
        } else {                                                    /* EVEN ROW*/
          hist[2][buffer[i] >> 3]++;                                /* CH[2] */
          hist[3][buffer[i+1] & 0x0F << 1 |                         /* CH[3] */
                buffer[i+2] >> 7]++ ;
        }
    }
Posted
Updated 27-Mar-19 3:57am
v4
Comments
[no name] 26-Mar-19 15:33pm    
Seriously?

if (i % (3 * 2 * num_cols / 2) < num_cols * (3) / 2) { /* ODD ROW */

The rest of "your code" smells too.
Stefan_Lang 27-Mar-19 4:35am    
While Gerry could have been more ... verbose, he does have a point: you're putting a lot of calculation steps into each expression. This makes it very hard to follow what you're trying to do, and it's a huge source of mistakes as is clearly visible in the if condition Gerry quoted: you're comparing a modulus against an integer - no matter what, this is never a good idea, and typically indicates a mistake. It's on the same level as comparing signed to unsigned values, degrees in the range of -180 to 180 do a degree value between 0 and 360, or even inches to millimeters, degrees to radians.

Likewise, the expressions to extract the 12 bit values from your buffer do a lot of things at the same time, and between operator precedence ruless, endianness and usage of bitwise and logical operators these expressians are a total mess: it's near impossible to say what they are calculating. You really must split up your code into simple expressions and then use the debugger to make sure that at each step your intermediate values are what you expect.

1 solution

I would try to make things simpler and functional first and then address the speed. Speed means nothing when the code doesn't work in the first place. Try something like this :
const int width = 4096;
 typedef union
 {
     UCHAR byte;
     struct nibble
     {
         UCHAR first : 4;
         UCHAR second : 4;
     } nibs;
 } bytenib;

 bytenib byte2;
 UCHAR byte1;
 UCHAR byte3;
 USHORT pixel1;
 USHORT pixel2;
 const int width = 4096;

 bool oddrow = row % 2;

 int i = 0;
 while( i < width )
 {
     byte1 = image[row][ i ];
     byte2.byte = image[row][ i + 1];
     byte3 = image[row][ i ];

     pixel1 = byte1 << 4;
     pixel1 |= byte2.nibs.second;
     pixel2 = byte3;
     pixel2 |= ( byte2.nibs.first << 8 );

     i += 3;
 }
This is partial code to get two twelve-bit pixels from three bytes. It doesn't take into account the odd/even aspect of things. It also shows a very easy way to determine whether a row is odd or even.

The key thing there is the union of a byte and two bit fields that are one nibble each (half a byte) or four bits. This is a very easy way to peel a byte in half.
 
Share this answer
 
Comments
Stefan_Lang 27-Mar-19 4:13am    
"Speed means nothing when the code doesn't work in the first place"
The best advice to give on this topic! Even if your solution ended at that point I would have upvoted it.
Rick York 27-Mar-19 10:53am    
Thanks. People sometimes have misguided priorities don't they?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900