~ubuntu-branches/ubuntu/trusty/ucl/trusty

« back to all changes in this revision

Viewing changes to .pc/01-Examples.patch/examples/uclpack.c

  • Committer: Package Import Robot
  • Author(s): Robert Luberda
  • Date: 2012-01-08 20:45:02 UTC
  • mfrom: (3.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20120108204502-ds3stjc0fqs4omis
Tags: 1.03-5
* Switch to `3.0 (quilt)' format. Add initial 01-Examples.patch
  containing previous changes.
* Switch to debhelper v9 and tiny rules file:
  + use dh_autotools-dev to update config.{sub,guess} files;
  + multi-arch support;
  + use dpkg-buildflags to set CFLAGS and LDFLAGS;
  + bump build-dependencies on debhelper and dpkg-dev.
* Fix examples/Makefile not to remove original *.c.gz files.
* debian/control:
  + add VCS fields.
  + drop ancient Conflicts/Replaces/Provides on libucl;
  + Standards-Version: 3.9.2 (no changes);
  + sort dependency fields with wrap-and-sort.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* uclpack.c -- example program: a simple file packer
 
2
 
 
3
   This file is part of the UCL data compression library.
 
4
 
 
5
   Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
 
6
   All Rights Reserved.
 
7
 
 
8
   The UCL library is free software; you can redistribute it and/or
 
9
   modify it under the terms of the GNU General Public License as
 
10
   published by the Free Software Foundation; either version 2 of
 
11
   the License, or (at your option) any later version.
 
12
 
 
13
   The UCL library is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with the UCL library; see the file COPYING.
 
20
   If not, write to the Free Software Foundation, Inc.,
 
21
   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
22
 
 
23
   Markus F.X.J. Oberhumer
 
24
   <markus@oberhumer.com>
 
25
   http://www.oberhumer.com/opensource/ucl/
 
26
 */
 
27
 
 
28
 
 
29
/*************************************************************************
 
30
// NOTE: this is an example program, so do not use to backup your data.
 
31
//
 
32
// This program lacks things like sophisticated file handling but is
 
33
// pretty complete regarding compression - it should provide a good
 
34
// starting point for adaption for you applications.
 
35
**************************************************************************/
 
36
 
 
37
#include <ucl/ucl.h>
 
38
#if defined(UCL_USE_ASM)
 
39
#  include <ucl/ucl_asm.h>
 
40
#endif
 
41
#if 1 && defined(UCL_USE_ASM)
 
42
   /* use assembler versions of the decompressors */
 
43
#  define ucl_nrv2b_decompress_8        ucl_nrv2b_decompress_asm_8
 
44
#  define ucl_nrv2b_decompress_safe_8   ucl_nrv2b_decompress_asm_safe_8
 
45
#  define ucl_nrv2d_decompress_8        ucl_nrv2d_decompress_asm_8
 
46
#  define ucl_nrv2d_decompress_safe_8   ucl_nrv2d_decompress_asm_safe_8
 
47
#  define ucl_nrv2e_decompress_8        ucl_nrv2e_decompress_asm_8
 
48
#  define ucl_nrv2e_decompress_safe_8   ucl_nrv2e_decompress_asm_safe_8
 
49
#endif
 
50
 
 
51
/* benchmark setup - do not introduce floating point dependencies for DOS16 */
 
52
#if !defined(WITH_TIMER) && !defined(UCL_OS_DOS16)
 
53
#  define WITH_TIMER 1
 
54
#endif
 
55
 
 
56
/* portability layer */
 
57
#define WANT_UCL_MALLOC 1
 
58
#define WANT_UCL_FREAD 1
 
59
#if defined(WITH_TIMER)
 
60
#define WANT_UCL_UCLOCK 1
 
61
#endif
 
62
#define WANT_UCL_WILDARGV 1
 
63
#include "examples/portab.h"
 
64
 
 
65
 
 
66
static const char *progname = NULL;
 
67
 
 
68
static unsigned long total_in = 0;
 
69
static unsigned long total_out = 0;
 
70
static int opt_debug = 0;
 
71
 
 
72
/* use option `-F' for faster operation - then we don't compute or verify
 
73
 * a checksum and always use the fast decompressor */
 
74
static ucl_bool opt_fast = 0;
 
75
 
 
76
/* magic file header for compressed files */
 
77
static const unsigned char magic[8] =
 
78
    { 0x00, 0xe9, 0x55, 0x43, 0x4c, 0xff, 0x01, 0x1a };
 
79
 
 
80
/* benchmark */
 
81
#if defined(WITH_TIMER)
 
82
static ucl_uclock_handle_t uc;
 
83
static double benchmark_bytes;
 
84
static double benchmark_secs;
 
85
#endif
 
86
 
 
87
 
 
88
/*************************************************************************
 
89
// file IO
 
90
**************************************************************************/
 
91
 
 
92
ucl_uint xread(FILE *f, ucl_voidp buf, ucl_uint len, ucl_bool allow_eof)
 
93
{
 
94
    ucl_uint l;
 
95
 
 
96
    l = (ucl_uint) ucl_fread(f,buf,len);
 
97
    if (l > len)
 
98
    {
 
99
        fprintf(stderr,"\nsomething's wrong with your C library !!!\n");
 
100
        exit(1);
 
101
    }
 
102
    if (l != len && !allow_eof)
 
103
    {
 
104
        fprintf(stderr,"\nread error - premature end of file\n");
 
105
        exit(1);
 
106
    }
 
107
    total_in += l;
 
108
    return l;
 
109
}
 
110
 
 
111
ucl_uint xwrite(FILE *f, const ucl_voidp buf, ucl_uint len)
 
112
{
 
113
    ucl_uint l;
 
114
 
 
115
    if (f != NULL)
 
116
    {
 
117
        l = (ucl_uint) ucl_fwrite(f,buf,len);
 
118
        if (l != len)
 
119
        {
 
120
            fprintf(stderr,"\nwrite error [%ld %ld]  (disk full ?)\n",
 
121
                   (long)len, (long)l);
 
122
            exit(1);
 
123
        }
 
124
    }
 
125
    total_out += len;
 
126
    return len;
 
127
}
 
128
 
 
129
 
 
130
int xgetc(FILE *f)
 
131
{
 
132
    unsigned char c;
 
133
    xread(f,(ucl_voidp) &c,1,0);
 
134
    return c;
 
135
}
 
136
 
 
137
void xputc(FILE *f, int c)
 
138
{
 
139
    unsigned char cc = (unsigned char) c;
 
140
    xwrite(f,(const ucl_voidp) &cc,1);
 
141
}
 
142
 
 
143
/* read and write portable 32-bit integers */
 
144
 
 
145
ucl_uint32 xread32(FILE *f)
 
146
{
 
147
    unsigned char b[4];
 
148
    ucl_uint32 v;
 
149
 
 
150
    xread(f,b,4,0);
 
151
    v  = (ucl_uint32) b[3] <<  0;
 
152
    v |= (ucl_uint32) b[2] <<  8;
 
153
    v |= (ucl_uint32) b[1] << 16;
 
154
    v |= (ucl_uint32) b[0] << 24;
 
155
    return v;
 
156
}
 
157
 
 
158
void xwrite32(FILE *f, ucl_uint32 v)
 
159
{
 
160
    unsigned char b[4];
 
161
 
 
162
    b[3] = (unsigned char) (v >>  0);
 
163
    b[2] = (unsigned char) (v >>  8);
 
164
    b[1] = (unsigned char) (v >> 16);
 
165
    b[0] = (unsigned char) (v >> 24);
 
166
    xwrite(f,b,4);
 
167
}
 
168
 
 
169
 
 
170
/*************************************************************************
 
171
// util
 
172
**************************************************************************/
 
173
 
 
174
static ucl_uint get_overhead(int method, ucl_uint size)
 
175
{
 
176
    if (method == 0x2b || method == 0x2d || method == 0x2e)
 
177
        return size / 8 + 256;
 
178
    return 0;
 
179
}
 
180
 
 
181
 
 
182
static char method_name[64];
 
183
 
 
184
static ucl_bool set_method_name(int method, int level)
 
185
{
 
186
    method_name[0] = 0;
 
187
    if (level < 1 || level > 10)
 
188
        return 0;
 
189
    if (method == 0x2b)
 
190
        sprintf(method_name,"NRV2B-99/%d", level);
 
191
    else if (method == 0x2d)
 
192
        sprintf(method_name,"NRV2D-99/%d", level);
 
193
    else if (method == 0x2e)
 
194
        sprintf(method_name,"NRV2E-99/%d", level);
 
195
    else
 
196
        return 0;
 
197
    return 1;
 
198
}
 
199
 
 
200
 
 
201
/*************************************************************************
 
202
// compress
 
203
**************************************************************************/
 
204
 
 
205
int do_compress(FILE *fi, FILE *fo, int method, int level, ucl_uint block_size)
 
206
{
 
207
    int r = 0;
 
208
    ucl_bytep in = NULL;
 
209
    ucl_bytep out = NULL;
 
210
    ucl_uint in_len;
 
211
    ucl_uint out_len;
 
212
    ucl_uint32 flags = opt_fast ? 0 : 1;
 
213
    ucl_uint32 checksum;
 
214
    ucl_uint overhead = 0;
 
215
#if defined(WITH_TIMER)
 
216
    ucl_uclock_t t_start, t_stop;
 
217
#endif
 
218
 
 
219
    total_in = total_out = 0;
 
220
 
 
221
/*
 
222
 * Step 1: write magic header, flags & block size, init checksum
 
223
 */
 
224
    xwrite(fo,magic,sizeof(magic));
 
225
    xwrite32(fo,flags);
 
226
    xputc(fo,method);           /* compression method */
 
227
    xputc(fo,level);            /* compression level */
 
228
    xwrite32(fo,block_size);
 
229
    checksum = ucl_adler32(0,NULL,0);
 
230
 
 
231
/*
 
232
 * Step 2: allocate compression buffers and work-memory
 
233
 */
 
234
    overhead = get_overhead(method,block_size);
 
235
    in = (ucl_bytep) ucl_malloc(block_size);
 
236
    out = (ucl_bytep) ucl_malloc(block_size + overhead);
 
237
    if (in == NULL || out == NULL)
 
238
    {
 
239
        printf("%s: out of memory\n", progname);
 
240
        r = 1;
 
241
        goto err;
 
242
    }
 
243
 
 
244
/*
 
245
 * Step 3: process blocks
 
246
 */
 
247
    for (;;)
 
248
    {
 
249
        /* read block */
 
250
        in_len = xread(fi,in,block_size,1);
 
251
        if (in_len <= 0)
 
252
            break;
 
253
 
 
254
        /* update checksum */
 
255
        if (flags & 1)
 
256
            checksum = ucl_adler32(checksum,in,in_len);
 
257
 
 
258
#if defined(WITH_TIMER)
 
259
        ucl_uclock_read(&uc, &t_start);
 
260
#endif
 
261
 
 
262
        /* compress block */
 
263
        r = UCL_E_ERROR;
 
264
        out_len = 0;
 
265
        if (method == 0x2b)
 
266
            r = ucl_nrv2b_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL);
 
267
        else if (method == 0x2d)
 
268
            r = ucl_nrv2d_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL);
 
269
        else if (method == 0x2e)
 
270
            r = ucl_nrv2e_99_compress(in,in_len,out,&out_len,0,level,NULL,NULL);
 
271
        if (r == UCL_E_OUT_OF_MEMORY)
 
272
        {
 
273
            printf("%s: out of memory in compress\n", progname);
 
274
            r = 1;
 
275
            goto err;
 
276
        }
 
277
        if (r != UCL_E_OK || out_len > in_len + get_overhead(method,in_len))
 
278
        {
 
279
            /* this should NEVER happen */
 
280
            printf("internal error - compression failed: %d\n", r);
 
281
            r = 2;
 
282
            goto err;
 
283
        }
 
284
 
 
285
#if defined(WITH_TIMER)
 
286
        ucl_uclock_read(&uc, &t_stop);
 
287
        benchmark_bytes += in_len;
 
288
        benchmark_secs += ucl_uclock_get_elapsed(&uc, &t_start, &t_stop);
 
289
#endif
 
290
 
 
291
        /* write uncompressed block size */
 
292
        xwrite32(fo,in_len);
 
293
 
 
294
        if (out_len < in_len)
 
295
        {
 
296
            /* write compressed block */
 
297
            xwrite32(fo,out_len);
 
298
            xwrite(fo,out,out_len);
 
299
        }
 
300
        else
 
301
        {
 
302
            /* not compressible - write uncompressed block */
 
303
            xwrite32(fo,in_len);
 
304
            xwrite(fo,in,in_len);
 
305
        }
 
306
    }
 
307
 
 
308
    /* write EOF marker */
 
309
    xwrite32(fo,0);
 
310
 
 
311
    /* write checksum */
 
312
    if (flags & 1)
 
313
        xwrite32(fo,checksum);
 
314
 
 
315
    r = 0;
 
316
err:
 
317
    ucl_free(out);
 
318
    ucl_free(in);
 
319
    return r;
 
320
}
 
321
 
 
322
 
 
323
/*************************************************************************
 
324
// decompression benchmark
 
325
**************************************************************************/
 
326
 
 
327
#if defined(WITH_TIMER)
 
328
 
 
329
void do_decompress_benchmark(int method, unsigned long benchmark_loops,
 
330
                             const ucl_bytep in, ucl_uint in_len,
 
331
                             ucl_bytep out, ucl_uint out_len)
 
332
{
 
333
    ucl_uclock_t t_start, t_stop;
 
334
 
 
335
    ucl_uclock_read(&uc, &t_start);
 
336
    while (benchmark_loops-- > 0)
 
337
    {
 
338
        int r = -1;
 
339
        ucl_uint new_len = out_len;
 
340
 
 
341
#if 1 && defined(UCL_USE_ASM)
 
342
        /* use fast assembler versions of the decompressors - see
 
343
         * asm/i386/00README.ASM for more info */
 
344
        if (method == 0x2b)
 
345
            r = ucl_nrv2b_decompress_asm_fast_8(in,in_len,out,&new_len,NULL);
 
346
        else if (method == 0x2d)
 
347
            r = ucl_nrv2d_decompress_asm_fast_8(in,in_len,out,&new_len,NULL);
 
348
        else if (method == 0x2e)
 
349
            r = ucl_nrv2e_decompress_asm_fast_8(in,in_len,out,&new_len,NULL);
 
350
#else
 
351
        if (method == 0x2b)
 
352
            r = ucl_nrv2b_decompress_8(in,in_len,out,&new_len,NULL);
 
353
        else if (method == 0x2d)
 
354
            r = ucl_nrv2d_decompress_8(in,in_len,out,&new_len,NULL);
 
355
        else if (method == 0x2e)
 
356
            r = ucl_nrv2e_decompress_8(in,in_len,out,&new_len,NULL);
 
357
#endif
 
358
        if (r != UCL_E_OK || new_len != out_len)
 
359
        {
 
360
            printf("%s: compressed data violation: error %d (0x%x: %ld/%ld/%ld)\n", progname, r, method, (long) in_len, (long) out_len, (long) new_len);
 
361
            printf("%s: unexpected failure in benchmark -- exiting.\n", progname);
 
362
            exit(1);
 
363
        }
 
364
        benchmark_bytes += out_len;
 
365
    }
 
366
    ucl_uclock_read(&uc, &t_stop);
 
367
    benchmark_secs += ucl_uclock_get_elapsed(&uc, &t_start, &t_stop);
 
368
}
 
369
 
 
370
#endif /* WITH_TIMER */
 
371
 
 
372
 
 
373
/*************************************************************************
 
374
// decompress / test
 
375
//
 
376
// We are using in-place decompression here.
 
377
**************************************************************************/
 
378
 
 
379
int do_decompress(FILE *fi, FILE *fo, unsigned long benchmark_loops)
 
380
{
 
381
    int r = 0;
 
382
    ucl_bytep buf = NULL;
 
383
    ucl_uint buf_len;
 
384
    unsigned char m [ sizeof(magic) ];
 
385
    ucl_uint32 flags;
 
386
    int method;
 
387
    int level;
 
388
    ucl_uint block_size;
 
389
    ucl_uint32 checksum;
 
390
    ucl_uint overhead = 0;
 
391
 
 
392
    total_in = total_out = 0;
 
393
 
 
394
/*
 
395
 * Step 1: check magic header, read flags & block size, init checksum
 
396
 */
 
397
    if (xread(fi,m,sizeof(magic),1) != sizeof(magic) ||
 
398
        memcmp(m,magic,sizeof(magic)) != 0)
 
399
    {
 
400
        printf("%s: header error - this file is not compressed by uclpack\n", progname);
 
401
        r = 1;
 
402
        goto err;
 
403
    }
 
404
    flags = xread32(fi);
 
405
    method = xgetc(fi);
 
406
    level = xgetc(fi);
 
407
    block_size = xread32(fi);
 
408
    overhead = get_overhead(method, block_size);
 
409
    if (overhead == 0 || !set_method_name(method, level))
 
410
    {
 
411
        printf("%s: header error - invalid method %d (level %d)\n",
 
412
                progname, method, level);
 
413
        r = 2;
 
414
        goto err;
 
415
    }
 
416
    if (block_size < 1024 || block_size > 8*1024*1024L)
 
417
    {
 
418
        printf("%s: header error - invalid block size %ld\n",
 
419
                progname, (long) block_size);
 
420
        r = 3;
 
421
        goto err;
 
422
    }
 
423
    printf("%s: block-size is %ld bytes\n", progname, (long)block_size);
 
424
 
 
425
    checksum = ucl_adler32(0,NULL,0);
 
426
 
 
427
/*
 
428
 * Step 2: allocate buffer for in-place decompression
 
429
 */
 
430
    buf_len = block_size + overhead;
 
431
    if (benchmark_loops > 0)
 
432
    {
 
433
        /* cannot use in-place decompression when doing benchmarks */
 
434
        buf_len += block_size;
 
435
    }
 
436
    buf = (ucl_bytep) ucl_malloc(buf_len);
 
437
    if (buf == NULL)
 
438
    {
 
439
        printf("%s: out of memory\n", progname);
 
440
        r = 4;
 
441
        goto err;
 
442
    }
 
443
 
 
444
/*
 
445
 * Step 3: process blocks
 
446
 */
 
447
    for (;;)
 
448
    {
 
449
        ucl_bytep in;
 
450
        ucl_bytep out;
 
451
        ucl_uint in_len;
 
452
        ucl_uint out_len;
 
453
 
 
454
        /* read uncompressed size */
 
455
        out_len = xread32(fi);
 
456
 
 
457
        /* exit if last block (EOF marker) */
 
458
        if (out_len == 0)
 
459
            break;
 
460
 
 
461
        /* read compressed size */
 
462
        in_len = xread32(fi);
 
463
 
 
464
        /* sanity check of the size values */
 
465
        if (in_len > block_size || out_len > block_size ||
 
466
            in_len == 0 || in_len > out_len)
 
467
        {
 
468
            printf("%s: block size error - data corrupted\n", progname);
 
469
            r = 5;
 
470
            goto err;
 
471
        }
 
472
 
 
473
        /* place compressed block at the top of the buffer */
 
474
        in = buf + buf_len - in_len;
 
475
        out = buf;
 
476
 
 
477
        /* read compressed block data */
 
478
        xread(fi,in,in_len,0);
 
479
 
 
480
        if (in_len < out_len)
 
481
        {
 
482
            /* decompress - use safe decompressor as data might be corrupted */
 
483
            ucl_uint new_len = out_len;
 
484
 
 
485
            if (method == 0x2b)
 
486
            {
 
487
                if (opt_fast)
 
488
                    r = ucl_nrv2b_decompress_8(in,in_len,out,&new_len,NULL);
 
489
                else
 
490
                    r = ucl_nrv2b_decompress_safe_8(in,in_len,out,&new_len,NULL);
 
491
            }
 
492
            else if (method == 0x2d)
 
493
            {
 
494
                if (opt_fast)
 
495
                    r = ucl_nrv2d_decompress_8(in,in_len,out,&new_len,NULL);
 
496
                else
 
497
                    r = ucl_nrv2d_decompress_safe_8(in,in_len,out,&new_len,NULL);
 
498
            }
 
499
            else if (method == 0x2e)
 
500
            {
 
501
                if (opt_fast)
 
502
                    r = ucl_nrv2e_decompress_8(in,in_len,out,&new_len,NULL);
 
503
                else
 
504
                    r = ucl_nrv2e_decompress_safe_8(in,in_len,out,&new_len,NULL);
 
505
            }
 
506
            if (r != UCL_E_OK || new_len != out_len)
 
507
            {
 
508
                printf("%s: compressed data violation: error %d (0x%x: %ld/%ld/%ld)\n", progname, r, method, (long) in_len, (long) out_len, (long) new_len);
 
509
                r = 6;
 
510
                goto err;
 
511
            }
 
512
            /* write decompressed block */
 
513
            xwrite(fo,out,out_len);
 
514
            /* update checksum */
 
515
            if ((flags & 1) && !opt_fast)
 
516
                checksum = ucl_adler32(checksum,out,out_len);
 
517
#if defined(WITH_TIMER)
 
518
            if (benchmark_loops > 0)
 
519
                do_decompress_benchmark(method,benchmark_loops,in,in_len,out,out_len);
 
520
#endif
 
521
        }
 
522
        else
 
523
        {
 
524
            /* write original (incompressible) block */
 
525
            xwrite(fo,in,in_len);
 
526
            /* update checksum */
 
527
            if ((flags & 1) && !opt_fast)
 
528
                checksum = ucl_adler32(checksum,in,in_len);
 
529
        }
 
530
    }
 
531
 
 
532
    /* read and verify checksum */
 
533
    if (flags & 1)
 
534
    {
 
535
        ucl_uint32 c = xread32(fi);
 
536
        if (!opt_fast && c != checksum)
 
537
        {
 
538
            printf("%s: checksum error - data corrupted\n", progname);
 
539
            r = 7;
 
540
            goto err;
 
541
        }
 
542
    }
 
543
 
 
544
    r = 0;
 
545
err:
 
546
    ucl_free(buf);
 
547
    return r;
 
548
}
 
549
 
 
550
 
 
551
/*************************************************************************
 
552
// misc support functions
 
553
**************************************************************************/
 
554
 
 
555
static void usage(void)
 
556
{
 
557
    printf("usage:\n");
 
558
    printf("  %s [options] input-file output-file      (compress)\n", progname);
 
559
    printf("  %s -d compressed-file output-file        (decompress)\n", progname);
 
560
    printf("  %s -t compressed-file...                 (test)\n", progname);
 
561
#if defined(WITH_TIMER)
 
562
    printf("  %s -t -D1000 compressed-file...          (test decompression speed)\n", progname);
 
563
#endif
 
564
    printf("\ncompression options:\n");
 
565
    printf("  -1...-9, --10   set compression level [default is `-7']\n");
 
566
    printf("  --nrv2b         use NRV2B compression method\n");
 
567
    printf("  --nrv2d         use NRV2D compression method [default]\n");
 
568
    printf("  --nrv2e         use NRV2E compression method\n");
 
569
    printf("\nother options:\n");
 
570
    printf("  -F              do not store or verify a checksum (faster)\n");
 
571
    printf("  -Bxxxx          set block-size for compression [default 262144]\n");
 
572
#if defined(WITH_TIMER)
 
573
    printf("  -Dxxxx          number of iterations for decompression benchmark\n");
 
574
#endif
 
575
    exit(1);
 
576
}
 
577
 
 
578
 
 
579
/* open input file */
 
580
static FILE *xopen_fi(const char *name)
 
581
{
 
582
    FILE *f;
 
583
 
 
584
    f = fopen(name,"rb");
 
585
    if (f == NULL)
 
586
    {
 
587
        printf("%s: cannot open input file %s\n", progname, name);
 
588
        exit(1);
 
589
    }
 
590
#if defined(HAVE_STAT) && defined(S_ISREG)
 
591
    {
 
592
        struct stat st;
 
593
#if defined(HAVE_LSTAT)
 
594
        if (lstat(name,&st) != 0 || !S_ISREG(st.st_mode))
 
595
#else
 
596
        if (stat(name,&st) != 0 || !S_ISREG(st.st_mode))
 
597
#endif
 
598
        {
 
599
            printf("%s: %s is not a regular file\n", progname, name);
 
600
            fclose(f);
 
601
            exit(1);
 
602
        }
 
603
    }
 
604
#endif
 
605
    return f;
 
606
}
 
607
 
 
608
 
 
609
/* open output file */
 
610
static FILE *xopen_fo(const char *name)
 
611
{
 
612
    FILE *f;
 
613
 
 
614
#if 0
 
615
    /* this is an example program, so make sure we don't overwrite a file */
 
616
    f = fopen(name,"rb");
 
617
    if (f != NULL)
 
618
    {
 
619
        printf("%s: file %s already exists -- not overwritten\n", progname, name);
 
620
        fclose(f);
 
621
        exit(1);
 
622
    }
 
623
#endif
 
624
    f = fopen(name,"wb");
 
625
    if (f == NULL)
 
626
    {
 
627
        printf("%s: cannot open output file %s\n", progname, name);
 
628
        exit(1);
 
629
    }
 
630
    return f;
 
631
}
 
632
 
 
633
 
 
634
/*************************************************************************
 
635
// main
 
636
**************************************************************************/
 
637
 
 
638
int __acc_cdecl_main main(int argc, char *argv[])
 
639
{
 
640
    int i = 1;
 
641
    int r = 0;
 
642
    FILE *fi = NULL;
 
643
    FILE *fo = NULL;
 
644
    const char *in_name = NULL;
 
645
    const char *out_name = NULL;
 
646
    ucl_bool opt_decompress = 0;
 
647
    ucl_bool opt_test = 0;
 
648
    int opt_method = 0x2d;
 
649
    int opt_level = 7;
 
650
    ucl_uint opt_block_size;
 
651
    unsigned long opt_decompress_loops = 0;
 
652
    const char *s;
 
653
 
 
654
    ucl_wildargv(&argc, &argv);
 
655
#if defined(WITH_TIMER)
 
656
    ucl_uclock_open(&uc);
 
657
#endif
 
658
    progname = argv[0];
 
659
    for (s = progname; *s; s++)
 
660
        if ((*s == '/' || *s == '\\') && s[1])
 
661
            progname = s + 1;
 
662
 
 
663
    printf("\nUCL data compression library (v%s, %s).\n",
 
664
            ucl_version_string(), ucl_version_date());
 
665
    printf("Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer\n");
 
666
    printf("http://www.oberhumer.com/opensource/ucl/\n\n");
 
667
 
 
668
#if 0
 
669
    printf(
 
670
"*** WARNING ***\n"
 
671
"   This is an example program, do not use to backup your data !\n"
 
672
"\n");
 
673
#endif
 
674
 
 
675
 
 
676
/*
 
677
 * Step 1: initialize the UCL library
 
678
 */
 
679
    if (ucl_init() != UCL_E_OK)
 
680
    {
 
681
        printf("internal error - ucl_init() failed !!!\n");
 
682
        printf("(this usually indicates a compiler bug - try recompiling\nwithout optimizations, and enable `-DUCL_DEBUG' for diagnostics)\n");
 
683
        exit(1);
 
684
    }
 
685
 
 
686
 
 
687
/*
 
688
 * Step 2: setup default options
 
689
 */
 
690
    opt_block_size = 256 * 1024L;
 
691
 
 
692
#if defined(ACC_MM_AHSHIFT)
 
693
    /* reduce memory requirements for ancient 640kB DOS real-mode */
 
694
    if (ACC_MM_AHSHIFT != 3)
 
695
        opt_block_size = 16 * 1024L;
 
696
#endif
 
697
 
 
698
 
 
699
/*
 
700
 * Step 3: get options
 
701
 */
 
702
 
 
703
    while (i < argc && argv[i][0] == '-')
 
704
    {
 
705
        if (strcmp(argv[i],"-d") == 0)
 
706
            opt_decompress = 1;
 
707
        else if (strcmp(argv[i],"-t") == 0)
 
708
            opt_test = 1;
 
709
        else if (strcmp(argv[i],"-F") == 0)
 
710
            opt_fast = 1;
 
711
        else if (strcmp(argv[i],"--2b") == 0)
 
712
            opt_method = 0x2b;
 
713
        else if (strcmp(argv[i],"--nrv2b") == 0)
 
714
            opt_method = 0x2b;
 
715
        else if (strcmp(argv[i],"--2d") == 0)
 
716
            opt_method = 0x2d;
 
717
        else if (strcmp(argv[i],"--nrv2d") == 0)
 
718
            opt_method = 0x2d;
 
719
        else if (strcmp(argv[i],"--2e") == 0)
 
720
            opt_method = 0x2e;
 
721
        else if (strcmp(argv[i],"--nrv2e") == 0)
 
722
            opt_method = 0x2e;
 
723
        else if ((argv[i][1] >= '1' && argv[i][1] <= '9') && !argv[i][2])
 
724
            opt_level = argv[i][1] - '0';
 
725
        else if (strcmp(argv[i],"--10") == 0)
 
726
            opt_level = 10;
 
727
        else if (strcmp(argv[i],"--best") == 0)
 
728
            opt_level = 10;
 
729
        else if (argv[i][1] == 'b' && argv[i][2])
 
730
        {
 
731
            long x = atol(&argv[i][2]);
 
732
            if (x >= 1024L && x <= 8*1024*1024L)
 
733
                opt_block_size = (ucl_uint) x;
 
734
            else {
 
735
                printf("%s: error: invalid block-size %ld\n", progname, x);
 
736
                exit(1);
 
737
            }
 
738
        }
 
739
        else if (argv[i][1] == 'D' && argv[i][2])
 
740
        {
 
741
#if defined(WITH_TIMER)
 
742
            long x = atol(&argv[i][2]);
 
743
            if (x > 1)
 
744
                opt_decompress_loops = x;
 
745
            else {
 
746
                printf("%s: error: invalid number of benchmark loops %ld\n", progname, x);
 
747
                exit(1);
 
748
            }
 
749
#else
 
750
            usage();
 
751
#endif
 
752
        }
 
753
        else if (strcmp(argv[i],"--debug") == 0)
 
754
            opt_debug += 1;
 
755
        else
 
756
            usage();
 
757
        i++;
 
758
    }
 
759
    if (opt_test && i >= argc)
 
760
        usage();
 
761
    if (!opt_test && i + 2 != argc)
 
762
        usage();
 
763
 
 
764
 
 
765
/*
 
766
 * Step 4: process file(s)
 
767
 */
 
768
 
 
769
    if (opt_test)
 
770
    {
 
771
        while (i < argc && r == 0)
 
772
        {
 
773
            in_name = argv[i++];
 
774
            fi = xopen_fi(in_name);
 
775
#if defined(WITH_TIMER)
 
776
            benchmark_bytes = benchmark_secs = 0.0;
 
777
#endif
 
778
            r = do_decompress(fi, NULL, opt_decompress_loops);
 
779
            if (r == 0)
 
780
                printf("%s: tested ok: %-10s %-11s: %6lu -> %6lu bytes\n",
 
781
                        progname, in_name, method_name, total_in, total_out);
 
782
            fclose(fi);
 
783
            fi = NULL;
 
784
#if defined(WITH_TIMER)
 
785
            if (r == 0 && benchmark_bytes > 0)
 
786
            {
 
787
                /* speed measured in uncompressed megabytes per second */
 
788
                double mb = benchmark_bytes / (1024.0 * 1024.0);
 
789
                double mbs = 0.0;
 
790
                if (benchmark_secs >= 0.0001) mbs = mb / benchmark_secs;
 
791
                printf("\n  [benchmark] %lu loops, %.3f MB, %.3f secs, %.3f MB/s\n\n", opt_decompress_loops, mb, benchmark_secs, mbs);
 
792
            }
 
793
#endif
 
794
        }
 
795
    }
 
796
    else if (opt_decompress)
 
797
    {
 
798
        in_name = argv[i++];
 
799
        out_name = argv[i++];
 
800
        fi = xopen_fi(in_name);
 
801
        fo = xopen_fo(out_name);
 
802
        r = do_decompress(fi, fo, 0);
 
803
        if (r == 0)
 
804
            printf("%s: decompressed %lu into %lu bytes\n",
 
805
                    progname, total_in, total_out);
 
806
    }
 
807
    else /* compress */
 
808
    {
 
809
        printf("%s: using block-size of %lu bytes\n", progname, (unsigned long)opt_block_size);
 
810
        if (!set_method_name(opt_method, opt_level))
 
811
        {
 
812
            printf("%s: internal error - invalid method %d (level %d)\n",
 
813
                   progname, opt_method, opt_level);
 
814
            goto quit;
 
815
        }
 
816
        in_name = argv[i++];
 
817
        out_name = argv[i++];
 
818
        fi = xopen_fi(in_name);
 
819
        fo = xopen_fo(out_name);
 
820
        r = do_compress(fi,fo,opt_method,opt_level,opt_block_size);
 
821
        if (r == 0)
 
822
        {
 
823
            printf("%s: algorithm %s, compressed %lu into %lu bytes\n",
 
824
                    progname, method_name, total_in, total_out);
 
825
#if defined(WITH_TIMER)
 
826
            if (opt_debug >= 1 && benchmark_bytes > 0)
 
827
            {
 
828
                /* speed measured in uncompressed kilobytes per second */
 
829
                double kb = benchmark_bytes / (1024.0);
 
830
                double kbs = 0.0;
 
831
                if (benchmark_secs >= 0.0001) kbs = kb / benchmark_secs;
 
832
                printf("\n  [compression speeed] %.3f KB, %.3f secs, %.3f KB/s\n\n", kb, benchmark_secs, kbs);
 
833
            }
 
834
#endif
 
835
#if 1 && defined(WITH_TIMER)
 
836
            printf("\n  Info: To test the decompression speed on your system type:\n"
 
837
                   "    `%s -t -D1000 %s'\n", progname, out_name);
 
838
#endif
 
839
        }
 
840
    }
 
841
 
 
842
quit:
 
843
    if (fi) fclose(fi);
 
844
    if (fo) fclose(fo);
 
845
#if defined(WITH_TIMER)
 
846
    ucl_uclock_close(&uc);
 
847
#endif
 
848
    return r;
 
849
}
 
850
 
 
851
/*
 
852
vi:ts=4:et
 
853
*/
 
854