Skip to content

Commit 5a8efa9

Browse files
authoredSep 11, 2025
Fixed some images crashing thumbnailer.
1 parent aa1c67a commit 5a8efa9

File tree

1 file changed

+46
-10
lines changed

1 file changed

+46
-10
lines changed
 

‎thumbnailer.c‎

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,15 @@ static AVFrame* select_best_frame(AVFrame* frames[], int size)
8787
}
8888

8989
// Calculate size and allocate buffer
90-
static void alloc_buffer(struct Buffer* dst)
90+
static int alloc_buffer(struct Buffer* dst)
9191
{
9292
dst->size
9393
= av_image_get_buffer_size(AV_PIX_FMT_RGBA, dst->width, dst->height, 1);
9494
dst->data = malloc(dst->size);
95+
if (!dst->data) {
96+
return AVERROR(ENOMEM);
97+
}
98+
return 0;
9599
}
96100

97101
// Use point subsampling to scale image up to target size and convert to RGBA
@@ -125,6 +129,9 @@ static void downscale(struct Buffer* dst, const struct Buffer const* src)
125129
// First sum all pixels into a multidimensional array
126130
const size_t size = dst->height * dst->width * sizeof(struct Pixel);
127131
struct Pixel(*img)[dst->width] = malloc(size);
132+
if (!img) {
133+
return; // Handle allocation failure
134+
}
128135
memset(img, 0, size);
129136

130137
int i = 0;
@@ -161,6 +168,9 @@ static void downscale(struct Buffer* dst, const struct Buffer const* src)
161168
i += 4;
162169
}
163170
}
171+
172+
// Free the temporary buffer
173+
free(img);
164174
}
165175

166176
// Decrease intensity of pixels with alpha
@@ -357,7 +367,10 @@ static int encode_frame(
357367
// scale_dims() does not work, if image size is exactly that of the target
358368
// thumbnail size. Perhaps a peculiarity of sws_scale().
359369
if (img->width < box.width && img->height < box.height) {
360-
alloc_buffer(img);
370+
err = alloc_buffer(img);
371+
if (err) {
372+
return err;
373+
}
361374
err = resample(img, frame);
362375
if (err) {
363376
return err;
@@ -375,15 +388,22 @@ static int encode_frame(
375388
// around the thumbnail size and much bigger ones.
376389
struct Buffer enlarged
377390
= { .width = img->width * 4, .height = img->height * 4 };
378-
alloc_buffer(&enlarged);
391+
err = alloc_buffer(&enlarged);
392+
if (err) {
393+
return err;
394+
}
379395
err = resample(&enlarged, frame);
380396
if (err) {
381397
free(enlarged.data);
382398
return err;
383399
}
384-
alloc_buffer(img);
400+
err = alloc_buffer(img);
401+
if (err) {
402+
free(enlarged.data);
403+
return err;
404+
}
385405
downscale(img, &enlarged);
386-
free(enlarged.data);
406+
// Don't free enlarged.data here - let Go handle all memory management
387407
adjust_orientation(img, orientation);
388408
return err;
389409
}
@@ -477,29 +497,42 @@ int generate_thumbnail(struct Buffer* img, AVFormatContext* avfc,
477497
int i = 0;
478498
AVFrame* frames[MAX_FRAMES] = { NULL };
479499
AVFrame* next = NULL;
500+
501+
// Initialize the output buffer to ensure clean state
502+
img->data = NULL;
503+
img->size = 0;
504+
img->width = 0;
505+
img->height = 0;
480506

481507
// Read up to 10 frames
482508
while (1) {
483509
next = av_frame_alloc();
510+
if (!next) {
511+
err = AVERROR(ENOMEM);
512+
goto cleanup;
513+
}
514+
484515
err = read_frame(avfc, avcc, next, stream);
485516
if (err) {
486-
goto end;
517+
av_frame_free(&next);
518+
goto cleanup;
487519
}
488520

489521
// Analyze only every 3rd frame to cover a larger time frame
490522
if (!(i++ % 3)) {
491523
frames[size++] = next;
492524
next = NULL;
493525
if (size == MAX_FRAMES) {
494-
goto end;
526+
break;
495527
}
496528
} else {
497529
av_frame_free(&next);
530+
next = NULL;
498531
}
499532
}
500533

501-
end:
502-
if (size) {
534+
cleanup:
535+
if (size > 0) {
503536
int orientation = 0;
504537
int rotation = get_rotation(avfc->streams[stream]);
505538

@@ -522,8 +555,11 @@ int generate_thumbnail(struct Buffer* img, AVFormatContext* avfc,
522555
img, select_best_frame(frames, size), thumb_dims, orientation);
523556
}
524557

558+
// Clean up all frames
525559
for (int i = 0; i < size; i++) {
526-
av_frame_free(&frames[i]);
560+
if (frames[i]) {
561+
av_frame_free(&frames[i]);
562+
}
527563
}
528564
if (next) {
529565
av_frame_free(&next);

0 commit comments

Comments
 (0)
Please sign in to comment.