static int ExportAlphaRGBA4444(WebPDecParams* const p, int y_pos, int max_lines_out) { const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride; #ifdef WEBP_SWAP_16BIT_CSP uint8_t* alpha_dst = base_rgba; #else uint8_t* alpha_dst = base_rgba + 1; #endif int num_lines_out = 0; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int width = p->scaler_a->dst_width; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t alpha_mask = 0x0f; while (WebPRescalerHasPendingOutput(p->scaler_a) && num_lines_out < max_lines_out) { int i; assert(y_pos + num_lines_out < p->output->height); WebPRescalerExportRow(p->scaler_a); for (i = 0; i < width; ++i) { // Fill in the alpha value (converted to 4 bits). const uint32_t alpha_value = p->scaler_a->dst[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } alpha_dst += buf->stride; ++num_lines_out; } if (is_premult_alpha && alpha_mask != 0x0f) { WebPApplyAlphaMultiply4444(base_rgba, width, num_lines_out, buf->stride); } return num_lines_out; }
static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p, int expected_num_lines_out) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; #ifdef WEBP_SWAP_16BIT_CSP uint8_t* alpha_dst = base_rgba; #else uint8_t* alpha_dst = base_rgba + 1; #endif uint32_t alpha_mask = 0x0f; int i, j; for (j = 0; j < num_rows; ++j) { for (i = 0; i < mb_w; ++i) { // Fill in the alpha value (converted to 4 bits). const uint32_t alpha_value = alpha[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } alpha += io->width; alpha_dst += buf->stride; } (void)expected_num_lines_out; assert(expected_num_lines_out == num_rows); if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride); } } return 0; }
static int ExportAlpha(WebPDecParams* const p, int y_pos, int max_lines_out) { const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* const base_rgba = buf->rgba + y_pos * buf->stride; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); uint8_t* dst = base_rgba + (alpha_first ? 0 : 3); int num_lines_out = 0; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t non_opaque = 0; const int width = p->scaler_a->dst_width; while (WebPRescalerHasPendingOutput(p->scaler_a) && num_lines_out < max_lines_out) { assert(y_pos + num_lines_out < p->output->height); WebPRescalerExportRow(p->scaler_a); non_opaque |= WebPDispatchAlpha(p->scaler_a->dst, 0, width, 1, dst, 0); dst += buf->stride; ++num_lines_out; } if (is_premult_alpha && non_opaque) { WebPApplyAlphaMultiply(base_rgba, alpha_first, width, num_lines_out, buf->stride); } return num_lines_out; }
static int ExportAlpha(WebPDecParams* const p, int y_pos) { const WebPRGBABuffer* const buf = &p->output->u.RGBA; uint8_t* const base_rgba = buf->rgba + (p->last_y + y_pos) * buf->stride; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); uint8_t* dst = base_rgba + (alpha_first ? 0 : 3); int num_lines_out = 0; const int is_premult_alpha = WebPIsPremultipliedMode(colorspace); uint32_t alpha_mask = 0xff; const int width = p->scaler_a.dst_width; while (WebPRescalerHasPendingOutput(&p->scaler_a)) { int i; assert(p->last_y + y_pos + num_lines_out < p->output->height); WebPRescalerExportRow(&p->scaler_a); for (i = 0; i < width; ++i) { const uint32_t alpha_value = p->scaler_a.dst[i]; dst[4 * i] = alpha_value; alpha_mask &= alpha_value; } dst += buf->stride; ++num_lines_out; } if (is_premult_alpha && alpha_mask != 0xff) { WebPApplyAlphaMultiply(base_rgba, alpha_first, width, num_lines_out, buf->stride); } return num_lines_out; }
static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p, int expected_num_lines_out) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; uint8_t* const dst = base_rgba + (alpha_first ? 0 : 3); const int has_alpha = WebPDispatchAlpha(alpha, io->width, mb_w, num_rows, dst, buf->stride); (void)expected_num_lines_out; assert(expected_num_lines_out == num_rows); // has_alpha is true if there's non-trivial alpha to premultiply with. if (has_alpha && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply(base_rgba, alpha_first, mb_w, num_rows, buf->stride); } } return 0; }
static int EmitAlphaRGB(const VP8Io* const io, WebPDecParams* const p) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int alpha_first = (colorspace == MODE_ARGB || colorspace == MODE_Argb); const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; uint8_t* dst = base_rgba + (alpha_first ? 0 : 3); uint32_t alpha_mask = 0xff; int i, j; for (j = 0; j < num_rows; ++j) { for (i = 0; i < mb_w; ++i) { const uint32_t alpha_value = alpha[i]; dst[4 * i] = alpha_value; alpha_mask &= alpha_value; } alpha += io->width; dst += buf->stride; } // alpha_mask is < 0xff if there's non-trivial alpha to premultiply with. if (alpha_mask != 0xff && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply(base_rgba, alpha_first, mb_w, num_rows, buf->stride); } } return 0; }
static int EmitAlphaRGBA4444(const VP8Io* const io, WebPDecParams* const p) { const uint8_t* alpha = io->a; if (alpha != NULL) { const int mb_w = io->mb_w; const WEBP_CSP_MODE colorspace = p->output->colorspace; const WebPRGBABuffer* const buf = &p->output->u.RGBA; int num_rows; const int start_y = GetAlphaSourceRow(io, &alpha, &num_rows); uint8_t* const base_rgba = buf->rgba + start_y * buf->stride; uint8_t* alpha_dst = base_rgba + 1; uint32_t alpha_mask = 0x0f; int i, j; for (j = 0; j < num_rows; ++j) { for (i = 0; i < mb_w; ++i) { const uint32_t alpha_value = alpha[i] >> 4; alpha_dst[2 * i] = (alpha_dst[2 * i] & 0xf0) | alpha_value; alpha_mask &= alpha_value; } alpha += io->width; alpha_dst += buf->stride; } if (alpha_mask != 0x0f && WebPIsPremultipliedMode(colorspace)) { WebPApplyAlphaMultiply4444(base_rgba, mb_w, num_rows, buf->stride); } } return 0; }
static int CustomSetup(VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int is_rgb = WebPIsRGBMode(colorspace); const int is_alpha = WebPIsAlphaMode(colorspace); p->memory = NULL; p->emit = NULL; p->emit_alpha = NULL; p->emit_alpha_row = NULL; if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) { return 0; } if (is_alpha && WebPIsPremultipliedMode(colorspace)) { WebPInitUpsamplers(); } if (io->use_scaling) { #if !defined(WEBP_REDUCE_SIZE) const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p); if (!ok) { return 0; // memory error } #else return 0; // rescaling support not compiled #endif } else { if (is_rgb) { WebPInitSamplers(); p->emit = EmitSampledRGB; // default if (io->fancy_upsampling) { #ifdef FANCY_UPSAMPLING const int uv_width = (io->mb_w + 1) >> 1; p->memory = WebPSafeMalloc(1ULL, (size_t)(io->mb_w + 2 * uv_width)); if (p->memory == NULL) { return 0; // memory error. } p->tmp_y = (uint8_t*)p->memory; p->tmp_u = p->tmp_y + io->mb_w; p->tmp_v = p->tmp_u + uv_width; p->emit = EmitFancyRGB; WebPInitUpsamplers(); #endif } } else { p->emit = EmitYUV; } if (is_alpha) { // need transparency output p->emit_alpha = (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ? EmitAlphaRGBA4444 : is_rgb ? EmitAlphaRGB : EmitAlphaYUV; if (is_rgb) { WebPInitAlphaProcessing(); } } }
static int CustomSetup(VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int is_rgb = WebPIsRGBMode(colorspace); const int is_alpha = WebPIsAlphaMode(colorspace); p->memory = NULL; p->emit = NULL; p->emit_alpha = NULL; p->emit_alpha_row = NULL; if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) { return 0; } if (io->use_scaling) { const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p); if (!ok) { return 0; } } else { if (is_rgb) { p->emit = EmitSampledRGB; #ifdef FANCY_UPSAMPLING if (io->fancy_upsampling) { const int uv_width = (io->mb_w + 1) >> 1; p->memory = malloc(io->mb_w + 2 * uv_width); if (p->memory == NULL) { return 0; } p->tmp_y = (uint8_t*)p->memory; p->tmp_u = p->tmp_y + io->mb_w; p->tmp_v = p->tmp_u + uv_width; p->emit = EmitFancyRGB; WebPInitUpsamplers(); } #endif } else { p->emit = EmitYUV; } if (is_alpha) { if (WebPIsPremultipliedMode(colorspace)) WebPInitPremultiply(); p->emit_alpha = (colorspace == MODE_RGBA_4444 || colorspace == MODE_rgbA_4444) ? EmitAlphaRGBA4444 : is_rgb ? EmitAlphaRGB : EmitAlphaYUV; } }
static int CustomSetup(VP8Io* io) { WebPDecParams* const p = (WebPDecParams*)io->opaque; const WEBP_CSP_MODE colorspace = p->output->colorspace; const int is_rgb = WebPIsRGBMode(colorspace); const int is_alpha = WebPIsAlphaMode(colorspace); p->memory = NULL; p->emit = NULL; p->emit_alpha = NULL; p->emit_alpha_row = NULL; if (!WebPIoInitFromOptions(p->options, io, is_alpha ? MODE_YUV : MODE_YUVA)) { return 0; } if (is_alpha && WebPIsPremultipliedMode(colorspace)) { WebPInitUpsamplers(); } if (io->use_scaling) { const int ok = is_rgb ? InitRGBRescaler(io, p) : InitYUVRescaler(io, p); if (!ok) { return 0; // memory error } } else { if (is_rgb) { p->emit = EmitSampledRGB; // default if (io->fancy_upsampling) { #ifdef FANCY_UPSAMPLING const int uv_width = (io->mb_w + 1) >> 1; p->memory = WebPSafeMalloc(1ULL, (size_t)(io->mb_w + 2 * uv_width)); if (p->memory == NULL) { return 0; // memory error. } p->tmp_y = (uint8_t*)p->memory; p->tmp_u = p->tmp_y + io->mb_w; p->tmp_v = p->tmp_u + uv_width; p->emit = EmitFancyRGB; WebPInitUpsamplers(); #endif } else { WebPInitSamplers(); } } else {