From 5c827225ab1645a47ee3826f44cbc0dfe30a4da6 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Fri, 10 Jul 2026 08:12:09 +0900 Subject: [PATCH] QNT: Calculate decompression buffers exactly Round image dimensions up to even values for QNT's 2x2 pixel blocks, and use the resulting exact size for pixel and alpha decompression. Verification against Only You Re Cross's QNT files confirmed that the former 1164-byte discrepancy is odd-height padding, not extra zlib output. Remove the obsolete fixed margin. --- src/qnt.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/qnt.c b/src/qnt.c index d3812fa..c658d58 100644 --- a/src/qnt.c +++ b/src/qnt.c @@ -40,11 +40,13 @@ #include "qnt.h" #include "system.h" -/* - zlib の展開バッファで、幅×高さ×3に、さらにどれくらい余裕をとるか - (リクルスで 1164バイトというのがあった) -*/ -#define ZLIBBUF_MARGIN 5*1024 +// QNT compressed data is arranged in 2x2 pixel blocks, so odd dimensions +// are decompressed through the next even width or height. +static long zlibbuf_size(qnt_header *qnt, int bytes_per_pixel) { + long width = (qnt->width + 1) & ~1; + long height = (qnt->height + 1) & ~1; + return width * height * bytes_per_pixel; +} /* Get information from header @@ -86,8 +88,8 @@ static void extract_header(uint8_t *b, qnt_header *qnt) { */ static void extract_pixel(qnt_header *qnt, uint8_t *pic, uint8_t *b) { int i, j, x, y, w, h; - long ucbuf = (qnt->width+1) * (qnt->height+1) * 3 + ZLIBBUF_MARGIN; - uint8_t *raw = malloc(sizeof(uint8_t) * ucbuf); + long ucbuf = zlibbuf_size(qnt, 3); + uint8_t *raw = malloc(ucbuf); if (Z_OK != uncompress(raw, &ucbuf, b, qnt->pixel_size)) { WARNING("uncompress failed"); @@ -168,8 +170,8 @@ static void extract_pixel(qnt_header *qnt, uint8_t *pic, uint8_t *b) { */ static void extract_alpha(qnt_header *qnt, uint8_t *pic, uint8_t *b) { int i, x, y, w, h; - long ucbuf = (qnt->width+1) * (qnt->height+1) + ZLIBBUF_MARGIN; - uint8_t *raw = malloc(sizeof(uint8_t) * ucbuf); + long ucbuf = zlibbuf_size(qnt, 1); + uint8_t *raw = malloc(ucbuf); if (Z_OK != uncompress(raw, &ucbuf, b, qnt->alpha_size)) { WARNING("uncompress failed"); @@ -231,11 +233,11 @@ cgdata *qnt_extract(uint8_t *data) { qnt_header qnt; extract_header(data, &qnt); - cg->pic = malloc(sizeof(uint8_t) * ((qnt.width+10) * (qnt.height+10) * 3)); + cg->pic = malloc(qnt.width * qnt.height * 3); extract_pixel(&qnt, cg->pic, data + qnt.hdr_size); if (qnt.alpha_size != 0) { - cg->alpha = malloc(sizeof(uint8_t) * ((qnt.width+10) * (qnt.height+10))); + cg->alpha = malloc(qnt.width * qnt.height); extract_alpha(&qnt, (uint8_t *)cg->alpha, data + qnt.hdr_size + qnt.pixel_size); }