@@ -162,26 +162,22 @@ internal_exr_destroy_part (exr_context_t ctxt, exr_priv_part_t cur)
162162 atomic_store (& (cur -> chunk_table ), (uintptr_t ) (0 ));
163163#endif
164164 if (ctable && ((uintptr_t ) ctable ) != UINTPTR_MAX ) dofree (ctable );
165+
166+ /* we avoid malloc on one part files, but need to check */
167+ if (cur != & (ctxt -> first_part )) { dofree (cur ); }
168+ else { memset (cur , 0 , sizeof (struct _priv_exr_part_t )); }
165169}
166170
167171/**************************************/
168172
169173static void
170174internal_exr_destroy_parts (exr_context_t ctxt )
171175{
172- exr_memory_free_func_t dofree = ctxt -> free_fn ;
173176 for (int p = 0 ; p < ctxt -> num_parts ; ++ p )
174- {
175- exr_priv_part_t cur = ctxt -> parts [p ];
176-
177- internal_exr_destroy_part (ctxt , cur );
178-
179- /* the first one is always the one that is part of the file */
180- if (cur != & (ctxt -> first_part )) { dofree (cur ); }
181- else { memset (cur , 0 , sizeof (struct _priv_exr_part_t )); }
182- }
177+ internal_exr_destroy_part (ctxt , ctxt -> parts [p ]);
183178
184- if (ctxt -> num_parts > 1 ) dofree (ctxt -> parts );
179+ if (ctxt -> parts != & (ctxt -> init_part )) ctxt -> free_fn (ctxt -> parts );
180+ ctxt -> init_part = NULL ;
185181 ctxt -> parts = NULL ;
186182 ctxt -> num_parts = 0 ;
187183}
@@ -200,15 +196,14 @@ internal_exr_add_part (
200196
201197 if (ncount == 1 )
202198 {
203- /* no need to zilch, the parent struct will have already been zero'ed */
199+ /* avoid an initial malloc by embedding a part in the struct... */
204200 part = & (f -> first_part );
201+ /* also need a pointer to pointer... */
205202 f -> init_part = part ;
206203 nptrs = & (f -> init_part );
207204 }
208205 else
209206 {
210- struct _priv_exr_part_t nil = {0 };
211-
212207 part = f -> alloc_fn (sizeof (struct _priv_exr_part_t ));
213208 if (!part ) return f -> standard_error (f , EXR_ERR_OUT_OF_MEMORY );
214209
@@ -218,8 +213,8 @@ internal_exr_add_part (
218213 f -> free_fn (part );
219214 return f -> standard_error (f , EXR_ERR_OUT_OF_MEMORY );
220215 }
221- * part = nil ;
222216 }
217+ memset (part , 0 , sizeof (struct _priv_exr_part_t ));
223218
224219 /* assign appropriately invalid values */
225220 part -> storage_mode = EXR_STORAGE_LAST_TYPE ;
@@ -234,16 +229,13 @@ internal_exr_add_part (
234229 part -> dwa_compression_level = f -> default_dwa_quality ;
235230
236231 /* put it into the part table */
237- if ( ncount > 1 )
232+ for ( int p = 0 ; p < f -> num_parts ; ++ p )
238233 {
239- for (int p = 0 ; p < f -> num_parts ; ++ p )
240- {
241- nptrs [p ] = f -> parts [p ];
242- }
243- nptrs [ncount - 1 ] = part ;
234+ nptrs [p ] = f -> parts [p ];
244235 }
236+ nptrs [f -> num_parts ] = part ;
245237
246- if (f -> num_parts > 1 ) { f -> free_fn (f -> parts ); }
238+ if (f -> parts && f -> parts != & ( f -> init_part ) ) { f -> free_fn (f -> parts ); }
247239 f -> parts = nptrs ;
248240 f -> num_parts = ncount ;
249241 if (outpart ) * outpart = part ;
@@ -264,20 +256,8 @@ internal_exr_revert_add_part (
264256 * new_index = -1 ;
265257
266258 internal_exr_destroy_part (ctxt , part );
267- if (ncount == 0 )
268- {
269- ctxt -> num_parts = 0 ;
270- ctxt -> init_part = NULL ;
271- ctxt -> parts = NULL ;
272- }
273- else if (ncount == 1 )
274- {
275- if (part == & (ctxt -> first_part )) ctxt -> first_part = * (ctxt -> parts [1 ]);
276- ctxt -> init_part = & (ctxt -> first_part );
277- ctxt -> free_fn (ctxt -> parts );
278- ctxt -> parts = & (ctxt -> init_part );
279- }
280- else
259+
260+ if ( ncount > 0 )
281261 {
282262 int np = 0 ;
283263 for (int p = 0 ; p < ctxt -> num_parts ; ++ p )
@@ -287,6 +267,13 @@ internal_exr_revert_add_part (
287267 ++ np ;
288268 }
289269 }
270+ else
271+ {
272+ if (ctxt -> parts && ctxt -> parts != & (ctxt -> init_part ))
273+ ctxt -> free_fn (ctxt -> parts );
274+
275+ ctxt -> parts = NULL ;
276+ }
290277 ctxt -> num_parts = ncount ;
291278}
292279
0 commit comments