GSI Object Oriented Online Offline (Go4) GO4-6.4.0
Loading...
Searching...
No Matches
f_ut_compress.c
Go to the documentation of this file.
1// $Id$
2//-----------------------------------------------------------------------
3// The GSI Online Offline Object Oriented (Go4) Project
4// Experiment Data Processing at EE department, GSI
5//-----------------------------------------------------------------------
6// Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7// Planckstr. 1, 64291 Darmstadt, Germany
8// Contact: http://go4.gsi.de
9//-----------------------------------------------------------------------
10// This software can be used under the license agreements as stated
11// in Go4License.txt file which is part of the distribution.
12//-----------------------------------------------------------------------
13
14/* type definitions */
15#include "typedefs.h"
16#include "f_ut_compress.h"
17#include <stdio.h>
18
19#define PACK(bit) if(*pc_in != 0){*pl_mask += bit ; *pc_out++ = *pc_in; } pc_in++;
20
21#ifdef GSI__LINUX
22#define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
23#endif
24#ifdef GSI__NT
25#define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
26#endif
27#ifdef GSI__WINNT
28#define UNPACK(bit) if(l_mask & bit ) *pc_out++ = *pc_in++; else *pc_out++ = 0;
29#endif
30#ifdef GSI__VMS
31#define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
32#endif
33#ifdef GSI__AIX
34#define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
35#endif
36#ifdef GSI__SOLARIS
37#define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
38#endif
39#ifdef GSI__LYNX
40#define UNPACK(bit) if(l_mask & bit ) *pc_out = *pc_in++; pc_out++;
41#endif
42/*****************+***********+****************************************/
43/* */
44/* GSI, Gesellschaft fuer Schwerionenforschung mbH */
45/* Postfach 11 05 41 */
46/* D-6100 Darmstadt 11 */
47/* */
48/*1+ C Procedure ***********+******************************************/
49/* */
50/*+ Module : f_ut_compr_size */
51/* */
52/*--------------------------------------------------------------------*/
53/*+ CALLING : size=f_ut_compr_size(*input,inlen) */
54/*--------------------------------------------------------------------*/
55/* */
56/*+ PURPOSE : return size of compressed data field. */
57/* */
58/*+ ARGUMENTS : */
59/* */
60/*+ input : (INTU1 *) Pointer to data field. */
61/*+ inlen : (INTS4) Length of input data field [bytes]. */
62/* */
63/*+ Return type : INTS4 */
64/*+ return : Number of bytes of compressed output */
65/*+ Include name: f_ut_compress.h */
66/* */
67/*2+Implementation************+****************************************/
68/* */
69/*+ Version : 1.01 */
70/*+ Author : H.G.Essel */
71/*+ Last Update : 13-Jul-2000 */
72/* */
73/*2+Internals*****+***********+****************************************/
74/* */
75/*+ Utility : UTIL */
76/*+ Created : 07-Jul-2000 */
77/* */
78/*1- C Procedure ***********+******************************************/
79INTS4 f_ut_compr_size(INTU1 *pc_input,INTS4 l_inlen)
80{
81INTU4 l_bytes;
82INTU4 l_masks;
83INTU4 *pl_mask,*pl_end;
84
85l_bytes=0;
86pl_mask=(INTU4 *)pc_input;
87pl_end=pl_mask+l_inlen/4;
88while(pl_mask!=pl_end)
89{
90 if(*pl_mask&0x000000ff) l_bytes++;
91 if(*pl_mask&0x0000ff00) l_bytes++;
92 if(*pl_mask&0x00ff0000) l_bytes++;
93 if(*pl_mask&0xff000000) l_bytes++;
94 pl_mask++;
95}
96if(l_bytes%4 != 0) l_bytes=l_bytes+4-l_bytes%4;
97l_masks=(l_inlen >> 5);
98if(l_inlen%32 != 0) l_masks++;
99return(l_bytes+4*l_masks+sizeof(s_compress));
100}
101
102/*1+ C Procedure ***********+******************************************/
103/* */
104/*+ Module : f_ut_compr_zeros */
105/* */
106/*--------------------------------------------------------------------*/
107/*+ CALLING : zeros=f_ut_compr_zeros(*input,inlen) */
108/*--------------------------------------------------------------------*/
109/* */
110/*+ PURPOSE : return % zero bytes. */
111/* */
112/*+ ARGUMENTS : */
113/* */
114/*+ input : (INTU1 *) Pointer to data field. */
115/*+ inlen : (INTS4) Length of input data field [bytes]. */
116/* */
117/*+ Return type : INTS4 */
118/*+ return : % of zero bytes */
119/*+ Include name: f_ut_compress.h */
120/* */
121/*2+Implementation************+****************************************/
122/* */
123/*+ Version : 1.01 */
124/*+ Author : H.G.Essel */
125/*+ Last Update : 13-Jul-2000 */
126/* */
127/*2+Internals*****+***********+****************************************/
128/* */
129/*+ Utility : UTIL */
130/*+ Created : 07-Jul-2000 */
131/* */
132/*1- C Procedure ***********+******************************************/
134{
135INTU4 I;
136INTU4 l_bytes;
137INTU1 *pc_in;
138
139pc_in =pc_input;
140l_bytes=0;
141for(I=1;I<=l_inlen;I++) if(*pc_in++ == 0) l_bytes++;
142return (l_bytes*100/l_inlen);
143}
144
145/*1+ C Procedure ***********+******************************************/
146/* */
147/*+ Module : f_ut_compr_pack */
148/* */
149/*--------------------------------------------------------------------*/
150/*+ CALLING : size=f_ut_compr_pack(*input,inlen,*output,outlen) */
151/*--------------------------------------------------------------------*/
152/* */
153/*+ PURPOSE : Compress data field by removing zero bytes */
154/* */
155/*+ ARGUMENTS : */
156/* */
157/*+ input : (INTU1 *) Pointer to input data field. */
158/*+ inlen : (INTS4) Length of input data field in bytes. */
159/*+ output : (INTU1 *) Pointer to compressed output data field. */
160/*+ outlen : (INTS4) Length of output data field. */
161/* */
162/*+ Return type : INTS4 */
163/*+ return : Number of bytes of compressed output */
164/*+ return : -1: output buffer may be too small */
165/*+ Include name: f_ut_compress.h */
166/* */
167/*2+Description***+***********+****************************************/
168/* */
169/*+ CALLING : size=f_ut_compr_pack(*input,inlen,*output,outlen) */
170/* */
171/*+ ARGUMENTS : */
172/* */
173/*+ input : (INTU1 *) Pointer to input data field. The field */
174/* must be longword aligned. */
175/*+ inlen : (INTS4) Length of input data field in bytes. */
176/*+ output : (INTU1 *) Pointer to output data field. */
177/* The output field must be 12.5% bigger than input. */
178/*+ outlen : (INTS4) Length of output data field in bytes. */
179/* */
180/*+ FUNCTION : The output field begins with structure s_compress: */
181/* */
182/*- INTU4 l_endian: set to 1 by creator */
183/*- INTU4 l_length: total size [b] of compr. buffer */
184/*- INTU4 l_masks: # of masks following this header */
185/*- INTU4 l_full_bytes: # of bytes of uncompressed buffer */
186/*- INTU4 l_comp_bytes: # of non zero bytes */
187/*- INTU4 l_pattern: COMPR__PATTERN */
188/*+ : */
189/* Then there follow inbytes/32 pattern longwords. */
190/* Then follow all non zero bytes. */
191/* Zero bytes are suppressed. The overhead is about */
192/* 13% of input, i.e. if no zeros are found, output is */
193/* 13% bigger than input. In the patterns, bits are */
194/* set for following nonzero bytes, not set for */
195/* suppressed zero bytes. */
196/*+ endian : When receiving a compressed buffer one must check */
197/* the endian. If it is not 1, one must swap */
198/* s_compress and then s_sompress.l_masks longwords. */
199/* Then the buffer can be uncompressed. The */
200/* uncompressed buffer must be checked again for right */
201/* endian, and eventually swapped. */
202/* */
203/*+ EXAMPLE : l=f_ut_compr_pack(pl_data,1024,pl_comp,2000); */
204/* l=f_ut_compr_unpack(pl_comp,pl_data,1024); */
205/* pl_data should be the same now. */
206/* */
207/*+ NOTE : Output data field must be 13% bigger than input. */
208/* */
209/*2+Implementation************+****************************************/
210/* */
211/*+ Version : 1.01 */
212/*+ Author : H.G.Essel */
213/*+ Last Update : 13-Jul-2000 */
214/* */
215/*2+Internals*****+***********+****************************************/
216/* */
217/*+ Utility : UTIL */
218/*+ Created : 07-Jul-2000 */
219/* */
220/*1- C Procedure ***********+******************************************/
221INTS4 f_ut_compr_pack(INTU1 *pc_input,INTS4 l_inlen,INTU1 *pc_output,INTS4 l_outlen)
222{
223INTU4 I;
224INTU4 l_bytes;
225INTU4 l_mask,l_masks;
226INTU4 *pl_mask;
227INTU1 *pc_out,*pc_in,*pc_1;
228s_compress *ps_compress;
229
230/* how many masks do we need: one for 32 bytes */
231l_masks=(l_inlen >> 5);
232if(l_inlen%32 != 0) l_masks++;
233/* on output we need the header, the masks, and maybe all bytes */
234if(l_outlen < (INTS4) (4*l_masks+sizeof(s_compress)+l_inlen)) return -1;
235pc_out=pc_output;
236pc_in =pc_input;
237ps_compress=(s_compress *)pc_out; /* header */
238pl_mask=(INTU4 *)(ps_compress+1); /* first mask behind header */
239pc_out = (INTU1 *)(pl_mask+l_masks);/* first data byte behind all masks */
240pc_1=pc_out;
241*pl_mask=0;
242l_mask=1;
243l_bytes=0;
244/* loop over all masks -1 */
245for(I=1;I<l_masks;I++)
246{
247 PACK(0x00000001);
248 PACK(0x00000002);
249 PACK(0x00000004);
250 PACK(0x00000008);
251 PACK(0x00000010);
252 PACK(0x00000020);
253 PACK(0x00000040);
254 PACK(0x00000080);
255 PACK(0x00000100);
256 PACK(0x00000200);
257 PACK(0x00000400);
258 PACK(0x00000800);
259 PACK(0x00001000);
260 PACK(0x00002000);
261 PACK(0x00004000);
262 PACK(0x00008000);
263 PACK(0x00010000);
264 PACK(0x00020000);
265 PACK(0x00040000);
266 PACK(0x00080000);
267 PACK(0x00100000);
268 PACK(0x00200000);
269 PACK(0x00400000);
270 PACK(0x00800000);
271 PACK(0x01000000);
272 PACK(0x02000000);
273 PACK(0x04000000);
274 PACK(0x08000000);
275 PACK(0x10000000);
276 PACK(0x20000000);
277 PACK(0x40000000);
278 PACK(0x80000000);
279 pl_mask++;
280 *pl_mask=0;
281}
282l_bytes=pc_out-pc_1 ;
283/* last mask could be less than 32 bytes */
284l_mask=1;
285for(I=0;I<(l_inlen-l_masks*32+32);I++)
286{
287 if(*pc_in != 0){*pl_mask += l_mask; *pc_out++ = *pc_in; l_bytes++; } l_mask = l_mask << 1; pc_in++;
288}
289/* add the number of last fragment bytes */
290ps_compress->l_endian = 1;
291ps_compress->l_length = l_bytes+4*l_masks+sizeof(s_compress);
292ps_compress->l_pattern = COMPR__PATTERN;
293ps_compress->l_masks = l_masks;
294ps_compress->l_full_bytes = l_inlen;
295ps_compress->l_comp_bytes = l_bytes; /* without header and masks */
296
297return (l_bytes+4*l_masks+sizeof(s_compress));
298}
299
300/*1+ C Procedure ***********+******************************************/
301/* */
302/*+ Module : f_ut_compr_unpack */
303/* */
304/*--------------------------------------------------------------------*/
305/*+ CALLING : size=f_ut_compr_unpack(*input,*output,outlen) */
306/*--------------------------------------------------------------------*/
307/* */
308/*+ PURPOSE : Deompress data field. */
309/* */
310/*+ ARGUMENTS : */
311/* */
312/*+ input : (INTU1 *) Pointer to compressed data field. */
313/*+ output : (INTU1 *) Pointer to uncompressed output data field.*/
314/*+ outlen : (INTS4) Length of output data field. */
315/* */
316/*+ Return type : INTS4 */
317/*+ return : 0 : OK */
318/*+ return : -1: output buffer may be too small */
319/*+ Include name: f_ut_compress.h */
320/* */
321/*2+Description***************+****************************************/
322/* Receiving a compressed buffer which could have */
323/* a different endian, proceed as follows: */
324/* Receive sizeof(s_compress) bytes and check */
325/* s_compress.l_endian. If not 1 swap s_compress. */
326/* Get s_compress.l_length-sizeof(s_compress) bytes. */
327/* Swap next s_compress.l_masks longwords. */
328/* Call f_ut_compr_unpack to compress the buffer. */
329/* The uncompressed buffer must be checked for correct */
330/* endian again. The method is up to the sender. */
331/* */
332/*2+Implementation************+****************************************/
333/* */
334/*+ Version : 1.01 */
335/*+ Author : H.G.Essel */
336/*+ Last Update : 13-Jul-2000 */
337/* */
338/*2+Internals*****+***********+****************************************/
339/* */
340/*+ Utility : UTIL */
341/*+ Created : 07-Jul-2000 */
342/* */
343/*1- C Procedure ***********+******************************************/
344INTS4 f_ut_compr_unpack(INTU1 *pc_input,INTU1 *pc_output,INTS4 l_outlen)
345{
346INTU4 L;
347INTU4 l_mask;
348INTU4 *pl_mask;
349INTU1 *pc_out,*pc_in;
350s_compress *ps_compress;
351
352ps_compress=(s_compress *)pc_input;
353/* is output buffer big enough? */
354if(ps_compress->l_full_bytes > l_outlen) return -1;
355
356#ifdef GSI__VMS
357pl_out=(INTU4 *) pc_output;
358pl_tmp=pl_out+(ps_compress->l_full_bytes>>2);
359while(pl_out != pl_tmp) *pl_out++ = 0;
360#endif
361#ifdef GSI__LYNX
362pl_out=(INTU4 *) pc_output;
363pl_tmp=pl_out+(ps_compress->l_full_bytes>>2);
364while(pl_out != pl_tmp) *pl_out++ = 0;
365#endif
366#ifdef GSI__AIX
367memset(pc_output,0,ps_compress->l_full_bytes);
368#endif
369
370pl_mask=(INTU4 *)(ps_compress+1);
371pc_in = (INTU1 *)(pl_mask+ps_compress->l_masks);
372pc_out=pc_output;
373/* all masks -1 */
374for(L=1;L<ps_compress->l_masks;L++)
375{
376 l_mask=*pl_mask;
377 UNPACK(0x00000001);
378 UNPACK(0x00000002);
379 UNPACK(0x00000004);
380 UNPACK(0x00000008);
381 UNPACK(0x00000010);
382 UNPACK(0x00000020);
383 UNPACK(0x00000040);
384 UNPACK(0x00000080);
385 UNPACK(0x00000100);
386 UNPACK(0x00000200);
387 UNPACK(0x00000400);
388 UNPACK(0x00000800);
389 UNPACK(0x00001000);
390 UNPACK(0x00002000);
391 UNPACK(0x00004000);
392 UNPACK(0x00008000);
393 UNPACK(0x00010000);
394 UNPACK(0x00020000);
395 UNPACK(0x00040000);
396 UNPACK(0x00080000);
397 UNPACK(0x00100000);
398 UNPACK(0x00200000);
399 UNPACK(0x00400000);
400 UNPACK(0x00800000);
401 UNPACK(0x01000000);
402 UNPACK(0x02000000);
403 UNPACK(0x04000000);
404 UNPACK(0x08000000);
405 UNPACK(0x10000000);
406 UNPACK(0x20000000);
407 UNPACK(0x40000000);
408 UNPACK(0x80000000);
409 pl_mask++;
410}
411l_mask=*pl_mask;
412/* restore bytes of last mask (could be less than 32) */
413for(L=0;L<ps_compress->l_full_bytes-ps_compress->l_masks*32+32;L++)
414{
415 if(l_mask%2 != 0) *pc_out++ = *pc_in++; else *pc_out++=0;
416 l_mask = l_mask >> 1;
417}
418return 0;
419}
INTS4 f_ut_compr_unpack(INTU1 *pc_input, INTU1 *pc_output, INTS4 l_outlen)
INTS4 f_ut_compr_zeros(INTU1 *pc_input, INTS4 l_inlen)
INTS4 f_ut_compr_pack(INTU1 *pc_input, INTS4 l_inlen, INTU1 *pc_output, INTS4 l_outlen)
INTS4 f_ut_compr_size(INTU1 *pc_input, INTS4 l_inlen)
#define PACK(bit)
#define COMPR__PATTERN
INTU4 l_comp_bytes
INTU4 l_full_bytes
INTU4 l_pattern
unsigned char INTU1
Definition typedefs.h:25
int INTS4
Definition typedefs.h:28
unsigned int INTU4
Definition typedefs.h:29