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.
Showing the changes to libavcodec (1 of 1 file). Show all
Unified · Split
| @@ -1114,14 +1114,139 @@ static void init_dequant4_coeff_table(SVQ3Context *s) · 1113 unmodified lines | ||
| 1114 | 1114 | } |
| 1115 | 1115 | } |
| 1116 | 1116 | |
| 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 | + | |
| 1117 | 1245 | static av_cold int svq3_decode_init(AVCodecContext *avctx) |
| 1118 | 1246 | { |
| 1119 | 1247 | SVQ3Context *s = avctx->priv_data; |
| 1120 | 1248 | int m, x, y; |
| 1121 | 1249 | unsigned char *extradata; |
| 1122 | − unsigned char *extradata_end; | |
| 1123 | − unsigned int size; | |
| 1124 | − int marker_found = 0; | |
| 1125 | 1250 | int ret; |
| 1126 | 1251 | |
| 1127 | 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 | 1280 | /* prowl for the "SEQH" marker in the extradata */ |
| 1156 | 1281 | extradata = (unsigned char *)avctx->extradata; |
| 1157 | − extradata_end = avctx->extradata + avctx->extradata_size; | |
| 1158 | 1282 | if (extradata) { |
| 1159 | 1283 | for (m = 0; m + 8 < avctx->extradata_size; m++) { |
| 1160 | 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 | 1289 | break; |
| 1163 | 1290 | } |
| 1164 | 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 | 1295 | s->mb_width = (avctx->width + 15) / 16; |
| 1291 | 1296 | s->mb_height = (avctx->height + 15) / 16; |
| 1292 | 1297 | s->mb_stride = s->mb_width + 1; |