# AVSLib :: 'clip' package :: 'arrays' module
# Copyright (c) 2005 George Zarkadas (gzarkadas@users.sourceforge.net)

# This program is free software; you can redistribute it and/or modify it under the terms of 
# the GNU General Public License as published by the Free Software Foundation; either 
# version 2 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program; 
# if not, write to the "Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
# MA  02111-1307  USA"

DefineModule("avslib", "clip", "arrays")

global __load__ = Eval("""
	LoadModule("avslib", "base", "conversion")
	LoadModule("avslib", "numeric", "core")
	LoadModule("avslib", "string", "core")
	""")
global __load__ = IsPackageLoaded("avslib", "array") ? NOP : Eval("""
	LoadModule("avslib", "array", "core")
	LoadModule("avslib", "array", "operators")
	LoadModule("avslib", "array", "transforms")
	LoadModule("avslib", "array", "properties")
	""")

# Returns the "most common" (ie with maximum occurence) pixel type of 
# a clip array. 
# The function first honors total RGB/YUV occurence and then specific
# occurences of RGB/YUV subtypes. In addition, when equal number of specific
# RGB/YUV subtypes is encountered, it favors YV12 over YUY2 and RGB32 over 
# RGB24, as well as YUY2 over RGB32 (when total RGB == total YUV).
# Thus:
# -- If most clips are in RGB/YUV it returns the RGB/YUV pixel_type with 
# the maximum occurence (favoring YV12 and RGB32 when YUV/RGB subtypes' 
# occurences are equal in number).
# -- If RGB clips == YUV clips, the specific subtype with the maximum 
# occurence is returned (favoring by this order: YV12 > YUY2 > RGB32 > RGB24 
# when all subtypes have the same occurence).
#
Function JointPixelType(string clips, bool "lowercase")
{
	lowercase = Default(lowercase, false)
	clen = clips.ArrayLen
	n_clips = clips.ArrayOpFunc("IsClip").ArrayOpFunc("CInt").ArraySum()
	Assert(n_clips == clen, \
		"JointPixelType: There are non-clip elements in input array.")
	nYV12 = clips.ArrayOpFunc("IsYV12").ArrayOpFunc("CInt").ArraySum()
	nYUY2 = clips.ArrayOpFunc("IsYUY2").ArrayOpFunc("CInt").ArraySum()
	nRGB32 = clips.ArrayOpFunc("IsRGB32").ArrayOpFunc("CInt").ArraySum()
	nRGB24 = clen - nRGB32 - nYUY2 - nYV12
	nYUV = nYV12 + nYUY2
	nRGB = nRGB32 + nRGB24
	nmax = Max(nRGB24, nRGB32, nYUY2, nYV12)
	# if most clips are in RGB/YUV favor it
	# else seek individually favoring YV12,YUY2,RGB32
	ret = nYUV > nRGB ? \
		(nYUY2 > nYV12 ? "YUY2" : "YV12") : ( \
	nYUV < nRGB ? \
		(nRGB24 > nRGB32 ? "RGB24" : "RGB32") \
	: ( \
		nmax == nYV12 ? \
			"YV12" : ( \
		nmax == nYUY2 ? \
			"YUY2" : ( \
		nmax == nRGB32 ? \
			"RGB32" \
		: "RGB24"))) )
	return lowercase ? LCase(ret) : ret
}

# Returns the "most common" (ie with maximum occurence) fps of 
# a clip array. 
# Between fps with the same occurence, the function favors those
# with the smaller value; ie if an array of eg. 5 clips has fps 
# [24,24,25,30,30] the function will return 24.

	Function __count_fps(float fps, string fps_array)
	{
		return fps_array.ArrayOpValue(fps, "==").ArrayOpFunc("CInt").ArraySum()
	}
	
Function JointFPS(string clips)
{
	clen = clips.ArrayLen
	n_clips = clips.ArrayOpFunc("IsClip").ArrayOpFunc("CInt").ArraySum()
	Assert(n_clips == clen, \
		"JointFPS: There are non-clip elements in input array.")
	_tmp = clips.ArrayOpFunc("Framerate")
	# get all distinct fps (in asc. sort order) and count their occurences
	frates = _tmp.ArrayDistinct()
	occurs = frates.ArrayOpFunc("__count_fps", StrQuote(_tmp))
	# find the maximum occurence number
	max_oc = occurs.ArrayMax()
	# remove all fps not equal to the maximum
	flags = occurs.ArrayOpValue(max_oc, "==").ArrayOpFunc("CInt")
	j_fps = occurs.ArrayReduce(flags)
	# select the first (ie the smaller) from all fps with same (maximum)
	# occurence
	return frates.ArrayGet(frates.ArrayIndexOf(j_fps.ArrayGet(0)))
}
