diff options
Diffstat (limited to 'Build/source/utils/asymptote/examples/tvgen.asy')
-rw-r--r-- | Build/source/utils/asymptote/examples/tvgen.asy | 1480 |
1 files changed, 0 insertions, 1480 deletions
diff --git a/Build/source/utils/asymptote/examples/tvgen.asy b/Build/source/utils/asymptote/examples/tvgen.asy deleted file mode 100644 index 0ea7ce3eb6d..00000000000 --- a/Build/source/utils/asymptote/examples/tvgen.asy +++ /dev/null @@ -1,1480 +0,0 @@ -/* tvgen - draw pm5544-like television test cards. - * Copyright (C) 2007, 2009, 2012, Servaas Vandenberghe. - * - * The tvgen code below is free software: you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with tvgen: see the file COPYING. If not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * tvgen-1.2/tvgen.asy http://picaros.org/ftp/soft/tvgen-1.2.tgz - * This asy script generates pm5544-like television test cards. The image - * parameters were derived from a 1990 recording. The basic parameters - * conform to itu-r bt.470, bt.601, and bt.709. There is no unique image - * since local variants exist and parameters have varied over time. - */ -//papertype="a4"; -import plain; -int verbose=settings.verbose/*+2*/; /* uncomment for debug info */ - -/* tv dot coordinates --> PS points */ -pair tvps(real col, real row, real xd, real yd, int Nv) { - real psx, psy; - psx=col*xd; psy=(Nv-row)*yd; - return (psx,psy); -} -path tvrect(int lc, int tr, int rc, int br, real xd, real yd, int Nv) { - real lx, ty, rx, by; - pair[] z; - - lx=lc*xd; ty=(Nv-tr)*yd; - rx=rc*xd; by=(Nv-br)*yd; - /* bl br tr tl */ - z[0]=(lx, by); - z[1]=(rx, by); - z[2]=(rx, ty); - z[3]=(lx, ty); - - return z[0]--z[1]--z[2]--z[3]--cycle; -} - -/********************* horizontal castellations ********************/ -/* Draw a horizontal red line in the top left and the bottom right - * castellation. These testlines disappear if the monitor is not set - * in a dot-exact mode. An example is image crop due to overscan. - * - * For 625 line systems any analog-compatible processing removes - * these red testlines since the first halfline of the odd field and - * the last halfline of the even field are ignored. A full 576 - * visible line frame often results via a final copy paste operation. - */ -void castelhor(int colortv, int[] rccoll, int[] rccolr, int cmaxi, int Nh, - int topdist, int botdist, - pen pdef, real xd, real yd, int Nv) { - pen pblack, pwhite, pred; - int i; - - pblack = pdef+gray(0.0); - pwhite = pdef+gray(1.0); - pred = pdef+rgb(0.75, 0, 0); - - /** top and bottom: white corners. **/ - for (i=-1; i<=cmaxi; ++i) { - pen pcast; - int inext, lc, rc, tr, br; - path zzc; - - inext = i+1; - if (inext%2 == 0) { - pcast = pwhite; - } else { - pcast = pblack; - } - - if (i >= 0) { - lc = rccolr[i]; - } else { - lc = 0; - } - if (inext <= cmaxi) { - rc = rccoll[inext]; - } else { - rc = Nh; - } - - if (i == 0 && colortv > 0 && topdist > 1) { - path zzr; - zzr = tvrect(lc,0, rc,1, xd,yd,Nv); - fill(zzr, p=pred); - tr = 1; - } else { - tr = 0; - } - zzc = tvrect(lc,tr, rc,topdist, xd,yd,Nv); - fill(zzc, p=pcast); - - if (inext == cmaxi && colortv > 0 && botdist+1 < Nv) { - path zzr; - zzr = tvrect(lc,Nv-1, rc,Nv, xd,yd,Nv); - fill(zzr, p=pred); - br = Nv-1; - } else { - br = Nv; - } - zzc = tvrect(lc,botdist, rc,br, xd,yd,Nv); - fill(zzc, p=pcast); - } - - return; -} - -/********************* vertical castellations ********************/ -/* The bottom right red rectangle tests for a non causal color FIR - * filter in the receiver. The last 2..4 dots then typically appear - * colorless, green, or cyan. - * - * This stems from the fact that the chroma subcarrier is of lower - * bandwidth than luma and thus continues after the last active sample. - * These trailing (y,u,v) samples result from an abrupt signal to zero - * transition and depend on the transmit and receive filters. Samples - * from VHS, system B/G/D/K, system I, or a DVD player output are - * different. Nevertheless, a sharpening filter uses this data and so - * adds false color to the last dots. - */ -void castelver(int colortv, int leftdist, int rightdist, int Nh, - int[] rcrowb, int[] rcrowt, int rmaxi, - pen pdef, real xd, real yd, int Nv) { - pen pblack, pwhite; - int i; - - pblack = pdef+gray(0.0); - pwhite = pdef+gray(1.0); - - for (i=0; i<rmaxi; ++i) { - int inext = i+1; - pen pcastl, pcastr; - int tr, br; - path zzc; - - if (inext%2 == 0) { - pcastl = pwhite; - } else { - pcastl = pblack; - } - if (inext == rmaxi && colortv>0) { - pcastr = pdef+rgb(0.75,0.0,0); - } else { - pcastr = pcastl; - } - - tr=rcrowb[i]; - br=rcrowt[i+1]; - zzc=tvrect( 0,tr, leftdist,br, xd,yd,Nv); - fill(zzc, p=pcastl); - zzc=tvrect(rightdist,tr, Nh,br, xd,yd,Nv); - fill(zzc, p=pcastr); - } - return; -} -/********************* image aspect ratio markers ********************/ -void rimarkers(real rimage, int Nh, int Nhc, int os, int Nvc, int Nsy, - pen pdef, real xd, real yd, int Nv) { - int[] ridefN={ 4, 16 }; - int[] ridefD={ 3, 9 }; - int i; - - for (i=0; i<2; ++i) { - real rid=ridefN[i]/ridefD[i]; - - if (rimage>rid) { - int off, offa, offb; - - /* Nhdef=Nh*rid/rimage */ - off=round(Nh*rid/rimage/2); - offa=off+os; - offb=off-os; - // write(offa,offb); - - if (2*offa<Nh) { - int hy, tr, br; - path zz; - - hy=floor(Nsy/3); - tr=Nvc-hy; - br=Nvc+hy; - - zz=tvrect(Nhc+offb, tr, Nhc+offa, br, xd,yd,Nv); - //dot(zz); - fill(zz, p=pdef); - zz=tvrect(Nhc-offa, tr, Nhc-offb, br, xd,yd,Nv); - fill(zz, p=pdef); - } - } - } /* for i */ - return; -} - -/************* crosshatch: line pairing, center interlace test *************/ -/* There are 2 coordinate systems in use: - * 1. integer number based for the gridlines - * - * coff, Nhc, rccoll[], rccolc[], rccolr[] : vertical gridlines, - * rcrowc, Nvc : horizontal gridlines, - * - * 2. real number based for the center circle - * - * ccenter={ cx=Nh/2, cy=Nv/2} : the true image center, - * rcoff rcright rcleft : offset to ccenter and points on the circle. - * - * Both centers coincide if Nh and Nv are even. - */ -void centerline(int colortv, - int[] rccoll, int[] rccolc, int[] rccolr, int divsx, - int Nhc, int os, - int[] rcrowt, int[] rcrowc, int[] rcrowb, int divsy, - int Nvc, - pair ccenter, real[] rcoff, pair[] rcright, pair[] rcleft, - pen pdef, real xd, real yd, int Nv) { - pen pblack, pwhite; - int cmaxi, maxoff, mincol, maxcol; - int rows, tr, br; - path zz; - - cmaxi=2*divsx+1; - - pblack=pdef+gray(0.0); - pwhite=pdef+gray(1.0); - - /* black background for center cross */ - if (colortv > 0) { - /* black, vertical gridlines redrawn below */ - pair[] z; - int col; - - z[0]=rcright[divsy]; - - col = rccolc[divsx+1]; - z[1]=tvps(col,rcrowc[divsy], xd,yd,Nv); - z[2]=tvps(col,rcrowc[divsy-1], xd,yd,Nv); - col = rccolc[divsx]; - z[3]=tvps(col,rcrowc[divsy-1], xd,yd,Nv); - z[4]=tvps(col,rcrowc[divsy], xd,yd,Nv); - - z[5]=rcleft[divsy]; - z[6]=rcleft[divsy+1]; - - z[7]=tvps(col,rcrowc[divsy+1], xd,yd,Nv); - z[8]=tvps(col,rcrowc[divsy+2], xd,yd,Nv); - col = rccolc[divsx+1]; - z[9]=tvps(col,rcrowc[divsy+2], xd,yd,Nv); - z[10]=tvps(col,rcrowc[divsy+1], xd,yd,Nv); - - z[11]=rcright[divsy+1]; - fill(z[1]--z[2]--z[3]--z[4] //--z[5]--z[6] - --arc(ccenter, z[5], z[6]) - --z[7]--z[8]--z[9]--z[10] //--z[11]--z[0] - --arc(ccenter,z[11], z[0]) - --cycle, p=pblack); - } else { - /* 3 rows of black squares inside the gratings */ - int i, imax = divsy+1; - - for (i=divsy-1; i<=imax; ++i) { /* all 3 rows */ - int lmaxoff, lmincol, lmaxcol; - int inext = i+1; - int tr, br, j; - - /* XXX rcoff is relative to ccenter */ - lmaxoff = min(floor(rcoff[i]), floor(rcoff[inext])); - lmincol = Nhc-lmaxoff; - lmaxcol = Nhc+lmaxoff; - - /* square top and bottom */ - tr = rcrowb[i]; - br = rcrowt[inext]; - - for (j=0; j<cmaxi; ++j) { /* column j */ - int jnext = j+1; - - if (lmincol<=rccolc[j] && rccolc[jnext]<=lmaxcol) { - /* square is inside circle */ - int lc, rc; - path zzsq; - - lc = rccolr[j]; - rc = rccoll[jnext]; - zzsq = tvrect(lc, tr, rc, br, xd,yd,Nv); - fill(zzsq, p=pblack); /* draw black squares */ - } - } /* for col j */ - } /* for row i */ - } - - /* center cross: vertical and horizontal centerline */ - maxoff = floor(rcoff[divsy]); /* XXX rcoff is relative to ccenter */ - mincol = Nhc-maxoff; - maxcol = Nhc+maxoff; - - rows=min(Nvc-rcrowc[divsy-1], rcrowc[divsy+2]-Nvc); - tr=Nvc-rows; - br=Nvc+rows; - if (verbose > 1) { - write("centerline long : rows tr br ", rows, tr, br); - } - zz=tvrect(Nhc-os, tr, Nhc+os, br, xd,yd,Nv); - fill(zz, p=pwhite); - zz=tvrect(Nhc-maxoff,Nvc-1, Nhc+maxoff,Nvc+1, xd,yd,Nv); - fill(zz, p=pwhite); - - /* vertical short lines */ - rows=min(Nvc-rcrowc[divsy], rcrowc[divsy+1]-Nvc); - tr=Nvc-rows; - br=Nvc+rows; - if (verbose > 1) { - write("centerline short: rows tr br ", rows, tr, br); - } - - if (colortv > 0) { - int i; - for (i=0; i<=cmaxi; ++i) { - int coll, colr; - - coll=rccoll[i]; - colr=rccolr[i]; - - if (mincol<=coll && colr<=maxcol) { - path zzv; - zzv=tvrect(coll, tr, colr, br, xd,yd,Nv); - fill(zzv, p=pwhite); - } - } - } - return; -} - -/************************ topbw **************************************/ -void topbw(int[] coff, int Nhc, int os, int urow, int trow, int brow, - pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb, - pen pdef, real xd, real yd, int Nv) { - pen pblack=pdef+gray(0.0), pwhite=pdef+gray(1.0); - pair[] ze; - path zext, zref, zint; - int off, col, cr; - - off=ceil((coff[2]+coff[3])/2); - ze[0]=tvps(Nhc+off,trow, xd,yd,Nv); - ze[1]=rcrt; - ze[2]=rclt; - ze[3]=tvps(Nhc-off,trow, xd,yd,Nv); - ze[4]=tvps(Nhc-off,brow, xd,yd,Nv); - col=Nhc-coff[2]-os; - ze[5]=tvps(col,brow, xd,yd,Nv); - ze[6]=tvps(col,trow, xd,yd,Nv); - cr=col+3*os; /* reflection test black pulse */ - zref=tvrect(col,trow, cr,brow, xd,yd,Nv); - ze[7]=tvps(cr,trow, xd,yd,Nv); - ze[8]=tvps(cr,brow, xd,yd,Nv); - ze[9]=tvps(Nhc+off,brow, xd,yd,Nv); - //dot(ze); - - zext=ze[0] // --ze[1]--ze[2] - --arc(ccenter, ze[1], ze[2]) - --ze[3]--ze[4]--ze[5]--ze[6]--ze[7]--ze[8]--ze[9]--cycle; - - off=ceil((coff[1]+coff[2])/2); - zint=tvrect(Nhc-off,urow, Nhc+off,trow, xd,yd,Nv); - - /* paths are completely resolved; no free endpoint conditions */ - fill(zext^^reverse(zint), p=pwhite); - fill(zint, p=pblack); - fill(zref, p=pblack); - - fill(arc(ccenter,rclt,rclb)--ze[4]--ze[3]--cycle, p=pblack); - fill(arc(ccenter,rcrb,rcrt)--ze[0]--ze[9]--cycle, p=pblack); - return; -} - -/************************ testtone **************************************/ -/* x on circle -> return y>=0 - * in: - * x x-coordinate relative to origin - * crad circle radius in y units, true size=crad*yd - */ -real testcircx(real x, real crad, real xd, real yd) { - real relx, ph, y; - - relx=x*xd/yd/crad; - if (relx>1) { - ph=0; - } else { - ph=acos(relx); - } - y=crad*sin(ph); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2 - - return y; -} -/* y on circle -> return x>=0 */ -real testcircy(real y, real crad, real xd, real yd) { - real rely, ph, x; - - rely=y/crad; - if (rely>1) { - ph=pi/2; - } else { - ph=asin(rely); - } - x=crad*cos(ph)*yd/xd; // or (x*xd)^2+(y*yd)^2=(crad*yd)^2 - - return x; -} - -/* brow>trow && xb>xt */ -void testtone(real Tt, int trow, int brow, - real ccol, real crow, real crad, - pen pdef, real xd, real yd, int Nv) { - int blocks, i; - real yt, xt, yb, xb, Ttt=Tt/2; - pair ccenter; - - yt=crow-trow; - xt=testcircy(yt, crad, xd, yd); - yb=crow-brow; - xb=testcircy(yb, crad, xd, yd); - //write('#xt yt\t',xt,yt); write('#xb yb\t',xb,yb); - - ccenter=tvps(ccol,crow, xd,yd,Nv); - - blocks=floor(2*xb/Tt); - - for (i=-blocks-1; i<=blocks; ++i) { - real tl, tr; - path zz; - - tl=max(-xb,min(i*Ttt,xb)); /* limit [-xb..xb] */ - tr=max(-xb,min((i+1)*Ttt,xb)); - - if (tl<-xt && tr<=-xt || tr>xt && tl>=xt) { /* top full circle */ - pair[] z; - real yl, yr; - - yl=testcircx(tl, crad, xd, yd); - yr=testcircx(tr, crad, xd, yd); - - z[0]=tvps(ccol+tl,brow, xd,yd,Nv); - z[1]=tvps(ccol+tr,brow, xd,yd,Nv); - z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv); - z[3]=tvps(ccol+tl,crow-yl, xd,yd,Nv); - - zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--cycle; - } else if(tl<-xt) { /* tl in circel, tr not, partial */ - pair[] z; - real yl; - - yl=testcircx(tl, crad, xd, yd); - - z[0]=tvps(ccol+tl,brow, xd,yd,Nv); - z[1]=tvps(ccol+tr,brow, xd,yd,Nv); - z[2]=tvps(ccol+tr,trow, xd,yd,Nv); - z[3]=tvps(ccol-xt,trow, xd,yd,Nv); - z[4]=tvps(ccol+tl,crow-yl, xd,yd,Nv); - - zz=z[0]--z[1]--z[2]--arc(ccenter,z[3],z[4])--cycle; - } else if(tr>xt) { /* tr in circle, tl not, partial */ - pair[] z; - real yr; - - yr=testcircx(tr, crad, xd, yd); - - z[0]=tvps(ccol+tl,brow, xd,yd,Nv); - z[1]=tvps(ccol+tr,brow, xd,yd,Nv); - z[2]=tvps(ccol+tr,crow-yr, xd,yd,Nv); - z[3]=tvps(ccol+xt,trow, xd,yd,Nv); - z[4]=tvps(ccol+tl,trow, xd,yd,Nv); - zz=z[0]--z[1]--arc(ccenter,z[2],z[3])--z[4]--cycle; - } else { /* full block */ - pair[] z; - - z[0]=tvps(ccol+tr,trow, xd,yd,Nv); - z[1]=tvps(ccol+tl,trow, xd,yd,Nv); - z[2]=tvps(ccol+tl,brow, xd,yd,Nv); - z[3]=tvps(ccol+tr,brow, xd,yd,Nv); - zz=z[0]--z[1]--z[2]--z[3]--cycle; - } - - if (tl<tr) { - if (i%2 == 0) { - fill(zz, p=pdef+gray(0.0)); - } else { - fill(zz, p=pdef+gray(0.75)); - } - } - } - return; -} - -/************************ color bars *************************************/ -void colorbars(int[] coff, int Nhc, int trow, int crow, int brow, - pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb, - pen pdef, real xd, real yd, int Nv) { - real cI=0.75; - real[] cR={ cI, 0, 0, cI, cI, 0 }; - real[] cG={ cI, cI, cI, 0, 0, 0 }; - real[] cB={ 0, cI, 0, cI, 0, cI }; - int cmax=2, poff, rows, i; - - rows=brow-trow; - poff=0; - for (i=0; i<=cmax; ++i) { - int off; - int ii=2*i, il=cmax-i, ir=i+cmax+1; - path zzl, zzr; - - off=ceil((coff[1+ii]+coff[2+ii])/2); - if (i!=0 && i<cmax) { - zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv); - zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv); - } else { - if(i==0) { - int col, pcol; - pair[] zl, zr; - - col=Nhc+off; - pcol=Nhc+poff; - zr[0]=tvps(col,trow, xd,yd,Nv); - zr[1]=tvps(pcol,trow, xd,yd,Nv); - zr[2]=tvps(pcol,crow, xd,yd,Nv); - zr[3]=tvps(Nhc+coff[0],crow, xd,yd,Nv); - zr[4]=tvps(Nhc+coff[0],brow, xd,yd,Nv); - zr[5]=tvps(col,brow, xd,yd,Nv); - zzr=zr[0]--zr[1]--zr[2]--zr[3]--zr[4]--zr[5]--cycle; - - col=Nhc-off; - pcol=Nhc-poff; - zl[0]=tvps(pcol,trow, xd,yd,Nv); - zl[1]=tvps(col,trow, xd,yd,Nv); - zl[2]=tvps(col,brow, xd,yd,Nv); - zl[3]=tvps(Nhc-coff[0],brow, xd,yd,Nv); - zl[4]=tvps(Nhc-coff[0],crow, xd,yd,Nv); - zl[5]=tvps(pcol,crow, xd,yd,Nv); - zzl=zl[0]--zl[1]--zl[2]--zl[3]--zl[4]--zl[5]--cycle; - } else { - int pcol; - pair[] zl, zr; - - pcol=Nhc+poff; - zr[0]=tvps(pcol,brow, xd,yd,Nv); - zr[1]=rcrb; - zr[2]=rcrt; - zr[3]=tvps(pcol,trow, xd,yd,Nv); - zzr=zr[0]--arc(ccenter,zr[1],zr[2])--zr[3]--cycle; - - pcol=Nhc-poff; - zl[0]=tvps(pcol,trow, xd,yd,Nv); - zl[1]=rclt; - zl[2]=rclb; - zl[3]=tvps(pcol,brow, xd,yd,Nv); - zzl=zl[0]--arc(ccenter,zl[1],zl[2])--zl[3]--cycle; - } - } - fill(zzr, p=pdef+rgb(cR[ir], cG[ir], cB[ir])); - fill(zzl, p=pdef+rgb(cR[il], cG[il], cB[il])); - - poff=off; - } - return; -} - -/************************ test frequencies ****************************/ -/* in - * theta rad - * freq 1/hdot - * step hdot - * out - * new phase theta - */ -real addphase(real theta, real freq, real step) { - real cycles, thetaret; - int coverflow; - - cycles=freq*step; - coverflow=floor(abs(cycles)); - if (coverflow>1) { - thetaret=0; - } else { - real dpi=2*pi; - - cycles-=coverflow*sgn(cycles); - thetaret=theta+cycles*dpi; /* cycles=(-1 .. 1) */ - - if (thetaret>pi) { - thetaret-=dpi; - } else if (thetaret<-pi) { - thetaret-=dpi; - } - } - - //write("addphase: ", step, theta, thetaret); - return thetaret; -} - -void testfreqs(real[] ftones, int[] coff, int Nhc, int trow,int crow,int brow, - pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb, - pen pdef, real xd, real yd, int Nv) { - int[] divc; - real[] divfl, divfr; - int i, divs, coffmax, off, divnext; - real fl, fr, thr, thl; - - /* Segment info for PAL continental test card - * segment i extends from (divc[i] .. divc[i+1]) with frequency divf[i] - */ - divs=2; // the number of segments to the right, total=2*divs+1 - divc[0]=0; - for (i=0; i<=divs; ++i) { - int ii=i*2, il=divs-i, ir=divs+i; - - divc[i+1]=ceil((coff[ii]+coff[ii+1])/2); /* xdot distance to center */ - - divfl[i]=ftones[divs-i]; - divfr[i]=ftones[divs+i]; - } - coffmax=divc[divs+1]; - - int trowlim=coff[0]; - int tr; - - tr=crow; - - divnext=0; - fl=0; - fr=0; - thl=0; /* ={ 0, -pi/2 } : initial angle at center vertical line Nhc */ - thr=thl; - /* draw a vertical line at off..off+1, use theta for off+1/2 */ - for (off=0; off<coffmax; ++off) { - real ampl, ampr; - int col; - path zz; - - if (off==trowlim) { - tr=trow; - } - - if (off == divc[divnext]) { - /* switch frequency: cycles=0.5*fcur+0.5*fnext */ - thl=addphase(thl, fl, -0.5); - thr=addphase(thr, fr, 0.5); - fl=divfl[divnext]; - fr=divfr[divnext]; - thl=addphase(thl, fl, -0.5); - thr=addphase(thr, fr, 0.5); - - ++divnext; - // thl=pi; thr=pi; - //write(off, fl, fr); - } else { - thl=addphase(thl, fl, -1); - thr=addphase(thr, fr, 1); - // thl=0; thr=0; - } - - ampl=(1+sin(thl))/2; - ampr=(1+sin(thr))/2; - //write(off, thr, ampr); - - col=Nhc-off-1; - zz=tvrect(col,tr, col+1,brow, xd,yd,Nv); - fill(zz, p=pdef+gray(ampl)); - col=Nhc+off; - zz=tvrect(col,tr, col+1,brow, xd,yd,Nv); - fill(zz, p=pdef+gray(ampr)); - } - - pair[] z; - z[0]=tvps(Nhc-coffmax,trow, xd,yd,Nv); - z[1]=tvps(Nhc-coffmax,brow, xd,yd,Nv); - fill(z[0]--arc(ccenter,rclt,rclb)--z[1]--cycle, p=pdef+gray(0.0)); - z[0]=tvps(Nhc+coffmax,brow, xd,yd,Nv); - z[1]=tvps(Nhc+coffmax,trow, xd,yd,Nv); - fill(z[0]--arc(ccenter,rcrb,rcrt)--z[1]--cycle, p=pdef+gray(0.0)); - return; -} - -/************************ gray bars **************************************/ -void graybars(int[] coff, int Nhc, int trow, int brow, - pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb, - pen pdef, real xd, real yd, int Nv) { - int[] gs={0, 20, 40, 60, 80, 100}; - int cmax=2, poff, i; - - poff=0; - for (i=0; i<=cmax; ++i) { - int off; - int ii=2*i, il=cmax-i, ir=i+cmax+1; - path zzl, zzr; - - off=ceil((coff[1+ii]+coff[2+ii])/2); - if (i<cmax) { - zzl=tvrect(Nhc-off,trow, Nhc-poff,brow, xd,yd,Nv); - zzr=tvrect(Nhc+poff,trow, Nhc+off,brow, xd,yd,Nv); - } else { - int pcol; - pair zlt, zlb, zrt, zrb; - - pcol=Nhc-poff; - zlt=tvps(pcol,trow, xd,yd,Nv); - zlb=tvps(pcol,brow, xd,yd,Nv); - zzl=zlt--arc(ccenter,rclt,rclb)--zlb--cycle; - - pcol=Nhc+poff; - zrb=tvps(pcol,brow, xd,yd,Nv); - zrt=tvps(pcol,trow, xd,yd,Nv); - zzr=zrb--arc(ccenter,rcrb,rcrt)--zrt--cycle; - } - fill(zzl, p=pdef+gray(gs[il]/100)); - fill(zzr, p=pdef+gray(gs[ir]/100)); - - poff=off; - } - return; -} - -/************************ bottom bw **************************************/ -void bottombw(int off, int Nhc, int trow, int brow, - pair ccenter, pair rclt, pair rclb, pair rcrt, pair rcrb, - pen pdef, real xd, real yd, int Nv) { - int rows; - pair zt, zb; - path zz; - - rows=brow-trow; - zz=tvrect(Nhc-off,trow, Nhc+off,brow, xd,yd,Nv); - fill(zz, p=pdef+gray(0.0)); - - zt=tvps(Nhc-off,trow, xd,yd,Nv); - zb=tvps(Nhc-off,brow, xd,yd,Nv); - fill(zt--arc(ccenter,rclt,rclb)--zb--cycle, p=pdef+gray(1.0)); - - zb=tvps(Nhc+off,brow, xd,yd,Nv); - zt=tvps(Nhc+off,trow, xd,yd,Nv); - fill(zb--arc(ccenter,rcrb,rcrt)--zt--cycle, p=pdef+gray(1.0)); - return; -} - -/************************ bottom circle **************************************/ -void bottomcirc(int off, int Nhc, int trow, real cx, real cy, real crad, - pair ccenter, pair rclt, pair rcrt, - pen pdef, real xd, real yd, int Nv) { - real cI=0.75; - real xl, yl, xr, yr, phil, phir; - pair ccleft, ccright; - pair[] z; - - xl=Nhc-off-cx; - phil=acos(xl*xd/yd/crad); - yl=crad*sin(phil); // or (x*xd)^2+(y*yd)^2=(crad*yd)^2 - ccleft=tvps(cx+xl,cy+yl, xd,yd,Nv); - //write(xl,yl); - - xr=Nhc+off-cx; - phir=acos(xr*xd/yd/crad); - yr=crad*sin(phir); - ccright=tvps(cx+xr,cy+yr, xd,yd,Nv); - - //dot(ccright); dot(ccleft); - // red center - z[0]=tvps(Nhc-off,trow, xd,yd,Nv); - z[1]=ccleft; - z[2]=ccright; - z[3]=tvps(Nhc+off,trow, xd,yd,Nv); - fill(z[0]--arc(ccenter,z[1],z[2])--z[3]--cycle, p=pdef+rgb(cI,0,0)); - - // yellow - z[0]=tvps(Nhc-off,trow, xd,yd,Nv); - z[1]=rclt; - z[2]=ccleft; - fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0)); - z[0]=tvps(Nhc+off,trow, xd,yd,Nv); - z[1]=ccright; - z[2]=rcrt; - fill(z[0]--arc(ccenter,z[1],z[2])--cycle, p=pdef+rgb(cI,cI,0)); - - return; -} - -/****************************** PAL ears ***********************************/ -/* values pro mille - * left y R G B - * 550 306 674 550 - * 500 363 500 859 - * 500 637 500 141 - * 450 694 326 450 - * right - * 600 600 684 166 - * 400 400 316 834 - * - * in: dright= -1 left ear, +1 right ear - */ -void palears(int[] coff, int[] coffa, int[] coffb, int Nhc, - int[] rcrowt, int[] rcrowb, int Nvc, int divsy, int dright, - pen pdef, real xd, real yd, int Nv) { - /* the amplitude of (u,v) as seen on a vectorscope, - * max 0.296 Vn for 100% saturation in W and V ears. - * cvbs: 0.7*( y +/- |u+jv| ) = -0.24 .. 0.93 V - * maxima: ebu 75/0 bars 0.70, bbc 100/25 0.88, 100/0 bars 0.93 - * burst: 0.150 Vcvbs, 21.4 IRE or 0.214 V normalized. - * luma: modulated for monochrome compatibility, 1990 version. - * choice: set amplitude of subcarrier equal to amplitude of colorburst. - */ - real cI=0.214; - - /* itu-r */ - real wr=0.299, wb=0.114, wg=1-wr-wb; /* wg=0.587, y=wr*R+wg*G+wb*B */ - real wu=0.493, wv=0.877; /* u=wu*(B-y) v=wv*(R-y) */ - /* (u,v) for zero G-y, phase of -34.5 degrees */ - real colu=wu*wg/wb, colv=-wv*wg/wr; /* for w=(G-y)/0.696 == 0 */ - - /* ears: U==0 W==0 W==0 U==0 */ - real[] cyl={ 0.55, 0.5, 0.5, 0.45 }; - real[] cul={ 0, colu, -colu, 0 }; - real[] cvl={ -1, colv, -colv, 1 }; - - /* ears: V==0 W==0 W==0 V==0 */ - real[] cyr={ 0.60, 0.5, 0.5, 0.40 }; - real[] cur={ -1, colu, -colu, 1 }; - real[] cvr={ 0, colv, -colv, 0 }; - - real[] cy, cu, cv; - pair[] z; - path[] zz; - int lcol, ccol, cicol, rcol, i; - - if (dright>0) { - if (verbose > 1) - write("right ears"); - cy=cyr; cu=cur; cv=cvr; - } else { - if (verbose > 1) - write("left ears"); - cy=cyl; cu=cul; cv=cvl; - } - - lcol=Nhc+dright*coffa[5]; - ccol=Nhc+dright*coff[6]; - cicol=Nhc+dright*coffa[6]; - rcol=Nhc+dright*coffb[7]; - - int urow, trow, crow, brow, arow; - urow=rcrowb[divsy-5]; - trow=rcrowt[divsy-3]; - crow=Nvc; - brow=rcrowb[divsy+4]; - arow=rcrowt[divsy+6]; - - z[0]=tvps(ccol,urow, xd,yd,Nv); - z[1]=tvps(ccol,trow, xd,yd,Nv); - z[2]=tvps(cicol,trow, xd,yd,Nv); - z[3]=tvps(cicol,crow, xd,yd,Nv); - z[4]=tvps(rcol,crow, xd,yd,Nv); - z[5]=tvps(rcol,urow, xd,yd,Nv); - zz[0]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle; - - zz[1]=tvrect(lcol,urow, ccol,trow, xd,yd,Nv); - zz[2]=tvrect(lcol,brow, ccol,arow, xd,yd,Nv); - - z[0]=tvps(ccol,arow, xd,yd,Nv); - z[1]=tvps(ccol,brow, xd,yd,Nv); - z[2]=tvps(cicol,brow, xd,yd,Nv); - z[3]=tvps(cicol,crow, xd,yd,Nv); - z[4]=tvps(rcol,crow, xd,yd,Nv); - z[5]=tvps(rcol,arow, xd,yd,Nv); - zz[3]=z[0]--z[1]--z[2]--z[3]--z[4]--z[5]--cycle; - - for (i=0; i<4; ++i) { - real y, u, v, A, ph, By, Ry, Gy, R, G, B; - - y=cy[i]; - u=cu[i]; - v=cv[i]; - - A=hypot(u,v); - ph= (u!=0 || v!=0) ? atan2(v,u) : 0.0; - if (v>=0) { - if (ph<0) - ph=ph+pi; - } else { - if (ph>0) - ph=ph-pi; - } - if (A>0) { - u=u/A*cI; - v=v/A*cI; - } - - By=u/wu; - Ry=v/wv; - Gy=(-wr*Ry-wb*By)/wg; - //write(y,Gy,A,ph*180/pi); - - R=Ry+y; - G=Gy+y; - B=By+y; - if (verbose > 1) - write(y*1000, round(R*1000), round(G*1000), round(B*1000)); - - fill(zz[i], p=pdef+rgb(R,G,B)); - } - return; -} - -/****************************** NTSC bars ***********************************/ -/* amplitude equals color burst smpte (pm: -V +U) - * y campl sat R G B - * left 0.5 0.21 70% -I? - * right 0.5 0.17 60% +Q? - */ -void ntscbars(int[] rccoll, int[] rccolr, int divsx, - int[] rcrowt, int[] rcrowb, int divsy, int dright, - pen pdef, real xd, real yd, int Nv) { - /* The amplitude of (i,q) as seen on a vectorscope, - * max 0.292 Vn for 100% saturation in I==0 ears. - * burst: 0.143 Vcvbs, 20 IRE or 0.200 V normalized. - * pedestal: (yp,up,vp)=(p,0,0)+(1-p)*(y,u,v), p=0.075. - * choice: equal amplitude for colorburst and subcarrier. - */ - real campl=0.200/0.925; - - /* wg=0.587, y=wr*R+wg*G+wb*B */ - real wr=0.299, wb=0.114, wg=1-wr-wb; - /* iT : iq -> RyBy : rotation+scaling */ - real iT11=0.95, iT12=0.62, iT21=-1.11, iT22=1.71; - - /* bars -2 -1 0 1 2 */ - real[] cyl={ 0.50, 0.50, 1, 0.50, 0.50 }; - real[] cil={ 0, 0, 0, -1, 1 }; - real[] cql={ -1, 1, 0, 0, 0 }; - int[] indl={ -7, -8, 0, 8, 7 }; - - real cy, ci, cq; - int rmaxi, dri, ind, ibase, lcol, rcol, i; - - rmaxi=2*divsy+1; - if (dright<-2 || dright>2) { - dri=2; - } else { - dri=2+dright; - } - - cy=cyl[dri]; - ci=cil[dri]; - cq=cql[dri]; - ind=indl[dri]; - ibase=divsx+ind; - lcol=rccolr[ibase]; - rcol=rccoll[ibase+1]; - - real A, By, Ry, Gy, R, G, B; - - A=hypot(ci,cq); - if (A>0) { - ci=ci/A*campl; - cq=cq/A*campl; - } - Ry=iT11*ci+iT12*cq; - By=iT21*ci+iT22*cq; - Gy=(-wr*Ry-wb*By)/wg; - //write(cy,Ry,Gy,By); - - R=Ry+cy; - G=Gy+cy; - B=By+cy; - if (verbose > 1) - write(ind, cy*1000, round(ci*1000), round(cq*1000), - round(R*1000), round(G*1000), round(B*1000)); - - for (i=0; i<rmaxi; ++i) { - path zz; - int brow, trow, inext=i+1; - - if (i>0) { - trow=rcrowb[i]; - } else { - trow=floor((rcrowb[i]+rcrowt[inext])/2); - } - - if (inext<rmaxi) { - brow=rcrowt[inext]; - } else { - brow=floor((rcrowb[i]+rcrowt[inext])/2); - } - - zz=tvrect(lcol,trow, rcol,brow, xd,yd,Nv); - fill(zz, p=pdef+rgb(R,G,B)); - } - - return; -} - -/****************************** main ***********************************/ -/* Conversion to bitmap: - * EPSPNG='gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE=png16m' - * asy -u bsys=2 -u colortv=1 -u os=1 -a Z tvgen - * $EPSPNG -r132x144 -g720x576 -sOutputFile=tvgen.png tvgen.eps - * - * asy -u bsys=2 -u colortv=1 -u os=1 tvgen - */ -int bsys=2, colortv=1, os=1; - -/* bsys: broadcast system - * bsys im aspect Nh - * 0 4/3 704 guaranteed analog broadcast itu-r bt.470 - * 1 4/3 720 new broadcast, most TV station logos and animations - * 2 15/11 720 total aperture analog 4/3, 1.37 film DVDs - * 3 20/11 720 total aperture analog 16/9, 1.85 film DVDs - * 4 4/3 768 bsys=0, square dot analog broadcast - * 5 4/3 768 bsys=1, square dot cable TV info channel - * 6 131/96 786 bsys=2, total square dot broadcast camera - * 7 16/9 720 new broadcast 16/9, SD from HD-1440 or itu-r bt.709 - * 8 4/3 704 525 analog broadcast itu-r bt.470 711x485 - * 9 4/3 720 525 new broadcast - * 10 15/11 720 525 total aperture analog broadcast - * 11 16/9 1920 1250, 1080 square dot at 12.5 frames/second - * 12 4/3 1600 1250, 1200 square dot at 12.5 frames/second - * - * colortv: - * 0 monochrome crosshatch, - * 1 pal ears, - * 2 ntsc bars, - * 3 neither ears nor bars. - * - * os: horizontal oversampling, typical values for 13.5MHz: - * 2 4/3 704*576, 15/11 720*576 - * 4 4/3 720*480 - * 5 4/3 704*480, 15/11 720*480, 4/3 768*576 14.4MHz - * 8 4/3 720*576, 20/11 720*576 - * 12 704->768 rerastering - * 16 720->768 rerastering - */ -access settings; -usersetting(); - -if (bsys<0 || bsys>12 || colortv<0 || colortv>3 || os<=0 || os>16) { - write("Error: bad user input: bsys, colortv, os=\t", bsys, colortv, os); - abort("Bad option -u bsys=N ?"); -} - -int[] bNdot= - { 12, 16, 12, 16, 1, 1, 1, 64, 10, 8, 10, 1, 1 }; -int[] bDdot= - { 11, 15, 11, 11, 1, 1, 1, 45, 11, 9, 11, 1, 1 }; -int[] bNh= - { 704, 720, 720, 720, 768, 768, 786, 720, 704, 720, 720, 1920, 1600 }; -int[] bNv= - { 576, 576, 576, 576, 576, 576, 576, 576, 480, 480, 480, 1080, 1200 }; -real[] bfs= - { 13.5,13.5,13.5,13.5, 14.75,14.4,14.75,13.5, 13.5,13.5,13.5, 36, 30 }; -int[] bNsy= - { 42, 42, 42, 42, 42, 42, 42, 42, 34, 34, 34, 78, 90 }; -int[] bNsh= - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -/* active lines for a 625 line frame - * The number of active video lines decreased around 1997. - * old: 3 run in + 575 visible + 3 run out = 581 lines - * new: 6 teletext and WSS + 575 visible - * Hence the image center shifted down by 3 lines. Thus - * old TV + new testcard = bottom is cut off, - * new TV + old testcard = top is cut off. - * - * To generate the old testcard either use Nv=582 Nsh=0 or Nv=576 Nsh=3. - * - * aspect ratio - * rimage=xsize/ysize rimage=rdot*Nh/Nv - * Nh=704 dots - * Nv=576 lines - * rd=ri*Nv/Nh=4/3*9/11=12/11 - * - * Nv: 480=2^5*3*5 576=2^6*3^2 - * Nh: 704=2^6*11 720=2^4*3^2*5 - * - * horizontal line distance for pre 1997 test pattern - * top 8 lines, 13 squares of Ny=43 lines, bottom 9 lines - * top 12 lines, 13 squares of Ny=42 lines, bottom 18 lines - * pairs are from odd even field - * Interlace test: Ny must be odd for a cross-hatch without centerline. - * - * squares: ly=Nsy, lx=rd*Nsx, lx=ly ==> Nsx=Nsy/rd={ 39.4, 38.5 } - * x line width 230 ns -> 3 dots - * bottom 2.9us red -> 39.15 dots - * - * resolution DPI from image aspect ratio - * Rv=Nv/ly, ly=4in - * ri=Ni/Di, Ni={ 4, 15, 16} Di={ 3, 11, 9} - * lx=ri*ly - * - * Rh=Nh/lx=Di*(Nh/(Ni*ly)) - * integer Rh: - * Ni=4 ri=4/Di => Nh=k*16 - * Ni=15 ri=15/Di => Nh=k*60 - * Ni=16 ri=16/Di => Nh=k*64 - * - * resolution DPI from dot aspect ratio, general algorithm, - * - * rd=Nd/Dd=ldx/ldy - * - * assume 1 dot = Nd x Dd square subdots at a resolution of k, in dpi, then - * - * ldx=Nd/k, ldy=Dd/k ==> Rh=k/Nd, Rv=k/Dd - * - * choosing k=m*Nd*Dd for integer Rh and Rv gives - * - * ldx=1/(m*Dd), ldy=1/(m*Nd), Rh=m*Dd, Rv=m*Nd - * - * and - * - * lx=Nh*ldx=Nh/(m*Dd), ly=Nv*ldy=Nv/(m*Nd) - * - * so choose m for the intended height Ly, in inch, as - * - * m=round(Nv/(Ly*Nd)) - * - * which limits Ly<=Nv/Nd since Rv>=Nd. - */ -//cm=72/2.540005; -real Ly, ly, lx, ysize, xsize, rimage, xd, yd, pwidth; -int Nd, Dd, m, Nh, Nv, Nshift, Na, Nsy; -real fs, Ttone; - -Nd=bNdot[bsys]; -Dd=bDdot[bsys]*os; -Nh=bNh[bsys]*os; -Nv=bNv[bsys]; - -Ly=4; // 4 inch vertical size -m=floor(0.5+Nv/(Ly*Nd)); -if (m < 1) m=1; -ly=Nv/(m*Nd); -lx=Nh/(m*Dd); - -ysize=ly*1inch; -xsize=lx*1inch; -rimage=xsize/ysize; -if (verbose > 1) { - write("#Nd Dd m ri:\t", Nd, Dd, m, rimage); -} -//size(xsize, ysize, Aspect); // should not have any effect - -Nsy=bNsy[bsys]; // grating size in lines 42,43 or 34,35 -Nshift=bNsh[bsys]; // shift image up: pre 1997 =3, 2007 =0 -fs=1e6*bfs[bsys]*os; -Na=0; // add 1,0,-1 to height of hor center squares for even Na+Nsy - -Ttone=fs/250e3; // period of ft=250 kHz, fs/ft=54 -real[] ftones={0.8e6/fs, 1.8e6/fs, 2.8e6/fs, 3.8e6/fs, 4.8e6/fs}; - -xd=xsize/Nh; -yd=ysize/Nv; -pwidth=min(abs(xd),abs(yd)); - -pen pdefault = squarecap+linewidth(pwidth); -pen pblack = pdefault+gray(0.0); -pen pwhite = pdefault+gray(1.0); - -/**** calculate grating repeats and size in tv dots ****/ -/* horizontal lines */ -int divsy, rdisty, Nvc, Nt, Nb, rmaxi; - -Nvc=floor(Nv/2)-Nshift; -/* top half picture (Nv-2)/2-(Nsy+Na)/2 dots for divisions of Nsy dots */ -divsy=floor(((Nv-2-Na)/Nsy-1)/2); -rdisty=Na+Nsy*(1+2*divsy); -/* first guess free lines top and bottom */ -Nt=Nvc-ceil(rdisty/2); -Nb=Nv-Nt-rdisty; -if (verbose > 1) { - write('#divsy t b: \t', divsy, Nt, Nb); -} -rmaxi=2*divsy+1; - -/* Nsyc: center square height - * line pairing test: verify distance of center to top and bot - * distance is odd ==> top=even/odd, cent=odd/even, bot=even/odd - * - * Nsyc odd: not possible - * - * Nsyc even: - * Nsyc/2 odd --> OK - * Nsyc/2 even --> stagger the raster one line upwards - * - * rcrowt top dist of hor line - * rcrowc true center for color info, distance to top of image. - * rcrowb bot dist of hor line - * - * offd = offu-Nsyc - * Nt = Nvc-(offu+divsy*Nsy); - * Nb = Nv-( Nvc-(offd-divsy*Nsy) ); - * ==> Nt+Nb = Nv-Nsyc-2*divsy*Nsy - */ -int Nsyc, offu, offd, Nyst=0, i; -int[] rcrowt, rcrowc, rcrowb; - -Nsyc=Nsy+Na; -offu=floor(Nsyc/2); -offd=offu-Nsyc; -if (Nsyc%2 != 0) { - Nyst=1; -} else if (Nsyc%4 == 0) { - Nyst=1; /* stagger */ -} -for (i=0; i<=divsy; ++i) { - int iu, id, ou, od, ru, rd; - - iu=divsy-i; - id=divsy+i+1; - - ou=offu+Nsy*i; - od=offd-Nsy*i; - if (verbose > 1) { - write(ou,od); - } - rcrowc[iu]=Nvc-ou; - rcrowc[id]=Nvc-od; - - ru=Nvc-(ou+Nyst); - rd=Nvc-(od+Nyst); - - rcrowt[iu]=ru-1; - rcrowb[iu]=ru+1; - - rcrowt[id]=rd-1; - rcrowb[id]=rd+1; -} -Nt=floor((rcrowt[0]+rcrowb[0])/2); -Nb=Nv-Nt-Nsyc-2*Nsy*divsy; -if (verbose > 1) { - write('#st t b: \t', Nyst, Nt, Nb); -} - -/* vertical lines - * (Nh-2*os)/2-Nsx/2 dots available for divisions of Nsx dots. - * At least 5 dots margin left and right ==> use -10*os - */ -real lsq, Nsx, rdistx; -int divsx, Nhc, Nl, Nr, cmaxi; - -lsq=Nsy*yd; -Nsx=lsq/xd; /* floating point */ -divsx=floor(((Nh-10*os)/Nsx-1)/2); -Nhc=round(Nh/2); -rdistx=(1+2*divsx)*Nsx; -Nl=Nhc-round(rdistx/2); -if (verbose > 1) { - write('#divsx Nsx l:\t', divsx, Nsx, Nl); -} -cmaxi=2*divsx+1; - -int[] coff, coffl, coffr; -int[] rccoll, rccolc, rccolr; -for (i=0; i<=divsx; ++i) { - int off, offl, offr, il, ir; - real cdist; - - cdist=Nsx*(1+2*i); /* horizontal distance 2 symmetrical vert lines */ - off=round(cdist/2); - // write(cdist, off); - offl=off-os; - offr=off+os; - - coff[i]=off; - coffl[i]=offl; - coffr[i]=offr; - - if (verbose > 1) { - write(cdist, off); - } - il=divsx-i; - ir=divsx+i+1; - - rccoll[il]=Nhc-offr; - rccolc[il]=Nhc-off; - rccolr[il]=Nhc-offl; - - rccoll[ir]=Nhc+offl; - rccolc[ir]=Nhc+off; - rccolr[ir]=Nhc+offr; -} -Nl=rccolc[0]; -Nr=Nh-rccolc[cmaxi]; -if (verbose > 1) { - write('#divsx Nsx l r:\t', divsx, Nsx, Nl, Nr); -} - -/**** draw gray background ****/ -{ - path zz; - - //zz=tvrect(0,0, Nh,Nv, xd,yd,Nv); - /* keep white canvas for castellations */ - zz=tvrect(rccoll[0],rcrowt[0], rccolr[cmaxi],rcrowb[rmaxi], xd,yd,Nv); - fill(zz, p=pdefault+gray(0.5)); - //dot(zz); -} -/**** draw center circle ****/ -real cx, cy, crad; -pair ccenter; -path ccirc; -cx=Nh/2; -cy=Nv/2-Nshift; -crad=6*Nsy; -if (Nv%2 != 0) { - crad+=0.5; -} -ccenter=tvps(cx,cy, xd,yd,Nv); -ccirc=circle(ccenter, crad*yd); -if (colortv<=0) { - draw(ccirc, p=pwhite+linewidth(2*yd)); -} - -/**** draw 2*divsy+2 horizontal gridlines ****/ -real[] rcang, rcoff; -pair[] rcright, rcleft; -int i; -for (i=0; i<=rmaxi; ++i) { - real y, ph, x; - path zzh; - pair zd; - - zzh=tvrect(0,rcrowt[i], Nh,rcrowb[i], xd,yd,Nv); - fill(zzh, p=pwhite); - - y=cy-rcrowc[i]; - if (abs(y)<crad) { - ph=asin(y/crad); - } else { - ph=pi/2; - } - rcang[i]=ph; - x=(crad*cos(ph))*yd/xd; - rcoff[i]=x; - zd=tvps(cx+x,cy-y, xd,yd,Nv); - rcright[i]=zd; - //dot(zd); - zd=tvps(cx-x,cy-y, xd,yd,Nv); - rcleft[i]=zd; -} - -/**** draw 2*divsx+2 vertical gridlines ****/ -for (i=0; i<=cmaxi; ++i) { - path zzv; - zzv=tvrect(rccoll[i],0, rccolr[i],Nv, xd,yd,Nv); - fill(zzv, p=pwhite); -} - -/**** castellations ****/ -castelhor(colortv, rccoll, rccolr, cmaxi, Nh, rcrowt[0], rcrowb[rmaxi], - pdefault, xd, yd, Nv); - -castelver(colortv, rccoll[0], rccolr[cmaxi], Nh, rcrowb, rcrowt, rmaxi, - pdefault, xd, yd, Nv); - -/****** markers for 4/3 aspect ratio ******/ -if (rimage>4/3) { - rimarkers(rimage, Nh, Nhc, os, Nvc, Nsy, pwhite, xd, yd, Nv); -} - -/****** line pairing center ******/ -centerline(colortv, rccoll, rccolc, rccolr, divsx, Nhc, os, - rcrowt, rcrowc, rcrowb, divsy, Nvc, - ccenter, rcoff, rcright, rcleft, pdefault, xd, yd, Nv); - -if (colortv>0) { - /* topbw structure */ - topbw(coff, Nhc, os, rcrowc[divsy-5], rcrowc[divsy-4], rcrowc[divsy-3], - ccenter, rcleft[divsy-4], rcleft[divsy-3], rcright[divsy-4], - rcright[divsy-3], pdefault, xd, yd, Nv); - - /* 250 kHz */ - testtone(Ttone, rcrowc[divsy-3], rcrowc[divsy-2], - cx, cy, crad, pdefault, xd, yd, Nv); - - /* color bars */ - colorbars(coff, Nhc, rcrowc[divsy-2], rcrowc[divsy-1], rcrowc[divsy], - ccenter, rcleft[divsy-2], rcleft[divsy], rcright[divsy-2], - rcright[divsy], pdefault, xd, yd, Nv); - - /* test frequencies */ - testfreqs(ftones, coff, Nhc, rcrowc[divsy+1], rcrowc[divsy+2], - rcrowc[divsy+3], ccenter, rcleft[divsy+1], rcleft[divsy+3], - rcright[divsy+1],rcright[divsy+3], pdefault, xd, yd, Nv); - - /* gray bars */ - graybars(coff, Nhc, rcrowc[divsy+3], rcrowc[divsy+4], ccenter, - rcleft[divsy+3], rcleft[divsy+4], - rcright[divsy+3], rcright[divsy+4], pdefault, xd,yd,Nv); - - /* PAL ears */ - if (colortv == 1) { - palears(coff,coffr,coffl, Nhc, rcrowt, rcrowb, Nvc, divsy, -1, - pdefault, xd, yd, Nv); - palears(coff,coffr,coffl, Nhc, rcrowt, rcrowb, Nvc, divsy, 1, - pdefault, xd, yd, Nv); - } else if (colortv == 2) { - ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, -1, - pdefault, xd, yd, Nv); - ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, 1, - pdefault, xd, yd, Nv); - ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, -2, - pdefault, xd, yd, Nv); - ntscbars(rccoll, rccolr, divsx, rcrowt, rcrowb, divsy, 2, - pdefault, xd, yd, Nv); - } - - /* bottom wh - black - wh */ - bottombw(round((coff[2]+coff[3])/2), Nhc, rcrowc[divsy+4], rcrowc[divsy+5], - ccenter, rcleft[divsy+4], rcleft[divsy+5], - rcright[divsy+4], rcright[divsy+5], pdefault, xd, yd, Nv); - - /* bottom yellow red circle */ - bottomcirc(coff[0], Nhc, rcrowc[divsy+5], cx, cy, crad, - ccenter, rcleft[divsy+5], rcright[divsy+5], pdefault, xd, yd, Nv); -} - -/********************** set id *********************/ -{ /* dpi */ - pair rpos=tvps(Nhc,round((rcrowc[divsy-4]+rcrowc[divsy-5])/2), xd,yd,Nv); - string iRhor, iRver, ires; - real Rh, Rv; - - Rh=Nh/xsize*inch; - Rv=Nv/ysize*inch; - iRhor=format("%.4gx", Rh); - iRver=format("%.4gdpi", Rv); - ires=insert(iRver,0, iRhor); - - /* size info */ - int rowbot=round((rcrowc[divsy+4]+rcrowc[divsy+5])/2); - pair tpos=tvps(Nhc,rowbot, xd,yd,Nv); - string ihor, iver, itot, iasp, ifm; - real asp, fm; - - ihor=format("%ix",Nh); - iver=format("%i ",Nv); - itot=insert(iver,0, ihor); - asp=xsize/ysize; - iasp=format("%.3g ",asp); - fm=fs/1e6; - ifm=format("%.4gMHz",fm); - itot=insert(iasp,0, itot); - itot=insert(ifm,0, itot); - - /* size of square */ - int rowNsy, colNsy; - pair Npos; - string iNsy; - pen pbw; - - rowNsy = round((rcrowc[divsy+5]+rcrowc[divsy+6])/2); - colNsy = round((rccolc[divsx+5]+rccolc[divsx+6])/2); - Npos = tvps(colNsy,rowNsy, xd,yd,Nv); - iNsy = format("%i", Nsy); - - if (colortv>0) { - pbw=pdefault+gray(1.0); - } else { - pbw=pdefault+gray(0.0); - } - label(ires, rpos, p=pbw); - label(itot, tpos, p=pbw); - label(iNsy, Npos, p=pbw); - if (verbose > 1) - write('#res:\t', ires, itot, iNsy); -} |