Grok 15.1.0
buffer.h
Go to the documentation of this file.
1
17#pragma once
18
19namespace grk
20{
21
22template<typename T>
24{
25 T* alloc(size_t length)
26 {
27 return new T[length];
28 }
29 void dealloc(T* buf)
30 {
31 delete[] buf;
32 }
33};
34template<typename T>
36{
37 T* alloc(size_t length)
38 {
39 return (T*)grk_aligned_malloc(length * sizeof(T));
40 }
41 void dealloc(T* buf)
42 {
44 }
45};
46template<typename T, template<typename TT> typename A>
47struct grk_buf : A<T>
48{
49 grk_buf(T* buffer, size_t off, size_t length, bool ownsData)
50 : buf(buffer), offset(off), len(length), owns_data(ownsData)
51 {}
52 grk_buf(T* buffer, size_t length) : grk_buf(buffer, 0, length, false) {}
53 grk_buf() : grk_buf(0, 0, 0, false) {}
54 grk_buf(T* buffer, size_t length, bool ownsData) : grk_buf(buffer, 0, length, ownsData) {}
55 virtual ~grk_buf()
56 {
57 dealloc();
58 }
59 explicit grk_buf(const grk_buf& rhs)
60 {
61 this->operator=(rhs);
62 }
63 grk_buf& operator=(const grk_buf& rhs) // copy assignment
64 {
65 return operator=(&rhs);
66 }
67 grk_buf& operator=(const grk_buf* rhs) // copy assignment
68 {
69 if(this != rhs)
70 { // self-assignment check expected
71 buf = rhs->buf;
72 offset = rhs->offset;
73 len = rhs->len;
74 owns_data = false;
75 }
76 return *this;
77 }
78 inline bool canRead(void)
79 {
80 return offset < len;
81 }
82 inline T read(void)
83 {
84 return buf[offset++];
85 }
86 inline bool write(T val)
87 {
88 if(offset == len)
89 return false;
90 buf[offset++] = val;
91
92 return true;
93 }
94 inline bool write(T* b, size_t size)
95 {
96 if(offset + size > len)
97 return false;
98 memcpy(buf + offset, b, size);
99 offset += size;
100
101 return true;
102 }
103 virtual bool alloc(size_t length)
104 {
105 if(buf && len > length)
106 return true;
107 dealloc();
108 buf = A<T>::alloc(length);
109 if(!buf)
110 return false;
111 len = length;
112 offset = 0;
113 owns_data = true;
114
115 return true;
116 }
117 virtual void dealloc()
118 {
119 if(owns_data)
120 A<T>::dealloc(buf);
121 buf = nullptr;
122 owns_data = false;
123 offset = 0;
124 len = 0;
125 }
126 // set buf to buf without owning it
127 void attach(T* buffer)
128 {
130 buf = buffer;
131 }
132 // set buf to buf and own it
133 void acquire(T* buffer)
134 {
136 buffer = buf;
137 owns_data = true;
138 }
139 // transfer buf to buffer, and cease owning it
140 void transfer(T** buffer)
141 {
142 if(buffer)
143 {
144 assert(!buf || owns_data);
145 *buffer = buf;
146 buf = nullptr;
147 owns_data = false;
148 }
149 }
150 size_t remainingLength(void)
151 {
152 return len - offset;
153 }
154 void incrementOffset(ptrdiff_t off)
155 {
156 /* we allow the offset to move to one location beyond end of buffer segment*/
157 if(off > 0)
158 {
159 if(offset > (size_t)(SIZE_MAX - (size_t)off))
160 {
161 grklog.warn("grk_buf8: overflow");
162 offset = len;
163 }
164 else if(offset + (size_t)off > len)
165 {
166#ifdef DEBUG_SEG_BUF
167 grklog.warn("grk_buf8: attempt to increment buffer offset out of bounds");
168#endif
169 offset = len;
170 }
171 else
172 {
173 offset = offset + (size_t)off;
174 }
175 }
176 else if(off < 0)
177 {
178 if(offset < (size_t)(-off))
179 {
180 grklog.warn("grk_buf8: underflow");
181 offset = 0;
182 }
183 else
184 {
185 offset = (size_t)((ptrdiff_t)offset + off);
186 }
187 }
188 }
189 T* currPtr(void) const
190 {
191 if(!buf)
192 return nullptr;
193 return buf + offset;
194 }
195 T* buf; /* internal array*/
196 size_t offset; /* current offset into array */
197 size_t len; /* length of array */
198 bool owns_data; /* true if buffer manages the buf array */
199};
200
203
204template<typename T>
206{
207 grk_buf2d_simple() : grk_buf2d_simple(nullptr, 0, 0) {}
208 grk_buf2d_simple(T* buf, uint32_t stride, uint32_t height)
209 : buf_(buf), stride_(stride), height_(height)
210 {}
212 {
213 buf_ += deltaX;
214
215 return *this;
216 }
218 {
219 buf_ += deltaY * stride_;
220
221 return *this;
222 }
224 uint32_t stride_;
225 uint32_t height_;
226};
227
228template<typename T, template<typename TT> typename A>
229struct grk_buf2d : protected grk_buf<T, A>, public grk_rect32
230{
231 grk_buf2d(T* buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
232 : grk_buf<T, A>(buffer, ownsData), grk_rect32(0, 0, w, h), stride(strd)
233 {}
234 grk_buf2d(uint32_t w, uint32_t h) : grk_buf2d(nullptr, false, w, 0, h) {}
235 explicit grk_buf2d(const grk_rect32* b)
236 : grk_buf<T, A>(nullptr, false), grk_rect32(b->x0, b->y0, b->x1, b->y1), stride(0)
237 {}
238 explicit grk_buf2d(const grk_rect32& b)
239 : grk_buf<T, A>(nullptr, false), grk_rect32(b.x0, b.y0, b.x1, b.y1), stride(0)
240 {}
241 grk_buf2d(const grk_rect32& b, [[maybe_unused]] bool useOrigin)
242 : grk_buf<T, A>(nullptr, false), grk_rect32(b), stride(0)
243 {}
244 grk_buf2d(void) : grk_buf2d(nullptr, 0, 0, 0, false) {}
245 explicit grk_buf2d(const grk_buf2d& rhs) : grk_buf<T, A>(rhs), grk_rect32(rhs), stride(rhs.stride)
246 {}
248 {
249 return grk_buf2d_simple<T>(this->buf, this->stride, this->height());
250 }
252 {
253 return grk_buf2d_simple<float>((float*)this->buf, this->stride, this->height());
254 }
255 grk_buf2d& operator=(const grk_buf2d& rhs) // copy assignment
256 {
257 return operator=(&rhs);
258 }
259 grk_buf2d& operator=(const grk_buf2d* rhs) // copy assignment
260 {
261 if(this != rhs)
262 { // self-assignment check expected
265 stride = rhs->stride;
266 }
267 return *this;
268 }
269 virtual ~grk_buf2d() = default;
270 bool alloc2d(bool clear)
271 {
272 if(!this->buf && width() && height())
273 {
274 if(!stride)
276 uint64_t data_size_needed = (uint64_t)stride * height() * sizeof(T);
277 if(!data_size_needed)
278 return true;
279 if(!grk_buf<T, A>::alloc(data_size_needed))
280 {
281 grk::grklog.error("Failed to allocate aligned memory buffer of dimensions %u x %u", stride,
282 height());
283 return false;
284 }
285 if(clear)
286 memset(this->buf, 0, data_size_needed);
287 }
288
289 return true;
290 }
291 // set buf to buffer without owning it
292 void attach(T* buffer, uint32_t strd)
293 {
294 grk_buf<T, A>::attach(buffer);
295 stride = strd;
296 }
297 void attach(grk_buf2d& rhs, uint32_t x, uint32_t y)
298 {
299 attach(&rhs, x, y);
300 }
301 void attach(grk_buf2d& rhs)
302 {
303 attach(&rhs, 0, 0);
304 }
305 void attach(grk_buf2d* rhs, uint32_t x, uint32_t y)
306 {
307 if(!rhs)
308 return;
310 this->buf = rhs->address(x, y);
311 this->len = rhs->len;
312 this->owns_data = false;
313 stride = rhs->stride;
314 }
315 void attach(grk_buf2d* rhs)
316 {
317 attach(rhs, 0, 0);
318 }
319 // set buf to buf and own it
320 void acquire(T* buffer, uint32_t strd)
321 {
323 stride = strd;
324 }
325 // transfer buf to buf, and cease owning it
326 void transfer(T** buffer, uint32_t* strd)
327 {
328 if(buffer)
329 {
331 *strd = stride;
332 }
333 }
334
341 {
342 return !(win.x0 >= x1 || win.x1 <= x0 || win.x1 > x1 || win.y0 >= y1 || win.y1 <= win.y0 ||
343 win.y1 > y1);
344 }
345 // rhs coordinates are in "this" coordinate system
346 template<typename F>
347 void copyFrom(const grk_buf2d& src, F filter)
348 {
349 return copyFrom(&src, filter);
350 }
351 // rhs coordinates are in "this" coordinate system
352 template<typename F>
353 void copyFrom(const grk_buf2d* src, F filter)
354 {
355 auto inter = intersection(src);
356 if(inter.empty())
357 return;
358
359 if(!src->buf)
360 return;
361
362 T* ptr = this->buf + (inter.y0 * stride + inter.x0);
363 T* srcPtr = src->buf + ((inter.y0 - src->y0) * src->stride + inter.x0 - src->x0);
364 uint32_t len = inter.width();
365 for(uint32_t j = inter.y0; j < inter.y1; ++j)
366 {
367 filter.copy(ptr, srcPtr, len);
368 ptr += stride;
369 srcPtr += src->stride;
370 }
371 }
373 {
374 void copy(T* dst, T* src, uint32_t len)
375 {
376 memcpy(dst, src, len);
377 }
378 };
379 void copyFrom(const grk_buf2d& src)
380 {
381 copy(src, memcpy_from());
382 }
383 T* getBuffer(void) const
384 {
385 return this->currPtr();
386 }
387 T* address(uint32_t x, uint32_t y)
388 {
389 return this->currPtr() + (uint64_t)x + (uint64_t)y * stride;
390 }
391 uint32_t stride;
392};
393
394} // namespace grk
#define SIZE_MAX
Definition MemManager.cpp:29
Copyright (C) 2016-2025 Grok Image Compression Inc.
Definition ICacheable.h:20
uint32_t grk_make_aligned_width(uint32_t width)
Definition MemManager.cpp:35
grk_buf< uint8_t, AllocatorVanilla > grk_buf8
Definition buffer.h:201
grk_rect< uint32_t > grk_rect32
Definition geometry.h:61
void * grk_aligned_malloc(size_t size)
Allocate memory aligned to a 16 byte boundary.
Definition MemManager.cpp:76
grk_buf< uint8_t, AllocatorAligned > grk_buf8_aligned
Definition buffer.h:202
void grk_aligned_free(void *ptr)
Definition MemManager.cpp:80
Logger & grklog
Definition Logger.cpp:20
Definition buffer.h:36
void dealloc(T *buf)
Definition buffer.h:41
T * alloc(size_t length)
Definition buffer.h:37
Definition buffer.h:24
void dealloc(T *buf)
Definition buffer.h:29
T * alloc(size_t length)
Definition buffer.h:25
Definition buffer.h:373
void copy(T *dst, T *src, uint32_t len)
Definition buffer.h:374
Definition buffer.h:206
grk_buf2d_simple(T *buf, uint32_t stride, uint32_t height)
Definition buffer.h:208
grk_buf2d_simple()
Definition buffer.h:207
T * buf_
Definition buffer.h:223
uint32_t height_
Definition buffer.h:225
grk_buf2d_simple & incX_IN_PLACE(size_t deltaX)
Definition buffer.h:211
grk_buf2d_simple & incY_IN_PLACE(size_t deltaY)
Definition buffer.h:217
uint32_t stride_
Definition buffer.h:224
void transfer(T **buffer, uint32_t *strd)
Definition buffer.h:326
void copyFrom(const grk_buf2d &src, F filter)
Definition buffer.h:347
grk_buf2d(uint32_t w, uint32_t h)
Definition buffer.h:234
T * getBuffer(void) const
Definition buffer.h:383
void attach(T *buffer, uint32_t strd)
Definition buffer.h:292
void attach(grk_buf2d *rhs, uint32_t x, uint32_t y)
Definition buffer.h:305
grk_buf2d(const grk_rect32 &b, bool useOrigin)
Definition buffer.h:241
void attach(grk_buf2d *rhs)
Definition buffer.h:315
void attach(grk_buf2d &rhs, uint32_t x, uint32_t y)
Definition buffer.h:297
void copyFrom(const grk_buf2d &src)
Definition buffer.h:379
bool alloc2d(bool clear)
Definition buffer.h:270
void copyFrom(const grk_buf2d *src, F filter)
Definition buffer.h:353
grk_buf2d(void)
Definition buffer.h:244
grk_buf2d(const grk_rect32 &b)
Definition buffer.h:238
grk_buf2d(const grk_buf2d &rhs)
Definition buffer.h:245
grk_buf2d(const grk_rect32 *b)
Definition buffer.h:235
grk_buf2d & operator=(const grk_buf2d *rhs)
Definition buffer.h:259
grk_buf2d & operator=(const grk_buf2d &rhs)
Definition buffer.h:255
virtual ~grk_buf2d()=default
T * address(uint32_t x, uint32_t y)
Definition buffer.h:387
grk_buf2d(T *buffer, bool ownsData, uint32_t w, uint32_t strd, uint32_t h)
Definition buffer.h:231
void acquire(T *buffer, uint32_t strd)
Definition buffer.h:320
grk_buf2d_simple< float > simpleF(void) const
Definition buffer.h:251
grk_buf2d_simple< T > simple(void) const
Definition buffer.h:247
uint32_t stride
Definition buffer.h:391
bool isWindowValid(grk_rect32 win)
Returns whether window bounds are valid (non empty and within buffer bounds)
Definition buffer.h:340
void attach(grk_buf2d &rhs)
Definition buffer.h:301
Definition buffer.h:48
size_t remainingLength(void)
Definition buffer.h:150
void attach(T *buffer)
Definition buffer.h:127
T read(void)
Definition buffer.h:82
grk_buf(T *buffer, size_t length)
Definition buffer.h:52
bool owns_data
Definition buffer.h:198
size_t len
Definition buffer.h:197
void incrementOffset(ptrdiff_t off)
Definition buffer.h:154
void acquire(T *buffer)
Definition buffer.h:133
bool write(T *b, size_t size)
Definition buffer.h:94
void transfer(T **buffer)
Definition buffer.h:140
grk_buf(T *buffer, size_t off, size_t length, bool ownsData)
Definition buffer.h:49
grk_buf()
Definition buffer.h:53
bool write(T val)
Definition buffer.h:86
grk_buf & operator=(const grk_buf *rhs)
Definition buffer.h:67
virtual bool alloc(size_t length)
Definition buffer.h:103
grk_buf(const grk_buf &rhs)
Definition buffer.h:59
bool canRead(void)
Definition buffer.h:78
grk_buf & operator=(const grk_buf &rhs)
Definition buffer.h:63
grk_buf(T *buffer, size_t length, bool ownsData)
Definition buffer.h:54
T * currPtr(void) const
Definition buffer.h:189
virtual ~grk_buf()
Definition buffer.h:55
virtual void dealloc()
Definition buffer.h:117
uint8_t * buf
Definition buffer.h:195
size_t offset
Definition buffer.h:196
uint32_t width() const
Definition geometry.h:335
uint32_t y1
Definition geometry.h:125
uint32_t x0
Definition geometry.h:125
grk_rect< uint32_t > intersection(const grk_rect< uint32_t > rhs) const
Definition geometry.h:281
uint32_t x1
Definition geometry.h:125
uint32_t height() const
Definition geometry.h:339
grk_rect< uint32_t > & operator=(const grk_rect< uint32_t > &rhs)
Definition geometry.h:202
uint32_t y0
Definition geometry.h:125