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.
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 | static av_cold int svq3_decode_init(AVCodecContext *avctx) | 1245 | static 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; |