FUNCTION gethd,headbytes,length=length,debug=debug ; ; DPS, CNSR, July 1992 ; ; Modified, DPS, November 1992 and January 1993, to handle revised KI ; header format. ; Modified by DPS, July 1994, to handle bytes added to image headers ; in processing. ; Modified by DPS, September 27, 1995, to rationalize handling of INTs ; and LONGs that are stored differently on Big-endian and little-endian ; machines, viz., Unix and DOS. ; Modified by DPS, November 24, 1995, to handle differences in !VERSION ; between v. 3.1.2 and 4.0.1a of IDL for Windows. ; ; This function accepts a 512-byte header from an image acquired ; by PoCa under KI, and returns a structure containing the header ; information. The structure field names parallel those used in KI ; as closely as possible. ; ; KI version 1.0 ; nb=N_ELEMENTS(headbytes) IF nb LT 512 THEN BEGIN MESSAGE,'Header too short - '+STRTRIM(nb,2)+' bytes',/INFORMATIONAL RETURN,-1 ENDIF ; ; Start by defining needed structures. ; ti={ t_struct, last:0, min:0, max:0, mean:0, num:0 } dosdate={ dosdate_t, day:0B, month:0B, year:0, dayofweek:0B } dostime={ dostime_t, hour:0B, minute:0B, second:0B, csecond:0B } te={ temp_t, tei:ti, tee:ti, td:ti, tcc:ti, tcf:ti, tfw:ti } ccdd={ ccd_descript, cols:0, rows:0, prescan:0, postscan:0, $ parallel_delay:0, parallel_states:0, $ frame_transfer:0, mpp_expose:0, mpp_clock:0, $ high_hwell:0, id:'CCD_designation#' } cm={ cam_misc, cam:0B, fw:0B, id:0B, port:0B, temp:te, heater:0, fan:0, $ acpower:0, plus5:0, plus15:0, minus15:0, preamp:0, $ exp_scale:0, sequence:0, ems_handle:0, imgsize:0L, $ version:0, dt:dosdate, tm:dostime, exposure_type:0B, $ pixel_max:0, pixel_min:0, opmode:0, lens:'', $ filter:'', loc:'', az:'', oper:'', jpegq:'', compfact:'', $ os_vers:'' } cs={ cam_sys, ccd:ccdd, at200_id:0, frame:0, open_delay:0, $ close_delay:0, preamp_delay:0, speed:0, data_bits:0 } ce={ cam_exp, ram:0L, exposure:0L, gain:0, mpp_mode:0, corg:0, rorg:0, $ cols:0, rows:0, sbin:0, pbin:0, clr_cnt:0, row_shift:0 } ; The following structure is needed to describe image processing ; applied to the raw images acquired by the Polar Camera. It has ; no counterpart in the header generated by KI. See the file ; ~cnsr3/bkgrd/header.mods for more information. pd={ proc_data, scale_factor:0B, base2:0B, bkgd_camera:0B $ , bkgd_filter:0B, bkgd_hstart:0B, bkgd_mstart:0B $ , bkgd_sstart:0B, bkgd_mlength:0B, bkgd_source:0B } KIh={ KI_header, misc:cm, sys:cs, exp:ce, proc:pd } ; Fill structures from headbytes array. ; NOTE: byte reversal done in rdkimg.pro is appropriate for INTEGER- ; type variables, but not for BYTE- or LONGWORD-type variables. Make a ; copy of headbytes and unreverse it for the latter cases. ; ; NOTE: As of September 27, 1995, header byte reversal is no longer done in ; rdkimg.pro. Changes have been made to this routine to accomodate. urhb=headbytes ; This is the BYTE array we work with. ptr=0 ; Pointer to current position in URHB. ; Some circumstances will still cause this routine to get a byte-swapped ; header byte array. The code below tests for and corrects byte-swapping. swap=0B IF STRING(urhb(242:249)) NE 'TH 7895B' THEN BEGIN IF KEYWORD_SET(debug) THEN PRINT,STRING(urhb(242:249)) BYTEORDER,urhb swap=1B IF KEYWORD_SET(debug) THEN PRINT,STRING(urhb(242:249)) ENDIF ; With the introduction of IDL v. 4.0 the contents of the !VERSION system ; variable has changed. The following test is intended to be general enough ; to distinguish between Windows-family versions and Unix versions. Note ; that the test has no idea about VAX/VMS. windows=(STRMID(STRLOWCASE(!VERSION.OS),0,3) EQ 'win') ; ; First fill 'misc' structure. ; nfields=N_TAGS(KIh.misc) ftype=[0,0,0,0,1,2,2,2,2,2,2,2,2,2,2,3,2,4,5,0,2,2,2,6,6,7,8,9,9,9,9] FOR i=0,nfields-1 DO BEGIN CASE ftype(i) OF 0: BEGIN ; BYTE-valued field KIh.misc.(i)=BYTE(urhb,ptr) ptr=ptr+1 END 1: BEGIN ; temperature structure ntemps=N_TAGS(KIh.misc.(i)) FOR j=0,ntemps-1 DO BEGIN ndata=N_TAGS(KIh.misc.(i).(j)) FOR k=0,ndata-1 DO BEGIN tmp2=FIX(urhb,ptr) ptr=ptr+2 IF NOT windows THEN BYTEORDER,tmp2 KIh.misc.(i).(j).(k)=tmp2 ENDFOR ENDFOR END 2: BEGIN ; INTEGER-valued field IF ptr MOD 2 EQ 1 THEN ptr=ptr+1 ; even pointer for INTEGER tmp2=FIX(urhb,ptr) ptr=ptr+2 IF NOT windows THEN BYTEORDER,tmp2 KIh.misc.(i)=tmp2 END 3: BEGIN ; LONGWORD-valued field tmp4=LONG(urhb,ptr) ptr=ptr+4 IF KEYWORD_SET(debug) THEN BEGIN PRINT,"Before LSWAP:" PRINT,tmp4 ENDIF IF NOT windows THEN BYTEORDER,tmp4,/LSWAP KIh.misc.(i)=tmp4 IF KEYWORD_SET(debug) THEN BEGIN PRINT,"After LSWAP:" PRINT,tmp4 HELP,KIh.misc.(i) ENDIF END 4: BEGIN ; DOS date structure KIh.misc.dt.day=BYTE(urhb,ptr) & ptr=ptr+1 KIh.misc.dt.month=BYTE(urhb,ptr) & ptr=ptr+1 tmp2=FIX(urhb,ptr) & ptr=ptr+2 IF NOT windows THEN BYTEORDER,tmp2 KIh.misc.dt.year=tmp2 KIh.misc.dt.dayofweek=BYTE(urhb,ptr) & ptr=ptr+2 END 5: BEGIN ; DOS time structure FOR j=0,3 DO BEGIN KIh.misc.(i).(j)=BYTE(urhb,ptr) & ptr=ptr+1 ENDFOR END 6: BEGIN ; BYTARR(6)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,6)) & ptr=ptr+6 END 7: BEGIN ; BYTARR(81)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,81)) & ptr=ptr+81 END 8: BEGIN ; BYTARR(11)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,11)) & ptr=ptr+11 END 9: BEGIN ; BYTARR(4)-valued field KIh.misc.(i)=STRING(BYTE(urhb,ptr,4)) & ptr=ptr+4 END ENDCASE ENDFOR ; Next fill 'sys' structure. This one is messy, and can't be dealt ; with as "elegantly" as the 'misc' structure. nccdparms=N_TAGS(KIh.sys.ccd) FOR i=0,nccdparms-6 DO BEGIN ; these are ordinary short integers tmp2=FIX(urhb,ptr) & ptr=ptr+2 IF NOT windows THEN BYTEORDER,tmp2 KIh.sys.ccd.(i)=tmp2 ENDFOR mask=1 FOR i=nccdparms-5,nccdparms-2 DO BEGIN ; single-bit flags KIh.sys.ccd.(i)=(mask AND BYTE(urhb,ptr))/mask mask=2*mask ENDFOR ptr=ptr+2 KIh.sys.ccd.id=STRING(BYTE(urhb,ptr,16)) & ptr=ptr+16 ; Finished with 'sys.ccd', so go on to the rest of 'sys'. syslong=LONG(urhb,ptr) & ptr=ptr+4 IF KEYWORD_SET(debug) THEN BEGIN PRINT,'Before LSWAP:' HELP,syslong ENDIF ; mirror-reverse all four bytes IF NOT windows THEN BYTEORDER,syslong,/LSWAP IF KEYWORD_SET(debug) THEN BEGIN PRINT,'After LSWAP:' HELP,syslong ENDIF fwidth=[0,5,1,5,5,7,3,5] ; define bit widths of fields FOR i=1,N_TAGS(KIh.sys)-1 DO BEGIN ; skip the 'ccd' structure field mask=2^fwidth(i)-1 ; define mask for i'th field KIh.sys.(i)=syslong AND mask ; mask appropriate bits syslong=ISHFT(syslong,-fwidth(i)) ; remove bits once read ENDFOR ; That should do it for 'sys'; now do 'exp'. tmp4=LONG(urhb,ptr) & ptr=ptr+4 IF NOT windows THEN BYTEORDER,tmp4,/LSWAP KIh.exp.ram=tmp4 exptime=LONG(urhb,ptr) & ptr=ptr+4 IF KEYWORD_SET(debug) THEN BEGIN PRINT,'Before LSWAP:' HELP,exptime ENDIF IF NOT windows THEN BYTEORDER,exptime,/LSWAP IF KEYWORD_SET(debug) THEN BEGIN PRINT,'After LSWAP:' HELP,exptime ENDIF KIh.exp.exposure=exptime FOR i=2,N_TAGS(KIh.exp)-1 DO BEGIN tmp2=FIX(urhb,ptr) & ptr=ptr+2 IF NOT windows THEN BYTEORDER,tmp2 KIh.exp.(i)=tmp2 ENDFOR ; Finally, read the bytes describing any processing done on the image. procbytes=BYTE(urhb,290,10) ptr=ptr+9 procptr=0 IF swap THEN BYTEORDER,procbytes FOR i=0,N_TAGS(KIh.proc)-1 DO BEGIN KIh.proc.(i)=BYTE(procbytes,procptr) & procptr=procptr+1 ENDFOR ; Th-th-th-that's all, folks! IF KEYWORD_SET(length) THEN PRINT,'First unused byte is ',ptr RETURN,KIh END