Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dipp-decode

Standalone ground-side decoders for DISCO-2 / DIPP image records — the .bin files pulled off the OBC.

Self-contained: nothing here references the DISCO2-module-template checkout. The only external requirements are libopenjp2 and libprotobuf-c.

dipp-decode/
├── Makefile
├── dipp_decode.c          full decoder → PNG (C, needs libopenjp2 + libprotobuf-c)
├── dipp_unpack.py         metadata + payload extraction (Python 3, stdlib only)
└── vendor/
    ├── metadata.proto     copied from DISCO2-module-template/protos/
    ├── metadata.pb-c.c    generated protobuf-c bindings
    ├── metadata.pb-c.h
    └── stb_image_write.h  PNG writer

Container format

Produced by batch_util.c:append_result_image on the OBC, consumed by csh/lib/csp_ippc/src/pipeline_slash.c:slash_csp_buffer_get:

repeat until EOF:
    uint32   meta_size        little-endian
    bytes    metadata         protobuf Metadata (vendor/metadata.proto)
    bytes    payload          meta.size bytes of image data

A single downloaded record holds one image, but both tools loop, so a concatenated batch works too.

The payload encoding depends on the module that produced it. jpeg2000_module.c uses OPJ_CODEC_J2K, so the payload is a raw J2K codestream (magic FF 4F FF 51), not a JP2 container, and it tags the metadata with enc = "j2k".

Note: csh's own -s/--save_png flag only understands enc == "jxl" (pipeline_slash.c:639). Point it at a j2k payload and it renders raw garbage. That is why these tools exist.

dipp_decode — full decode to PNG

make
./dipp_decode image.bin              # metadata + decoded PNG
./dipp_decode image.bin -o out       # write outputs to out/
./dipp_decode image.bin -o out -r    # also keep the raw .j2k
./dipp_decode image.bin -m           # metadata only, writes nothing
  • Decodes raw J2K and JP2 payloads.
  • Always writes an 8-bit .png. For >8-bit images it also writes a 16-bit .pnm, since PNG output here is 8-bit only and you would otherwise lose the low bits of a 12- or 16-bit sensor frame.
  • Payloads that are already PNG/JPEG/WebP/JXL are written out verbatim.
  • A payload with no recognisable magic is treated as interleaved raw samples if its length matches width * height * channels * bytes_per_sample; otherwise it is dumped as .raw for inspection.
  • Exits non-zero if any record fails.

If autodetection picks the wrong openjpeg:

make OPJ_INC=/usr/include/openjpeg-2.5 OPJ_LIB=/usr/lib/x86_64-linux-gnu

The Makefile ignores the ambient CC/CFLAGS and does not use pkg-config on purpose — after sourcing the Yocto SDK environment both point into the aarch64 cross sysroot, which would quietly build a binary that cannot run on the workstation.

dipp_unpack.py — zero-dependency inspection

Pure stdlib, including a small protobuf wire-format reader. Runs on any machine with Python 3 and no build environment.

./dipp_unpack.py image.bin           # metadata + extract payloads
./dipp_unpack.py image.bin -m        # metadata only

It does not decode JPEG 2000 — it extracts the .j2k so you can open it in any viewer, or hand it to opj_decompress:

./dipp_unpack.py image.bin -o out
opj_decompress -i out/image_img0.j2k -o out/image_img0.png

Reading the metadata dump

=== image 0 (metadata 43 bytes) ===
    size       : 282 bytes (payload)
    dimensions : 64 x 48
    channels   : 3
    bits_pixel : 8
    timestamp  : 1753100000
    obid       : 42
    camera     : wide-angle
    items      : 1
      enc              = "j2k" (string)
    payload    : 282 bytes, JPEG 2000 raw codestream
    decoded: 64x48, 3 component(s), 8 bit/sample
    wrote out/image_img0.png

When something looks wrong, check in this order:

  • payload : ... JPEG 2000 raw codestream — the module ran and produced real j2k. If it says uncompressed / unknown, the pipeline passed the input through without compressing.
  • enc = "j2k" — confirms add_custom_metadata_string fired.
  • size vs dimensions — compression ratio. If sizewidth × height × channels, nothing compressed.
  • bits_pixel — if this reads 16 but the sensor is really 8-bit, the encoder read past the end of the input buffer and the image will look like noise.
  • opj_read_header failed / opj_decode failed — the codestream itself is malformed. That points at the encoder settings on the OBC, not the download.

Regenerating the protobuf bindings

Only needed if metadata.proto changes upstream:

protoc-c --c_out=. --proto_path=vendor vendor/metadata.proto && mv metadata.pb-c.* vendor/

Verified

  • 8-bit RGB lossless payload decodes bit-exact against the source pixels.
  • 12-bit grayscale lossy payload decodes, with full depth preserved in the 16-bit .pnm.
  • Multi-record files, uncompressed payloads, truncated files, and random junk all handled without crashing; non-zero exit on failure.
  • Both tools extract byte-identical payloads from the same input.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages