Grok 20.3.2
StreamIO.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016-2026 Grok Image Compression Inc.
3 *
4 * This source code is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Affero General Public License, version 3,
6 * as published by the Free Software Foundation.
7 *
8 * This source code is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Affero General Public License for more details.
12 *
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 */
17
18#pragma once
19
20namespace grk
21{
22
23void grk_write(uint8_t* dest, const uint8_t* value, [[maybe_unused]] uint8_t sizeOfType,
24 uint32_t numBytes);
25
26template<typename TYPE>
27void grk_write(uint8_t* dest, TYPE value, uint32_t numBytes)
28{
29 grk_write(dest, (const uint8_t*)&value, sizeof(TYPE), numBytes);
30}
31
32template<typename TYPE>
33void grk_write(uint8_t* dest, TYPE value)
34{
35 grk_write(dest, value, sizeof(TYPE));
36}
37
38template<typename TYPE>
39void grk_write(uint8_t** dest, TYPE value)
40{
41 grk_write(*dest, value, sizeof(TYPE));
42 *dest += sizeof(TYPE);
43}
44
45template<typename TYPE>
46void grk_read(const uint8_t* src, TYPE* value, uint32_t numBytes)
47{
48 assert(numBytes > 0 && numBytes <= sizeof(TYPE));
49 if(numBytes == 0 || numBytes > sizeof(TYPE))
50 throw std::runtime_error("read size too large");
51
52 *value = 0;
53 memcpy(value, src, numBytes); // Copy bytes directly
54#if defined(_MSC_VER) // MSVC
55 if(numBytes == 8)
56 {
57 *value = (TYPE)_byteswap_uint64((uint64_t)*value); // Big-endian to little-endian
58 }
59 else if(numBytes == 4)
60 {
61 *value = (TYPE)_byteswap_ulong((uint32_t)*value);
62 }
63 else if(numBytes == 2)
64 {
65 *value = (TYPE)_byteswap_ushort((uint16_t)*value);
66 }
67#elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || \
68 defined(__OpenBSD__) // POSIX with byteswap.h
69#include <byteswap.h>
70 if(numBytes == 8)
71 {
72 *value = (TYPE)bswap_64((uint64_t)*value);
73 }
74 else if(numBytes == 4)
75 {
76 *value = (TYPE)bswap_32((uint32_t)*value);
77 }
78 else if(numBytes == 2)
79 {
80 *value = (TYPE)bswap_16((uint16_t)*value);
81 }
82#else // Fallback for other POSIX systems
83 if(numBytes == 8)
84 {
85 uint64_t tmp = *(uint64_t*)value;
86 *value = (TYPE)(((tmp >> 56) & 0xFF) | ((tmp >> 40) & 0xFF00) | ((tmp >> 24) & 0xFF0000) |
87 ((tmp >> 8) & 0xFF000000) | ((tmp << 8) & 0xFF00000000) |
88 ((tmp << 24) & 0xFF0000000000) | ((tmp << 40) & 0xFF000000000000) |
89 ((tmp << 56) & 0xFF00000000000000));
90 }
91 else if(numBytes == 4)
92 {
93 uint32_t tmp = *(uint32_t*)value;
94 *value = (TYPE)(((tmp >> 24) & 0xFF) | ((tmp >> 8) & 0xFF00) | ((tmp << 8) & 0xFF0000) |
95 ((tmp << 24) & 0xFF000000));
96 }
97 else if(numBytes == 2)
98 {
99 uint16_t tmp = *(uint16_t*)value;
100 *value = (TYPE)(((tmp >> 8) & 0xFF) | ((tmp << 8) & 0xFF00));
101 }
102#endif
103}
104
105template<typename TYPE>
106void grk_read(uint8_t** src, uint32_t* bytesRemaining, TYPE* value, uint32_t numBytes)
107{
108 grk_read(*src, value, numBytes);
109 *src += numBytes;
110 if(bytesRemaining)
111 {
112 if(*bytesRemaining < numBytes)
113 throw std::runtime_error("grk_read: not enough bytes to read data");
114 *bytesRemaining -= numBytes;
115 }
116}
117
118template<typename TYPE>
119void grk_read(uint8_t** src, TYPE* value, uint32_t numBytes)
120{
121 grk_read(src, nullptr, value, numBytes);
122}
123
124template<typename TYPE>
125void grk_read(const uint8_t* dest, TYPE* value)
126{
127 grk_read<TYPE>(dest, value, sizeof(TYPE));
128}
129
130template<typename TYPE>
131void grk_read(uint8_t** dest, uint32_t* bytesRemaining, TYPE* value)
132{
133 grk_read<TYPE>(*dest, value, sizeof(TYPE));
134 *dest += sizeof(TYPE);
135 if(bytesRemaining)
136 {
137 if(*bytesRemaining < sizeof(TYPE))
138 throw std::runtime_error("grk_read: not enough bytes to read data");
139 *bytesRemaining -= (uint32_t)sizeof(TYPE);
140 }
141}
142
143template<typename TYPE>
144void grk_read(uint8_t** dest, TYPE* value)
145{
146 return grk_read(dest, nullptr, value);
147}
148
149} // namespace grk
ResWindow.
Definition CompressedChunkCache.h:36
void grk_read(const uint8_t *src, TYPE *value, uint32_t numBytes)
Definition StreamIO.h:46
void grk_write(uint8_t *dest, const uint8_t *value, uint8_t sizeOfType, uint32_t numBytes)
Definition StreamIO.cpp:25