Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 8th September 2015, 16:43   #1  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
Evenly padding to mod8/16?

Hi, I'm looking for a script that can evenly pad to mod8/16. I came across this function:
Quote:
Originally Posted by Didée View Post
Code:
function mmod1(clip c, int h, int v) { c.pointresize(c.width+(1-c.width)%h+h-1, c.height+(1-c.height)%v+v-1, 0,0, c.width+(1-c.width)%h+h-1, c.height+(1-c.height)%v+v-1) }
It does what I want but unfortunately it only pads the bottom right borders. There's nothing wrong with this and it's in fact the correct thing to do in certain situations but there are other times were padding the borders evenly is more desirable. I've tried modifying the script to do just that but I was unsuccessful. Any help would be be appreciated.
Reel.Deel is offline   Reply With Quote
Old 8th September 2015, 17:08   #2  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Function P2M8 (clip input)
{
w = input.width ()
h = input.height ()
w8 = int ((w + 4) / 8) * 8
h8 = int ((h + 4)/ 8) * 8
left = int ((w8 - w) / 2)
right = w8 - w - left
top = int ((h8 - h) / 2)
bot = h8 - h - top
return Padding (input, left, top, right, bot)
}

Function Padding (clip input, int "left", int "top", int "right", int "bottom")
{
w = input.width ()
h = input.height ()

output = input.PointResize (w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom)

return output
}

WARNING: ain't tested it... use it at ur own risk

Last edited by feisty2; 8th September 2015 at 17:15.
feisty2 is offline   Reply With Quote
Old 8th September 2015, 20:28   #3  |  Link
ajp_anton
Registered User
 
ajp_anton's Avatar
 
Join Date: Aug 2006
Location: Stockholm/Helsinki
Posts: 805
Pad to any mod, optionally separately for width and height. Also not tested =).

function padtomod(clip input,int hmod,int "vmod")
{
vmod = default(vmod, hmod)
w = input.width
h = input.height
hpad = ceil(w/hmod)*hmod
vpad = ceil(h/vmod)*vmod

left = round((hpad-w)/2)
top = round((vpad-h)/2)

return input.pointresize(hpad, vpad, -left, -top, hpad, vpad)
}

Last edited by ajp_anton; 8th September 2015 at 20:31.
ajp_anton is offline   Reply With Quote
Old 20th September 2015, 14:23   #4  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
@ajp_anton

Finally tried out padtomod but unfortunately it's cropping instead of padding.
Reel.Deel is offline   Reply With Quote
Old 20th September 2015, 18:08   #5  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,373
EDIT New and improved - supports rounding up or down to the nearest mod-X size. Round down by default.
Code:
XXSource(...)
UUSize(Width-39, Round(Height+2*PI), mod=8, floor=true)
return Last

##################################
### crop or add borders to ensure clip is a certain size
##
## @ wid, hgt - new desired width & height (no mod requirement)
## @ mod   - mod value (default = minimum = 4)
## @ floor - always go to the smaller of the two nearest mod sizes (default true)
##
function UUSize(clip C, int wid, int hgt, int "mod", bool "floor")
{
    mod  = Max(4, Default(mod, 4)) 
    flor = Default(floor, true)

    out_wid = (flor) ? wid-(wid%mod) : wid+(wid%mod)
    out_hgt = (flor) ? hgt-(hgt%mod) : hgt+(hgt%mod)

    C ## Last==C
    bdrX  = out_wid - Width
    bdrY  = out_hgt - Height
    bdrLt = Ceil(Float(bdrX) / 2.0)
    bdrTp = Ceil(Float(bdrY) / 2.0)
    bdrLt = bdrLt - (bdrLt % 2)
    bdrTp = bdrTp - (bdrTp % 2)
    bdrRt = (bdrX - bdrLt) 
    bdrBt = (bdrY - bdrTp)

    AddBorders(
    \   Max(0, bdrLt), Max(0, bdrTp), 
    \   Max(0, bdrRt), Max(0, bdrBt))

    Crop(
    \   ((bdrLt < 0) ? -bdrLt : 0), 
    \   ((bdrTp < 0) ? -bdrTp : 0), 
    \   ((bdrRt < 0) ?  bdrRt : out_wid), 
    \   ((bdrBt < 0) ?  bdrBt : out_hgt))

    return Last
}

Last edited by raffriff42; 21st September 2015 at 02:20. Reason: new function
raffriff42 is offline   Reply With Quote
Old 21st September 2015, 03:41   #6  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
@ raffriff42

Neat script, the only downside is I want to pad (duplicate edge pixels) not add borders. ajp_anton's script does exactly want I but as I mentioned earlier it's cropping instead of padding. I tried tweaking it but only made it worse.
Reel.Deel is offline   Reply With Quote
Old 21st September 2015, 04:20   #7  |  Link
Desbreko
Registered User
 
Desbreko's Avatar
 
Join Date: Feb 2015
Posts: 55
Gotta convert ints to floats before dividing or else the result is automatically converted to an int.

Code:
function padtomod(clip input, int hmod, int "vmod")
{
vmod = default(vmod, hmod)
w = input.width()
h = input.height()
hpad = ceil(float(w)/float(hmod))*hmod
vpad = ceil(float(h)/float(vmod))*vmod

left = round((hpad-w)/2)
top = round((vpad-h)/2)

return input.pointresize(hpad, vpad, -left, -top, hpad, vpad)
}
__________________
Twitter, AviSynth scripts

Last edited by Desbreko; 21st September 2015 at 04:28.
Desbreko is offline   Reply With Quote
Old 21st September 2015, 06:45   #8  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,373
Quote:
Originally Posted by Reel.Deel View Post
Neat script, the only downside is I want to pad (duplicate edge pixels) not add borders.
OK, I have one...
Quote:
Originally Posted by Didée View Post
Code:
function Padding(clip c, int left, int top, int right, int bottom)
{
  w = c.width()
  h = c.height()
  c.pointresize( w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom )
}
raffriff42 is offline   Reply With Quote
Old 21st September 2015, 13:21   #9  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,373
You might be interested in this, too:
Code:
## based on GradFunkMirror
# http://forum.doom9.org/showthread.php?t=165658
#
function AddMirrorBorders(clip C, int "bdrx", int "bdry")
{
    bdrx  = Max(2, Default(bdrx, 16))
    bdry  = Max(2, Default(bdry, 16))

    bdrLt = Max(0, bdrx - (bdrx % 2))
    bdrTp = Max(0, bdry - (bdry % 2))
    bdrRt = 2 * bdrx - bdrLt 
    bdrBt = 2 * bdry - bdrTp

    CL = C.Crop(0, 0, bdrLt, 0)
    CR = C.Crop(C.Width-bdrRt, 0, bdrRt, 0)

    C2 = (bdrLt==0) 
    \  ? (bdrRt==0) 
    \     ? C
    \     : StackHorizontal(C, CR.FlipHorizontal)
    \  : (bdrRt==0)
    \     ? StackHorizontal(CL.FlipHorizontal, C)
    \     : StackHorizontal(CL.FlipHorizontal, C, CR.FlipHorizontal)

    CT = C2.Crop(0, 0, 0, bdrTp) 
    CB = C2.Crop(0, C2.Height-bdrBt, 0, bdrBt)

    C3 = (bdrTp==0) 
    \  ? (bdrBt==0) 
    \     ? C2
    \     : StackVertical(C2, CB.FlipVertical)
    \  : (bdrBt==0)
    \     ? StackVertical(CT.FlipVertical, C2)
    \     : StackVertical(CT.FlipVertical, C2, CB.FlipVertical)

    return C3
}
raffriff42 is offline   Reply With Quote
Old 21st September 2015, 15:08   #10  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
Quote:
Originally Posted by Desbreko View Post
Gotta convert ints to floats before dividing or else the result is automatically converted to an int.

Code:
function padtomod(clip input, int hmod, int "vmod")
{
vmod = default(vmod, hmod)
w = input.width()
h = input.height()
hpad = ceil(float(w)/float(hmod))*hmod
vpad = ceil(float(h)/float(vmod))*vmod

left = round((hpad-w)/2)
top = round((vpad-h)/2)

return input.pointresize(hpad, vpad, -left, -top, hpad, vpad)
}
Thanks Desbreko, works correctly now.

---

Now I need to figure out how to create another small function that crops based on the padding added by padtomod. Any ideas? Another thing I'm wondering about is how does padtomod treat a clip with odd dimensions? I now that PointResize can only do integers so does it just pad more to one side or am I missing something.
Reel.Deel is offline   Reply With Quote
Old 21st September 2015, 17:34   #11  |  Link
Desbreko
Registered User
 
Desbreko's Avatar
 
Join Date: Feb 2015
Posts: 55
If the resolution is odd, it will put an extra pixel of padding on the bottom and right sides as needed.

Now that I take another look, the Round function in the left and top variable assignments isn't needed since, again, it's dividing two ints and any remainder is automatically truncated. So those lines could be simplified to this:

left = (hpad-w)/2
top = (vpad-h)/2

Or, if you want the extra padding on the top and left sides instead, you could change them to this:

left = ceil((hpad-w)/2.0)
top = ceil((vpad-h)/2.0)

To crop the padding, here's a function that takes a target width and height and crops the sides of the clip evenly to reach that resolution:

Code:
function CropEven(clip input, int target_width, int target_height)
{
w = input.Width()
h = input.Height()
hcrop = w-target_width
vcrop = h-target_height

lcrop = Floor(hcrop/2.0)
tcrop = Floor(vcrop/2.0)
rcrop = Ceil(hcrop/2.0)
bcrop = Ceil(vcrop/2.0)

return input.Crop(lcrop, tcrop, -rcrop, -bcrop)
}
Like the padtomod function, it will crop the extra pixels off the bottom and right sides if the target resolution is odd. If you want it to crop them from the top and left instead, you can swap the Floor and Ceil calls.
__________________
Twitter, AviSynth scripts
Desbreko is offline   Reply With Quote
Old 22nd September 2015, 00:49   #12  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,373
This one expands with your choice of borders, duplication, or mirroring. It crops as well. First a test and demo routine...
Code:
XXXSource(...)
## use a test source with detail near the edges (not colorbars)

## reduce contrast to see subtitles & colored border more clearly (test only)
(IsRGB) ? RGBAdjust(0.5, 0.5, 0.5, 1, 64, 64, 64) : ColorYUV(cont_y=-128, cont_u=-192, cont_v=-192)

## try to force image size to all values from (width-17, height-17) to (width+17, height+17) 
## let's see what happens...
return Animate(Last, 0, 36, "CropExtest", -17, +17).Trim(0, 36)
## ...view in step mode, not real time!

##################################
function CropExtest(clip C, int delta)
{
    ## TEST OPTIONS:

    _mod    = 4 ##  one of (4|8|16|32)

    ##[[ choose one:
    _option = $ffff00   ##  set border color
    #_option = -1        ##  extend
    #_option = -2        ##  mirror
    #]]

    _debug  = true

    ## Animate() above requires final clip to be a constant size
    awid = 960 
    ahgt = 540

   C ## Last==C
    return CropEx(Width+delta, Height+delta, _mod, border=_option, debug=_debug)
    \ .Spline64Resize(awid, ahgt)
    \ .Subtitle(String(delta, "delta=%0.0f"), align=8, size=Height/16)
}
Now the actual code:
Code:
# http://forum.doom9.org/showthread.php?p=1739635#post1739635
## fka UUSize4
##################################
### symmetrically crop or expand a clip to ensure it is a certain size, 
### with size forced to mod-4, mod-8 etc
##
## @ wid, hgt - new desired width & height (will be rounded to nearest 'mod')
## @ mod      - mod value; one of (1|2|4|8|16|32); default 2
##               (if negative, round UP, else round down)
## @ border   - border color; default 0 (black border)
##               (if -1, mode="extend"; if -2, mode="mirror")
## @ mode     - expand method: ("extend"|"mirror"|"border") default/fallback="border"
##               (overrides "border" argument for those who prefer this syntax)
## @ debug    - show internal variables
##
function CropEx(clip C, float wid, float hgt, int "mod",   
\               int "border", string "mode", bool "debug")
{
    mode    = Default(mode, "border")
    mdd     = Default(mod, 2)
    border  = Default(border, 0)
    dbug    = Default(debug, false)

    mult    = (mdd>0) ? -1 : 1
    mdd     = Abs(mdd)

    Assert((mdd==1||mdd==2||mdd==4||mdd==8||mdd==16||mdd==32), 
    \  "CropEx: 'mod' argument not one of (1|2|4|8|16|32)")

    border = Min(Max(-2, border), $ffffff)

    wid = Round(wid)
    hgt = Round(hgt)
    out_wid = wid + mult * (wid % mdd)
    out_hgt = hgt + mult * (hgt % mdd)

    C ## Last==C
    bdrX  = out_wid - Width
    bdrY  = out_hgt - Height
    bdrLt = Ceil(Float(bdrX) / 2.0)
    bdrTp = Ceil(Float(bdrY) / 2.0)
    bdrLt = bdrLt - (bdrLt % 2)
    bdrTp = bdrTp - (bdrTp % 2)
    bdrRt = (bdrX - bdrLt) 
    bdrBt = (bdrY - bdrTp)

    mode = (mode=="extend") ? mode
    \    : (mode=="mirror") ? mode
    \    : (border==-1) ? "extend"
    \    : (border==-2) ? "mirror"
    \    : "border"

    dbg="CropEx:"                                   +String(mdd, "       mod= %0.0f")
    dbg=dbg+"\n"+String(C.Width, "in_wid= %0.0f")   +String(C.Height, "    in_hgt= %0.0f")
    dbg=dbg+"\n"+String(wid, "arg_wid= %0.0f")      +String(hgt, "    arg_hgt= %0.0f")
    dbg=dbg+"\n"+String(bdrX, "bdrX= %+0.0f")       +String(bdrY, "       bdrY= %+0.0f")
    dbg=dbg+"\n"+String(bdrLt, "bdrLt= %+0.0f")     +String(bdrTp, "      bdrTp= %+0.0f")
    dbg=dbg+"\n"+String(bdrRt, "bdrRt= %+0.0f")     +String(bdrBt, "      bdrBt= %+0.0f")
    dbg=dbg+"\n"+String(out_wid, "out_wid= %0.0f")  +String(out_hgt, "    out_hgt= %0.0f")
    dbg=dbg+"\n mode = '"+mode+"'"                  +String(border, "    border= %0.0f")

    (mode=="extend") ? padding(
    \       Max(0, bdrLt), Max(0, bdrTp), 
    \       Max(0, bdrRt), Max(0, bdrBt))
    \ : (mode=="mirror") ? MirrorBorders(
    \       Max(0, bdrLt), Max(0, bdrTp), 
    \       Max(0, bdrRt), Max(0, bdrBt))
    \ : AddBorders(
    \       Max(0, bdrLt), Max(0, bdrTp), 
    \       Max(0, bdrRt), Max(0, bdrBt), border) 

    Crop(
    \   ((bdrLt < 0) ? -bdrLt : 0), 
    \   ((bdrTp < 0) ? -bdrTp : 0), 
    \   ((bdrRt < 0) ?  bdrRt : out_wid), 
    \   ((bdrBt < 0) ?  bdrBt : out_hgt))

    return (!dbug) ? Last : Subtitle(dbg, align=5, lsp=0)
}

##################################
function MirrorBorders(clip C, int left, int top, int right, int bottom)
{
    bdrLt = Max(0, left  )
    bdrTp = Max(0, top   )
    bdrRt = Max(0, right )
    bdrBt = Max(0, bottom)

    C ## Last==c

    (bdrLt==0) ? Last : StackHorizontal(
    \                       stack_to_wid(bdrLt, flip=true)
    \                       .Crop(0, 0, bdrLt, 0)
    \                       .FlipHorizontal, 
    \                       Last)

    (bdrRt==0) ? Last : StackHorizontal(
    \                       Last, 
    \                       stack_to_wid(bdrRt, flip=true)
    \                       .Crop(Width-bdrRt, 0, bdrRt, 0)
    \                       .FlipHorizontal)

    (bdrTp==0) ? Last : StackVertical(
    \                       stack_to_hgt(bdrTp, flip=true)
    \                       .Crop(0, 0, 0, bdrTp)
    \                       .FlipVertical, 
    \                       Last)

    (bdrBt==0) ? Last : StackVertical(
    \                       Last, 
    \                       stack_to_hgt(bdrBt, flip=true)
    \                       .Crop(0, Height-bdrBt, 0, bdrBt)
    \                       .FlipVertical)    
    return Last
}

##############################
## Stack clip 'C' horizontally until it is at least 'wid' wide
function stack_to_wid(clip C, int wid, clip "R", bool "flip") {
    R = Default(R, C)
    flip = Default(flip, false)
    C2 = (flip) ? C.FlipHorizontal : C
    return (R.Width >= wid) ? R
    \  : stack_to_wid(C, wid, StackHorizontal(R, C2))
}

##############################
## Stack clip 'C' vertically until it is at least 'hgt' high
function stack_to_hgt(clip C, int hgt, clip "R", bool "flip") {
    R = Default(R, C)
    flip = Default(flip, false)
    C2 = (flip) ? C.FlipVertical : C
    return (R.Height >= hgt) ? R
    \  : stack_to_hgt(C, hgt, StackVertical(R, C2))
}

Last edited by raffriff42; 16th April 2017 at 19:10. Reason: 2017 version renamed to CropEx
raffriff42 is offline   Reply With Quote
Old 22nd September 2015, 02:15   #13  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
Quote:
Originally Posted by Desbreko View Post
If the resolution is odd, it will put an extra pixel of padding on the bottom and right sides as needed.

Now that I take another look, the Round function in the left and top variable assignments isn't needed since, again, it's dividing two ints and any remainder is automatically truncated. So those lines could be simplified to this:

left = (hpad-w)/2
top = (vpad-h)/2

Or, if you want the extra padding on the top and left sides instead, you could change them to this:

left = ceil((hpad-w)/2.0)
top = ceil((vpad-h)/2.0)

To crop the padding, here's a function that takes a target width and height and crops the sides of the clip evenly to reach that resolution:

Code:
function CropEven(clip input, int target_width, int target_height)
{
w = input.Width()
h = input.Height()
hcrop = w-target_width
vcrop = h-target_height

lcrop = Floor(hcrop/2.0)
tcrop = Floor(vcrop/2.0)
rcrop = Ceil(hcrop/2.0)
bcrop = Ceil(vcrop/2.0)

return input.Crop(lcrop, tcrop, -rcrop, -bcrop)
}
Like the padtomod function, it will crop the extra pixels off the bottom and right sides if the target resolution is odd. If you want it to crop them from the top and left instead, you can swap the Floor and Ceil calls.
CropEven is what I was looking for. Thanks again for the help. The additional info might also come in handy later.

padtomod and CropEven made things much easier
Code:
input = last
padtomod(16)
processing().moreprocessing()
CropEven(last, input.width(), input.height())

@raffriff42
Interesting script, will make note of it. Kinda reminds of PadResize()/PadMirror().
Reel.Deel is offline   Reply With Quote
Old 14th November 2015, 01:19   #14  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
How can I make padtomod add additional padding if the source is already the specified mod?

Right now I'm doing something like padtomod(16).Padding(8,8,8,8) / Crop(8,8,-8,-8,true).CropEven(src.width(), src.height()). It works but I was wondering if it can be done a bit better within padtomod.
Reel.Deel is offline   Reply With Quote
Old 15th November 2015, 05:14   #15  |  Link
Desbreko
Registered User
 
Desbreko's Avatar
 
Join Date: Feb 2015
Posts: 55
This will let you specify a minimum amount of padding to be added to the left/right and top/bottom sides. So instead of PadToMod(16).Padding(8,8,8,8) you can just use PadToMod(16,16,8,8).

Code:
function PadToMod(clip input, int hmod, int "vmod", int "hmin", int "vmin")
{
vmod = Default(vmod, hmod)
hmin = Default(hmin, 0)
vmin = Default(vmin, hmin)

w = input.Width()
h = input.Height()

hpad = Ceil(Float(w)/Float(hmod))*hmod
vpad = Ceil(Float(h)/Float(vmod))*vmod
left = Floor((hpad-w)/2.0)
top  = Floor((vpad-h)/2.0)

hadd = Ceil(Float(hmin*2)/Float(hmod))*hmod
vadd = Ceil(Float(vmin*2)/Float(vmod))*vmod

hpad = left < hmin ? hpad+hadd   : hpad
vpad = top  < vmin ? vpad+vadd   : vpad
left = left < hmin ? left+hadd/2 : left
top  = top  < vmin ? top+vadd/2  : top

return input.PointResize(hpad, vpad, -left, -top, hpad, vpad)
}
__________________
Twitter, AviSynth scripts
Desbreko is offline   Reply With Quote
Old 24th November 2015, 14:34   #16  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,664
Thanks Desbreko, it's working beautifully.

Code:
x = Width()%16 == 0 ? 8 : 0
y = Height()%16 == 0 ? 8 : 0

PadToMod(16, 16, x, y)
Reel.Deel is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:04.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.