| 211 | } |
| 212 | |
| 213 | static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end, const unsigned char* buffer, size_t buffer_size) |
| 214 | { |
| 215 | assert(buffer_size % kByteGroupSize == 0); |
| 216 | |
| 217 | unsigned char* header = data; |
| 218 | |
| 219 | // round number of groups to 4 to get number of header bytes |
| 220 | size_t header_size = (buffer_size / kByteGroupSize + 3) / 4; |
| 221 | |
| 222 | if (size_t(data_end - data) < header_size) |
| 223 | return NULL; |
| 224 | |
| 225 | data += header_size; |
| 226 | |
| 227 | memset(header, 0, header_size); |
| 228 | |
| 229 | for (size_t i = 0; i < buffer_size; i += kByteGroupSize) |
| 230 | { |
| 231 | if (size_t(data_end - data) < kByteGroupDecodeLimit) |
| 232 | return NULL; |
| 233 | |
| 234 | int best_bits = 8; |
| 235 | size_t best_size = encodeBytesGroupMeasure(buffer + i, 8); |
| 236 | |
| 237 | for (int bits = 1; bits < 8; bits *= 2) |
| 238 | { |
| 239 | size_t size = encodeBytesGroupMeasure(buffer + i, bits); |
| 240 | |
| 241 | if (size < best_size) |
| 242 | { |
| 243 | best_bits = bits; |
| 244 | best_size = size; |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | int bitslog2 = (best_bits == 1) ? 0 : (best_bits == 2 ? 1 : (best_bits == 4 ? 2 : 3)); |
| 249 | assert((1 << bitslog2) == best_bits); |
| 250 | |
| 251 | size_t header_offset = i / kByteGroupSize; |
| 252 | |
| 253 | header[header_offset / 4] |= bitslog2 << ((header_offset % 4) * 2); |
| 254 | |
| 255 | unsigned char* next = encodeBytesGroup(data, buffer + i, best_bits); |
| 256 | |
| 257 | assert(data + best_size == next); |
| 258 | data = next; |
| 259 | } |
| 260 | |
| 261 | return data; |
| 262 | } |
| 263 | |
| 264 | static unsigned char* encodeVertexBlock(unsigned char* data, unsigned char* data_end, const unsigned char* vertex_data, size_t vertex_count, size_t vertex_size, unsigned char last_vertex[256]) |
| 265 | { |
no test coverage detected