├── DotCrawlPlusPlus.avsi ├── LICENSE.md ├── README.md └── images └── .gitkeep /DotCrawlPlusPlus.avsi: -------------------------------------------------------------------------------- 1 | #avisynth 2 | 3 | ####################################### 4 | ## DotCrawl++ (Full analog effect powered with AviSynth+) 5 | # http://forum.doom9.org/showthread.php?t=170433 6 | #@ Original by: raffriff42, 2014-04-03 7 | #@ Mod by: RGM and contributors on GitHub, 2022 8 | ####################################### 9 | 10 | ## SEE ALSO: 11 | ## AVAA - A/V Artifact Alias 12 | ## http://www.avartifactatlas.com/ 13 | ## ScanLines 14 | ## http://avisynth.nl/index.php/Scanlines 15 | ## CRT emulation with scanline and phosphor effects - cretindesalpes 16 | ## http://forum.doom9.org/showthread.php?p=1683051 17 | 18 | /* 19 | http://www.doom9.org/index.html?/capture/chroma_artefacts.html 20 | 21 | Rainbow effects and dot crawls are caused by imperfect separation of the luma and 22 | chroma components of a composite video signal. This effect is called <> It is most noticeable on computer generated images like subtitles, 24 | weather maps, stationary logos and video images where you have hi-frequency data 25 | (like the shot of a skyscraper in the distance). 26 | 27 | Whenever you have strong alternating, fine patterns (= high frequencies) in luma, 28 | you have <>. Whenever you have a sudden, big change in chroma 29 | (typically computer generated graphics etc.), you have <>. 30 | 31 | The technical terms are as follows: 32 | "rainbow" is cross color (hi-frequency luma data upsets the chroma demodulator) 33 | "dot crawl" is cross luminance (chroma leftovers in the Y signal). 34 | 35 | */ 36 | 37 | 38 | ## PLUGINS: 39 | 40 | ## MaskTools 41 | # https://github.com/pinterf/masktools/releases/ 42 | 43 | ## AddGrainC 44 | # https://github.com/pinterf/AddGrainC/releases 45 | 46 | ## FFT3DFilter 47 | # https://github.com/pinterf/fft3dfilter/releases 48 | 49 | ## GRunT 50 | # https://github.com/pinterf/GRunT/releases 51 | 52 | ## TEMmod 53 | # https://github.com/Asd-g/TEMmod/releases 54 | 55 | ### TABLE OF CONTENTS ### 56 | #-------------- 57 | #@function dcpp_preset(clip C, string "preset", 58 | ##\ float "dots", float "rainbow", 59 | ##\ bool "showpreset", bool "showargs", float "threads") 60 | #-------------- 61 | #@function dotcrawlplusplus(clip C, int "dotstyle", 62 | ##\ float "dotblend", float "dotscale", int "dotleak", 63 | ##\ int "csub", float "cblur", float "lblur", 64 | ##\ int "lnoise", int "cnoise", float "streaking", 65 | ##\ float "rainbow", bool "showargs", float "threads") 66 | #-------------- 67 | #@function dcpp_makedotcrawl(clip T, int "size") 68 | #@function dcpp_makedots(clip T, float "offset", int "size") 69 | #@function dcpp_makerainbow(clip C, float "chroma") 70 | #@function dcpp_uumidpass(clip C, 71 | ##\ int "tlo", int "thi", bool "setupmode") 72 | #@function dcpp_uuhipass(clip C, int "tlo", int "thi", bool "setupmode") 73 | #@function dcpp_histostretch(clip C, 74 | ##\ float "thresh_lo", float "thresh_hi", float "gamma", bool "show") 75 | #@function stack_to_size(clip C, int wid, int hgt) 76 | #@function stack_to_wid(clip C, int wid, clip "R") 77 | #@function stack_to_hgt(clip C, int hgt, clip "R") 78 | #@function convert_to_Y8(clip C) 79 | #@function convert_to_YV24(clip C) 80 | #-------------- 81 | #@function StrReplace(string base, string findstr, string repstr) 82 | #@function f2cuv(float f) 83 | #@function _uumod(int m, float f, bool "z") 84 | #@function StrinF(float f) 85 | #@function UUGaussianBlurYV12(clip C, float "varY", float "varC", 86 | ##\ float "radY", float "radC", 87 | ##\ string "show") 88 | #@function UUGaussianBlurY(clip C, float "var", float "rad") 89 | #@function UUSize2(clip C, int wid, int hgt) 90 | #-------------- 91 | #@function gridmask_square(clip C, int size) 92 | #@function gridmask_diag(clip C, int size) 93 | #-------------- 94 | 95 | ####################################### 96 | ### emulate NTSC dot crawl & analog video cassette recorder noise 97 | ## 98 | ## @ preset - choices: 99 | ## "mild" - minimal effect 100 | ## "medium" - softer chroma; a little added noise 101 | ## "heavy" - very soft & noisy 102 | ## "strong" - like medium but more so 103 | ## "bigdot1" - larger dots #1 104 | ## "bigdot2" - larger dots #2 105 | ## "bigdot3" - larger dots #3 106 | ## "betacam" - Analog formats - Betacam 107 | ## empty string ("") defaults to "medium"; 108 | ## unrecognized values raise an error. 109 | ## @ dots - dotcrawl effect amount 110 | ## (default depends on preset) 111 | ## @ rainbow - rainbow effect amount 112 | ## (default depends on preset) 113 | ## @ rb_strength - rainbow effect mask strength 114 | ## (default 40) 115 | ## @ cblur - chroma blur amount 116 | ## (default depends on preset) 117 | ## @ lblur - luma blur amount 118 | ## (default depends on preset) 119 | ## @ emode - edge mask mode 120 | ## (default 2) 121 | ## @ showpreset - if true, show the preset name as a Subtitle 122 | ## (default false) 123 | ## @ showargs - if true, show the arguments as a Subtitle 124 | ## (default false) 125 | ## @ threads - cpu threads you want to use 126 | ## (default 4) 127 | ## 128 | function dcpp_preset(clip C, string "preset", 129 | \ float "dots", float "rainbow", int "rb_strength", float "cblur", float "lblur", 130 | \ int "emode", bool "showpreset", bool "showargs", float "threads") 131 | { 132 | preset = Default(preset, "") 133 | dots = Default(dots, 134 | \ (preset=="bigdot3") ? 0.7 135 | \ : (preset=="bigdot2") ? 0.7 136 | \ : (preset=="bigdot1") ? 0.7 137 | \ : (preset=="betacam") ? 1.0 138 | \ : (preset=="heavy") ? 1.0 139 | \ : (preset=="strong") ? 1.0 140 | \ : (preset=="mild") ? 0.7 141 | \ : 0.7) 142 | dots = Float(Min(Max(0, dots), 1)) 143 | rainbow = Default(rainbow, 144 | \ (preset=="bigdot3") ? 0.3 145 | \ : (preset=="bigdot2") ? 0.3 146 | \ : (preset=="bigdot1") ? 0.3 147 | \ : (preset=="betacam") ? 0.2 148 | \ : (preset=="heavy") ? 1.0 149 | \ : (preset=="strong") ? 0.6 150 | \ : (preset=="mild") ? 0.3 151 | \ : 0.4) 152 | rb = Float(Min(Max(0, rainbow), 1)) 153 | cblur = Default(cblur, 154 | \ (preset=="bigdot3") ? 0.0 155 | \ : (preset=="bigdot2") ? 0.0 156 | \ : (preset=="bigdot1") ? 0.0 157 | \ : (preset=="betacam") ? 0.2 158 | \ : (preset=="heavy") ? 1.0 159 | \ : (preset=="strong") ? 0.5 160 | \ : (preset=="mild") ? 0.0 161 | \ : 0.0) 162 | cblur = Float(Min(Max(0, cblur), 1.5)) 163 | lblur = Default(lblur, 164 | \ (preset=="bigdot3") ? 0.0 165 | \ : (preset=="bigdot2") ? 0.0 166 | \ : (preset=="bigdot1") ? 0.0 167 | \ : (preset=="betacam") ? 0.4 168 | \ : (preset=="heavy") ? 0.5 169 | \ : (preset=="strong") ? 0.0 170 | \ : (preset=="mild") ? 0.0 171 | \ : 0.0) 172 | lblur = Float(Min(Max(0, lblur), 1.5)) 173 | emode = Int(Min(Max(0, Default(emode, 2)), 5)) 174 | rb_strength = Int(Min(Max(0, Default(rb_strength, 40)), 50)) 175 | showpreset = Default(showpreset, false) 176 | showargs = Default(showargs, false) 177 | threads = Default(threads, 4) 178 | 179 | C ## Last 180 | R = (preset=="bigdot3") 181 | \ ? dotcrawlplusplus(dotstyle=2, 182 | \ dotblend=dots, dotscale=3, dotleak=0, 183 | \ csub=1, cblur=cblur, lblur=lblur, 184 | \ lnoise=0, cnoise=0, emode=emode, streaking=0, 185 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 186 | \ : (preset=="bigdot2") 187 | \ ? dotcrawlplusplus(dotstyle=2, 188 | \ dotblend=dots, dotscale=2, dotleak=0, 189 | \ csub=1, cblur=cblur, lblur=lblur, 190 | \ lnoise=0, cnoise=0, emode=emode, streaking=0, 191 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 192 | \ : (preset=="bigdot1") 193 | \ ? dotcrawlplusplus(dotstyle=2, 194 | \ dotblend=dots, dotscale=1.5, dotleak=0, 195 | \ csub=1, cblur=cblur, lblur=lblur, 196 | \ lnoise=0, cnoise=0, emode=emode, streaking=0, 197 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 198 | \ : (preset=="betacam") 199 | \ ? dotcrawlplusplus(dotstyle=0, 200 | \ dotblend=dots, dotscale=1, dotleak=0, 201 | \ csub=3, cblur=cblur, lblur=lblur, 202 | \ lnoise=2, cnoise=2, emode=emode, streaking=0, 203 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 204 | \ : (preset=="heavy") 205 | \ ? dotcrawlplusplus(dotstyle=0, 206 | \ dotblend=dots, dotscale=2, dotleak=32, 207 | \ csub=4, cblur=cblur, lblur=lblur, 208 | \ lnoise=22, cnoise=32, emode=emode, streaking=1, 209 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 210 | \ : (preset=="strong") 211 | \ ? dotcrawlplusplus(dotstyle=1, 212 | \ dotblend=dots, dotscale=1.5, dotleak=24, 213 | \ csub=4, cblur=cblur, lblur=lblur, 214 | \ lnoise=4, cnoise=4, emode=emode, streaking=0, 215 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 216 | \ : (preset=="mild") 217 | \ ? dotcrawlplusplus(dotstyle=0, 218 | \ dotblend=dots, dotscale=1, dotleak=0, 219 | \ csub=1, cblur=cblur, lblur=lblur, 220 | \ lnoise=0, cnoise=0, emode=emode, streaking=0, 221 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 222 | \ : (preset=="medium" || preset=="") 223 | \ ? dotcrawlplusplus(dotstyle=0, 224 | \ dotblend=dots, dotscale=1, dotleak=0, 225 | \ csub=2, cblur=cblur, lblur=lblur, 226 | \ lnoise=2, cnoise=4, emode=emode, streaking=0, 227 | \ rainbow=rb, rb_strength=rb_strength, showargs=showargs, threads=threads) 228 | \ : Assert(false, "dotcrawlplusplus: unrecognized preset") 229 | 230 | return (showpreset==false) ? R 231 | \ : R.Subtitle(preset, x=-1, y=Round(0.7*C.Height), 232 | \ size=C.Height/8, text_color=$66c0c0c0, halo_color=$66000000) 233 | } 234 | 235 | ####################################### 236 | ### emulate NTSC dot crawl & analog video cassette recorder noise 237 | ## 238 | ## @ dotstyle - dots style (0..2; default 0) 239 | ## @ dotblend - dots opacity (default 1.0) 240 | ## @ dotscale - scale of dot crawl (1..4; default 1; >2 is ugly) 241 | ## @ dotleak - allow some dot crawl everywhere 242 | ## (0-255; default 0; 32 is just visble; >64 is extreme) 243 | ## @ csub - default 2 (1=betacam; 2=VHS) 244 | ## @ cblur - default 0.3 (0.0=no added blur; 0.5=VHS) 245 | ## @ lblur - default 0.3 246 | ## @ lnoise - default 4 (0=bypass; 2=subliminal; 22-33=VHS) 247 | ## @ cnoise - default 4 (0=bypass; 2=subliminal; 33=VHS) 248 | ## @ emode - edge mask mode 249 | ## (default 2, mt_edge modes) 250 | ## @ streaking - default 0.0 (1.0=extreme horizontal streaking) 251 | ## @ rainbow - rainbow effect opacity (default 0.2) 252 | ## @ rb_strength - rainbow effect mask strength (default 40) 253 | ## @ showargs - if true, show the arguments as a Subtitle 254 | ## @ threads - cpu threads you want to use (default 4) 255 | ## 256 | ## @version 1.3 05-Apr-2014 raffriff42 (compatible w/ AVS 2.58) 257 | ## @version 1.4 06-Apr-2014 raffriff42 (rainbow) 258 | ## @version 2.0 09-Apr-2014 raffriff42 (internal dot generator) 259 | ## @version 2.1 12-Apr-2014 raffriff42 (improved rainbow) 260 | ## 261 | function dotcrawlplusplus(clip C, int "dotstyle", 262 | \ float "dotblend", float "dotscale", int "dotleak", 263 | \ int "csub", float "cblur", float "lblur", 264 | \ int "lnoise", int "cnoise", int "emode", float "streaking", 265 | \ float "rainbow", int "rb_strength", bool "showargs", float "threads") 266 | { 267 | Assert(IsClip(C) && (IsYV12(C) || Is444(C)), 268 | \ "dotcrawlplusplus: clip 'C' must be YV12 or YV24") 269 | Assert((C.Width % 8)==0 && (C.Height % 8)==0, 270 | \ "dotcrawlplusplus: clip 'C' resolution is not mod-8") 271 | 272 | dotstyle = Min(Max(0, Default(dotstyle, 0)), 2) 273 | dotblend = Float(Min(Max(0, Default(dotblend, 1)), 1)) 274 | dotleak = Min(Max(0, Default(dotleak, 0)), 255) 275 | dotscale = Float(Min(Max(1, Default(dotscale, 1)), 4)) 276 | csub = Min(Max(1, Default(csub, 2)), 4) 277 | cblur = Float(Min(Max(0, Default(cblur, 0.3)), 1.5)) 278 | lblur = Float(Min(Max(0, Default(lblur, 0.3)), 1.5)) 279 | lnoise = Min(Max(0, Default(lnoise, 4)), 64) 280 | cnoise = Min(Max(0, Default(cnoise, 4)), 64) 281 | emode = Min(Max(0, Default(emode, 2)), 5) 282 | streaking = Float(Min(Max(0, Default(streaking, 0)), 1)) 283 | rainbow = Float(Min(Max(0, Default(rainbow, 0.2)), 1)) 284 | rb_strength = Int(Min(Max(0, Default(rb_strength, 17)), 50)) 285 | showargs = Default(showargs, false) 286 | threads = Default(threads, 4) 287 | 288 | C = (showargs==false) ? C : C.Subtitle( 289 | \ " dotblend=" + StrinF(dotblend) 290 | \ + "\n dotleak=" + String(dotleak) 291 | \ + "\n dotscale=" + StrinF(dotscale) 292 | \ + "\n csub=" + String(csub) 293 | \ + "\n cblur=" + StrinF(cblur) 294 | \ + "\n lblur=" + StrinF(lblur) 295 | \ + "\n lnoise=" + String(lnoise) 296 | \ + "\n cnoise=" + String(cnoise) 297 | \ + "\n emode=" + String(emode) 298 | \ + "\n streaking=" + StrinF(streaking) 299 | \ + "\n rainbow=" + StrinF(rainbow) 300 | \ + "\n rb_strength=" + String(rb_strength) , 301 | \ lsp=0, align=4, x=-1, y=-1, 302 | \ text_color=$ccffffff, halo_color=$cc000000) 303 | 304 | if(threads>0){ 305 | SetFilterMTMode("DEFAULT_MT_MODE", 2) 306 | } 307 | 308 | if(C.BitsPerComponent != 8){ 309 | C = C.ConvertBits(8) 310 | } 311 | 312 | ## soften & add noise ######################## 313 | C ## Last 314 | Tweak(hue=33) ## IQ translation: I to V, Q to U 315 | 316 | ## US, VS : U & V, subsampled 317 | 318 | sh = Min(0.8 * csub / 2.0, streaking) 319 | sv = (0.125 * csub / 2.0) 320 | US = UtoY.BilinearResize(_uumod(2, 0.5*Width/csub), Height/csub) 321 | \ .AddGrainC(cnoise, hcorr=sh, vcorr=sv) 322 | VS = VtoY.BilinearResize(_uumod(2, 1.0*Width/csub), Height/csub) 323 | \ .AddGrainC(cnoise, hcorr=sh, vcorr=sv) 324 | Y = Grayscale 325 | \ .AddGrainC(lnoise, hcorr=0.25, vcorr=0.125) 326 | \ .convert_to_Y8() 327 | 328 | US = (cblur<0.01) ? US : US.Blur(cblur,0) 329 | VS = (cblur<0.01) ? VS : VS.Blur(cblur,0) 330 | Y = (lblur<0.01) ? Y : Y.Blur(lblur,0) 331 | 332 | US = US.BilinearResize(Width/2, Height/2) 333 | VS = VS.BilinearResize(Width/2, Height/2) 334 | #return US.Grayscale() 335 | 336 | ## chroma transition edge masks ############## 337 | 338 | mdots2 = (dotscale>2) 339 | 340 | #emode="laplace" ## (least sensitive) 341 | #emode="roberts" 342 | #emode="cartoon" 343 | #emode="sobel" 344 | #emode="min/max" 345 | #emode="prewitt" ## (most sensitive) 346 | 347 | emode = (emode==1) ? "roberts" 348 | \ : (emode==2) ? "cartoon" 349 | \ : (emode==3) ? "sobel" 350 | \ : (emode==4) ? "min/max" 351 | \ : (emode==5) ? "prewitt" 352 | \ : "laplace" 353 | 354 | ## 'EU' = 'edge mask, U channel' 355 | EU = US.mt_edge(mode=emode).convert_to_Y8() 356 | 357 | ## 'EV' = 'edge mask, V channel' 358 | EV = VS.mt_edge(mode=emode).convert_to_Y8() 359 | 360 | EU2 = (mdots2==false) ? EU 361 | \ : EU.mt_expand.mt_expand.Blur(1.0) 362 | EV2 = (mdots2==false) ? EV 363 | \ : EV.mt_expand.mt_expand.Blur(1.0) 364 | #return StackHorizontal(StackVertical(EU,EU2),StackVertical(EV,EV2)).Grayscale() 365 | 366 | ## 'EC' = 'edge mask, color' 367 | EC = mt_logic(EU2, EV2, "max") 368 | EC = (dotleak==0) ? EC 369 | \ : EC.Levels(32, 1.0, 235, dotleak, 255, coring=false) 370 | EC = EC.BilinearResize(Width, Height) 371 | #return EC.Grayscale() 372 | 373 | YToUV(US, VS, Y) 374 | Tweak(hue=-33) ## reverse IQ translation above 375 | 376 | ## dot crawl ################################# 377 | 378 | dotcrawl = dcpp_makedotcrawl(2) 379 | dotcrawl = (Abs(1.0-dotscale)<0.3) ? dotcrawl 380 | \ : dotcrawl.BilinearResize( 381 | \ _uumod(2, dotscale*dotcrawl.Width), 382 | \ _uumod(2, dotscale*dotcrawl.Height)) 383 | dotcrawl = dotcrawl.UUSize2(EC.Width, EC.Height) 384 | #return dotcrawl 385 | dotmask = EC.mt_logic(dotcrawl, "min") 386 | #dotmask = EC.TEMmod() 387 | #return dotmask.Grayscale() 388 | 389 | #return dotmask 390 | 391 | dotoffset = ((dotscale>1.5) ? 2 : 1) 392 | dotmode = (dotstyle==0) ? "add" : "blend" 393 | 394 | dotclip = (dotstyle==1) ? Overlay(Last, x=dotoffset, y=dotoffset) 395 | \ : (dotstyle==2) ? Overlay(Tweak(bright=20, sat=0.5), x=1, y=1) 396 | \ : last 397 | 398 | Overlay(dotclip, mask=dotmask, mode=dotmode, opacity=(dotblend*0.1)) 399 | 400 | ## rainbow ################################### 401 | 402 | ## 'RC' = 'Rainbow Clip' 403 | RC = dcpp_makerainbow() 404 | 405 | ## 'RM' = 'Rainbow Mask' 406 | RM = dcpp_uumidpass(rb_strength=rb_strength) 407 | #RM = (csub<2) ? RM : RM.mt_expand().Blur(1) 408 | #RM = RM.Levels(0, 0.2, 220, 0, 255, coring=false).Grayscale() 409 | 410 | ## 'RY' = 'Rainbow Luma' 411 | ## (without it, rainbow is missing @ white areas) 412 | RY = RC.ConvertToRGB32().ShowGreen("YV12") 413 | #return RC 414 | #return RM 415 | 416 | ## final assembly ############################ 417 | 418 | showmask = false 419 | return (showmask) ? C.Overlay(dotmask.GrayScale(), opacity=0.5) 420 | \ : (rainbow<0.01) ? Last 421 | \ : Last.Overlay(RC, mask=RM, mode="chroma", opacity=rainbow) 422 | \ .Overlay(RY, mask=RM, mode="luma", opacity=Min(0.4*rainbow, 0.1)) 423 | 424 | if(threads>0){ 425 | Prefetch(threads) 426 | } 427 | } 428 | 429 | ################################## 430 | ### generate a moving dot crawl 431 | ## 432 | ## @ C - "template" clip (size, frame rate etc) minimum size 512x512 433 | ## @ size - 1-4 (default 2) 434 | ## 435 | ## @ returns moving dots clip 436 | ## 437 | function dcpp_makedotcrawl(clip T, int "size") 438 | { 439 | size = Default(size, 2) 440 | size = (size==1) ? 2 441 | \ : (size==2) ? 3 442 | \ : (size==3) ? 4 443 | \ : (size==4) ? 5 444 | \ : Assert(false, "dcpp_makedotcrawl: invalid 'size' argument") 445 | 446 | T ## Last 447 | Crop(0, 0, 448 | \ _uumod(8, Min(Height, size*4), false), 449 | \ _uumod(8, Min(Width, size*4), false)) 450 | global gdots00 = dcpp_makedots(0.00, size) 451 | global gdots25 = dcpp_makedots(0.25, size) 452 | global gdots50 = dcpp_makedots(0.50, size) 453 | global gdots75 = dcpp_makedots(0.75, size) 454 | 455 | ## slow crawl (min size=2) 456 | GScriptClip(Last.ConvertToYV24(), """ 457 | ConditionalSelect(Last, "current_frame % 4", 458 | \ gdots00, gdots25, gdots50, gdots75) 459 | """) 460 | 461 | #SeparateFields.SelectEvery(2, 1).AssumeFrameBased() 462 | #SeparateFields.SelectEvery(2, 1).AssumeFrameBased() 463 | #Crop(0, 0, Height*2, 0) 464 | #Spline16Resize(Width/2, Height) 465 | 466 | size = (size==2) ? 2 467 | \ : (size==3) ? 4 468 | \ : (size==4) ? 8 469 | \ : (size==5) ? 16 470 | \ : 1 471 | Crop(0, 0, 472 | \ (Width<=size)?0:(-Width % size), 473 | \ (Height<=size)?0:(-Height % size)) 474 | 475 | stack_to_size(T.Width, T.Height) 476 | return Last 477 | } 478 | 479 | ################################## 480 | ### generate a dot pattern 481 | ## 482 | ## @ C - "template" clip (size, frame rate etc) 483 | ## @ offset - 0 to 1 484 | ## @ size - 1-5 (default 2) 485 | ## 486 | function dcpp_makedots(clip T, float "offset", int "size") 487 | { 488 | Assert(IsClip(T) && HasVideo(T), 489 | \ "dcpp_makedots: clip 'T' invalid") 490 | 491 | offset = Float(Min(Max(0, Default(offset, 0)), 1)) 492 | size = Default(size, 2) 493 | size = (size==1) ? 1 494 | \ : (size==2) ? 2 495 | \ : (size==3) ? 4 496 | \ : (size==4) ? 8 497 | \ : (size==5) ? 16 498 | \ : Assert(false, "dcpp_makedots: invalid 'size' argument") 499 | off_i = Round(offset * 2.0 * size) 500 | 501 | T = T.ConvertToYV12().Loop() 502 | #R = mt_logic( 503 | #\ mt_lutspa(T, mode="absolute", chroma="-128", 504 | #\ expr=("""((((y/(2*$s))%2)>0) ? cos((x/$s)*pi) : -1*(cos((x/$s)*pi)))*108+126""") 505 | #\ .StrReplace("$s", String(size)).mt_polish), 506 | #\ mt_lutspa(T, mode="absolute", chroma="-128", 507 | #\ expr=("cos((y/$s)*pi)*108+126") 508 | #\ .StrReplace("$s", String(size)).mt_polish), 509 | #\ "andn") 510 | R = mt_lutspa(T, mode="absolute", chroma="-128", expr=("x 4 % 2 < 0 1 ? y 4 % 2 < 0 1 ? + 1 == 0 255 ?")) 511 | 512 | R = R.ConvertToYV24() 513 | R = (off_i==0) ? R 514 | \ : StackHorizontal( 515 | \ R.Crop(0, 0, -R.Width % size, 0), 516 | \ R) 517 | R = ((R.Width-off_i) 0 255 x "+LO+" - 255 "+HI+" "+LO+" - / * - ? ?" : \ 544 | "x "+LO+" < 0 x "+HI+" > 255 0 x "+LO+" - 255 "+LO+" "+HI+" - / * - ? ?" 545 | 546 | msk = raw.mt_lut(code,u=-128,v=-128) 547 | 548 | show ? msk : mt_merge(raw, filtered, msk, luma=true, U=3,V=3)} 549 | 550 | ################################## 551 | ### create halos 552 | ## 553 | ## PS.: Uses dcpp_halo_lumamask 554 | ## 555 | ## @ bright_halo - bright halo intensity (default 0.4) 556 | ## @ dark_halo - dark halo intensity (default 0.5) 557 | ## 558 | function dcpp_halo(clip C, float "bright_halo", float "dark_halo"){ 559 | 560 | bright_halo_value = Default(bright_halo, .4) 561 | dark_halo_value = Default(dark_halo, .5) 562 | 563 | C 564 | 565 | a=last 566 | halo_b_mask=last.TEMmod(threshY=17).mt_expand.mt_expand.mt_expand #mask for bright halos 567 | halo_d_mask=last.TEMmod(threshY=17).mt_expand #mask for dark halos 568 | halo_bright3=dcpp_halo_lumamask(a,a,b=170,w=230, show=true).levels(0,1,50,0,255,false).mt_expand(u=-128,v=-128).mt_binarize() #luma mask to remove later 569 | halo_dark3=dcpp_halo_lumamask(a,a,b=0,w=65, show=true, upper=true).mt_inflate().mt_binarize(40) 570 | #b=overlay(b,bright3,mode="subtract") #remove bright sections from bright halos 571 | halo_d=overlay(halo_b_mask,halo_d_mask,mode="subtract").mt_deflate() #hollow out mask for dark halos by subtracting area for brights 572 | #d=overlay(d,bright3,mode="subtract") #remove bright sections from dark halo mask 573 | halo_d=overlay(halo_d,halo_dark3,mode="subtract") #REMOVE DARK SECTIONS FROM DARK MASK 574 | #b=overlay(b,dark3,mode="subtract") #REMOVE DARK SECTIONS FROM BRIGHT MASK 575 | dark_halo=generalconvolution(matrix="0 0 0 0 1 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 2 0 0 0 0 1 -1 3 2 1 2 -3 -1 1 0 0 0 0 2 0 0 0 0 0 0 0 0 -2 0 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 1 0 0 0 0",chroma=false) 576 | bright_halo=generalconvolution(matrix="0 0 -2 0 0 0 0 2 0 0 -2 2 1 2 -2 0 0 2 0 0 0 0 -2 0 0",chroma=false) 577 | overlay(last,bright_halo,mask=halo_b_mask,opacity=bright_halo_value) #FINAL BRIGHT HALO STRENGTH 578 | overlay(last,dark_halo,mask=halo_d,opacity=dark_halo_value) #FINAL DARK HALO STRENGTH 579 | 580 | } 581 | 582 | ################################## 583 | ### generate a rainbow pattern 584 | ## 585 | ## @ sat - chroma intensity (default 1.0) 586 | ## @ xluma - ratio of clip cross-luma to fixed pattern (0..1; default 0.75) 587 | ## 588 | function dcpp_makerainbow(clip C, float "sat") 589 | { 590 | sat = Float(Default(sat, 1)) 591 | #xluma = Float(Min(Max(0, Default(xluma, 0.75)), 1)) 592 | 593 | color_sat = int(50000*sat) 594 | 595 | /*Y = C.ConvertToY8() 596 | YB = Y.UUGaussianBlurYV12(radY=3).ConvertToY8() 597 | YH = Y.Subtract(YB) 598 | \ .mt_lut(("(x<$lo)?($lo):((x>$hi)?($hi):(x))") 599 | \ .StrReplace("$lo", String(128-8)) 600 | \ .StrReplace("$hi", String(128+8)) 601 | \ .mt_polish()) 602 | \ .ConvertToRGB32() 603 | 604 | H1 = YH.GeneralConvolution(128, """ 605 | 2 0 0 606 | 0 0 0 607 | 0 0 -2 """).ConvertToYV12() 608 | H2 = YH.GeneralConvolution(128, """ 609 | -2 0 0 610 | 0 0 0 611 | 0 0 2 """).ConvertToYV12() 612 | 613 | slh = ("x 1 $o - * y $o * + ").StrReplace("$o", String(xluma)) 614 | 615 | U = mt_lutspa(C, mode="absolute", 616 | \ expr="x 64 / y -32 / + pi * cos -48 * 126 + ", chroma="-128") 617 | U = mt_lutxy(U, H1, slh, U=-128, V=-128) 618 | 619 | V = mt_lutspa(C, mode="absolute", 620 | \ expr="x 72 / y -36 / + pi * sin 64 * 126 + ", chroma="-128") 621 | V = mt_lutxy(V, H2, slh, U=-128, V=-128) 622 | 623 | return YToUV(U, V, Y).ConvertToYV12() 624 | \ .ColorYUV(cont_y=f2cuv(0), cont_u=f2cuv(sat), cont_v=f2cuv(sat))*/ 625 | 626 | C 627 | #AddGrain(0,1,0.4,50000,seed=1) 628 | AddGrainC(var=0,uvar=color_sat,hcorr=.9,vcorr=.4,seed=1) 629 | #blur(0,1.5).blur(0,1.5).blur(0,1.5) 630 | #\ .Crop(0, 0, -256, 0).Histogram(mode="levels") 631 | } 632 | 633 | ################################## 634 | ### "mid pass" 635 | function dcpp_uumidpass( 636 | \ clip C, int "rb_strength", int "tlo", int "thi", bool "setupmode") 637 | { 638 | rb_strength = Default(rb_strength, 40) 639 | tlo = Default(tlo, 128) 640 | thi = Default(thi, 148) 641 | setupmode = Default(setupmode, false) 642 | 643 | /*CG = C.Grayscale() 644 | Last = CG 645 | Blur(1, 1) 646 | FFT3DFilter(bt=1, bw=64, bh=64, ow=32, oh=32, 647 | \ sigma=0, sigma2=0, sigma3=500, sigma4=100000) 648 | Subtract(UUGaussianBlurY(rad=1)) 649 | mt_expand() 650 | Grayscale() 651 | return (setupmode) 652 | \ ? dcpp_histostretch(50.0, 0.01, 1.8, true) 653 | \ : Levels(tlo, 1.8, thi, 0, 255, coring=false)*/ 654 | 655 | C 656 | #TEMmod(threshY=12) 657 | 658 | b=C.TEMmod(threshY=rb_strength).mt_expand 659 | 660 | btopleft=BilinearResize(b,width,height,src_top=1,src_left=.5).invert() 661 | diag=overlay(b,btopleft,mode="subtract") 662 | btopright=BilinearResize(b,width,height,src_top=-1,src_left=-.5).invert() 663 | diag=overlay(diag,btopright,mode="subtract") 664 | btop=BilinearResize(b,width,height,src_top=-2).invert() 665 | diag=overlay(diag,btop,mode="subtract") 666 | btop=BilinearResize(b,width,height,src_top=2).invert() 667 | diag=overlay(diag,btop,mode="subtract") 668 | bleft=BilinearResize(b,width,height,src_left=-2).invert() 669 | diag=overlay(diag,bleft,mode="subtract") 670 | bleft=BilinearResize(b,width,height,src_left=2).invert() 671 | diag=overlay(diag,bleft,mode="subtract").mt_deflate().mt_deflate().mt_expand().mt_expand() 672 | diag 673 | 674 | #mask = maskhs(starthue=160,endhue=180,maxsat=100,minsat=50,coring=false).ConvertToYV12().mt_expand().BilinearResize(last.width, last.height) 675 | #mask 676 | } 677 | 678 | ################################## 679 | ### DEAD 680 | function dcpp_uuhipass(clip C, int "tlo", int "thi", bool "setupmode") 681 | { 682 | tlo = Default(tlo, 128) 683 | thi = Default(thi, 255) 684 | setupmode = Default(setupmode, false) 685 | 686 | Last = C.UUHipass(unblur=0.1, sharp=0.5, cont=1, gray=true, show="") 687 | mt_expand() 688 | Grayscale() 689 | return (setupmode) 690 | \ ? dcpp_histostretch(50.0, 0.01, 1.8, true) 691 | \ : Levels(tlo, 1.8, thi, 0, 255, coring=false) 692 | } 693 | 694 | ################################## 695 | ### auto dynamic histogram stretch 696 | function dcpp_histostretch( 697 | \ clip C, float "thresh_lo", float "thresh_hi", float "gamma", bool "show") 698 | { 699 | thresh_lo = Float(Default(thresh_lo, 0)) 700 | thresh_hi = Float(Default(thresh_hi, 0)) 701 | gamma = Float(Default(gamma, 1)) 702 | show = Default(show, false) 703 | 704 | return (show==false) 705 | \ ? GScriptClip(C, (""" 706 | \ lo=YPlaneMin($tlo) 707 | \ hi=YPlaneMax($thi) 708 | \ Levels(lo, $gam, hi, 0, 255, coring=false) 709 | \ """) 710 | \ .StrReplace("$tlo", String(thresh_lo)) 711 | \ .StrReplace("$thi", String(thresh_hi)) 712 | \ .StrReplace("$gam", String(gamma)) 713 | \ ) 714 | \ : GScriptClip(C, (""" 715 | \ lo=YPlaneMin($tlo) 716 | \ hi=YPlaneMax($thi) 717 | \ hgt=Height/16 718 | \ Levels(lo, $gam, hi, 0, 255, coring=false) 719 | \ Subtitle("lo($tlo)="+String(lo)+"\nhi($thi)="+String(hi), 720 | \ size=hgt, text_color=$808080, x=-1, y=hgt, lsp=2*hgt) 721 | \ """) 722 | \ .StrReplace("$tlo", String(thresh_lo, "%0.2f")) 723 | \ .StrReplace("$thi", String(thresh_hi, "%0.2f")) 724 | \ .StrReplace("$gam", String(gamma)) 725 | \ ) 726 | } 727 | 728 | ############################## 729 | ## Stack clip 'C' until it is at least 'wid' wide 730 | function stack_to_size(clip C, int wid, int hgt) { 731 | C ## Last 732 | stack_to_wid(wid) 733 | stack_to_hgt(hgt) 734 | Crop(0, 0, wid, hgt) 735 | return Last 736 | } 737 | 738 | ############################## 739 | ## Stack clip 'C' horizontally until it is at least 'wid' wide 740 | function stack_to_wid(clip C, int wid, clip "R") { 741 | R = Default(R, C) 742 | return (R.Width >= wid) ? R 743 | \ : stack_to_wid(C, wid, StackHorizontal(R, C)) 744 | } 745 | 746 | ############################## 747 | ## Stack clip 'C' vertically until it is at least 'hgt' high 748 | function stack_to_hgt(clip C, int hgt, clip "R") { 749 | R = Default(R, C) 750 | return (R.Height >= hgt) ? R 751 | \ : stack_to_hgt(C, hgt, StackVertical(R, C)) 752 | } 753 | 754 | ################################## 755 | function convert_to_Y8(clip C) { 756 | ## hackish workaround for avs 2.58 757 | ## for use within this script only 758 | try { 759 | return C.ConvertToY8() 760 | } catch (e) { 761 | return C.ConvertToYV12().Tweak(sat=0) 762 | } 763 | } 764 | 765 | ################################## 766 | function convert_to_YV24(clip C) { 767 | ## hackish workaround for avs 2.58 768 | ## for use within this script only 769 | try { 770 | return C.ConvertToYV24() 771 | } catch (e) { 772 | return C.ConvertToRGB24() 773 | } 774 | } 775 | 776 | /*__END__*/ 777 | #################### library routines: #################### 778 | 779 | # http://avisynth.nl/index.php/HDColorBars 780 | ################################## 781 | ## 782 | function StrReplace(string base, string findstr, string repstr) 783 | { 784 | pos = FindStr(base, findstr) 785 | return (StrLen(findstr)==0) || (pos==0) 786 | \ ? base 787 | \ : StrReplace( 788 | \ LeftStr(base, pos-1) + repstr + 789 | \ MidStr(base, pos+StrLen(findstr)), 790 | \ findstr, repstr) 791 | } 792 | 793 | ####################################### 794 | ### transform "normal" float arguments to 795 | ### ColorYUV's "gain_x", "gamma_x" & "cont_x" scale 796 | ## 797 | function f2cuv(float f) { 798 | return Round((f - 1.0) * 256.0) 799 | } 800 | 801 | ################################## 802 | ## return argument 'f' as integer and ensure it is Mod 'm' 803 | ## 804 | ## @ m - mod value 805 | ## @ f - input (may be positive or negative) 806 | ## @ z - always mod towards zero after rounding (default true) 807 | ## 808 | ## Examples: 809 | ## _uumod(2, 3.4) == 2 810 | ## _uumod(2, 3.6) == 4 811 | ## _uumod(2, -3.4) == -2 812 | ## _uumod(2, -3.6) == -4 813 | ## 814 | ## _uumod(2, 3) == 2 815 | ## _uumod(2, 3, false) == 4 816 | ## _uumod(2, -3) == -2 817 | ## _uumod(2, -3, false) == -4 818 | ## 819 | function _uumod(int m, float f, bool "z") 820 | { 821 | m = Max(1, m) 822 | mult = Default(z, true) ? -1 : 1 823 | fsgn = Sign(f) 824 | i = Round(Abs(f)) 825 | return fsgn * Max(0, i + mult * (i % m)) 826 | } 827 | 828 | ####################################### 829 | ## format a Float as a String with 2 decimals 830 | function StrinF(float f) 831 | { 832 | return String(f, "%0.2f") 833 | } 834 | 835 | ################################## 836 | ### emulate GaussianBlur (YV12 only version) 837 | ## 838 | ## @ varY - works like GaussianBlur (default=1.5) 839 | ## @ varC - works like GaussianBlur (default=varY) 840 | ## @ radY - blur radius (varY squared); overrides varY 841 | ## @ radC - blur radius (varC squared); overrides varC 842 | ## @ show - ("Y"|"U"|"V"|"") (default="" - all channels) 843 | ## 844 | ## @version 1.0 raffriff42 23-Oct-2013 845 | ## 846 | function UUGaussianBlurYV12( 847 | \ clip C, float "varY", float "varC", 848 | \ float "radY", float "radC", 849 | \ string "show") 850 | { 851 | varY = Max(0.0, Float(Default(varY, 1.5 ))) 852 | radY = Float(Default(radY, Pow(varY, 0.5))) 853 | varY = Pow(Min(Max(0.0, radY), 256.0), 2.0) 854 | 855 | varC = Max(0.0, Float(Default(varC, varY))) 856 | radC = Float(Default(radC, Pow(varC, 0.5))) 857 | varC = Pow(Min(Max(0.0, radC), 256.0), 2.0) 858 | 859 | show = Default(show, "") 860 | 861 | B = (C.IsYV24) ? C : C.ConvertToYV24() 862 | 863 | U = B.UToY8.UUGaussianBlurY(varC) 864 | V = B.VToY8.UUGaussianBlurY(varC) 865 | Y = B.ConvertToY8.UUGaussianBlurY(varY) 866 | B = YToUV(U, V, Y) 867 | 868 | R = (StrCmpi(show,"Y")==0) ? Y 869 | \ : (StrCmpi(show,"U")==0) ? U 870 | \ : (StrCmpi(show,"V")==0) ? V 871 | \ : (varY<0.003 && varC<0.003) ? C 872 | \ : (varY==varC) ? C.UUGaussianBlurY(varY) 873 | \ : B 874 | return R.ConvertToYV12() 875 | } 876 | 877 | ################################## 878 | ### emulate GaussianBlur - simplified version, 879 | ## does not care about source color model 880 | ## 881 | ## @ var - works like GaussianBlur's varY 882 | ## @ rad - works like most "normal" GaussianBlurs 883 | ## 884 | ## @version 1.1 raffriff42 23-Oct-2013 885 | ## 886 | function UUGaussianBlurY(clip C, float "var", float "rad") 887 | { 888 | var = Max(0.0, Float(Default(var, 1.0))) 889 | rad = Max(1.0, Float(Default(rad, Pow(var, 0.5)))) 890 | var = Pow(Min(Max(0.0, rad), 60.0), 2.0) 891 | 892 | w0 = C.Width 893 | h0 = C.Height 894 | w1 = Round(w0/rad) 895 | h1 = Round(h0/rad) /* formerly "w0/rad" ?? */ 896 | 897 | B = C.BilinearResize( 898 | \ Min(Max(12, w1 + (w1 % 2)), w0), 899 | \ Min(Max(12, h1 + (h1 % 2)), h0)) 900 | 901 | B = B.Blur(1.0).Blur(1.0) 902 | 903 | return (var<0.01) ? C 904 | \ : (var<1.5) ? C.Blur(0.85 * var) 905 | \ : (B.Width>8 && B.Height>8) ? B.GaussResize(w0, h0) 906 | \ : B.BilinearResize(w0, h0) 907 | } 908 | 909 | ################################## 910 | ### crop or add border to ensure clip is a certain size 911 | # 912 | #@param pan - -1=left, 0=center, 1=right; [default = 0] 913 | #@param tilt - -1=up, 0=center, 1=down; [default = 0] 914 | # 915 | function UUSize2(clip C, int wid, int hgt, float "pan", float "tilt") 916 | { 917 | isrgb = (C.IsRGB24 || C.IsRGB32) 918 | 919 | bdrWid = (wid - C.Width) 920 | bdrHgt = (hgt - C.Height) 921 | 922 | xctr = Min(Max(-1.0, Float(Default(pan, 0.0))), 1.0) 923 | yctr = Min(Max(-1.0, Float(Default(tilt, 0.0))), 1.0) 924 | 925 | bdrLt = Abs(Round(Float(bdrWid) / 2.0)) 926 | bdrLt = bdrLt + Round(bdrLt * xctr) 927 | bdrLt = Sign(bdrWid) * (bdrLt + (isrgb ? 0 : (bdrLt % 2))) 928 | 929 | bdrTp = Abs(Round(Float(bdrHgt) / 2.0)) 930 | bdrTp = bdrTp + Round(bdrTp * yctr) 931 | bdrTp = Sign(bdrHgt) * (bdrTp + (isrgb ? 0 : (bdrTp % 2))) 932 | 933 | bdrRt = (bdrWid - bdrLt) 934 | bdrBt = (bdrHgt - bdrTp) 935 | 936 | C = C.AddBorders( 937 | \ ((bdrLt > 0) ? bdrLt : 0), 938 | \ ((bdrTp > 0) ? bdrTp : 0), 939 | \ ((bdrRt > 0) ? bdrRt : 0), 940 | \ ((bdrBt > 0) ? bdrBt : 0)) 941 | 942 | C = C.Crop( 943 | \ ((bdrLt < 0) ? -bdrLt : 0), 944 | \ ((bdrTp < 0) ? -bdrTp : 0), 945 | \ ((bdrRt < 0) ? bdrRt : wid), 946 | \ ((bdrBt < 0) ? bdrBt : hgt)) 947 | 948 | return C 949 | } 950 | 951 | ####################################### 952 | ## Not used in dotcrawlplus, but a related function: 953 | ## create a fixed pattern of dots. 954 | function gridmask_square(clip C, int size) 955 | { 956 | C 957 | return mt_logic( 958 | \ mt_lutspa(mode="absolute", chroma="-128", 959 | \ expr=("""cos(x / $s * pi) * 108 + 126""") 960 | \ .StrReplace("$s", String(size)) 961 | \ .mt_polish ), 962 | \ mt_lutspa(mode="absolute", chroma="-128", 963 | \ expr=("cos(y / $s * pi) * 108 + 126") 964 | \ .StrReplace("$s", String(size)) 965 | \ .mt_polish ), 966 | \ "andn") 967 | } 968 | 969 | ####################################### 970 | ## Not used in dotcrawlplus, but a related function: 971 | ## create a fixed pattern of dots. 972 | function gridmask_diag(clip C, int size) 973 | { 974 | C 975 | return mt_logic( 976 | \ mt_lutspa(mode="absolute", chroma="-128", 977 | \ expr=("""(cos(x / $s * pi) * ((y / 2 * $s % 2) > 0) ? 1 : -1) * 108 + 126""") 978 | \ .StrReplace("$s", String(size)).mt_polish), 979 | \ mt_lutspa(mode="absolute", chroma="-128", 980 | \ expr=("cos(y / $s * pi) * 108 + 126") 981 | \ .StrReplace("$s", String(size)).mt_polish), 982 | \ "andn") 983 | } 984 | 985 | 986 | 987 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #
2 | ####

***A modernization of DotCrawlPlus, an filter that emulates analog artifacts.***

3 | 4 |
5 | 6 | [![Release version](https://img.shields.io/github/v/release/rgm89git/DotCrawlPlusPlus?color=blue&label=&style=for-the-badge)](https://github.com/rgm89git/DotCrawlPlusPlus/releases/latest) 7 | [![Downloads](https://img.shields.io/github/downloads/rgm89git/DotCrawlPlusPlus/total?style=for-the-badge&color=blue)](https://github.com/rgm89git/DotCrawlPlusPlus/releases/latest) 8 | [![Commits](https://img.shields.io/github/commit-activity/m/rgm89git/DotCrawlPlusPlus?label=commits&style=for-the-badge)](https://github.com/rgm89git/DotCrawlPlusPlus/commits) 9 | [![Last Commit](https://img.shields.io/github/last-commit/rgm89git/DotCrawlPlusPlus?style=for-the-badge)](https://github.com/rgm89git/DotCrawlPlusPlus/commits) 10 | [![Doom9 Thread](https://img.shields.io/badge/-DOOM9%20THREAD-blue?style=for-the-badge)](https://forum.doom9.org/showthread.php?t=184188) 11 | [![License](https://img.shields.io/github/license/rgm89git/DotCrawlPlusPlus?style=for-the-badge)](https://github.com/rgm89git/DotCrawlPlusPlus/blob/main/LICENSE.md) 12 | 13 | *Original by: [raffriff42](https://forum.doom9.org/showthread.php?t=170433)* 14 | 15 |
16 | 17 | ## Demos 18 | **Colorbars w/ Overscan Borders** 19 | 20 | Colorbars w/ DotCrawl++ 21 | 22 | ```avisynth 23 | ColorBars(pixel_type="YV12") 24 | Amplify(0) 25 | 26 | Spline64Resize(640,480) 27 | AddBorders(6,0,6,0) 28 | Spline64Resize(640,480) 29 | 30 | sharpen(.5) 31 | blur(1) 32 | 33 | dcpp_preset("betacam",threads=4) 34 | ``` 35 | 36 | **Test Charts w/ Overscan Borders** *(credits to [belle-nuit.com](https://www.belle-nuit.com/test-chart))* 37 | 38 | Test Charts w/ Overscan Borders 39 | 40 | ``` 41 | ImageSource("testchartntsc.tif") 42 | ConvertToYV12() 43 | 44 | Spline64Resize(640,480) 45 | AddBorders(6,0,6,0) 46 | Spline64Resize(640,480) 47 | 48 | sharpen(.5) 49 | blur(1) 50 | 51 | dcpp_preset("betacam",threads=4) 52 | ``` 53 | 54 | ## Usage 55 | 56 | **Choose a preset:** 57 | ``` 58 | dcpp_preset(clip C, string "preset", float "dots", float "rainbow", bool "showpreset", bool "showargs", float "threads") 59 | @ preset - choices: 60 | "mild" - minimal effect 61 | "medium" - softer chroma; a little added noise 62 | "heavy" - very soft & noisy 63 | "strong" - like medium but more so 64 | "bigdot1" - larger dots #1 65 | "bigdot2" - larger dots #2 66 | "bigdot3" - larger dots #3 67 | "betacam" - Analog formats - Betacam 68 | empty string ("") defaults to "medium"; 69 | unrecognized values raise an error. 70 | @ dots - dotcrawl effect amount 71 | (default depends on preset) 72 | @ rainbow - rainbow effect amount 73 | (default depends on preset) 74 | @ rb_strength - rainbow effect mask strength 75 | (default 17) 76 | @ cblur - chroma blur amount 77 | (default depends on preset) 78 | @ lblur - luma blur amount 79 | (default depends on preset) 80 | @ showpreset - if true, show the preset name as a Subtitle 81 | (default false) 82 | @ showargs - if true, show the arguments as a Subtitle 83 | (default false) 84 | @ threads - cpu threads you want to use 85 | (default 4) 86 | ``` 87 | 88 | **Or use the main function *(with your settings)*:** 89 | ``` 90 | dotcrawlplusplus(clip C, int "dotstyle", float "dotblend", float "dotscale", int "dotleak", int "csub", float "cblur", float "lblur", int "lnoise", int "cnoise", float "streaking", float "rainbow", bool "showargs", float "threads") 91 | @ dotstyle - dots style (0..2; default 0) 92 | @ dotblend - dots opacity (default 1.0) 93 | @ dotscale - scale of dot crawl (1..4; default 1; >2 is ugly) 94 | @ dotleak - allow some dot crawl everywhere 95 | (0-255; default 0; 32 is just visble; >64 is extreme) 96 | @ csub - default 2 (1=betacam; 2=VHS) 97 | @ cblur - default 0.3 (0.0=no added blur; 0.5=VHS) 98 | @ lblur - default 0.3 99 | @ lnoise - default 4 (0=bypass; 2=subliminal; 22-33=VHS) 100 | @ cnoise - default 4 (0=bypass; 2=subliminal; 33=VHS) 101 | @ streaking - default 0.0 (1.0=extreme horizontal streaking) 102 | @ rainbow - rainbow effect opacity (default 0.2) 103 | @ rb_strength - rainbow effect mask strength (default 17) 104 | @ showargs - if true, show the arguments as a Subtitle 105 | @ threads - cpu threads you want to use (default 4) 106 | ``` 107 | 108 | **You can also create halo artifacts:** 109 | ``` 110 | dcpp_halo(clip C, float "bright_halo", float "dark_halo") 111 | @ bright_halo - bright halo intensity (default 0.4) 112 | @ dark_halo - dark halo intensity (default 0.5) 113 | ``` 114 | 115 | ## Requisites 116 | 117 | - **[AviSynth+](https://github.com/AviSynth/AviSynthPlus/releases)** 118 | - **Plugins** *(need to be added onto the plugins folders on the AviSynth+ program folder)* 119 | - [MaskTools](https://github.com/pinterf/masktools/releases/) 120 | - [AddGrainC](https://github.com/pinterf/AddGrainC/releases) 121 | - [FFT3DFilter](https://github.com/pinterf/fft3dfilter/releases) *(need FFTW 3.3.5 dlls)* 122 | - [GRunT](https://github.com/pinterf/GRunT/releases) 123 | - [TEMmod](https://github.com/Asd-g/TEMmod/releases) 124 | 125 | ## Initial Contributions 126 | 127 | - **@SaurusX** *(Doom9)* - (Helping with rainbowing) 128 | - **@zarxrax** *(Doom9)* - (Contributing with rainbowing) 129 | 130 | ## Credits 131 | 132 | - **@Dogway** (LumaMask - old version) 133 | 134 | ## License 135 | 136 | This GitHub repository is licensed under the GNU General Public License v3.0 (GPL3). 137 | -------------------------------------------------------------------------------- /images/.gitkeep: -------------------------------------------------------------------------------- 1 | 2 | --------------------------------------------------------------------------------