// Copyright 2013 Google Inc. All Rights Reserved. // // Use of this source code is governed by a BSD-style license // that can be found in the COPYING file in the root of the source // tree. An additional intellectual property rights grant can be found // in the file PATENTS. All contributing project authors may // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // // Utilities for processing transparent channel. // // Author: Skal (pascal.massimino@gmail.com)
#include <assert.h> #include"src/dsp/dsp.h"
// Tables can be faster on some platform but incur some extra binary size (~2k). #if !defined(USE_TABLES_FOR_ALPHA_MULT) #define USE_TABLES_FOR_ALPHA_MULT 0 // ALTERNATE_CODE #endif
void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows, int inverse) { int n; for (n = 0; n < num_rows; ++n) {
WebPMultARGBRow((uint32_t*)ptr, width, inverse);
ptr += stride;
}
}
void WebPMultRows(uint8_t* WEBP_RESTRICT ptr, int stride, const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, int width, int num_rows, int inverse) { int n; for (n = 0; n < num_rows; ++n) {
WebPMultRow(ptr, alpha, width, inverse);
ptr += stride;
alpha += alpha_stride;
}
}
// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.) // for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5), // one can use instead: (x * a * 65793 + (1 << 23)) >> 24 #if 1 // (int)(x * a / 255.) #define MULTIPLIER(a) ((a) * 32897U) #define PREMULTIPLY(x, m) (((x) * (m)) >> 23) #else// (int)(x * a / 255. + .5) #define MULTIPLIER(a) ((a) * 65793U) #define PREMULTIPLY(x, m) (((x) * (m) + (1U << 23)) >> 24) #endif
#if !WEBP_NEON_OMIT_C_CODE staticvoid ApplyAlphaMultiply_C(uint8_t* rgba, int alpha_first, int w, int h, int stride) { while (h-- > 0) {
uint8_t* const rgb = rgba + (alpha_first ? 1 : 0); const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3); int i; for (i = 0; i < w; ++i) { const uint32_t a = alpha[4 * i]; if (a != 0xff) { const uint32_t mult = MULTIPLIER(a);
rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
}
}
rgba += stride;
}
} #endif// !WEBP_NEON_OMIT_C_CODE #undef MULTIPLIER #undef PREMULTIPLY
static WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) { return (x * m) >> 16;
}
static WEBP_INLINE void ApplyAlphaMultiply4444_C(uint8_t* rgba4444, int w, int h, int stride, int rg_byte_pos /* 0 or 1 */) { while (h-- > 0) { int i; for (i = 0; i < w; ++i) { const uint32_t rg = rgba4444[2 * i + rg_byte_pos]; const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)]; const uint8_t a = ba & 0x0f; const uint32_t mult = MULTIPLIER(a); const uint8_t r = multiply(dither_hi(rg), mult); const uint8_t g = multiply(dither_lo(rg), mult); const uint8_t b = multiply(dither_hi(ba), mult);
rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
}
rgba4444 += stride;
}
} #undef MULTIPLIER
staticvoid ApplyAlphaMultiply_16b_C(uint8_t* rgba4444, int w, int h, int stride) { #if (WEBP_SWAP_16BIT_CSP == 1)
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 1); #else
ApplyAlphaMultiply4444_C(rgba4444, w, h, stride, 0); #endif
}
#if !WEBP_NEON_OMIT_C_CODE staticint DispatchAlpha_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, int width, int height,
uint8_t* WEBP_RESTRICT dst, int dst_stride) {
uint32_t alpha_mask = 0xff; int i, j;
for (j = 0; j < height; ++j) { for (i = 0; i < width; ++i) { const uint32_t alpha_value = alpha[i];
dst[4 * i] = alpha_value;
alpha_mask &= alpha_value;
}
alpha += alpha_stride;
dst += dst_stride;
}
return (alpha_mask != 0xff);
}
staticvoid DispatchAlphaToGreen_C(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, int width, int height,
uint32_t* WEBP_RESTRICT dst, int dst_stride) { int i, j; for (j = 0; j < height; ++j) { for (i = 0; i < width; ++i) {
dst[i] = alpha[i] << 8; // leave A/R/B channels zero'd.
}
alpha += alpha_stride;
dst += dst_stride;
}
}
staticint ExtractAlpha_C(const uint8_t* WEBP_RESTRICT argb, int argb_stride, int width, int height,
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
uint8_t alpha_mask = 0xff; int i, j;
int (*WebPHasAlpha8b)(const uint8_t* src, int length); int (*WebPHasAlpha32b)(const uint8_t* src, int length); void (*WebPAlphaReplace)(uint32_t* src, int length, uint32_t color);
//------------------------------------------------------------------------------ // Init function
// If defined, use CPUInfo() to overwrite some pointers with faster versions. if (VP8GetCPUInfo != NULL) { #ifdefined(WEBP_HAVE_SSE2) if (VP8GetCPUInfo(kSSE2)) {
WebPInitAlphaProcessingSSE2(); #ifdefined(WEBP_HAVE_SSE41) if (VP8GetCPUInfo(kSSE4_1)) {
WebPInitAlphaProcessingSSE41();
} #endif
} #endif #ifdefined(WEBP_USE_MIPS_DSP_R2) if (VP8GetCPUInfo(kMIPSdspR2)) {
WebPInitAlphaProcessingMIPSdspR2();
} #endif
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.