1;+
2;
3; NAME:
4;     READ_ENVI_FILE
5; PURPOSE:
6;     Reads an ENVI style formatted image file (both compressed and
7;     uncompressed).
8;
9; CATEGORY:
10;     File I/O
11;
12; CALLING SEQUENCE:
13;     READ_ENVI_FILE, filename, image=image, info=image_info
14;
15; KEYWORD PARAMETERS:
16;     FILENAME: A string containing the full filepath name of the image.
17;     IMAGE: Variable name to contain the image/array
18;     INFO: Variable name to contain the image information as a structure
19;     HELP: showing how to use and exit
20;
21; OUTPUTS:
22;     image: An array containing the image
23;     image_info: A structure containing information about the image
24;                 eg. number of samples, number of lines, number of bands,
25;                 data type, interleave, file description, band names.
26;
27; MODIFICATION HISTORY:
28; 02-Jul-2012: Written by Josh Sixsmith
29; 16-Feb-2014: Better managment of input filenames
30;
31; LICENCE:
32; Copyright (C) 2012, Josh Sixsmith
33; This program is free software; you can redistribute it and/or modify
34; it under the terms of the GNU General Public License as published by
35; the Free Software Foundation; either version 3 of the License, or
36; (at your option) any later version.
37;
38;-
39;
40function NUM_SAMPLES, header
41;
42COMPILE_OPT hidden
43ON_ERROR, 2
44;
45fnsw = WHERE(STRPOS(header, "samples") NE -1, count)
46IF (count NE 0) THEN BEGIN
47   fns  = STRTRIM(header[fnsw], 2)
48   fns1 = STRPOS(fns, '=')
49   ns   = STRMID(fns, fns1 + 2)
50   ;;
51   RETURN, (LONG(ns))[0]
52ENDIF ELSE BEGIN
53   MESSAGE, 'Number of Samples Not Found.'
54ENDELSE
55;
56END
57;
58;-----------------------------------------------------------------------
59;
60function NUM_LINES, header
61;
62COMPILE_OPT hidden
63ON_ERROR, 2
64;
65fnlw = WHERE(STRPOS(header, "lines") NE -1, count)
66IF (count NE 0) THEN BEGIN
67   fnl  = STRTRIM(header[fnlw], 2)
68   fnl1 = STRPOS(fnl, '=')
69   nl   = STRMID(fnl, fnl1 + 2)
70   ;;
71   RETURN, (LONG(nl))[0]
72ENDIF ELSE BEGIN
73   MESSAGE, 'Number of Lines Not Found.'
74ENDELSE
75;
76END
77;
78;-----------------------------------------------------------------------
79;
80function NUM_BANDS, header
81;
82COMPILE_OPT hidden
83ON_ERROR, 2
84;
85fnbw = WHERE(STRPOS(header, "bands") NE -1, count)
86IF (count NE 0) THEN BEGIN
87   fnb = STRTRIM(header[fnbw], 2)
88   fnb1 = STRPOS(fnb, '=')
89   nb = STRMID(fnb, fnb1 + 2)
90   ;;
91   RETURN, (LONG(nb))[0]
92ENDIF ELSE BEGIN
93   MESSAGE, 'Number of Bands Not Found.'
94ENDELSE
95;
96END
97;
98;-----------------------------------------------------------------------
99;
100function MAP_INFO, header
101;
102COMPILE_OPT hidden
103ON_ERROR, 2
104;
105fmiw = WHERE(STRPOS(header, "map") NE -1, count)
106IF (count NE 0) THEN BEGIN
107   fmi = STRTRIM(header[fmiw], 2)
108   b1 = STRPOS(fmi, '{')
109   b2  = STRPOS(fmi, '}', /reverse_search)
110   b2b = STRSPLIT(STRMID(fmi, b1+1, b2-b1-1), ',', /extract)
111   mi  = {MapInfo, $
112          ProjectionName : b2b[0], $
113          ULRefX : b2b[1], $
114          ULRefY : b2b[2],$
115          ULXCoord : b2b[3],$
116          ULYCoord : b2b[4], $
117          XS : b2b[5], $
118          YS : b2b[6], $
119          Zone : b2b[7], $
120          Units : b2b[8]}
121ENDIF ELSE BEGIN
122   mi = {map_info, empty:''}
123ENDELSE
124;
125RETURN, mi
126;
127END
128;
129;-----------------------------------------------------------------------
130;
131FUNCTION DATATYPE, header
132;
133COMPILE_OPT hidden
134ON_ERROR, 2
135;
136;; Maybe need a check for correct data type, using filesize and array
137;; dimensions before trying to read the data.
138;
139fdtw = WHERE(STRPOS(header, "data type") NE -1, count)
140IF (count NE 0) THEN BEGIN
141   fdt =  STRTRIM(header[fdtw], 2)
142   fdt1 = STRPOS(fdt, '=')
143   dtype   = STRMID(fdt, fdt1 + 2)
144   ;;
145   RETURN, (FIX(dtype))[0]
146ENDIF ELSE BEGIN
147   MESSAGE, 'No Data Type Found.'
148ENDELSE
149;
150END
151;
152;-----------------------------------------------------------------------
153;
154FUNCTION interleave, header
155;
156COMPILE_OPT hidden
157ON_ERROR, 2
158;
159filw = WHERE(STRPOS(header, "interleave") NE -1, count)
160IF (count NE 0) THEN BEGIN
161   fil = STRTRIM(header[filw], 2)
162   fil1 = STRPOS(fil, '=')
163   ileave   = STRMID(fil, fil1 + 2)
164   ;;
165   IF (STRCMP(ileave, 'BSQ', /fold_case)) EQ 1 THEN BEGIN
166      intleave = 0
167   ENDIF ELSE BEGIN
168      IF (strcmp(ileave, 'BIL', /fold_case)) EQ 1 THEN BEGIN
169         intleave = 1
170      ENDIF ELSE BEGIN
171         IF (STRCMP(ileave, 'BIP', /fold_case)) EQ 1 THEN BEGIN
172            intleave = 2
173         ENDIF ELSE BEGIN
174            MESSAGE, 'Unknown Interleaving; Need either BSQ/BIL/BIP.'
175         ENDELSE
176      ENDELSE
177   ENDELSE
178   ;;
179ENDIF ELSE BEGIN
180   MESSAGE, 'No Interleave Found, Assuming BSQ.', /continue
181   intleave = 0
182ENDELSE
183;
184RETURN, intleave
185;
186END
187;
188;-----------------------------------------------------------------------
189;
190function READ_HEADER, filename
191;
192COMPILE_OPT hidden
193ON_ERROR, 2
194;
195OPENR, lun, filename, /get_lun
196array = ''
197line = ''
198;
199WHILE NOT EOF(lun) DO BEGIN
200   READF, lun, line
201   array = [array, line]
202ENDWHILE
203;
204FREE_LUN, lun
205RETURN, array[1:*]
206;
207END
208;
209;-----------------------------------------------------------------------
210;
211function SENSOR_TYPE, header
212;
213COMPILE_OPT hidden
214ON_ERROR, 2
215;
216fstw = WHERE(STRPOS(header, "sensor type") NE -1, count)
217IF (count NE 0) THEN BEGIN
218   fst = STRTRIM(header[fstw], 2)
219   fst1 = STRPOS(fst, '=')
220   stype   = (STRMID(fst, fst1 + 2))[0]
221   ;;
222ENDIF ELSE BEGIN
223   stype = "Unknown"
224ENDELSE
225;
226RETURN, stype
227END
228;
229;-----------------------------------------------------------------------
230;
231function WAVELENGTH_UNITS, header
232;
233COMPILE_OPT hidden
234ON_ERROR, 2
235;
236fwuw = WHERE(STRPOS(header, "wavelength units") NE -1, count)
237IF (count NE 0) THEN BEGIN
238   fwu = STRTRIM(header[fwuw], 2)
239   fwu1 = STRPOS(fwu, '=')
240   wvunits   = (STRMID(fwu, fwu1 + 2))[0]
241   ;;
242ENDIF ELSE BEGIN
243   wvunits = "Unknown"
244ENDELSE
245;
246RETURN, wvunits
247END
248;
249;-----------------------------------------------------------------------
250;
251function BAND_NAMES, header
252;
253COMPILE_OPT hidden
254ON_ERROR, 2
255;
256fbnw = WHERE(STRPOS(header, "band names") NE -1, count)
257IF (count NE 0) THEN BEGIN
258   fbn = STRTRIM(header[fbnw], 2)
259   fbn1 = STRPOS(fbn, '{')
260   ;;
261   eb_array = STRPOS(header[fbnw+1:*], '}')
262   names = ''
263   FOR i = 1, N_ELEMENTS(eb_array) DO BEGIN
264      names = names + header[fbnw+i]
265   ENDFOR
266   eb = STRPOS(names, '}')
267   names  = STRTRIM(STRMID(names, 0, eb), 2)
268   b_names = STRSPLIT(names, ',', /extract)
269   ;;
270ENDIF ELSE BEGIN
271   nb   = num_bands(header)
272   band = STRING(LONARR(nb))
273   number=STRING(LONARR(nb))
274   b_names=STRING(LONARR(nb))
275   ;;
276   ;;create the array with value 'Band' placed in each element
277   FOR i=0L, nb[0]-1 DO BEGIN
278      band[i]= 'Band '
279   ENDFOR
280   ;;
281   ;;create the array with values of 1 to the total number of files
282   FOR i=0L, nb[0]-1 DO BEGIN
283      number[i]= STRTRIM(i+1,1)
284   ENDFOR
285   ;;
286   ;;concatenate (join) the band and number arrays into one singular array
287   FOR i=0L, nb[0]-1 DO BEGIN
288      b_names[i]= band[i] + number[i]
289   ENDFOR
290ENDELSE
291;
292RETURN, b_names
293END
294;
295;-----------------------------------------------------------------------
296;
297function BYTE_ORDER, header
298;
299COMPILE_OPT hidden
300ON_ERROR, 2
301;
302fbow = WHERE(STRPOS(header, "byte order") NE -1, count)
303IF (count NE 0) THEN BEGIN
304   fbo = STRTRIM(header[fbow], 2)
305   fbo1 = STRPOS(fbo, '=')
306   byt_order   = (FIX(STRMID(fbo, fbo1 + 2)))[0]
307ENDIF ELSE BEGIN
308   MESSAGE, 'Byte order not found, assuming byte order of current machine.', /continue
309   byt_order = (BYTE(1,0,1))[0] ? 0 : 1
310ENDELSE
311;
312RETURN, byt_order
313;
314END
315;
316;-----------------------------------------------------------------------
317;
318function HEADER_OFFSET, header
319;
320COMPILE_OPT hidden
321ON_ERROR, 2
322;
323fhow = WHERE(STRPOS(header, "header offset") NE -1, count)
324IF (count NE 0) THEN BEGIN
325   fho = STRTRIM(header[fhow], 2)
326   fho1 = STRPOS(fho, '=')
327   offset = (LONG(STRMID(fho, fho1 + 2)))[0]
328ENDIF ELSE BEGIN
329   MESSAGE, 'No offset found, assuming zero.', /continue
330   offset = 0L
331ENDELSE
332;
333RETURN, offset
334;
335END
336;
337;-----------------------------------------------------------------------
338;
339function DESCRIPTION, header
340;
341COMPILE_OPT hidden
342ON_ERROR, 2
343;
344fdsw = WHERE(STRPOS(header, "description") NE -1, count)
345IF (count NE 0) THEN BEGIN
346   fds = STRTRIM(header[fdsw], 2)
347   fds1 = STRPOS(fds, '{')
348   ;;
349   ;; Using the same method as for band names. It seems to work fine.
350   eb_array = STRPOS(header[fdsw+1:*], '}')
351   desc = ''
352   FOR i = 1, N_ELEMENTS(eb_array) DO BEGIN
353      desc = desc + header[fdsw+i]
354   ENDFOR
355   eb = STRPOS(desc, '}')
356   descrip  = (STRTRIM(STRMID(desc, 0, eb), 2))[0]
357   ;;
358ENDIF ELSE BEGIN
359   descrip = 'None'
360ENDELSE
361;
362RETURN, descrip
363;
364END
365;
366;-----------------------------------------------------------------------
367;
368FUNCTION FILETYPE, header
369;
370COMPILE_OPT hidden
371ON_ERROR, 2
372;
373fftw = WHERE(STRPOS(header, "file type") NE -1, count)
374IF (count NE 0) THEN BEGIN
375   ff_t = STRTRIM(header[fftw], 2)
376   fft1 = STRPOS(ff_t, '=')
377   ftype = (STRMID(ff_t, fft1 + 2))[0]
378ENDIF ELSE BEGIN
379   MESSAGE, 'File type not found, assumed ENVI Standard.', /continue
380   ftype = 'ENVI Standard'
381ENDELSE
382;
383RETURN, ftype
384;
385END
386;
387;-----------------------------------------------------------------------
388;
389function F_COMPRESSION, header
390;
391COMPILE_OPT hidden
392ON_ERROR, 2
393;
394ffcw = WHERE(STRPOS(header, "file compression") NE -1, count)
395IF (count NE 0) THEN BEGIN
396   ffc  = STRTRIM(header[ffcw], 2)
397   ffc1 = STRPOS(ffc, '=')
398   fc   = STRMID(ffc, ffc1 + 2)
399   rfc   = FIX(fc[0])
400ENDIF ELSE BEGIN
401   rfc   = 0
402ENDELSE
403;
404RETURN, rfc
405;
406END
407;
408; -----------------------------------------------------
409; better managing finding the files (.IMG + .HDR or .IMG.HDR + .IMG)
410;
411function ENVI_SELECT_FILENAME, filename, hname, fname, test=test, debug=debug
412;
413suffixe=STRMID(filename, 3, /reverse_offset)
414files_found=0
415;
416; testing first case: HDR file as input.
417;
418IF (STRCMP(suffixe, '.hdr', /fold_case)) EQ 1 THEN BEGIN
419    ;; path
420    path=FILE_DIRNAME(filename, /mark_directory)
421    if path EQ './' then path=''
422    ;;
423    bodyname=FILE_BASENAME(filename, '.hdr')
424    fname=FILE_SEARCH(path+bodyname+'.img',/fold)
425    if (STRLEN(fname) EQ 0) then begin
426        mess='No IMG data file found corresponding to HDR header file : '
427        MESSAGE, mess+filename
428    endif
429    if (N_ELEMENTS(fname) GT 1) then begin
430        MESSAGE,/continue, 'More than one IMG data file found, first used !'
431        fname=fname[0]
432    endif
433    hname=filename
434    files_found=1
435endif
436;
437; testing first case: IMG file as input.
438;
439IF (STRCMP(suffixe, '.img', /fold_case)) EQ 1 THEN BEGIN
440    ;; path
441    path=FILE_DIRNAME(filename, /mark_directory)
442    if path EQ './' then path=''
443    ;;
444    bodyname=FILE_BASENAME(filename, '.img')
445    ;; we use '*.hdr' because we may have '.img.hdr' or '.hdr'
446    hname=FILE_SEARCH(path+bodyname+'*.hdr',/fold)
447    if (STRLEN(hname) EQ 0) then begin
448        mess='No HDR header file found corresponding to IMG data file : '
449        MESSAGE, mess+filename
450    endif
451    if (N_ELEMENTS(hname) GT 1) then begin
452        MESSAGE,/continue, 'More than one HDR header file found, first used !'
453        hname=hname[0]
454    endif
455    fname=filename
456    files_found=1
457endif
458;
459; if just the "file_basename" is provide, do we have the files ?
460;
461if (files_found EQ 0) then begin
462    ;; path
463    path=FILE_DIRNAME(filename, /mark_directory)
464    if path EQ './' then path=''
465    ;;
466    hname=FILE_SEARCH(filename+'*.hdr',/fold)
467    fname=FILE_SEARCH(filename+'*.img',/fold)
468    ;
469    if (N_ELEMENTS(hname) EQ 0) then $
470      MESSAGE, /cont, 'no HDR header file found with given basename pattern'
471    ;;
472    if (N_ELEMENTS(fname) EQ 0) then $
473      MESSAGE, /cont, 'no IMG data file found with given basename pattern'
474    ;;
475    if ((N_ELEMENTS(hname) EQ 1) AND (N_ELEMENTS(fname) EQ 1)) then begin
476        b1=FILE_BASENAME(hname,'.hdr',/fold)
477        b1bis=FILE_BASENAME(hname,'.img.hdr',/fold)
478        b2=FILE_BASENAME(fname,'.img',/fold)
479        if STRCMP(b1,b2,/fold_case) EQ 1 then files_found=1
480        if STRCMP(b1bis,b2,/fold_case) EQ 1 then files_found=1
481        if files_found EQ 0 then begin
482            MESSAGE, /cont, 'bad files names, please check the input filter'
483        endif
484    endif
485    ;;
486    txt='found, please check input filename'
487    if (N_ELEMENTS(hname) GT 1) then begin
488        MESSAGE, /cont, 'More than one HDR header file '+txt
489    endif
490    if (N_ELEMENTS(fname) GT 1) then begin
491        MESSAGE, /cont, 'More than one IMG data file '+txt
492    endif
493endif
494;
495; Are really the files around ? Are the files void ?
496;
497if (files_found EQ 1) then begin
498    count=0
499    if ~FILE_TEST(fname) then begin
500        count++
501        MESSAGE, /continue, 'IMG data file not found (no file/bad name ?)'
502    endif else begin
503        if FILE_TEST(fname,/zero_length) then begin
504            count++
505            MESSAGE, /continue, 'IMG data file does not contain data !'
506        endif
507    endelse
508    if ~FILE_TEST(hname) then begin
509        count++
510        MESSAGE, /continue, 'HDR header file not found (no file/bad name ?)'
511    endif else begin
512        if FILE_TEST(hname,/zero_length) then begin
513            count++
514            MESSAGE, /continue, 'HDR header file does not contain data !'
515        endif
516    endelse
517    if (count NE 0) then files_found=0
518endif
519;
520if (files_found GT 0) then begin
521    PRINT, 'IMG data filename   = ', fname
522    PRINT, 'HDR header filename = ', hname
523    PRINT, 'Directory name      = ', FILE_DIRNAME(hname, /mark_directory)
524endif
525;
526if KEYWORD_SET(test) then STOP
527;
528return, files_found
529;
530end
531;
532;-----------------------------------------------------------------------
533;
534pro READ_ENVI_FILE, filename, image=image, info=info, $
535                    help=help, test=test, debug=debug
536;
537if ~KEYWORD_SET(debug) then ON_ERROR, 2
538;
539if KEYWORD_SET(help) THEN BEGIN
540   PRINT, 'pro TEST_READ_ENVI, filename, image=image, info=info, $'
541   PRINT, '                    help=help, test=test, debug=debug'
542   PRINT, ''
543   PRINT, 'Reads an ENVI style image format. Set info to a variable'
544   PRINT, 'that will contain a structure containing the image'
545   PRINT, 'information such as samples, lines, bands, data type etc.'
546   PRINT, ''
547   PRINT, 'Warning : currently, suffixes can be only .IMG for data files and'
548   PRINT, '(.IMG.HRD or .HDR) for Header files [with any Up/Low case combi]'
549   return
550ENDIF
551;
552txt='FILENAME (.HDR, .IMG or basename)'
553;
554if N_PARAMS() EQ 0 then filename=DIALOG_PICKFILE(filter='*.hdr')
555if N_ELEMENTS(filename) GT 1 then $
556  MESSAGE, 'You can provide only one '+txt+' at once'
557;
558; from a given file name (w/o extension .hrd/.img + w/o path)
559; returning ONE and only one pair of Hname+Fname
560;
561files_found=ENVI_SELECT_FILENAME(filename, hname, fname, test=test)
562if ~files_found then MESSAGE, 'Please check carrefully the input '+txt
563;
564; after this point, we have one IMG file and one HDR file
565; (existances checked)
566;
567if KEYWORD_SET(debug) then STOP
568;
569hdr = READ_HEADER(hname)
570;
571;; Get the description info
572descript = DESCRIPTION(hdr)
573;
574;; Get samples, lines, bands, datatype, interleave
575ns = NUM_SAMPLES(hdr)
576nl = NUM_LINES(hdr)
577nb = NUM_BANDS(hdr)
578;
579dtype    = DATATYPE(hdr)
580intleave = INTERLEAVE(hdr)
581;
582CASE intleave OF
583   ;; BSQ Interleaving
584   0: BEGIN
585      CASE dtype OF
586         0: MESSAGE, 'Undefined Data Type.'
587         1: image = BYTARR(ns, nl, nb, /nozero)
588         2: image = INTARR(ns, nl, nb, /nozero)
589         3: image = LONARR(ns, nl, nb, /nozero)
590         4: image = FLTARR(ns, nl, nb, /nozero)
591         5: image = DBLARR(ns, nl, nb, /nozero)
592         6: image = COMPLEXARR(ns, nl, nb, /nozero)
593         7: image = STRARR(ns, nl, nb)
594         8: MESSAGE, 'Structured Arrays Not Supported.'
595         9: image = DCOMPLEXARR(ns, nl, nb, /nozero)
596         10: image = PTRARR(ns, nl, nb, /nozero)
597         11: image = OBJARR(ns, nl, nb, /nozero)
598         12: image = UINTARR(ns, nl, nb, /nozero)
599         13: image = ULONARR(ns, nl, nb, /nozero)
600         14: image = LON64ARR(ns, nl, nb, /nozero)
601         15: image = ULON64ARR(ns, nl, nb, /nozero)
602         ELSE: MESSAGE, 'Unknown Data Type.'
603      ENDCASE
604      BREAK
605   END
606                                ; BIL Interleaving
607   1: BEGIN
608      CASE dtype OF
609         0: MESSAGE, 'Undefined Data Type.'
610         1: image = BYTARR(ns, nb, nl, /nozero)
611         2: image = INTARR(ns, nb, nl, /nozero)
612         3: image = LONARR(ns, nb, nl, /nozero)
613         4: image = FLTARR(ns, nb, nl, /nozero)
614         5: image = DBLARR(ns, nb, nl, /nozero)
615         6: image = COMPLEXARR(ns, nb, nl, /nozero)
616         7: image = STRARR(ns, nb, nl)
617         8: MESSAGE, 'Structured Arrays Not Supported.'
618         9: image = DCOMPLEXARR(ns, nb, nl, /nozero)
619         10: image = PTRARR(ns, nb, nl, /nozero)
620         11: image = OBJARR(ns, nb, nl, /nozero)
621         12: image = UINTARR(ns, nb, nl, /nozero)
622         13: image = ULONARR(ns, nb, nl, /nozero)
623         14: image = LON64ARR(ns, nb, nl, /nozero)
624         15: image = ULON64ARR(ns, nb, nl, /nozero)
625         ELSE: MESSAGE, 'Unknown Data Type.'
626      ENDCASE
627      BREAK
628   END
629                                ; BIP Interleaving
630   2: BEGIN
631      CASE dtype OF
632         0: MESSAGE, 'Undefined Data Type.'
633         1: image = BYTARR(nb, ns, nl, /nozero)
634         2: image = INTARR(nb, ns, nl, /nozero)
635         3: image = LONARR(nb, ns, nl, /nozero)
636         4: image = FLTARR(nb, ns, nl, /nozero)
637         5: image = DBLARR(nb, ns, nl, /nozero)
638         6: image = COMPLEXARR(nb, ns, nl, /nozero)
639         7: image = STRARR(nb, ns, nl)
640         8: MESSAGE, 'Structured Arrays Not Supported.'
641         9: image = DCOMPLEXARR(nb, ns, nl, /nozero)
642         10: image = PTRARR(nb, ns, nl, /nozero)
643         11: image = OBJARR(nb, ns, nl, /nozero)
644         12: image = UINTARR(nb, ns, nl, /nozero)
645         13: image = ULONARR(nb, ns, nl, /nozero)
646         14: image = LON64ARR(nb, ns, nl, /nozero)
647         15: image = ULON64ARR(nb, ns, nl, /nozero)
648         ELSE: MESSAGE, 'Unknown Data Type.'
649      ENDCASE
650      BREAK
651   END
652   ELSE: MESSAGE, 'Unknown Interleave.'
653ENDCASE
654;
655;; byte order of file
656f_byte_order = BYTE_ORDER(hdr)
657;
658;; file type
659ftype = FILETYPE(hdr)
660;
661;; byte order of current machine
662m_byte_order = (BYTE(1,0,1))[0] ? 0 : 1
663;
664;; header offset
665h_offset = HEADER_OFFSET(hdr)
666;
667;; file compression
668compressed = F_COMPRESSION(hdr)
669;
670IF (f_byte_order NE m_byte_order) THEN BEGIN
671   IF compressed NE 0 THEN BEGIN
672      OPENR, lun, fname, /get_lun, /swap_endian, /compress
673   ENDIF ELSE BEGIN
674      OPENR, lun, fname, /get_lun, /swap_endian
675   ENDELSE
676   POINT_LUN, lun, h_offset
677   READU, lun, image
678   FREE_LUN, lun
679ENDIF ELSE BEGIN
680   ;; Open and read the image file
681   IF compressed NE 0 THEN BEGIN
682      OPENR, lun, fname, /get_lun, /compress
683   ENDIF ELSE BEGIN
684      OPENR, lun, fname, /get_lun
685   ENDELSE
686   POINT_LUN, lun, h_offset
687   READU, lun, image
688   FREE_LUN, lun
689ENDELSE
690;
691stype = SENSOR_TYPE(hdr)
692wl_units = WAVELENGTH_UNITS(hdr)
693bnames = BAND_NAMES(hdr)
694
695info = {Samples:ns, Lines:nl, Bands:nb, Data_Type:dtype,$
696        Interleave:intleave, Filename:fname, Sensor_Type:stype, $
697        Wavelength_Units:wl_units, Band_Names:bnames, $
698        Byte_Order:f_byte_order, Header_offset:h_offset, $
699        Description:descript, File_Type:ftype}
700;
701if KEYWORD_SET(test) then STOP
702;
703END
704