#define UNPREMULTIPLY_ALPHA(x, y) ((((x) << 16) - ((x) << 9) + (x)) / ((((x) + (y)) << 8) - ((x) + (y)) - (y) * (x)))
#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
int RtmpPublisher_putVideoData(RtmpPublisher* rp, uint8_t* data, int dataSize) {
//blend RGBA
if (rp->watermarkEnable)
{
if( rp->overlayX > rp->dst_width || rp->overlayY > rp->dst_height ||
rp->mPngRGBA->width > rp->dst_width || rp->mPngRGBA->height > rp->dst_height)
{
}else{
//this mirror
int startline = rp->dst_width * rp->overlayY * 4;
int startinline = rp->overlayX * 4;
int overlayWidth = rp->mPngRGBA->width < rp->dst_width ? rp->mPngRGBA->width : rp->dst_width;
int overlaystartline = 0;
int i = 0;
int j = 0;
for (j = 0; j < rp->mPngRGBA->height; j++) {
for (i = 0; i < overlayWidth * 4; i += 4) {
// R = R1 * a + R2 * (1-a);
int alpha = UNPREMULTIPLY_ALPHA(rp->mPngRGBA->pixels[overlaystartline + i + 3], *(data + startline + startinline + i + 3));
int oneminusalpha = 255 - alpha;
*(data + startline + startinline + i + 0) = FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 0] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 0))) );
*(data + startline + startinline + i + 1) = FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 1] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 1))) );
*(data + startline + startinline + i + 2) =FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 2] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 2))) );
}
startline += rp->dst_width * 4;
overlaystartline += rp->mPngRGBA->width * 4;
}
}
//rp->mPngRGBA->pixels, rp->mPngRGBA->width, rp->mPngRGBA->height;
}
}
//--------------------------
if (rp->mirrorEnable != rp->logomirrorEnable) {
rp->logomirrorEnable = rp->mirrorEnable;
int k = 0;
int line = 0;
for (line = 0; line < rp->mPngRGBA->height * rp->mPngRGBA->width * 4; ) {
int last = rp->mPngRGBA->width * 4 - 4 ;
for (k = 0; k< last; k += 4, last -= 4) {
unsigned char r = rp->mPngRGBA->pixels[line + last + 0];
unsigned char g = rp->mPngRGBA->pixels[line + last + 1];
unsigned char b = rp->mPngRGBA->pixels[line + last + 2];
unsigned char a = rp->mPngRGBA->pixels[line + last + 3];
unsigned char r1 = rp->mPngRGBA->pixels[line + k + 0];
unsigned char g1 = rp->mPngRGBA->pixels[line + k + 1];
unsigned char b1 = rp->mPngRGBA->pixels[line + k + 2];
unsigned char a1 = rp->mPngRGBA->pixels[line + k + 3];
rp->mPngRGBA->pixels[line + last + 0] = r1;
rp->mPngRGBA->pixels[line + last + 1] = g1;
rp->mPngRGBA->pixels[line + last + 2] = b1;
rp->mPngRGBA->pixels[line + last + 3] = a1;
rp->mPngRGBA->pixels[line + k + 0] = r;
rp->mPngRGBA->pixels[line + k + 1] = g;
rp->mPngRGBA->pixels[line + k + 2] = b;
rp->mPngRGBA->pixels[line + k + 3] = a;
}
line += rp->mPngRGBA->width * 4;
}
}
#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
int RtmpPublisher_putVideoData(RtmpPublisher* rp, uint8_t* data, int dataSize) {
//blend RGBA
if (rp->watermarkEnable)
{
if( rp->overlayX > rp->dst_width || rp->overlayY > rp->dst_height ||
rp->mPngRGBA->width > rp->dst_width || rp->mPngRGBA->height > rp->dst_height)
{
}else{
//this mirror
int startline = rp->dst_width * rp->overlayY * 4;
int startinline = rp->overlayX * 4;
int overlayWidth = rp->mPngRGBA->width < rp->dst_width ? rp->mPngRGBA->width : rp->dst_width;
int overlaystartline = 0;
int i = 0;
int j = 0;
for (j = 0; j < rp->mPngRGBA->height; j++) {
for (i = 0; i < overlayWidth * 4; i += 4) {
// R = R1 * a + R2 * (1-a);
int alpha = UNPREMULTIPLY_ALPHA(rp->mPngRGBA->pixels[overlaystartline + i + 3], *(data + startline + startinline + i + 3));
int oneminusalpha = 255 - alpha;
*(data + startline + startinline + i + 0) = FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 0] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 0))) );
*(data + startline + startinline + i + 1) = FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 1] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 1))) );
*(data + startline + startinline + i + 2) =FAST_DIV255( ((rp->mPngRGBA->pixels[overlaystartline + i + 2] * alpha) + (oneminusalpha * *(data + startline + startinline + i + 2))) );
}
startline += rp->dst_width * 4;
overlaystartline += rp->mPngRGBA->width * 4;
}
}
//rp->mPngRGBA->pixels, rp->mPngRGBA->width, rp->mPngRGBA->height;
}
}
//--------------------------
if (rp->mirrorEnable != rp->logomirrorEnable) {
rp->logomirrorEnable = rp->mirrorEnable;
int k = 0;
int line = 0;
for (line = 0; line < rp->mPngRGBA->height * rp->mPngRGBA->width * 4; ) {
int last = rp->mPngRGBA->width * 4 - 4 ;
for (k = 0; k< last; k += 4, last -= 4) {
unsigned char r = rp->mPngRGBA->pixels[line + last + 0];
unsigned char g = rp->mPngRGBA->pixels[line + last + 1];
unsigned char b = rp->mPngRGBA->pixels[line + last + 2];
unsigned char a = rp->mPngRGBA->pixels[line + last + 3];
unsigned char r1 = rp->mPngRGBA->pixels[line + k + 0];
unsigned char g1 = rp->mPngRGBA->pixels[line + k + 1];
unsigned char b1 = rp->mPngRGBA->pixels[line + k + 2];
unsigned char a1 = rp->mPngRGBA->pixels[line + k + 3];
rp->mPngRGBA->pixels[line + last + 0] = r1;
rp->mPngRGBA->pixels[line + last + 1] = g1;
rp->mPngRGBA->pixels[line + last + 2] = b1;
rp->mPngRGBA->pixels[line + last + 3] = a1;
rp->mPngRGBA->pixels[line + k + 0] = r;
rp->mPngRGBA->pixels[line + k + 1] = g;
rp->mPngRGBA->pixels[line + k + 2] = b;
rp->mPngRGBA->pixels[line + k + 3] = a;
}
line += rp->mPngRGBA->width * 4;
}
}