Source browser
examples/shaders/bayer_unpack.cpp
Read the complete file below or download its original bytes. Line numbers provide stable links to a declaration or processing step.
File fingerprint
1// Decode byte-addressed Bayer8, little-endian Bayer16, MIPI RAW10 or MIPI RAW12.
2// Each packed_words[] uint carries four consecutive bytes, least significant byte first.
3#ifdef __cplusplus // Expose host declarations only when a C++ compiler reads this shader.
4#include "shdr.h" // Include shdr.h declarations.
5#endif // Finish this conditional compilation branch.
6layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in; // Group 64 independent invocations along x.
7layout(std430, binding = 0) readonly buffer Packed { // Read four packed bytes per uint in little-endian byte order through buffer binding 0.
8 uint packed_words[]; // Store four packed bytes per uint in little-endian byte order.
9}; // Finish this declaration.
10layout(std430, binding = 1) writeonly buffer Samples { // Write one unpacked unsigned sensor value per pixel through buffer binding 1.
11 uint samples[]; // Store one unpacked unsigned sensor value per pixel.
12}; // Finish this declaration.
13uniform uint count; // Limit work to the valid element count, including a partial final workgroup.
14uniform uint packing; // Select Bayer8, little-endian Bayer16, MIPI RAW10 or MIPI RAW12 byte packing.
15uniform uint bit_depth; // Set the number of valid bits in each unpacked sensor sample.
16uint byte_at(uint position) { // Extract one byte from the little-endian packed uint buffer.
17 return (packed_words[position / 4u] >> ((position % 4u) * 8u)) & 255u; // Shift the requested byte to the low bits and mask away the other three bytes.
18} // End this block.
19void main() { // Decode one packed sensor sample into an unsigned Bayer value.
20 uint i = gl_GlobalInvocationID.x; // Select this invocation's global x coordinate.
21 if (i >= count) // Stop padding invocations before reading or writing an element.
22 return; // Stop this invocation before performing another resource access.
23 uint value = 0u; // Initialize the unpacked sample before selecting its byte format.
24 if (packing == 0u) // Decode a format with one complete sample in each byte.
25 value = byte_at(i); // Read the Bayer8 sample directly.
26 else if (packing == 1u) // Decode a little-endian format with two bytes per sample.
27 value = byte_at(i * 2u) | (byte_at(i * 2u + 1u) << 8u); // Combine the low and high bytes of the Bayer16 sample.
28 else if (packing == 2u) { // Decode four RAW10 samples sharing one low-bit byte.
29 uint start = (i / 4u) * 5u; // Locate this four-sample RAW10 group of five bytes.
30 value = (byte_at(start + i % 4u) << 2u) | ((byte_at(start + 4u) >> ((i % 4u) * 2u)) & 3u); // Combine the eight high bits with this sample's two low bits.
31 } else { // Decode two RAW12 samples sharing one low-bit byte.
32 uint start = (i / 2u) * 3u; // Locate this two-sample RAW12 group of three bytes.
33 value = (byte_at(start + i % 2u) << 4u) | ((byte_at(start + 2u) >> ((i % 2u) * 4u)) & 15u); // Combine the eight high bits with this sample's four low bits.
34 } // End this block.
35 samples[i] = value & ((1u << bit_depth) - 1u); // Keep only the declared valid sensor bits in the unpacked sample.
36} // End this block.