| 1339 | } |
| 1340 | |
| 1341 | static int webp_decode_frame(AVCodecContext *avctx, AVFrame *p, |
| 1342 | int *got_frame, AVPacket *avpkt) |
| 1343 | { |
| 1344 | WebPContext *s = avctx->priv_data; |
| 1345 | GetByteContext gb; |
| 1346 | int ret; |
| 1347 | uint32_t chunk_type, chunk_size; |
| 1348 | int vp8x_flags = 0; |
| 1349 | |
| 1350 | s->avctx = avctx; |
| 1351 | s->width = 0; |
| 1352 | s->height = 0; |
| 1353 | *got_frame = 0; |
| 1354 | s->has_alpha = 0; |
| 1355 | s->has_exif = 0; |
| 1356 | s->has_iccp = 0; |
| 1357 | bytestream2_init(&gb, avpkt->data, avpkt->size); |
| 1358 | |
| 1359 | if (bytestream2_get_bytes_left(&gb) < 12) |
| 1360 | return AVERROR_INVALIDDATA; |
| 1361 | |
| 1362 | if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { |
| 1363 | av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); |
| 1364 | return AVERROR_INVALIDDATA; |
| 1365 | } |
| 1366 | |
| 1367 | chunk_size = bytestream2_get_le32(&gb); |
| 1368 | if (bytestream2_get_bytes_left(&gb) < chunk_size) |
| 1369 | return AVERROR_INVALIDDATA; |
| 1370 | |
| 1371 | if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) { |
| 1372 | av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n"); |
| 1373 | return AVERROR_INVALIDDATA; |
| 1374 | } |
| 1375 | |
| 1376 | while (bytestream2_get_bytes_left(&gb) > 8) { |
| 1377 | char chunk_str[5] = { 0 }; |
| 1378 | |
| 1379 | chunk_type = bytestream2_get_le32(&gb); |
| 1380 | chunk_size = bytestream2_get_le32(&gb); |
| 1381 | if (chunk_size == UINT32_MAX) |
| 1382 | return AVERROR_INVALIDDATA; |
| 1383 | chunk_size += chunk_size & 1; |
| 1384 | |
| 1385 | if (bytestream2_get_bytes_left(&gb) < chunk_size) { |
| 1386 | /* we seem to be running out of data, but it could also be that the |
| 1387 | bitstream has trailing junk leading to bogus chunk_size. */ |
| 1388 | break; |
| 1389 | } |
| 1390 | |
| 1391 | switch (chunk_type) { |
| 1392 | case MKTAG('V', 'P', '8', ' '): |
| 1393 | if (!*got_frame) { |
| 1394 | ret = vp8_lossy_decode_frame(avctx, p, got_frame, |
| 1395 | avpkt->data + bytestream2_tell(&gb), |
| 1396 | chunk_size); |
| 1397 | if (ret < 0) |
| 1398 | return ret; |
nothing calls this directly
no test coverage detected