| 165 | } |
| 166 | |
| 167 | static unsigned char* encodeBytesGroup(unsigned char* data, const unsigned char* buffer, int bits) |
| 168 | { |
| 169 | assert(bits >= 1 && bits <= 8); |
| 170 | |
| 171 | if (bits == 1) |
| 172 | return data; |
| 173 | |
| 174 | if (bits == 8) |
| 175 | { |
| 176 | memcpy(data, buffer, kByteGroupSize); |
| 177 | return data + kByteGroupSize; |
| 178 | } |
| 179 | |
| 180 | size_t byte_size = 8 / bits; |
| 181 | assert(kByteGroupSize % byte_size == 0); |
| 182 | |
| 183 | // fixed portion: bits bits for each value |
| 184 | // variable portion: full byte for each out-of-range value (using 1...1 as sentinel) |
| 185 | unsigned char sentinel = (1 << bits) - 1; |
| 186 | |
| 187 | for (size_t i = 0; i < kByteGroupSize; i += byte_size) |
| 188 | { |
| 189 | unsigned char byte = 0; |
| 190 | |
| 191 | for (size_t k = 0; k < byte_size; ++k) |
| 192 | { |
| 193 | unsigned char enc = (buffer[i + k] >= sentinel) ? sentinel : buffer[i + k]; |
| 194 | |
| 195 | byte <<= bits; |
| 196 | byte |= enc; |
| 197 | } |
| 198 | |
| 199 | *data++ = byte; |
| 200 | } |
| 201 | |
| 202 | for (size_t i = 0; i < kByteGroupSize; ++i) |
| 203 | { |
| 204 | if (buffer[i] >= sentinel) |
| 205 | { |
| 206 | *data++ = buffer[i]; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | return data; |
| 211 | } |
| 212 | |
| 213 | static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end, const unsigned char* buffer, size_t buffer_size) |
| 214 | { |