#!SCRIPTSHELLCMD_MARKER ############################################################################## # # # CONFIGURABLE THINGS ... # # # ############################################################################## # First off, is the shell after the '#!' at the top of the file valid? It # must be the full pathname of a shell that understands shell functions. # The suggested order of preference is full/path/of/ksh, full/path/of/bash. # If you want to use some non-standard initial verbosity, then set it # here, otherwise a sensible default is set elsewhere. # VERBOSE_LEVEL=3 # provide extra information # VERBOSE_LEVEL=0 # provide no messages at all # VERBOSE_LEVEL=1000 # provide all debug DFLT_THN_MODE=1024x768_5x6 DFLT_THP_COL_BG=black DFLT_THT_COL_BG=white DFLT_THP_QLT_PC=80 DFLT_FIL_MODE=normal DFLT_VERBOSE_LEVEL=2 TMPDIR=/var/tmp ############################################################################## # # # THE AUTHOR MAY CHANGE THINGS BELOW HERE, BUT THE CONFIGUROR SHOULD NOT! # # # ############################################################################## PROGNAME=`basename $0` # $Id: mtn.in,v 1.7 1998/01/28 14:58:03 alexis Exp $ VERSION="PATCHLEVEL_MARKER" OUTNAME="index" MTNTMPDIR=$TMPDIR/$PROGNAME.$$ ############################################################################## # # # MAIN FUNCTION # # # # This function processes options and then performs whatever this script is # # supposed to do. It is called from the very end of the script. # # # ############################################################################## main() { THN_MODE=$DFLT_THN_MODE FIL_MODE=$DFLT_FIL_MODE THP_COL_BG=$DFLT_THP_COL_BG THT_COL_BG=$DFLT_THT_COL_BG THP_QLT_PC=$DFLT_THP_QLT_PC VERBOSE_LEVEL=$DFLT_VERBOSE_LEVEL # Process options - author to add extra options! while [ "X$1" != X ]; do case "$1" in -V) if expr "$VERSION" : 'P.*R$' > /dev/null; then warning "this is a development version; use 'ident' for version information" exit 1 else echo "$PROGNAME version $VERSION" exit 0 fi ;; -d) [ "X$2" = X ] && usage VERBOSE_LEVEL=$2 shift ;; -v) VERBOSE_LEVEL=3 ;; -r) FIL_MODE=recurse ;; -m) [ "X$2" != X ] || usage THN_MODE=$2 shift ;; -*) usage ;; *) break ;; esac shift done [ $FIL_MODE = normal -a "X$1" = X ] && usage set_mode_vars $THN_MODE rm -fr $MTNTMPDIR trap "echo 'cleaning up, please wait ...'; rm -fr $MTNTMPDIR; exit 1" 1 2 15 mkdir $MTNTMPDIR ########################################################################### # # Create blank title and picture of maximum sizes # ########################################################################### info "creating blank thumbnail ..." pbmmake -$THP_COL_BG $THP_WDT_PXL $THP_HGT_PXL > $MTNTMPDIR/blank-pic.pbm info "creating blank title ..." pbmmake -$THT_COL_BG $THP_WDT_PXL $THT_HGT_PXL > $MTNTMPDIR/blank-tit.pbm case $FIL_MODE in normal) process $OUTNAME "$*" ;; recurse) OLD_PWD=`pwd` find ${*:-.} -type f | grep -v '.xvpics' | sed 's/^\(.*\)\/[^\/][^\/]*$/\1/' | sort -u | while read DIR; do info "recursing into $DIR ..." cd $DIR if [ -f index0.jpg ]; then info "index0.jpg exists" else process $OUTNAME * fi cd $OLD_PWD done ;; esac } set_mode_vars() { case $THN_MODE in 1024x768_5x6) IDP_HGT_THN=5 IDP_WDT_THN=6 THP_WDT_PXL=170 THP_HGT_PXL=123 THT_HGT_PXL=29 IDT_HGT_PXL=29 IDT_WDT_PXL=984 ;; *) error "invalid or unsupported mode" ;; esac } ############################################################################## # # # USAGE FUNCTION # # # # This function just displays a message indicating the correct usage # # syntax. It is called from whereever a usage syntax error is detected - # # mainly from the option and required argument processing code. # # # ############################################################################## usage() { { echo "Usage: $PROGNAME [ -d | -v ] [ -r ] [ -m x_x ] { | } ..." echo " $PROGNAME -V" } >&2 exit 2 } ############################################################################## # # # STATUS MESSAGE FUNCTIONS # # # # These functions display standard messages on the screen. These include # # error messages, warnings, informational messages and debug messages. # # # ############################################################################## internal() { echo "$PROGNAME: INTERNAL \ ERROR: $*" >&2 exit 2 } VERBOSE_LEVEL=${VERBOSE_LEVEL:-2} error() { FATAL=false while :; do case "$1" in -f) FATAL=true ;; -*) internal "invalid option to error() '$1'" ;; *) break ;; esac shift done if [ $VERBOSE_LEVEL -ge 1 ]; then if [ $FATAL = true ]; then echo "$PROGNAME: FATAL \ ERROR: $*" >&2 else echo "$PROGNAME: \ ERROR: $*" >&2 fi fi [ $FATAL = true ] && exit 1 return 1 } VERBOSE_LEVEL=${VERBOSE_LEVEL:-2} warning() { [ $VERBOSE_LEVEL -ge 2 ] && { echo "$PROGNAME: \ WARNING: $*" >&2; } return 0 } VERBOSE_LEVEL=${VERBOSE_LEVEL:-2} debug() { [ $VERBOSE_LEVEL -ge $1 ] && { shift; echo "$PROGNAME: \ DEBUG: $*" >&2; } return 0 } VERBOSE_LEVEL=${VERBOSE_LEVEL:-2} info() { [ $VERBOSE_LEVEL -lt 3 ] && return while :; do case "$1" in -*) internal "invalid option to info() '$1'" ;; *) break ;; esac shift done echo "$PROGNAME: \ INFO: $*" >&2 return 0 } # The method to suppress the newline displayed by the 'echo' command # varies from system to system. This function abstracts this variation. # Note that even if you don't use this command directly yourself, it *is* # called by other functions in this script. ############################################################################## # # # SUPPORT FUNCTIONS # # # ############################################################################## # This function should be called for each major command this script calls. # It tests that the command exists and is in a standard place. It should be # called *after* option processing. A simple example of how to use it is: # REMSH_CMD=`locatecmd remsh rsh ssh` || error -f "can't locate remote shell" # Note that 'whichcmd' is required by 'locatecmd'. locatecmd() { for POSSCMD in $*; do [ X`whichcmd $POSSCMD` != X ] && { echo $POSSCMD; return 0; } done return 1 } whichcmd() { for DIR in `echo $PATH | sed 's/:/ /g'`; do [ -x $DIR/$1 ] && { echo $DIR/$1; return 0; } done return 1 } process() { debug 4 "process: TOF" L_OUTNAME=$1 shift PROCFILES="$*" for FILE in $PROCFILES; do debug 4 "process: loop $FILE" FILEBASE=`basename $FILE` ####################################################################### # # Convert each picture to PNM format # ####################################################################### info "$FILE: converting image to PNM format ..." case $FILE in *.[jJ][Pp][Gg]|*.[Jj][Pp][Ee][Gg]) djpeg < $FILE ;; *.[Gg][Ii][Ff]) giftopnm < $FILE ;; *) error "$FILE: unknown file extension" ;; ####################################################################### # # Scale each picture to maximum allowable size without distorting # ####################################################################### esac | { info "$FILE: \ creating ${THP_WDT_PXL}x$THP_HGT_PXL thumbnail ..." pnmscale -xysize $THP_WDT_PXL $THP_HGT_PXL > $MTNTMPDIR/$FILEBASE-sclpic.pnm } ####################################################################### # # Put each picture in the middle of a maximum sized blank thumbnail # ####################################################################### info "$FILE: calculating required thumbnail offsets ..." set X `pnmfile $MTNTMPDIR/$FILEBASE-sclpic.pnm` X=$5; Y=$7 info "$FILE: centering thumbnail ..." pnmpaste $MTNTMPDIR/$FILEBASE-sclpic.pnm `expr \( $THP_WDT_PXL - $X \) / 2` `expr \( $THP_HGT_PXL - $Y \) / 2` $MTNTMPDIR/blank-pic.pbm > $MTNTMPDIR/$FILEBASE-pddpic.pnm ####################################################################### # # For each picture generate a title # ####################################################################### info "$FILE: generating title ..." pbmtext `echo $FILE | cut -c1-20` > $MTNTMPDIR/$FILEBASE-tit.pbm ####################################################################### # # Put each picture's title in middle of a maximum sized blank title # ####################################################################### info "$FILE: calculating title padding offsets ..." set X `pnmfile $MTNTMPDIR/$FILEBASE-tit.pbm` X=$5; Y=$7 info "$FILE: centering title ..." pnmpaste $MTNTMPDIR/$FILEBASE-tit.pbm `expr \( $THP_WDT_PXL - $X \) / 2` `expr \( $THT_HGT_PXL - $Y \) / 2` $MTNTMPDIR/blank-tit.pbm > $MTNTMPDIR/$FILEBASE-pddtit.pnm done IDXS=0 COLS=0 ROWS=0 ROWPICFILES= ROWTITFILES= IDXFILES= ########################################################################### # # Now combine all the correctly sized titles and thumbnails # ########################################################################### for FILE in $PROCFILES; do info "next: $FILE" FILEBASE=`basename $FILE` ROWPICFILES="$ROWPICFILES $MTNTMPDIR/$FILEBASE-pddpic.pnm" ROWTITFILES="$ROWTITFILES $MTNTMPDIR/$FILEBASE-pddtit.pnm" COLS=`expr $COLS + 1` ####################################################################### # # If we have six then combine the titles and thumbnails into a row # ####################################################################### if [ `expr $COLS / $IDP_WDT_THN` = 1 ]; then info "complete row: $ROWPICFILES - creating row $MTNTMPDIR/rowpic-$ROWS.pnm" pnmcat -lr -$THP_COL_BG $ROWPICFILES > $MTNTMPDIR/rowpic-$ROWS.pnm ROWPICFILES= pnmcat -lr -$THT_COL_BG $ROWTITFILES > $MTNTMPDIR/rowtit-$ROWS.pnm ROWTITFILES= IDXFILES="$IDXFILES $MTNTMPDIR/rowpic-$ROWS.pnm $MTNTMPDIR/rowtit-$ROWS.pnm" ROWS=`expr $ROWS + 1` COLS=0 fi ####################################################################### # # If we have five rows then combine them into an index # ####################################################################### if [ `expr $ROWS / $IDP_HGT_THN` = 1 ]; then info "complete index: $IDXFILES - creating index $MTNTMPDIR/$L_OUTNAME$IDXS.pnm" pnmcat -tb $IDXFILES | cjpeg -Q $THP_QLT_PC > $L_OUTNAME$IDXS.jpg IDXFILES= IDXS=`expr $IDXS + 1` ROWS=0 fi done ########################################################################### # # Now combine all outstanding pics that weren't enough to make a row # and pad to the end of the row with blanks # ########################################################################### if [ $COLS != 0 ]; then info "incomplete row - padding with blanks ($COLS/$IDP_WDT_THN)" while [ `expr $COLS / $IDP_WDT_THN` = 0 ]; do info "next: blank" ROWPICFILES="$ROWPICFILES $MTNTMPDIR/blank-pic.pbm" ROWTITFILES="$ROWTITFILES $MTNTMPDIR/blank-tit.pbm" COLS=`expr $COLS + 1` done info "padded row: $ROWPICFILES - creating row $MTNTMPDIR/rowpic-$ROWS.pnm" pnmcat -lr -$THP_COL_BG $ROWPICFILES > $MTNTMPDIR/rowpic-$ROWS.pnm ROWPICFILES= pnmcat -lr -$THT_COL_BG $ROWTITFILES > $MTNTMPDIR/rowtit-$ROWS.pnm ROWTITFILES= IDXFILES="$IDXFILES $MTNTMPDIR/rowpic-$ROWS.pnm $MTNTMPDIR/rowtit-$ROWS.pnm" ROWS=`expr $ROWS + 1` COLS=0 fi ########################################################################### # # Now combine all outstanding rows that weren't enough to make an index # ########################################################################### if [ $ROWS != 0 ]; then info "incomplete index (not padding): $IDXFILES - creating index $MTNTMPDIR/$L_OUTNAME$IDXS.pnm" pnmcat -tb $IDXFILES | cjpeg -Q $THP_QLT_PC > $L_OUTNAME$IDXS.jpg IDXFILES= IDXS=`expr $IDXS + 1` ROWS=0 fi rm -fr $MTNTMPDIR } ############################################################################## # # # ENTRY POINT # # # ############################################################################## # All files created should be readable by all. You might want to change this # to 'umask 077' to exclude all access for group and others. umask 022 # Call the main function, passing it the same arguments that this script # itself recieved. main "$@" # If main() returned an exit code then now pass that back to the thing that # called this script. Note that that is what would happen anyway but this # just makes that a little more explicit. exit $?