1

I want to read 8 bits at a time from a file in little endian format, I think my cpu is also little endian so I need not to worry about the endianess, right?

what I am reading are numbers, intensity values of RGGB CFA from a RAW12 file.

Here is my code -

  uint8_t first8bits, second8bits, third8bits;
  file.read((char*)&first8bits, sizeof(uint8_t));
  file.read((char*)&second8bits, sizeof(uint8_t));
  file.read((char*)&third8bits, sizeof(uint8_t));
  Red_channel = (first8bits) << 4 | (second8bits & 0xF0) >> 4;
  Green_channel = (second8bits & 0x0F) | (third8bits);

I have seen others reading it 8 bits into a char array and then converting it to a number, how do I do that? Since the machine I am testing the code of is little endian I think I dont need to do byte swap but what if some other person tests this code on big endian machine, how do I find at runtime if the machine is little endian or big endian?

Any help would me much appreciated.

ksraj
  • 13
  • 2
  • In this case you don't have to worry about endianness. How do you want to represent the image once you read it in? That'll help answer the question of how to read it. – Alecto Irene Perez Mar 27 '19 at 03:39
  • 1
    When you read a byte at a time you don't need to worry about the endianness of your processor, only that of the file. – Mark Ransom Mar 27 '19 at 03:44
  • If you have a question about de-Bayering that should be separate, just be warned that it's a large topic and the question is likely to be closed for being too broad. – Mark Ransom Mar 27 '19 at 03:46
  • @MarkRansom so is what I am doing correct? Or should I read the bits into char and then do it – ksraj Mar 27 '19 at 03:48
  • Looks fine, although you'll find that calling `read` for each byte will end up being slow. Of course I can't verify that it matches your file layout. – Mark Ransom Mar 27 '19 at 03:58

2 Answers2

1

If you're on posix platform, you're likely have <endian.h>

Which along with those functions http://man7.org/linux/man-pages/man3/htole32.3.html offers macrodefinitions: __LITTLE_ENDIAN , __BIG_ENDIAN, __BYTE_ORDER (likely included from glib/types.h or bits/types.h)

So you can use preprocessor

#if __BYTE_ORDER == __LITTLE_ENDIAN

to define templates or types which result in one or another operation if required. Endiannes means that you must watch: a) order of bytes b) order of bit fields in struct. Big endian matches "network" order of bytes, but in case of bit fields, on little endian platform first defined field is the least significant and on big endian - the most significant. Technically that's not defined by standard but this order is "canonized" by kernel code of Linux and other OSes.

If you're on Windows, you're on little endian platform. On ARM and MIPS things are more complex, as CPU can actually switch its endiannes to a degree. That's the reason why those library functions do exist.

Bit shift operations would allow to ignore order and can be used IF you will keep in mind that bit shift operation automatically promotes its operand to int.

Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
0

The code I have used is correct, another way to do this could be

char inBuf [3];
intputfile.read(inBuf, 3);
cfa[i][cnt] = ((uint8_t)inBuf[0]) << 4 | ((uint8_t)inBuf[1] & 0xF0) >> 4;
cfa[i][cnt+1] = ((uint8_t)inBuf[1] & 0x0F) << 8 | ((uint8_t)inBuf[2]);
ksraj
  • 13
  • 2