Bug Summary

File:root/firefox-clang/third_party/aom/aom_dsp/grain_table.c
Warning:line 287, column 15
Read function called when stream is in EOF state. Function has no effect

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name grain_table.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -I /root/firefox-clang/media/libaom -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -I /root/firefox-clang/media/libaom/config/linux/x64 -I /root/firefox-clang/media/libaom/config -I /root/firefox-clang/third_party/aom -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-sign-compare -Wno-unused-function -Wno-unreachable-code -Wno-unneeded-internal-declaration -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/third_party/aom/aom_dsp/grain_table.c
1/*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12/*!\file
13 * \brief This file has the implementation details of the grain table.
14 *
15 * The file format is an ascii representation for readability and
16 * editability. Array parameters are separated from the non-array
17 * parameters and prefixed with a few characters to make for easy
18 * localization with a parameter set. Each entry is prefixed with "E"
19 * and the other parameters are only specified if "update-parms" is
20 * non-zero.
21 *
22 * filmgrn1
23 * E <start-time> <end-time> <apply-grain> <random-seed> <update-parms>
24 * p <ar_coeff_lag> <ar_coeff_shift> <grain_scale_shift> ...
25 * sY <num_y_points> <point_0_x> <point_0_y> ...
26 * sCb <num_cb_points> <point_0_x> <point_0_y> ...
27 * sCr <num_cr_points> <point_0_x> <point_0_y> ...
28 * cY <ar_coeff_y_0> ....
29 * cCb <ar_coeff_cb_0> ....
30 * cCr <ar_coeff_cr_0> ....
31 * E <start-time> ...
32 */
33#include <inttypes.h>
34#include <string.h>
35#include <stdio.h>
36#include "aom_dsp/aom_dsp_common.h"
37#include "aom_dsp/grain_table.h"
38#include "aom_mem/aom_mem.h"
39
40static const char kFileMagic[8] = { 'f', 'i', 'l', 'm', 'g', 'r', 'n', '1' };
41
42static void grain_table_entry_read(FILE *file,
43 struct aom_internal_error_info *error_info,
44 aom_film_grain_table_entry_t *entry) {
45 aom_film_grain_t *pars = &entry->params;
46 int num_read =
47 fscanf(file, "E %" PRId64"l" "d" " %" PRId64"l" "d" " %d %hd %d\n", &entry->start_time,
48 &entry->end_time, &pars->apply_grain, &pars->random_seed,
49 &pars->update_parameters);
50 if (num_read == 0 && feof(file)) return;
14
Assuming 'num_read' is not equal to 0
51 if (num_read != 5) {
15
Assuming 'num_read' is equal to 5
16
Taking false branch
52 aom_internal_error(error_info, AOM_CODEC_ERROR,
53 "Unable to read entry header. Read %d != 5", num_read);
54 }
55 if (pars->update_parameters) {
17
Assuming field 'update_parameters' is not equal to 0
18
Taking true branch
56 num_read = fscanf(file, "p %d %d %d %d %d %d %d %d %d %d %d %d\n",
57 &pars->ar_coeff_lag, &pars->ar_coeff_shift,
58 &pars->grain_scale_shift, &pars->scaling_shift,
59 &pars->chroma_scaling_from_luma, &pars->overlap_flag,
60 &pars->cb_mult, &pars->cb_luma_mult, &pars->cb_offset,
61 &pars->cr_mult, &pars->cr_luma_mult, &pars->cr_offset);
62 if (num_read != 12) {
19
Assuming 'num_read' is equal to 12
20
Taking false branch
63 aom_internal_error(error_info, AOM_CODEC_ERROR,
64 "Unable to read entry params. Read %d != 12",
65 num_read);
66 }
67 if (1 != fscanf(file, "\tsY %d ", &pars->num_y_points)) {
21
Assuming the condition is false
22
Taking false branch
68 aom_internal_error(error_info, AOM_CODEC_ERROR,
69 "Unable to read num y points");
70 }
71 for (int i = 0; i < pars->num_y_points; ++i) {
23
Assuming 'i' is >= field 'num_y_points'
24
Loop condition is false. Execution continues on line 78
72 if (2 != fscanf(file, "%d %d", &pars->scaling_points_y[i][0],
73 &pars->scaling_points_y[i][1])) {
74 aom_internal_error(error_info, AOM_CODEC_ERROR,
75 "Unable to read y scaling points");
76 }
77 }
78 if (1 != fscanf(file, "\n\tsCb %d", &pars->num_cb_points)) {
25
Assuming the condition is false
26
Taking false branch
79 aom_internal_error(error_info, AOM_CODEC_ERROR,
80 "Unable to read num cb points");
81 }
82 for (int i = 0; i < pars->num_cb_points; ++i) {
27
Assuming 'i' is >= field 'num_cb_points'
28
Loop condition is false. Execution continues on line 89
83 if (2 != fscanf(file, "%d %d", &pars->scaling_points_cb[i][0],
84 &pars->scaling_points_cb[i][1])) {
85 aom_internal_error(error_info, AOM_CODEC_ERROR,
86 "Unable to read cb scaling points");
87 }
88 }
89 if (1 != fscanf(file, "\n\tsCr %d", &pars->num_cr_points)) {
29
Assuming the condition is false
30
Taking false branch
90 aom_internal_error(error_info, AOM_CODEC_ERROR,
91 "Unable to read num cr points");
92 }
93 for (int i = 0; i < pars->num_cr_points; ++i) {
31
Assuming 'i' is >= field 'num_cr_points'
32
Loop condition is false. Execution continues on line 101
94 if (2 != fscanf(file, "%d %d", &pars->scaling_points_cr[i][0],
95 &pars->scaling_points_cr[i][1])) {
96 aom_internal_error(error_info, AOM_CODEC_ERROR,
97 "Unable to read cr scaling points");
98 }
99 }
100
101 if (fscanf(file, "\n\tcY")) {
33
Assuming the condition is false
34
Taking false branch
102 aom_internal_error(error_info, AOM_CODEC_ERROR,
103 "Unable to read Y coeffs header (cY)");
104 }
105 const int n = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
106 for (int i = 0; i < n; ++i) {
35
Assuming 'i' is >= 'n'
36
Loop condition is false. Execution continues on line 112
107 if (1 != fscanf(file, "%d", &pars->ar_coeffs_y[i])) {
108 aom_internal_error(error_info, AOM_CODEC_ERROR,
109 "Unable to read Y coeffs");
110 }
111 }
112 if (fscanf(file, "\n\tcCb")) {
37
Assuming the condition is false
38
Taking false branch
113 aom_internal_error(error_info, AOM_CODEC_ERROR,
114 "Unable to read Cb coeffs header (cCb)");
115 }
116 for (int i = 0; i <= n; ++i) {
39
Assuming 'i' is > 'n'
40
Loop condition is false. Execution continues on line 122
117 if (1 != fscanf(file, "%d", &pars->ar_coeffs_cb[i])) {
118 aom_internal_error(error_info, AOM_CODEC_ERROR,
119 "Unable to read Cb coeffs");
120 }
121 }
122 if (fscanf(file, "\n\tcCr")) {
41
Assuming the condition is false
42
Taking false branch
123 aom_internal_error(error_info, AOM_CODEC_ERROR,
124 "Unable read to Cr coeffs header (cCr)");
125 }
126 for (int i = 0; i
42.1
'i' is > 'n'
<= n; ++i) {
43
Loop condition is false. Execution continues on line 132
127 if (1 != fscanf(file, "%d", &pars->ar_coeffs_cr[i])) {
128 aom_internal_error(error_info, AOM_CODEC_ERROR,
129 "Unable to read Cr coeffs");
130 }
131 }
132 (void)fscanf(file, "\n");
44
Assuming stream reaches end-of-file here
133 }
134}
135
136static void grain_table_entry_write(FILE *file,
137 aom_film_grain_table_entry_t *entry) {
138 const aom_film_grain_t *pars = &entry->params;
139 fprintf(file, "E %" PRId64"l" "d" " %" PRId64"l" "d" " %d %d %d\n", entry->start_time,
140 entry->end_time, pars->apply_grain, pars->random_seed,
141 pars->update_parameters);
142 if (pars->update_parameters) {
143 fprintf(file, "\tp %d %d %d %d %d %d %d %d %d %d %d %d\n",
144 pars->ar_coeff_lag, pars->ar_coeff_shift, pars->grain_scale_shift,
145 pars->scaling_shift, pars->chroma_scaling_from_luma,
146 pars->overlap_flag, pars->cb_mult, pars->cb_luma_mult,
147 pars->cb_offset, pars->cr_mult, pars->cr_luma_mult,
148 pars->cr_offset);
149 fprintf(file, "\tsY %d ", pars->num_y_points);
150 for (int i = 0; i < pars->num_y_points; ++i) {
151 fprintf(file, " %d %d", pars->scaling_points_y[i][0],
152 pars->scaling_points_y[i][1]);
153 }
154 fprintf(file, "\n\tsCb %d", pars->num_cb_points);
155 for (int i = 0; i < pars->num_cb_points; ++i) {
156 fprintf(file, " %d %d", pars->scaling_points_cb[i][0],
157 pars->scaling_points_cb[i][1]);
158 }
159 fprintf(file, "\n\tsCr %d", pars->num_cr_points);
160 for (int i = 0; i < pars->num_cr_points; ++i) {
161 fprintf(file, " %d %d", pars->scaling_points_cr[i][0],
162 pars->scaling_points_cr[i][1]);
163 }
164 fprintf(file, "\n\tcY");
165 const int n = 2 * pars->ar_coeff_lag * (pars->ar_coeff_lag + 1);
166 for (int i = 0; i < n; ++i) {
167 fprintf(file, " %d", pars->ar_coeffs_y[i]);
168 }
169 fprintf(file, "\n\tcCb");
170 for (int i = 0; i <= n; ++i) {
171 fprintf(file, " %d", pars->ar_coeffs_cb[i]);
172 }
173 fprintf(file, "\n\tcCr");
174 for (int i = 0; i <= n; ++i) {
175 fprintf(file, " %d", pars->ar_coeffs_cr[i]);
176 }
177 fprintf(file, "\n");
178 }
179}
180
181// TODO(https://crbug.com/aomedia/3228): Update this function to return an
182// integer status.
183void aom_film_grain_table_append(aom_film_grain_table_t *t, int64_t time_stamp,
184 int64_t end_time,
185 const aom_film_grain_t *grain) {
186 if (!t->tail || memcmp(grain, &t->tail->params, sizeof(*grain))) {
187 aom_film_grain_table_entry_t *new_tail = aom_malloc(sizeof(*new_tail));
188 if (!new_tail) return;
189 memset(new_tail, 0, sizeof(*new_tail));
190 if (t->tail) t->tail->next = new_tail;
191 if (!t->head) t->head = new_tail;
192 t->tail = new_tail;
193
194 new_tail->start_time = time_stamp;
195 new_tail->end_time = end_time;
196 new_tail->params = *grain;
197 } else {
198 t->tail->end_time = AOMMAX(t->tail->end_time, end_time)(((t->tail->end_time) > (end_time)) ? (t->tail->
end_time) : (end_time))
;
199 t->tail->start_time = AOMMIN(t->tail->start_time, time_stamp)(((t->tail->start_time) < (time_stamp)) ? (t->tail
->start_time) : (time_stamp))
;
200 }
201}
202
203int aom_film_grain_table_lookup(aom_film_grain_table_t *t, int64_t time_stamp,
204 int64_t end_time, int erase,
205 aom_film_grain_t *grain) {
206 aom_film_grain_table_entry_t *entry = t->head;
207 aom_film_grain_table_entry_t *prev_entry = NULL((void*)0);
208 uint16_t random_seed = grain ? grain->random_seed : 0;
209 if (grain) memset(grain, 0, sizeof(*grain));
210
211 while (entry) {
212 aom_film_grain_table_entry_t *next = entry->next;
213 if (time_stamp >= entry->start_time && time_stamp < entry->end_time) {
214 if (grain) {
215 *grain = entry->params;
216 if (time_stamp != 0) grain->random_seed = random_seed;
217 }
218 if (!erase) return 1;
219
220 const int64_t entry_end_time = entry->end_time;
221 if (time_stamp <= entry->start_time && end_time >= entry->end_time) {
222 if (t->tail == entry) t->tail = prev_entry;
223 if (prev_entry) {
224 prev_entry->next = entry->next;
225 } else {
226 t->head = entry->next;
227 }
228 aom_free(entry);
229 } else if (time_stamp <= entry->start_time &&
230 end_time < entry->end_time) {
231 entry->start_time = end_time;
232 } else if (time_stamp > entry->start_time &&
233 end_time >= entry->end_time) {
234 entry->end_time = time_stamp;
235 } else {
236 aom_film_grain_table_entry_t *new_entry =
237 aom_malloc(sizeof(*new_entry));
238 if (!new_entry) return 0;
239 new_entry->next = entry->next;
240 new_entry->start_time = end_time;
241 new_entry->end_time = entry->end_time;
242 new_entry->params = entry->params;
243 entry->next = new_entry;
244 entry->end_time = time_stamp;
245 if (t->tail == entry) t->tail = new_entry;
246 }
247 // If segments aren't aligned, delete from the beginning of subsequent
248 // segments
249 if (end_time > entry_end_time) {
250 // Ignoring the return value here is safe since we're erasing from the
251 // beginning of subsequent entries.
252 aom_film_grain_table_lookup(t, entry_end_time, end_time, /*erase=*/1,
253 NULL((void*)0));
254 }
255 return 1;
256 }
257 prev_entry = entry;
258 entry = next;
259 }
260 return 0;
261}
262
263aom_codec_err_t aom_film_grain_table_read(
264 aom_film_grain_table_t *t, const char *filename,
265 struct aom_internal_error_info *error_info) {
266 FILE *const file = fopen(filename, "rb");
267 error_info->error_code = AOM_CODEC_OK;
268
269 if (!file
0.1
'file' is non-null
) {
1
Taking false branch
270 error_info->error_code = AOM_CODEC_ERROR;
271 return AOM_CODEC_ERROR;
272 }
273
274 error_info->setjmp = 1;
275 if (setjmp(error_info->jmp)_setjmp (error_info->jmp) == 0) {
2
Assuming the condition is true
3
Taking true branch
276 // Read in one extra character as there should be white space after
277 // the header.
278 char magic[9];
279 if (!fread(magic, 9, 1, file) || memcmp(magic, kFileMagic, 8)) {
4
Assuming the condition is false
5
Taking false branch
280 aom_internal_error(error_info, AOM_CODEC_ERROR,
281 "Unable to read (or invalid) file magic");
282 }
283
284 aom_film_grain_table_entry_t *prev_entry = NULL((void*)0);
285 for (;;) {
6
Loop condition is true. Entering loop body
46
Loop condition is true. Entering loop body
286 // Check for end of file before attempting to read.
287 int c = fgetc(file);
47
Read function called when stream is in EOF state. Function has no effect
288 if (c == EOF(-1)) {
7
Taking false branch
289 break;
290 }
291 ungetc(c, file);
292
293 aom_film_grain_table_entry_t *entry = aom_malloc(sizeof(*entry));
294 if (!entry) {
8
Assuming 'entry' is non-null
9
Taking false branch
295 aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
296 "Unable to allocate grain table entry");
297 }
298 memset(entry, 0, sizeof(*entry));
299 entry->next = NULL((void*)0);
300
301 if (prev_entry
9.1
'prev_entry' is null
) prev_entry->next = entry;
10
Taking false branch
302 if (!t->head) t->head = entry;
11
Assuming field 'head' is non-null
12
Taking false branch
303 t->tail = entry;
304 prev_entry = entry;
305
306 grain_table_entry_read(file, error_info, entry);
13
Calling 'grain_table_entry_read'
45
Returning from 'grain_table_entry_read'
307 }
308 }
309
310 fclose(file);
311 error_info->setjmp = 0;
312
313 return error_info->error_code;
314}
315
316aom_codec_err_t aom_film_grain_table_write(
317 const aom_film_grain_table_t *t, const char *filename,
318 struct aom_internal_error_info *error_info) {
319 FILE *const file = fopen(filename, "wb");
320 error_info->error_code = AOM_CODEC_OK;
321
322 if (!file) {
323 error_info->error_code = AOM_CODEC_ERROR;
324 return AOM_CODEC_ERROR;
325 }
326
327 error_info->setjmp = 1;
328 if (setjmp(error_info->jmp)_setjmp (error_info->jmp) == 0) {
329 if (!fwrite(kFileMagic, 8, 1, file)) {
330 aom_internal_error(error_info, AOM_CODEC_ERROR,
331 "Unable to write file magic");
332 }
333
334 fprintf(file, "\n");
335 aom_film_grain_table_entry_t *entry = t->head;
336 while (entry) {
337 grain_table_entry_write(file, entry);
338 entry = entry->next;
339 }
340 }
341
342 fclose(file);
343 error_info->setjmp = 0;
344
345 return error_info->error_code;
346}
347
348void aom_film_grain_table_free(aom_film_grain_table_t *t) {
349 aom_film_grain_table_entry_t *entry = t->head;
350 while (entry) {
351 aom_film_grain_table_entry_t *next = entry->next;
352 aom_free(entry);
353 entry = next;
354 }
355 memset(t, 0, sizeof(*t));
356}