#!/bin/sh
#
# anytopnm - attempt to convert an unknown type of image file to a P?M file.
#
# Copyright (C) 1991 by Jef Poskanzer.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation.  This software is provided "as is" without express or
# implied warranty.



putInputIntoTempfile() {

    # $1 is the input file specification
    # $2 is the temporary file name
    
    rm -f "$2"
    if [ "$1" = "-" ] ; then
            cat > "$2"
    else
        # We'd like to do a -e here to test the existence of the filesystem
        # object per se, and thus give a more specific error message.  But
        # some systems don't have -e.
        if [ ! -f "$1" ] ; then
            echo "$progname: '$1' does not exist or is not a file" 1>&2
            exit 1
            fi
        
        if [ ! -r "$1" ] ; then
            echo "$progname: '$1' is not readable" 1>&2
            exit 1
            fi
        
        if [ -z "$1" ] ; then
            echo "$progname: '$1' is empty" 1>&2
            exit 1
            fi
        
        cat < "$1" > "$2"
        fi
}



setMimeType() {
#------------------------------------------------------------------------------
# Set variable 'mimeType' to the mime type string (e.g. "application/binary")
#
# If we can't tell, set it to "unknown".
#------------------------------------------------------------------------------
    # $1 is the file name

    # Old versions of 'file' cannot tell us the mime type; they lack any option
    # to do so.
    #
    # Newer ones have a --mime option for that.
    #
    # Still newer ones (ca 2008) have a --mime option, but it does something
    # different - it prints the mime type plus the mime encoding.  And they
    # have --mime-type to print just the mime type.

    file --mime-type /dev/null >/dev/null 2>/dev/null
    if [ $? -eq 0 ]; then
        # Now that we know the --mime-type option exists, use it.
        mimeType=`file --mime-type "$1" | cut -d: -f2- | cut -c2-`
    else
        # file --mime-type failed; we don't know why, but we assume it's
        # because it is an older 'file' program that doesn't have a --mime-type
        # option.
        file --mime /dev/null >/dev/null 2>/dev/null
        if [ $? -eq 0 ]; then
            # Now that we know the --mime option exists, use it.
            mimeType=`file --mime "$1" | cut -d: -f2- | cut -c2-`
        else
            # file --mime failed; we don't know why, but we assume it's because
            # it is an older 'file' program that doesn't have a --mime option.
            mimeType="unknown"
        fi
    fi
}



computeTypeFromMimeType () {

# $1 is the mime type string
    
    case "$1" in

        image/jpeg )
            filetype="jfif"
            ;;
        image/gif )
            filetype="gif"
            ;;
        image/tiff )
            filetype="tiff"
            ;;
        image/bmp )
            filetype="bmp"
            ;;
        image/x-ms-bmp )
            filetype="bmp"
            ;;
        image/png )
            filetype="png"
            ;;
        image/x-portable-bitmap | image/x-portable-pixmap | \
                image/x-portable-greymap)
            filetype="pnm"
            ;;
        image/x-xpm )
            filetype="xpm"
            ;;
        * )
            filetype=unknown
            ;;
        esac
}



computeTypeFromTypeDescription () {

# $1 is the full description from 'file' of the file type

    case "$1" in
    
        *PBM* | *PGM* | *PPM* | *Netpbm*PAM*)
            filetype=pnm
            ;;
    
        *JPEG* | *JFIF* )
            filetype=jfif
            ;;
    
        *PNG* )
            filetype=png
            ;;
    
        *GIF* )
            filetype=gif
            ;;
    
        *TIFF* )
            filetype=tiff
            ;;
    
        # We have seen "PC bitmap" and "PC bitmap data"
        *PC*bitmap* )
            filetype=bmp
            ;;
        
        *uuencoded* )
            filetype=uuencoded
            ;;
    
        *bzip2*compressed*data* )
            filetype=bzip2
            ;;
    
        *bzip*compressed*data* )
            filetype=bzip
            ;;
        
        *gzip*compressed*data* )
            filetype=gzip
            ;;
    
        *XWD*X*Window*Dump* ) 
            filetype=xwd
            ;;

        *compress* )
            filetype=compress
            ;;
    
        *btoa* )
            filetype=btoa
            ;;
    
        *Sun* | *rasterfile* )
            filetype=rast
            ;;
    
        *IFF*ILBM* )
            filetype=ilbm
            ;;
    
        *Lisp* )
            filetype=lispm
            ;;
    
        *PC*Paintbrush* )
            filetype=pcx
            ;;
    
        *Bennet* )
            filetype=ybm
            ;;
    
        *pixmap*image*text* )
            filetype=xpm
            ;;
    
        # This has to come after all other 'text' files, or you may be
        # disappointed.
        *text* )
            filetype=text
            ;;
    
        *MicroDesign* )
            filetype=mda
            ;;
    
        * )
            filetype=unknown
            ;;
        esac
}



computeTypeFromFilenameExtension () {
# $1 is the filename extension (".gif", etc.)

    case "$1" in

        *.pbm | *.pbm.* | *.pgm | *.pgm.* | *.ppm | *.ppm.* )
            filetype=pnm
            ;;
        *.JPEG | *.jpeg | *.jpg | *.JPG )
            filetype=jfif
            ;;
        *.gif | *.gif.* )
            filetype=gif
            ;;
        *.png | *.PNG )
            filetype=png
            ;;
        *.tif | *.tif.* | *.tiff | *.tiff.* )
            filetype=tiff
            ;;
        *.bmp )
            filetype=bmp
            ;;
        *.x | *.x.* | *.xbm | *.xbm.* | *.x10bm | *.x10bm.* | \
            *.x11bm | *.x11bm.* | *.bitmap | *.bitmap.* )
            filetype=xbm
            ;;
        *.r | *.r.* | *.rast | *.rast.* )
            filetype=rast
            ;;
        *.mac | *.mac.* | *.macp | *.macp.* )
            filetype=macp
            ;;
        *.g3 | *.g3.* | *.fax | *.fax.* )
            filetype=g3
            ;;
        *.xwd | *.xwd.* | *.x10wd | *.x10wd.* \
                | *.x11wd | *.x11wd.* )
            filetype=xwd
            ;;
        *.brush | *.brush.* )
            filetype=brush
            ;;
        *.img | *.img.* )
            filetype=gem
            ;;
        *.pcx | *.pcx.* )
            filetype=pcx
            ;;
        *.pic | *.pic.* | *.pict | *.pict.* | *.pict2 | *.pict2.* )
            filetype=pict
            ;;
        *.fs | *.fs.* | *.face | *.face.* )
            filetype=fs
            ;;
        *.hips | *.hips.* )
            filetype=hips
            ;;
        *.fits | *.fits.* )
            filetype=fits
            ;;
        *.iff | *.iff.* | *.ilbm | *.ilbm.* )
            filetype=ilbm
            ;;
        *.lispm | *.lispm.* )
            filetype=lispm
            ;;
        *.mtv | *.mtv.* )
            filetype=mtv
            ;;
        *.qrt | *.qrt.* )
            filetype=qrt
            ;;
        *.tga | *.tga.* | *.targa | *.targa.* )
            filetype=tga
            ;;
        *.xim | *.xim.* )
            filetype=xim
            ;;
        *.xpm | *.xpm.* | *.xpm2 | *.xpm2.* )
            filetype=xpm
            ;;
        *.pi1 | *.pi1.* )
            filetype=pi1
            ;;
        *.pi3 | *.pi3.* )
            filetype=pi3
            ;;
        *.spu | *.spu.* )
            filetype=spu
            ;;
        *.spc | *.spc.* )
            filetype=spc
            ;;
        *.ybm | *.ybm.* | *.face | *.face.* )
            filetype=ybm
            ;;
        *.mda | *.mdp )
            filetype=mda
            ;;
        * )
            filetype=unknown
            ;;
        esac
}



determineType () {

# $1 is the name of the file that contains the subject file's contents
# $2 is the mime type or "unknown"
# $3 is the type description from 'file'

    if [ "$2" = "unknown" ]; then
        filetype="unknown"
    else
        computeTypeFromMimeType "$2"
        fi

    if [ "$filetype" = "unknown" ]; then
        computeTypeFromTypeDescription "$3"
        fi

    if [ "$filetype" = "unknown" ]; then
        computeTypeFromFilenameExtension "$4"
        fi
}



convertIt () {
# Based on the file type computed, do the conversion

# $1 is the input file name
# $2 is our file type code

case "$2" in

    pnm )
        cat "$file"
        ;;

    uuencoded )
        newfile="$tempdir/atn.decode.$$"
        rm -f "$newfile"
        (echo begin 600 $newfile; sed 1d < "$file") | uudecode
        anytopnm "$newfile"
        ;;

    bzip2 )
        bzip2 -dk < "$file" | anytopnm -
        ;;

    bzip )
        bzip -dk < "$file" | anytopnm -
        ;;

    gzip )
        gzip --decompress --to-stdout < "$file" | anytopnm -
        ;;

    compress )
        uncompress -c < "$file" | anytopnm -
        ;;

    btoa )
        atob < "$file" | anytopnm -
        ;;

    rast )
        rasttopnm "$file"
        ;;

    gif )
        giftopnm -image=all "$file"
        ;;

    tiff )
        tifftopnm "$file"
        ;;

    ilbm )
        ilbmtoppm "$file"
        ;;

    lispm )
        lispmtopgm "$file"
        ;;

    pcx )
        pcxtoppm "$file"
        ;;

    ybm )
        ybmtopbm "$file"
        ;;

    xpm )
        xpmtoppm < "$file"
        ;;

    # This has to come after all other 'text' files, or you may be
    # disappointed.
    text )
        pbmtext -builtin fixed < "$file"
        ;;

    jfif )
        jpegtopnm "$file"
        ;;

    png )
        pngtopam "$file"
        ;;

    mda )
        mdatopbm -d -- "$file"
        ;;

    bmp )
        bmptoppm "$file"
        ;;
    
    xbm )
        xbmtopbm "$file"
        ;;
    macp )
        macptopbm "$file"
        ;;
    g3 )
        g3topbm "$file"
        ;;
    xwd )
        xwdtopnm "$file"
        ;;
    brush )
        brushtopbm "$file"
        ;;
    img )
        gemtopbm "$file"
        ;;
    pcx ) 
        pcxtoppm "$file"
        ;;
    pict )
        picttoppm "$file"
        ;;
    fs )
        fstopgm "$file"
        ;;
    hips )
        hipstopgm "$file"
        ;;
    fits )
        fitstopnm "$file"
        ;;
    mtv )
        mtvtoppm "$file"
        ;;
    qrt )
        qrttoppm "$file"
        ;;
    tga )
        tgatoppm "$file"
        ;;
    xim )
        ximtoppm "$file"
        ;;
    pi1 )
        pi1toppm "$file"
        ;;
    pi3 )
        pi3topbm "$file"
        ;;
    spu )
        sputoppm "$file"
        ;;
    spc )
        spctoppm "$file"
        ;;
    * )
        echo "$progname: INTERNAL ERROR.  Illegal value of filetype variable"
        exit 1
        ;;

    esac
}



###############################################################################
#                                MAINLINE
###############################################################################

progname=$0

if [ $# -gt 1 ] ; then
    echo "Too many arguments: $#.  The only valid argument is the" \
         "input file name." 1>&2
    exit 1
elif [ $# -eq 1 ] ; then
    if [ "$1" = "--version" -o "$1" = "-version" ] ; then
        pamtopnm --version ; exit $?
    else 
        inputFile="$1"
    fi
else
        inputFile="-"

fi

tempdir=$(mktemp -d "${TMPDIR:-/tmp}/anytopnm.XXXXXXXX") ||
    { echo "Could not create temporary file. Exiting." 1>&2; exit 1; }
trap 'rm -rf $tempdir' 0

# Take out all spaces
# Find the filename extension for last-ditch efforts later

# We used to do this, but it doesn't work with all Awks.  The sed below
# is universal.  2005.11.02.
#fileExtension=`echo "$inputFile" | \
#               $AWK '{gsub(" ","");gsub(".*\\\\.",".");print}'`

fileExtension=`echo "$inputFile" | sed 's/ //;s/.*\././g'`

file="$tempdir/atn.stdin.$$"

putInputIntoTempfile "$inputFile" "$file"

setMimeType "$file"

typeDescription=`file "$file" | cut -d: -f2- | cut -c2-`

determineType "$file" "$mimeType" "$typeDescription" "$fileExtension"

if [ "$filetype" = "unknown" ]; then
    echo "$progname: unknown file type.  " \
        "'file' says mime type is '$mimeType', " 1>&2
    echo "type description is '$typeDescription'" 1>&2
    exit 1
    fi

convertIt $file $filetype

exit 0
