| 36 | } |
| 37 | |
| 38 | static VP8StatusCode ParseVP8X(const uint8_t** const data, size_t* const data_size, |
| 39 | int* const found_vp8x, int* const width_ptr, int* const height_ptr, |
| 40 | uint32_t* const flags_ptr) { |
| 41 | const uint32_t vp8x_size = CHUNK_HEADER_SIZE + VP8X_CHUNK_SIZE; |
| 42 | assert(data != nullptr); |
| 43 | assert(data_size != nullptr); |
| 44 | assert(found_vp8x != nullptr); |
| 45 | |
| 46 | *found_vp8x = 0; |
| 47 | |
| 48 | if (*data_size < CHUNK_HEADER_SIZE) { |
| 49 | return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. |
| 50 | } |
| 51 | |
| 52 | if (!memcmp(*data, "VP8X", TAG_SIZE)) { |
| 53 | int width, height; |
| 54 | uint32_t flags; |
| 55 | const uint32_t chunk_size = GetLE32(*data + TAG_SIZE); |
| 56 | if (chunk_size != VP8X_CHUNK_SIZE) { |
| 57 | return VP8_STATUS_BITSTREAM_ERROR; // Wrong chunk size. |
| 58 | } |
| 59 | |
| 60 | // Verify if enough data is available to validate the VP8X chunk. |
| 61 | if (*data_size < vp8x_size) { |
| 62 | return VP8_STATUS_NOT_ENOUGH_DATA; // Insufficient data. |
| 63 | } |
| 64 | flags = GetLE32(*data + 8); |
| 65 | width = 1 + GetLE24(*data + 12); |
| 66 | height = 1 + GetLE24(*data + 15); |
| 67 | if (width * (uint64_t)height >= MAX_IMAGE_AREA) { |
| 68 | return VP8_STATUS_BITSTREAM_ERROR; // image is too large |
| 69 | } |
| 70 | |
| 71 | if (flags_ptr != nullptr) *flags_ptr = flags; |
| 72 | if (width_ptr != nullptr) *width_ptr = width; |
| 73 | if (height_ptr != nullptr) *height_ptr = height; |
| 74 | // Skip over VP8X header bytes. |
| 75 | *data += vp8x_size; |
| 76 | *data_size -= vp8x_size; |
| 77 | *found_vp8x = 1; |
| 78 | } |
| 79 | return VP8_STATUS_OK; |
| 80 | } |
| 81 | |
| 82 | static VP8StatusCode ParseRIFF(const uint8_t** const data, size_t* const data_size, |
| 83 | int have_all_data, size_t* const riff_size) { |
no test coverage detected