FUNCTION img_read, img_file, img_data, Red, Green, Blue,    $
        pseudocolor     = PseudoColor   ,   $
        truecolorimage  = TrueColorImage,   $
        rgbplane        = RGBPlane      ,   $
        truedimension   = truedimension ,   $
        exten_no        = exten_no      ,   $
        silent          = silent        ,   $
        _extra          = _extra        ,   $
        img_info        = img_info      ,   $
        errormessage    = errormessage
    @compile_opt.pro        ; On error, return to caller

InitVar, PseudoColor    , /key
InitVar, truedimension  , 1
InitVar, silent         , 0
InitVar, exten_no       , 0

; Prompt for file name

CASE 1 OF
IsType(img_file, /undefined): tmp = (dialog_pickfile(title='Select PNG, GIF, TIF, BMP, FIT, FTS or IMG file',_extra=_extra))[0]
img_file NE '': tmp = (file_search(img_file))[0]
ELSE: tmp = img_file
ENDCASE

IF tmp EQ '' THEN BEGIN
    InitVar, img_file, ''
    errormessage = (['No file name specified','File not found, '+img_file])[img_file NE '']
    IF silent LE 1 THEN message, /info, errormessage

    status = 0
    img_data = -1

    RETURN, status
ENDIF

;img_file = GetFileSpec(tmp)

img_file = tmp
gzipped = gunzip_file(img_file, raw_file)

IF gzipped THEN BEGIN
    zip_file = img_file
    img_file = raw_file
ENDIF

type = GetFileSpec(img_file, part='type')
status = 1

CASE strlowcase(type) OF

'.png': BEGIN

    catch, error

    CASE error OF
    0   : img_data = read_png(img_file, Red, Green, Blue)   ; Read PNG file
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

    IF status THEN BEGIN
        TrueColorImage = size(img_data, /n_dim) EQ 3
        IF TrueColorImage THEN BEGIN
            tmp = (where(size(img_data,/dim) EQ 3))[0]
            IF truedimension NE tmp+1 THEN BEGIN
                tmp = shift( [0,1,2], truedimension-(tmp+1))
                img_data = transpose(img_data, tmp)
            ENDIF
        ENDIF
    ENDIF

END

'.gif': BEGIN

    catch, error

    CASE error OF
    0   : read_gif, img_file, img_data, Red, Green, Blue; Read GIF file
    ELSE: BEGIN
        errormessage = !error_state.msg
        if silent le 1 then message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

END

'.tif': BEGIN                                           ; Read TIF file

    catch, error

    CASE error OF
    0   : img_data = read_tiff( img_file, Red, Green, Blue, planar=Planar )
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

    IF status THEN BEGIN

        ; Put the image upside down. (Why did I do this????)

        IF Planar EQ 2 THEN BEGIN           ; img_data=0, color planes in Red,Green,Blue
            ;Red   = reverse(Red  ,2)
            ;Green = reverse(Green,2)
            ;Blue  = reverse(Blue ,2)

            img_data = SuperArray(Red, 3, /lead)
            img_data = SubArray(img_data, element=1, add=Green)
            img_data = SubArray(img_data, element=2, add=Blue )

            tmp = temporary(Red)            ; Destroy Red, Green, Blue arrays
            tmp = temporary(Green)
            tmp = (temporary(Blue))[0]

            TrueColorImage = 1-PseudoColor

            CASE PseudoColor OF             ; Reduce to pseudo-color image
            0: RGBPlane = [0,1,2]           ; Order of color planes (r,g,b-planes)
            1: img_data = color_quan(img_data, 1, Red, Green, Blue)
            ENDCASE

        ENDIF ELSE BEGIN
            ;img_data = reverse(img_data,2)

        ENDELSE

    ENDIF

END

'.jpg': BEGIN                           ; Read JPEG file

    catch, error

    CASE error OF
    0   : read_jpeg, img_file, img_data, true=truedimension
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

    IF status THEN BEGIN

        TrueColorImage = 1-PseudoColor

        CASE PseudoColor OF                 ; Reduce to pseudo-color image
        0: RGBPlane = [0,1,2]               ; Order of color planes (r,g,b-planes)
        1: img_data = color_quan(img_data, truedimension, Red, Green, Blue)
        ENDCASE

    ENDIF

END

'.jpeg': BEGIN                          ; Read JPEG file

    catch, error

    CASE error OF
    0   : read_jpeg, img_file, img_data, true=truedimension
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

    IF status THEN BEGIN

        TrueColorImage = 1-PseudoColor

        CASE PseudoColor OF                 ; Reduce to pseudo-color image
        0: RGBPlane = [0,1,2]               ; Order of color planes (r,g,b-planes)
        1: img_data = color_quan(img_data, truedimension, Red, Green, Blue)
        ENDCASE

    ENDIF

END

'.bmp': BEGIN                           ; Read BMP file

    catch, error

    CASE error OF
    0   : img_data = read_bmp ( img_file, Red, Green, Blue, /rgb )
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel

    IF status THEN BEGIN

        IF IsType(Red,/undefined) THEN BEGIN

            TrueColorImage = 1-PseudoColor

            CASE PseudoColor OF
            0: RGBPlane = [0,1,2]
            1: img_data = color_quan( img_data, 1, Red, Green, Blue)
            ENDCASE
        ENDIF

    ENDIF

 END

'.fit' : BEGIN
    catch, error

    CASE error OF
    0   : img_data = readfits ( img_file , img_info, exten_no=exten_no ); Read FITS file
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel
END

'.fits': BEGIN
    catch, error

    CASE error OF
    0   : img_data = readfits ( img_file , img_info, exten_no=exten_no  ); Read FITS file
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel
END

'.fts' : BEGIN
    catch, error

    CASE error OF
    0   : img_data = readfits ( img_file , img_info, exten_no=exten_no  ); Read FITS file
    ELSE: BEGIN
        errormessage = !error_state.msg
        IF silent LE 1 THEN message, /info, errormessage
        status = 0
    END
    ENDCASE

    catch, /cancel
END

'.txt' : status = flt_read( img_file, img_data, errormessage=errormessage ) ; Read ASCII file

'.img' : BEGIN
    status = bin_read(img_file, img_data, type=IsType(/short_int),  $
        header=160, nx=384, /silent, errormessage=errormessage)
    if status then img_data = rotate(img_data,3)        ; Read CCD image file
END

'.nic' : status = bin_read( img_file, img_data, trailer=img_info, /silent, errormessage=errormessage)

'.pph' : status = bin_read( img_file, img_data, trailer=img_info, /silent, errormessage=errormessage)

'.grd' : status = grd_read( img_file, img_data, errormessage=errormessage )

ELSE   : BEGIN
    message, /info, 'No reader for '+type+' files implemented'
    status = 0
END
ENDCASE

CASE status OF
0: img_data = -1
1: BEGIN

    ; ======== FUDGE
    ;
    ; At this point img_info (if it exists) is a FITS header string array, or a binary trailer.

    ; The output img_info is returned mainly for the benefit of the qview widget.
    ; It should be a two-element string array. The first is generic information; the second should
    ; be a string indicating the time to be associated with the image.

    is_smei = 0
    is_frm  = 0
    is_sky  = 0
    is_cal  = 0

    CASE IsType(img_info) OF

    IsType(/string): BEGIN      ; FITS header

        time = smei_filename(img_file,mode=mode,pos_tt=is_smei)
        is_smei = is_smei[0] NE -1      ; 1 if file name contains time  

        is_sky = IsType(mode,/string)

        CASE is_sky OF
        0: BEGIN
            is_frm = IsType(mode,/generic_integer)
            IF is_frm THEN smei_hdr = smei_frm_cvhdr(from_fits=img_info, /to_hdr)
        END
        1: BEGIN
            is_cal = mode EQ 'cal'
            is_sky = 1-is_cal
        END
        ENDCASE

    END

    IsType(/byte_x): BEGIN      ; Trailer from .nic or .pph file

        is_smei = n_elements(img_info) GT 3
        is_frm = is_smei
        IF is_frm THEN is_frm = where( string(img_info[0:2]) EQ ['buf','pat'] ) NE -1

        ; This reads the SMEI frame again to apply the head room (multiplication by 4/3 if needed)

        IF is_frm THEN img_data = smei_frm_read(img_file, hdr=smei_hdr, /silent)

    END

    ELSE:

    ENDCASE

    CASE 1 OF

    is_cal: BEGIN
        img_data = MagnifyArray(img_data, 256/(size(img_data,/dim))[1])
        nn = size(img_data,/dim)
        fxaddpar, img_info, 'NAXIS1', nn[0]
        fxaddpar, img_info, 'NAXIS2', nn[1]
        img_info = [strjoin(img_info+string([13b,10b])),'']
    END

    is_frm: BEGIN
        img_info = [smei_frm_cvhdr(from_hdr=smei_hdr, /to_ascii),       $
                    TimeGet( smei_property(smei_hdr,/time), /ymd, upto=TimeUnit(/sec))]
        img_data = MagnifyArray(img_data, 256/(size(img_data,/dim))[1])
    END

    is_sky:     $
        img_info = [strjoin(img_info+string([13b,10b])),    $
                    TimeGet( time, /ymd, upto=TimeUnit(/sec))]

    ELSE: BEGIN
        CASE IsType(img_info) OF
        IsType(/string): img_info = [strjoin(img_info+string([13b,10b])),'']
        IsType(/byte_x): img_info = [string(img_info),'']
        ELSE           : img_info = ['','']
        ENDCASE
    END

    ENDCASE

    ; ===============

    IF silent LE 0 THEN BEGIN
        zmin = min(img_data, /nan, max=zmax)
        IF IsType(zmin,/byte_x) THEN BEGIN
            zmin = fix(zmin)
            zmax = fix(zmax)
        ENDIF
        CASE gzipped OF
        0: message, /info, hide_env(img_file)+' ['+strcompress(zmin,/rem)+','+strcompress(zmax,/rem)+']'
        1: message, /info, hide_env(zip_file)+' ['+strcompress(zmin,/rem)+','+strcompress(zmax,/rem)+']'
        ENDCASE
    ENDIF

END
ENDCASE

; Delete the temporary uncompressed image file (created from gzip file)

IF gzipped THEN tmp = do_file(img_file, /delete, /silent)

RETURN, status  &  END