blob: f1ac2c703ee8fcfaa8c83bb5bc9315e6a9ef726d [file] [log] [blame]
/*
* 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);
}