From 1db888ba40c18915b829bb5e108293cdd2f07e88 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Tue, 27 Mar 2012 12:24:56 +0000 Subject: [PATCH] take colorspace into account when cropping (cherry picked from commit 4e33653b52637c74ae30adde7990265d1d43994b) Conflicts: src/dec/vp8l.c --- src/dec/io.c | 14 ++++++++------ src/dec/webp.c | 11 +++++++---- src/dec/webpi.h | 10 +++++----- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/dec/io.c b/src/dec/io.c index 122cf1c6..2760a29d 100644 --- a/src/dec/io.c +++ b/src/dec/io.c @@ -468,12 +468,14 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) { static int CustomSetup(VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; - const int is_rgb = (p->output->colorspace < MODE_YUV); + const WEBP_CSP_MODE colorspace = p->output->colorspace; + const int is_rgb = (colorspace < MODE_YUV); + const int is_alpha = IsAlphaMode(colorspace); p->memory = NULL; p->emit = NULL; p->emit_alpha = NULL; - if (!WebPIoInitFromOptions(p->options, io)) { + if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) { return 0; } @@ -502,11 +504,11 @@ static int CustomSetup(VP8Io* io) { } else { p->emit = EmitYUV; } - if (IsAlphaMode(p->output->colorspace)) { - // We need transparency output + if (is_alpha) { // need transparency output p->emit_alpha = - is_rgb ? (p->output->colorspace == MODE_RGBA_4444 ? - EmitAlphaRGBA4444 : EmitAlphaRGB) : EmitAlphaYUV; + is_rgb ? (colorspace == MODE_RGBA_4444 ? EmitAlphaRGBA4444 + : EmitAlphaRGB) + : EmitAlphaYUV; } } diff --git a/src/dec/webp.c b/src/dec/webp.c index c8f9afa1..b995eb3f 100644 --- a/src/dec/webp.c +++ b/src/dec/webp.c @@ -613,7 +613,7 @@ VP8StatusCode WebPDecode(const uint8_t* data, uint32_t data_size, // Cropping and rescaling. int WebPIoInitFromOptions(const WebPDecoderOptions* const options, - VP8Io* const io) { + 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; @@ -623,9 +623,12 @@ int WebPIoInitFromOptions(const WebPDecoderOptions* const options, if (io->use_cropping) { w = options->crop_width; h = options->crop_height; - // TODO(skal): take colorspace into account. Don't assume YUV420. - x = options->crop_left & ~1; - y = options->crop_top & ~1; + x = options->crop_left; + y = options->crop_top; + if (src_colorspace >= MODE_YUV) { // only snap for YUV420 or YUV422 + x &= ~1; + y &= ~1; // TODO(later): only for YUV420, not YUV422. + } if (x < 0 || y < 0 || w <= 0 || h <= 0 || x + w > W || y + h > H) { return 0; // out of frame boundary error } diff --git a/src/dec/webpi.h b/src/dec/webpi.h index a40817b5..1c36abf3 100644 --- a/src/dec/webpi.h +++ b/src/dec/webpi.h @@ -121,6 +121,11 @@ VP8StatusCode WebPParseHeaders(const uint8_t** data, uint32_t* data_size, // hooks will use the supplied 'params' as io->opaque handle. void WebPInitCustomIo(WebPDecParams* const params, VP8Io* const io); +// Setup crop_xxx fields, mb_w and mb_h in io. 'src_colorspace' refers +// to the *compressed* format, not the output one. +int WebPIoInitFromOptions(const WebPDecoderOptions* const options, + VP8Io* const io, WEBP_CSP_MODE src_colorspace); + //------------------------------------------------------------------------------ // Internal functions regarding WebPDecBuffer memory (in buffer.c). // Don't really need to be externally visible for now. @@ -144,12 +149,7 @@ void WebPCopyDecBuffer(const WebPDecBuffer* const src, // Copy and transfer ownership from src to dst (beware of parameter order!) void WebPGrabDecBuffer(WebPDecBuffer* const src, WebPDecBuffer* const dst); -//------------------------------------------------------------------------------ -// Cropping and rescaling. -// Setup crop_xxx fields, mb_w and mb_h -int WebPIoInitFromOptions(const WebPDecoderOptions* const options, - VP8Io* const io); //------------------------------------------------------------------------------