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

Showing the changes to libavcodec (1 of 1 file). Show all

Unified · Split

libavcodec/svq3.c+132−127
@@ -1114,14 +1114,139 @@ static void init_dequant4_coeff_table(SVQ3Context *s) · 1113 unmodified lines
1114 }1114 }
1115}1115}
1116 1116
1117static 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
1117static av_cold int svq3_decode_init(AVCodecContext *avctx)1245static av_cold int svq3_decode_init(AVCodecContext *avctx)
1118{1246{
1119 SVQ3Context *s = avctx->priv_data;1247 SVQ3Context *s = avctx->priv_data;
1120 int m, x, y;1248 int m, x, y;
1121 unsigned char *extradata;1249 unsigned char *extradata;
1122 unsigned char *extradata_end;
1123 unsigned int size;
1124 int marker_found = 0;
1125 int ret;1250 int ret;
1126 1251
1127 s->cur_pic = &s->frames[0];1252 s->cur_pic = &s->frames[0];
@@ -1154,139 +1279,19 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) · 26 unmodified lines
1154 1279
1155 /* prowl for the "SEQH" marker in the extradata */1280 /* prowl for the "SEQH" marker in the extradata */
1156 extradata = (unsigned char *)avctx->extradata;1281 extradata = (unsigned char *)avctx->extradata;
1157 extradata_end = avctx->extradata + avctx->extradata_size;
1158 if (extradata) {1282 if (extradata) {
1159 for (m = 0; m + 8 < avctx->extradata_size; m++) {1283 for (m = 0; m + 8 < avctx->extradata_size; m++) {
1160 if (!memcmp(extradata, "SEQH", 4)) {1284 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;
1162 break;1289 break;
1163 }1290 }
1164 extradata++;1291 extradata++;
1165 }1292 }
1166 }1293 }
1167 1294
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
1290 s->mb_width = (avctx->width + 15) / 16;1295 s->mb_width = (avctx->width + 15) / 16;
1291 s->mb_height = (avctx->height + 15) / 16;1296 s->mb_height = (avctx->height + 15) / 16;
1292 s->mb_stride = s->mb_width + 1;1297 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