diff --git a/avisynth_prs/draw_prs.cpp b/avisynth_prs/draw_prs.cpp index e4bb048fa..829288bc2 100644 --- a/avisynth_prs/draw_prs.cpp +++ b/avisynth_prs/draw_prs.cpp @@ -85,10 +85,16 @@ PVideoFrame __stdcall DrawPRS::GetFrame(int n, IScriptEnvironment* env) { frame.w = avsFrame->GetRowSize()/4; frame.h = avsFrame->GetHeight(); frame.pitch = avsFrame->GetPitch(); - frame.colorSpace = ColorSpace_RGB32; frame.flipColors = true; frame.flipVertical = true; + // Set colorspace + VideoInfo vi = child->GetVideoInfo(); + if (vi.IsYV12()) frame.colorSpace = ColorSpace_YV12; + else if (vi.IsYUY2()) frame.colorSpace = ColorSpace_YUY2; + else if (vi.IsRGB32()) frame.colorSpace = ColorSpace_RGB32; + else if (vi.IsRGB24()) frame.colorSpace = ColorSpace_RGB24; + // Draw into the frame file.DrawFrame(n,&frame); } diff --git a/prs/prs_specs.txt b/prs/prs_specs.txt index 450a1b588..385062580 100644 --- a/prs/prs_specs.txt +++ b/prs/prs_specs.txt @@ -119,16 +119,16 @@ Start and end frame numbers are both inclusive. 0x1B blend mode (8 bit unsigned) Alpha multiplier: -0x00 is "invisible",0xFF is "fully visible". This value is multiplied onto +0x00 is "invisible", 0xFF is "fully visible". This value is multiplied onto the alpha value of each pixel in the image to get the actual alpha value for -that pixel. +that pixel, that is: finalAlpha = pixelAlpha * globalAlpha / 255; Blend modes: - 0 none (dest*(1-alpha) + src*alpha) - 1 add (dest*(1-alpha) + (src+dest)*alpha) - 2 subtract (dest*(1-alpha) + (src-dest)*alpha) - 3 inverse subtract (dest*(1-alpha) + (dest-src)*alpha) - 4 multiply (dest*(1-alpha) + src*dest*alpha) + 0 none (src*alpha + dest*(1-alpha)) + 1 add (src*alpha + dest) + 2 subtract (dest - src*alpha); + 3 inverse subtract (src*alpha - dest) (is this it?) + 4 multiply (src*alpha * dst / 255) Values are clipped before they are multiplied with alpha. Layers: diff --git a/prs/prs_video_frame.cpp b/prs/prs_video_frame.cpp index ce0cf2f92..697bda676 100644 --- a/prs/prs_video_frame.cpp +++ b/prs/prs_video_frame.cpp @@ -77,6 +77,8 @@ PRSVideoFrame::~PRSVideoFrame () { /////////////////////////////////// // Overlay frame on top of another +// This function could get some optimization/assembly love +// Also, perhaps using "(x+1) >> 8" instead of "x / 255" should be considered. void PRSVideoFrame::Overlay(PRSVideoFrame *dstFrame,int x,int y,unsigned char alpha,unsigned char blend) { // TODO: Colorspace conversion, for now, the function assumes RGB32 on RGB32! @@ -155,6 +157,22 @@ void PRSVideoFrame::Overlay(PRSVideoFrame *dstFrame,int x,int y,unsigned char al *dst++ = MAX(0,(int(dc3) - sc3*a)/255); *dst++ = 255-(ia*(255-da)/255); // Is this correct? } + + // Inverse subtract blend + else if (blend == 3) { + *dst++ = MAX(0,(sc1*a - int(dc1))/255); + *dst++ = MAX(0,(sc2*a - int(dc2))/255); + *dst++ = MAX(0,(sc3*a - int(dc3))/255); + *dst++ = 255-(ia*(255-da)/255); // Is this correct? + } + + // Multiply blend + else if (blend == 4) { + *dst++ = MIN(255,(int(sc1)*a * int(dc1) / 255)/255); + *dst++ = MIN(255,(int(sc2)*a * int(dc2) / 255)/255); + *dst++ = MIN(255,(int(sc3)*a * int(dc3) / 255)/255); + *dst++ = 255-(ia*(255-da)/255); // Is this correct? + } } } }