Log in

View Full Version : RT_Stats, Compile-time/Runtime Functions v1.43 - 08 Oct 2014


Pages : 1 2 3 4 5 6 [7] 8 9 10 11

StainlessS
8th October 2014, 01:17
RT_Stats v1.43, new version see 1st post.

New DBase and Array funcs:


RT_DBaseGetID(String Filename,Int ix)
There are 16 ID attributes in the DBase file header that may be used internally by DBase utility functions rather than using user
attributes. This function allows script functions to use the same ID's (int or float) for whatever purpose a scriptor requires.
Built in utilty functions will use these to eg match a DBase to some clip, store Width or whatever.
Filename, DBase Filename, no default.
Ix, ID array element index range 0 -> 15.
Returns the value of the set ID, Int or Float (or type Int 0 if not yet set).


RT_DBaseSetID(String Filename,Int ix, Value)
There are 16 ID attributes in the DBase file header, that may be used internally by DBase utility functions rather than using user
attributes. This function allows script functions to use the same ID's (int or float) for whatever purpose a scriptor requires.
RT_DBaseAlloc() initializes all ID's to type Int, 0.
Filename, DBase Filename, no default.
Ix, ID array element index range 0 -> 15.
Value, Int or Float, The value that ID(ix) will be set to.
Returns Value. Error if type not of type Int or type Float.


RT_ArrayGetID(String Filename,Int ix)
There are 16 ID attributes in the Array file header that may be used internally by array utility functions rather than using user
attributes. This function allows script functions to use the same ID's (int or float) for whatever purpose a scriptor requires.
Built in utilty functions will use these to eg match an array to some clip, store Width or whatever.
Filename, ARRAY Filename, no default.
Ix, ID array element index range 0 -> 15.
Returns the value of the set ID, Int or Float (or type Int 0 if not yet set).


RT_ArraySetID(String Filename,Int ix, Value)
There are 16 ID attributes in the Array file header, that may be used internally by array utility functions rather than using user
attributes. This function allows script functions to use the same ID's (int or float) for whatever purpose a scriptor requires.
RT_ArrayAlloc() initializes all ID's to type Int, 0.
Filename, Array Filename, no default.
Ix, ID array element index range 0 -> 15.
Value, Int or Float, The value that ID(ix) will be set to.
Returns Value. Error if type not of type Int or type Float.


New RT_QwikScan related func:

RT_QwikScanEstimateLumaTol(clip SearchClip,clip FindClip,int "n"=current_frame,int "n2"=current_Frame,int "Matrix"=(Width>1100||Height>600?3:2))
Returns an estimate of minimum required LumaTol for use by RT_QwikScan().
SearchClip, clip using DBase in RT_QuickScan, ie with EXACT fingerprints in DBase.
FindClip, clip to estimate LumaTol for.
n = SearchClip frame number, default current_frame in runtime environment.
n2= FindClip frame number, default current_frame in runtime environment.
Matrix, RGB Default = (Width > 1100 OR Height>600) then 3(PC709) else 2(PC601). YUV not used. Conversion of RGB to YUV.
The clip/frame order IS SIGNIFICANT, make sure you have them the correct way around, FindClip(n2) is the frame for which
LumaTol is estimated, SearchClip(n) is the frame be be matched to.
Implemented for script that had many almost identical frames where purpose was to find UNDO's in a paint program capture clip
and remove the UNDO's from the clip. Was used to get a LumaTol estimate on frame prior to suspected UNDO frame where LumaTol
would be sufficiently great to also detect the start of an edit sequence as frame sort after, would be closer to the UNDO frame
than the frame for which the estimate was made. In this case, SearchClip(n) would be the suspect UNDO frame and FindClip(n2) would
be the frame we get an estimate for where goal is to find a frame that matches SearchClip(n).
The function returns 16.0 (maximum LumaTol) if no valid value of LumaTol is possible.
Thread that this function was implemented for (probably post after linked one):
http://forum.doom9.org/showthread.php?p=1694208#post1694208

wiseant
21st October 2014, 03:09
Hi StainlessS

First of all, Re post #269 in this thread:
I have been away from this forum since December 2013
I am pleased to see that you are still working on RT_Stats
Also happy to see that you are using SendSpace as well as MediaFire - I probably did access MediaFire previously with IE - hence the pop-up problem - I normally use FireFox with AdBlock Plus

I just downloaded your latest RT_Stats and read through RT_Stats.txt - but I can't figure out how to accomplish what I want to do

Re this script for resizing a folder of images:

RT_Debug("Processing BMP File",FN)
k = ImageSource(FN,end=end).ConvertToRGB32()

iHeight = k.height
iWidth = k.width


if (iHeight >= iWidth) {
iHeight1 = canvasheight
iWidth1 = (canvasheight * iWidth) / iHeight
x = canvaswidth - iWidth1
x1 = x/2
#
if (iwidth1 % 2 > 0) {
iwidth1 =iwidth1+1
}
k = k.bilinearresize(iWidth1,canvasheight).addborders(x1,0,x1,0,$101010)

}
#
if (iWidth > iHeight) {
iWidth1 = canvaswidth
iHeight1 = (canvaswidth*iHeight)/iWidth
y = canvasheight-iHeight1
#
if (iheight1 % 2 > 0) {
iheight1 = iheight1+1
}
y1 = y/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(0,y1,0,y1,$101010)
}
#
if (iwidth1 > canvaswidth) {
iwidth1 = canvaswidth
iheight1 = (canvaswidth*iheight)/iwidth
y = canvasheight-iheight1
#
if (iheight1 % 2 > 0) {
iheight1 =iheight1+1
}
y1 = y/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(0,y1,0,y1,$101010)
}
#
if (iHeight1 > canvasheight) {
iHeight1 = canvasheight
iWidth1 = (canvasheight*iWidth)/iHeight
x = canvaswidth-iWidth1
#
if (iwidth1 % 2 > 0) {
iwidth1 = iwidth1+1
}
x1 = x/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(x1,0,x1,0,$101010)

}
RT_Debug("NewWidth= ",String(k.Width),"NewHeight =",String(k.height))
picclip = (IsClip(picclip)) ? picclip ++ k : k
RT_Debug("")
}
""")
PicClip
assumefps(fps)


What I want to do is to have a subtitle for each image. I could have a text file that has each Caption (subtitle) on a line by line basis - corresponding to each image, i.e. if I have 500 images, I would have a text file that has 500 lines of text.

So after each image get processed [resized] - I want to add the corresponding caption [subtitle]

Any suggestions to get me started?

TIA
wiseant

StainlessS
21st October 2014, 11:46
Hi again Wiseant, nice to see you back.

Rather than reinventing the wheel again, how about just using the ImageSplicer.avs script in RT_Stats AVS folder, perhaps it will serve.

As a test, I had a group of 100 BMP files named "CropTest_001.BMP" -> "CropTest_100.BMP", and executed this script to create a
Captions.Txt file.


GScript("""
S=""
for(i=1,100) {
S=RT_TxtAddStr(S,RT_String("%3d ) My Name is CropTest_%03d.BMP",i,i))
}
RT_Writefile("Captions.Txt","%s",S)
""")
Return MessageClip("All Done")


Then used this client script to call ImageSplicer()


Import("ImageSplicer.avs")

FN=".\CROPTEST\*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF"
SzLimit= -768
FAR=1.333
AutoCrop=True
AutoLevelStrength=1.0
ShowBorder=True
ShowAutoLevel=True
Subs=True
CropThresh = -1.0
ScanPerc=49.0
Baffle=4
Debug=False
Debug_QBC=False
Resizer="Spline64resize(_W_,_H_)"
Matrix=2

ImageSplicer(FN,SzLimit,FAR=FAR,AutoCrop=AutoCrop,AutoLevelStrength=AutoLevelStrength,ShowBorder=ShowBorder,ShowAutoLevel=ShowAutoLevel, \
Subs=Subs, CropThresh=CropThresh,Baffle=Baffle,ScanPerc=ScanPerc,Debug=Debug,Debug_QBC=Debug_QBC,Resizer=Resizer,matrix=matrix)

CaptionsFN = "Captions.Txt"
Captions = RT_ReadTxtFromFile(CaptionsFN)

ScriptClip("""
S=RT_TxtGetLine(Captions,current_frame)
Subtitle(S,Align=5,Size=24)
Return Last
""")

Return Last


You need to edit the config settings of course.

EDIT: Just for those curious about the config stuff:

Function ImageSplicer(String "FileName",int "SzLimit",Float "FAR",Bool "AutoCrop",Float "AutoLevelStrength",bool "ShowAutoLevel",bool "ShowBorder", \
bool "Subs", Float "CropThresh",Float "FPS",int "WMod",int "HMod",int "Baffle",Float "ScanPerc", \
bool "Debug", bool "Debug_QBC",String "Resizer",int "Matrix",float "Ignore") {
##########################################
VERS="ImageSplicer v1.10 - 17 Mar 2013" # Requires GScript, RT_Stats v1.10
#
# ImageSplicer, joins together images of different sizes into a sort of slideshow, auto cropping borders, auto levelling, resizing or original size,
# border padding to chosen aspect ratio.
# Gets max width/height of all images (after optional auto cropping) and creates a background 'canvas' based on SzLimit & FAR.
# SzLimit==0: Images kept at original dimensions (post cropping), canvas made to encompass all cropped images.
# SzLimit>0: The shorter canvas dimension (FAR) limited to AT MOST SzLimit, where images will be resized to fit canvas.
# Avoids upsizing to a larger size than biggest cropped source image, if biggest less than SzLimit then output is biggest.
# SzLimit<0: The shorter canvas dimension (FAR) set at abs(SzLimit) and images resized to fit canvas.
#
# Args:-
# Filename: Default "*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF". Image Path and wildcard with mulitple pipe separated extensions.
# SzLimit: Default=0, 0=No resize. Greater than 0 is limit on shorter dimension (see FAR), -ve resize to abs(SzLimit) shorter dimension.
# FAR: Default 4.0/3.0. Output Frame Aspect Ratio, if FAR>=1.0 then SzLimit affects height, else affects width.
# AutoCrop: Default=True. Crops borders off images.
# AutoLevelStrength: Default 0.0, Auto luma leveling, range 0.0 -> 1.0, 0.0 is OFF.
# ShowAutoLevel: Default False. If true then shows Auto leveling on right hande side of image ONLY.
# ShowBorder: Default False. When padding to maintain Frame Aspect Ratio, borders are shown in red.
# Subs: Default False. Shows Subtitled info on frames.
# CropThresh: Default -0.5
# CropThresh <=0.0 is PC levels AUTO thresh where cropthresh is set to minimum luma pixel + abs(CropThresh).
# Default is very sensitive threshold to avoid possibility of overcropping (-0.5 -> -1.0, usually safe, more -ve less safe).
# You may raise (make more -ve) auto CropThresh if not cropping enough but risk overcropping on dark images if you do.
# CropThresh >0.0 is explicit threshold @ PC Levels, probably best avoided.
# RGB clips are converted to YUV-Y using Matrix arg @ PCLevels and CropThresh acting on Average Luma of scanline (h/v).
# FPS: Default 1.0. Frames Per Second of output clip.
# WMod: Default 2. Output clip width is a multiple of WMod.
# HMod: Default 2. Output clip height is a multiple of HMod.
# Baffle: Default 4 (1->32), affects cropping.
# Number of scanlines that must break a CropThresh to be accepted as Image. Avoids noise. Not usually altered.
# Baffle also affects speed, higher can be faster for big borders but also means that more scanlines must break threshold to be accepted as image.
# ScanPerc: Default 49.0, cropping. Percentage of image to scan per side. Not usually altered.
# Debug: Default False. Show debug info via DebugView. Need DebugView: http://technet.microsoft.com/en-gb/sysinternals/bb545027
# Debug_QBC: Default False. Show debug messages from RT_QueryBorderCrop.
# Resizer: Default "Spline36Resize(_W_,_H_)", the resizer to use. "_W_" and "_H_" are replaced by the resize width & height.
# Matrix: 2->3, Default If pic width <=720 Then 2(PC601) Else 3(PC709). Used in converting RGB to YUV-Y.
# Ignore: Default 0.2, Cropping. Percentage, Threshold of pixels to ignore when getting Luma minimum, avoids a few noisy pixels.
# As for YPlaneMin Threshold arg.

wiseant
21st October 2014, 20:46
Hi StainlessS

It is good to be back - there is a lot of expertise in this forum
Thanks for the info - I will try your scripts later today.

I am able to add captions this way:


GScript("""
c0="Hello World"
c1="Hello and GoodBye"
c2="Love is all you need"
c3="avisynth rocks"
c4="Gscript is awesome"
...
caption = Eval("c"+String(i))
...
RT_Debug("NewWidth= ",String(k.Width),"NewHeight =",String(k.height))
k=k.subtitle((Caption), 8, 460)


I could create an avsi file with the captions

Now, the next thing I want to do is to add transitions using vcmohan's TransAll plugin

e.g.

TransRipple(k0,k1,60,32)

where I would need to create an array of k values - I'll try to figure out the syntax I need today

StainlessS
21st October 2014, 22:05
Captions would be easiest handled in a text file, and add them relative to frame number.
I cant say I've ever used Dissolve for anything, nor anything like it, you are on your own there.
Best I can suggest is to get aquainted with something like ImageView (or I played with Slide Show Movie Maker about 10 years ago).
They will have stuff for dissolve etc and can be done with a few clicks rather than days of hand editing stuff together.
If you are talking about 500+ pics, that is a lot of hand editing, adding Trim/Splace or Dissolve like stuff.
You could prepare a clip of single frames with captions, and then save as BitMaps, then perhaps either use ImageView or
create a script to pull single frames in one at a times and concatenate a load of duplicates, and dissolve with what youve got so far.
Or, you might want to delay adding the captions until dissolve's etc done and all joined together, then render Subtitle captions relative to frame
number (eg current_frame/25 is caption for frame if you have 25 frames per original picture).
Anyway, if you choose to use Avisynth for this, do it in stages, with separate script for each stage.
Forget the "c0="Hello World" stuff, too labour intensive.

EDIT: I think the movie maker thing I mentioned allowed you to save as executable where you could select to play in order,
or random order as a slide show or use it as a Screen Saver. (EDIT: And display original filenames or adjust frame display duration
etc).

EDIT: What exactly are you trying to do, will the clips be of differing lengths and perhaps have a music audio track ?
Also, what dissolves are you considering, ie just a single one TransRipple, or more than one ?

StainlessS
22nd October 2014, 03:01
EDIT: What exactly are you trying to do, will the clips be of differing lengths and perhaps have a music audio track ?
Also, what dissolves are you considering, ie just a single one TransRipple, or more than one ?

Have anticipated reply, something for you to play with.
STEP_1: ImageSplicer_Client.avs, Create AVI of Slides without captions, Edit to suit.

# ImageSplicer_Client.avs
Import("ImageSplicer.avs")

FN=".\IMAGE\*.BMP|JPG|JPE|JPEG|PNG|TGA|TIF|GIF|TIFF"
SzLimit= -768
FAR=1.333
AutoCrop=True
AutoLevelStrength=1.0
ShowBorder=False
ShowAutoLevel=False
Subs=False
CropThresh = -0.5
ScanPerc=49.0
Baffle=4
Debug=False
Debug_QBC=False
Resizer="Spline64resize(_W_,_H_)"
Matrix=2

ImageSplicer(FN,SzLimit,FAR=FAR,AutoCrop=AutoCrop,AutoLevelStrength=AutoLevelStrength,ShowBorder=ShowBorder,ShowAutoLevel=ShowAutoLevel, \
Subs=Subs, CropThresh=CropThresh,Baffle=Baffle,ScanPerc=ScanPerc,Debug=Debug,Debug_QBC=Debug_QBC,Resizer=Resizer,matrix=matrix)


Return Last # Save file as RGB32 AVI, Project_1.AVI


STEP_2: MakeDB.avs, Make a DB containing caption + other stuff.

# MakeDB.avs

PROJECT = "PROJECT_1"

FPS = 25.0 # O/P Project rate, (calc frames required)
USE_AUDIO = True # If False, dont read audio length (allow script use without existing wav files)
# Also allows setup of Int FrameCount

TEXT = PROJECT + ".TXT" # Source text containing data inserted into DBase
DB = PROJECT + ".DB"
#
DB_TYPESTRING = "ss1024ii" # String Caption[256], String AudioFile[1024], Int Transition, Int FrameCount
#
FIELD_CAPTION = 0
FIELD_AUDIO = 1
FIELD_TRANSITION = 2
FIELD_FRAMECOUNT = 3
#
RECORDS = 6 # Number of images in project
#
TYPE_BOOL = 0
TYPE_INT = 1
TYPE_FLOAT = 2
TYPE_STRING = 3
TYPE_BIN = 4
#

HASH = RT_Ord("#") # ASCII code for hash

RT_DBaseAlloc(DB,RECORDS,DB_TYPESTRING) # Allocate DBase, RECORDS records, and FIELDS fields as per TYPESTRING

TXT = RT_ReadTxtFromFile(TEXT)
NLINES = RT_TxtQueryLines(TXT)
RT_DBaseSetAttrib(DB,0,FPS) # Pass FPS into Caption&Dissolve script

GSCript("""
c = 0 cb = ColorBars().Trim(0,-1).KillAudio
Record = 0 Field = 0
For(Line=0,NLINES-1) {
S=RT_TxtGetLine(TXT,Line)
RT_DebugF("Line=%d Record=%d Field=%d S=%s",Line,Record,Field,S,name="MakeDB: ")
if(RT_Ord(S) != HASH) { # Ignore single hash line when hash at START OF LINE ONLY
Type = RT_DBaseFieldType(DB,Field)
if(Type==TYPE_STRING) {
RT_DBaseSetField(DB,record,field,S) # Set String
} Else If(Type==TYPE_INT){
RT_DBaseSetField(DB,record,field,RT_NumberValue(S)) # Set Int
}
if(Field < 2) { # We Only set first 3 Fields in this script (0 -> 2)
Field = Field + 1
} Else {
newc = cb.RT_Subtitle("%3d )\nCaption = %s\nAudioFile = %s\nTransition= %d",
\ record+1,RT_DBaseGetField(DB,record,0),RT_DBaseGetField(DB,record,1),RT_DBaseGetField(DB,record,2))
if(USE_AUDIO) {
AFN = RT_DBaseGetField(DB,record,1) # Audio Filename
AUD = WavSource(AFN)
Duration = AudioDuration(AUD) # Avisynth v2.6 ONLY
Frames = Int(Duration * FPS + 1.0)
RT_DBaseSetField(DB,record,FIELD_FRAMECOUNT,Frames) # Length of this clip in video frames
newc = newc.RT_Subtitle("Duration = %.2f\nFrames=%d",Duration,Frames,align=5)
}
c = (c.IsClip) ? c ++ newc : newc
Record = Record + 1 # next time new record
Field = 0 # start new at field 0
if(Record == RECORDS) {
Line = NLINES # Break, no more, ignore empty lines
}
}
}
}
Return c
""")

Return Last


STEP_3: Caption&Dissolve.avs, Final step create movie including audio + captions (can add-in more transitions)

#Caption&Dissolve.avs

PROJECT = "PROJECT_1"
AVI_FN = PROJECT + ".AVI"
DB = PROJECT + ".DB"
#
FIELD_CAPTION = 0
FIELD_AUDIO = 1
FIELD_TRANSITION = 2
FIELD_FRAMECOUNT = 3
#
TYPE_BOOL = 0
TYPE_INT = 1
TYPE_FLOAT = 2
TYPE_STRING = 3
TYPE_BIN = 4
#
RECORDS = RT_DBaseRecords(DB)
FIELDS = RT_DBaseFields(DB)
#
OVERLAP = 50

FPS = RT_DbaseGetAttrib(DB,0) # Get as set by MakeDB.AVS
AVI = AviSource(AVI_FN).AssumeFPS(FPS)

TRANSITION_NONE = 0
TRANSITION_DISSOLVE = 1

GSCript("""
c = 0
For(record=0,RECORDS - 1) {
Frames = RT_DBaseGetField(DB,record,FIELD_FRAMECOUNT)
Transition = RT_DBaseGetField(DB,record,FIELD_TRANSITION) # For whatever you want it
k = AVI.Trim(record,-1)
Caption= RT_DBaseGetField(DB,record,FIELD_CAPTION)
Caption= RT_String("%d/%d ) %s",record+1,RECORDS,Caption) # Add TrackNo indicator
RT_DebugF("%s",Caption)
k = k.SubTitle(Caption,Align=1,Size=24)
k = k.Loop(Frames,0,0) # Make Clip same length as audio
AUD = WavSource(RT_DBaseGetField(DB,record,FIELD_AUDIO))
k = AudioDub(k,AUD)
k = k.Trim(0,0) # Exactly to length
if(!c.IsClip) {
c = k # Non to join to
} Else {
if(Transition == TRANSITION_DISSOLVE) {
c = Dissolve(c,k,OVERLAP)

### INSERT MORE TRANSITION CODE ELSE's HERE

} Else { # CATCH ALL - TRANSITION_NONE
c = c ++ k
}
}
}
Return c
""")

Return Last



DUMMY DATA for STEP_2 MakeDB.avs, ie "PROJECT_1.TXT"

#1) Hash is a comment and record separator, Caption, AudioFile, Transition code
All you need is love - The Beatles
.\MUSIC\AllYouNeedIsLove.wav
1
#2)
If I Fell - The Beatles
.\MUSIC\IfIFell.wav
1
#3)
A hard days night - The Beatles
.\MUSIC\AHardDaysNight.wav
1
#4)
I am The walrus - The Beatles
.\MUSIC\IAmTheWalrus.wav
1
#5)
Strawberry Fields Forever - The Beatles
.\MUSIC\StrawberryFieldsForever.wav
1
#6)
Lucy in the sky with diamonds - The Beatles
.\MUSIC\LucyInTheSkyWithDiamonds.wav
1

I've only implemented Transition 1

Good Luck.

EDIT: AudioDuration() in STEP_2 requires v2.6, Also, MUST NOT have any blank or missing lines in Project_1.txt
Hashes are not needed, just visual separators.

wiseant
22nd October 2014, 21:38
Hi StainlessS

Wow, that is a lot of information - thanks once again for your time.


Captions would be easiest handled in a text file, and add them relative to frame number.


Yes, I agree with that - the only problem I see is correctly matching each caption to each image. Probably best to process the stream of images first - then create the text file of Captions. The order depends on the naming convention - e.g. if I have image names of 1.bmp ... 500.bmp then the sequence goes 1.bmp, 10.bmp, 100.bmp, 101.bmp ... 199.bmp, 2.bmp, 20.bmp, etc. And if I have descriptive names without numbers - it would be difficult to presume the order that the images are processed in. But if I add a one or two letter prefix -> ts0001.png ... ts0100.png - the order is preserved


EDIT: What exactly are you trying to do, will the clips be of differing lengths and perhaps have a music audio track ?
Also, what dissolves are you considering, i.e. just a single one TransRipple, or more than one ?


Right now, I am focusing on doing transitions with the TransAll plugin - I got it to work whereby there are different transitions between each image. Now I need to experiment with the fastest way of doing captions - I will try your script re reading captions from a text file.

The next thing I want to look at is adding audio - but I don't think I want an audio clip for each image - they will only display for 3 to 5 secs - so once I know the duration of the entire image sequence I can add audio. For example, if I have 500 images x 3 sec = 1500 sec = 25 minutes - I could create a 25 minute audio file or loop a 3 minute audio 5 times [though I need to find out how to do that].

Here is my script for transitions - I am using the old template simply because I am familiar with it - haven't had time to study "ImageSplicer.avs"

I created a new variable k1 - so the transitions are between k and k1. And the transition used is based on the modulus values.

You are a better coder than me, so I am sure there is a more elegant way to do this . . .



fps = 24
end = 48
GScript("""
picclip = 0
DEBUG = True
result = RT_WriteFileList("D:\Temp\*.png","sept.List")
Assert((result!=0),"No BMP files found")
BMPLIST = RT_ReadTxtFromFile("sept.List")
FILES = RT_TxtQueryLines(BMPLIST)
RT_Debug("Found BMP files = " + String(FILES))
RT_Debug(" ")
canvaswidth = 960
canvasheight = 400
For(i=0,FILES-2) {
FN = RT_TxtGetLine(BMPLIST,i)
FN1 = RT_TxtGetLine(BMPLIST,i+1)
RT_Debug("Processing BMP File",FN)
RT_Debug("Processing BMP File",FN1)
k = ImageSource(FN,end=end).ConvertToRGB32()
k1 = ImageSource(FN1,end=end).ConvertToRGB32()
iHeight = k.height
iWidth = k.width
iHeightN = k1.height
iWidthN = k1.width
#
if (iHeight >= iWidth) {
iHeight1 = canvasheight
iWidth1 = (canvasheight * iWidth) / iHeight
x = canvaswidth - iWidth1
x1 = x/2
#
if (iwidth1 % 2 > 0) {
iwidth1 = iwidth1+1
}
k = k.bilinearresize(iWidth1,canvasheight).addborders(x1,0,x1,0,$101010)
}
#
if (iHeightN >= iWidthN) {
iHeight1N = canvasheight
iWidth1N = (canvasheight * iWidthN) / iHeightN
x = canvaswidth - iWidth1N
x1 = x/2
#
if (iwidth1N % 2 > 0) {
iwidth1N = iwidth1N+1
}
k1 = k1.bilinearresize(iWidth1N,canvasheight).addborders(x1,0,x1,0,$101010)
}
#
if (iWidth > iHeight) {
iWidth1 = canvaswidth
iHeight1 = (canvaswidth*iHeight)/iWidth
y = canvasheight-iHeight1
#
if (iheight1 % 2 > 0) {
iheight1 = iheight1+1
}
y1 = y/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(0,y1,0,y1,$101010)
}
#
if (iWidthN > iHeightN) {
iWidth1N = canvaswidth
iHeight1N = (canvaswidth*iHeightN)/iWidthN
y = canvasheight-iHeight1N
#
if (iheight1N % 2 > 0) {
iheight1N = iheight1N+1
}
y1 = y/2
k1 = k1.bilinearresize(iWidth1N,iHeight1N).addborders(0,y1,0,y1,$101010)
}
#
if (iwidth1 > canvaswidth) {
iwidth1 = canvaswidth
iheight1 = (canvaswidth*iheight)/iwidth
y = canvasheight-iheight1
#
if (iheight1 % 2 > 0) {
iheight1 = iheight1+1
}
y1 = y/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(0,y1,0,y1,$101010)
}
#
if (iwidth1N > canvaswidth) {
iwidth1N = canvaswidth
iheight1N = (canvaswidth*iheightN)/iwidthN
y = canvasheight-iheight1N
#
if (iheight1 % 2 > 0) {
iheight1N =iheight1N+1
}
y1 = y/2
k1 = k1.bilinearresize(iWidth1N,iHeight1N).addborders(0,y1,0,y1,$101010)
}
#
if (iHeight1 > canvasheight) {
iHeight1 = canvasheight
iWidth1 = (canvasheight*iWidth)/iHeight
x = canvaswidth-iWidth1
#
if (iwidth1 % 2 > 0) {
iwidth1 = iwidth1+1
}
x1 = x/2
k = k.bilinearresize(iWidth1,iHeight1).addborders(x1,0,x1,0,$101010)
}
#
if (iHeight1N > canvasheight) {
iHeight1N = canvasheight
iWidth1N = (canvasheight*iWidthN)/iHeightN
x = canvaswidth-iWidth1N
#
if (iwidth1N % 2 > 0) {
iwidth1N = iwidth1N+1
}
x1 = x/2
k1 = k1.bilinearresize(iWidth1N,iHeight1N).addborders(x1,0,x1,0,$101010)
}
#
RT_Debug("NewWidth= ",String(k.Width),"NewHeight =",String(k.height))
#
mod1=Fmod(i, 1)
mod2=Fmod(i, 2)
mod3=Fmod(i, 3)
mod4=Fmod(i, 5)
mod5=Fmod(i, 7)
mod6=Fmod(i, 11)
mod7=Fmod(i, 13)
mod8=Fmod(i, 17)
mod9=Fmod(i, 19)
#
if (mod1==0) {
m=TransPush(k,k1,20)
}
#
if (mod2==0) {
m=TransSlantRollIn(k,k1,20)
}
#
if (mod3==0) {
m=TransWipe(k,k1,20,"up")
}
#
if (mod4==0) {
m=TransSlideOut(k,k1,20,"west")
}
#
if (mod5==0) {
m=TransSprite(k,k1,20,"left")
}
#
if (mod6==0) {
m=TransVenetianBlinds(k,k1,20,type="vert")
}
#
if (mod7==0) {
m=TransVenetianBlinds(k,k1,20,type="hor")
}
#
if (mod8==0) {
m=TransWeave(k,k1,20,"weave")
}
#
if (mod9==0) {
m=TransWipe(k,k1,20,"down")
}
#
picclip = (IsClip(picclip)) ? picclip ++ m : m
RT_Debug("")
}
""")
PicClip
assumefps(fps)



And here is a link for a sequence with transitions:

https://www.mediafire.com/?kvf57gfkcycqv36

I just extracted 100 images from "Tears of Steel" open source project - there are a few frames that have blocks - ? decode/encode error?

wiseant

StainlessS
22nd October 2014, 21:54
Wiseant,
I currently have less time to spend here, my interests have dispersed.
Take whatever you can from what was offerred, and if of use then please take.
Good luck.

StainlessS
26th October 2014, 04:41
@Wiseant
Sorry I was a little curt in my last post, I am not able to assist at present, a little busy getting into android
stuff, have spent a little time trying to (successfully) un-screw my botched flashing of my new tab (which I absolutely love,
way better than previous 3 or 4 that I've had).
Anyways, hope you sort your stuff out, and may your god smile upon you. :)

wiseant
27th October 2014, 19:24
@StainlessS

No problem. I was able to figure everything out - I used your suggestion about creating a "Captions" file then reading it and using Subtitle() to place it. I also figured out how to do transitions - pleased with the simple routine that I created . . .

Android stuff eh - have you looked into the Intel XDK?

"Intel XDK HTML5 Cross-platform Development Tool provides a simplified workflow to enable developers to easily design, debug, build, and deploy HTML5 web and hybrid apps across multiple app stores, and form factor devices. "

StainlessS
28th October 2014, 21:53
Thanks wiseant, I'll take a look. I'm not really interested in eg Windows phone or iPhone but I guess that could change.
I wanna get into all sides of Android, ie base Linux and diffs to android, customising ROM's, and apps.

Glad you got your stuff sorted, bye.

fvisagie
19th December 2014, 21:07
Is it a concept principle of AviSynth, that variables by reference are impossible?

I am unsure how useful it may be to you, but referencing variables can be approximated with Eval():
strvar = "Hello, World!"
strvarptr = "strvar"

MessageClip(Eval(strvarptr))

StainlessS
19th December 2014, 23:10
Yes, that can be done and better in a plugin.

Some parts of RT_ already do similar to set some variables although usually only taking a variable name Prefix and
setting some variable to a particular value.
(Plugin can set both Global and Local vars to a particular value, whether vars already existing or not)

Some parts of RT_ also return a string so as to set multiple variables all at once within an Eval.
eg, Return_String="Var_A = 27 Var_B= 42 Var_C = 66", where "Var_" might be the Prefix supplied to function.

EDIT: And I guess that 'by reference' is not actually being used here anyway, the item that is actually being set is (in your example) the
un-named argument to MessageClip() which cannot be referenced anyway or anywhere.

StainlessS
24th December 2014, 20:30
Update to previously posted DGIndex script template:

/*
ReDAR_DGIT.avs v0.1 - DGIndex AVS Template - By StainlessS.
Requires GSCript, RT_Stats v1.30+, RoboCrop, TIVTC, FFT3DFilter, NicAudio plugins.
Requires MediaInfo CLI version.

Progressive, or NTSC FILM with soft pulldown.
Purpose:- Crop letterboxing, with additional crop/resize to LESS wide screen DAR, CANNOT make more wide (DAR = Display Aspect Ratio).
Useful to crop to eg 16:9 on 16:9 hand held device.
Can also resize to SAR 1:1 [Sample (pixel) Aspect Ratio] for devices/players that cannot deal with non 1:1 clips.
Can Also call TFM and TDecimate to remove soft pulldown from NTSC FILM when Honour Pulldown Flags was used in DGIndex.
Signals resultant DAR for MeGUI in Global vars MeGUI_DarX and MeGUI_DarY.
*/

SHOW=False # Show Info on frame.
FRAME_DAR =RT_Undefined # Float, Input DAR of frame before RoboCrop(including letterboxing). RT_Undefined auto interrogates d2v file.
OUT_DAR =2.21/1.0 # Float, 0.0 = Use RoboCrop'ed DAR : Other = Additional crop to output DAR, eg FRAME 16:9, Robocrop'ed 2.4:1, OUT 16:9.
OUT_DAR_IS_LIMIT=True # If False, then OUT_DAR is required output DAR. (Error if OUT_DAR > RoboCrop'ed DAR, Cannot widen aspect ratio)
# If True and OUT_DAR != 0.0(0.0=RoboCrop'ed DAR), then reduce DAR only if RoboCrop'ed DAR is greater than OUT_DAR.
# Allows setting of maximum allowable output DAR(feel less like a peeping Tom for 2.4:1, eg limit to 16:9 on 4:3 device).

OUT_HEIGHT=0 # Int, 0 = Use RoboCrop'ed Height, Otherwise vertical resize to OUT_HEIGHT
OUT_WIDTH =0 # Int, 0 = Use OUT_SAR : Otherwise ignore OUT_SAR and use explicit OUT_WIDTH
OUT_SAR =0.0 # Float, Used if OUT_WIDTH=0 : 0.0 = Original SAR(crop only if OUT_HEIGHT=0) : 1.0 = 1:1 SAR
#
STRENGTH =0.75 # Float, Luma Auto Level strength (0.0 -> 1.0, 0.0=off)
UPCONV=True # Bool, False = no upsample(Progressive Encoded), True=upsample to YUY2(Progressive encoded as Interlaced), Can leave True.
###### Less often Changed
SAMPLES=32 # Int, Frames to sample, used by both RoboCrop and Auto Luma Levelling.
THRESH=-32 # int, -32 = RoboCrop AUTO Thresh
CROPMODE=2 # int, RoboCrop CropMode. 1=CropLess, 2= CropMore(Default)
TFM=True # If True, and FrameRate > 29.0 and MPEG-2 and DGIndex 'Honour Pulldown Flags' then Call TFM and TDecimate.
TFM_ANIME=False # True if Anime, For TDecimate
XMOD=0 # Int, 0=AUTO For crop/resize.
WMOD=4 # Int, 0=AUTO For crop/resize. (4 avoids problems on eg mp4 encodes displayed in MPC-HC)
MEDIAINFO="C:\BIN\MEDIAINFO.EXE" # To Check Aspect Ratio in IFO and compare with VOB : If conflict use IFO_MODE
IFO_MODE= 0 # 0 Error Alert on VOB/IFO DAR mismatch, 1 = Use IFO Frame Aspect Ratio
# List of programs that DONT like WMOD=2 for eg YUV.
# WMOD=0(AUTO) For YV12 will use eg 2 but switch to 4 if Process Name in WMOD4_PROGS list below (can append other names as in Task Manager).
WMOD4_PROGS="
VirtualDubMod.exe # VirtualDub Current OK
AVSEdit.exe # Built in Player
mplayer2.exe
wmplayer.exe
mpc-hc.exe
"
ROBOCROP_DEBUG=False
AUTOLEVEL_DEBUG=False
######################
### Filled in by DGIndex when using as DGIndex Template
VideoFileName ="__vid__"
AudioFileName =LCase("__aud__")
AudioDelay =Value("__del__")
######################
MPEG2Source(VideoFileName,UpConv=(UPCONV)?1:0) # Upconv to convert to YUY2, unmangle chroma if encoded as interlaced.

AudioExt=RT_GetFileExtension(AudioFileName)

Audio= (AudioExt==".ac3") ? NICAC3Source(AudioFileName,channels=2,DRC=0)
\ : (AudioExt==".mpa"||AudioExt=="mp1"||AudioExt==".mp2"||AudioExt==".mp3") ? NicMPG123Source(AudioFileName,Normalize=False)
\ : (AudioExt==".wav") ? RaWavSource(AudioFileName)
\ : (AudioExt==".dts") ? NicDTSSource(AudioFileName)
\ : 0

Assert(!isInt(Audio),"NO AUDIO")

(!isInt(Audio)) ? AudioDub(Audio).DelayAudio(AudioDelay).Trim(0,0) : NOP # Trim, chop/add audio to length

(!isInt(Audio) && AudioRate() <> 44100) ? ResampleAudio(44100) : NOP
#(!isInt(Audio) && AudioRate() <> 48000) ? ResampleAudio(48000) : NOP
#(!IsInt(Audio) && (AudioRate() <> 44100 && AudioRate() <> 48000))?ResampleAudio(44100) : NOP
#(!IsInt(Audio))? ConvertToMonO().ResampleAudio(44100) : NOP

######
GSCript("""
myName="ReDAR_DGIT: "
D2VVOBS_S = RT_ReadTxtFromFile(VideoFileName,lines=1,start=1)
D2V_START=RT_NumberValue(D2VVOBS_S) + 3
D2V_LINES = 12
SS0=""
if(TFM && FrameRate>29.0) {
MPEG_LINE = RT_FileFindStr(VideoFileName,"MPEG_Type",Sig=False,start=D2V_START,lines=D2V_LINES)
MPEG_S = RT_ReadTxtFromFile(VideoFileName,lines=1,start=MPEG_LINE)
MPEG2 = (RT_FindStr(MPEG_S,"=2",Pos=9) >= 0)
if(MPEG2) {
HONOUR_LINE = RT_FileFindStr(VideoFileName,"Field_Operation",Sig=False,start=D2V_START,lines=D2V_LINES)
HONOUR_S=RT_ReadTxtFromFile(VideoFileName,lines=1,Start=HONOUR_LINE)
HONOUR_PULLDOWN_FLAGS=(RT_FindStr(HONOUR_S,"=0",Sig=False,Pos=15) > 0)
if(HONOUR_PULLDOWN_FLAGS) {
FIN_LINE = RT_FileFindStr(VideoFileName,"FINISHED",Sig=False)
Assert(FIN_LINE>=0,myName+"'FINISHED' NOT FOUND in d2v file")
FIN_S = RT_ReadTxtFromFile(VideoFileName,lines=1,Start=FIN_LINE)
IsFILM = (RT_FindStr(FIN_S,"FILM",Sig=False,Pos=9) > 0)
FILM_PERC = RT_NumberValue(FIN_S,Pos=9)
FILM_PERC = (IsFILM) ? FILM_PERC : 100-FILM_PERC
if(FILM_PERC >= 95) {
SS0=RT_String("Calling TFM and TDecimate")
RT_DebugF(SS0,name=myName)
SS0=SS0+Chr(10)
TFM(d2v=VideoFileName)
TDecimate(mode=(TFM_ANIME)?1:0)
}
}
}
}
# Cannot eg Trim/Add frames before here, will interfere with TFM and TDecimate
if(!Defined(FRAME_DAR)) { # Interrogate d2v for FRAME Display Aspect Ratio (incl letterboxing)
FDAR_LINE=RT_FileFindStr(VideoFileName,"Aspect_Ratio=",Sig=False,start=D2V_START,lines=D2V_LINES)
Assert(FDAR_LINE>=0,myName+"'Aspect Ratio' NOT FOUND in d2v file")
FDAR_S=MidStr(RT_ReadTxtFromFile(VideoFileName,lines=1,start=FDAR_LINE),14)
FNDS=RT_String("16:9,625\n16:9,525\n4:3,625\n4:3,525") # DGIndex version of MPEG1 PAR (y/x)
REPS=RT_String("0.7031\n0.8437\n0.9375\n1.1250") # Actual numbers replacing (MPEG1 PAR=y/x)
FDAR_S=RT_StrReplaceMulti(FDAR_S,FNDS,REPS) # Convert MPEG1 625(PAL),525(NTSC) Ratio to number
FDAR_N=Value(FDAR_S) # May be Float
COLON=RT_FindStr(FDAR_S,":") # Ratio ?
FDAR_D=(COLON==0) ? 1 : RT_NumberValue(FDAR_S,Pos=COLON+1)
Assert(FDAR_N>0 && FDAR_D>0,myName+"Error Reading d2v 'Aspect Ratio' (N="+String(FDAR_N)+",D="+String(FDAR_D)+")")
# Get Frame DAR from:- 1:1 SAR, or MPEG2 DAR, or MPEG1 PAR(y/x)
FRAME_DAR=(FDAR_N==1 && FDAR_D==1) ? Float(Width)/Height : (COLON!=0) ? Float(FDAR_N)/FDAR_D : (Float(Width)/Height)/FDAR_N
FRAME_DAR = Round(FRAME_DAR * 1000.0) / 1000.0
If(MEDIAINFO != "" && Exist(MEDIAINFO)) {
MPEG_S = RT_ReadTxtFromFile(VideoFileName,lines=1,start=2)
MPEG_S= RT_TxtGetLine(MPEG_S) # remove newline
M_EXT = RT_GetFileExtension(MPEG_S)
if(M_EXT == ".VOB") {
IFO = RT_FilenameSplit(MPEG_S,7)
IFO = LeftStr(IFO,Strlen(IFO)-1)
IFO = IFO + "0.IFO"
if(Exist(IFO)) {
RT_DebugF("File Is VOB and IFO exists",name=myName)
TMP=RT_GetFullPathName("~"+RT_LocalTimeString + ".txt")
RT_DebugF("Calling MediaInfo on IFO '%s'",IFO,name=myName)
# write Aspect Ratio in form "1.333" to file TMP
result=RT_Call(
\ RT_QuoteStr(MEDIAINFO) +
\ " --LogFile=" +
\ RT_QuoteStr(TMP) +
\ " --Inform=Video;%DisplayAspectRatio% " +
\ RT_Quotestr(IFO)
\ , hide=True,Debug=True
\ )
if(result==0 && Exist(TMP)) {
MI_TXT = RT_TxtGetLine(RT_ReadTxtFromFile(TMP))
RT_FileDelete(TMP)
Val = Value(MI_TXT)
RT_DebugF("MediaInfo Text = %s",MI_TXT,name=myName)
if(Val != FRAME_DAR) {
RT_DebugF("IFO(%f) and d2v(%f) Aspect Ratios DISAGREE, Using IFO AR = %f",Val,FRAME_DAR,Val,name=myName)
Assert(IFO_MODE==1,RT_String("IFO(%f) and d2v(%f) Aspect Ratios DISAGREE\nSet FRAME_DAR manually"
\ ,Val,FRAME_DAR))
FRAME_DAR=Val
} Else {
RT_DebugF("IFO and d2v Aspect Ratios AGREE on %f",FRAME_DAR,name=myName)
}
} Else {
RT_DebugF("MediaInfo Fails, result = %d",result,name=myName)
}
}
}
}
}

PROCESSNAME=RT_GetProcessName()
XMOD = (XMOD!=0) ? XMOD : RT_ColorSpaceXMod()
WMOD = (WMOD!=0) ? WMOD : (IsYUV() && RT_TxtFindStr(WMOD4_PROGS,PROCESSNAME,Sig=False)>=0) ? 4 : RT_ColorSpaceXMod
HMOD = Max(RT_ColorSpaceYMod(Laced=false),2)
RT_DebugF("ProcessName = %s WMOD=%d HMOD=%d",PROCESSNAME,WMOD,HMOD,name=myName)
OUT_DAR =Float(OUT_DAR)
OUT_SAR =Float(OUT_SAR)
SAR=RT_GetSAR(FRAME_DAR) # Sample (pixel) aspect ratio of input frame
SS1=RT_String("INPUT: %dx%d DAR=%.3f SAR=%.3f FAR=%.3f",Width,Height,FRAME_DAR,SAR,Float(Width)/Height)
RT_DebugF(SS1,name=myName)
SS1=SS0+SS1
RoboCrop(samples=SAMPLES,thresh=THRESH,cropmode=CROPMODE,debug=ROBOCROP_DEBUG,hmod=HMOD,Laced=false)
DAR=RT_GetDAR(SAR) # Image DAR after RoboCrop'ed letterboxing
SS2=RT_String("RoboCrop: %dx%d DAR=%.3f SAR=%.3f FAR=%.3f",Width,Height,DAR,SAR,Float(Width)/Height)
RT_DebugF(SS2,name=myName)
if(OUT_DAR_IS_LIMIT && OUT_DAR > DAR) {
OUT_DAR = DAR # Do not report Error, we are just limiting DAR
RT_DebugF("Ignoring OUT_DAR, (RoboCrop'ed DAR is Less))",name=myName)
}
Assert(OUT_DAR <= DAR,"OUT_DAR("+String(OUT_DAR,"%.3f") + ") Must be <= DAR("+String(DAR,"%.3f")+")")
OUT_SAR = (OUT_SAR == 0.0) ? SAR : OUT_SAR
OUT_DAR = (OUT_DAR == 0.0) ? DAR : OUT_DAR
OUT_HEIGHT=OUT_HEIGHT/HMOD*HMOD
OUT_WIDTH =OUT_WIDTH /WMOD*WMOD
H = (OUT_HEIGHT == 0) ? Height : OUT_HEIGHT # RoboCrop'ed OR user supplied resize height
# If OUT_WIDTH==0 Then use H(Height or user OUT_HEIGHT) & OUT_SAR(SAR or user OUT_SAR) to calc output width ELSE user OUT_WIDTH.
W = (OUT_WIDTH==0) ? Int(H * OUT_DAR / Float(OUT_SAR) / WMOD) * WMOD : OUT_WIDTH
if(OUT_WIDTH==0 && H==Height && OUT_SAR==SAR) { # Output RoboCrop'ed Width,Height, No resize, non-fractional cropping
CROP_WIDTH = W # Crop Only, maintain SAR, with approx OUT_DAR (occurs when original OUT_WIDTH==0 and OUT_HEIGHT==0 and OUT_SAR==0.0)
CROP_LEFT = Int((Width - CROP_WIDTH) * 0.5 / XMOD + 0.5) * XMOD # Crop centering, CROP_WIDTH and CROP_LEFT are Int
} Else { # Crop/Resize with fractional cropping to OUT_DAR
CROP_WIDTH = Width * (Float(OUT_DAR) / DAR)
CROP_LEFT = (Width - CROP_WIDTH) * 0.5 # Crop centering, CROP_WIDTH and CROP_LEFT are Float
}
# Now decide none, crop only, or crop/resize. CROP_WIDTH and CROP_LEFT may be Int or Float.
if(CROP_WIDTH==Width && CROP_LEFT==0 && W==Width && H==Height) {
SS3=RT_String("NO CROP/RESIZE, %dx%d DAR=%.3f",Width,Height,DAR)
} Else if(Int(CROP_LEFT/XMOD)*XMOD == CROP_LEFT && CROP_WIDTH==W && H==Height) { # Crop Only
CROP_LEFT=Int(CROP_LEFT)
CROP_WIDTH=Int(CROP_WIDTH)
Crop(CROP_LEFT,0,CROP_WIDTH,-0) # Cropping does not alter SAR
DAR=RT_GetDAR(SAR) # Calc resultant DAR after crop
SS3=RT_String("Crop(%.d, %d, %d, %d)",CROP_LEFT,0,CROP_WIDTH,-0)
} Else {
DAR=RT_GetCropDAR(DAR,CROP_LEFT,0,CROP_WIDTH,-0) # Pre-calc resultant DAR of Last clip, after possible fractional cropping
Spline36Resize(W,H, CROP_LEFT,0,CROP_WIDTH,-0)
SAR=RT_GetSAR(DAR) # Calc new SAR due to Resizing
SS3=RT_String("Resize(%d,%d, %.1f, %d, %.1f, %d)",W,H, CROP_LEFT,0,CROP_WIDTH,-0)
}
RT_DebugF(SS3,name=myName)
SS9=""
if(STRENGTH>0.0) { # Auto Luma Levelling
Eval(RT_QueryLumaMinMax(samples=SAMPLES,debug=AUTOLEVEL_DEBUG)) # Get luma min/max over SAMPLES frames
if(IsRGB()) { CSMin = 0 CSMax = 255 }
else { CSMin = 16 CSMax = 235 }
ALMin = Int(CSMin - ((CSMin - QLMMMin) * STRENGTH) + 0.5) # Round Up
ALMax = Int(CSMax - ((CSMax - QLMMMax) * STRENGTH)) # Round down
if(ALMin!=CSMin || ALMax != CSMax) {
SS9=RT_String("Levels(%d,1.0,%d,%d,%d,Coring=False)",ALMin,AlMax,CSMin,CSMax)
Levels(ALMin,1.0,ALMax,CSMin,CSMax,Coring=False) # DO NOT use Coring
}
}
RT_DebugF ("%s\nOUT: %dx%d DAR=%.3f SAR=%.3f FAR=%.3f ",SS9,Width,Height,DAR,SAR,Float(Width)/Height,name=myName)
(SHOW) ? RT_Subtitle("%s\n%s\n%s\n%s\nOUT: %dx%d DAR=%.3f SAR=%.3f FAR=%.3f",SS1,SS2,SS3,SS9,Width,Height,DAR,SAR,Float(Width)/Height) : NOP
RT_SignalDar(OUT_DAR) # Tell MeGUI the Exact required Display Aspect Ratio rather than approximate.
RT_DebugF("Signalled MeGUI DAR=%f MeGUI_DarX=%d MeGUI_DarY=%d",OUT_DAR,MeGUI_DarX,MeGUI_DarY,name=myName)
ConvertToYV12
# FFT3DFilter(Sigma=1.6,plane=0,Sharpen=0.03)
""")
Return Last

Forensic
26th January 2015, 01:50
@StainlessS
If RT_Stats supports it for a planar video, what is the command to change every pixel with Y=250 pixel to now be Y=180? (my current method is extremely slow). Thank you in advance.

StainlessS
27th January 2015, 10:11
If RT_Stats supports it for a planar video, what is the command to change every pixel with Y=250 pixel to now be Y=180? (my current method is extremely slow).

Sorry Forensic, nothing to do that (that would require a standard filter rather than a runtime environment function).
How about MaskTools Lut stuff ?

EDIT:
Maybe something like this:

# Return Clip Difference of input clips (amp==true = Amplified, show==true = show background)
Function ClipDelta(clip clip1,clip clip2,bool "amp",bool "show") {
amp=Default(amp,false)
show=Default(show,false)
c2=clip1.levels(128-32,1.0,128+32,128-32,128+32).greyscale()
c1=clip1.subtract(clip2)
c1=(amp)?c1.levels(127,1.0,129,0,255):c1
return (show)?c1.Merge(c2):c1
}

Avisource("Test_hotspot.avi").ConvertToYV12()
ORG=Last
#TARGET= 250
TARGET= 200
SWAP = 180
#S=RT_string("(x==%d) ? %d : x",TARGET,SWAP)
S=RT_string("(x>=%d) ? %d : x",TARGET,SWAP)
q=MT_Polish(S)
RT_DebugF("%s\n%s",S,Q)
MT_lut(MT_Polish(S),U=2,V=2)

D1=ClipDelta(ORG,Last)
D2=ClipDelta(ORG,Last,Amp=True)

T= StackHorizontal(ORG,Last)
B= StackHorizontal(D1,D2)
StackVertical(T,B)


There dont seem to be any Luma of 250 so I modded a bit to do something (uncomment relevant lines)

Forensic
27th January 2015, 20:59
Worked like a charm. Thank you!!!!!

martin53
7th February 2015, 10:19
Sorry my question is off topic here - but I didn't dare to post in the AviSynth release thread since I believe this question must be too stupid. And since I used RT_Stats for my test below, it's at least a little related to this thread ;)

Problem: With the most recent AviSynth 2.60 RC1, the AviSynth.h from this distribution, empty NegInvert/Simplesample and VS Express 2013, I just couldn't successfully use a "LoadPlugin()" command in AvsPmod (V2.51).
There is always a crash window like
Traceback (most recent call last):
File "avsp.pyo", line 9295, in OnMenuVideoRefresh
File "avsp.pyo", line 14083, in ShowVideoFrame
File "avsp.pyo", line 14598, in UpdateScriptAVI
File "pyavs.pyo", line 138, in __init__
File "pyavs.pyo", line 249, in CreateErrorClip
UnicodeDecodeError: 'ascii' codec can't decode byte 0x83 in position 24: ordinal not in range(128)
I fiddled the whole day because I thought I made some mistake regarding Unicode/multibyte characters, created new projects, installed VC2010 :confused:
Finally I decided to test the same thing with a proved plugin like RT_Stats (your honor, StainlessS).
And
LoadPlugin("C:\RT_Stats26.dll")
Version()

fails the same. Vdub fails, too (less copy/paste friendly). Same with AviSynth26a5.

But I can use RT_Stats26.dll and my VC2013-compiled test plugin from the autoload plugin directory! (I just did not want to include my work in progress there too soon, but instead only load it into a designated test script)

Question: I read the AviSynth manual (the LoadPlugin section), looks to me as if LoadPlugin is still the right command. Can someone please retest, and any idea what I am doing wrong?

Groucho2004
7th February 2015, 10:53
What does VDub report?

martin53
7th February 2015, 14:18
Thanks to Au3Info_x64:
Avisynth open failure:
LoadPlugin: ƒvƒ‰ƒOƒCƒ“‰Š‰ƒGƒ‰[
(......\__TestScript.avs, line 1)
And this is exactly the same error message I get when I provide a non-existent filename, an invalid path, or an empty string to the function.

Groucho2004
7th February 2015, 15:14
Post the script (the actual .avs file, don't just paste the content here).

StainlessS
7th February 2015, 16:28
I defer to the right honourable Groucho2004 on this.
Martin53, that was a real long safari you were on, me thought you got eaten by Lions and Tigers and Bears! Oh my!

StainlessS
7th February 2015, 19:44
Same problem was reported here, although there does not seem to be any indication of the cause.
http://forum.doom9.org/showthread.php?p=1697206#post1697206

martin53
7th February 2015, 20:31
Post the script (the actual .avs file, don't just paste the content here).

With all respect - are you asking me to add a 14 characters text file as an attachment, instead of copying it into the post, or do I get you wrong? I wrote several of these scripts and all do the same. Open AvsPmod, File|New, type LoadPlugin("") and press F5. That's all.

@StainlessS: I wasn't away all the time, but busy ... Nice to feel you're glad I post again.

StainlessS
7th February 2015, 20:44
Yep, I saw you about 2 or 3 weeks ago.
I think Grouchy may have wanted to view in HEX/ASCII editor, have you viewed in HEX ?
Also, if you have some free time, could you take a gander at this:- http://forum.doom9.org/showthread.php?p=1708424#post1708424
Any comments appreciated.

StainlessS
7th February 2015, 20:51
Here same 0xC1 error as reported in link to similar problem as in post #323.
http://forum.doom9.org/showthread.php?p=1696498#post1696498

Perhaps you just copied runtimes into system32/SysWOW64 instead of using installer. (also might require more current version).

EDIT: Your attached file just looks like plain ASCII. Above should fix your problem I think (reinstall latest runtimes, not copy).

martin53
7th February 2015, 22:02
1st of all, thanks for the support!

I remember two things: when I ran the installer, I got a windows compatibility problem assistant window - or how that may be called in english. After the installer had finished, it proposed to run it again with the proposed compatibility settings; and since I did not see an objection, I confirmed that, so I effectivly ran the installer twice.
Today, when I first opended AVSInfoTool127, it showed the old 26a5 version first, but after some seconds, without any intervention from my side, the GUI kinda reopened and showed RC1. When I ran AVSInfoTool again, I think it re-opened once more after some 5 or 10 seconds, but before and afterwards it always showed RC1.
'Version()' also shows RC1.
The dll in C:\Windows\system32 is 393 kB, with date 01-13-2015, as is the one in SysWOW64.

I just removed the compatibility settings for the installer and re-installed, same. Then uninstalled via control panel / reinstalled with installer: Same.

EDIT I don't remember copying/moving dlls manually on this machine. Of the MS VS redistributalbles, these are installed (read from control panel):
2005 8.0.56336 426KB and 8.0.50727.42
2005 (x64) 8.0.61000
2008 x64 9.0.30729.6161
2008 x86 9.0.21011, 9.0.30729, 9.0.30729.17, 9.0.30729.4974 and 9.0.30729.6161
2010 x64 10.0.40219
2010 x86 10.0.40219
Visual Studio 2012 x64 Redistributables 14.0.0.1 (*not* 'Microsoft Visual C++ 20xx Redistributable...')
Visual Studio 2012 x86 Redistributables 14.0.0.1
2013 x64 12.0.30501
2013 x86 12.0.30501

Groucho2004
7th February 2015, 22:08
Today, when I first opended AVSInfoTool127, it showed the old 26a5 version first, but after some seconds, without any intervention from my side, the GUI kinda reopened and showed RC1. When I ran AVSInfoTool again, I think it re-opened once more after some 5 or 10 seconds, but before and afterwards it always showed RC1.
I can't even begin to imagine how this could happen. Something really fishy going on on your system. Sorry, at this point I have no advice.

Wilbert
7th February 2015, 23:17
Do you have multiple avisynth.dll's on your system?

StainlessS
8th February 2015, 01:18
Hi people. Just warning of removal of two functions from RT_Stats.

RT_ArrayGetNels(string FileName)
Filename, Array Filename, no default.
Returns int, total number of elements in array as set by RT_ArrayAlloc, or current number of elements if RT_ArrayAppend used to add
elements to end of single dimension array, or RT_ArrayExtend used to increase Dim1 dimension.
For a 3 dimensional array where Dim1=10, Dim2=20,Dim3=30 would return 10*20*30 ie 6000.

***
***
***

RT_ArrayGetNelMax(string FileName)
Filename, Array Filename, no default.
Returns int, maximum number of elements that could theoretically be stored in current array, taking into account the
current number of dimensions and the size of dimensions 2 and 3.


Dont know if anybody (but me) actually uses the ARRAY functions, dont think these two funcs are too important.
Reason is that I will be implementing file size greater than 2GB and those fn's will in some cases not be able to return the total number
of elements in an ARRAY.

I have so far implemented for big DBase file, described a bit here:

RT_DBaseRecordsMax(String Filename,Bool "Current"=True)
Filename, DBASE Filename, no default.
Return maximum number of records that can be stored in the DBase file.
When Current==True (default [new argument v1.45]) takes into account the file system and space on drive available to
the user (ie takes into account user disk space quotas, and eg FAT32 file system).
When Current==False, (as pre v1.45) returns maximum number of records that could be stored in file based on
Min((256GB - 1MB - DBase header size) / Record Size, $7FFFFFFE) [where record size is sum of all field sizes].
So, new to v1.45, shows as default the current maximum which will vary if copied to eg FAT32 filesystem, or when disk
space is reduced. Maximum possible file size has been limited to about 256GB, for no particular reason, maximum number of
records is $7FFFFFFE, ie maximum +ve integer - 1 (a lil bit more than 2 billion). Where available disk space is 'unlimited',
max size will still be limited to about 256GB or $7FFFFFFE records.


Hope the changes do not cause major problems for anyone, say here if they do, and make alternative suggestions if you have any.

Think I might also take this opportunity to remove some args from these two function, below

RT_LumaSceneChange(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(Width>1100||Height>600?3:2), \
Float "Bias"=0.0,Float "Gain"=1.0,Float "Cont"=1.0,Float "Rpow"=1.0,Float "Spow"=1.0,Float "SPMid"=0.5,Bool "Pord"=false)

RT_LumaMovement(clip,clip2,int "n"=current_frame,int "delta"=0,int "x"=0,int "y"=0,int "w"=0,int "h"=0,
int "n2"=current_frame,int "delta2"=0,int "x2"=x,int "y2"=y,bool "interlaced"=false,int "Matrix"=(Width>1100||Height>600?3:2),
int "Mode"=0,int "BlkW"=64,int "BlkH"=64 \
Float "Bias"=0.0,Float "Gain"=1.0,Float "Cont"=1.0,Float "Rpow"=1.0,Float "Spow"=1.0,Float "SPMid",Bool "Pord"=false)


The above args seemed like a good idea at the time, and were only included as part of a bug fix update, left in before I could verify if there were of much use.
They seem not to be much use at all, except with occasional clip [unfortunately, the only clip I had tested with was such a clip].

EDIT: This function will still be available (although not implemented quite like described).

RT_ArrayGetDim1Max(string FileName)
Filename, Array Filename, no default.
Returns int, maximum theoretical Dim1 dimension for the current array with current fixed size Dim2 and Dim3 dimensions.
For 1 dimension Array: (maximum +ve integer - header size) / ElSize.
For 2 dimension Array: (maximum +ve integer - header size) / (ElSize * Dim2).
For 3 dimension Array: (maximum +ve integer - header size) / (ElSize * Dim2 * Dim3).


Also this

RT_ArrayGetDim(string FileName,int "Dim"=0)
Returns number of dimensions in array or the size of any 1 of the dimensions.
Filename, Array Filename, no default.
Dim, default 0. (Range 0 -> 3).
0, returns the number of dimensions in the array.
1->3, returns size of that dimension.
Invalid dimensions will return 0, eg RT_ArrayGetDim(FileName,Dim=2) on single dimension array returns 0.
Error if Dim less than than 0 or greater than 3.

martin53
8th February 2015, 09:20
Do you have multiple avisynth.dll's on your system?

Thanks for your attention also, Wilbert! No, only one AviSynth install.

But I got the guilty.:devil:
It is LoadPluginEx.dll from 11-03-2003, size 60KB, part of the warpsharppackage_25_dll_20031103, this package is in my autoload plugins folder. I'll see if I'll have problems when I move the dll to a quarantine folder.

Again - that was really quick how you all responded and gave good hints!:thanks:

martin53
8th February 2015, 09:35
Dont know if anybody (but me) actually uses the ARRAY functions

My 2013 AWB script heavily uses arrays, but not RT_ArrayGetNels(). It also uses RT_LumaSceneChange(), but not with the red arguments. :)

StainlessS
8th February 2015, 18:36
@M53, I guess this has probably been suggested already, but Groucho2004 Avisynth Info Tool Avisynth Info Tool
is pretty good, if it points out any C plugins, would be best to move to separate directories (other than autoload plug), and separate for
C v2.0 and later C plugins as they both have differing load function requirements.

Ah good, somebody does use those ARRAY funcs, I shall probably do ARRAY utility funcs to read in frame to ARRAY and write to frame from ARRAY,
and probably histogram reading funcs.
Removal of the Bias etc args from those other funcs would allow me to not consider them dead functions, and I could now perhaps improve.
Thanx for you reply.

martin53
7th March 2015, 10:51
StainlessS,
I recently mulled over StrReplace.
Today, there are two algorithms. One locates the find substring in the input, takes the left part until the found position from the input string plus concatenated replacement string as preliminary output, and continues search after the position plus length of the find string.
The alternative, known as StrReplaceDeep, does not put the replacement string to the preliminary output without ever searching it, too, but puts it left to the next recursion's input string.
Both suffer from specific drawbacks, which can make them unexpectedly unsuitable. #1 does not recursively replace("......", "..", ".") to "." since find matches that start inside the replacement string are not found. #2 becomes a black hole if the replacement string contains the full find string.

The best method to cover both drawbacks is, to my opinion, to use 'as much as possible' of the replacement string for the next find recursion. 'As much as possible' can easily be identified as 'at least one character of the original input string after the find string must be included', i.e. only the right part of the replacement string which is 1 char shorter than the find string, plus the remaining input string give the next input string. The left part of the replacement string which needed to be cut off is directly concatenated to the preliminary output string.
Function StrReplace(string s,string find,string replace) # Repeated, string replacements
# Original:- http://forum.doom9.org/showthread.php?t=147846 By Vampiredom, Gavino, IanB
{k=StrLen(replace)-min(StrLen(replace),StrLen(find)-1) i=s.FindStr(find) return(i==0?s:s.LeftStr(i-1)+replace.LeftStr(k)+(replace.MidStr(k+1)+s.MidStr(Strlen(find)+i)).StrReplace(find,replace))}
My suggestion is that this implementation replaces both RT_StrReplace and RT_StrReplaceDeep.

martin53
8th March 2015, 11:05
The embedded script implements part of AvsInfoTool with the help of the RT_InternalFunctions(), RT_PluginFunctions() and RT_FSelSaveAs() functions.

It also calls each function to retrieve the type of the return value.
Some functions make the system crash or hang - an indication that they are not tolerant against unreasonable input values. A list of such functions, and a prepared return value instead of the call helps against that.

The intention is to show the functionality of the RT_Stats plugin and to obtain a list of all functions you have on your system. Maybe you didn't know one or the other.
Try {RT_Version()} catch (msg) {assert(false,"This script requires the RT_Stats plugin.")}
Try {GEval("")} catch (msg) {assert(false,"This script requires the GScript plugin.")}

#============================================================================
Filename=RT_FSelSaveAs(title="Save Filter list",dir="",filt="Text files|*.txt",fn="_AllFunctions.txt",debug=true)
Assert(FileName.IsString(), "Please provide a file name to save the filter list")

#============================================================================
RT_WriteFile(Filename, VersionString(), Append=false)
WriteInternalFunctionsSyntax(RT_InternalFunctions(), Filename)
WritePluginFunctionsSyntax(RT_PluginFunctions(), Filename)
BlankClip().subtitle("Function info is complete.",align=5)

#============================================================================
function WriteInternalFunctionsSyntax(string fu_list, string Filename) {
GScript("""
done=""
while(fu_list != "") {
i = FindStr(fu_list+" ", " ")
fu_name = LeftStr(fu_list, i-1)
fu_list = MidStr(fu_list, i+1)
params = RT_PluginParam(fu_name)
if (FindStr(done, fu_name+params)==0) {
done = done + " "+fu_name+params
RT_WriteFile(Filename, "internal %s ( %s ) -> %s", fu_name, params, GetReturnType(fu_name, params), Append=true)
}
}
""")
}
#============================================================================
function WritePluginFunctionsSyntax(string fu_list, string Filename) {
GScript("""
done=""
while(fu_list != "") {
i = FindStr(fu_list+" ", " ")
fu_name = LeftStr(fu_list, i-1)
fu_list = MidStr(fu_list, i+1)
i = FindStr(fu_name, "_")
if (i>0) {
params = RT_PluginParam(fu_name)
if (FindStr(fu_list, "_"+fu_name)==0 && FindStr(done, "_"+fu_name+params)==0) {
done = done + " _"+fu_name+params
RT_WriteFile(Filename, "plugin %s ( %s ) -> %s", fu_name, params, GetReturnType(fu_name, params), Append=true)
}
}
}
""")
}
#============================================================================
#function GetReturnType(string fu, string params) { return "?" }
#============================================================================
function GetReturnType(string fu, string params) {
GScript("""
RT_DebugF("Fu=%s %s", fu, params, name="GetReturnType")
if (MidStr(fu,3,1)=="+") {fu = LeftStr(fu,2)+MidStr(fu,2)}
if (MidStr(fu,2,1)=="+") {fu = LeftStr(fu,1)+fu}
else if (fu=="Assert") {return "conditional halt"}
else if (FindStr(fu, "avss_26_DSS2")>0) {return "clip"}
else if (FindStr(fu, "ImageSeq_")>0) {return "clip"}
else if (FindStr(fu, "LoadCPlugin")>0) {return "void"}
else if (FindStr(fu, "LoadVirtualdubPlugin")>0) {return "void"}
else if (FindStr(fu, "MDepan")>0) {return "clip"}
else if (FindStr(fu, "MSCDetection")>0) {return "clip"}
else if (FindStr(fu, "ResampleAudio")>0) {return "clip"}
else if (FindStr(fu, "Resize")>0) {return "clip"}
else if (FindStr(fu, "RT_FSel")>0) {return ". "}
else if (FindStr(fu, "Source")>0) {return "clip"}
else {
bc = BlankClip(width=8,height=8,length=1,pixel_type="YV12")
fp = LeftStr(params,2)=="cc" ? "(bc,bc)"
\ : LeftStr(params,2)=="cf" ? "(bc,0.1)"
\ : LeftStr(params,3)=="cci" ? "(bc,bc,0)"
\ : LeftStr(params,5)=="ciiii" ? "(bc,0,0,0,0)"
\ : LeftStr(params,4)=="ciii" ? "(bc,0,0,0)"
\ : LeftStr(params,3)=="cii" ? "(bc,0,0)"
\ : LeftStr(params,2)=="ci" ? "(bc,0)"
\ : LeftStr(params,1)=="c" ? "(bc)"
\ : LeftStr(params,2)=="ff" ? "(0.1,0.1)"
\ : LeftStr(params,1)=="f" ? "(0.1)"
\ : LeftStr(params,2)=="ii" ? "(0,0)"
\ : LeftStr(params,1)=="i" ? "(0)"
\ : LeftStr(params,2)=="ss" ? "("+chr(34)+"1"+chr(34)+","+chr(34)+"1"+chr(34)+")"
\ : LeftStr(params,2)=="si" ? "("+chr(34)+"1"+chr(34)+",1)"
\ : LeftStr(params,1)=="s" ? "("+chr(34)+"1"+chr(34)+")"
\ : "()"
Try {
r = Eval("current_frame=0 "+fu+fp)
r = r.IsBool ? "bool" : r.IsClip ? "clip" : r.IsInt ? "int" : r.IsFloat ? "float" : r.IsString ? "string" : "?"}
catch (msg) { Try {r = r.IsBool ? "bool" : r.IsClip ? "clip" : r.IsInt ? "int" : r.IsFloat ? "float" : r.IsString ? "string" : "?" } catch(msg) {r = "?"}
}
if (r=="?") {
bc = BlankClip(width=8,height=8,length=1,pixel_type="RGB32")
fp = LeftStr(params,2)=="cc" ? "(bc,bc)"
\ : LeftStr(params,2)=="cf" ? "(bc,0.1)"
\ : LeftStr(params,3)=="cci" ? "(bc,bc,0)"
\ : LeftStr(params,5)=="ciiii" ? "(bc,0,0,-0,-0)"
\ : LeftStr(params,4)=="ciii" ? "(bc,0,0,0)"
\ : LeftStr(params,3)=="cii" ? "(bc,0,0)"
\ : LeftStr(params,2)=="ci" ? "(bc,0)"
\ : "(bc)"
Try {
r = Eval("current_frame=0 "+fu+fp)
r = r.IsBool ? "bool" : r.IsClip ? "clip" : r.IsInt ? "int " : r.IsFloat ? "float" : r.IsString ? "string" : "?"
} catch (msg) {
r = "?"
}
}
if (r=="?" && LeftStr(params,1)=="c") {r="clip?"}
return r
}
""")
}

Groucho2004
8th March 2015, 11:27
The attached script implements part of AvsInfoTool with the help of the RT_InternalFunctions(), RT_PluginFunctions() and RT_FSelSaveAs() functions.
Don't attach stuff here, it could take days to be approved. Post it to pastebin or similar.

martin53
8th March 2015, 12:11
Don't attach stuff here, it could take days to be approved. Post it to pastebin or similar.

Hmm, my opinion: better days to be approved than deleted in a few months. I embedded it directly now.

creaothceann
8th March 2015, 13:22
You can specify on pastebin that it should never be deleted.

StainlessS
9th March 2015, 20:10
M53,
There is requirement for both, deep replacement is rarely needed and would yield unexpected results on occasion.
There is no 'black hole' as you suggest.
(NOTE, the link given in your version [removed here] as original source of StrReplace is actually a link to GScript thread.)

I did not implement RT_StrReplaceDeep, exactly as in script version, it does if you like, 'super deep' replacement, ie rescans even prior to
replacements, perhaps it should not, I will reconsider there.

Note, snip below (excluding M53 version) implements bug fixes for the v2.58 string concatenation bug.


# test 1
SOUR = "......"
FND = ".."
REP = "."
# result
# '......' # SOUR
# '...' # ORG_StrReplace
# '...' # RT_StrReplace
# '.' # M53_StrReplace
# '.' # StrReplaceDeep
# '.' # RT_StrReplaceDeep

# test 2
#SOUR = ".... .. ...."
#FND = ".. "
#REP = " ."
# result
# '.... .. ....' # SOUR
# '.. . .....' # ORG_StrReplace
# '.. . .....' # RT_StrReplace
# '.. . .....' # M53_StrReplace
# '.. . .....' # StrReplaceDeep
# ' ......' # RT_StrReplaceDeep, As implemented, rescans whole string (even prior to current replaced)

# test 3, 'Black hole does not exist !
SOUR = ".... .. ...."
FND = ".."
REP = "...."
# result
# '.... .. ....' # SOUR
# '........ .... ........' # ORG_StrReplace
# '........ .... ........' # RT_StrReplace
# '.......... .... ..........' # M53_StrReplace : whats with this ???
# '........ .... ........' # StrReplaceDeep
# '........ .... ........' # RT_StrReplaceDeep (only deep if Replace string shorter than Find string).

# test 4, Original requirement test (compact SPACE, ie ALL ' ' to ' ')
SOUR = "[10] 9 -0.13 0.16 0.004 0.99927"
FND = " "
REP = " "
# result
# '[10] 9 -0.13 0.16 0.004 0.99927' # SOUR
# '[10] 9 -0.13 0.16 0.004 0.99927' # ORG_StrReplace
# '[10] 9 -0.13 0.16 0.004 0.99927' # RT_StrReplace
# '[10] 9 -0.13 0.16 0.004 0.99927' # M53_StrReplace
# '[10] 9 -0.13 0.16 0.004 0.99927' # StrReplaceDeep
# '[10] 9 -0.13 0.16 0.004 0.99927' # RT_StrReplaceDeep (only deep if Replace string shorter than Find string).


S = ORG_StrReplace (SOUR,FND,REP)
SS = RT_StrReplace (SOUR,FND,REP)
SSS = M53_StrReplace (SOUR,FND,REP)
SSSS = StrReplaceDeep (SOUR,FND,REP)
SSSSS = RT_StrReplaceDeep(SOUR,FND,REP)

blankclip

return RT_Subtitle("'%s'\n'%s'\n'%s'\n'%s'\n'%s'\n'%s'",SOUR,S,SS,SSS,SSSS,SSSSS)


# Note, recursively calls ORG_StrReplace not StrReplace
function ORG_StrReplace(string s, string find, string replace) {
# # Original:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 : By Vampiredom, Gavino, IanB
# i = s.FindStr(find)
# return (i == 0 ? s : s.LeftStr(i-1)+replace+s.MidStr(Strlen(find)+i).StrReplace(find, replace))
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
i=s.FindStr(find)
return(i==0?s:RT_StrAddStr(s.LeftStr(i-1),replace,s.MidStr(Strlen(find)+i).ORG_StrReplace(find,replace)))
}

# Note, recursively calls M53_StrReplace not StrReplace
Function M53_StrReplace(string s,string find,string replace) {
k=StrLen(replace)-min(StrLen(replace),StrLen(find)-1)
i=s.FindStr(find)
return(i==0?s:s.LeftStr(i-1)+replace.LeftStr(k)+(replace.MidStr(k+1)+s.MidStr(Strlen(find)+i)).M53_StrReplace(find,replace))
}

# Note, recursively calls ORG_StrReplace not StrReplace
Function StrReplaceDeep(string s,string find,string replace) # DEEP Repeated, string replacements
# When replacing eg pairs of SPACE characters by single SPACE, StrReplace can leave some pairs non replaced.
# Assumes that you want to rescan where replaced string could constitute part of a new find substring,
# Length of replace must be shorter than length of find, else will call StrReplace instead.
# Based On:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
# {i=s.FindStr(find)return i==0?s:s.LeftStr(i-1)+( strlen(replace)<strlen(find)? \
# StrReplaceDeep(replace+s.MidStr(Strlen(find)+i),find,replace) : replace+StrReplace(s.MidStr(Strlen(find)+i),find,replace))}
# Converted to use RT_Stats RT_StrAddStr() to avoid 2.58/2.6a3 string concatenation bug:-
{
i=s.FindStr(find)
return i==0?s:RT_StrAddStr(s.LeftStr(i-1),( strlen(replace)<strlen(find)
\ ? StrReplaceDeep(RT_StrAddStr(replace,s.MidStr(Strlen(find)+i)),find,replace)
\ : RT_StrAddStr(replace,ORG_StrReplace(s.MidStr(Strlen(find)+i),find,replace))))
}




EDIT: Cocked up the 'black hole test', EDITED.

EDIT: Note, some functions (including some of mine) return variable result types, eg -ve int to denote error, or float result.
EDIT: Or eg DBase funcs return any type.

EDIT: Original post of StrReplaceDeep:- http://forum.doom9.org/showthread.php?p=1596053#post1596053

martin53
9th March 2015, 21:01
(NOTE, the link given in your version [removed] as original source of StrReplace is actually a link to GScript thread.)
Umm... maybe once did an overshoot replace in my scripts collection, will immediately correct that.
# test 3, 'Black hole does not exist !
SOUR = ".... .. ...."
FND = ".."
REP = "...."
# result
# '........ .... ........' # ORG_StrReplace
# '........ .... ........' # RT_StrReplace
# '.......... .... ..........' # M53_StrReplace : whats with this ???
# '........ .... ........' # StrReplaceDeep
# '........ .... ........' # RT_StrReplaceDeep (only deep if Replace string shorter than Find string).
OK, my apologies that I didn't experiment with (RT_-)StrReplaceDeep, but just figured out the algorithm theoretically, and did not take into account the black hole preventer switch that checks if replace is shorter than find. My version does not have that yet, maybe it was introduced after I copied it to my script base.
I thought of that switch, too, but I consider it less reasonable than the new proposal, e.g. with find=".." and replace="blahblah." Also I judge the above M53_StrReplace result OK, since 'you get what you asked for' with computers, not 'what you had in mind to ask for' or whatever. But that is biased for sure. It's a suggestion, I don't insist of course. In my scripts, I remove e.g. repeated empty lines when I open a playlist, thus I needed StrReplaceDeep; but I hate to distinguish between two functions and so use 'M53_StrReplace', as you call it, all over my script base. I'll tell when I'll ever be dissatisfied with it :)

EDIT: Black hole occurs if find string is in replace string? I.e.
Function StrReplaceDeep(string s,string find,string replace)
...
{
i=s.FindStr(find)
return i==0?s:RT_StrAddStr(s.LeftStr(i-1),( strlen(replace)<strlen(find) replace.FindStr(find) == 0
\ ? StrReplaceDeep(RT_StrAddStr(s.LeftStr(i-1),replace,s.MidStr(Strlen(find)+i)),find,replace)
\ : RT_StrAddStr(replace,ORG_StrReplace(s.MidStr(Strlen(find)+i),find,replace)))) # or M53_StrReplace() here
}
green part replaces red part, blue part added because StrReplaceDeep(">>>>><", "><", "<") = ???

StainlessS
9th March 2015, 22:40
Post #339, added test 4, and added SOUR to result comments.

As M53_StrReplace complies with original intent of StrReplaceDeep (SPACE compacting), will modify to use your algo (for RT_StrReplaceDeep).

martin53
12th March 2015, 17:48
Just to satisfy possible interest in solution variants, and as a reference to understand the concepts, my personal - maybe stable - current algo
#=====================================================================================================================
Function StrReplace(string s,string find,string replace) # Repeated, string replacements
# Based On:- http://forum.doom9.org/showthread.php?p=1540504#post1540504 By Vampiredom, Gavino, IanB
{
# use RT_Stats RT_StrAddStr() if present to avoid 2.58/2.6a3 string concatenation bug
function StrAddStr(a,b,c){Try{return RT_StrAddStr(a,b,c)}catch(msg){return a+b+c}}
i=s.FindStr(find) f=StrLen(find) r=StrLen(replace) k=r-min(r,f-1)
return i==0?s:replace.FindStr(find)==0
\ ? StrReplace(StrAddStr(s.LeftStr(i-1),replace,s.MidStr(i+f)),find,replace)
\ : StrAddStr(s.LeftStr(i-1),replace.LeftStr(k),StrReplace(replace.MidStr(k+1)+s.MidStr(i+f),find,replace))
}
#=====================================================================================================================
Function StrReplaceDeep(string s,string find,string replace) # Repeated, string replacements
{return StrReplace(s,find,replace)}
#=====================================================================================================================
with
StrReplace(">>>>>><",">><","><<") == "><<<<<<" (recursive call with later replacements more left in string than previous replacements)
StrReplace(">......",">." ,">.>") == ">.>.>.>.>.>.>" (recursive call with find string in replace string, replace string longer than find string, no black hole)
StrReplace("[10]______9___-0.13____0.16___0.004_0.99927","__","_") == "[10]_9_-0.13_0.16_0.004_0.99927" (original intent)

StainlessS
13th March 2015, 02:47
Thank you M53, bit busy at moment, shall revisit later.

It also uses RT_LumaSceneChange(), but not with the red arguments.

Have now deleted both RT_LumaSceneChange() and RT_LumaMovement() from plug, RT_LumaSceneChange without red args is identical to RT_LumaDifference
and RT_LumaMovement replacing with RT_FrameMovement. Args something like this, (not finalized).


RT_LumaDifference, "cc[n]i[delta]i[x]i[y]i[w]i[h]i[n2]i[delta2]i[x2]i[y2]i[Interlaced]b[matrix]i" # No difference

RT_FrameDifference,"cc[n]i[n2]i[ChromaWeight]f[x]i[y]i[w]i[h]i[x2]i[y2]i[altscan]b" # Additional args after Chromaweight

RT_FrameMovement, "cc[n]i[n2]i[x]i[y]i[w]i[h]i[x2]i[y2]i[altscan]b[matrix]i[Chromaweight]f[blkw]i[blkh]i[Mode]i"
# Mode selects LumaDiff or FrameDiff, perhaps later additional modes.



RT_FrameDifference will implement 'Altscan' (elsewhere uses 'Interlaced' [bad choice of arg name], to mean 'every other line').
May at some point implement eg 'ChromaI' bool used where YV12 interlaced chroma (gets more complicated when mixed with Altscan
and two comparison frames). Also, will 'auto' detect if both gray frames (perhaps 'DetectGray' average pixel difference [EDIT: from gray] float arg, currently 1.0) and switch to ChromaWeight=0.0 if both frames grayscale. (EDIT: For color clips with grayscale scene, eg "A Matter of Life and Death", 'Sin City' might be tricky, best treat as Grayscale all through ie ChromaWeight=0.0)

DBase limit extended to lesser of available disk space, or 1TB-1MB max size or $7FFFFFFE records.
Array to 1TB-1MB, or $7FFFFFFE max dim 1 for 1 dim array. For 2 dim array, total size is 256MB for dim 2, or for 3 dim array is 256MB for elements in
dimensions 2 and 3.

Any of the supplied AVS scipts in zip will be updated to use the new plug versions.
If I have to remove a few funcs, then I might as well do all script breaking changes in one go.

EDIT:
Some additional plugz or modz:

env->AddFunction("RT_ForceProcess", "c[Startframe]i[EndFrame]i", RT_ForceProcess, 0);
env->AddFunction("RT_DBaseGetTypeString", "s",RT_DBaseGetTypeString, 0);
env->AddFunction("RT_DBaseSetID", "si.+",RT_DBaseSetID , 0);
env->AddFunction("RT_DBaseCheckID", "si.+",RT_DBaseCheckID, 0);
env->AddFunction("RT_ArraySetID", "si.+",RT_ArraySetID , 0);
env->AddFunction("RT_ArrayCheckID", "si.+",RT_ArrayCheckID, 0);


RT_ForceProcess scans clip (possibly extended to audio too at some future point, If I can get TWriteAVI to support audio out).
RT_DBaseGetTypeString, used to duplicate a DBase with identical fields.
RT_DBaseSet/CheckID (and array ver$), can set or check multiple DBase/Array ID's in one call.
Number of DB/ARR ID's raised from 16 to 128.

EDIT: On 2nd thoughts, think I limited DBase/Arr to lesser of Available_DiskSpace-1MB or 1TB, and not 1TB-1MB.

EDIT: "A Matter of Life and Death" (http://en.wikipedia.org/wiki/A_Matter_of_Life_and_Death_%28film%29)
originally released in USA as "Stairway to Heaven".

StainlessS
20th April 2015, 02:53
Yo dudes.
Anybody ever heard of a plugin to determine if a clip/range is Grayscale ? (did search on IsGray/IsGrayScale and variant spellings).
I'm gonna implement (well basically have already), with x,y,w,h frame coords, and alternate raster line scanning.
What I've done works on Planar YUY2 and RGB, and should be very fast (or slower if you demand full scan).
Could set Local var with eg ISGrayScale bool, and/or metric on Grayness.
Should be very fast on colour ranges where Only IsGrayScale bool result is required, would exit scan when threshold number of pixels exceeded,
could test after every scanline and so avoid full frame scan when determined to be color.
For YUV, % threshold number of pixels varying from $xx8080.
For RGB, % threshold number of pixels varying from Min(R,G,B) == Max(R,G,B).
This will be implemented as runtime Function in RT, any interest in a separate standard plugin ? (does one already exist ?)

EDIT: Actually IsColor() would maybe more appropriate as above % threshold of pixels varying from Gray could return True (in RT runtime or as local var in filter plug) or set metric if required where % of pixels not gray could be rendered on frame and/or set as local var (slower if render or set local scan full metric). IsColor() does not show in search either.

EDIT: Got me a yodelling fox outside right now, 03:22 AM :)
EDIT: A couple of days ago a fox casually sauntered past me about 5 feet away, did not even bother looking at me,
they are getting really cheeky nowadays in London.
EDIT: And the escaped green parakeets are all over the place for the past couple of years. (group escape about 30 years ago
in Richmond Park).

EDIT: Modded IsColor() type func to count differences from Gray more like so.
Let Cdf = allowed maximum difference from Gray that will NOT be counted (default 0),
Let CTh = % Threshold to calculate number of differences that are more than CDf away from Gray.
PixLim=(xdim*yDim) * CTh / 100.0 * 2 [two counts, for U+V for YUV, and Max(R,G,B)-Mid(R,G,B) and Mid(R,G,B)-Min(R.G,B) for RGB]
YUV

if(Abs(u-128)>CDf) Then Cnt=Cnt+1
if(Abs(v-128)>CDf) Then Cnt=Cnt+1

... Later

return (Cnt > Pixlim) # If color return True


RGB

if(Max(R,G,B)-Mid(R,G,B)>CDf) Then Cnt = Cnt + 1
if(Mid(R,G,B)-Min(R,G,B)>CDf) Then Cnt = Cnt + 1

... Later

return (Cnt > Pixlim) # If color return True


EDIT: Or perhaps more like so (more precise control for CDf).
Let Cdf = allowed maximum difference from Gray that will NOT be counted (default 0),
Let CTh = % Threshold to calculate number of differences that are more than CDf away from Gray.
PixLim=(xdim*yDim) * CTh / 100.0

YUV

dif = Abs(u-128) + Abs(v-128)
if(dif > CDf) Then Cnt=Cnt+1

... Later

return (Cnt > Pixlim) # If color return True


RGB



dif = Max(R,G,B)-Mid(R,G,B) + (Mid(R,G,B)-Min(R,G,B)
if(dif > CDf) Then Cnt=Cnt+1

... Later

return (Cnt > Pixlim) # If color return True

StainlessS
1st July 2015, 03:45
@Martin53,

For your version StrReplace,

s=StrReplace("abc","","1")

ie replace "" with "1",
Causes silent crash due to stack exhaustion.
(Problem due to FindStr("abc","") returning result 1 [bit of a daft result, 0 not found would perhaps be more sensible]).
Should return source string s where StrLen(find)==0

StainlessS
19th September 2015, 08:10
Here, two updates to scripts that are currently supplied with RT_Stats.
Scripts are demo color detectors, added a marker to indicate detection location.
Next version RT will have indicator in the Security Camera Motion Detection script, to show where motion was detected.
Uses RectMarker function first posted here:- http://forum.doom9.org/showthread.php?p=1733583#post1733583

Luma Y Detector

#RT_YInRAngeLocate() Tester

OBJECT_W = 20 # Object to find, size in pixels
OBJECT_H = 40 # Object to find, size in pixels

AREA_X = 0 # Area of frame to search (0,0,0,0=full frame {As Crop})
AREA_Y = 0
AREA_W = 0
AREA_H = 0

LUMA_MIN = 235 # Luma minimum of object to find
LUMA_MAX = 255

# Fake input clip, for testing
a = BlankClip(length=481,width=480,height=480)
b = BlankClip (width=OBJECT_W, height=OBJECT_H, color=$FFFFFF)
a.Animate (0, a.FrameCount () - 1, "Overlay", b, 0, 0, b, 480, 480)

ConvertToYV12() # Any colorspace ok so long as LUMA_MIN/MAX OK (RGB -> Luma-Y)

MarkerColor = $FFFF00 # Detection marker color
MARKER_TYPE = False # False = Corners only marker, True=Full Rect Marker
Msk = Last.RectMarker(OBJECT_W+8,OBJECT_H+8,MARKER_TYPE)
Mrk = Msk.BlankClip(Color=MarkerColor)

DEBUG=false
NOTFOUND="NOT FOUND" # Last few frames should show not found, depends upon OBJECT_W/H (as partially disappears off frame).
sep = ", "
ket = "] "
COORDINATES="Y_Coordinates.txt"
RT_FileDelete(COORDINATES) # Delete coordinates file

ScriptClip ("""
Bingo=RT_YInRangeLocate(debug=DEBUG,Baffle_W=OBJECT_W,Baffle_H=OBJECT_H,x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,Lo=LUMA_MIN,hi=LUMA_MAX)
(Bingo) ? WriteFile (COORDINATES,"current_frame","KET", "YIRL_X", "sep", "YIRL_Y", "sep", "YIRL_W", "sep", "YIRL_H")
\ : WriteFile (COORDINATES,"current_frame","KET", "NOTFOUND")
(Bingo) ? Overlay(Mrk,x=YIRL_X-4,y=YIRL_Y-4,Mask=Msk,Mode="Blend",output="YV12")
\ : NOP
Return Last
""")

Return Last

Function RectMarker(clip c,int W, Int H,Bool "Hit") {
# req RT_Stats & mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Hit=Default(hit,False)
InFix = (Hit)
\ ? RT_string("(((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d)|(x==0|x==%d|y==0|y==%d)))?255:0", W-2,H-2,W-4,H-4,W-1,H-1)
\ : RT_string("((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d))?255:0", W-2,H-2,W-4,H-4)
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return mt_lutspa(relative = false,yExpr=mt_Polish(InFix), chroma = "128")
}


RGB Detector

# RGBInRangeLocate_Test

RED =$AA # Object Color to look for
GREEN =$CC
BLUE =$FF

OBJECT_W = 10 # Object Width
OBJECT_H = 10 # Object Height

AREA_X = 0 # Area of frame to search (0,0,0,0=full frame, As Crop)
AREA_Y = 0
AREA_W = 0
AREA_H = 0

R_MIN = RED R_MAX = RED
G_MIN = GREEN G_MAX = GREEN
B_MIN = BLUE B_MAX = BLUE

# Overlay Converts RGB->YUV->RGB (can set inexact color). Use Layer Instead, MUST set ALPHA
RGBA=((255 * 256 + RED)*256+GREEN)*256+BLUE

COORDINATES="RGB_Coordinates.txt"

# Fake input clip, for testing
a = BlankClip(length=480,width=480,height=480)
b = a.BlankClip(width=OBJECT_W, height=OBJECT_H, color=RGBA)
a.Animate (0, a.FrameCount () - 1, "Layer", b,"add",257, 0, 0, b,"add",257, 479, 479)

MarkerColor = $FFFF00 # Detection marker color
MARKER_TYPE = False # False = Corners only marker, True=Full Rect Marker
Msk = Last.RectMarker(OBJECT_W+8,OBJECT_H+8,MARKER_TYPE)
Mrk = Msk.BlankClip(Color=MarkerColor)


NOTFOUND="NOT FOUND" # Will be NOT FOUND, As OBJECT moves out of frame at end of clip (can no longer find size OBJECT_W x OBJECT_H)
sep = ", "
Ket = "] "
RT_FileDelete(COORDINATES) # Delete coordinates file
DEBUG=False
ScriptClip ("""
Bingo=RT_RgbInRangeLocate(x=AREA_X,y=AREA_Y,w=AREA_W,h=AREA_H,
\ RLo=R_MIN,Rhi=R_MAX,GLo=G_MIN,Ghi=G_MAX,BLo=B_MIN,Bhi=B_MAX,Baffle_W=OBJECT_W,Baffle_H=OBJECT_H,debug=DEBUG)
(Bingo) ? WriteFile (COORDINATES,"current_frame", "Ket", "RGBIRL_X", "sep", "RGBIRL_Y")
\ : WriteFile (COORDINATES,"current_frame", "Ket", "NOTFOUND")

(Bingo) ? Overlay(Mrk,x=RGBIRL_X-4,y=RGBIRL_Y-4,Mask=Msk,Mode="Blend")
\ : NOP
Return Last
""")

Return Last

Function RectMarker(clip c,int W, Int H,Bool "Hit") {
# req RT_Stats & mt_tools_2, Returns YV12 frame WxH same FPS as c and without audio
Hit=Default(hit,False)
InFix = (Hit)
\ ? RT_string("(((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d)|(x==0|x==%d|y==0|y==%d)))?255:0", W-2,H-2,W-4,H-4,W-1,H-1)
\ : RT_string("((x<=1|x>=%d|y<=1|y>=%d)&(x<4|x>=%d)&(y<4|y>=%d))?255:0", W-2,H-2,W-4,H-4)
c.Blankclip(width=W,height=H,Length=1,pixel_type="YV12").Killaudio
return mt_lutspa(relative = false,yExpr=mt_Polish(InFix), chroma = "128")
}

jmac698
28th October 2015, 11:10
Just to let you know I need a 16bit version of planetcrop. I'm happy to report that imagesource reads 16bit PNG fine. It's chugging away at a set now. I'm going to have to find a way to split the 16bits into high and low parts and a way to encode it back into 16 bit pngs. I was thinking some incantations of imagemagick might do this. I could do it as video also but I don't know if there's any codecs that handle 16bit. In fact I think my images are really 12 bit though.

I'm working on the mod myself but feel free to help if you want a challenge :)

ps
About that statistics analysis - that's backed up as I write a CHDK script to aquire all the data. I have to do some testing to see if setting out of the ordinary ISO ranges actually work on the camera. There's also some weirdness about ISO not being true ISO but inflated market values.

ps2
it took a while but processing finished, perfect alignment at defaults gj :)

and here's some frames to play with
http://wikisend.com/download/839422/MoonHDR.7z

StainlessS
29th October 2015, 02:21
Hi Jmac, I see you there.
Have DL your clip and will have a play.

StainlessS
29th October 2015, 03:34
JM, can you post what you got so far so I can take a peek, thanx.

EDIT: I'm guess'in that 'most significant BIT' alone would be sufficient for detection.
(more than 8 would be overkill)

jmac698
29th October 2015, 06:13
Yes my thoughts exactly, though theoretically it could be a dim image, practically I would never expose a planet so dimly. It could be dim mind you, if I use a low ISO (which means less initial noise), but not THAT dim.

So the idea would be, detect on upper 8 bits, apply the crop to high and low images, then output stacked. Should be simple. Then imagemagick to stack/unstack. I do have a question though, what does autolevel=1 do? I was expecting to make the brightest pixel = 255. Speaking of which, that feature may take some work to work in 16bit.

Btw this pre-aligning *really* helps. The stacking programs I have either crash or take forever to align badly aligned images. But I couldn't stack the images I have; one remaining problem is rotation, I need to de-rotate what I have. I'm not using the "drifting across view" method any more, just handheld, so the alignment is a bit messier. I don't think there's any rotation detection plugins existing for Avisynth.

ps however, if I convert from polar to cartesian and make a "map" of the planet, then it's a simple shift finding to find the rotation angle, that could be simple.

update:
incantation is (create stacked high/low from 16bit PNG)

convert IMG_7853.png ( +clone -evaluate and 255 -evaluate multiply 256 ) -evaluate and 65280 -append -depth 8 test.png