PRO rdkimg,file,headbytes,image,flag=flag,verbose=verbose,nofix=nofix ;+ ; NAME: ; RDKIMG ; ; PURPOSE: ; Read a KI-generated Polar Camera image file from disk and ; return the header bytes and image. ; ; CATEGORY: ; ; CALLING SEQUENCE: ; RDKIMG, FILENAME, HEADBYTES, IMAGE, FLAG=FLAG ; ; INPUTS: ; FILENAME: An unambiguous pathname to the image file. ; ; KEYWORD PARAMETERS: ; FLAG: An optional keyword which returns 0 if the header ; bytes and image are read successfully, and a 1 ; otherwise. ; /VERBOSE: If set, the procedure announces exception conditions ; and/or nonstandard actions taken. Default is silent ; operation. ; /NOFIX: If set, prevents an attempt to diagnose and correct ; a possible image problem that occurred in December ; 1994. See notes below for a description of the ; problem. Default is to attempt to correct the ; problem. ; ; OUTPUTS: ; HEADBYTES: A 512-byte array containing the header bytes ; from the image. Function GETHD converts this ; array to a header structure. If an I/O error ; occurs while reading the file, or the file to ; be read is shorter than 512 bytes, or the file ; contains an odd number of bytes, the scalar ; value -1 is returned. ; IMAGE: An square integer array containing the image. The ; dimensions of the array depend on the on-chip ; binning factors in effect at the time of image ; acquisition. If the routine is run on a Unix host, ; bytes are swapped in each array element to account ; for the endian differences between DOS and Unix. ; If any of the error conditions mentioned above ; occurs, or the number of bytes read from the file ; is less than the number specified in the header, ; the scalar value -1 is returned. ; ; COMMON BLOCKS: ; None. ; ; SIDE EFFECTS: ; None. ; ; RESTRICTIONS: ; The file must exist. If it exists but has been compressed ; on the Unix side with /usr/local/bin/gzip, the routine ; creates a temporary unzipped copy of the file and operates ; on the copy, deleting it before returning. ; ; PROCEDURE: ; The OS is first checked, to determine whether byte-swapping ; will be required. Then if the file name indicates that ; the file has been 'gzipped', a temporary copy of the unzipped ; file is created. The actual reading of the file is ; straightforward. Byte-swapping occurs immediately after ; reading, if needed. If the header is present, it is decoded ; to determine the dimensions of the image array. If the ; image is all there, it is cast to an INTEGER array of the ; correct size. ; ; SEE ALSO: ; GETHD.PRO, FIXBIN.PRO ; ; MODIFICATION HISTORY: ; Written Jul/Aug 1992 by D P Steele. ; Modified 93/07/07 by DPS: ; If the file name passed ends in '.z' or '.gz', the ; routine spawns a process to 'gunzip' the file to ; a temporary copy, reads the copy in, and spawns ; another process to remove the copy. This requires ; that the user be 'cnsr3', as all images now belong ; to that user. ; Modified 94/05/26 by DPS: ; Added keyword FLAG. ; Modified 95/01/17 by DPS: ; If image size disagrees with header parameters but ; is compatible with legitimate header values, header ; is corrected and likely image flaws are remedied ; as best they can be. Specifically, starting on ; 941129, software binning to 4x4 was implemented, ; incorrectly at first, with the result that a ; 4x4-binned image was overwritten over the first ; 25% of the raw 2x2 image. The 4x4 portion is used ; to reconstitute the top 25% of the 2x2-binned image, ; and the header parameters are adjusted to reflect ; the reconstituted image. ; ;- ON_IOERROR,bad_file @isitdos flag=0B zip=(STRPOS(file,'z') EQ STRLEN(file)-1) OR $ (STRPOS(file,'gz') EQ STRLEN(file)-2) IF zip THEN BEGIN command=gzipcmd+'-d -v -c '+file+rd+'tmp' SPAWN,command sfile='tmp' ENDIF ELSE sfile=STRTRIM(file,2) OPENR,unit,sfile,/GET_LUN filestat=FSTAT(unit) IF filestat.SIZE EQ 0 THEN BEGIN CLOSE,unit & FREE_LUN,unit MESSAGE,'No bytes found in file '+file+'; aborting',/INFORMATIONAL headbytes=-1 image=-1 flag=1B RETURN ENDIF in=BYTARR(filestat.SIZE) READU,unit,in CLOSE,unit & FREE_LUN,unit IF zip GT 0 THEN SPAWN,rmcmd+'tmp' IF filestat.SIZE LT 512 THEN BEGIN MESSAGE,'Header incomplete in file '+file+'; aborting',/INFORMATIONAL headbytes=-1 image=-1 flag=1B RETURN ENDIF ; If an odd number of bytes was read, something is wrong IF filestat.SIZE MOD 2 NE 0 THEN BEGIN MESSAGE,file+' contains an odd number of bytes; aborting',/INFORMATIONAL headbytes=-1 image=-1 flag=1B RETURN ENDIF ; Reverse byte order to put image integers in big-endian order for Unix; ; this messes up the header, though. IF NOT dos THEN BYTEORDER,in headbytes=BYTE(in,0,512) ; extract header bytes ; Now put the header right, if it was reversed above. IF NOT dos THEN BYTEORDER,headbytes KIh=gethd(headbytes) ; decode header cols=KIh.exp.cols/KIh.exp.sbin ; actual # of columns in image rows=KIh.exp.rows/KIh.exp.pbin ; actual # of rows in image CASE filestat.SIZE OF 512L+2L*cols*rows: BEGIN ; nominal file size found image=FIX(in,512,cols,rows) ; extract image bytes END 512L+4*2L*cols*rows: BEGIN ; image 4x expected size image=FIX(in,512,2*cols,2*rows) fixbin,headbytes,image,/top4th,verbose=verbose IF KEYWORD_SET(verbose) THEN $ MESSAGE,'Image larger than expected in ' $ +file+' - header corrected' $ ,/INFORMATIONAL END ELSE: BEGIN MESSAGE,'Wrong number of bytes read from '+file,/INFORMATIONAL image=-1 flag=1B RETURN END ENDCASE ; Special case - December 1994 images binned 4x4 were sometimes ; messed up in a way FIXBIN.PRO can correct (I hope)! IF NOT KEYWORD_SET(nofix) THEN BEGIN IF (KIh.misc.dt.year EQ 1994) AND (KIH.misc.dt.month EQ 12) THEN BEGIN KIh=gethd(headbytes) ; make sure image parameters are up to date IF (KIH.exp.sbin EQ 4) AND (KIH.exp.pbin EQ 4) THEN $ fixbin,headbytes,image,verbose=verbose ENDIF ENDIF RETURN bad_file: MESSAGE,'I/O error reading '+file,/INFORMATIONAL headbytes=-1 image=-1 flag=1B RETURN END