// Copyright 2017 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, NEON version. // // Author: Skal (pascal.massimino@gmail.com)
staticint DispatchAlpha_NEON(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 = 0xffu;
uint8x8_t mask8 = vdup_n_u8(0xff);
uint32_t tmp[2]; int i, j; for (j = 0; j < height; ++j) { // We don't know if alpha is first or last in dst[] (depending on rgbA/Argb // mode). So we must be sure dst[4*i + 8 - 1] is writable for the store. // Hence the test with 'width - 1' instead of just 'width'. for (i = 0; i + 8 <= width - 1; i += 8) {
uint8x8x4_t rgbX = vld4_u8((const uint8_t*)(dst + 4 * i)); const uint8x8_t alphas = vld1_u8(alpha + i);
rgbX.val[0] = alphas;
vst4_u8((uint8_t*)(dst + 4 * i), rgbX);
mask8 = vand_u8(mask8, alphas);
} for (; 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;
}
vst1_u8((uint8_t*)tmp, mask8);
alpha_mask *= 0x01010101;
alpha_mask &= tmp[0];
alpha_mask &= tmp[1]; return (alpha_mask != 0xffffffffu);
}
staticvoid DispatchAlphaToGreen_NEON(const uint8_t* WEBP_RESTRICT alpha, int alpha_stride, int width, int height,
uint32_t* WEBP_RESTRICT dst, int dst_stride) { int i, j;
uint8x8x4_t greens; // leave A/R/B channels zero'd.
greens.val[0] = vdup_n_u8(0);
greens.val[2] = vdup_n_u8(0);
greens.val[3] = vdup_n_u8(0); for (j = 0; j < height; ++j) { for (i = 0; i + 8 <= width; i += 8) {
greens.val[1] = vld1_u8(alpha + i);
vst4_u8((uint8_t*)(dst + i), greens);
} for (; i < width; ++i) dst[i] = alpha[i] << 8;
alpha += alpha_stride;
dst += dst_stride;
}
}
staticint ExtractAlpha_NEON(const uint8_t* WEBP_RESTRICT argb, int argb_stride, int width, int height,
uint8_t* WEBP_RESTRICT alpha, int alpha_stride) {
uint32_t alpha_mask = 0xffu;
uint8x8_t mask8 = vdup_n_u8(0xff);
uint32_t tmp[2]; int i, j; for (j = 0; j < height; ++j) { // We don't know if alpha is first or last in dst[] (depending on rgbA/Argb // mode). So we must be sure dst[4*i + 8 - 1] is writable for the store. // Hence the test with 'width - 1' instead of just 'width'. for (i = 0; i + 8 <= width - 1; i += 8) { const uint8x8x4_t rgbX = vld4_u8((const uint8_t*)(argb + 4 * i)); const uint8x8_t alphas = rgbX.val[0];
vst1_u8((uint8_t*)(alpha + i), alphas);
mask8 = vand_u8(mask8, alphas);
} for (; i < width; ++i) {
alpha[i] = argb[4 * i];
alpha_mask &= alpha[i];
}
argb += argb_stride;
alpha += alpha_stride;
}
vst1_u8((uint8_t*)tmp, mask8);
alpha_mask *= 0x01010101;
alpha_mask &= tmp[0];
alpha_mask &= tmp[1]; return (alpha_mask == 0xffffffffu);
}
staticvoid ExtractGreen_NEON(const uint32_t* WEBP_RESTRICT argb,
uint8_t* WEBP_RESTRICT alpha, int size) { int i; for (i = 0; i + 16 <= size; i += 16) { const uint8x16x4_t rgbX = vld4q_u8((const uint8_t*)(argb + i)); const uint8x16_t greens = rgbX.val[1];
vst1q_u8(alpha + i, greens);
} for (; i < size; ++i) alpha[i] = (argb[i] >> 8) & 0xff;
}
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.