2D/3D models + textures of flora used in my C&C Generals: Situation Zero mod project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

328 lines
10 KiB

#!/bin/bash
#
# Developed by Fred Weinhaus 5/2/2010 .......... 9/12/2015
#
# ------------------------------------------------------------------------------
#
# Licensing:
#
# Copyright © Fred Weinhaus
#
# My scripts are available free of charge for non-commercial use, ONLY.
#
# For use of my scripts in commercial (for-profit) environments or
# non-free applications, please contact me (Fred Weinhaus) for
# licensing arrangements. My email address is fmw at alink dot net.
#
# If you: 1) redistribute, 2) incorporate any of these scripts into other
# free applications or 3) reprogram them in another scripting language,
# then you must contact me for permission, especially if the result might
# be used in a commercial or for-profit environment.
#
# My scripts are also subject, in a subordinate manner, to the ImageMagick
# license, which can be found at: http://www.imagemagick.org/script/license.php
#
# ------------------------------------------------------------------------------
#
####
#
# USAGE: huemap [-h hues] [-t tolers] [-r] infile outfile
# USAGE: huemap [-help]
#
# OPTIONS:
#
# -h hues hues=srchue,dsthue; source and destination hue values;
# comma separated list; 0<=integer<=360; default=240,120
# maps blue to green
# -t tolers tolers=stoler,dtoler; source and destination range of
# hues on each side of hue values; 0<=integer<=360;
# default=10,10
# -r reverse direction of range of destination hues
#
###
#
# NAME: HUEMAP
#
# PURPOSE: To transform the hues in an image from one range to another.
#
# DESCRIPTION: HUEMAP transform the hues in an image from one range to another.
# One hue can be mapped to another single hue. One range of hues can be mapped
# to a single hue. Or one range of hues can be mapped to another range of hues.
# This is similar to GIMP's Rotate Hues.
#
#
# OPTIONS:
#
# -h hues ... HUES=SRCHUE,DSTHUE. These are source and destination hue values
# in the range of 0<=integer<=360. The source hue (range) will be replaced by
# the detination hue (range), depending upon the tolers values below. The
# default=240,120 maps blue to green.
#
# -t tolers ... TOLERS=STOLER,DTOLER. These are the source and destination
# ranges on each side of the specified hues that determine the range of hues
# to be mapped. Values are in the range of 0<=integer<=360. The default=10,10.
#
# -r ... REVERSE the direction of the range of destination hues.
#
# REQUIREMENT: IM version 6.3.5-7 or higher due to the use of -clut.
#
# NOTE: If the image has an alpha channel, it will be copied unchanged to
# the output image.
#
# CAVEAT: No guarantee that this script will work on all platforms,
# nor that trapping of inconsistent parameters is complete and
# foolproof. Use At Your Own Risk.
#
######
#
# set default values
hues="240,120" # src,dst hues
tolers="10,10" # src and dst ranges on either side of src,dst hues
reverse="no" # reverse direction of start and end dst
# set directory for temporary files
dir="." # suggestions are dir="." or dir="/tmp"
# set up functions to report Usage and Usage with Description
PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path
PROGDIR=`dirname $PROGNAME` # extract directory of program
PROGNAME=`basename $PROGNAME` # base name of program
usage1()
{
echo >&2 ""
echo >&2 "$PROGNAME:" "$@"
sed >&2 -e '1,/^####/d; /^###/g; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
}
usage2()
{
echo >&2 ""
echo >&2 "$PROGNAME:" "$@"
sed >&2 -e '1,/^####/d; /^######/g; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME"
}
# function to report error messages
errMsg()
{
echo ""
echo $1
echo ""
usage1
exit 1
}
# function to test for minus at start of value of second part of option 1 or 2
checkMinus()
{
test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise
[ $test -eq 1 ] && errMsg "$errorMsg"
}
# test for correct number of arguments and get values
if [ $# -eq 0 ]
then
# help information
echo ""
usage2
exit 0
elif [ $# -gt 7 ]
then
errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---"
else
while [ $# -gt 0 ]
do
# get parameter values
case "$1" in
-help) # help information
echo ""
usage2
exit 0
;;
-h) # get hues
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID HUES SPECIFICATION ---"
checkMinus "$1"
hues=`expr "$1" : '\([,0-9]*\)'`
[ "$hues" = "" ] && errMsg "--- HUES=$hues MUST BE TWO COMMA DELIMITED NON-NEGATIVE INTEGERS ---"
;;
-t) # get tolers
shift # to get the next parameter
# test if parameter starts with minus sign
errorMsg="--- INVALID TOLERANCES SPECIFICATION ---"
checkMinus "$1"
tolers=`expr "$1" : '\([,0-9]*\)'`
[ "$tolers" = "" ] && errMsg "--- TOLERANCES=$tolers MUST BE TWO COMMA DELIMITED NON-NEGATIVE INTEGERS ---"
;;
-r) # get reverse
reverse="yes"
;;
-) # STDIN and end of arguments
break
;;
-*) # any other - argument
errMsg "--- UNKNOWN OPTION ---"
;;
*) # end of arguments
break
;;
esac
shift # next option
done
#
# get infile and outfile
infile="$1"
outfile="$2"
fi
# test that infile provided
[ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED"
# test that outfile provided
[ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED"
# get im version
im_version=`convert -list configure | \
sed '/^LIB_VERSION_NUMBER /!d; s//,/; s/,/,0/g; s/,0*\([0-9][0-9]\)/\1/g' | head -n 1`
srchue=`echo $hues | cut -d, -f 1`
dsthue=`echo $hues | cut -d, -f 2`
stoler=`echo $tolers | cut -d, -f 1`
dtoler=`echo $tolers | cut -d, -f 2`
#echo "srchue=$srchue; dsthue=$dsthue; stoler=$stoler; dtoler=$dtoler"
# set up temp files
tmpI1="$dir/huemap_I_$$.mpc"
tmpI2="$dir/huemap_I_$$.cache"
tmpH1="$dir/huemap_H_$$.mpc"
tmpH2="$dir/huemap_H_$$.cache"
tmpS1="$dir/huemap_S_$$.mpc"
tmpS2="$dir/huemap_S_$$.cache"
tmpL1="$dir/huemap_L_$$.mpc"
tmpL2="$dir/huemap_L_$$.cache"
tmpG1="$dir/huemap_G_$$.mpc"
tmpG2="$dir/huemap_G_$$.cache"
tmpT1="$dir/huemap_T_$$.mpc"
tmpT2="$dir/huemap_T_$$.cache"
tmpA1="$dir/huemap_A_$$.mpc"
tmpA2="$dir/huemap_A_$$.cache"
trap "rm -f $tmpI1 $tmpI2 $tmpH1 $tmpH2 $tmpS1 $tmpS2 $tmpL1 $tmpL2 $tmpG1 $tmpG2 $tmpT1 $tmpT2 $tmpA1 $tmpA2;" 0
trap "rm -f $tmpI1 $tmpI2 $tmpH1 $tmpH2 $tmpS1 $tmpS2 $tmpL1 $tmpL2 $tmpG1 $tmpG2 $tmpT1 $tmpT2 $tmpA1 $tmpA2; exit 1" 1 2 3 15
trap "rm -f $tmpI1 $tmpI2 $tmpH1 $tmpH2 $tmpS1 $tmpS2 $tmpL1 $tmpL2 $tmpG1 $tmpG2 $tmpT1 $tmpT2 $tmpA1 $tmpA2; exit 1" ERR
# read the input image and filter image into the temp files and test validity.
convert -quiet "$infile" +repage "$tmpI1" ||
errMsg "--- FILE $infile DOES NOT EXIST OR IS NOT AN ORDINARY FILE, NOT READABLE OR HAS ZERO SIZE ---"
# separate alpha channel if exists
is_alpha=`identify -ping -verbose $tmpI1 | grep "Alpha" | head -n 1`
if [ "$is_alpha" != "" ]; then
convert $tmpI1 -alpha extract $tmpA1
convert $tmpI1 -alpha off $tmpI1
fi
# convert to HSL and separate channels
convert $tmpI1 -colorspace HSL -channel R -separate $tmpH1
convert $tmpI1 -colorspace HSL -channel G -separate $tmpS1
convert $tmpI1 -colorspace HSL -channel B -separate $tmpL1
# create length 360 gradient
convert -size 1x360 gradient: -rotate 90 $tmpG1
# modify gradient as lut to apply to hue channel
# create gradient section of length=2*toler+1 and value=dst1 to dst2 scaled to percent
# insert into beginning of transparent row
# due to bug, make it red, then change to dst later
dst1=`convert xc: -format "%[fx:($dsthue-$dtoler)]" info:`
dst2=`convert xc: -format "%[fx:($dsthue+$dtoler)]" info:`
#echo "dst1=$dst1; dst2=$dst2"
if [ "$reverse" = "yes" ]; then
dst=$dst1
dst1=$dst2
dst2=$dst
fi
#echo "dst1=$dst1; dst2=$dst2"
len=$((2*$stoler+1))
if [ $stoler -eq 0 -a $dtoler -gt 0 ]; then
errMsg "--- DESTINATION TOLERANCE MUST BE 0 IF SOURCE TOLERANCE IS 0 ---"
elif [ $dtoler -eq 0 ]; then
convert -size ${len}x1 xc:red \
-background none -gravity west -extent 360x1 $tmpT1
else
# test if range crosses hue=0 red
test=`convert xc: -format "%[fx:($dst1<0||$dst2<0)?1:0]" info:`
if [ $test -eq 1 ]; then
convert -size ${len}x1 xc: \
-fx "uu=($dst2-$dst1)*i/(w-1)+$dst1; mod(uu+360,360)/360" \
-channel red -evaluate set 0 +channel \
-background none -gravity west -extent 360x1 $tmpT1
else
dst1=`convert xc: -format "%[fx:100*$dst1/360]" info:`
dst2=`convert xc: -format "%[fx:100*$dst2/360]" info:`
convert -size ${len}x1 gradient:"gray($dst1%)"-"gray($dst2%)" \
-channel red -evaluate set 0 +channel \
-background none -gravity west -extent 360x1 $tmpT1
fi
fi
# roll the above tmp to the correct start (hue) position
# and composite with gradient
# and convert red to dst
src1=`convert xc: -format "%[fx:$srchue-$stoler]" info:`
sign=`convert xc: -format "%[fx:sign($src1)<0?0:1]" info:`
abs_src1=`convert xc: -format "%[fx:abs($src1)]" info:`
if [ $sign -eq 0 ]; then
rollval="-${abs_src1}+0"
else
rollval="+${abs_src1}+0"
fi
#echo "rollval=$rollval"
if [ $dtoler -eq 0 ]; then
dst1=`convert xc: -format "%[fx:100*$dst1/360]" info:`
convert $tmpG1 \( $tmpT1 -roll $rollval \) \
-compose over -composite \
-fill "gray($dst1%)" -opaque red \
$tmpG1
else
convert $tmpG1 \( $tmpT1 -roll $rollval \) \
-compose over -composite \
-channel G -separate +channel \
$tmpG1
fi
# apply modified gradient as lut to hue channel
convert $tmpH1 $tmpG1 -interpolate nearest-neighbor -clut $tmpH1
# colorspace swapped at IM 6.7.5.5, but not properly fixed until 6.7.6.6
# before swap verbose info reported colorspace=RGB after colorspace=sRGB
if [ "$im_version" -ge "06070606" ]; then
cspace="sRGB"
else
cspace="RGB"
fi
# recombine channels and convert to RGB
convert $tmpH1 -colorspace HSL \
$tmpH1 -compose CopyRed -composite \
$tmpS1 -compose CopyGreen -composite \
$tmpL1 -compose CopyBlue -composite \
-colorspace $cspace $tmpI1
# add alpha channel back if needed
if [ "$is_alpha" = "True" ]; then
convert $tmpI1 $tmpA1 -alpha off -compose copy_opacity -composite "$outfile"
else
convert $tmpI1 "$outfile"
fi
exit 0