	PRO DECOMP_SCIENCE, RASTER, SCIENCE, VALID, DATA
;+
; Project     : SOHO - CDS
;
; Name        : DECOMP_SCIENCE
;
; Purpose     : Decompress science telemetry data.
;
; Explanation : This routine decides which telemetry compression scheme is
;		being used, and calls the appropriate procedure to perform the
;		decompression.
;
; Use         : DECOMP_SCIENCE, RASTER, SCIENCE, VALID, DATA
;
; Inputs      : RASTER	= Raster structure from FORM_RASTER.
;		SCIENCE	= Byte array containing the science telemetry stream
;			  for an entire exposure.  Note that SCIENCE could
;			  decompress to more data points than are consistent
;			  with the data windows definitions (RASTER.N_DATA)
;			  because of filling of telemetry stream, or fewer
;			  points because of missing packets or incomplete
;			  exposures.
;		VALID	= Byte array containing validity data for the bytes in
;			  the SCIENCE array.  The values of VALID must be
;			  either all bits set ('FF'XB) for valid data bytes, or
;			  all bits not set ('00'XB) for missing data bytes.
;			  VALID must have the same number of elements as
;			  SCIENCE.
;
; Opt. Inputs : None.
;
; Outputs     : DATA	= Short or long integer array of RASTER.N_DATA points
;			  containing the decompressed science data.  Values
;			  which cannot be recovered from the telemetry stream
;			  will be set to -1.
;
; Opt. Outputs: None.
;
; Keywords    : None.
;
; Calls       : IEEE_TO_HOST, VDS_UNPACK, VBWL_UNPACK, SUMWIN_UNPACK
;
; Common      : None.
;
; Restrictions: Only RASTER.N_DATA points will be returned, even if the science
;		telemetry stream could in theory decompress to more data
;		points.  The rest of the SCIENCE array is considered to be
;		fill.
;
; Side effects: None.
;
; Category    : Data Handling, Telemetry.
;
; Prev. Hist. : None.
;
; Written     : William Thompson, GSFC, 24 March 1993.
;
; Modified    : Version 1, William Thompson, GSFC, 16 April 1993.
;		Version 2, William Thompson, GSFC, 16 November 1993.
;			Changed meaning of compression mode 1, to match actual
;			use in telemetry.
;		Version 3, William Thompson, GSFC, 26 August 1994.
;			Properly implemented compression modes TRUNK, VBWL,
;			SUMLINE, and SUMWIN.  Made COPY the default.
;		Version 4, William Thompson, GSFC, 30 August 1994
;			Take unsigned integers into account for COPY and VBWL
;			methods.
;		Version 5, William Thompson, GSFC, 17 November 1995
;			Made VBWL decompression more robust.
;		Version 6, William Thompson, GSFC, 4 March 1996
;			Corrected problem with SUMLINE compression
;		Version 7, William Thompson, GSFC, 12 March 1996
;			Further corrected problem with SUMLINE compression
;		Version 8, William Thompson, GSFC, 13 March 1996
;			Corrected bug with SUMWIN compression.
;		Version 9, William Thompson, GSFC, 20 October 1997
;			Recognize compression mode 8 as valid.  Treat like
;			compression mode 1.
;               Version 10, William Thompson, GSFC, 14 July 2003
;                       Make sure FFFFFFFF is treated as long, not ulong
;
; Version     : Version 9, 20 October 1997
;-
;
	ON_ERROR, 2
;
;  Test the number of parameters.
;
	IF N_PARAMS() NE 4 THEN MESSAGE,	$
		'Syntax:  DECOMP_SCIENCE, RASTER, SCIENCE, VALID, DATA'
;
;  Make sure that SCIENCE and VALID are both byte arrays, and have the same
;  number of elements.
;
	SZ = SIZE(SCIENCE)
	IF SZ(SZ(0)+1) NE 1 THEN MESSAGE,'SCIENCE must be of type byte'
	SZ = SIZE(VALID)
	IF SZ(SZ(0)+1) NE 1 THEN MESSAGE,'VALID must be of type byte'
	IF N_ELEMENTS(SCIENCE) NE N_ELEMENTS(VALID) THEN MESSAGE,	$
		'SCIENCE and VALID must have the same number of elements'
;
;  Extract the needed information from the raster header.
;
	COMPRESSION = RASTER.HEADER.SCI.COMPRESSION
	N_DATA = RASTER.N_DATA
;
;  Call the appropriate decompression routine.
;
	CASE COMPRESSION OF
;
;  VDS packed 12-bit integers.  Unless all 12 bits can be unpacked, set the
;  data values to -1.
;
		2:  BEGIN
			VDS_UNPACK, SCIENCE, TEMP
			VDS_UNPACK, VALID, VAL
			W = WHERE(VAL NE 'FFF'X, N_FOUND)
			IF N_FOUND GT 0 THEN TEMP(W) = -1
			NN = N_ELEMENTS(TEMP) < N_DATA
			DATA = REPLICATE(-1,N_DATA)
			DATA(0) = TEMP(0:NN-1)
			END
;
;  Variable block word length (VBWL) compression.  This decompression can not
;  be applied past any missing packets.
;
		3:  BEGIN
			W = WHERE(VALID NE 'FF'X, N_FOUND)
			IF N_FOUND GT 0 THEN SCI = SCIENCE(0:W(0)-1) ELSE $
				SCI = SCIENCE
			N_WINDOWS = RASTER.HEADER.NWINDOWS
			VBWL_UNPACK, SCI, TEMP, RASTER.N_DATA,		$
				RASTER.INSTRUMENT EQ 'GIS',		$
				RASTER.HEADER.SCI.COMP_OPTION,		$
				RASTER.SP_STATUS.VDS_ORIENT,		$
				RASTER.HEADER.DATA_WIN(0:N_WINDOWS-1),	$
				GOOD
			NN = N_ELEMENTS(TEMP) < N_DATA
			DATA = REPLICATE(-1L,N_DATA)
			DATA(0) = UNSIGN(TEMP(0:NN-1))
			W = WHERE(GOOD(0:NN-1) EQ 0, COUNT)
			IF COUNT GT 0 THEN DATA(W) = -1
			END
;
;  SUMLINE compression.  All the points along the first dimension in each
;  window (either row or column, depending on the VDS readout orientation) are
;  summed together into a single 32 bit integer.  *Note*, no provision is made
;  for unsigned integers.
;
		6:  BEGIN
			TEMP = FIX(SCIENCE,0,2,N_ELEMENTS(SCIENCE)/4)
			TEMP1 = TEMP
			TEMP(0,*) = TEMP1(1,*)		;Word ordering
			TEMP(1,*) = TEMP1(0,*)
			TEMP = LONG(TEMP,0,N_ELEMENTS(SCIENCE)/4)
			IEEE_TO_HOST, TEMP		;Byte ordering
			VAL  = LONG(VALID,0,N_ELEMENTS(VALID)/4)
			W = WHERE(VAL NE 'FFFFFFFF'XL, N_FOUND)
			IF N_FOUND GT 0 THEN TEMP(W) = -1
			NN = N_ELEMENTS(TEMP) < N_DATA
			DATA = REPLICATE(-1L,N_DATA)
			DATA(0) = TEMP(0:NN-1)
			END
;
;  SUMWIN compression.  All the points in each window are summed together into
;  a single 64 bit integer.  This is converted into a double precision floating
;  point number for compatibility with IDL and FITS, resulting in a small loss
;  in precision, but no loss in dynamic range.
;
		7:  BEGIN
			SUMWIN_UNPACK, SCIENCE, TEMP
			SUMWIN_UNPACK, VALID, VAL
			SUMWIN_UNPACK, REPLICATE(255B,8), TEST
			W = WHERE(VAL NE TEST, N_FOUND)
			IF N_FOUND GT 0 THEN TEMP(W) = -1.D0
			NN = N_ELEMENTS(TEMP) < N_DATA
			DATA = REPLICATE(-1.D0,N_DATA)
			DATA(0) = TEMP(0:NN-1)
			END
;
;  No compression.  Return as long array because all 16 bits may be used as an
;  unsigned integer.  This is the default, but an error message is printed if
;  the compression option is anything but 1 or 8 (although it isn't *really* an
;  error for compression modes 4 and 5).
;
		ELSE:  BEGIN
			IF (COMPRESSION NE 1) AND (COMPRESSION NE 8) THEN $
				CDS_MESSAGE, /CONTINUE, $
				'Unrecognized compression method: ' +	$
				STRTRIM(FIX(COMPRESSION),2), /ATTENTION
;
			NN = (N_ELEMENTS(SCIENCE)/2) < N_DATA
			DATA = REPLICATE(-1L,N_DATA)
			IF NN GT 0 THEN BEGIN
				TEMP = FIX(SCIENCE,0,NN)
				IEEE_TO_HOST, TEMP		;Byteordering
				DATA(0) = UNSIGN(TEMP)
				VAL = FIX(VALID,0,NN)
				W = WHERE(VAL NE FIX('FFFF'X), N_FOUND)
				IF N_FOUND GT 0 THEN DATA(W) = -1
			ENDIF
			END
	ENDCASE
;
	RETURN
	END
