in static-webp/src/main/jni/static-webp/webp.cpp [585:662]
void WebPFrame_nativeRenderFrame(
JNIEnv* pEnv,
jobject thiz,
jint width,
jint height,
jobject bitmap) {
auto spNativeContext = getWebPFrameNativeContext(pEnv, thiz);
if (!spNativeContext) {
throwIllegalStateException(pEnv, "Already disposed");
return;
}
AndroidBitmapInfo bitmapInfo;
if (AndroidBitmap_getInfo(pEnv, bitmap, &bitmapInfo) != ANDROID_BITMAP_RESULT_SUCCESS) {
throwIllegalStateException(pEnv, "Bad bitmap");
return;
}
if (width < 0 || height < 0) {
throwIllegalArgumentException(pEnv, "Width or height is negative !");
return;
}
if (bitmapInfo.width < (unsigned) width || bitmapInfo.height < (unsigned) height) {
throwIllegalStateException(pEnv, "Width or height is too small");
return;
}
if (bitmapInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
spNativeContext.reset();
throwIllegalStateException(pEnv, "Wrong color format");
return;
}
WebPDecoderConfig config;
int ret = WebPInitDecoderConfig(&config);
if (!ret) {
throwIllegalStateException(pEnv, "WebPInitDecoderConfig failed");
return;
}
const uint8_t* pPayload = spNativeContext->pPayload;
size_t payloadSize = spNativeContext->payloadSize;
ret = (WebPGetFeatures(pPayload , payloadSize, &config.input) == VP8_STATUS_OK);
if (!ret) {
spNativeContext.reset();
throwIllegalStateException(pEnv, "WebPGetFeatures failed");
return;
}
uint8_t* pixels;
if (AndroidBitmap_lockPixels(pEnv, bitmap, (void**) &pixels) != ANDROID_BITMAP_RESULT_SUCCESS) {
spNativeContext.reset();
throwIllegalStateException(pEnv, "Bad bitmap");
return;
}
config.options.no_fancy_upsampling = 1;
if (width != spNativeContext->width || height != spNativeContext->height) {
config.options.use_scaling = true;
config.options.scaled_width = width;
config.options.scaled_height = height;
}
config.output.colorspace = MODE_rgbA;
config.output.is_external_memory = 1;
config.output.u.RGBA.rgba = pixels;
config.output.u.RGBA.stride = bitmapInfo.stride;
config.output.u.RGBA.size = bitmapInfo.stride * bitmapInfo.height;
ret = WebPDecode(pPayload, payloadSize, &config);
AndroidBitmap_unlockPixels(pEnv, bitmap);
if (ret != VP8_STATUS_OK) {
spNativeContext.reset();
throwIllegalStateException(pEnv, "Failed to decode frame. VP8StatusCode: %d", ret);
}
}