mirror of
https://chromium.googlesource.com/libyuv/libyuv
synced 2025-12-06 16:56:55 +08:00
ARGBAttenuate and ARGBUnattenuate for converting to/from attentuated ARGB
BUG=none TEST=none Review URL: https://webrtc-codereview.appspot.com/490008 git-svn-id: http://libyuv.googlecode.com/svn/trunk@240 16f28f9a-4ce2-e073-06de-1de4eb20be90
This commit is contained in:
parent
96af870c8a
commit
829e7ea402
@ -1,6 +1,6 @@
|
|||||||
Name: libyuv
|
Name: libyuv
|
||||||
URL: http://code.google.com/p/libyuv/
|
URL: http://code.google.com/p/libyuv/
|
||||||
Version: 239
|
Version: 240
|
||||||
License: BSD
|
License: BSD
|
||||||
License File: LICENSE
|
License File: LICENSE
|
||||||
|
|
||||||
|
|||||||
@ -160,6 +160,16 @@ int I422ToUYVY(const uint8* src_y, int src_stride_y,
|
|||||||
uint8* dst_frame, int dst_stride_frame,
|
uint8* dst_frame, int dst_stride_frame,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
|
|
||||||
|
// Convert unattentuated ARGB values to preattenuated ARGB.
|
||||||
|
int ARGBAttenuate(const uint8* src_argb, int src_stride_argb,
|
||||||
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
|
// Convert preattentuated ARGB values to unattenuated ARGB.
|
||||||
|
int ARGBUnattenuate(const uint8* src_argb, int src_stride_argb,
|
||||||
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
|
int width, int height);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // namespace libyuv
|
} // namespace libyuv
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
#ifndef INCLUDE_LIBYUV_VERSION_H_
|
||||||
#define INCLUDE_LIBYUV_VERSION_H_
|
#define INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
#define LIBYUV_VERSION 239
|
#define LIBYUV_VERSION 240
|
||||||
|
|
||||||
#endif // INCLUDE_LIBYUV_VERSION_H_
|
#endif // INCLUDE_LIBYUV_VERSION_H_
|
||||||
|
|
||||||
|
|||||||
@ -863,6 +863,105 @@ int ARGBRect(uint8* dst_argb, int dst_stride_argb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Multiply source RGB by alpha and store to destination.
|
||||||
|
static void ARGBAttenuateRow_C(const uint8* src_argb, uint8* dst_argb,
|
||||||
|
int width) {
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
const uint32 b = src_argb[0];
|
||||||
|
const uint32 g = src_argb[1];
|
||||||
|
const uint32 r = src_argb[2];
|
||||||
|
const uint32 a = src_argb[3];
|
||||||
|
dst_argb[0] = (b * a + 128) / 255;
|
||||||
|
dst_argb[1] = (g * a + 128) / 255;
|
||||||
|
dst_argb[2] = (r * a + 128) / 255;
|
||||||
|
dst_argb[3] = a;
|
||||||
|
src_argb += 4;
|
||||||
|
dst_argb += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert unattentuated ARGB values to preattenuated ARGB by multiplying RGB by
|
||||||
|
// by alpha.
|
||||||
|
// An unattenutated ARGB alpha blend uses the formula
|
||||||
|
// p = a * f + (1 - a) * b
|
||||||
|
// where
|
||||||
|
// p is output pixel
|
||||||
|
// f is foreground pixel
|
||||||
|
// b is background pixel
|
||||||
|
// a is alpha value from foreground pixel
|
||||||
|
// An preattenutated ARGB alpha blend uses the formula
|
||||||
|
// p = f + (1 - a) * b
|
||||||
|
// where
|
||||||
|
// f is foreground pixel premultiplied by alpha
|
||||||
|
|
||||||
|
int ARGBAttenuate(const uint8* src_argb, int src_stride_argb,
|
||||||
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
|
int width, int height) {
|
||||||
|
if (height < 0) {
|
||||||
|
height = -height;
|
||||||
|
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||||
|
src_stride_argb = -src_stride_argb;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
ARGBAttenuateRow_C(src_argb, dst_argb, width);
|
||||||
|
src_argb += src_stride_argb;
|
||||||
|
dst_argb += dst_stride_argb;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Divide source RGB by alpha and store to destination.
|
||||||
|
static void ARGBUnattenuateRow_C(const uint8* src_argb, uint8* dst_argb,
|
||||||
|
int width) {
|
||||||
|
for (int i = 0; i < width; ++i) {
|
||||||
|
uint32 b = src_argb[0];
|
||||||
|
uint32 g = src_argb[1];
|
||||||
|
uint32 r = src_argb[2];
|
||||||
|
const uint32 a = src_argb[3];
|
||||||
|
if (a) {
|
||||||
|
b = (b * 255 + 127) / a;
|
||||||
|
if (b > 255) {
|
||||||
|
b = 255;
|
||||||
|
}
|
||||||
|
g = (g * 255 + 127) / a;
|
||||||
|
if (g > 255) {
|
||||||
|
g = 255;
|
||||||
|
}
|
||||||
|
r = (r * 255 + 127) / a;
|
||||||
|
if (r > 255) {
|
||||||
|
r = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst_argb[0] = b;
|
||||||
|
dst_argb[1] = g;
|
||||||
|
dst_argb[2] = r;
|
||||||
|
dst_argb[3] = a;
|
||||||
|
src_argb += 4;
|
||||||
|
dst_argb += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert unattentuated ARGB values to preattenuated ARGB by multiplying RGB by
|
||||||
|
// by alpha.
|
||||||
|
int ARGBUnattenuate(const uint8* src_argb, int src_stride_argb,
|
||||||
|
uint8* dst_argb, int dst_stride_argb,
|
||||||
|
int width, int height) {
|
||||||
|
if (height < 0) {
|
||||||
|
height = -height;
|
||||||
|
src_argb = src_argb + (height - 1) * src_stride_argb;
|
||||||
|
src_stride_argb = -src_stride_argb;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < height; ++y) {
|
||||||
|
ARGBUnattenuateRow_C(src_argb, dst_argb, width);
|
||||||
|
src_argb += src_stride_argb;
|
||||||
|
dst_argb += dst_stride_argb;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
} // namespace libyuv
|
} // namespace libyuv
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user