Skip to content

Commit 84e09b1

Browse files
committed
fix LZW data alloc size calculation
1 parent f066d17 commit 84e09b1

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

src/cgif_raw.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ static uint32_t create_byte_list_block(uint8_t *byteList, uint8_t *byteListBlock
300300
/* create all LZW raster data in GIF-format */
301301
static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const uint8_t* pImageData, const uint16_t initDictLen, const uint8_t initCodeLen){
302302
LZWGenState* pContext;
303-
uint32_t lzwPos, bytePos;
303+
uint32_t lzwPos, bytePos, entriesPerCycle, maxResets;
304304
uint32_t bytePosBlock;
305305
int r;
306306
// TBD recycle LZW tree list and map (if possible) to decrease the number of allocs
@@ -310,7 +310,11 @@ static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const
310310
pContext->pTreeMap = malloc(((MAX_DICT_LEN / 2) + 1) * (initDictLen * sizeof(uint16_t))); // TBD check return value of malloc
311311
pContext->numPixel = numPixel;
312312
pContext->pImageData = pImageData;
313-
pContext->pLZWData = malloc(sizeof(uint16_t) * (numPixel + 2)); // TBD check return value of malloc
313+
// Buffer must hold at max (conservative upper bound): 1 initial clear + numPixel data codes + N reset clears + 1 termination
314+
// where N = max dictionary resets = ceil(numPixel / (MAX_DICT_LEN - initDictLen - 2))
315+
entriesPerCycle = MAX_DICT_LEN - initDictLen;
316+
maxResets = (numPixel + entriesPerCycle - 1) / entriesPerCycle;
317+
pContext->pLZWData = malloc(sizeof(uint16_t) * (numPixel + 2 + maxResets)); // TBD check return value of malloc
314318
pContext->LZWPos = 0;
315319

316320
// actually generate the LZW sequence.

0 commit comments

Comments
 (0)