The open imaging DSP library
Loading...
Searching...
No Matches
ring.h
1
5#ifndef MPIX_RING_H
6#define MPIX_RING_H
7
8#include <stdbool.h>
9#include <string.h>
10
16struct mpix_ring {
18 uint8_t *data;
20 size_t size;
22 size_t head;
24 size_t tail;
26 size_t peek;
28 bool full;
29};
30
31static inline void mpix_ring_init(struct mpix_ring *ring, uint8_t *buf, size_t size)
32{
33 memset(ring, 0x00, sizeof(*ring));
34 ring->data = buf;
35 ring->size = size;
36}
37
38static inline bool mpix_ring_is_full(struct mpix_ring *ring)
39{
40 return ring->full;
41}
42
43static inline bool mpix_ring_is_empty(struct mpix_ring *ring)
44{
45 return ring->head == ring->tail && !ring->full;
46}
47
48static inline size_t mpix_ring_headroom(struct mpix_ring *ring)
49{
50 if (ring->head < ring->tail) {
51 /* [::::H T::::]
52 * ^^^^^^^
53 */
54 return ring->tail - ring->head;
55 }
56 if (ring->tail < ring->head) {
57 /* [ T::::::H ]
58 * ^^^^^
59 */
60 return ring->size - ring->head;
61 }
62 if (mpix_ring_is_empty(ring)) {
63 /* [ TH ]
64 * ^^^^^
65 */
66 return ring->size - ring->head;
67 }
68 return 0;
69}
70
71static inline size_t mpix_ring_tailroom(struct mpix_ring *ring)
72{
73 if (ring->head < ring->tail) {
74 /* [::::H T::::]
75 * ^^^^^
76 */
77 return ring->size - ring->tail;
78 }
79 if (ring->tail < ring->head) {
80 /* [ T::::::H ]
81 * ^^^^^^^
82 */
83 return ring->head - ring->tail;
84 }
85 if (mpix_ring_is_full(ring)) {
86 /* [::::::::::HT::::]
87 * ^^^^^
88 */
89 return ring->size - ring->tail;
90 }
91 return 0;
92}
93
94static inline size_t mpix_ring_peekroom(struct mpix_ring *ring)
95{
96 if (ring->head < ring->tail && ring->tail < ring->peek) {
97 /* [::::H T:P::]
98 * ^^^
99 */
100 return ring->size - ring->peek;
101 }
102 if (ring->peek < ring->head && ring->head < ring->tail) {
103 /* [:P::H T::::]
104 * ^^^
105 */
106 return ring->head - ring->peek;
107 }
108 if (ring->tail < ring->peek && ring->peek < ring->head) {
109 /* [ T:P::::H ]
110 * ^^^^^
111 */
112 return ring->head - ring->peek;
113 }
114 if (mpix_ring_is_full(ring) && ring->tail <= ring->peek) {
115 /* [::::::::::HT:P::]
116 * ^^^
117 */
118 return ring->size - ring->peek;
119 }
120 if (mpix_ring_is_full(ring) && ring->peek < ring->head) {
121 /* [::P:::::::HT::::]
122 * ^^^^^^^^
123 */
124 return ring->head - ring->peek;
125 }
126 return 0;
127}
128
129static inline size_t mpix_ring_total_used(struct mpix_ring *ring)
130{
131 if (ring->head < ring->tail) {
132 /* [::::H T::::]
133 * ^^^^^ ^^^^^
134 */
135 return ring->head + ring->size - ring->tail;
136 }
137 if (ring->tail < ring->head) {
138 /* [ T::::::H ]
139 * ^^^^^^^^
140 */
141 return ring->head - ring->tail;
142 }
143 if (mpix_ring_is_full(ring)) {
144 /* [::::::::::HT::::]
145 * ^^^^^^^^^^^^^^^^
146 */
147 return ring->size;
148 }
149 return 0;
150}
151
152static inline uint8_t *mpix_ring_write(struct mpix_ring *ring, size_t size)
153{
154 uint8_t *data = ring->data + ring->head;
155
156 if (mpix_ring_headroom(ring) < size) {
157 return NULL;
158 }
159 ring->head = (ring->head + size) % ring->size;
160 ring->peek = ring->tail;
161 ring->full = (ring->head == ring->tail);
162 return data;
163}
164
165static inline uint8_t *mpix_ring_read(struct mpix_ring *ring, size_t size)
166{
167 uint8_t *data = ring->data + ring->tail;
168
169 if (mpix_ring_tailroom(ring) < size) {
170 return NULL;
171 }
172 ring->tail = (ring->tail + size) % ring->size;
173 ring->peek = ring->tail;
174 ring->full = 0;
175 return data;
176}
177
178static inline uint8_t *mpix_ring_peek(struct mpix_ring *ring, size_t size)
179{
180 uint8_t *data = ring->data + ring->peek;
181
182 if (mpix_ring_peekroom(ring) < size) {
183 return NULL;
184 }
185 ring->peek = (ring->peek + size) % ring->size;
186 return data;
187}
188
189#endif
Ring buffer of pixels.
Definition ring.h:16
bool full
Definition ring.h:28
uint8_t * data
Definition ring.h:18
size_t peek
Definition ring.h:26
size_t head
Definition ring.h:22
size_t size
Definition ring.h:20
size_t tail
Definition ring.h:24