2 * Raw FLAC picture parser
3 * Copyright (c) 2001 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/avassert.h"
24 #include "flac_picture.h"
28 int ff_flac_parse_picture(AVFormatContext
*s
, uint8_t *buf
, int buf_size
)
30 const CodecMime
*mime
= ff_id3v2_mime_tags
;
31 enum AVCodecID id
= AV_CODEC_ID_NONE
;
32 AVBufferRef
*data
= NULL
;
33 uint8_t mimetype
[64], *desc
= NULL
;
34 AVIOContext
*pb
= NULL
;
36 int width
, height
, ret
= 0;
40 pb
= avio_alloc_context(buf
, buf_size
, 0, NULL
, NULL
, NULL
, NULL
);
42 return AVERROR(ENOMEM
);
44 /* read the picture type */
46 if (type
>= FF_ARRAY_ELEMS(ff_id3v2_picture_types
)) {
47 av_log(s
, AV_LOG_ERROR
, "Invalid picture type: %d.\n", type
);
48 if (s
->error_recognition
& AV_EF_EXPLODE
) {
49 RETURN_ERROR(AVERROR_INVALIDDATA
);
54 /* picture mimetype */
56 if (len
<= 0 || len
>= 64 ||
57 avio_read(pb
, mimetype
, FFMIN(len
, sizeof(mimetype
) - 1)) != len
) {
58 av_log(s
, AV_LOG_ERROR
, "Could not read mimetype from an attached "
60 if (s
->error_recognition
& AV_EF_EXPLODE
)
61 ret
= AVERROR_INVALIDDATA
;
64 av_assert0(len
< sizeof(mimetype
));
67 while (mime
->id
!= AV_CODEC_ID_NONE
) {
68 if (!strncmp(mime
->str
, mimetype
, sizeof(mimetype
))) {
74 if (id
== AV_CODEC_ID_NONE
) {
75 av_log(s
, AV_LOG_ERROR
, "Unknown attached picture mimetype: %s.\n",
77 if (s
->error_recognition
& AV_EF_EXPLODE
)
78 ret
= AVERROR_INVALIDDATA
;
82 /* picture description */
85 if (!(desc
= av_malloc(len
+ 1))) {
86 RETURN_ERROR(AVERROR(ENOMEM
));
89 if (avio_read(pb
, desc
, len
) != len
) {
90 av_log(s
, AV_LOG_ERROR
, "Error reading attached picture description.\n");
91 if (s
->error_recognition
& AV_EF_EXPLODE
)
98 /* picture metadata */
99 width
= avio_rb32(pb
);
100 height
= avio_rb32(pb
);
106 av_log(s
, AV_LOG_ERROR
, "Invalid attached picture size: %d.\n", len
);
107 if (s
->error_recognition
& AV_EF_EXPLODE
)
108 ret
= AVERROR_INVALIDDATA
;
111 if (!(data
= av_buffer_alloc(len
+ FF_INPUT_BUFFER_PADDING_SIZE
))) {
112 RETURN_ERROR(AVERROR(ENOMEM
));
114 memset(data
->data
+ len
, 0, FF_INPUT_BUFFER_PADDING_SIZE
);
115 if (avio_read(pb
, data
->data
, len
) != len
) {
116 av_log(s
, AV_LOG_ERROR
, "Error reading attached picture data.\n");
117 if (s
->error_recognition
& AV_EF_EXPLODE
)
122 st
= avformat_new_stream(s
, NULL
);
124 RETURN_ERROR(AVERROR(ENOMEM
));
127 av_init_packet(&st
->attached_pic
);
128 st
->attached_pic
.buf
= data
;
129 st
->attached_pic
.data
= data
->data
;
130 st
->attached_pic
.size
= len
;
131 st
->attached_pic
.stream_index
= st
->index
;
132 st
->attached_pic
.flags
|= AV_PKT_FLAG_KEY
;
134 st
->disposition
|= AV_DISPOSITION_ATTACHED_PIC
;
135 st
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
136 st
->codec
->codec_id
= id
;
137 st
->codec
->width
= width
;
138 st
->codec
->height
= height
;
139 av_dict_set(&st
->metadata
, "comment", ff_id3v2_picture_types
[type
], 0);
141 av_dict_set(&st
->metadata
, "title", desc
, AV_DICT_DONT_STRDUP_VAL
);
148 av_buffer_unref(&data
);