- num_strips = BE_16 (&s->data[8]);
- encoded_buf_size = ((s->data[1] << 16) | BE_16 (&s->data[2]));
- if (encoded_buf_size != s->size)
- sega_film_data = 1;
- if (sega_film_data)
- s->data += 12;
- else
- s->data += 10;
-
- if (num_strips > MAX_STRIPS)
- num_strips = MAX_STRIPS;
+ num_strips = AV_RB16 (&s->data[8]);
+ encoded_buf_size = AV_RB24(&s->data[1]);
+
+ /* if this is the first frame, check for deviant Sega FILM data */
+ if (s->sega_film_skip_bytes == -1) {
+ if (!encoded_buf_size) {
+ av_log_ask_for_sample(s->avctx, "encoded_buf_size is 0");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
+ /* If the encoded frame size differs from the frame size as indicated
+ * by the container file, this data likely comes from a Sega FILM/CPK file.
+ * If the frame header is followed by the bytes FE 00 00 06 00 00 then
+ * this is probably one of the two known files that have 6 extra bytes
+ * after the frame header. Else, assume 2 extra bytes. The container
+ * size also cannot be a multiple of the encoded size. */
+ if (s->size >= 16 &&
+ (s->data[10] == 0xFE) &&
+ (s->data[11] == 0x00) &&
+ (s->data[12] == 0x00) &&
+ (s->data[13] == 0x06) &&
+ (s->data[14] == 0x00) &&
+ (s->data[15] == 0x00))
+ s->sega_film_skip_bytes = 6;
+ else
+ s->sega_film_skip_bytes = 2;
+ } else
+ s->sega_film_skip_bytes = 0;
+ }
+
+ s->data += 10 + s->sega_film_skip_bytes;
+
+ num_strips = FFMIN(num_strips, MAX_STRIPS);