Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/MbsAPI/f_ut_compress.c

Go to the documentation of this file.
00001 //---------------------------------------------------------------
00002 //        Go4 Release Package v2.10-5 (build 21005) 
00003 //                      03-Nov-2005
00004 //---------------------------------------------------------------
00005 //       The GSI Online Offline Object Oriented (Go4) Project
00006 //       Experiment Data Processing at DVEE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
00015 //----------------------------------------------------------------
00016 /* type definitions */
00017 #include "typedefs.h"
00018 #include "f_ut_compress.h"
00019 #include <stdio.h>
00020 
00021 #define PACK(bit)   if(*pc_in != 0){*pl_mask += bit ; *pc_out++ = *pc_in; }  pc_in++;
00022 
00023 #ifdef GSI__LINUX
00024 #define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
00025 #endif
00026 #ifdef GSI__NT
00027 #define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
00028 #endif
00029 #ifdef GSI__WINNT
00030 #define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
00031 #endif
00032 #ifdef GSI__VMS
00033 #define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
00034 #endif
00035 #ifdef GSI__AIX
00036 #define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
00037 #endif
00038 #ifdef GSI__LYNX
00039 #define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
00040 #endif
00041 /*****************+***********+****************************************/
00042 /*                                                                    */
00043 /*   GSI, Gesellschaft fuer Schwerionenforschung mbH                  */
00044 /*   Postfach 11 05 41                                                */
00045 /*   D-6100 Darmstadt 11                                              */
00046 /*                                                                    */
00047 /*1+ C Procedure ***********+******************************************/
00048 /*                                                                    */
00049 /*+ Module      : f_ut_compr_size                                     */
00050 /*                                                                    */
00051 /*--------------------------------------------------------------------*/
00052 /*+ CALLING     : size=f_ut_compr_size(*input,inlen)                  */
00053 /*--------------------------------------------------------------------*/
00054 /*                                                                    */
00055 /*+ PURPOSE     : return size of compressed data field.               */
00056 /*                                                                    */
00057 /*+ ARGUMENTS   :                                                     */
00058 /*                                                                    */
00059 /*+    input    : (INTU1 *) Pointer to data field.                    */
00060 /*+    inlen    : (INTS4) Length of input data field [bytes].         */
00061 /*                                                                    */
00062 /*+ Return type : INTS4                                               */
00063 /*+    return   : Number of bytes of compressed output                */
00064 /*+ Include name: f_ut_compress.h                                     */
00065 /*                                                                    */
00066 /*2+Implementation************+****************************************/
00067 /*                                                                    */
00068 /*+ Version     : 1.01                                                */
00069 /*+ Author      : H.G.Essel                                           */
00070 /*+ Last Update : 13-Jul-2000                                         */
00071 /*                                                                    */
00072 /*2+Internals*****+***********+****************************************/
00073 /*                                                                    */
00074 /*+ Utility     : UTIL                                                */
00075 /*+ Created     : 07-Jul-2000                                         */
00076 /*                                                                    */
00077 /*1- C Procedure ***********+******************************************/
00078 INTS4 f_ut_compr_size(INTU1 *pc_input,INTS4 l_inlen)
00079 {
00080 INTU4 I,J,K,L,M,N;
00081 INTU4 l_bytes;
00082 INTU4 l_masks;
00083 INTU4 *pl_mask,*pl_end;
00084 INTU1 *pc_out,*pc_in;
00085 s_compress  *ps_compress;
00086 
00087 pc_in =pc_input;
00088 l_bytes=0;
00089 pl_mask=(INTU4 *)pc_input;
00090 pl_end=pl_mask+l_inlen/4;
00091 while(pl_mask!=pl_end)
00092 {
00093  if(*pl_mask&0x000000ff) l_bytes++;
00094  if(*pl_mask&0x0000ff00) l_bytes++;
00095  if(*pl_mask&0x00ff0000) l_bytes++;
00096  if(*pl_mask&0xff000000) l_bytes++;
00097  pl_mask++;
00098 }
00099 if(l_bytes%4 != 0) l_bytes=l_bytes+4-l_bytes%4;
00100 l_masks=(l_inlen >> 5);
00101 if(l_inlen%32 != 0) l_masks++;
00102 return(l_bytes+4*l_masks+sizeof(s_compress));
00103 }
00104 
00105 /*1+ C Procedure ***********+******************************************/
00106 /*                                                                    */
00107 /*+ Module      : f_ut_compr_zeros                                    */
00108 /*                                                                    */
00109 /*--------------------------------------------------------------------*/
00110 /*+ CALLING     : zeros=f_ut_compr_zeros(*input,inlen)                */
00111 /*--------------------------------------------------------------------*/
00112 /*                                                                    */
00113 /*+ PURPOSE     : return % zero bytes.                                */
00114 /*                                                                    */
00115 /*+ ARGUMENTS   :                                                     */
00116 /*                                                                    */
00117 /*+    input    : (INTU1 *) Pointer to data field.                    */
00118 /*+    inlen    : (INTS4) Length of input data field [bytes].         */
00119 /*                                                                    */
00120 /*+ Return type : INTS4                                               */
00121 /*+    return   : % of zero bytes                                     */
00122 /*+ Include name: f_ut_compress.h                                     */
00123 /*                                                                    */
00124 /*2+Implementation************+****************************************/
00125 /*                                                                    */
00126 /*+ Version     : 1.01                                                */
00127 /*+ Author      : H.G.Essel                                           */
00128 /*+ Last Update : 13-Jul-2000                                         */
00129 /*                                                                    */
00130 /*2+Internals*****+***********+****************************************/
00131 /*                                                                    */
00132 /*+ Utility     : UTIL                                                */
00133 /*+ Created     : 07-Jul-2000                                         */
00134 /*                                                                    */
00135 /*1- C Procedure ***********+******************************************/
00136 INTS4 f_ut_compr_zeros(INTU1 *pc_input,INTS4 l_inlen)
00137 {
00138 INTU4 I,J,K,L,M,N;
00139 INTU4 l_bytes;
00140 INTU4 l_mask;
00141 INTU4 *pl_mask;
00142 INTU1 *pc_out,*pc_in;
00143 s_compress  *ps_compress;
00144 
00145 pc_in =pc_input;
00146 l_bytes=0;
00147 for(I=1;I<=l_inlen;I++) if(*pc_in++ == 0) l_bytes++;
00148 return (l_bytes*100/l_inlen);
00149 }
00150 
00151 /*1+ C Procedure ***********+******************************************/
00152 /*                                                                    */
00153 /*+ Module      : f_ut_compr_pack                                     */
00154 /*                                                                    */
00155 /*--------------------------------------------------------------------*/
00156 /*+ CALLING     : size=f_ut_compr_pack(*input,inlen,*output,outlen)   */
00157 /*--------------------------------------------------------------------*/
00158 /*                                                                    */
00159 /*+ PURPOSE     : Compress data field by removing zero bytes          */
00160 /*                                                                    */
00161 /*+ ARGUMENTS   :                                                     */
00162 /*                                                                    */
00163 /*+    input    : (INTU1 *) Pointer to input data field.              */
00164 /*+    inlen    : (INTS4) Length of input data field in bytes.        */
00165 /*+    output   : (INTU1 *) Pointer to compressed output data field.  */
00166 /*+    outlen   : (INTS4) Length of output data field.                */
00167 /*                                                                    */
00168 /*+ Return type : INTS4                                               */
00169 /*+    return   : Number of bytes of compressed output                */
00170 /*+    return   : -1: output buffer may be too small                  */
00171 /*+ Include name: f_ut_compress.h                                     */
00172 /*                                                                    */
00173 /*2+Description***+***********+****************************************/
00174 /*                                                                    */
00175 /*+ CALLING     : size=f_ut_compr_pack(*input,inlen,*output,outlen)   */
00176 /*                                                                    */
00177 /*+ ARGUMENTS   :                                                     */
00178 /*                                                                    */
00179 /*+    input    : (INTU1 *) Pointer to input data field. The field    */
00180 /*                must be longword aligned.                           */
00181 /*+    inlen    : (INTS4) Length of input data field in bytes.        */
00182 /*+    output   : (INTU1 *) Pointer to output data field.             */
00183 /*                The output field must be 12.5% bigger than input.   */
00184 /*+    outlen   : (INTS4) Length of output data field in bytes.       */
00185 /*                                                                    */
00186 /*+ FUNCTION    : The output field begins with structure s_compress:  */
00187 /*                                                                    */
00188 /*-               INTU4 l_endian:     set to 1 by creator             */
00189 /*-               INTU4 l_length:     total size [b] of compr. buffer */
00190 /*-               INTU4 l_masks:      # of masks following this header */
00191 /*-               INTU4 l_full_bytes: # of bytes of uncompressed buffer */
00192 /*-               INTU4 l_comp_bytes: # of non zero bytes             */
00193 /*-               INTU4 l_pattern:    COMPR__PATTERN                  */
00194 /*+ :                                                                  */
00195 /*                Then there follow inbytes/32 pattern longwords.     */
00196 /*                Then follow all non zero bytes.                     */
00197 /*                Zero bytes are suppressed. The overhead is about    */
00198 /*                13% of input, i.e. if no zeros are found, output is */
00199 /*                13% bigger than input. In the patterns, bits are    */
00200 /*                set for following nonzero bytes, not set for        */
00201 /*                suppressed zero bytes.                              */
00202 /*+  endian     : When receiving a compressed buffer one must check   */
00203 /*                the endian. If it is not 1, one must swap           */
00204 /*                s_compress and then s_sompress.l_masks longwords.   */
00205 /*                Then the buffer can be uncompressed. The            */
00206 /*                uncompressed buffer must be checked again for right */
00207 /*                endian, and eventually swapped.                     */
00208 /*                                                                    */
00209 /*+ EXAMPLE     : l=f_ut_compr_pack(pl_data,1024,pl_comp,2000);       */
00210 /*                l=f_ut_compr_unpack(pl_comp,pl_data,1024);          */
00211 /*                pl_data should be the same now.                     */
00212 /*                                                                    */
00213 /*+ NOTE        : Output data field must be 13% bigger than input.    */
00214 /*                                                                    */
00215 /*2+Implementation************+****************************************/
00216 /*                                                                    */
00217 /*+ Version     : 1.01                                                */
00218 /*+ Author      : H.G.Essel                                           */
00219 /*+ Last Update : 13-Jul-2000                                         */
00220 /*                                                                    */
00221 /*2+Internals*****+***********+****************************************/
00222 /*                                                                    */
00223 /*+ Utility     : UTIL                                                */
00224 /*+ Created     : 07-Jul-2000                                         */
00225 /*                                                                    */
00226 /*1- C Procedure ***********+******************************************/
00227 INTS4 f_ut_compr_pack(INTU1 *pc_input,INTS4 l_inlen,INTU1 *pc_output,INTS4 l_outlen)
00228 {
00229 INTU4 I,J,K,L,M,N;
00230 INTU4 l_bytes;
00231 INTU4 l_mask,l_masks;
00232 INTU4 *pl_mask;
00233 INTU1 *pc_out,*pc_in,*pc_1;
00234 s_compress  *ps_compress;
00235 
00236 /* how many masks do we need: one for 32 bytes */
00237 l_masks=(l_inlen >> 5);
00238 if(l_inlen%32 != 0) l_masks++;
00239 /* on output we need the header, the masks, and maybe all bytes */
00240 if(l_outlen < 4*l_masks+sizeof(s_compress)+l_inlen) return -1;
00241 pc_out=pc_output;
00242 pc_in =pc_input;
00243 ps_compress=(s_compress *)pc_out;   /* header */
00244 pl_mask=(INTU4 *)(ps_compress+1);   /* first mask behind header */
00245 pc_out = (INTU1 *)(pl_mask+l_masks);/* first data byte behind all masks */
00246 pc_1=pc_out;
00247 *pl_mask=0;
00248 l_mask=1;
00249 l_bytes=0;
00250 /* loop over all masks -1 */
00251 for(I=1;I<l_masks;I++)
00252 {
00253   PACK(0x00000001);
00254   PACK(0x00000002);
00255   PACK(0x00000004);
00256   PACK(0x00000008);
00257   PACK(0x00000010);
00258   PACK(0x00000020);
00259   PACK(0x00000040);
00260   PACK(0x00000080);
00261   PACK(0x00000100);
00262   PACK(0x00000200);
00263   PACK(0x00000400);
00264   PACK(0x00000800);
00265   PACK(0x00001000);
00266   PACK(0x00002000);
00267   PACK(0x00004000);
00268   PACK(0x00008000);
00269   PACK(0x00010000);
00270   PACK(0x00020000);
00271   PACK(0x00040000);
00272   PACK(0x00080000);
00273   PACK(0x00100000);
00274   PACK(0x00200000);
00275   PACK(0x00400000);
00276   PACK(0x00800000);
00277   PACK(0x01000000);
00278   PACK(0x02000000);
00279   PACK(0x04000000);
00280   PACK(0x08000000);
00281   PACK(0x10000000);
00282   PACK(0x20000000);
00283   PACK(0x40000000);
00284   PACK(0x80000000);
00285     pl_mask++;
00286     *pl_mask=0;
00287 }
00288 l_bytes=pc_out-pc_1 ;
00289 /* last mask could be less than 32 bytes */
00290 l_mask=1;
00291 for(I=0;I<(l_inlen-l_masks*32+32);I++)
00292 {
00293     if(*pc_in != 0){*pl_mask += l_mask; *pc_out++ = *pc_in; l_bytes++; } l_mask = l_mask << 1; pc_in++;
00294 }
00295 /* add the number of last fragment bytes */
00296 ps_compress->l_endian     = 1;
00297 ps_compress->l_length     = l_bytes+4*l_masks+sizeof(s_compress);
00298 ps_compress->l_pattern    = COMPR__PATTERN;
00299 ps_compress->l_masks      = l_masks;
00300 ps_compress->l_full_bytes = l_inlen;
00301 ps_compress->l_comp_bytes = l_bytes; /* without header and masks */
00302 
00303 return (l_bytes+4*l_masks+sizeof(s_compress));
00304 }
00305 
00306 /*1+ C Procedure ***********+******************************************/
00307 /*                                                                    */
00308 /*+ Module      : f_ut_compr_unpack                                   */
00309 /*                                                                    */
00310 /*--------------------------------------------------------------------*/
00311 /*+ CALLING     : size=f_ut_compr_unpack(*input,*output,outlen)       */
00312 /*--------------------------------------------------------------------*/
00313 /*                                                                    */
00314 /*+ PURPOSE     : Deompress data field.                               */
00315 /*                                                                    */
00316 /*+ ARGUMENTS   :                                                     */
00317 /*                                                                    */
00318 /*+    input    : (INTU1 *) Pointer to compressed data field.         */
00319 /*+    output   : (INTU1 *) Pointer to uncompressed output data field.*/
00320 /*+    outlen   : (INTS4) Length of output data field.                */
00321 /*                                                                    */
00322 /*+ Return type : INTS4                                               */
00323 /*+    return   : 0 : OK                                              */
00324 /*+    return   : -1: output buffer may be too small                  */
00325 /*+ Include name: f_ut_compress.h                                     */
00326 /*                                                                    */
00327 /*2+Description***************+****************************************/
00328 /*                Receiving a compressed buffer which could have      */
00329 /*                a different endian, proceed as follows:             */
00330 /*                Receive sizeof(s_compress) bytes and check          */
00331 /*                s_compress.l_endian. If not 1 swap s_compress.      */
00332 /*                Get s_compress.l_length-sizeof(s_compress) bytes.   */
00333 /*                Swap next s_compress.l_masks longwords.             */
00334 /*                Call f_ut_compr_unpack to compress the buffer.      */
00335 /*                The uncompressed buffer must be checked for correct */
00336 /*                endian again. The method is up to the sender.       */
00337 /*                                                                    */
00338 /*2+Implementation************+****************************************/
00339 /*                                                                    */
00340 /*+ Version     : 1.01                                                */
00341 /*+ Author      : H.G.Essel                                           */
00342 /*+ Last Update : 13-Jul-2000                                         */
00343 /*                                                                    */
00344 /*2+Internals*****+***********+****************************************/
00345 /*                                                                    */
00346 /*+ Utility     : UTIL                                                */
00347 /*+ Created     : 07-Jul-2000                                         */
00348 /*                                                                    */
00349 /*1- C Procedure ***********+******************************************/
00350 INTS4 f_ut_compr_unpack(INTU1 *pc_input,INTU1 *pc_output,INTS4 l_outlen)
00351 {
00352 INTU4 I,J,K,L,M,N;
00353 INTU4 l_mask;
00354 INTU4 *pl_mask,*pl_tmp,*pl_out;
00355 INTU1 *pc_out,*pc_in;
00356 s_compress  *ps_compress;
00357 
00358 ps_compress=(s_compress *)pc_input;
00359 /* is output buffer big enough?  */
00360 if(ps_compress->l_full_bytes > l_outlen) return -1;
00361 
00362 #ifdef GSI__VMS
00363 pl_out=(INTU4 *) pc_output;
00364 pl_tmp=pl_out+(ps_compress->l_full_bytes>>2);
00365 while(pl_out != pl_tmp) *pl_out++ = 0;
00366 #endif
00367 #ifdef GSI__LYNX
00368 pl_out=(INTU4 *) pc_output;
00369 pl_tmp=pl_out+(ps_compress->l_full_bytes>>2);
00370 while(pl_out != pl_tmp) *pl_out++ = 0;
00371 #endif
00372 #ifdef GSI__AIX
00373 memset(pc_output,0,ps_compress->l_full_bytes);
00374 #endif
00375 
00376 pl_mask=(INTU4 *)(ps_compress+1);
00377 pc_in = (INTU1 *)(pl_mask+ps_compress->l_masks);
00378 pc_out=pc_output;
00379 /* all masks -1 */
00380 for(L=1;L<ps_compress->l_masks;L++)
00381 {
00382     l_mask=*pl_mask;
00383     UNPACK(0x00000001);
00384     UNPACK(0x00000002);
00385     UNPACK(0x00000004);
00386     UNPACK(0x00000008);
00387     UNPACK(0x00000010);
00388     UNPACK(0x00000020);
00389     UNPACK(0x00000040);
00390     UNPACK(0x00000080);
00391     UNPACK(0x00000100);
00392     UNPACK(0x00000200);
00393     UNPACK(0x00000400);
00394     UNPACK(0x00000800);
00395     UNPACK(0x00001000);
00396     UNPACK(0x00002000);
00397     UNPACK(0x00004000);
00398     UNPACK(0x00008000);
00399     UNPACK(0x00010000);
00400     UNPACK(0x00020000);
00401     UNPACK(0x00040000);
00402     UNPACK(0x00080000);
00403     UNPACK(0x00100000);
00404     UNPACK(0x00200000);
00405     UNPACK(0x00400000);
00406     UNPACK(0x00800000);
00407     UNPACK(0x01000000);
00408     UNPACK(0x02000000);
00409     UNPACK(0x04000000);
00410     UNPACK(0x08000000);
00411     UNPACK(0x10000000);
00412     UNPACK(0x20000000);
00413     UNPACK(0x40000000);
00414     UNPACK(0x80000000);
00415     pl_mask++;
00416 }
00417 l_mask=*pl_mask;
00418 /* restore bytes of last mask (could be less than 32) */
00419 for(L=0;L<ps_compress->l_full_bytes-ps_compress->l_masks*32+32;L++)
00420 {
00421     if(l_mask%2 != 0) *pc_out++ = *pc_in++; else *pc_out++=0;
00422     l_mask = l_mask >> 1;
00423 }
00424 return 0;
00425 }
00426 
00427 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Tue Nov 8 10:56:08 2005 for Go4-v2.10-5 by doxygen1.2.15