;+
; Project     :	SOHO - CDS
;
; Name        :	VBWL_UNPACK
;
; Purpose     :	Unpack VBWL compressed telemetry data
;
; Explanation :	This routine decompresses telemetry data that was compressed
;		with the Variable Block Word Length (VBWL) algorithm.
;
; Use         :	VBWL_UNPACK, INPUT, OUTPUT, SIZE, DETECTOR, OPTION,	$
;			ORIENTATION, DATA_WIN, GOOD
;
; Inputs      :	INPUT	    = Byte or short integer array of telemetry data.
;		SIZE	    = Number of data points that should be retrieved.
;			      The routine may not successfully retrieve as many
;			      as this.
;		DETECTOR    = Either 0 for NIS or 1 for GIS.
;		OPTION	    = The compression option.
;		ORIENTATION = Either 0 for by row or 1 for by column.
;		DATA_WIN    = The data extraction window list, either as a
;			      structure or as an array.
;
; Opt. Inputs :	None.
;
; Outputs     :	OUTPUT	= Output array.  Depending on whether there are missing
;			  packets, this may be smaller than the SIZE parameter
;			  would suggest.
;		GOOD	= Will be set to 1 for pixels successfully retrieved.
;			  Otherwise, will be set to zero.
;
; Opt. Outputs:	None.
;
; Keywords    :	None.
;
; Calls       :	EXTVBWLBLOCK
;
; Common      :	None.
;
; Restrictions:	None.
;
; Side effects:	None.
;
; Category    :	Data handling, Telemetry.
;
; Prev. Hist. : Parts are taken out of DCMPDATA by Martin Carter.  However,
;		this is only temporary until a C interface can be written.
;
; Written     :	William Thompson, GSFC, 19 August 1994
;
; Modified    :	Version 1, William Thompson, GSFC, 1 September 1994
;		Version 2, William Thompson, GSFC, 2 November 1995
;			Modified EXTBITS to return -1 if trying to access bytes
;			beyond the end of the data.
;		Version 3, William Thompson, GSFC, 17 November 1995
;			Added output array GOOD.
;		Version 4, William Thompson, GSFC, 3 February 1996
;			Fixed bug when used with GIS data from FITSGEN.
;		Version 5, William Thompson, GSFC, 24 May 1999
;			Accommodated IDL/v5.2 hex constants change
;
; Version     : Version 5, 24 May 1999
;-
;
	PRO VBWL_UNPACK, INPUT, OUTPUT, SIZE, DETECTOR, OPTION, ORIENTATION, $
		DATA_WIN, GOOD
;
	ON_ERROR, 2
;
;  This common block should be temporary, until a C interface can be made to
;  work.
;
	COMMON DECOMPBLOCK, BITS
;
;  Initialize the BITS array.
;
	BITS = ['0000'XL, '0001'XL, '0003'XL, '0007'XL, '000F'XL, $
		'001F'XL, '003F'XL, '007F'XL, '00FF'XL, $
		'01FF'XL, '03FF'XL, '07FF'XL, '0FFF'XL, $
		'1FFF'XL, '3FFF'XL, '7FFF'XL, 'FFFF'XL]
;
;  Check the number of parameters.
;
	IF N_PARAMS() NE 8 THEN MESSAGE, 'Syntax:  VBWL_UNPACK,INPUT,' + $
		'OUTPUT,SIZE,DETECTOR,OPTION,ORIENTATION,DATA_WIN,GOOD'
;
;  Redefine INPUT to be a short integer array, rather than a byte array.
;
	INP = FIX(INPUT,0,N_ELEMENTS(INPUT)/2)
	HOST_TO_IEEE, INP
;
;  Define some local variables.
;
	WORDPOS = 0L
	BITPOS = 0
	PIXELPOS = 0L
	OUTPUT = INTARR(SIZE)
	GOOD = INTARR(SIZE)
;
;  Find the number of windows, and the widths of each window in the exposure.
;
	IF DATATYPE(DATA_WIN,1) EQ 'Structure' THEN BEGIN
	    N_WINDOWS = N_ELEMENTS(DATA_WIN)
	    IF DETECTOR EQ 1 THEN BEGIN		;GIS
		XWIDTH = DATA_WIN.LENGTH
		YWIDTH = 1
	    END ELSE BEGIN
		XWIDTH = DATA_WIN.LENGTHX	;NIS
		YWIDTH = DATA_WIN.LENGTHY
	    ENDELSE
	END ELSE BEGIN
	    SZ = SIZE(DATA_WIN)
	    N_WINDOWS = SZ(2)
	    IF DETECTOR EQ 1 THEN BEGIN		;GIS
		XWIDTH = DATA_WIN(1,*)
		YWIDTH = REPLICATE(1,N_WINDOWS)
	    END ELSE BEGIN			;NIS
		XWIDTH = DATA_WIN(2,*)
		YWIDTH = DATA_WIN(3,*)
	    ENDELSE
	ENDELSE
;
;  Loop over the windows in the exposure.
;
	FOR WINDOW = 0, N_WINDOWS-1 DO BEGIN
;
;  Set up the blocksize.  If OPTION is 0, then the default blocksize for the
;  detector is used.
;
	    OPT = OPTION AND '7'X
	    IF OPT EQ 0 THEN BEGIN
		IF DETECTOR EQ 1 THEN BEGIN	;GIS
		    BLOCKSIZE = 16
		END ELSE BEGIN			;NIS
		    IF ORIENTATION EQ 0 THEN BEGIN
			BLOCKSIZE = XWIDTH(WINDOW) ;Spectral
		    END ELSE BEGIN
			BLOCKSIZE = YWIDTH(WINDOW) ;Spatial
		    ENDELSE
		ENDELSE
;
;  Otherwise, the option gives the blocksize.
;
	    END ELSE CASE OPT OF
		1: BLOCKSIZE = 8L
		2: BLOCKSIZE = 16L
		3: BLOCKSIZE = 32L
		4: BLOCKSIZE = 64L
		5: BLOCKSIZE = 126L	;Yes, not 128
		6: BLOCKSIZE = 256L
		7: BLOCKSIZE = 512L
	    ENDCASE
;
;  Loop over the blocks in the window.
;
	    AREA = LONG(XWIDTH(WINDOW))*YWIDTH(WINDOW)
	    FOR BLOCKS = 0, (AREA/BLOCKSIZE)-1 DO BEGIN
;
;  Decompress the pixels in the block.
;
		OUTPUT(PIXELPOS:PIXELPOS+BLOCKSIZE-1) =	$
			EXTVBWLBLOCK(BLOCKSIZE,INP,WORDPOS,BITPOS,GOODDATA)
		GOOD(PIXELPOS:PIXELPOS+BLOCKSIZE-1) = GOODDATA
		PIXELPOS = PIXELPOS + BLOCKSIZE
	    ENDFOR
;
;  Decompress the remaining pixels in the window.
;
	    REMAINDER = AREA MOD BLOCKSIZE
	    IF REMAINDER GT 0 THEN BEGIN
		OUTPUT(PIXELPOS:PIXELPOS+REMAINDER-1) =	$
		    EXTVBWLBLOCK(REMAINDER,INP,WORDPOS,BITPOS,GOODDATA)
		GOOD(PIXELPOS:PIXELPOS+REMAINDER-1) = GOODDATA
		PIXELPOS = PIXELPOS + LONG(REMAINDER)
	    ENDIF
	ENDFOR
;
	RETURN
	END
