ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_viewer_ppm.c File Reference

RGB565 <-> 8-bit RGB conversion and the shared binary-PPM (P6) writer. More...

#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <unistd.h>
#include "ra8_err.h"
#include "ra8_viewer_reader.h"
#include "ra8_viewer_reader_internal.h"
Include dependency graph for ra8_viewer_ppm.c:

Go to the source code of this file.

Macros

#define O_CLOEXEC   (0)
 No-op close-on-exec fallback for hosts lacking the flag.

Enumerations

enum  ra8_viewer_rgb565_shift_t : uint8_t {
  k_rgb565_r_shift = 11U ,
  k_rgb565_g_shift = 5U ,
  k_rgb565_r5_drop = 3U ,
  k_rgb565_g6_drop = 2U ,
  k_rgb565_r5_fill = 2U ,
  k_rgb565_g6_fill = 4U ,
  k_rgb565_hi_shift = 8U
}
 Field positions and channel-width conversions for RGB565 packing. More...
enum  ra8_viewer_rgb565_mask_t : uint32_t {
  k_rgb565_r5_mask = 0x1FU ,
  k_rgb565_g6_mask = 0x3FU ,
  k_rgb565_b5_mask = 0x1FU
}
 Channel masks used to unpack an RGB565 word. More...
enum  ra8_viewer_ppm_t : uint8_t {
  k_ppm_channels = 3U ,
  k_ppm_idx_r = 0U ,
  k_ppm_idx_g = 1U ,
  k_ppm_idx_b = 2U
}
 Layout constants of the binary portable-pixmap (P6) output. More...
enum  ra8_viewer_ppm_io_t : uint16_t {
  k_ppm_u32_digits = 10U ,
  k_ppm_decimal_radix = 10U ,
  k_ppm_header_bytes = 32U ,
  k_ppm_chunk_pixels = 1024U ,
  k_ppm_file_mode = 0666 ,
  k_ppm_chunk_bytes = k_ppm_chunk_pixels * k_ppm_channels
}
 Bounded buffers used by the descriptor-backed PPM publisher. More...

Functions

uint16_t ra8_viewer_pack565 (uint8_t rr, uint8_t gg, uint8_t bb)
 Pack 8-bit RGB channels into one RGB565 word.
uint16_t ra8_viewer_pack565_le_pair (uint8_t lo, uint8_t hi)
 Reassemble one little-endian RGB565 word.
static RA8_INTERNAL void internal_unpack565 (uint16_t px, uint8_t rgb[k_ppm_channels])
 Expand one RGB565 word into three 8-bit channels.
static RA8_INTERNAL bool internal_write_all (int fd, const uint8_t *bytes, size_t length)
 Write exactly length bytes to one owned host descriptor.
static RA8_INTERNAL size_t internal_append_u32 (char out[k_ppm_header_bytes], size_t offset, uint32_t value)
 Append one unsigned decimal value to a fixed PPM header.
static RA8_INTERNAL size_t internal_ppm_header (char out[k_ppm_header_bytes], uint32_t width, uint32_t height)
 Build the locale-independent binary-PPM header for width x height.
ra8_err_t ra8_viewer_write_ppm565 (const uint16_t *px, uint32_t w, uint32_t h, const char *path)
 Write arbitrary caller-owned RGB565 pixels as binary PPM.
ra8_err_t ra8_viewer_dump_ppm (const ra8_viewer_reader_t *r, const char *path)
 Write the current fixed framebuffer as binary PPM.

Detailed Description

RGB565 <-> 8-bit RGB conversion and the shared binary-PPM (P6) writer.

Both headless proofs – the fixed-framebuffer dump (ra8_viewer_dump_ppm) and the scroll-tile dump in the CLI – expand the same RGB565 pixels to 8-bit RGB and write the same P6 file. That conversion lives here once so the two paths cannot drift, and so the field shifts / masks are named constants in one place rather than literals repeated at each call site.

The 5->8 and 6->8 bit expansions replicate the high bits into the low bits ((v << 3) | (v >> 2)), which maps 0x1F to 0xFF exactly – a plain shift would cap white at 0xF8 and tint every dump.

Since
0.1.0

Definition in file ra8_viewer_ppm.c.

Macro Definition Documentation

◆ O_CLOEXEC

#define O_CLOEXEC   (0)

No-op close-on-exec fallback for hosts lacking the flag.

Definition at line 33 of file ra8_viewer_ppm.c.

Enumeration Type Documentation

◆ ra8_viewer_ppm_io_t

enum ra8_viewer_ppm_io_t : uint16_t

Bounded buffers used by the descriptor-backed PPM publisher.

Enumerator
k_ppm_u32_digits 

Decimal digits in UINT32_MAX.

k_ppm_decimal_radix 

Decimal numeric base.

k_ppm_header_bytes 

Complete P6 header capacity.

k_ppm_chunk_pixels 

Pixels converted before each write.

k_ppm_file_mode 

Host output mode before process mask.

k_ppm_chunk_bytes 

Conversion buffer capacity in bytes.

Definition at line 77 of file ra8_viewer_ppm.c.

◆ ra8_viewer_ppm_t

enum ra8_viewer_ppm_t : uint8_t

Layout constants of the binary portable-pixmap (P6) output.

Since
0.1.0
Enumerator
k_ppm_channels 

Bytes per P6 pixel (R, G, B).

k_ppm_idx_r 

Red byte index within a P6 pixel.

k_ppm_idx_g 

Green byte index within a P6 pixel.

k_ppm_idx_b 

Blue byte index within a P6 pixel.

Definition at line 69 of file ra8_viewer_ppm.c.

◆ ra8_viewer_rgb565_mask_t

enum ra8_viewer_rgb565_mask_t : uint32_t

Channel masks used to unpack an RGB565 word.

Since
0.1.0
Enumerator
k_rgb565_r5_mask 

5-bit red field mask.

k_rgb565_g6_mask 

6-bit green field mask.

k_rgb565_b5_mask 

5-bit blue field mask.

Definition at line 58 of file ra8_viewer_ppm.c.

◆ ra8_viewer_rgb565_shift_t

enum ra8_viewer_rgb565_shift_t : uint8_t

Field positions and channel-width conversions for RGB565 packing.

The _drop values narrow 8-bit channels on the way in; the _fill values position the replicated high bits on the way back out.

Since
0.1.0
Enumerator
k_rgb565_r_shift 

Red field position in the 16-bit word.

k_rgb565_g_shift 

Green field position in the 16-bit word.

k_rgb565_r5_drop 

8->5-bit reduction for red/blue.

k_rgb565_g6_drop 

8->6-bit reduction for green.

k_rgb565_r5_fill 

5->8 low-bit replication shift (red/blue).

k_rgb565_g6_fill 

6->8 low-bit replication shift (green).

k_rgb565_hi_shift 

High-byte position of a little-endian pixel.

Definition at line 43 of file ra8_viewer_ppm.c.

Function Documentation

◆ internal_append_u32()

RA8_INTERNAL size_t internal_append_u32 ( char out[k_ppm_header_bytes],
size_t offset,
uint32_t value )
static

Append one unsigned decimal value to a fixed PPM header.

Builds digits in reverse order and copies them back without locale, formatting streams, or dynamic allocation.

Parameters
[out]outHeader storage with k_ppm_header_bytes capacity.
[in]offsetFirst unwritten header byte.
[in]valueValue to append.
Returns
New first-unwritten offset.
Return values
0Not returned; at least one digit is always appended.
Precondition
out has enough remaining room for ten decimal digits.
offset is below k_ppm_header_bytes.
Postcondition
The decimal spelling of value occupies the appended bytes.
No terminating NUL is written or required.
Note
Pure apart from out; thread-safe.
Since
0.1.0

Definition at line 176 of file ra8_viewer_ppm.c.

References k_ppm_decimal_radix, k_ppm_header_bytes, and k_ppm_u32_digits.

Referenced by internal_ppm_header().

◆ internal_ppm_header()

RA8_INTERNAL size_t internal_ppm_header ( char out[k_ppm_header_bytes],
uint32_t width,
uint32_t height )
static

Build the locale-independent binary-PPM header for width x height.

Appends fixed syntax and explicit unsigned decimal dimensions into the caller-owned bounded header without formatting streams.

Parameters
[out]outHeader storage with k_ppm_header_bytes capacity.
[in]widthNon-zero image width.
[in]heightNon-zero image height.
Returns
Number of initialized header bytes.
Return values
0Not returned for valid dimensions.
Precondition
out has k_ppm_header_bytes writable bytes.
width and height are non-zero.
Postcondition
out begins with a complete P6 header of the returned length.
No terminating NUL is written or required.
Note
Pure apart from out; thread-safe.
Since
0.1.0

Definition at line 210 of file ra8_viewer_ppm.c.

References internal_append_u32(), and k_ppm_header_bytes.

Referenced by ra8_viewer_write_ppm565().

◆ internal_unpack565()

RA8_INTERNAL void internal_unpack565 ( uint16_t px,
uint8_t rgb[k_ppm_channels] )
static

Expand one RGB565 word into three 8-bit channels.

High-bit replication, so a saturated field maps to 0xFF exactly.

Parameters
[in]pxPacked RGB565 pixel.
[out]rgbReceives {R, G, B} (non-NULL, k_ppm_channels bytes).
Precondition
rgb has room for k_ppm_channels bytes.
px is a native-endian RGB565 word.
Postcondition
rgb holds the three expanded 8-bit channels.
No state other than rgb is mutated.
Note
Pure; thread-safe.
Since
0.1.0

Definition at line 112 of file ra8_viewer_ppm.c.

References k_ppm_channels, k_ppm_idx_b, k_ppm_idx_g, k_ppm_idx_r, k_rgb565_b5_mask, k_rgb565_g6_drop, k_rgb565_g6_fill, k_rgb565_g6_mask, k_rgb565_g_shift, k_rgb565_r5_drop, k_rgb565_r5_fill, k_rgb565_r5_mask, k_rgb565_r_shift, and RA8_INTERNAL.

Referenced by ra8_viewer_write_ppm565().

◆ internal_write_all()

RA8_INTERNAL bool internal_write_all ( int fd,
const uint8_t * bytes,
size_t length )
static

Write exactly length bytes to one owned host descriptor.

Advances across short writes and retries EINTR; every other error fails closed so a partial image is never reported as successful.

Parameters
[in]fdOpen write-only host descriptor.
[in]bytesSource bytes (non-NULL when length is non-zero).
[in]lengthNumber of bytes to publish.
Returns
true only when all requested bytes were written.
Return values
trueAll length bytes were written.
falseA non-retryable error or zero-length write stopped progress.
Precondition
fd is owned by the caller and open for writing.
bytes spans at least length readable bytes.
Postcondition
On true the descriptor advanced by exactly length bytes.
On false the descriptor may contain a bounded prefix.
Note
Not thread-safe when callers share fd.
Since
0.1.0

Definition at line 143 of file ra8_viewer_ppm.c.

References RA8_INTERNAL.

Referenced by ra8_viewer_write_ppm565().

◆ ra8_viewer_dump_ppm()

ra8_err_t ra8_viewer_dump_ppm ( const ra8_viewer_reader_t * r,
const char * path )
nodiscard

Write the current fixed framebuffer as binary PPM.

Definition at line 263 of file ra8_viewer_ppm.c.

References ra8_viewer_reader::fb, k_ra8_err_null_ptr, k_ra8_viewer_fb_height, k_ra8_viewer_fb_width, and ra8_viewer_write_ppm565().

Referenced by internal_render_page().

◆ ra8_viewer_pack565()

uint16_t ra8_viewer_pack565 ( uint8_t rr,
uint8_t gg,
uint8_t bb )
nodiscard

Pack 8-bit RGB channels into one RGB565 word.

Definition at line 87 of file ra8_viewer_ppm.c.

References k_rgb565_g6_drop, k_rgb565_g_shift, k_rgb565_r5_drop, and k_rgb565_r_shift.

Referenced by internal_band_pixel().

◆ ra8_viewer_pack565_le_pair()

uint16_t ra8_viewer_pack565_le_pair ( uint8_t lo,
uint8_t hi )
nodiscard

Reassemble one little-endian RGB565 word.

Definition at line 95 of file ra8_viewer_ppm.c.

References k_rgb565_hi_shift.

Referenced by internal_band_pixel().

◆ ra8_viewer_write_ppm565()

ra8_err_t ra8_viewer_write_ppm565 ( const uint16_t * px,
uint32_t w,
uint32_t h,
const char * path )
nodiscard