Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

f_ut_compress.c

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

Generated on Fri Nov 28 12:59:33 2008 for Go4-v3.04-1 by  doxygen 1.4.2