source: trunk/src/3rdparty/libmng/libmng_zlib.c

Last change on this file was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 21.6 KB
Line 
1/* ************************************************************************** */
2/* * For conditions of distribution and use, * */
3/* * see copyright notice in libmng.h * */
4/* ************************************************************************** */
5/* * * */
6/* * project : libmng * */
7/* * file : libmng_zlib.c copyright (c) 2000-2004 G.Juyn * */
8/* * version : 1.0.9 * */
9/* * * */
10/* * purpose : ZLIB library interface (implementation) * */
11/* * * */
12/* * author : G.Juyn * */
13/* * * */
14/* * comment : implementation of the ZLIB library interface * */
15/* * * */
16/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
17/* * - changed strict-ANSI stuff * */
18/* * 0.5.1 - 05/11/2000 - G.Juyn * */
19/* * - filled the deflatedata routine * */
20/* * 0.5.1 - 05/12/2000 - G.Juyn * */
21/* * - changed trace to macro for callback error-reporting * */
22/* * * */
23/* * 0.5.2 - 05/20/2000 - G.Juyn * */
24/* * - fixed for JNG alpha handling * */
25/* * 0.5.2 - 05/24/2000 - G.Juyn * */
26/* * - moved init of default zlib parms from here to * */
27/* * "mng_hlapi.c" * */
28/* * * */
29/* * 0.5.3 - 06/16/2000 - G.Juyn * */
30/* * - changed progressive-display processing * */
31/* * * */
32/* * 0.9.2 - 08/05/2000 - G.Juyn * */
33/* * - changed file-prefixes * */
34/* * * */
35/* * 0.9.3 - 08/08/2000 - G.Juyn * */
36/* * - fixed compiler-warnings from Mozilla * */
37/* * 0.9.3 - 09/07/2000 - G.Juyn * */
38/* * - added support for new filter_types * */
39/* * * */
40/* * 1.0.5 - 08/07/2002 - G.Juyn * */
41/* * - added test-option for PNG filter method 193 (=no filter) * */
42/* * 1.0.5 - 08/19/2002 - G.Juyn * */
43/* * - B597134 - libmng pollutes the linker namespace * */
44/* * 1.0.5 - 09/19/2002 - G.Juyn * */
45/* * - added warning for too much IDAT data * */
46/* * * */
47/* * 1.0.6 - 07/07/2003 - G.R-P * */
48/* * - added MNG_NO_16BIT_SUPPORT support * */
49/* * * */
50/* * 1.0.9 - 10/09/2004 - G.R-P * */
51/* * - added MNG_NO_1_2_4BIT_SUPPORT support * */
52/* * * */
53/* ************************************************************************** */
54
55#include "libmng.h"
56#include "libmng_data.h"
57#include "libmng_error.h"
58#include "libmng_trace.h"
59#ifdef __BORLANDC__
60#pragma hdrstop
61#endif
62#include "libmng_memory.h"
63#include "libmng_pixels.h"
64#include "libmng_filter.h"
65#include "libmng_zlib.h"
66
67#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
68#pragma option -A /* force ANSI-C */
69#endif
70
71/* ************************************************************************** */
72
73#ifdef MNG_INCLUDE_ZLIB
74
75/* ************************************************************************** */
76
77voidpf mngzlib_alloc (voidpf pData,
78 uInt iCount,
79 uInt iSize)
80{
81 voidpf pPtr; /* temporary space */
82
83#ifdef MNG_INTERNAL_MEMMNGMT
84 pPtr = calloc (iCount, iSize); /* local allocation */
85#else
86 if (((mng_datap)pData)->fMemalloc) /* callback function set ? */
87 pPtr = ((mng_datap)pData)->fMemalloc (iCount * iSize);
88 else
89 pPtr = Z_NULL; /* can't allocate! */
90#endif
91
92 return pPtr; /* return the result */
93}
94
95/* ************************************************************************** */
96
97void mngzlib_free (voidpf pData,
98 voidpf pAddress)
99{
100#ifdef MNG_INTERNAL_MEMMNGMT
101 free (pAddress); /* free locally */
102#else
103 if (((mng_datap)pData)->fMemfree) /* callback set? */
104 ((mng_datap)pData)->fMemfree (pAddress, 1);
105#endif
106}
107
108/* ************************************************************************** */
109
110mng_retcode mngzlib_initialize (mng_datap pData)
111{
112#ifdef MNG_SUPPORT_TRACE
113 MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_START);
114#endif
115
116#ifdef MNG_INTERNAL_MEMMNGMT
117 pData->sZlib.zalloc = Z_NULL; /* let zlib figure out memory management */
118 pData->sZlib.zfree = Z_NULL;
119 pData->sZlib.opaque = Z_NULL;
120#else /* use user-provided callbacks */
121 pData->sZlib.zalloc = mngzlib_alloc;
122 pData->sZlib.zfree = mngzlib_free;
123 pData->sZlib.opaque = (voidpf)pData;
124#endif
125
126 pData->bInflating = MNG_FALSE; /* not performing any action yet */
127 pData->bDeflating = MNG_FALSE;
128
129#ifdef MNG_SUPPORT_TRACE
130 MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_END);
131#endif
132
133 return MNG_NOERROR; /* done */
134}
135
136/* ************************************************************************** */
137
138mng_retcode mngzlib_cleanup (mng_datap pData)
139{
140#ifdef MNG_SUPPORT_TRACE
141 MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_START);
142#endif
143
144 if (pData->bInflating) /* force zlib cleanup */
145 mngzlib_inflatefree (pData);
146 if (pData->bDeflating)
147 mngzlib_deflatefree (pData);
148
149#ifdef MNG_SUPPORT_TRACE
150 MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_END);
151#endif
152
153 return MNG_NOERROR; /* done */
154}
155
156/* ************************************************************************** */
157
158mng_retcode mngzlib_inflateinit (mng_datap pData)
159{
160 int iZrslt;
161
162#ifdef MNG_SUPPORT_TRACE
163 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_START);
164#endif
165 /* initialize zlib structures and such */
166 iZrslt = inflateInit (&pData->sZlib);
167
168 if (iZrslt != Z_OK) /* on error bail out */
169 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
170
171 pData->bInflating = MNG_TRUE; /* really inflating something now */
172 pData->sZlib.next_out = 0; /* force JIT initialization */
173
174#ifdef MNG_SUPPORT_TRACE
175 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_END);
176#endif
177
178 return MNG_NOERROR; /* done */
179}
180
181/* ************************************************************************** */
182
183#ifdef MNG_SUPPORT_DISPLAY
184mng_retcode mngzlib_inflaterows (mng_datap pData,
185 mng_uint32 iInlen,
186 mng_uint8p pIndata)
187{
188 int iZrslt;
189 mng_retcode iRslt;
190 mng_ptr pSwap;
191
192#ifdef MNG_SUPPORT_TRACE
193 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_START);
194#endif
195
196 pData->sZlib.next_in = pIndata; /* let zlib know where to get stuff */
197 pData->sZlib.avail_in = (uInt)iInlen;
198
199 if (pData->sZlib.next_out == 0) /* initialize output variables ? */
200 { /* let zlib know where to store stuff */
201 pData->sZlib.next_out = pData->pWorkrow;
202 pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
203#ifdef MNG_NO_1_2_4BIT_SUPPORT
204 if (pData->iPNGdepth < 8)
205 pData->sZlib.avail_out = (uInt)((pData->iPNGdepth*pData->iRowsize + 7)/8
206 + pData->iPixelofs);
207#endif
208#ifdef MNG_NO_16BIT_SUPPORT
209 if (pData->iPNGdepth > 8)
210 pData->sZlib.avail_out = (uInt)(2*pData->iRowsize + pData->iPixelofs);
211#endif
212 }
213
214 do
215 { /* now inflate a row */
216 iZrslt = inflate (&pData->sZlib, Z_SYNC_FLUSH);
217 /* produced a full row ? */
218 if (((iZrslt == Z_OK) || (iZrslt == Z_STREAM_END)) &&
219 (pData->sZlib.avail_out == 0))
220 { /* image not completed yet ? */
221 if (pData->iRow < (mng_int32)pData->iDataheight)
222 {
223#ifdef MNG_NO_1_2_4BIT_SUPPORT
224 if (pData->iPNGdepth == 1)
225 {
226 /* Inflate Workrow to 8-bit */
227 mng_int32 iX;
228 mng_uint8p pSrc = pData->pWorkrow+1;
229 mng_uint8p pDest = pSrc + pData->iRowsize - (pData->iRowsize+7)/8;
230
231 for (iX = ((pData->iRowsize+7)/8) ; iX > 0 ; iX--)
232 *pDest++ = *pSrc++;
233
234 pDest = pData->pWorkrow+1;
235 pSrc = pDest + pData->iRowsize - (pData->iRowsize+7)/8;
236 for (iX = pData->iRowsize; ;)
237 {
238 *pDest++ = (((*pSrc)>>7)&1);
239 if (iX-- <= 0)
240 break;
241 *pDest++ = (((*pSrc)>>6)&1);
242 if (iX-- <= 0)
243 break;
244 *pDest++ = (((*pSrc)>>5)&1);
245 if (iX-- <= 0)
246 break;
247 *pDest++ = (((*pSrc)>>4)&1);
248 if (iX-- <= 0)
249 break;
250 *pDest++ = (((*pSrc)>>3)&1);
251 if (iX-- <= 0)
252 break;
253 *pDest++ = (((*pSrc)>>2)&1);
254 if (iX-- <= 0)
255 break;
256 *pDest++ = (((*pSrc)>>1)&1);
257 if (iX-- <= 0)
258 break;
259 *pDest++ = (((*pSrc) )&1);
260 if (iX-- <= 0)
261 break;
262 pSrc++;
263 }
264 }
265 else if (pData->iPNGdepth == 2)
266 {
267 /* Inflate Workrow to 8-bit */
268 mng_int32 iX;
269 mng_uint8p pSrc = pData->pWorkrow+1;
270 mng_uint8p pDest = pSrc + pData->iRowsize - (2*pData->iRowsize+7)/8;
271
272 for (iX = ((2*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
273 *pDest++ = *pSrc++;
274
275 pDest = pData->pWorkrow+1;
276 pSrc = pDest + pData->iRowsize - (2*pData->iRowsize+7)/8;
277 for (iX = pData->iRowsize; ;)
278 {
279 *pDest++ = (((*pSrc)>>6)&3);
280 if (iX-- <= 0)
281 break;
282 *pDest++ = (((*pSrc)>>4)&3);
283 if (iX-- <= 0)
284 break;
285 *pDest++ = (((*pSrc)>>2)&3);
286 if (iX-- <= 0)
287 break;
288 *pDest++ = (((*pSrc) )&3);
289 if (iX-- <= 0)
290 break;
291 pSrc++;
292 }
293 }
294 else if (pData->iPNGdepth == 4)
295 {
296 /* Inflate Workrow to 8-bit */
297 mng_int32 iX;
298 mng_uint8p pSrc = pData->pWorkrow+1;
299 mng_uint8p pDest = pSrc + pData->iRowsize - (4*pData->iRowsize+7)/8;
300
301 for (iX = ((4*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
302 *pDest++ = *pSrc++;
303
304 pDest = pData->pWorkrow+1;
305 pSrc = pDest + pData->iRowsize - (4*pData->iRowsize+7)/8;
306 for (iX = pData->iRowsize; ;)
307 {
308 *pDest++ = (((*pSrc)>>4)&0x0f);
309 if (iX-- <= 0)
310 break;
311 *pDest++ = (((*pSrc) )&0x0f);
312 if (iX-- <= 0)
313 break;
314 pSrc++;
315 }
316 }
317 if (pData->iPNGdepth < 8 && pData->iColortype == 0)
318 {
319 /* Expand samples to 8-bit by LBR */
320 mng_int32 iX;
321 mng_uint8p pSrc = pData->pWorkrow+1;
322 mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
323
324 for (iX = pData->iRowsize; iX > 0; iX--)
325 *pSrc++ *= multiplier[pData->iPNGdepth];
326 }
327#endif
328#ifdef MNG_NO_16BIT_SUPPORT
329 if (pData->iPNGdepth > 8)
330 {
331 /* Reduce Workrow to 8-bit */
332 mng_int32 iX;
333 mng_uint8p pSrc = pData->pWorkrow+1;
334 mng_uint8p pDest = pSrc;
335
336 for (iX = pData->iRowsize; iX > 0; iX--)
337 {
338 *pDest = *pSrc;
339 pDest++;
340 pSrc+=2;
341 }
342 }
343#endif
344
345#ifdef FILTER192 /* has leveling info ? */
346 if (pData->iFilterofs == MNG_FILTER_DIFFERING)
347 iRslt = init_rowdiffering (pData);
348 else
349#endif
350 iRslt = MNG_NOERROR;
351 /* filter the row if necessary */
352 if ((!iRslt) && (pData->iFilterofs < pData->iPixelofs ) &&
353 (*(pData->pWorkrow + pData->iFilterofs)) )
354 iRslt = mng_filter_a_row (pData);
355 else
356 iRslt = MNG_NOERROR;
357 /* additional leveling/differing ? */
358 if ((!iRslt) && (pData->fDifferrow))
359 {
360 iRslt = ((mng_differrow)pData->fDifferrow) (pData);
361
362 pSwap = pData->pWorkrow;
363 pData->pWorkrow = pData->pPrevrow;
364 pData->pPrevrow = pSwap; /* make sure we're processing the right data */
365 }
366
367 if (!iRslt)
368 {
369#ifdef MNG_INCLUDE_JNG
370 if (pData->bHasJHDR) /* is JNG alpha-channel ? */
371 { /* just store in object ? */
372 if ((!iRslt) && (pData->fStorerow))
373 iRslt = ((mng_storerow)pData->fStorerow) (pData);
374 }
375 else
376#endif /* MNG_INCLUDE_JNG */
377 { /* process this row */
378 if ((!iRslt) && (pData->fProcessrow))
379 iRslt = ((mng_processrow)pData->fProcessrow) (pData);
380 /* store in object ? */
381 if ((!iRslt) && (pData->fStorerow))
382 iRslt = ((mng_storerow)pData->fStorerow) (pData);
383 /* color correction ? */
384 if ((!iRslt) && (pData->fCorrectrow))
385 iRslt = ((mng_correctrow)pData->fCorrectrow) (pData);
386 /* slap onto canvas ? */
387 if ((!iRslt) && (pData->fDisplayrow))
388 {
389 iRslt = ((mng_displayrow)pData->fDisplayrow) (pData);
390
391 if (!iRslt) /* check progressive display refresh */
392 iRslt = mng_display_progressive_check (pData);
393
394 }
395 }
396 }
397
398 if (iRslt) /* on error bail out */
399 MNG_ERROR (pData, iRslt);
400
401 if (!pData->fDifferrow) /* swap row-pointers */
402 {
403 pSwap = pData->pWorkrow;
404 pData->pWorkrow = pData->pPrevrow;
405 pData->pPrevrow = pSwap; /* so prev points to the processed row! */
406 }
407
408 iRslt = mng_next_row (pData); /* adjust variables for next row */
409
410 if (iRslt) /* on error bail out */
411 MNG_ERROR (pData, iRslt);
412 }
413 /* let zlib know where to store next output */
414 pData->sZlib.next_out = pData->pWorkrow;
415 pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
416#ifdef MNG_NO_1_2_4BIT_SUPPORT
417 if (pData->iPNGdepth < 8)
418 pData->sZlib.avail_out = (uInt)((pData->iPNGdepth*pData->iRowsize + 7)/8
419 + pData->iPixelofs);
420#endif
421#ifdef MNG_NO_16BIT_SUPPORT
422 if (pData->iPNGdepth > 8)
423 pData->sZlib.avail_out = (uInt)(2*pData->iRowsize + pData->iPixelofs);
424#endif
425 }
426 } /* until some error or EOI
427 or all pixels received */
428 while ( (iZrslt == Z_OK) && (pData->sZlib.avail_in > 0) &&
429 ( (pData->iRow < (mng_int32)pData->iDataheight) ||
430 ( (pData->iPass >= 0) && (pData->iPass < 7) ) ) );
431 /* on error bail out */
432 if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
433 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
434 /* too much data ? */
435 if ((iZrslt == Z_OK) && (pData->sZlib.avail_in > 0))
436 MNG_WARNING (pData, MNG_TOOMUCHIDAT);
437
438#ifdef MNG_SUPPORT_TRACE
439 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_END);
440#endif
441
442 return MNG_NOERROR;
443}
444#endif /* MNG_SUPPORT_DISPLAY */
445
446/* ************************************************************************** */
447
448mng_retcode mngzlib_inflatedata (mng_datap pData,
449 mng_uint32 iInlen,
450 mng_uint8p pIndata)
451{
452 int iZrslt;
453
454#ifdef MNG_SUPPORT_TRACE
455 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_START);
456#endif
457 /* let zlib know where to get stuff */
458 pData->sZlib.next_in = pIndata;
459 pData->sZlib.avail_in = (uInt)iInlen;
460 /* now inflate the data in one go! */
461 iZrslt = inflate (&pData->sZlib, Z_FINISH);
462 /* not enough room in output-buffer ? */
463 if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
464 return MNG_BUFOVERFLOW;
465 /* on error bail out */
466 if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
467 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
468
469#ifdef MNG_SUPPORT_TRACE
470 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_END);
471#endif
472
473 return MNG_NOERROR;
474}
475
476/* ************************************************************************** */
477
478mng_retcode mngzlib_inflatefree (mng_datap pData)
479{
480 int iZrslt;
481
482#ifdef MNG_SUPPORT_TRACE
483 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_START);
484#endif
485
486 pData->bInflating = MNG_FALSE; /* stopped it */
487
488 iZrslt = inflateEnd (&pData->sZlib); /* let zlib cleanup its own stuff */
489
490 if (iZrslt != Z_OK) /* on error bail out */
491 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
492
493#ifdef MNG_SUPPORT_TRACE
494 MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_END);
495#endif
496
497 return MNG_NOERROR; /* done */
498}
499
500/* ************************************************************************** */
501
502mng_retcode mngzlib_deflateinit (mng_datap pData)
503{
504 int iZrslt;
505
506#ifdef MNG_SUPPORT_TRACE
507 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_START);
508#endif
509 /* initialize zlib structures and such */
510 iZrslt = deflateInit2 (&pData->sZlib, pData->iZlevel, pData->iZmethod,
511 pData->iZwindowbits, pData->iZmemlevel,
512 pData->iZstrategy);
513
514 if (iZrslt != Z_OK) /* on error bail out */
515 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
516
517 pData->bDeflating = MNG_TRUE; /* really deflating something now */
518
519#ifdef MNG_SUPPORT_TRACE
520 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_END);
521#endif
522
523 return MNG_NOERROR; /* done */
524}
525
526/* ************************************************************************** */
527
528mng_retcode mngzlib_deflaterows (mng_datap pData,
529 mng_uint32 iInlen,
530 mng_uint8p pIndata)
531{
532#ifdef MNG_SUPPORT_TRACE
533 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_START);
534#endif
535
536
537
538
539#ifdef MNG_SUPPORT_TRACE
540 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_END);
541#endif
542
543 return MNG_NOERROR;
544}
545
546/* ************************************************************************** */
547
548mng_retcode mngzlib_deflatedata (mng_datap pData,
549 mng_uint32 iInlen,
550 mng_uint8p pIndata)
551{
552 int iZrslt;
553
554#ifdef MNG_SUPPORT_TRACE
555 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_START);
556#endif
557
558 pData->sZlib.next_in = pIndata; /* let zlib know where to get stuff */
559 pData->sZlib.avail_in = (uInt)iInlen;
560 /* now deflate the data in one go! */
561 iZrslt = deflate (&pData->sZlib, Z_FINISH);
562 /* not enough room in output-buffer ? */
563 if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
564 return MNG_BUFOVERFLOW;
565 /* on error bail out */
566 if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
567 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
568
569#ifdef MNG_SUPPORT_TRACE
570 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_END);
571#endif
572
573 return MNG_NOERROR;
574}
575
576/* ************************************************************************** */
577
578mng_retcode mngzlib_deflatefree (mng_datap pData)
579{
580 int iZrslt;
581
582#ifdef MNG_SUPPORT_TRACE
583 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_START);
584#endif
585
586 iZrslt = deflateEnd (&pData->sZlib); /* let zlib cleanup its own stuff */
587
588 if (iZrslt != Z_OK) /* on error bail out */
589 MNG_ERRORZ (pData, (mng_uint32)iZrslt);
590
591 pData->bDeflating = MNG_FALSE; /* stopped it */
592
593#ifdef MNG_SUPPORT_TRACE
594 MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_END);
595#endif
596
597 return MNG_NOERROR; /* done */
598}
599
600/* ************************************************************************** */
601
602#endif /* MNG_INCLUDE_ZLIB */
603
604/* ************************************************************************** */
605/* * end of file * */
606/* ************************************************************************** */
607
Note: See TracBrowser for help on using the repository browser.