mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 13:50:09 +01:00
We have 3 copies of this function, so put it in the shared static library. Reviewed-by: Tapani Pälli <tapani.palli@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34118>
106 lines
2 KiB
C
106 lines
2 KiB
C
/*
|
|
* Copyright 2024-2025 Intel Corporation
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#include "error_decode_lib.h"
|
|
|
|
#include <zlib.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
const char *
|
|
ascii85_decode_char(const char *in, uint32_t *v)
|
|
{
|
|
*v = 0;
|
|
|
|
if (*in == 'z') {
|
|
in++;
|
|
} else {
|
|
*v += in[0] - 33; *v *= 85;
|
|
*v += in[1] - 33; *v *= 85;
|
|
*v += in[2] - 33; *v *= 85;
|
|
*v += in[3] - 33; *v *= 85;
|
|
*v += in[4] - 33;
|
|
in += 5;
|
|
}
|
|
|
|
return in;
|
|
}
|
|
|
|
int zlib_inflate(uint32_t **ptr, int len)
|
|
{
|
|
struct z_stream_s zstream;
|
|
void *out;
|
|
const uint32_t out_size = 128*4096; /* approximate obj size */
|
|
|
|
memset(&zstream, 0, sizeof(zstream));
|
|
|
|
zstream.next_in = (unsigned char *)*ptr;
|
|
zstream.avail_in = 4*len;
|
|
|
|
if (inflateInit(&zstream) != Z_OK)
|
|
return 0;
|
|
|
|
out = malloc(out_size);
|
|
zstream.next_out = out;
|
|
zstream.avail_out = out_size;
|
|
|
|
do {
|
|
switch (inflate(&zstream, Z_SYNC_FLUSH)) {
|
|
case Z_STREAM_END:
|
|
goto end;
|
|
case Z_OK:
|
|
break;
|
|
default:
|
|
free(out);
|
|
inflateEnd(&zstream);
|
|
return 0;
|
|
}
|
|
|
|
if (zstream.avail_out)
|
|
break;
|
|
|
|
out = realloc(out, 2*zstream.total_out);
|
|
if (out == NULL) {
|
|
inflateEnd(&zstream);
|
|
return 0;
|
|
}
|
|
|
|
zstream.next_out = (unsigned char *)out + zstream.total_out;
|
|
zstream.avail_out = zstream.total_out;
|
|
} while (1);
|
|
end:
|
|
inflateEnd(&zstream);
|
|
free(*ptr);
|
|
*ptr = out;
|
|
return zstream.total_out / 4;
|
|
}
|
|
|
|
int ascii85_decode(const char *in, uint32_t **out, bool inflate)
|
|
{
|
|
int len = 0, size = 1024;
|
|
|
|
*out = realloc(*out, sizeof(uint32_t)*size);
|
|
if (*out == NULL)
|
|
return 0;
|
|
|
|
while (*in >= '!' && *in <= 'z') {
|
|
uint32_t v = 0;
|
|
|
|
if (len == size) {
|
|
size *= 2;
|
|
*out = realloc(*out, sizeof(uint32_t)*size);
|
|
if (*out == NULL)
|
|
return 0;
|
|
}
|
|
|
|
in = ascii85_decode_char(in, &v);
|
|
(*out)[len++] = v;
|
|
}
|
|
|
|
if (!inflate)
|
|
return len;
|
|
|
|
return zlib_inflate(out, len);
|
|
}
|