Code: Select all
REM Extract the chroma content from the source image by applying both
REM horizontal and vertical filters. The horizontal filter is a simple
REM bandpass centered on colour subcarrier (4.433 MHz) and the vertical
REM filters are bandpass with peaks at 72, 216 and 360 c/aph.
REM The 72 c/aph component is multiplied by the 216 plus 360 c/aph
REM components to generate a 288 c/aph component (with zero horizontal
REM frequency) for use in measuring the vertical component of geometric
REM distortion (the 360 c/aph is necessary for drwep3.y and drw20200.y)
REM Finally the U and V chroma are separated using a diagonal filter.
DEF PROCchroma
PROCbpfilt(Raw%, Tsc%, SourceWidth%*SourceHeight%)
PROCvfilt48(^coeff.cvbpf%(0), Tsc%-23*SourceWidth%, \
\ SourceWidth%*SourceHeight%, Csc%) : REM 72+216 c/aph
IF ChromaGain <> 0 THEN
PROCvfilt48(^coeff.cv72f%(0), Tsc%-23*SourceWidth%, \
\ SourceWidth%*SourceHeight%, C72%) : REM 72 c/aph
PROCvfilt48(^coeff.cv216%(0), Tsc%-23*SourceWidth%, \
\ SourceWidth%*SourceHeight%, C216%) : REM 216 c/aph
PROCvfilt48(^coeff.cv360%(0), Tsc%-23*SourceWidth%, \
\ SourceWidth%*SourceHeight%, C360%) : REM 360 c/aph
ENDIF
REM To protect the x-measurement from cross-colour we must ensure
REM that the 72 c/aph and 216 c/aph components are pre-separated
REM into U and V before being multiplied, otherwise 72 c/aph luma
REM could mix with its 3rd harmonic to produce 144 c/aph 'chroma'.
PROCproduct(C216%, C360%, C72%, C288%) : REM 216 & 360 summed
PROCseparate(C72%, Uuf%, Vuf%) : REM Uuf%, Vuf% temp 72
IF Xmode% = 216 THEN
PROCseparate(C216%, U144%, V144%) : REM U144%, V144% temp 216
PROCproduct(Uuf%, Uuf%, U144%, U144%) : REM Twice 72 * 216
PROCproduct(Vuf%, Vuf%, V144%, V144%) : REM Twice 72 * 216
ELSE
PROCproduct(Uuf%, Uuf%, Uuf%, U144%) : REM Twice 72 * 72
PROCproduct(Vuf%, Vuf%, Vuf%, V144%) : REM Twice 72 * 72
ENDIF
PROCseparate(Csc%, Uuf%, Vuf%)
ENDPROC
;-------------------------------------------------------------------------
REM Make U and V baseband chrominance (unfiltered) by rectifying the
REM separated modulated U and V chroma and using quadrant map for sign.
REM The post-demodulation low-pass filter happens in the down-scaling.
DEF PROCdouv
LOCAL line%
REM Generate chrominance:
FOR line% = 0 TO SourceHeight%-1
PROCmakeuv(Uuf% + line%*SourceWidth%, \
\ Vuf% + line%*SourceWidth%, \
\ ^MapOut&(line% DIV YblockSize%,0))
NEXT line%
ENDPROC
;-------------------------------------------------------------------------
REM Downscale the luminance and baseband chrominance from (typically)
REM 1920x1080 to 720x576 using polyphase FIR filters (8 phases vertical
REM and 3 phases horizontal). The luminance filters preserve the full
REM PAL bandwidth, but the chrominance filters deliberately remove the
REM high frequencies, both as a post-demodulation filter and as the
REM 'reconstruction filter' for the low (120 x 90) block resolution.
DEF PROCscale
LOCAL I%, F%, L%, P%, pp
REM Vertical scaling:
pp = 0
FOR L% = 0 TO OutputHeight%-1
I% = INT(pp)
F% = 8*(pp-I%)
PROCvfilter(^coeff.yvlpf%(7-F%,0), Lum%+(I%-15)*SourceWidth%, \
\ SourceWidth%, Ytmp%+L%*SourceWidth%)
IF ChromaGain <> 0 THEN
PROCvfilter(^coeff.cvlpf%(7-F%,0), Uuf%+(I%-15)*SourceWidth%, \
\ SourceWidth%, Utmp%+L%*SourceWidth%)
PROCvfilter(^coeff.cvlpf%(7-F%,0), Vuf%+(I%-15)*SourceWidth%, \
\ SourceWidth%, Vtmp%+L%*SourceWidth%)
ENDIF
pp += SourceHeight%/OutputHeight%
NEXT L%
REM Horizontal scaling:
pp = 0
FOR P% = 0 TO OutputWidth%-1
I% = INT(pp)
F% = 3*(pp-I%)
PROChfilter(^coeff.yhlpf%(2-F%,0), Ytmp%+I%-15, SourceWidth%, Yout%+P%)
IF ChromaGain <> 0 THEN
PROChfilter(^coeff.chlpf%(2-F%,0), Utmp%+I%-15, SourceWidth%, Uout%+P%)
PROChfilter(^coeff.chlpf%(2-F%,0), Vtmp%+I%-15, SourceWidth%, Vout%+P%)
ENDIF
pp += SourceWidth%/OutputWidth%
NEXT P%
ENDPROC
;-------------------------------------------------------------------------
REM Measure the vertical component of the geometric distortion by cross-
REM correlating a 288 c/aph signal with zero horizontal frequency (derived
REM by multiplying the 72 c/aph and 216+360 c/aph components) against a
REM 288 c/aph reference file. Since one cycle of 288 c/aph corresponds
REM to 3.75 HD lines only a 'modulo-4' result is produced; this must
REM afterwards be 'disambiguated' to give an absolute vertical measurement.
REM To improve the S/N ratio the correlation is performed over a 3x3
REM 'macroblock' centered on the block of interest.
DEF PROCyprocess
LOCAL A%, B%, C%, D%, M%, N%, P%, R%, V%, W%, X%, Y%, Z%, c%(), sum
DIM c%(3,Xblocks%-1,Yblocks%-1)
IF Undistorted% sum = sum25 ELSE sum = sum9
C% = XblockSize%
D% = YblockSize%
W% = SourceWidth%
FOR Y% = 0 TO Yblocks%-1
FOR X% = 0 TO Xblocks%-1
P% = Y%*D%*W% + X%*C%
A% = C288% + P%
Z% = P% + Wref%
FOR V% = 0 TO 3
B% = Z% - V%*W%
c%(V%,X%,Y%) = USR(correlate)
NEXT
NEXT
NEXT Y%
Cy%() = 0
Dy%() = 128
FOR Y% = 1 TO Yblocks%-2 : REM ignore edge blocks (filtering etc.)
FOR X% = 1 TO Xblocks%-2 : REM ignore edge blocks (filtering etc.)
M% = &80000000 : REM maximum
FOR V% = 0 TO 3
B% = ^c%(V%,X%,Y%)
C% = USR(sum)
IF C% > M% M% = C% : R% = V%
NEXT
B% = ^c%((R%+2)MOD4,X%,Y%)
N% = USR(sum)
Dy%(X%,Y%) = R%
Cy%(X%,Y%) = ((M%-N%) DIV 3) >> ChromaScale% : REM So X and Y give similar CCs
NEXT
NEXT Y%
PROCdisambiguate(Dy%(), Cy%(), Fy%(), Ythresh%)
REM Even out positive and negative excursions:
PROCbalance(Dy%(), Fy%())
ENDPROC