fn generate_decoded(app_info: &Data, bytes_per_line: usize, lines_per_screen: usize) -> Vec<Line> {
    let initial_offset = app_info.start_address.min(3);
    OverlappingChunks::new(
        &app_info.contents[(app_info.start_address - initial_offset)..],
        bytes_per_line,
        6,
    )
    .take(lines_per_screen)
    .enumerate()
    .map(|(row, chunk)| {
        Line::from(
            ByteAlignedDecoder::new(chunk, app_info.encoding)
                .skip(initial_offset)
                .take(bytes_per_line)
                .enumerate()
                .map(|(col, character)| {
                    let byte_pos = app_info.start_address + (row * bytes_per_line) + col;
                    let mut span = Span::styled(
                        character.escape().to_string(),
                        Style::default().fg(*character.color()),
                    );
                    // Highlight the selected byte in the ASCII table
                    let last_drag = app_info.last_drag.unwrap_or(app_info.offset);
                    if byte_pos == app_info.offset
                        || (app_info.offset..=last_drag).contains(&byte_pos)
                        || (last_drag..=app_info.offset).contains(&byte_pos)
                    {
                        span.style = span.style.bg(COLOR_NULL);
                    }
                    span
                })
                .collect::<Vec<Span>>(),
        )
    })
    .collect::<Vec<Line>>()
}
Display decoded bytes with correct highlighting and colors.

NOTE: In UTF-8, a character takes up to 4 bytes and thus the encoding can break at the ends of a
chunk. Increasing the chunk size by 3 bytes at both ends before decoding and cropping them of
afterwards solves the issue for the visible parts.
src/screen.rs