The open source OpenXR runtime
1// Copyright 2019, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Format helpers and block code.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup aux_util
8 */
9
10#include "util/u_format.h"
11
12#include <assert.h>
13
14
15const char *
16u_format_str(enum xrt_format f)
17{
18 switch (f) {
19 case XRT_FORMAT_R8G8B8X8: return "XRT_FORMAT_R8G8B8X8";
20 case XRT_FORMAT_R8G8B8A8: return "XRT_FORMAT_R8G8B8A8";
21 case XRT_FORMAT_R8G8B8: return "XRT_FORMAT_R8G8B8";
22 case XRT_FORMAT_R8G8: return "XRT_FORMAT_R8G8";
23 case XRT_FORMAT_R8: return "XRT_FORMAT_R8";
24 case XRT_FORMAT_BAYER_GR8: return "XRT_FORMAT_BAYER_GR8";
25 case XRT_FORMAT_L8: return "XRT_FORMAT_L8";
26 case XRT_FORMAT_BITMAP_8X1: return "XRT_FORMAT_BITMAP_8X1";
27 case XRT_FORMAT_BITMAP_8X8: return "XRT_FORMAT_BITMAP_8X8";
28 case XRT_FORMAT_YUV888: return "XRT_FORMAT_YUV888";
29 case XRT_FORMAT_YUYV422: return "XRT_FORMAT_YUYV422";
30 case XRT_FORMAT_UYVY422: return "XRT_FORMAT_UYVY422";
31 case XRT_FORMAT_MJPEG: return "XRT_FORMAT_MJPEG";
32 case XRT_FORMAT_BC4: return "XRT_FORMAT_BC4";
33 default: assert(!"unsupported format"); return 0;
34 }
35}
36
37bool
38u_format_is_blocks(enum xrt_format f)
39{
40 switch (f) {
41 case XRT_FORMAT_R8G8B8X8:
42 case XRT_FORMAT_R8G8B8A8:
43 case XRT_FORMAT_R8G8B8:
44 case XRT_FORMAT_R8G8:
45 case XRT_FORMAT_R8:
46 case XRT_FORMAT_BAYER_GR8:
47 case XRT_FORMAT_L8:
48 case XRT_FORMAT_BITMAP_8X1:
49 case XRT_FORMAT_BITMAP_8X8:
50 case XRT_FORMAT_YUV888:
51 case XRT_FORMAT_YUYV422:
52 case XRT_FORMAT_UYVY422:
53 case XRT_FORMAT_BC4:
54 // Yes
55 return true;
56 case XRT_FORMAT_MJPEG:
57 // Compressed
58 return false;
59 default: assert(!"unsupported format"); return 0;
60 }
61}
62
63uint32_t
64u_format_block_width(enum xrt_format f)
65{
66 switch (f) {
67 case XRT_FORMAT_R8G8B8X8:
68 case XRT_FORMAT_R8G8B8A8:
69 case XRT_FORMAT_R8G8B8:
70 case XRT_FORMAT_R8G8:
71 case XRT_FORMAT_R8:
72 case XRT_FORMAT_BAYER_GR8:
73 case XRT_FORMAT_L8:
74 case XRT_FORMAT_YUV888:
75 // Regular one pixel per block formats.
76 return 1;
77 case XRT_FORMAT_YUYV422:
78 case XRT_FORMAT_UYVY422:
79 // Two pixels per block.
80 return 2;
81 case XRT_FORMAT_BITMAP_8X8:
82 case XRT_FORMAT_BITMAP_8X1:
83 // Eight pixels per block.
84 return 8; // NOLINT
85 case XRT_FORMAT_BC4:
86 // four pixels wide
87 return 4;
88 default: assert(!"unsupported format"); return 0;
89 }
90}
91
92uint32_t
93u_format_block_height(enum xrt_format f)
94{
95 switch (f) {
96 case XRT_FORMAT_R8G8B8X8:
97 case XRT_FORMAT_R8G8B8A8:
98 case XRT_FORMAT_R8G8B8:
99 case XRT_FORMAT_R8G8:
100 case XRT_FORMAT_R8:
101 case XRT_FORMAT_BAYER_GR8:
102 case XRT_FORMAT_L8:
103 case XRT_FORMAT_BITMAP_8X1:
104 case XRT_FORMAT_YUV888:
105 case XRT_FORMAT_YUYV422:
106 case XRT_FORMAT_UYVY422:
107 // One pixel high.
108 return 1;
109 case XRT_FORMAT_BITMAP_8X8:
110 // Eight pixels high.
111 return 8;
112 case XRT_FORMAT_BC4:
113 // four pixels high
114 return 4;
115 default: assert(!"unsupported format"); return 0;
116 }
117}
118
119size_t
120u_format_block_size(enum xrt_format f)
121{
122 switch (f) {
123 case XRT_FORMAT_BITMAP_8X1:
124 case XRT_FORMAT_R8:
125 case XRT_FORMAT_BAYER_GR8:
126 case XRT_FORMAT_L8:
127 // One byte blocks
128 return 1;
129 case XRT_FORMAT_R8G8:
130 // Two bytes, 16bits.
131 return 2;
132 case XRT_FORMAT_R8G8B8:
133 case XRT_FORMAT_YUV888:
134 // Weird 24bit pixel formats.
135 return 3;
136 case XRT_FORMAT_R8G8B8X8:
137 case XRT_FORMAT_R8G8B8A8:
138 case XRT_FORMAT_YUYV422: // Four bytes per two pixels.
139 case XRT_FORMAT_UYVY422: // Four bytes per two pixels.
140 // 32bit pixel formats.
141 return 4;
142 case XRT_FORMAT_BC4: // 64 bits.
143 case XRT_FORMAT_BITMAP_8X8: return 8;
144 default: assert(!"unsupported format"); return 0;
145 }
146}
147
148void
149u_format_size_for_dimensions(enum xrt_format f, uint32_t width, uint32_t height, size_t *out_stride, size_t *out_size)
150{
151 uint32_t sw = u_format_block_width(f);
152 uint32_t sh = u_format_block_height(f);
153 size_t block_size = u_format_block_size(f);
154
155 // Round up
156 uint32_t num_blocks_x = (width + (sw - 1)) / sw;
157 uint32_t num_blocks_y = (height + (sh - 1)) / sh;
158
159 // Add it all together
160 size_t stride = num_blocks_x * block_size;
161 size_t size = num_blocks_y * stride;
162
163 *out_stride = stride;
164 *out_size = size;
165}