1/* zutil.c -- target dependent utility functions for the compression library
2 * Copyright (C) 1995-2002 Jean-loup Gailly.
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6/* $Id: zutil.c 14574 2005-10-29 16:27:43Z bonefish $ */
7/* @(#) $Id: zutil.c 14574 2005-10-29 16:27:43Z bonefish $ */
8
9#include "zutil.h"
10
11/* PDFlib GmbH: conflicts with Visual Studio.NET
12struct internal_state      {int dummy;}; *//* for buggy compilers */
13
14#ifndef STDC
15extern void exit OF((int));
16#endif
17
18const char *z_errmsg[10] = {
19"need dictionary",     /* Z_NEED_DICT       2  */
20"stream end",          /* Z_STREAM_END      1  */
21"",                    /* Z_OK              0  */
22"file error",          /* Z_ERRNO         (-1) */
23"stream error",        /* Z_STREAM_ERROR  (-2) */
24"data error",          /* Z_DATA_ERROR    (-3) */
25"insufficient memory", /* Z_MEM_ERROR     (-4) */
26"buffer error",        /* Z_BUF_ERROR     (-5) */
27"incompatible version",/* Z_VERSION_ERROR (-6) */
28""};
29
30
31const char * ZEXPORT zlibVersion()
32{
33    return ZLIB_VERSION;
34}
35
36#ifdef DEBUG
37
38#  ifndef verbose
39#    define verbose 0
40#  endif
41int z_verbose = verbose;
42
43void z_error (
44    char *m)
45{
46    fprintf(stderr, "%s\n", m);
47    exit(1);
48}
49#endif
50
51/* exported to allow conversion of error code to string for compress() and
52 * uncompress()
53 */
54const char * ZEXPORT zError(
55    int err)
56{
57    return ERR_MSG(err);
58}
59
60
61#ifndef HAVE_MEMCPY
62
63void zmemcpy(
64    Bytef* dest,
65    const Bytef* source,
66    uInt  len)
67{
68    if (len == 0) return;
69    do {
70        *dest++ = *source++; /* ??? to be unrolled */
71    } while (--len != 0);
72}
73
74int zmemcmp(
75    const Bytef* s1,
76    const Bytef* s2,
77    uInt  len)
78{
79    uInt j;
80
81    for (j = 0; j < len; j++) {
82        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
83    }
84    return 0;
85}
86
87void zmemzero(
88    Bytef* dest,
89    uInt  len)
90{
91    if (len == 0) return;
92    do {
93        *dest++ = 0;  /* ??? to be unrolled */
94    } while (--len != 0);
95}
96#endif
97
98#ifdef __TURBOC__
99#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
100/* Small and medium model in Turbo C are for now limited to near allocation
101 * with reduced MAX_WBITS and MAX_MEM_LEVEL
102 */
103#  define MY_ZCALLOC
104
105/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
106 * and farmalloc(64K) returns a pointer with an offset of 8, so we
107 * must fix the pointer. Warning: the pointer must be put back to its
108 * original form in order to free it, use zcfree().
109 */
110
111#define MAX_PTR 10
112/* 10*64K = 640K */
113
114local int next_ptr = 0;
115
116typedef struct ptr_table_s {
117    voidpf org_ptr;
118    voidpf new_ptr;
119} ptr_table;
120
121local ptr_table table[MAX_PTR];
122/* This table is used to remember the original form of pointers
123 * to large buffers (64K). Such pointers are normalized with a zero offset.
124 * Since MSDOS is not a preemptive multitasking OS, this table is not
125 * protected from concurrent access. This hack doesn't work anyway on
126 * a protected system like OS/2. Use Microsoft C instead.
127 */
128
129voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
130{
131    voidpf buf = opaque; /* just to make some compilers happy */
132    ulg bsize = (ulg)items*size;
133
134    /* If we allocate less than 65520 bytes, we assume that farmalloc
135     * will return a usable pointer which doesn't have to be normalized.
136     */
137    if (bsize < 65520L) {
138        buf = farmalloc(bsize);
139        if (*(ush*)&buf != 0) return buf;
140    } else {
141        buf = farmalloc(bsize + 16L);
142    }
143    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
144    table[next_ptr].org_ptr = buf;
145
146    /* Normalize the pointer to seg:0 */
147    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
148    *(ush*)&buf = 0;
149    table[next_ptr++].new_ptr = buf;
150    return buf;
151}
152
153void  zcfree (voidpf opaque, voidpf ptr)
154{
155    int n;
156    if (*(ush*)&ptr != 0) { /* object < 64K */
157        farfree(ptr);
158        return;
159    }
160    /* Find the original pointer */
161    for (n = 0; n < next_ptr; n++) {
162        if (ptr != table[n].new_ptr) continue;
163
164        farfree(table[n].org_ptr);
165        while (++n < next_ptr) {
166            table[n-1] = table[n];
167        }
168        next_ptr--;
169        return;
170    }
171    ptr = opaque; /* just to make some compilers happy */
172    Assert(0, "zcfree: ptr not found");
173}
174#endif
175#endif /* __TURBOC__ */
176
177
178#if defined(M_I86) && !defined(__32BIT__)
179/* Microsoft C in 16-bit mode */
180
181#  define MY_ZCALLOC
182
183#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
184#  define _halloc  halloc
185#  define _hfree   hfree
186#endif
187
188voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
189{
190    if (opaque) opaque = 0; /* to make compiler happy */
191    return _halloc((long)items, size);
192}
193
194void  zcfree (voidpf opaque, voidpf ptr)
195{
196    if (opaque) opaque = 0; /* to make compiler happy */
197    _hfree(ptr);
198}
199
200#endif /* MSC */
201
202
203#ifndef MY_ZCALLOC /* Any system without a special alloc function */
204
205#ifndef STDC
206extern voidp  calloc OF((uInt items, uInt size));
207extern void   free   OF((voidpf ptr));
208#endif
209
210voidpf zcalloc (
211    voidpf opaque,
212    unsigned items,
213    unsigned size)
214{
215    if (opaque) items += size - size; /* make compiler happy */
216    return (voidpf)calloc(items, size);
217}
218
219void  zcfree (
220    voidpf opaque,
221    voidpf ptr)
222{
223    free(ptr);
224    if (opaque) return; /* make compiler happy */
225}
226
227#endif /* MY_ZCALLOC */
228