| 377 | } |
| 378 | |
| 379 | static VP8StatusCode ParseHeadersInternal(const uint8_t* data, size_t data_size, int* const width, |
| 380 | int* const height, int* const has_alpha, |
| 381 | int* const has_animation, int* const format, |
| 382 | WebPHeaderStructure* const headers) { |
| 383 | int canvas_width = 0; |
| 384 | int canvas_height = 0; |
| 385 | int image_width = 0; |
| 386 | int image_height = 0; |
| 387 | int found_riff = 0; |
| 388 | int found_vp8x = 0; |
| 389 | int animation_present = 0; |
| 390 | const int have_all_data = (headers != nullptr) ? headers->have_all_data : 0; |
| 391 | |
| 392 | VP8StatusCode status; |
| 393 | WebPHeaderStructure hdrs; |
| 394 | |
| 395 | if (data == nullptr || data_size < RIFF_HEADER_SIZE) { |
| 396 | return VP8_STATUS_NOT_ENOUGH_DATA; |
| 397 | } |
| 398 | memset(&hdrs, 0, sizeof(hdrs)); |
| 399 | hdrs.data = data; |
| 400 | hdrs.data_size = data_size; |
| 401 | |
| 402 | // Skip over RIFF header. |
| 403 | status = ParseRIFF(&data, &data_size, have_all_data, &hdrs.riff_size); |
| 404 | if (status != VP8_STATUS_OK) { |
| 405 | return status; // Wrong RIFF header / insufficient data. |
| 406 | } |
| 407 | found_riff = (hdrs.riff_size > 0); |
| 408 | |
| 409 | // Skip over VP8X. |
| 410 | { |
| 411 | uint32_t flags = 0; |
| 412 | status = ParseVP8X(&data, &data_size, &found_vp8x, &canvas_width, &canvas_height, &flags); |
| 413 | if (status != VP8_STATUS_OK) { |
| 414 | return status; // Wrong VP8X / insufficient data. |
| 415 | } |
| 416 | animation_present = !!(flags & ANIMATION_FLAG); |
| 417 | if (!found_riff && found_vp8x) { |
| 418 | // Note: This restriction may be removed in the future, if it becomes |
| 419 | // necessary to send VP8X chunk to the decoder. |
| 420 | return VP8_STATUS_BITSTREAM_ERROR; |
| 421 | } |
| 422 | if (has_alpha != nullptr) *has_alpha = !!(flags & ALPHA_FLAG); |
| 423 | if (has_animation != nullptr) *has_animation = animation_present; |
| 424 | if (format != nullptr) *format = 0; // default = undefined |
| 425 | |
| 426 | image_width = canvas_width; |
| 427 | image_height = canvas_height; |
| 428 | if (found_vp8x && animation_present && headers == nullptr) { |
| 429 | status = VP8_STATUS_OK; |
| 430 | goto ReturnWidthHeight; // Just return features from VP8X header. |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | if (data_size < TAG_SIZE) { |
| 435 | status = VP8_STATUS_NOT_ENOUGH_DATA; |
| 436 | goto ReturnWidthHeight; |
no test coverage detected