| 240 | } |
| 241 | |
| 242 | int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size, int* const width, |
| 243 | int* const height) { |
| 244 | if (data == nullptr || data_size < VP8_FRAME_HEADER_SIZE) { |
| 245 | return 0; // not enough data |
| 246 | } |
| 247 | // check signature |
| 248 | if (!VP8CheckSignature(data + 3, data_size - 3)) { |
| 249 | return 0; // Wrong signature. |
| 250 | } else { |
| 251 | const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); |
| 252 | const int key_frame = !(bits & 1); |
| 253 | const int w = ((data[7] << 8) | data[6]) & 0x3fff; |
| 254 | const int h = ((data[9] << 8) | data[8]) & 0x3fff; |
| 255 | |
| 256 | if (!key_frame) { // Not a keyframe. |
| 257 | return 0; |
| 258 | } |
| 259 | |
| 260 | if (((bits >> 1) & 7) > 3) { |
| 261 | return 0; // unknown profile |
| 262 | } |
| 263 | if (!((bits >> 4) & 1)) { |
| 264 | return 0; // first frame is invisible! |
| 265 | } |
| 266 | if (((bits >> 5)) >= chunk_size) { // partition_length |
| 267 | return 0; // inconsistent size information. |
| 268 | } |
| 269 | if (w == 0 || h == 0) { |
| 270 | return 0; // We don't support both width and height to be zero. |
| 271 | } |
| 272 | |
| 273 | if (width) { |
| 274 | *width = w; |
| 275 | } |
| 276 | if (height) { |
| 277 | *height = h; |
| 278 | } |
| 279 | |
| 280 | return 1; |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start, size_t length) { |
| 285 | size_t i; |
no test coverage detected