Table of contents
HDR-10bpp-Display-Test: Packing ten-bit channels for a Cairo surface
This display experiment loads image data into a GTK drawing area through Cairo. Viewer3.py makes the pixel representation explicit: channel samples are masked and packed into a uint32 buffer before creating an RGB30 surface.
- Languages
- 2Code breakdown
- Documented components
- 2Explore modules
- Source documents
- 1Read the instructions
Repository languagesPython 98.43%2
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| Python | 8,200 | |
| Shell | 131 |
1. Overview
1.1. Why it exists
10-bit HDR pipeline testing color banding and luminance curves on Linux display servers.
1.2. Best fit
Calibration and verification of 4K 10-bit HDR displays on Linux workstations.
2. Use cases
Linux scripts to check that an HDR display really shows 10 bits per channel under an X server at depth 30.
- Start X at depth 30
- Display testerX server (Xorg)
Xdepth.sh runs startx -- -depth 30 and prints the depth from xwininfo, falling back to depth 24; xorg.conf sets DefaultDepth 30.
- Show a 10-bit gray gradient
- Display testerHDR10 monitor
Viewer.py packs the RGB channels of images/gray_gradient_10.tiff into a cairo FORMAT_RGB30 surface and draws it in a GTK 3 window.
- Compare 8-bit and 10-bit
- Display testerHDR10 monitor
The images/ folder holds gray_gradient_8.tiff next to gray_gradient_10.tiff, so the same gradient can be viewed at both depths to compare banding by eye.
- Play a video at 10 bpc
- Display testerHDR10 monitor
Viewer3.py adds a Typer CLI with --image-path and --video-path; videos are read frame by frame with imageio's ffmpeg reader in a thread at 30 fps.
2.1. Scenario: Checking a new HDR10 monitor on Ubuntu
- Stop the display manager: sudo systemctl stop lightdm || sudo systemctl stop gdm, then sudo pkill Xorg.
- Start X with startx -- -depth 30 (or run Xdepth.sh).
- Confirm with xwininfo -root | grep Depth that the root window reports depth 30.
- Run python3 Viewer.py to open images/gray_gradient_10.tiff in the viewer window.
- Look for banding in the gradient; smooth steps mean the 10-bit path works end to end.
Files readREADME.mdViewer.pyViewer3.pyXdepth.shxorg.conf
3. Getting started
These commands come from the repository documentation. They were not run during this review.
sudo apt-get install xserver-xorg python3 python3-gi python3-gi-cairo gir1.2-gtk-3.0 imagejpip3 install imageiogit clone https://github.com/yourusername/HDR-10bpp-Display-Test.gitcd HDR-10bpp-Display-Testsudo systemctl stop lightdm || sudo systemctl stop gdm
sudo pkill Xorg4. Repository references
Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.
Prerequisites and first run
4.1. Prerequisites
README.md
To run the test, you will need the following software installed on your system:
- X server
- Python 3
- GTK 3
- ImageJ (for displaying images with a 10-bit color depth)
- ImageIO (for reading image files) You can install these packages on Ubuntu or Debian-based systems by running the following command:
4.2. Installing
README.md
Operations and troubleshooting
4.3. Troubleshooting
README.md
Development and contributions
4.4. HDR-10bpp-Display-Test
README.md
4.5. Running the test
README.md
To run the test, follow these steps:
- Clone the repository:
- Navigate to the project directory:
- Stop the display manager and X server:
- Start the X server with a color depth of 30:
- If the X server was started successfully, the output of the following command should indicate a depth of 30:
- Launch the viewer application:
- The viewer window will open. To display an image, run the following command:
- The image should be displayed in the viewer window. Verify that the image is displayed correctly and that the colors are accurate.
5. Features and components 2
- Pixels and drawing
- imageio reads the source array. _draw_on allocates a packed buffer and shifts each channel according to the selected depth, then passes it to cairo.ImageSurface.create_for_data. The GTK draw callback paints that surface.
- Video path
- A worker reads video frames and updates the current image at a requested cadence. Drawing also manually processes pending GTK events. This older approach deserves particular attention to UI-thread ownership when maintained.
6. Architecture
Expand a component to follow its connections, or explore the full diagram.
Image or video input
imageio array
Channel masking and packing
- From imageio array
- To Cairo RGB30 surface
Cairo RGB30 surface
GTK drawing area
- From Cairo RGB30 surface
Mermaid Interactive diagram
System overview of the components and connections verified in the repository.

flowchart LR
node_user(("Test operator"))
node_imagej["ImageJ"]
subgraph group_setup["Display setup"]
node_xserver["X server"]
end
subgraph group_viewers["Viewer applications"]
node_viewer1["Image viewer<br/>[Viewer.py]"]
node_viewer3["Image/video viewer<br/>[Viewer3.py]"]
end
subgraph group_render["Image rendering"]
node_gtk1["GTK window<br/>[Viewer.py]"]
node_gtk3["GTK window<br/>[Viewer3.py]"]
node_imageio1["Image input<br/>[Viewer.py]"]
node_imageio3["Image/video input<br/>[Viewer3.py]"]
node_cairo1["Cairo drawing<br/>[Viewer.py]"]
node_cairo3["Cairo drawing<br/>[Viewer3.py]"]
end
node_user -->|"starts at depth"| node_xserver
node_user -->|"launches"| node_viewer1
node_user -->|"launches"| node_viewer3
node_gtk1 -->|"dispatches draw"| node_cairo1
node_gtk3 -->|"dispatches draw"| node_cairo3
node_user -->|"opens image"| node_imagej
node_imagej -->|"displays for checking"| node_viewer1
group_viewers --> group_render
class node_xserver toneBlue
class node_viewer1,node_viewer3 toneAmber
class node_gtk1,node_gtk3,node_imageio1,node_imageio3,node_cairo1,node_cairo3 toneMint
class node_user,node_imagej toneIndigo
A Linux HDR and 10-bit display test. The workflow starts an X server at the requested depth, opens an image or video viewer, and draws frames through GTK and Cairo for visual checking.
- Components
- 11
- Connections
- 13
- Evidence-backed links
- 13/13
Text version of the diagram
The diagram merges parallel links between groups, so it shows 8 of 13. Full list:
- Test operator → X server (starts at depth)
- Test operator → Image viewer (launches)
- Test operator → Image/video viewer (launches)
- Image viewer → GTK window (creates window)
- Image viewer → Image input (reads image)
- Image viewer → Cairo drawing (draws image)
- GTK window → Cairo drawing (dispatches draw)
- Image/video viewer → GTK window (creates window)
- Image/video viewer → Image/video input (reads image/video)
- Image/video viewer → Cairo drawing (draws frames)
- GTK window → Cairo drawing (dispatches draw)
- Test operator → ImageJ (opens image)
- ImageJ → Image viewer (displays for checking)
Follow one path through the code
Inspect _draw_on to see exactly where bit depth affects shifts and surface selection. Ten-bit storage concerns numeric precision; HDR transfer functions, metadata and display calibration require additional work outside this packing step.
7. Technical dossier
Built from the source at commit 9c72e07 (4 files). Each item comes from a pattern match in the code, so open the linked file before relying on it.
7.1. Layers and modules
Folders are sorted into layers by name, from the user interface down to data access. Because the sorting uses names only, the diagram says nothing about calls between layers.
Mermaid Layered view
flowchart TB
subgraph L_core["Core source"]
direction TB
core_0["(root)<br/>3 files"]
end
| Module | Layer | Files | Types | Extensions |
|---|---|---|---|---|
(root) | Core source | 3 | 2 | .py .sh |
7.2. C4 model
From system context to code declarations. Each level reflects the available source evidence.
UML 1 · System context
The widest C4 view: who uses the project and which outside systems and data stores it relies on. Rendered with uml-mcp.
PlantUML source
@startuml
!include <C4/C4_Context>
LAYOUT_LEFT_RIGHT()
System(SYS, "HDR-10bpp-Display-Test", "This display experiment loads image data into a GTK drawing area thro…")
@enduml
Level 2: the available sources do not support this view.
UML 3 · Components and layers
Modules grouped by source-layer classification. Boundaries show organization, not runtime isolation or call relationships. Rendered with uml-mcp.
PlantUML source
@startuml
!include <C4/C4_Component>
LAYOUT_TOP_DOWN()
System_Boundary(SYS, "HDR-10bpp-Display-Test") {
Boundary(L0, "Core source", "layer") {
Component(M0_0, "(root)", "Python, .sh", "3 files")
}
}
@enduml
UML 4 · Code
Selected declarations, fields and methods grouped by source file. No inheritance or call edges are inferred. Rendered with uml-mcp.
PlantUML source
@startuml
skinparam backgroundColor transparent
skinparam shadowing false
skinparam roundCorner 10
skinparam defaultFontName Arial
skinparam defaultFontSize 13
skinparam ArrowColor #4e6070
skinparam ArrowFontColor #3d4f5f
skinparam titleFontSize 14
skinparam actorBorderColor #006a62
skinparam actorBackgroundColor #e9f3f4
skinparam usecaseBorderColor #006a62
skinparam usecaseBackgroundColor #e9f3f4
skinparam componentBorderColor #006a62
skinparam componentBackgroundColor #e9f3f4
skinparam interfaceBorderColor #006a62
skinparam interfaceBackgroundColor #ffffff
skinparam nodeBorderColor #4e6070
skinparam nodeBackgroundColor #f4f8fb
skinparam databaseBorderColor #006a62
skinparam databaseBackgroundColor #ffffff
skinparam cloudBorderColor #4e6070
skinparam cloudBackgroundColor #f0f5fa
skinparam artifactBorderColor #006a62
skinparam artifactBackgroundColor #ffffff
skinparam rectangleBorderColor #b0c2d3
skinparam activityBorderColor #006a62
skinparam activityBackgroundColor #e9f3f4
skinparam partitionBorderColor #b0c2d3
skinparam stereotypeCBackgroundColor #ffffff
top to bottom direction
hide empty members
package "HDR-10bpp-Display-Test" {
package "Viewer3.py" as F0 {
class "Viewer" as T0_0 {
_initUI()
_window_state()
size()
fullscreen()
display_image()
_draw()
}
}
}
@enduml
7.3. Data flow
The calls from the GitDiagram graph, in the order you meet them from the entry points. GitDiagram generates the graph with AI; the file paths it cites were checked against the repository tree.
Mermaid Sequence diagram
sequenceDiagram
autonumber
participant P0 as Test operator
participant P1 as X server
participant P2 as Image viewer
participant P3 as Image/video viewer
participant P4 as ImageJ
participant P5 as GTK window
participant P6 as Image input
participant P7 as Cairo drawing
participant P8 as Image/video input
P0->>P1: starts at depth
P0->>P2: launches
P0->>P3: launches
P0->>P4: opens image
P2->>P5: creates window
P2->>P6: reads image
P2->>P7: draws image
P3->>P5: creates window
P3->>P8: reads image/video
P3->>P7: draws frames
P4->>P2: displays for checking
P5->>P7: dispatches draw
P5->>P7: dispatches draw
Steps as text
- Test operator to X server starts at depth
- Test operator to Image viewer launches
- Test operator to Image/video viewer launches
- Test operator to ImageJ opens image
- Image viewer to GTK window creates window
- Image viewer to Image input reads image
- Image viewer to Cairo drawing draws image
- Image/video viewer to GTK window creates window
- Image/video viewer to Image/video input reads image/video
- Image/video viewer to Cairo drawing draws frames
- ImageJ to Image viewer displays for checking
- GTK window to Cairo drawing dispatches draw
- GTK window to Cairo drawing dispatches draw
7.4. Private interface
These names are internal by the language’s conventions: a leading underscore, private, static or pub(crate).
- underscore helper
- 11
_initUIViewer.py:36_window_stateViewer.py:51_drawViewer.py:80
7.5. Business logic
Once UI code and the services and entities above are set aside, these classes have the most methods.
ViewerCore source, 12 methods_initUI, _window_state, size, fullscreen, display_image, _draw
7.6. CI/CD pipeline
No CI/CD pipeline in the repository. The code is built and run by hand, as described above.
7.7. Deployment
Mermaid Deployment diagram
flowchart LR
repo[("GitHub repository")]
local["Local machine"]
repo -->|"clone and run"| local
The repository has no Dockerfile, Compose file or hosting configuration, so the code runs on the machine that clones it.
The available sources do not document the remaining sections.
8. Types and file structure
2 declared types, with 2 in the base-relationship overview.
Type diagram
classDiagram
direction TB
class td926548d9d56["Viewer"] {
__init__()
_initUI()
_window_state()
size()
}
class t015018d2192b["Viewer"] {
__init__()
_initUI()
_window_state()
size()
}
class bb574778f1f7f["object"] {
<<unresolved_base>>
}
bb574778f1f7f <|-- td926548d9d56
class ba71980200e35["object"] {
<<unresolved_base>>
}
ba71980200e35 <|-- t015018d2192b
Unresolved bases remain labelled; full signatures are not reconstructed.
9. Reference
4 / 4 eligible files read (7 in the tree); 0 oversized, 0 failed reads and 0 syntax diagnostics.
What the scan covers
Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.
Linguist statistics cover the whole repository and may include other languages.
11. Files to read 3
12. Glossary
Repository
The versioned source files, configuration, and history of a project.
README
The repository’s entry document, usually covering its purpose and initial setup.
Dependency
A library, tool, or service that another component needs to build or run.
Volume and bind mount
A volume is storage managed by the container platform; a bind mount exposes a chosen host path inside a container.
CLI
A text interface in which commands and arguments select operations. Exit codes let scripts detect success or failure.
Webhook
An HTTP request sent to another system when an event occurs. The receiver needs to validate the request before acting on it.
13. References
- antoinebou12. (2026, November 5). HDR-10bpp-Display-Test. [Software repository] github.com.
- antoinebou12. (2026, November 5). HDR-10bpp-Display-Test: README. [Repository documentation] github.com.
- antoinebou12. (2026, November 5). Viewer3.py. [Source file] github.com.
- antoinebou12. (2026, November 5). Xdepth.sh. [Source file] github.com.
- antoinebou12. (2026, November 5). xorg.conf. [Source file] github.com.
- Boucher, A. (2024, January 1). HDR-10bpp-Display-Test. [Project article] antoineboucher.info.
- Boucher, A. (2026, October 23). HDR-10bpp-Display-Test: Packing ten-bit channels for a Cairo surface. [Project article] antoineboucher.info.
Sources without a publication date show the date they were last checked, November 5, 2026. File links retain the inspected revision where available.