@@ -42,7 +42,9 @@ typedef struct {
4242
4343typedef struct {
4444 uint16_t * pTreeInit ; // LZW dictionary tree for the initial dictionary (0-255 max)
45- uint16_t * pTreeList ; // LZW dictionary tree as list (max. number of children per node = 1)
45+ uint16_t * pTreeListMap ; // LZW tree list: mapPos per node
46+ uint8_t * pTreeListColor ; // LZW tree list: child color per node
47+ uint16_t * pTreeListIdx ; // LZW tree list: child LZW index per node
4648 uint16_t * pTreeMap ; // LZW dictionary tree as map (backup to pTreeList in case more than 1 child is present)
4749 uint16_t * pLZWData ; // pointer to LZW data
4850 const uint8_t * pImageData ; // pointer to image data
@@ -92,27 +94,27 @@ static void resetDict(LZWGenState* pContext, const uint16_t initDictLen) {
9294 ++ (pContext -> LZWPos ); // increment position in LZW data
9395 // reset LZW list
9496 memset (pContext -> pTreeInit , 0 , initDictLen * sizeof (uint16_t ) * initDictLen );
95- memset (pContext -> pTreeList , 0 , ((sizeof (uint16_t ) * 2 ) + sizeof (uint16_t )) * MAX_DICT_LEN );
97+ memset (pContext -> pTreeListMap , 0 , sizeof (uint16_t ) * MAX_DICT_LEN );
98+ memset (pContext -> pTreeListColor , 0 , sizeof (uint8_t ) * MAX_DICT_LEN );
99+ memset (pContext -> pTreeListIdx , 0 , sizeof (uint16_t ) * MAX_DICT_LEN );
96100}
97101
98102/* add new child node */
99103static void add_child (LZWGenState * pContext , const uint16_t parentIndex , const uint16_t LZWIndex , const uint16_t initDictLen , const uint8_t nextColor ) {
100- uint16_t * pTreeList ;
101- uint16_t mapPos ;
104+ uint16_t mapPos ;
102105
103- pTreeList = pContext -> pTreeList ;
104- mapPos = pTreeList [parentIndex * (2 + 1 )];
106+ mapPos = pContext -> pTreeListMap [parentIndex ];
105107 if (!mapPos ) { // if pTreeMap is not used yet for the parent node
106- if (pTreeList [parentIndex * ( 2 + 1 ) + 2 ]) { // if at least one child node exists, switch to pTreeMap
108+ if (pContext -> pTreeListIdx [parentIndex ]) { // if at least one child node exists, switch to pTreeMap
107109 mapPos = pContext -> mapPos ;
108110 // add child to mapping table (pTreeMap)
109111 memset (pContext -> pTreeMap + ((mapPos - 1 ) * initDictLen ), 0 , initDictLen * sizeof (uint16_t ));
110112 pContext -> pTreeMap [(mapPos - 1 ) * initDictLen + nextColor ] = LZWIndex ;
111- pTreeList [parentIndex * ( 2 + 1 )] = mapPos ;
113+ pContext -> pTreeListMap [parentIndex ] = mapPos ;
112114 ++ (pContext -> mapPos );
113115 } else { // use the free spot in pTreeList for the child node
114- pTreeList [parentIndex * ( 2 + 1 ) + 1 ] = nextColor ; // color that leads to child node
115- pTreeList [parentIndex * ( 2 + 1 ) + 2 ] = LZWIndex ; // position of child node
116+ pContext -> pTreeListColor [parentIndex ] = nextColor ; // color that leads to child node
117+ pContext -> pTreeListIdx [parentIndex ] = LZWIndex ; // position of child node
116118 }
117119 } else { // directly add child node to pTreeMap
118120 pContext -> pTreeMap [(mapPos - 1 ) * initDictLen + nextColor ] = LZWIndex ;
@@ -123,7 +125,6 @@ static void add_child(LZWGenState* pContext, const uint16_t parentIndex, const u
123125/* find next LZW code representing the longest pixel sequence that is still in the dictionary*/
124126static int lzw_crawl_tree (LZWGenState * pContext , uint32_t * pStrPos , uint16_t parentIndex , const uint16_t initDictLen ) {
125127 uint16_t * pTreeInit ;
126- uint16_t * pTreeList ;
127128 uint32_t strPos ;
128129 uint16_t nextParent ;
129130 uint16_t mapPos ;
@@ -132,7 +133,6 @@ static int lzw_crawl_tree(LZWGenState* pContext, uint32_t* pStrPos, uint16_t par
132133 return CGIF_EINDEX ; // error: index in image data out-of-bounds
133134 }
134135 pTreeInit = pContext -> pTreeInit ;
135- pTreeList = pContext -> pTreeList ;
136136 strPos = * pStrPos ;
137137 // get the next LZW code from pTreeInit:
138138 // the initial nodes (0-255 max) have more children on average.
@@ -165,13 +165,13 @@ static int lzw_crawl_tree(LZWGenState* pContext, uint32_t* pStrPos, uint16_t par
165165 return CGIF_EINDEX ; // error: index in image data out-of-bounds
166166 }
167167 // first try to find child in LZW list
168- if (pTreeList [parentIndex * ( 2 + 1 ) + 2 ] && pTreeList [parentIndex * ( 2 + 1 ) + 1 ] == pContext -> pImageData [strPos + 1 ]) {
169- parentIndex = pTreeList [parentIndex * ( 2 + 1 ) + 2 ];
168+ if (pContext -> pTreeListIdx [parentIndex ] && pContext -> pTreeListColor [parentIndex ] == pContext -> pImageData [strPos + 1 ]) {
169+ parentIndex = pContext -> pTreeListIdx [parentIndex ];
170170 ++ strPos ;
171171 continue ;
172172 }
173173 // not found child yet? try to look into the LZW mapping table
174- mapPos = pContext -> pTreeList [parentIndex * ( 2 + 1 ) ];
174+ mapPos = pContext -> pTreeListMap [parentIndex ];
175175 if (mapPos ) {
176176 nextParent = pContext -> pTreeMap [(mapPos - 1 ) * initDictLen + pContext -> pImageData [strPos + 1 ]];
177177 if (nextParent ) {
@@ -314,8 +314,10 @@ static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const
314314 r = CGIF_EALLOC ;
315315 goto LZWGENERATE_Cleanup ;
316316 }
317- pContext -> pTreeList = malloc (((sizeof (uint16_t ) * 2 ) + sizeof (uint16_t )) * MAX_DICT_LEN );
318- if (pContext -> pTreeList == NULL ) {
317+ pContext -> pTreeListMap = malloc (sizeof (uint16_t ) * MAX_DICT_LEN );
318+ pContext -> pTreeListColor = malloc (sizeof (uint8_t ) * MAX_DICT_LEN );
319+ pContext -> pTreeListIdx = malloc (sizeof (uint16_t ) * MAX_DICT_LEN );
320+ if (pContext -> pTreeListMap == NULL || pContext -> pTreeListColor == NULL || pContext -> pTreeListIdx == NULL ) {
319321 r = CGIF_EALLOC ;
320322 goto LZWGENERATE_Cleanup ;
321323 }
@@ -377,7 +379,9 @@ static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const
377379LZWGENERATE_Cleanup :
378380 free (pContext -> pLZWData );
379381 free (pContext -> pTreeInit );
380- free (pContext -> pTreeList );
382+ free (pContext -> pTreeListMap );
383+ free (pContext -> pTreeListColor );
384+ free (pContext -> pTreeListIdx );
381385 free (pContext -> pTreeMap );
382386 free (pContext );
383387 return r ;
0 commit comments