Thanks, there’s something weird in the way the values are encoded that I’m missing. It seems like even though it says 8 bits per pixel, when they arrive, in memory there are actually two bytes for each pixel. And for the metadata, there is ‘other’ information in the second byte.
So, for example when I look the last four pixels of the first row I get this:
var access = image.Planes.GetLinearAccess<byte>();
var pixel1 = access[1020, 0];
var pixel2 = access[1021, 0];
var pixel3 = access[1022, 0];
var pixel4 = access[1023, 0];
This returns 1, 0, 101, 184
But if I access memory directly:
for (int i = 0; i < 4096; i++)
var byt = Marshal.ReadByte(access.BasePtr, i);
I find this:
(The second half of that is probably the CameraId). So it seems there’s extra information ‘hiding’ in there that I can’t see using access indexers. I guess this has something to do with XInc being 2? This is weird, because I’ve had expected
GetLinearAccess<ushort> to work in this case, but that throws.
Now I know this, I can just do a
Marshal.ReadInt32(access.BasePtr, 2040) directly to find the FrameCounter. (Correction, it needs to be uint - which Marshal doesn’t handle, and also I haven’t tested beyond 216 to verify).
Switching away from RAW format I have XInc = 3, and for the data range related to FrameCounter, I see this:
I’m not at all sure what the middle two are for. Actually, looking at the images, it looks like that could be actually sensor information ‘bleeding’ through, maybe the metadata only writes onto two out of three bytes?
Anyway, I’ve tried this up to 216 + 1, and it seems to work:
var byt1 = Marshal.ReadByte(access.BasePtr, 3060);
var byt2 = Marshal.ReadByte(access.BasePtr, 3061);
var byt3 = Marshal.ReadByte(access.BasePtr, 3064);
var byt4 = Marshal.ReadByte(access.BasePtr, 3065);
//3 & 4 reversed is on purpose! - found empirically
var id = (byt3 << 24) + (byt4 << 16) + (byt2 << 8) + byt1;
In my context, one image is 20cm, so 216 is about 13km, which is not unrealistic. An extra byte pushes me up beyond 3000km, which is better