!----------------------------------------------------------------- !--------------- special set of characters for RCS information !----------------------------------------------------------------- ! $Source$ $Revision$ $Date$ !----------------------------------------------------------------- SUBROUTINE GET_COMPHEADER(KTAB,SIZEKTAB,KNBELT,KTYPECOD) INTEGER, INTENT(IN) :: SIZEKTAB INTEGER(KIND=8), DIMENSION(SIZEKTAB), INTENT(IN) :: KTAB INTEGER, INTENT(OUT) :: KNBELT ! size of decompressed array INTEGER, INTENT(OUT) :: KTYPECOD ! code for compression type CHARACTER(LEN=8) :: STRKEY INTEGER :: INTCHAR INTEGER :: JI CALL SET_EXTRACTIDX(0,0) ! extract string header DO JI=1,8 CALL EXTRACT_BBUFF(KTAB,8,INTCHAR) STRKEY(JI:JI) = CHAR(INTCHAR) END DO ! Treat array if it is compressed IF (STRKEY == 'COMPRESS') THEN CALL EXTRACT_BBUFF(KTAB,32,KTYPECOD) CALL EXTRACT_BBUFF(KTAB,32,KNBELT) ELSE KNBELT =-1 KTYPECOD = 0 END IF END SUBROUTINE GET_COMPHEADER SUBROUTINE DECOMPRESS_FIELD(XTAB,NBELT,COMPTAB,NBCOMPELT,CODINGTYPE) USE MODD_COMPPAR USE MODE_SEARCHGRP IMPLICIT NONE INTEGER, INTENT(IN) :: NBELT INTEGER, INTENT(IN) :: NBCOMPELT REAL (KIND=8),DIMENSION(NBELT),TARGET,INTENT(OUT) :: XTAB INTEGER(KIND=8),DIMENSION(NBCOMPELT), INTENT(IN) :: COMPTAB INTEGER, INTENT(IN) :: CODINGTYPE INTEGER,DIMENSION(:), ALLOCATABLE :: ITAB LOGICAL,DIMENSION(:), ALLOCATABLE :: GMASK REAL :: XREF, XCOEFF INTEGER :: INBLEV INTEGER :: ILEVNBELT INTEGER :: JI INTEGER :: IND1, IND2 INTEGER :: IDIMX,IDIMY INTEGER :: IEXTCOD REAL(KIND=8),DIMENSION(:),POINTER :: XPTRTAB REAL :: XMIN,XMAX SELECT CASE (CODINGTYPE) CASE (JPCSTENCOD) CALL EXTRACT_BBUFF(COMPTAB,32,XREF) XTAB(:) = XREF CASE (JPSOPENCOD) CALL EXTRACT_BBUFF(COMPTAB,32,IDIMX) CALL EXTRACT_BBUFF(COMPTAB,32,IDIMY) ILEVNBELT = IDIMX * IDIMY INBLEV = NBELT/(ILEVNBELT) ALLOCATE(ITAB(ILEVNBELT)) DO JI=1,INBLEV IND1=(JI-1)*ILEVNBELT+1 IND2=JI*ILEVNBELT XPTRTAB=>XTAB(IND1:IND2) IF (LPDEBUG) PRINT *,'###### Decompress(SOPENCOD) LEVEL ',JI,'######' CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF) END DO CASE (JPEXTENCOD) CALL EXTRACT_BBUFF(COMPTAB,32,IDIMX) CALL EXTRACT_BBUFF(COMPTAB,32,IDIMY) ILEVNBELT = IDIMX * IDIMY INBLEV = NBELT/(ILEVNBELT) ALLOCATE(ITAB(ILEVNBELT)) ALLOCATE(GMASK(ILEVNBELT)) DO JI=1,INBLEV IF (LPDEBUG) PRINT *,'###### Decompress(EXTENCOD) LEVEL ',JI,'######' IND1=(JI-1)*ILEVNBELT+1 IND2=JI*ILEVNBELT XPTRTAB=>XTAB(IND1:IND2) ! CALL EXTRACT_BBUFF(COMPTAB,3,IEXTCOD) IF (IEXTCOD == JPOTHER) THEN CALL EXTRACT_BBUFF(COMPTAB,3,IEXTCOD) IEXTCOD = IEXTCOD + 8 END IF IF (LPDEBUG) PRINT *, "IEXTCOD = ",IEXTCOD SELECT CASE(IEXTCOD) CASE(JPLOG) ! Conversion to log values of original data 0<=x<1 CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) GMASK(:) = .TRUE. WHERE (ITAB == 0) GMASK = .FALSE. XPTRTAB = 0.0 END WHERE CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1) WHERE(GMASK) XPTRTAB = EXP(XPTRTAB) END WHERE CASE(JPCONST) ! constant value array CALL EXTRACT_BBUFF(COMPTAB,32,XREF) XPTRTAB(:) = XREF IF (LPDEBUG) PRINT *," CONST value=",XREF CASE(JP2VAL) ! 2 different values in array CALL EXTRACT_BBUFF(COMPTAB,32,XMIN) CALL EXTRACT_BBUFF(COMPTAB,32,XMAX) CALL EXTRACTINTARRAY(ITAB) WHERE (ITAB == 0) XPTRTAB = XMIN ELSEWHERE XPTRTAB = XMAX END WHERE IF (LPDEBUG) PRINT *," 2 values:",XMIN,XMAX CASE(JP3VAL) ! 3 different values in array CALL EXTRACT_BBUFF(COMPTAB,32,XMIN) CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XMAX) CALL EXTRACTINTARRAY(ITAB) WHERE (ITAB == 0) XPTRTAB = XMIN ELSEWHERE XPTRTAB = XREF END WHERE WHERE (ITAB == 2) XPTRTAB = XMAX IF (LPDEBUG) PRINT *," 3 values:",XMIN,XREF,XMAX CASE(JPNORM) ! same as JPSOPENCOD CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF) IF (LPDEBUG) PRINT *," normal, XREF/XCOEFF = ",XREF,XCOEFF CASE(JPMINEXCL) ! Min value is isolated CALL EXTRACT_BBUFF(COMPTAB,32,XMIN) CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) GMASK(:) = .TRUE. WHERE (ITAB == 0) GMASK = .FALSE. XPTRTAB = XMIN END WHERE CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1) IF (LPDEBUG) PRINT *," Min exclus, MIN/XREF/XCOEFF = ",XMIN,XREF,XCOEFF CASE(JPMAXEXCL) ! Max value is isolated CALL EXTRACT_BBUFF(COMPTAB,32,XMAX) CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) GMASK(:) = .TRUE. WHERE (ITAB == 65535) GMASK = .FALSE. XPTRTAB = XMAX END WHERE CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,0) IF (LPDEBUG) PRINT *," Max exclus, MAX/XREF/XCOEFF = ",XMAX,XREF,XCOEFF CASE(JPMINMAXEXCL) ! Min&Max value are isolated CALL EXTRACT_BBUFF(COMPTAB,32,XMIN) CALL EXTRACT_BBUFF(COMPTAB,32,XMAX) CALL EXTRACT_BBUFF(COMPTAB,32,XREF) CALL EXTRACT_BBUFF(COMPTAB,32,XCOEFF) CALL EXTRACTINTARRAY(ITAB) GMASK(:) = .TRUE. WHERE (ITAB == 0) GMASK = .FALSE. XPTRTAB = XMIN END WHERE WHERE (ITAB == 65535) GMASK = .FALSE. XPTRTAB = XMAX END WHERE CALL DECOMP_FOP(XPTRTAB,ITAB,XREF,XCOEFF,GMASK,1) IF (LPDEBUG) PRINT *," Min et Max exclus, MIN/MAX/XREF/XCOEFF = ",& &XMIN,XMAX,XREF,XCOEFF END SELECT END DO CASE DEFAULT PRINT *,'Error in CODINGTYPE : program aborted' STOP END SELECT CONTAINS SUBROUTINE DECOMP_FOP(PTAB,KTAB,PREF,PCOEFF,OMASK,KINDCOR) REAL(KIND=8), DIMENSION(:), INTENT(INOUT) :: PTAB ! Attention: avec le compilateur PGF, utiliser INTENT(OUT) provoque une recopie ! complete du tableau dans PTAB (avec ecrasement possible des valeurs ! presentes a l'appel de la procedure). Le phenomene est genant lorsque ! DECOMP_FOP ne calcule que sur une portion de PTAB (valeurs min et/ou max ! sont presentes). En declarant PTAB en INOUT, les valeurs en entree de la routine ! sont conservees si elles n'ont pas ete modifiees. INTEGER, DIMENSION(:), INTENT(IN) :: KTAB REAL, INTENT(IN) :: PREF REAL, INTENT(IN) :: PCOEFF LOGICAL, DIMENSION(:),INTENT(IN),OPTIONAL :: OMASK INTEGER,INTENT(IN),OPTIONAL :: KINDCOR ! 1 if Min value is isolated, 0 otherwise INTEGER :: INDCOR IF (.NOT. PRESENT(KINDCOR)) THEN INDCOR = 0 ELSE INDCOR = KINDCOR END IF IF (PRESENT(OMASK)) THEN WHERE (OMASK) PTAB(:) = PCOEFF*(KTAB(:)-INDCOR)+PREF END WHERE ELSE IF (PCOEFF == 0.0) THEN PTAB(:) = PREF ELSE PTAB(:) = PCOEFF*KTAB(:)+PREF END IF END IF END SUBROUTINE DECOMP_FOP SUBROUTINE EXTRACTINTARRAY(KTAB) INTEGER,DIMENSION(:),INTENT(OUT) :: KTAB ! ! COMPTAB, IDIMX and IDIMY are defined in the calling routine ! INTEGER :: NBGRP INTEGER :: IBE INTEGER :: CPT INTEGER :: JJ INTEGER :: ALONE INTEGER :: NBITCOD,IMIN INTEGER :: GELT INTEGER :: JELT INTEGER :: IEPS CALL EXTRACT_BBUFF(COMPTAB,32,NBGRP) ! PRINT *,'Nbre de groupes =',NBGRP CALL EXTRACT_BBUFF(COMPTAB,5,IBE) ! PRINT *,'Nbre de bits pour coder le nombre d''elements:',IBE CPT = 1 DO JJ=1,NBGRP ! PRINT *,'Groupe ',JJ,' : ' CALL EXTRACT_BBUFF(COMPTAB,1,ALONE) CALL EXTRACT_BBUFF(COMPTAB,16,IMIN) ! PRINT *,'IREF=',IMIN IF (ALONE == 1) THEN ! 1 seul elt dans le groupe ! PRINT *,'--> un seul element dans le groupe' KTAB(CPT)=IMIN CPT=CPT+1 ELSE CALL EXTRACT_BBUFF(COMPTAB,4,NBITCOD) CALL EXTRACT_BBUFF(COMPTAB,IBE,GELT) ! PRINT *,'--> ',GELT,' elts, codage ecart sur ',nbitcod,'bits' IF (NBITCOD > 0) THEN DO JELT=1,GELT CALL EXTRACT_BBUFF(COMPTAB,NBITCOD,IEPS) KTAB(CPT) = IMIN+IEPS CPT=CPT+1 END DO ELSE KTAB(CPT:CPT+GELT-1) = IMIN CPT = CPT+GELT END IF END IF END DO CALL INVERTCOL(KTAB,IDIMX,IDIMY) END SUBROUTINE EXTRACTINTARRAY END SUBROUTINE DECOMPRESS_FIELD