int WebPIoInitFromOptions(const WebPDecoderOptions* const options, VP8Io* const io, WEBP_CSP_MODE src_colorspace) { const int W = io->width; const int H = io->height; int x = 0, y = 0, w = W, h = H; // Cropping io->use_cropping = (options != NULL) && (options->use_cropping > 0); if (io->use_cropping) { w = options->crop_width; h = options->crop_height; x = options->crop_left; y = options->crop_top; if (!WebPIsRGBMode(src_colorspace)) { // only snap for YUV420 x &= ~1; y &= ~1; } if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) { return 0; // out of frame boundary error } } io->crop_left = x; io->crop_top = y; io->crop_right = x + w; io->crop_bottom = y + h; io->mb_w = w; io->mb_h = h; // Scaling io->use_scaling = (options != NULL) && (options->use_scaling > 0); if (io->use_scaling) { int scaled_width = options->scaled_width; int scaled_height = options->scaled_height; if (!WebPRescalerGetScaledDimensions(w, h, &scaled_width, &scaled_height)) { return 0; } io->scaled_width = scaled_width; io->scaled_height = scaled_height; } // Filter io->bypass_filtering = options && options->bypass_filtering; // Fancy upsampler #ifdef FANCY_UPSAMPLING io->fancy_upsampling = (options == NULL) || (!options->no_fancy_upsampling); #endif if (io->use_scaling) { // disable filter (only for large downscaling ratio). io->bypass_filtering = (io->scaled_width < W * 3 / 4) && (io->scaled_height < H * 3 / 4); io->fancy_upsampling = 0; } return 1; }
VP8StatusCode WebPAllocateDecBuffer(int w, int h, const WebPDecoderOptions* const options, WebPDecBuffer* const out) { VP8StatusCode status; if (out == NULL || w <= 0 || h <= 0) { return VP8_STATUS_INVALID_PARAM; } if (options != NULL) { // First, apply options if there is any. if (options->use_cropping) { const int cw = options->crop_width; const int ch = options->crop_height; const int x = options->crop_left & ~1; const int y = options->crop_top & ~1; if (x < 0 || y < 0 || cw <= 0 || ch <= 0 || x + cw > w || y + ch > h) { return VP8_STATUS_INVALID_PARAM; // out of frame boundary. } w = cw; h = ch; } if (options->use_scaling) { int scaled_width = options->scaled_width; int scaled_height = options->scaled_height; if (!WebPRescalerGetScaledDimensions( w, h, &scaled_width, &scaled_height)) { return VP8_STATUS_INVALID_PARAM; } w = scaled_width; h = scaled_height; } } out->width = w; out->height = h; // Then, allocate buffer for real. status = AllocateBuffer(out); if (status != VP8_STATUS_OK) return status; // Use the stride trick if vertical flip is needed. if (options != NULL && options->flip) { status = WebPFlipBuffer(out); } return status; }