PipelinePanSharp.sml

  Download

More scripts: Pipeline

Syntax Highlighing:

comments, key words, predefined symbols, class members & methods, functions & classes
            
# PipelinePanSharp.sml
# Sample script that illustrates 
# 1) the use of a custom dialog window constructed using an XML dialog specification 
# 2) assembly of an Image Pipeline using options set from the dialog
# The script computes a pan-sharpened color-composite image from three low-resolution bands 
# of a multispectral image (must match each other in dimensions and extents) and a higher-resolution 
# panchromatic image.  The low-res bands must overlap but need not match the extents of the hi-res
# image; the low-res composite image is automatically resampled to match the extents of the hi-res
# image before the multiresolution fusion stage.
# The pan-sharpened image can be saved as an RVC raster object or as a TIFF, PNG, JP2, or JPEG file. 
# If the Apply Contrast option is selected for an input raster, 
# the last-used contrast table is used to set up a filter to apply contrast to that
# raster before further processing.  If no contrast table is found, a 
# default normalized contrast table is automatically computed and used.
# Randy Smith
# MicroImages, Inc.
# 26 March 2008
# Requires Version 2007:73 of the TNT products.
##############################################################################
###################  Global Variable Declarations  ###########################
##############################################################################
class STRING xml$;			# string containing the XML text with the dialog specification
class XMLDOC dlgdoc;			# class instance for the XML document
class XMLNODE psfdlgnode;	# class instance for the node in the XML
									# document corresponding to the dialog
class GUI_DLG psfdialog;	# class instance for the GUI dialog
class GUI_CTRL_LABEL panSatLabel, rgbSatLabel;		# labels for pan and rgb saturation fields
class GUI_CTRL_LABEL methodLabel, geoformatLabel;	# labels for the method and geoformat comboboxes
class GUI_CTRL_LABEL ratioLabel;							# label for the ratio field
class GUI_CTRL_EDIT_NUMBER panSat, rgbSat;		# numeric fields for saturation values
class GUI_CTRL_EDIT_NUMBER ratio;					# numeric field for JP2 compression ratio / JPEG quality
class GUI_CTRL_COMBOBOX methodBox, formatBox;	# method and format comboboxes
class GUI_CTRL_COMBOBOX geoformatBox;				# geoformat combobox
class GUI_FORMDATA data;								# class instance for retrieved dialog settings
class RVC_RASTER Red, Green, Blue, Pan;			# class instances for the input rasters
class STRING method$;		# color blending method from dialog combobox;
class STRING format$;		# selected output format from dialog combobox
numeric err;			# value returned by various predefined functions; use to manually handle errors
numeric rgbMax;		# maximum value for setting RGB Saturation, set from datatype
numeric panMax;		# maximum value for setting Pan Saturation, set from datatype
numeric satEnabled;		# flag to indicate whether saturation controls are enabled/disabled
numeric geoformatEnabled;	# flag to indicate whether geoformat controls are enabled/disabled
numeric ratioSet;				# flag to indicate whether ratio controls are enabled/disabled
#######################################################################
##################  Procedures & Functions  ###########################
########################################
### error checking procedure
proc ReportError(numeric linenum, numeric err) 
	{
	printf("FAILED -line: %d, error: %d\n", linenum - 1, err);
	PopupError(err); 
	}
####################################################################
### procedure called when color blending method is set on the dialog
proc OnSelectMethod() 
	{
	method$ = methodBox.GetSelectedItemID();
	if ( (method$ == "basicHIS" or method$ == "modHIS" or method$ == "HBS") && satEnabled == 0 )
		{
		panSatLabel.SetEnabled(1);
		rgbSatLabel.SetEnabled(1);
		panSat.SetValueNum(panMax);
		panSat.SetEnabled(1);
		rgbSat.SetValueNum(rgbMax);
		rgbSat.SetEnabled(1);
		satEnabled = 1;
		}
	else if (method$ == "Brovey" && satEnabled == 1)
		{
		panSatLabel.SetEnabled(0);
		rgbSatLabel.SetEnabled(0);
		panSat.SetEnabled(0);
		rgbSat.SetEnabled(0);
		satEnabled = 0;
		}
	}
#################################################
### procedure to enable geoformat dialog controls
proc geoformatEnable() 
	{
	geoformatLabel.SetEnabled(1);
	geoformatBox.SetEnabled(1);
	geoformatEnabled = 1;
	}
###############################################################################
### procedure to disable JP2 target ratio and JPEG compression quality controls 
proc ratioDisable() 
	{
	ratioLabel.SetVisible(0);
	ratio.SetVisible(0);
	ratioSet = 0;
	}
##############################################################################
### procedure to enable JP2 target ratio and JPEG compression quality controls
proc ratioEnable() 
	{
	ratioLabel.SetVisible(1);
	ratioLabel.SetEnabled(1);
	ratio.SetVisible(1);
	ratio.SetEnabled(1);
	ratioSet = 1;
	}
#################################################################
### function called when Output Format is changed on the dialog
proc OnSelectFormat() 
	{
	format$ = formatBox.GetSelectedItemID();
	if ( format$ == "GeoTIFF" or format$ == "PNG" or format$ == "JP2" )
		{
		if (geoformatEnabled == 0)
			geoformatEnable();
		if (ratioSet) then ratioDisable();
		}
	else if (format$ == "JP2l")
		{
		if (geoformatEnabled == 0)
			geoformatEnable();
		ratioLabel.SetLabel("Target Ratio");
		if (ratioSet == 0) then ratioEnable();
		ratio.SetValue(10,0);
		}
	else if (format$ == "JPEG")
		{
		if (geoformatEnabled == 0) then geoformatEnable();
		ratioLabel.SetLabel("Quality");
		ratio.SetValue(80,0);
		if (ratioSet == 0) then ratioEnable();
		}
	else if (format$ == "RVC" && geoformatEnabled == 1)
		{
		geoformatLabel.SetEnabled(0);
		geoformatBox.SetEnabled(0);
		geoformatEnabled = 0;
		if (ratioSet) then ratioDisable();
		}
	} # end of proc OnSelectFormat()
##############################################################################
### procedure to compute standard contrast table for copy of input raster that 
### has no contrast table if apply contrast is selected
proc computeCon(class CONTRAST con, class RVC_RASTER Rast) 
	{
	class RVC_OBJECT tempFile;
	class RVC_RASTER tempRast;
	# copy source raster to temporary file, then close source raster
	tempFile.MakeTempFile(1);
	Rast.CopyTo(tempFile, tempRast);
	Rast.Close();
	# open temporary raster and compute standard contrast table for it
	tempRast.OpenAttached("Write");
	con.ComputeStandard(tempRast, "normalize");
	Rast = tempRast;			# reassign temporary raster to original raster variable
	tempRast.Close();			# close temporary raster
	}
####################################################################################
### procedure to initially disable OK button on main dialog window when it opens and 
### get handles for controls that are accessed more than once in the script
proc OnOpenDlg () 
	{
	psfdialog.SetOkEnabled( 0 );
	methodBox = psfdialog.GetCtrlByID("method");
	formatBox = psfdialog.GetCtrlByID("format");
	ratio = psfdialog.GetCtrlByID("ratio");
	ratio.SetVisible(0);
	ratioLabel = psfdialog.GetCtrlByID("ratioLabel");
	ratioLabel.SetVisible(0);
	geoformatBox = psfdialog.GetCtrlByID("geoformat");
	geoformatLabel = psfdialog.GetCtrlByID("geoformatLabel");
	panSatLabel = psfdialog.GetCtrlByID("panSatLabel");
	rgbSatLabel = psfdialog.GetCtrlByID("rgbSatLabel");
	panSat = psfdialog.GetCtrlByID("panSat");
	rgbSat = psfdialog.GetCtrlByID("rgbSat");
	}
###################################################################################
### procedure to write band filename / object name to the dialog (in edittext field)
proc SetBandInfo(class RVC_RASTER Band, string id$) 
	{
	local string filename$, objname$, dlgtext$;
	local numeric objnum;
	filename$ = GetObjectFileName( Band );
	objnum = GetObjectNumber( Band );
	objname$ = GetObjectName( filename$, objnum );
	dlgtext$ = sprintf( "%s.%s /  %s", FileNameGetName(filename$), FileNameGetExt(filename$), objname$ );
	psfdialog.SetCtrlValueStr( id$, dlgtext$ );
	}	# end proc GetBand()
################################################################################################
### callback procedure for the Red... pushbutton; prompts user to select the Red color component
proc SelectRed () 
	{
	GetInputRaster( Red, 0, 0);
	# check to ensure that first raster selected is an unsigned 8-bit or 16-bit grayscale raster
	if (Red.$Info.Type == "8-bit unsigned" or Red.$Info.Type == "16-bit unsigned")
		{
		SetBandInfo( Red, "rname" );
		psfdialog.GetCtrlByID( "conred" ).SetEnabled( 1 );
		psfdialog.GetCtrlByID( "getg" ).SetEnabled( 1 );
		# PIPELINE SOURCE FOR RED LOW-RES
		class IMAGE_PIPELINE_SOURCE_RVC source_Red(Red.GetObjItem() );
		err = source_Red.Initialize();
		if ( err < 0) ReportError(_context.CurrentLineNum, err);
		else print("Set red source.");
		# set default maximum value for RGB saturation from datatype
		if (Red.$Info.Type == "8-bit unsigned") then rgbMax = 254;
		else if (Red.$Info.Type == "16-bit unsigned") then rgbMax = 62537;
		}
	else
		{
		print("Only an 8-bit or 16-bit unsigned raster can be used for this input.");
		}
	}	# end proc SelectRed()
####################################################################################################
### callback procedure for the Green... pushbutton; prompts user to select the Green color component 
proc SelectGreen () 
	{
	GetInputRaster(Green, Red.$Info.NumLins, Red.$Info.NumCols, Red.$Info.Type);
	SetBandInfo( Green, "gname" );
	psfdialog.GetCtrlByID( "congrn" ).SetEnabled( 1 );
	psfdialog.GetCtrlByID( "getb" ).SetEnabled( 1 );
	# PIPELINE SOURCE FOR GREEN LOW-RES
	class IMAGE_PIPELINE_SOURCE_RVC source_Green(Green.GetObjItem() );
	err = source_Green.Initialize();
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	else print("Set green source.");
	}	# end proc SelectGreen()
##################################################################################################
### callback procedure for the Blue... pushbutton; prompts user to select the Blue color component 
proc SelectBlue () 
	{
	GetInputRaster(Blue, Red.$Info.NumLins, Red.$Info.NumCols, Red.$Info.Type);
	SetBandInfo( Blue, "bname" );
	psfdialog.GetCtrlByID( "conblue" ).SetEnabled( 1 );
	psfdialog.GetCtrlByID( "getp" ).SetEnabled( 1 );
	# PIPELINE SOURCE FOR BLUE LOW-RES
	class IMAGE_PIPELINE_SOURCE_RVC source_Blue(Blue.GetObjItem() );
	err = source_Blue.Initialize();
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	else print("Set blue source.");
	}	# end proc SelectBlue()
######################################################################################################
### callback procedure for the Intensity... pushbutton; prompts user to select the Intensity component
 proc SelectPan () 
	{
	GetInputRaster(Pan);
	if (Pan.$Info.Type == "8-bit unsigned" or Pan.$Info.Type == "16-bit unsigned")
		{
		SetBandInfo( Pan, "pname" );
		psfdialog.GetCtrlByID( "conpan" ).SetEnabled( 1 );
		# PIPELINE SOURCE FOR HI-RES PANCHROMATIC IMAGE
		class IMAGE_PIPELINE_SOURCE_RVC source_Pan(Pan.GetObjItem() );
		err = source_Pan.Initialize();
		if ( err < 0) ReportError(_context.CurrentLineNum, err);
		else print("Set pan source.");
		psfdialog.GetCtrlByID("methodLabel").SetEnabled(1);		# enable controls for method and format
		methodBox.SetEnabled(1);
		psfdialog.GetCtrlByID("formatLabel").SetEnabled(1);
		formatBox.SetEnabled(1);
		# set default values for color blending method and output format in case these
		# control settings are not changed
		method$ = "Brovey";		format$ = "RVC";
		# set maximum value for pan saturation
		if (Pan.$Info.Type == "8-bit unsigned") then panMax = 254;
		else if (Pan.$Info.Type == "16-bit unsigned") then panMax = 62537;
		psfdialog.SetOkEnabled( 1 );	# enable the dialog's OK button
		}
	else
		{
		print("Binary, composite, & floating point rasters cannot be used as input for this script.  Exiting now.");
		Exit();
		}
	}	# end proc SelectPan()
##################################################################################################
### callback procedure for the OK button on the dialog to retrieve the dialog settings and store in GUI_FORMDATA
proc GetValues () {
	data = psfdialog.GetValues();
	}
#####################################################################################
####################################   Main Program   ###############################
#####################################################################################
clear();
$warnings 3;
##############################################################
### string variable with XML specification for control dialog
xml$='<?xml version="1.0"?>
<root>
	<dialog id="psf" Title="Pan-Sharpen to Selected Format" OnOpen = "OnOpenDlg()" OnOK = "GetValues()" >
		<pane Orientation="vertical">
			<groupbox Name=" Select Input Rasters: " ExtraBorder="4">
				<pane Orientation="horizontal">
					<pushbutton Name="Red..." WidthGroup="Buttons" OnPressed="SelectRed()"/>
					<edittext id="rname" Width="25" ReadOnly="true"/>
					<togglebutton id="conred" Name="Apply contrast" Enabled="0" Selected="true"/>
				</pane>
				<pane Orientation="horizontal">
					<pushbutton id="getg" Name="Green..." WidthGroup="Buttons" Enabled="0" OnPressed="SelectGreen()"/>
					<edittext id="gname" Width="25" ReadOnly="true"/>
					<togglebutton id="congrn" Name="Apply contrast" Enabled="0" Selected="true"/>
				</pane>
				<pane Orientation="horizontal">
					<pushbutton id="getb" Name="Blue..." WidthGroup="Buttons" Enabled="0" OnPressed="SelectBlue()"/>
					<edittext id="bname" Width="25" ReadOnly="true"/>
					<togglebutton id="conblue" Name="Apply contrast" Enabled="0" Selected="true"/>
				</pane>
				<pane Orientation="horizontal">
					<pushbutton id="getp" Name="Pan..." WidthGroup="Buttons" Enabled="0" OnPressed="SelectPan()"/>
					<edittext id="pname" Width="25" ReadOnly="true"/>
					<togglebutton id="conpan" Name="Apply contrast" Enabled="0" Selected="true"/>
				</pane>
			</groupbox>
		</pane>
		<pane Orientation="horizontal">
			<label id="methodLabel" HorizAlign="Right" HorizResize="Fixed" Enabled="0">Color Blending Mode: </label>
			<combobox id="method" Default="HIS" Height="3" Width="7" SelectStyle="single" HorizResize="Fixed" Enabled="0" OnSelection="OnSelectMethod();">
				<item Value="Brovey">Brovey</item>
				<item Value="basicHIS">basic HIS</item>
				<item Value="modHIS">modified HIS</item>
				<item Value="HBS">HBS</item>
			</combobox>
		</pane>
		<pane Orientation="horizontal">
			<label id="panSatLabel" Enabled="0">Pan saturation value</label>
			<editnumber id="panSat" Width="3" Precision="0" MinVal="0" Enabled="0"/>
			<label id="rgbSatLabel" Enabled="0">RGB saturation value</label>
			<editnumber id="rgbSat" Width="3" Precision="0" MinVal="0" Enabled="0"/>
		</pane>
		<pane Orientation="horizontal">
			<label id="formatLabel" HorizAlign="Right" HorizResize="Fixed" Enabled="0">Output Format</label>
			<combobox id="format" Default="RVC" Width="7" HorizAlign="Right" HorizResize="Fixed" Enabled="0" OnSelection="OnSelectFormat();">
				<item Value="RVC">RVC</item>
				<item Value="GeoTIFF">GeoTIFF</item>
				<item Value="PNG">PNG</item>
				<item Value="JP2">JP2 Lossless</item>
				<item Value="JP2l">JP2 Lossy</item>
				<item Value="JPEG">JPEG</item>
			</combobox>
			<label id="ratioLabel" HorizAlign="Right" HorizResize="Fixed" Enabled="0">Target Ratio</label>
			<editnumber id="ratio" Width="3" Precision="0" MinVal="0" Enabled="0"/> 
		</pane>
		<pane Orientation="horizontal">
			<label id="geoformatLabel" HorizAlign="Right" HorizResize="Fixed" Enabled="0">Additional georeference</label>
			<combobox id="geoformat" Default="none" Width="11" HorizAlign="Right" HorizResize="Fixed" Enabled="0">
				<item Value="none">None</item>
				<item Value="ArcWorld">ArcWorld</item>
				<item Value="KML">Google KML</item>
			</combobox>
		</pane>
	</dialog>
</root>';
### parse XML text for the dialog into memory; return an error code (number < 0 ) if there are syntax errors
err = dlgdoc.Parse(xml$);
if ( err < 0 ) 
	{
	PopupError( err ); 	# Popup an error dialog. "Details" button shows syntax errors.
	Exit();
	}
### get the dialog element from the parsed XML document and show error message if the dialog element can't be found
psfdlgnode = dlgdoc.GetElementByID("psf");
if ( psfdlgnode == 0 ) 
	{
	PopupMessage("Could not find dialog node in XML document");
	Exit();
	}
#### Set the XML dialog element as the source for the GUI_DLG class instance we are using for the dialog window.
psfdialog.SetXMLNode(psfdlgnode);
err = psfdialog.DoModal();
if ( err == -1 ) 
	{	# exit script if Cancel button on dialog is pressed
	Exit();
	}
######################################################################################################
### Set up STAGE_ARRAY of threee stages for compositing the low-res bands.  Populate later either with 
### source or with filter-lookup stage if contrast enhancement is to be applied for that color
class IMAGE_PIPELINE_STAGE_ARRAY stagesForComposite(3);
#######################################################
### apply contrast tables to Low Res bands if requested
## contrast for Red
if ( data.GetValueStr( "conred" ) == "true" ) 
	{
	print("Setting up Red contrast.");
	class CONTRAST conRed;
	err = conRed.Read(Red);
	if ( err < 0 ) 				# no contrast table found
		{
		computeCon(conRed, Red);	# compute standard normalized contrast
		print("No contrast table found for Red, computing normalized contrast.");
		}
	# PIPELINE FILTER_LOOKUP to apply lookup table (from contrast) to source
	class IMAGE_PIPELINE_FILTER_LOOKUP lookupRed (source_Red);
	err = lookupRed.SetContrastParm(conRed);		# set CONTRAST class instance as lookup table
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	err = lookupRed.Initialize();
	if ( err < 0) 
		ReportError(_context.CurrentLineNum, err);
	else
		print("Initialized Red contrast");
	stagesForComposite.SetItem(0, lookupRed);		# set red lookup filter as first item in stage array (0-based indexing)
	}
else
	{
	stagesForComposite.SetItem(0, source_Red);	# set red source as first item in stage array
	print("Using uncontrasted Red source.");
	}
# contrast for Green
if ( data.GetValueStr( "congrn" ) == "true" )
	{
	print("Setting up Green contrast.");
	class CONTRAST conGreen;
	err = conGreen.Read(Green);
	if ( err < 0 )					# no contrast table found
		{
		computeCon(conGreen, Green);	# compute standard normalized contrast
		print("No contrast table found for Green, computing normalized contrast.");
		}
	# PIPELINE FILTER_LOOKUP to apply lookup table (from contrast) to source
	class IMAGE_PIPELINE_FILTER_LOOKUP lookupGreen (source_Green);
	err = lookupGreen.SetContrastParm(conGreen);		# set CONTRAST class instance as lookup table
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	err = lookupGreen.Initialize();
	if ( err < 0) 
		ReportError(_context.CurrentLineNum, err);
	else
		print("Initialized Green contrast");
	stagesForComposite.SetItem(1, lookupGreen);	# set green lookup filter as second item in stage array
	}
else
	{
	stagesForComposite.SetItem(1, source_Green);	# set green source as second item in stage array
	print("Using uncontrasted Green source.");
	}
# contrast for Blue
if ( data.GetValueStr( "conblue" ) == "true" )
	{
	print("Setting up Blue contrast.");
	class CONTRAST conBlue;
	err = conBlue.Read(Blue);
	if ( err < 0 )					# no contrast table found
		{
		computeCon(conBlue, Blue);	 	# compute standard normalized contrast
		print("No contrast table found for Blue, computing normalized contrast.");
		}
	# PIPELINE FILTER_LOOKUP to apply lookup table (from contrast) to source
	class IMAGE_PIPELINE_FILTER_LOOKUP lookupBlue (source_Blue);
	err = lookupBlue.SetContrastParm(conBlue);		# set CONTRAST class instance as lookup table
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	err = lookupBlue.Initialize();
	if ( err < 0) 
		ReportError(_context.CurrentLineNum, err);
	else
		print("Initialized Blue contrast.");
	stagesForComposite.SetItem(2, lookupBlue);	# set blue lookup filter as third item in stage array
	}
else
	{
	stagesForComposite.SetItem(2, source_Blue);	# set blue source as third item in stage array
	print("Using uncontrasted Blue source.");
	}
# PIPELINE FILTER_COMPOSITE to make composite from Low Res RGB bands (required for Fusion filter)
# Filter can make different composites from different numbers of components, so it takes a STAGE_ARRAY of 
# input stages set up previously (populated in this case by sources or derived FILTER_LOOKUP stages)
class IMAGE_PIPELINE_FILTER_COMPOSITE filter_comp(stagesForComposite, "RGB");
err = filter_comp.Initialize();
if ( err < 0) 
	ReportError(_context.CurrentLineNum, err);
else
	print("Composite filter initialized.");
# PIPELINE FILTER_RESAMPLE to resample composite Low Res RGB image to match the extents and georeference
# of the Hi Res panchromatic image.
class IMAGE_PIPELINE_FILTER_RESAMPLE filter_resample(filter_comp, source_Pan, "Nearest");
err = filter_resample.Initialize();
if ( err < 0) 
	ReportError(_context.CurrentLineNum, err);
else
	print("Resample filter initialized.");
############################################################
# Apply contrast to Hi Res panchromatic image if requested 
# and set up fusion filter with either pan source or its
# derived filter_lookup
############################################################
class IMAGE_PIPELINE_STAGE HiRes;		# stage for Hi Res pan image, either original or contrast-enhanced
if ( data.GetValueStr( "conpan" ) == "true" )	# apply contrast selected
	{
	print("Setting up Pan contrast.");
	class CONTRAST conPan;
	err = conPan.Read(Pan);
	if ( err < 0 )				# no contrast table found
		{
		computeCon(conPan, Pan);	# compute standard normalized contrast
		print("No contrast table found for Pan, computing normalized contrast.");
		}
	# PIPELINE FILTER_LOOKUP to apply lookup table (from contrast) to source
	class IMAGE_PIPELINE_FILTER_LOOKUP lookupPan (source_Pan);
	err = lookupPan.SetContrastParm(conPan);		# set CONTRAST class instance as lookup table
	if ( err < 0) ReportError(_context.CurrentLineNum, err);
	err = lookupPan.Initialize();
	if ( err < 0) 
		ReportError(_context.CurrentLineNum, err);
	else
		print("Initialized Pan contrast.");
	HiRes = lookupPan;		# assign FILTER_LOOKUP to HiRes stage
	}
else				# no apply contrast, use original pan image source
	{
	HiRes = source_Pan;		# assign SOURCE_RVC to HiRes stage
	print("Using uncontrasted Pan source.");
	}
##########################################################################
# PIPELINE FILTER_FUSION_XXX
# Set up appropriate fusion filter for the selected color blending method
##########################################################################
class IMAGE_PIPELINE_FILTER filter_fusion;	# generic class instance for the fusion filter; 
															# assign particular fusion filter to this name
if (method$ == "Brovey")
	{
	class IMAGE_PIPELINE_FILTER_FUSION_BROVEY filter_Brovey(HiRes, filter_resample);
	filter_fusion = filter_Brovey;
	print("Using Brovey method.");
	}
# need panSat and rgbSat values for remaining methods
else if (method$ == "basicHIS")
	{
	class IMAGE_PIPELINE_FILTER_FUSION_BASICHIS filter_basicHIS(HiRes, filter_resample, data.GetValueNum("panSat"), data.GetValueNum("rgbSat") );
	filter_fusion = filter_basicHIS;
	print("Using Basic HIS method."); 
	}
else if (method$ == "modHIS")
	{
	class IMAGE_PIPELINE_FILTER_FUSION_MODHIS filter_modHIS(HiRes, filter_resample, data.GetValueNum("panSat"), data.GetValueNum("rgbSat") );
	filter_modHIS.SetIntensityProportion(0.5);
	filter_modHIS.SetSaturationBoost(1.3);
	filter_modHIS.SetSaturationMax(100);
	filter_fusion = filter_modHIS;
	print("Using Modified HIS method.");
	}
else if (method$ == "HBS")
	{
	class IMAGE_PIPELINE_FILTER_FUSION_BASICHBS filter_HBS(HiRes, filter_resample, data.GetValueNum("panSat"), data.GetValueNum("rgbSat") );
	filter_fusion = filter_HBS;
	print("Using HBS method.");
	}
err = filter_fusion.Initialize();
if ( err < 0) 
	ReportError(_context.CurrentLineNum, err);
else
	print("Initialized fusion filter.");
##########################################################################
# PIPELINE TARGET
# Prompt for output and set up appropriate pipeline target based on selected format
##########################################################################
class IMAGE_PIPELINE_TARGET target;			# generic target; assign selected target class to this variable
#format$ = data.GetValueStr("format");
class STRING defaultName$ = _context.ScriptDir + "/image";
if (format$ == "RVC")
	{
	class RVC_OBJITEM outObjItem;
	DlgGetObject("Choose new raster for the pan-sharpened composite:", "Raster", outObjItem, "NewOnly");
	class IMAGE_PIPELINE_TARGET_RVC target_RVC(filter_fusion, outObjItem);
	target = target_RVC;
	}
else if (format$ == "GeoTIFF")
	{
	class STRING outFileName$ = GetOutputFileName(defaultName$, "Choose destination and name for output GeoTIFF file", ".tif");
	class FILEPATH outFilePath(outFileName$);
	printf("Output file path = %s\n", outFilePath);
	class IMAGE_PIPELINE_TARGET_TIFF_SETTINGS tiffSettings;
	tiffSettings.SetCompression("LZW");
	class IMAGE_PIPELINE_TARGET_TIFF target_TIFF(filter_fusion, outFilePath, data.GetValueStr("geoformat") );
	target_TIFF.SetParms(tiffSettings);
	target = target_TIFF;
	}
else if (format$ == "PNG")
	{
	class STRING outFileName$ = GetOutputFileName(defaultName$, "Choose destination and name for output PNG file", ".png");
	class FILEPATH outFilePath(outFileName$);
	printf("Output file path = %s\n", outFilePath);
	class IMAGE_PIPELINE_TARGET_PNG target_PNG(filter_fusion, outFilePath, data.GetValueStr("geoformat") );
	target = target_PNG;
	}
else if (format$ == "JP2" or format$ == "JP2l")
	{
	class STRING outFileName$ = GetOutputFileName(defaultName$, "Choose destination and name for output JP2 file", ".jp2");
	class FILEPATH outFilePath(outFileName$);
	printf("Output file path = %s\n", outFilePath);
	class IMAGE_PIPELINE_TARGET_J2K_SETTINGS j2kSettings;
	j2kSettings.SetGeoMethod("GeoTIFF");
	if (format$ == "JP2") 
		{
		j2kSettings.SetReversible(1);
		print("Setting JP2 lossless compression.");
		}
	else
		{
		j2kSettings.SetTargetRatio(data.GetValueNum("ratio") );
		printf("Setting JP2 lossy compression with target ratio %d\n", data.GetValueNum("ratio") );
		}
	class IMAGE_PIPELINE_TARGET_J2K target_J2K(filter_fusion, outFilePath, j2kSettings, data.GetValueStr("geoformat") );
	target = target_J2K;
	}
else if (format$ == "JPEG")
	{
	class STRING outFileName$ = GetOutputFileName(defaultName$, "Choose destination and name for output JPEG file", ".jpg");
	class FILEPATH outFilePath(outFileName$);
	printf("Output file path = %s\n", outFilePath);
	class IMAGE_PIPELINE_TARGET_JPEG target_JPEG(filter_fusion, outFilePath, data.GetValueNum("ratio"), data.GetValueStr("geoformat") );
	target = target_JPEG;
	}
target.Initialize();
if ( err < 0) 
	ReportError(_context.CurrentLineNum, err);
else
	print("Initialized target.");
target.Process();
print("Processing...");
print("Done.");