| 1399 | } |
| 1400 | |
| 1401 | static int side_data_exif_parse(AVFrame *dst, const AVPacketSideData *sd_pkt) |
| 1402 | { |
| 1403 | AVExifMetadata ifd = { 0 }; |
| 1404 | AVExifEntry *entry = NULL; |
| 1405 | AVBufferRef *buf = NULL; |
| 1406 | AVFrameSideData *sd_frame; |
| 1407 | int ret; |
| 1408 | |
| 1409 | ret = av_exif_parse_buffer(NULL, sd_pkt->data, sd_pkt->size, &ifd, |
| 1410 | AV_EXIF_TIFF_HEADER); |
| 1411 | if (ret < 0) |
| 1412 | return ret; |
| 1413 | |
| 1414 | ret = av_exif_get_entry(NULL, &ifd, av_exif_get_tag_id("Orientation"), 0, &entry); |
| 1415 | if (ret < 0) |
| 1416 | goto end; |
| 1417 | |
| 1418 | if (!entry) { |
| 1419 | ret = av_exif_ifd_to_dict(NULL, &ifd, &dst->metadata); |
| 1420 | if (ret < 0) |
| 1421 | goto end; |
| 1422 | |
| 1423 | sd_frame = av_frame_side_data_new(&dst->side_data, &dst->nb_side_data, AV_FRAME_DATA_EXIF, |
| 1424 | sd_pkt->size, 0); |
| 1425 | if (sd_frame) |
| 1426 | memcpy(sd_frame->data, sd_pkt->data, sd_pkt->size); |
| 1427 | ret = sd_frame ? 0 : AVERROR(ENOMEM); |
| 1428 | |
| 1429 | goto end; |
| 1430 | } else if (entry->count <= 0 || entry->type != AV_TIFF_SHORT) { |
| 1431 | ret = AVERROR_INVALIDDATA; |
| 1432 | goto end; |
| 1433 | } |
| 1434 | |
| 1435 | // If a display matrix already exists in the frame, give it priority |
| 1436 | if (av_frame_side_data_get(dst->side_data, dst->nb_side_data, AV_FRAME_DATA_DISPLAYMATRIX)) |
| 1437 | goto finish; |
| 1438 | |
| 1439 | sd_frame = av_frame_side_data_new(&dst->side_data, &dst->nb_side_data, AV_FRAME_DATA_DISPLAYMATRIX, |
| 1440 | sizeof(int32_t) * 9, 0); |
| 1441 | if (!sd_frame) { |
| 1442 | ret = AVERROR(ENOMEM); |
| 1443 | goto end; |
| 1444 | } |
| 1445 | |
| 1446 | ret = av_exif_orientation_to_matrix((int32_t *)sd_frame->data, entry->value.uint[0]); |
| 1447 | if (ret < 0) |
| 1448 | goto end; |
| 1449 | |
| 1450 | finish: |
| 1451 | av_exif_remove_entry(NULL, &ifd, entry->id, 0); |
| 1452 | |
| 1453 | ret = av_exif_ifd_to_dict(NULL, &ifd, &dst->metadata); |
| 1454 | if (ret < 0) |
| 1455 | goto end; |
| 1456 | |
| 1457 | ret = av_exif_write(NULL, &ifd, &buf, AV_EXIF_TIFF_HEADER); |
| 1458 | if (ret < 0) |
no test coverage detected