VP8StatusCode WebPGetFeaturesInternal(byte* data, uint data_size, WebPBitstreamFeatures* features, int version) { VP8StatusCode status; if (version != WEBP_DECODER_ABI_VERSION) { return VP8_STATUS_INVALID_PARAM; // version mismatch } if (features == null) { return VP8_STATUS_INVALID_PARAM; } status = GetFeatures(data, data_size, features); if (status == VP8_STATUS_NOT_ENOUGH_DATA) { return VP8_STATUS_BITSTREAM_ERROR; // Not-enough-data treated as error. } return status; }
static void DefaultFeatures(WebPBitstreamFeatures* features) { assert(features); memset(features, 0, sizeof(*features)); features.bitstream_version = 0; }
static VP8StatusCode GetFeatures(byte* data, uint data_size, WebPBitstreamFeatures* features) { uint vp8_chunk_size = 0; uint riff_size = 0; uint flags = 0; uint vp8x_skip_size = 0; uint vp8_skip_size = 0; int* width = &features.width; int* height = &features.height; VP8StatusCode status; if (features == null || data == null) { return VP8_STATUS_INVALID_PARAM; } DefaultFeatures(features); // Skip over RIFF header. status = WebPParseRIFF(&data, &data_size, &riff_size); if (status != VP8_STATUS_OK) { return status; // Wrong RIFF header / insufficient data. } // Skip over VP8X. status = WebPParseVP8X(&data, &data_size, &vp8x_skip_size, width, height, &flags); if (status != VP8_STATUS_OK) { return status; // Wrong VP8X / insufficient data. } features.has_alpha = !!(flags & ALPHA_FLAG); if (vp8x_skip_size > 0) { return VP8_STATUS_OK; // Return features from VP8X header. } // Skip over VP8 header. status = WebPParseVP8Header(&data, &data_size, riff_size, &vp8_skip_size, &vp8_chunk_size); if (status != VP8_STATUS_OK) { return status; // Wrong VP8 chunk-header / insufficient data. } if (vp8_skip_size == 0) { vp8_chunk_size = data_size; // No VP8 chunk wrapper over raw VP8 data. } // Validates raw VP8 data. if (!VP8GetInfo(data, data_size, vp8_chunk_size, width, height)) { return VP8_STATUS_BITSTREAM_ERROR; } return VP8_STATUS_OK; // Return features from VP8 header. }
// Retrieve features from the bitstream. The *features structure is filled // with information gathered from the bitstream. // Returns false in case of error or version mismatch. // In case of error, features.bitstream_status will reflect the error code. static VP8StatusCode WebPGetFeatures(byte* data, uint data_size, ref WebPBitstreamFeatures features) { return WebPGetFeaturesInternal(data, data_size, features, WEBP_DECODER_ABI_VERSION); }