History

avcodec/svq3: Factor out decoding extradata

Reduces indentation and avoids an extra variable for whether a sequence header has been found. It also fixes potential undefined behaviour: NULL + 0 is undefined and happens when no extradata is available.

Andreas Rheinhardt committed 1 year ago

Commit 0468b861 parent 0b3dae61 file · +132 −127Browse files

Unified · Split

libavcodec/svq3.c+132−127
@@ -1114,14 +1114,139 @@ static void init_dequant4_coeff_table(SVQ3Context *s) · 1113 unmodified lines
11141114 }
11151115 }
11161116
1117+static av_cold int svq3_decode_extradata(AVCodecContext *avctx, SVQ3Context *s,
1118+ int seqh_offset)
1119+{
1120+ const uint8_t *extradata = avctx->extradata + seqh_offset;
1121+ unsigned int size = AV_RB32(extradata + 4);
1122+ GetBitContext gb;
1123+ int ret;
1124+
1125+ if (size > avctx->extradata_size - seqh_offset - 8)
1126+ return AVERROR_INVALIDDATA;
1127+ extradata += 8;
1128+ init_get_bits(&gb, extradata, size * 8);
1129+
1130+ /* 'frame size code' and optional 'width, height' */
1131+ int frame_size_code = get_bits(&gb, 3);
1132+ int w, h;
1133+ switch (frame_size_code) {
1134+ case 0:
1135+ w = 160;
1136+ h = 120;
1137+ break;
1138+ case 1:
1139+ w = 128;
1140+ h = 96;
1141+ break;
1142+ case 2:
1143+ w = 176;
1144+ h = 144;
1145+ break;
1146+ case 3:
1147+ w = 352;
1148+ h = 288;
1149+ break;
1150+ case 4:
1151+ w = 704;
1152+ h = 576;
1153+ break;
1154+ case 5:
1155+ w = 240;
1156+ h = 180;
1157+ break;
1158+ case 6:
1159+ w = 320;
1160+ h = 240;
1161+ break;
1162+ case 7:
1163+ w = get_bits(&gb, 12);
1164+ h = get_bits(&gb, 12);
1165+ break;
1166+ }
1167+ ret = ff_set_dimensions(avctx, w, h);
1168+ if (ret < 0)
1169+ return ret;
1170+
1171+ s->halfpel_flag = get_bits1(&gb);
1172+ s->thirdpel_flag = get_bits1(&gb);
1173+
1174+ /* unknown fields */
1175+ int unk0 = get_bits1(&gb);
1176+ int unk1 = get_bits1(&gb);
1177+ int unk2 = get_bits1(&gb);
1178+ int unk3 = get_bits1(&gb);
1179+
1180+ s->low_delay = get_bits1(&gb);
1181+ avctx->has_b_frames = !s->low_delay;
1182+
1183+ /* unknown field */
1184+ int unk4 = get_bits1(&gb);
1185+
1186+ av_log(avctx, AV_LOG_DEBUG, "Unknown fields %d %d %d %d %d\n",
1187+ unk0, unk1, unk2, unk3, unk4);
1188+
1189+ if (skip_1stop_8data_bits(&gb) < 0)
1190+ return AVERROR_INVALIDDATA;
1191+
1192+ s->has_watermark = get_bits1(&gb);
1193+
1194+ if (!s->has_watermark)
1195+ return 0;
1196+
1197+#if CONFIG_ZLIB
1198+ unsigned watermark_width = get_interleaved_ue_golomb(&gb);
1199+ unsigned watermark_height = get_interleaved_ue_golomb(&gb);
1200+ int u1 = get_interleaved_ue_golomb(&gb);
1201+ int u2 = get_bits(&gb, 8);
1202+ int u3 = get_bits(&gb, 2);
1203+ int u4 = get_interleaved_ue_golomb(&gb);
1204+ unsigned long buf_len = watermark_width *
1205+ watermark_height * 4;
1206+ int offset = get_bits_count(&gb) + 7 >> 3;
1207+
1208+ if (watermark_height <= 0 ||
1209+ get_bits_left(&gb) <= 0 ||
1210+ (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height)
1211+ return AVERROR_INVALIDDATA;
1212+
1213+ av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n",
1214+ watermark_width, watermark_height);
1215+ av_log(avctx, AV_LOG_DEBUG,
1216+ "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
1217+ u1, u2, u3, u4, offset);
1218+
1219+ uint8_t *buf = av_malloc(buf_len);
1220+ if (!buf)
1221+ return AVERROR(ENOMEM);
1222+
1223+ if (uncompress(buf, &buf_len, extradata + offset,
1224+ size - offset) != Z_OK) {
1225+ av_log(avctx, AV_LOG_ERROR,
1226+ "could not uncompress watermark logo\n");
1227+ av_free(buf);
1228+ return -1;
1229+ }
1230+ s->watermark_key = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), 0, buf, buf_len));
1231+
1232+ s->watermark_key = s->watermark_key << 16 | s->watermark_key;
1233+ av_log(avctx, AV_LOG_DEBUG,
1234+ "watermark key %#"PRIx32"\n", s->watermark_key);
1235+ av_free(buf);
1236+
1237+ return 0;
1238+#else
1239+ av_log(avctx, AV_LOG_ERROR,
1240+ "this svq3 file contains watermark which need zlib support compiled in\n");
1241+ return AVERROR(ENOSYS);
1242+#endif
1243+}
1244+
11171245 static av_cold int svq3_decode_init(AVCodecContext *avctx)
11181246 {
11191247 SVQ3Context *s = avctx->priv_data;
11201248 int m, x, y;
11211249 unsigned char *extradata;
1122− unsigned char *extradata_end;
1123− unsigned int size;
1124− int marker_found = 0;
11251250 int ret;
11261251
11271252 s->cur_pic = &s->frames[0];
@@ -1154,139 +1279,19 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) · 26 unmodified lines
11541279
11551280 /* prowl for the "SEQH" marker in the extradata */
11561281 extradata = (unsigned char *)avctx->extradata;
1157− extradata_end = avctx->extradata + avctx->extradata_size;
11581282 if (extradata) {
11591283 for (m = 0; m + 8 < avctx->extradata_size; m++) {
11601284 if (!memcmp(extradata, "SEQH", 4)) {
1161− marker_found = 1;
1285+ /* if a match was found, parse the extra data */
1286+ ret = svq3_decode_extradata(avctx, s, m);
1287+ if (ret < 0)
1288+ return ret;
11621289 break;
11631290 }
11641291 extradata++;
11651292 }
11661293 }
11671294
1168− /* if a match was found, parse the extra data */
1169− if (marker_found) {
1170− GetBitContext gb;
1171− int frame_size_code;
1172− int unk0, unk1, unk2, unk3, unk4;
1173− int w,h;
1174−
1175− size = AV_RB32(&extradata[4]);
1176− if (size > extradata_end - extradata - 8)
1177− return AVERROR_INVALIDDATA;
1178− init_get_bits(&gb, extradata + 8, size * 8);
1179−
1180− /* 'frame size code' and optional 'width, height' */
1181− frame_size_code = get_bits(&gb, 3);
1182− switch (frame_size_code) {
1183− case 0:
1184− w = 160;
1185− h = 120;
1186− break;
1187− case 1:
1188− w = 128;
1189− h = 96;
1190− break;
1191− case 2:
1192− w = 176;
1193− h = 144;
1194− break;
1195− case 3:
1196− w = 352;
1197− h = 288;
1198− break;
1199− case 4:
1200− w = 704;
1201− h = 576;
1202− break;
1203− case 5:
1204− w = 240;
1205− h = 180;
1206− break;
1207− case 6:
1208− w = 320;
1209− h = 240;
1210− break;
1211− case 7:
1212− w = get_bits(&gb, 12);
1213− h = get_bits(&gb, 12);
1214− break;
1215− }
1216− ret = ff_set_dimensions(avctx, w, h);
1217− if (ret < 0)
1218− return ret;
1219−
1220− s->halfpel_flag = get_bits1(&gb);
1221− s->thirdpel_flag = get_bits1(&gb);
1222−
1223− /* unknown fields */
1224− unk0 = get_bits1(&gb);
1225− unk1 = get_bits1(&gb);
1226− unk2 = get_bits1(&gb);
1227− unk3 = get_bits1(&gb);
1228−
1229− s->low_delay = get_bits1(&gb);
1230−
1231− /* unknown field */
1232− unk4 = get_bits1(&gb);
1233−
1234− av_log(avctx, AV_LOG_DEBUG, "Unknown fields %d %d %d %d %d\n",
1235− unk0, unk1, unk2, unk3, unk4);
1236−
1237− if (skip_1stop_8data_bits(&gb) < 0)
1238− return AVERROR_INVALIDDATA;
1239−
1240− s->has_watermark = get_bits1(&gb);
1241− avctx->has_b_frames = !s->low_delay;
1242− if (s->has_watermark) {
1243−#if CONFIG_ZLIB
1244− unsigned watermark_width = get_interleaved_ue_golomb(&gb);
1245− unsigned watermark_height = get_interleaved_ue_golomb(&gb);
1246− int u1 = get_interleaved_ue_golomb(&gb);
1247− int u2 = get_bits(&gb, 8);
1248− int u3 = get_bits(&gb, 2);
1249− int u4 = get_interleaved_ue_golomb(&gb);
1250− unsigned long buf_len = watermark_width *
1251− watermark_height * 4;
1252− int offset = get_bits_count(&gb) + 7 >> 3;
1253− uint8_t *buf;
1254−
1255− if (watermark_height <= 0 ||
1256− get_bits_left(&gb) <= 0 ||
1257− (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height)
1258− return AVERROR_INVALIDDATA;
1259−
1260− buf = av_malloc(buf_len);
1261− if (!buf)
1262− return AVERROR(ENOMEM);
1263−
1264− av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n",
1265− watermark_width, watermark_height);
1266− av_log(avctx, AV_LOG_DEBUG,
1267− "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
1268− u1, u2, u3, u4, offset);
1269− if (uncompress(buf, &buf_len, extradata + 8 + offset,
1270− size - offset) != Z_OK) {
1271− av_log(avctx, AV_LOG_ERROR,
1272− "could not uncompress watermark logo\n");
1273− av_free(buf);
1274− return -1;
1275− }
1276− s->watermark_key = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_CCITT), 0, buf, buf_len));
1277−
1278− s->watermark_key = s->watermark_key << 16 | s->watermark_key;
1279− av_log(avctx, AV_LOG_DEBUG,
1280− "watermark key %#"PRIx32"\n", s->watermark_key);
1281− av_free(buf);
1282−#else
1283− av_log(avctx, AV_LOG_ERROR,
1284− "this svq3 file contains watermark which need zlib support compiled in\n");
1285− return AVERROR(ENOSYS);
1286−#endif
1287− }
1288− }
1289−
12901295 s->mb_width = (avctx->width + 15) / 16;
12911296 s->mb_height = (avctx->height + 15) / 16;
12921297 s->mb_stride = s->mb_width + 1;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t