1 | /* ************************************************************************** */
|
---|
2 | /* * For conditions of distribution and use, * */
|
---|
3 | /* * see copyright notice in libmng.h * */
|
---|
4 | /* ************************************************************************** */
|
---|
5 | /* * * */
|
---|
6 | /* * project : libmng * */
|
---|
7 | /* * file : libmng_read.c copyright (c) 2000-2007 G.Juyn * */
|
---|
8 | /* * version : 1.0.10 * */
|
---|
9 | /* * * */
|
---|
10 | /* * purpose : Read logic (implementation) * */
|
---|
11 | /* * * */
|
---|
12 | /* * author : G.Juyn * */
|
---|
13 | /* * * */
|
---|
14 | /* * comment : implementation of the high-level read logic * */
|
---|
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 | /* * - added callback error-reporting support * */
|
---|
20 | /* * 0.5.1 - 05/12/2000 - G.Juyn * */
|
---|
21 | /* * - changed trace to macro for callback error-reporting * */
|
---|
22 | /* * * */
|
---|
23 | /* * 0.5.2 - 05/19/2000 - G.Juyn * */
|
---|
24 | /* * - cleaned up some code regarding mixed support * */
|
---|
25 | /* * 0.5.2 - 05/20/2000 - G.Juyn * */
|
---|
26 | /* * - added support for JNG * */
|
---|
27 | /* * 0.5.2 - 05/31/2000 - G.Juyn * */
|
---|
28 | /* * - fixed up punctuation (contribution by Tim Rowley) * */
|
---|
29 | /* * * */
|
---|
30 | /* * 0.5.3 - 06/16/2000 - G.Juyn * */
|
---|
31 | /* * - changed progressive-display processing * */
|
---|
32 | /* * * */
|
---|
33 | /* * 0.9.1 - 07/08/2000 - G.Juyn * */
|
---|
34 | /* * - changed read-processing for improved I/O-suspension * */
|
---|
35 | /* * 0.9.1 - 07/14/2000 - G.Juyn * */
|
---|
36 | /* * - changed EOF processing behavior * */
|
---|
37 | /* * 0.9.1 - 07/14/2000 - G.Juyn * */
|
---|
38 | /* * - changed default readbuffer size from 1024 to 4200 * */
|
---|
39 | /* * * */
|
---|
40 | /* * 0.9.2 - 07/27/2000 - G.Juyn * */
|
---|
41 | /* * - B110320 - fixed GCC warning about mix-sized pointer math * */
|
---|
42 | /* * 0.9.2 - 07/31/2000 - G.Juyn * */
|
---|
43 | /* * - B110546 - fixed for improperly returning UNEXPECTEDEOF * */
|
---|
44 | /* * 0.9.2 - 08/04/2000 - G.Juyn * */
|
---|
45 | /* * - B111096 - fixed large-buffer read-suspension * */
|
---|
46 | /* * 0.9.2 - 08/05/2000 - G.Juyn * */
|
---|
47 | /* * - changed file-prefixes * */
|
---|
48 | /* * * */
|
---|
49 | /* * 0.9.3 - 08/26/2000 - G.Juyn * */
|
---|
50 | /* * - added MAGN chunk * */
|
---|
51 | /* * 0.9.3 - 10/11/2000 - G.Juyn * */
|
---|
52 | /* * - removed test-MaGN * */
|
---|
53 | /* * 0.9.3 - 10/16/2000 - G.Juyn * */
|
---|
54 | /* * - added support for JDAA * */
|
---|
55 | /* * * */
|
---|
56 | /* * 0.9.5 - 01/23/2001 - G.Juyn * */
|
---|
57 | /* * - fixed timing-problem with switching framing_modes * */
|
---|
58 | /* * * */
|
---|
59 | /* * 1.0.4 - 06/22/2002 - G.Juyn * */
|
---|
60 | /* * - B495443 - incorrect suspend check in read_databuffer * */
|
---|
61 | /* * * */
|
---|
62 | /* * 1.0.5 - 07/04/2002 - G.Juyn * */
|
---|
63 | /* * - added errorcode for extreme chunk-sizes * */
|
---|
64 | /* * 1.0.5 - 07/08/2002 - G.Juyn * */
|
---|
65 | /* * - B578572 - removed eMNGma hack (thanks Dimitri!) * */
|
---|
66 | /* * 1.0.5 - 07/16/2002 - G.Juyn * */
|
---|
67 | /* * - B581625 - large chunks fail with suspension reads * */
|
---|
68 | /* * 1.0.5 - 08/19/2002 - G.Juyn * */
|
---|
69 | /* * - B597134 - libmng pollutes the linker namespace * */
|
---|
70 | /* * - added HLAPI function to copy chunks * */
|
---|
71 | /* * 1.0.5 - 09/16/2002 - G.Juyn * */
|
---|
72 | /* * - added event handling for dynamic MNG * */
|
---|
73 | /* * * */
|
---|
74 | /* * 1.0.6 - 05/25/2003 - G.R-P * */
|
---|
75 | /* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */
|
---|
76 | /* * 1.0.6 - 07/07/2003 - G.R-P * */
|
---|
77 | /* * - added MNG_NO_DELTA_PNG reduction * */
|
---|
78 | /* * - skip additional code when MNG_INCLUDE_JNG is not enabled * */
|
---|
79 | /* * 1.0.6 - 07/29/2003 - G.R-P * */
|
---|
80 | /* * - added conditionals around PAST chunk support * */
|
---|
81 | /* * 1.0.6 - 08/17/2003 - G.R-P * */
|
---|
82 | /* * - added conditionals around non-VLC chunk support * */
|
---|
83 | /* * * */
|
---|
84 | /* * 1.0.7 - 03/10/2004 - G.R-P * */
|
---|
85 | /* * - added conditionals around openstream/closestream * */
|
---|
86 | /* * * */
|
---|
87 | /* * 1.0.8 - 04/08/2004 - G.Juyn * */
|
---|
88 | /* * - added CRC existence & checking flags * */
|
---|
89 | /* * 1.0.8 - 04/11/2004 - G.Juyn * */
|
---|
90 | /* * - added data-push mechanisms for specialized decoders * */
|
---|
91 | /* * 1.0.8 - 07/06/2004 - G.R-P * */
|
---|
92 | /* * - defend against using undefined closestream function * */
|
---|
93 | /* * 1.0.8 - 07/28/2004 - G.R-P * */
|
---|
94 | /* * - added check for extreme chunk-lengths * */
|
---|
95 | /* * * */
|
---|
96 | /* * 1.0.9 - 09/16/2004 - G.Juyn * */
|
---|
97 | /* * - fixed chunk pushing mechanism * */
|
---|
98 | /* * 1.0.9 - 12/05/2004 - G.Juyn * */
|
---|
99 | /* * - added conditional MNG_OPTIMIZE_CHUNKINITFREE * */
|
---|
100 | /* * 1.0.9 - 12/06/2004 - G.Juyn * */
|
---|
101 | /* * - added conditional MNG_OPTIMIZE_CHUNKASSIGN * */
|
---|
102 | /* * - added conditional MNG_OPTIMIZE_CHUNKREADER * */
|
---|
103 | /* * 1.0.9 - 12/20/2004 - G.Juyn * */
|
---|
104 | /* * - cleaned up macro-invocations (thanks to D. Airlie) * */
|
---|
105 | /* * 1.0.9 - 12/31/2004 - G.R-P * */
|
---|
106 | /* * - removed stray characters from #ifdef directive * */
|
---|
107 | /* * * */
|
---|
108 | /* * 1.0.10 - 04/08/2007 - G.Juyn * */
|
---|
109 | /* * - added support for mPNG proposal * */
|
---|
110 | /* * * */
|
---|
111 | /* ************************************************************************** */
|
---|
112 |
|
---|
113 | #include "libmng.h"
|
---|
114 | #include "libmng_data.h"
|
---|
115 | #include "libmng_error.h"
|
---|
116 | #include "libmng_trace.h"
|
---|
117 | #ifdef __BORLANDC__
|
---|
118 | #pragma hdrstop
|
---|
119 | #endif
|
---|
120 | #include "libmng_memory.h"
|
---|
121 | #include "libmng_objects.h"
|
---|
122 | #include "libmng_object_prc.h"
|
---|
123 | #include "libmng_chunks.h"
|
---|
124 | #ifdef MNG_OPTIMIZE_CHUNKREADER
|
---|
125 | #include "libmng_chunk_descr.h"
|
---|
126 | #endif
|
---|
127 | #include "libmng_chunk_prc.h"
|
---|
128 | #include "libmng_chunk_io.h"
|
---|
129 | #include "libmng_display.h"
|
---|
130 | #include "libmng_read.h"
|
---|
131 |
|
---|
132 | #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
|
---|
133 | #pragma option -A /* force ANSI-C */
|
---|
134 | #endif
|
---|
135 |
|
---|
136 | /* ************************************************************************** */
|
---|
137 |
|
---|
138 | #ifdef MNG_INCLUDE_READ_PROCS
|
---|
139 |
|
---|
140 | /* ************************************************************************** */
|
---|
141 |
|
---|
142 | mng_retcode mng_process_eof (mng_datap pData)
|
---|
143 | {
|
---|
144 | if (!pData->bEOF) /* haven't closed the stream yet ? */
|
---|
145 | {
|
---|
146 | pData->bEOF = MNG_TRUE; /* now we do! */
|
---|
147 |
|
---|
148 | #ifndef MNG_NO_OPEN_CLOSE_STREAM
|
---|
149 | if (pData->fClosestream && !pData->fClosestream ((mng_handle)pData))
|
---|
150 | {
|
---|
151 | MNG_ERROR (pData, MNG_APPIOERROR);
|
---|
152 | }
|
---|
153 | #endif
|
---|
154 | }
|
---|
155 |
|
---|
156 | return MNG_NOERROR;
|
---|
157 | }
|
---|
158 |
|
---|
159 | /* ************************************************************************** */
|
---|
160 |
|
---|
161 | mng_retcode mng_release_pushdata (mng_datap pData)
|
---|
162 | {
|
---|
163 | mng_pushdatap pFirst = pData->pFirstpushdata;
|
---|
164 | mng_pushdatap pNext = pFirst->pNext;
|
---|
165 |
|
---|
166 | #ifdef MNG_SUPPORT_TRACE
|
---|
167 | MNG_TRACE (pData, MNG_FN_RELEASE_PUSHDATA, MNG_LC_START);
|
---|
168 | #endif
|
---|
169 |
|
---|
170 | pData->pFirstpushdata = pNext; /* next becomes the first */
|
---|
171 |
|
---|
172 | if (!pNext) /* no next? => no last! */
|
---|
173 | pData->pLastpushdata = MNG_NULL;
|
---|
174 | /* buffer owned and release callback defined? */
|
---|
175 | if ((pFirst->bOwned) && (pData->fReleasedata))
|
---|
176 | pData->fReleasedata ((mng_handle)pData, pFirst->pData, pFirst->iLength);
|
---|
177 | else /* otherwise use internal free mechanism */
|
---|
178 | MNG_FREEX (pData, pFirst->pData, pFirst->iLength);
|
---|
179 | /* and free it */
|
---|
180 | MNG_FREEX (pData, pFirst, sizeof(mng_pushdata));
|
---|
181 |
|
---|
182 | #ifdef MNG_SUPPORT_TRACE
|
---|
183 | MNG_TRACE (pData, MNG_FN_RELEASE_PUSHDATA, MNG_LC_END);
|
---|
184 | #endif
|
---|
185 |
|
---|
186 | return MNG_NOERROR;
|
---|
187 | }
|
---|
188 |
|
---|
189 | /* ************************************************************************** */
|
---|
190 |
|
---|
191 | mng_retcode mng_release_pushchunk (mng_datap pData)
|
---|
192 | {
|
---|
193 | mng_pushdatap pFirst = pData->pFirstpushchunk;
|
---|
194 | mng_pushdatap pNext = pFirst->pNext;
|
---|
195 |
|
---|
196 | #ifdef MNG_SUPPORT_TRACE
|
---|
197 | MNG_TRACE (pData, MNG_FN_RELEASE_PUSHCHUNK, MNG_LC_START);
|
---|
198 | #endif
|
---|
199 |
|
---|
200 | pData->pFirstpushchunk = pNext; /* next becomes the first */
|
---|
201 |
|
---|
202 | if (!pNext) /* no next? => no last! */
|
---|
203 | pData->pLastpushchunk = MNG_NULL;
|
---|
204 | /* buffer owned and release callback defined? */
|
---|
205 | if ((pFirst->bOwned) && (pData->fReleasedata))
|
---|
206 | pData->fReleasedata ((mng_handle)pData, pFirst->pData, pFirst->iLength);
|
---|
207 | else /* otherwise use internal free mechanism */
|
---|
208 | MNG_FREEX (pData, pFirst->pData, pFirst->iLength);
|
---|
209 | /* and free it */
|
---|
210 | MNG_FREEX (pData, pFirst, sizeof(mng_pushdata));
|
---|
211 |
|
---|
212 | #ifdef MNG_SUPPORT_TRACE
|
---|
213 | MNG_TRACE (pData, MNG_FN_RELEASE_PUSHCHUNK, MNG_LC_END);
|
---|
214 | #endif
|
---|
215 |
|
---|
216 | return MNG_NOERROR;
|
---|
217 | }
|
---|
218 |
|
---|
219 | /* ************************************************************************** */
|
---|
220 |
|
---|
221 | MNG_LOCAL mng_retcode read_data (mng_datap pData,
|
---|
222 | mng_uint8p pBuf,
|
---|
223 | mng_uint32 iSize,
|
---|
224 | mng_uint32 * iRead)
|
---|
225 | {
|
---|
226 | mng_retcode iRetcode;
|
---|
227 | mng_uint32 iTempsize = iSize;
|
---|
228 | mng_uint8p pTempbuf = pBuf;
|
---|
229 | mng_pushdatap pPush = pData->pFirstpushdata;
|
---|
230 | mng_uint32 iPushsize = 0;
|
---|
231 | *iRead = 0; /* nothing yet */
|
---|
232 |
|
---|
233 | #ifdef MNG_SUPPORT_TRACE
|
---|
234 | MNG_TRACE (pData, MNG_FN_READ_DATA, MNG_LC_START);
|
---|
235 | #endif
|
---|
236 |
|
---|
237 | while (pPush) /* calculate size of pushed data */
|
---|
238 | {
|
---|
239 | iPushsize += pPush->iRemaining;
|
---|
240 | pPush = pPush->pNext;
|
---|
241 | }
|
---|
242 |
|
---|
243 | if (iTempsize <= iPushsize) /* got enough push data? */
|
---|
244 | {
|
---|
245 | while (iTempsize)
|
---|
246 | {
|
---|
247 | pPush = pData->pFirstpushdata;
|
---|
248 | /* enough data remaining in this buffer? */
|
---|
249 | if (pPush->iRemaining <= iTempsize)
|
---|
250 | { /* no: then copy what we've got */
|
---|
251 | MNG_COPY (pTempbuf, pPush->pDatanext, pPush->iRemaining);
|
---|
252 | /* move pointers & lengths */
|
---|
253 | pTempbuf += pPush->iRemaining;
|
---|
254 | *iRead += pPush->iRemaining;
|
---|
255 | iTempsize -= pPush->iRemaining;
|
---|
256 | /* release the depleted buffer */
|
---|
257 | iRetcode = mng_release_pushdata (pData);
|
---|
258 | if (iRetcode)
|
---|
259 | return iRetcode;
|
---|
260 | }
|
---|
261 | else
|
---|
262 | { /* copy the needed bytes */
|
---|
263 | MNG_COPY (pTempbuf, pPush->pDatanext, iTempsize);
|
---|
264 | /* move pointers & lengths */
|
---|
265 | pPush->iRemaining -= iTempsize;
|
---|
266 | pPush->pDatanext += iTempsize;
|
---|
267 | pTempbuf += iTempsize;
|
---|
268 | *iRead += iTempsize;
|
---|
269 | iTempsize = 0; /* all done!!! */
|
---|
270 | }
|
---|
271 | }
|
---|
272 | }
|
---|
273 | else
|
---|
274 | {
|
---|
275 | mng_uint32 iTempread = 0;
|
---|
276 | /* get it from the app then */
|
---|
277 | if (!pData->fReaddata (((mng_handle)pData), pTempbuf, iTempsize, &iTempread))
|
---|
278 | MNG_ERROR (pData, MNG_APPIOERROR);
|
---|
279 |
|
---|
280 | *iRead += iTempread;
|
---|
281 | }
|
---|
282 |
|
---|
283 | #ifdef MNG_SUPPORT_TRACE
|
---|
284 | MNG_TRACE (pData, MNG_FN_READ_DATA, MNG_LC_END);
|
---|
285 | #endif
|
---|
286 |
|
---|
287 | return MNG_NOERROR;
|
---|
288 | }
|
---|
289 |
|
---|
290 | /* ************************************************************************** */
|
---|
291 |
|
---|
292 | MNG_LOCAL mng_retcode read_databuffer (mng_datap pData,
|
---|
293 | mng_uint8p pBuf,
|
---|
294 | mng_uint8p * pBufnext,
|
---|
295 | mng_uint32 iSize,
|
---|
296 | mng_uint32 * iRead)
|
---|
297 | {
|
---|
298 | mng_retcode iRetcode;
|
---|
299 |
|
---|
300 | #ifdef MNG_SUPPORT_TRACE
|
---|
301 | MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_START);
|
---|
302 | #endif
|
---|
303 |
|
---|
304 | if (pData->bSuspensionmode)
|
---|
305 | {
|
---|
306 | mng_uint8p pTemp;
|
---|
307 | mng_uint32 iTemp;
|
---|
308 |
|
---|
309 | *iRead = 0; /* let's be negative about the outcome */
|
---|
310 |
|
---|
311 | if (!pData->pSuspendbuf) /* need to create a suspension buffer ? */
|
---|
312 | {
|
---|
313 | pData->iSuspendbufsize = MNG_SUSPENDBUFFERSIZE;
|
---|
314 | /* so, create it */
|
---|
315 | MNG_ALLOC (pData, pData->pSuspendbuf, pData->iSuspendbufsize);
|
---|
316 |
|
---|
317 | pData->iSuspendbufleft = 0; /* make sure to fill it first time */
|
---|
318 | pData->pSuspendbufnext = pData->pSuspendbuf;
|
---|
319 | }
|
---|
320 | /* more than our buffer can hold ? */
|
---|
321 | if (iSize > pData->iSuspendbufsize)
|
---|
322 | {
|
---|
323 | mng_uint32 iRemain;
|
---|
324 |
|
---|
325 | if (!*pBufnext) /* first time ? */
|
---|
326 | {
|
---|
327 | if (pData->iSuspendbufleft) /* do we have some data left ? */
|
---|
328 | { /* then copy it */
|
---|
329 | MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
|
---|
330 | /* fixup variables */
|
---|
331 | *pBufnext = pBuf + pData->iSuspendbufleft;
|
---|
332 | pData->pSuspendbufnext = pData->pSuspendbuf;
|
---|
333 | pData->iSuspendbufleft = 0;
|
---|
334 | }
|
---|
335 | else
|
---|
336 | {
|
---|
337 | *pBufnext = pBuf;
|
---|
338 | }
|
---|
339 | }
|
---|
340 | /* calculate how much to get */
|
---|
341 | iRemain = iSize - (mng_uint32)(*pBufnext - pBuf);
|
---|
342 | /* let's go get it */
|
---|
343 | iRetcode = read_data (pData, *pBufnext, iRemain, &iTemp);
|
---|
344 | if (iRetcode)
|
---|
345 | return iRetcode;
|
---|
346 | /* first read after suspension return 0 means EOF */
|
---|
347 | if ((pData->iSuspendpoint) && (iTemp == 0))
|
---|
348 | { /* that makes it final */
|
---|
349 | mng_retcode iRetcode = mng_process_eof (pData);
|
---|
350 | if (iRetcode) /* on error bail out */
|
---|
351 | return iRetcode;
|
---|
352 | /* indicate the source is depleted */
|
---|
353 | *iRead = iSize - iRemain + iTemp;
|
---|
354 | }
|
---|
355 | else
|
---|
356 | {
|
---|
357 | if (iTemp < iRemain) /* suspension required ? */
|
---|
358 | {
|
---|
359 | *pBufnext = *pBufnext + iTemp;
|
---|
360 | pData->bSuspended = MNG_TRUE;
|
---|
361 | }
|
---|
362 | else
|
---|
363 | {
|
---|
364 | *iRead = iSize; /* got it all now ! */
|
---|
365 | }
|
---|
366 | }
|
---|
367 | }
|
---|
368 | else
|
---|
369 | { /* need to read some more ? */
|
---|
370 | while ((!pData->bSuspended) && (!pData->bEOF) && (iSize > pData->iSuspendbufleft))
|
---|
371 | { /* not enough space left in buffer ? */
|
---|
372 | if (pData->iSuspendbufsize - pData->iSuspendbufleft -
|
---|
373 | (mng_uint32)(pData->pSuspendbufnext - pData->pSuspendbuf) <
|
---|
374 | MNG_SUSPENDREQUESTSIZE)
|
---|
375 | {
|
---|
376 | if (pData->iSuspendbufleft) /* then lets shift (if there's anything left) */
|
---|
377 | MNG_COPY (pData->pSuspendbuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
|
---|
378 | /* adjust running pointer */
|
---|
379 | pData->pSuspendbufnext = pData->pSuspendbuf;
|
---|
380 | }
|
---|
381 | /* still not enough room ? */
|
---|
382 | if (pData->iSuspendbufsize - pData->iSuspendbufleft < MNG_SUSPENDREQUESTSIZE)
|
---|
383 | MNG_ERROR (pData, MNG_INTERNALERROR);
|
---|
384 | /* now read some more data */
|
---|
385 | pTemp = pData->pSuspendbufnext + pData->iSuspendbufleft;
|
---|
386 |
|
---|
387 | iRetcode = read_data (pData, pTemp, MNG_SUSPENDREQUESTSIZE, &iTemp);
|
---|
388 | if (iRetcode)
|
---|
389 | return iRetcode;
|
---|
390 | /* adjust fill-counter */
|
---|
391 | pData->iSuspendbufleft += iTemp;
|
---|
392 | /* first read after suspension returning 0 means EOF */
|
---|
393 | if ((pData->iSuspendpoint) && (iTemp == 0))
|
---|
394 | { /* that makes it final */
|
---|
395 | mng_retcode iRetcode = mng_process_eof (pData);
|
---|
396 | if (iRetcode) /* on error bail out */
|
---|
397 | return iRetcode;
|
---|
398 |
|
---|
399 | if (pData->iSuspendbufleft) /* return the leftover scraps */
|
---|
400 | MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft);
|
---|
401 | /* and indicate so */
|
---|
402 | *iRead = pData->iSuspendbufleft;
|
---|
403 | pData->pSuspendbufnext = pData->pSuspendbuf;
|
---|
404 | pData->iSuspendbufleft = 0;
|
---|
405 | }
|
---|
406 | else
|
---|
407 | { /* suspension required ? */
|
---|
408 | if ((iSize > pData->iSuspendbufleft) && (iTemp < MNG_SUSPENDREQUESTSIZE))
|
---|
409 | pData->bSuspended = MNG_TRUE;
|
---|
410 |
|
---|
411 | }
|
---|
412 |
|
---|
413 | pData->iSuspendpoint = 0; /* reset it here in case we loop back */
|
---|
414 | }
|
---|
415 |
|
---|
416 | if ((!pData->bSuspended) && (!pData->bEOF))
|
---|
417 | { /* return the data ! */
|
---|
418 | MNG_COPY (pBuf, pData->pSuspendbufnext, iSize);
|
---|
419 |
|
---|
420 | *iRead = iSize; /* returned it all */
|
---|
421 | /* adjust suspension-buffer variables */
|
---|
422 | pData->pSuspendbufnext += iSize;
|
---|
423 | pData->iSuspendbufleft -= iSize;
|
---|
424 | }
|
---|
425 | }
|
---|
426 | }
|
---|
427 | else
|
---|
428 | {
|
---|
429 | iRetcode = read_data (pData, (mng_ptr)pBuf, iSize, iRead);
|
---|
430 | if (iRetcode)
|
---|
431 | return iRetcode;
|
---|
432 | if (*iRead == 0) /* suspension required ? */
|
---|
433 | pData->bSuspended = MNG_TRUE;
|
---|
434 | }
|
---|
435 |
|
---|
436 | pData->iSuspendpoint = 0; /* safely reset it here ! */
|
---|
437 |
|
---|
438 | #ifdef MNG_SUPPORT_TRACE
|
---|
439 | MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_END);
|
---|
440 | #endif
|
---|
441 |
|
---|
442 | return MNG_NOERROR;
|
---|
443 | }
|
---|
444 |
|
---|
445 | /* ************************************************************************** */
|
---|
446 |
|
---|
447 | MNG_LOCAL mng_retcode process_raw_chunk (mng_datap pData,
|
---|
448 | mng_uint8p pBuf,
|
---|
449 | mng_uint32 iBuflen)
|
---|
450 | {
|
---|
451 |
|
---|
452 | #ifndef MNG_OPTIMIZE_CHUNKREADER
|
---|
453 | /* the table-idea & binary search code was adapted from
|
---|
454 | libpng 1.1.0 (pngread.c) */
|
---|
455 | /* NOTE1: the table must remain sorted by chunkname, otherwise the binary
|
---|
456 | search will break !!! (ps. watch upper-/lower-case chunknames !!) */
|
---|
457 | /* NOTE2: the layout must remain equal to the header part of all the
|
---|
458 | chunk-structures (yes, that means even the pNext and pPrev fields;
|
---|
459 | it's wasting a bit of space, but hey, the code is a lot easier) */
|
---|
460 |
|
---|
461 | #ifdef MNG_OPTIMIZE_CHUNKINITFREE
|
---|
462 | mng_chunk_header mng_chunk_unknown = {MNG_UINT_HUH, mng_init_general, mng_free_unknown,
|
---|
463 | mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0, sizeof(mng_unknown_chunk)};
|
---|
464 | #else
|
---|
465 | mng_chunk_header mng_chunk_unknown = {MNG_UINT_HUH, mng_init_unknown, mng_free_unknown,
|
---|
466 | mng_read_unknown, mng_write_unknown, mng_assign_unknown, 0, 0};
|
---|
467 | #endif
|
---|
468 |
|
---|
469 | #ifdef MNG_OPTIMIZE_CHUNKINITFREE
|
---|
470 |
|
---|
471 | mng_chunk_header mng_chunk_table [] =
|
---|
472 | {
|
---|
473 | #ifndef MNG_SKIPCHUNK_BACK
|
---|
474 | {MNG_UINT_BACK, mng_init_general, mng_free_general, mng_read_back, mng_write_back, mng_assign_general, 0, 0, sizeof(mng_back)},
|
---|
475 | #endif
|
---|
476 | #ifndef MNG_SKIPCHUNK_BASI
|
---|
477 | {MNG_UINT_BASI, mng_init_general, mng_free_general, mng_read_basi, mng_write_basi, mng_assign_general, 0, 0, sizeof(mng_basi)},
|
---|
478 | #endif
|
---|
479 | #ifndef MNG_SKIPCHUNK_CLIP
|
---|
480 | {MNG_UINT_CLIP, mng_init_general, mng_free_general, mng_read_clip, mng_write_clip, mng_assign_general, 0, 0, sizeof(mng_clip)},
|
---|
481 | #endif
|
---|
482 | #ifndef MNG_SKIPCHUNK_CLON
|
---|
483 | {MNG_UINT_CLON, mng_init_general, mng_free_general, mng_read_clon, mng_write_clon, mng_assign_general, 0, 0, sizeof(mng_clon)},
|
---|
484 | #endif
|
---|
485 | #ifndef MNG_NO_DELTA_PNG
|
---|
486 | #ifndef MNG_SKIPCHUNK_DBYK
|
---|
487 | {MNG_UINT_DBYK, mng_init_general, mng_free_dbyk, mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk, 0, 0, sizeof(mng_dbyk)},
|
---|
488 | #endif
|
---|
489 | #endif
|
---|
490 | #ifndef MNG_SKIPCHUNK_DEFI
|
---|
491 | {MNG_UINT_DEFI, mng_init_general, mng_free_general, mng_read_defi, mng_write_defi, mng_assign_general, 0, 0, sizeof(mng_defi)},
|
---|
492 | #endif
|
---|
493 | #ifndef MNG_NO_DELTA_PNG
|
---|
494 | {MNG_UINT_DHDR, mng_init_general, mng_free_general, mng_read_dhdr, mng_write_dhdr, mng_assign_general, 0, 0, sizeof(mng_dhdr)},
|
---|
495 | #endif
|
---|
496 | #ifndef MNG_SKIPCHUNK_DISC
|
---|
497 | {MNG_UINT_DISC, mng_init_general, mng_free_disc, mng_read_disc, mng_write_disc, mng_assign_disc, 0, 0, sizeof(mng_disc)},
|
---|
498 | #endif
|
---|
499 | #ifndef MNG_NO_DELTA_PNG
|
---|
500 | #ifndef MNG_SKIPCHUNK_DROP
|
---|
501 | {MNG_UINT_DROP, mng_init_general, mng_free_drop, mng_read_drop, mng_write_drop, mng_assign_drop, 0, 0, sizeof(mng_drop)},
|
---|
502 | #endif
|
---|
503 | #endif
|
---|
504 | #ifndef MNG_SKIPCHUNK_LOOP
|
---|
505 | {MNG_UINT_ENDL, mng_init_general, mng_free_general, mng_read_endl, mng_write_endl, mng_assign_general, 0, 0, sizeof(mng_endl)},
|
---|
506 | #endif
|
---|
507 | #ifndef MNG_SKIPCHUNK_FRAM
|
---|
508 | {MNG_UINT_FRAM, mng_init_general, mng_free_fram, mng_read_fram, mng_write_fram, mng_assign_fram, 0, 0, sizeof(mng_fram)},
|
---|
509 | #endif
|
---|
510 | {MNG_UINT_IDAT, mng_init_general, mng_free_idat, mng_read_idat, mng_write_idat, mng_assign_idat, 0, 0, sizeof(mng_idat)}, /* 12-th element! */
|
---|
511 | {MNG_UINT_IEND, mng_init_general, mng_free_general, mng_read_iend, mng_write_iend, mng_assign_general, 0, 0, sizeof(mng_iend)},
|
---|
512 | {MNG_UINT_IHDR, mng_init_general, mng_free_general, mng_read_ihdr, mng_write_ihdr, mng_assign_general, 0, 0, sizeof(mng_ihdr)},
|
---|
513 | #ifndef MNG_NO_DELTA_PNG
|
---|
514 | #ifdef MNG_INCLUDE_JNG
|
---|
515 | {MNG_UINT_IJNG, mng_init_general, mng_free_general, mng_read_ijng, mng_write_ijng, mng_assign_general, 0, 0, sizeof(mng_ijng)},
|
---|
516 | #endif
|
---|
517 | {MNG_UINT_IPNG, mng_init_general, mng_free_general, mng_read_ipng, mng_write_ipng, mng_assign_general, 0, 0, sizeof(mng_ipng)},
|
---|
518 | #endif
|
---|
519 | #ifdef MNG_INCLUDE_JNG
|
---|
520 | {MNG_UINT_JDAA, mng_init_general, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0, sizeof(mng_jdaa)},
|
---|
521 | {MNG_UINT_JDAT, mng_init_general, mng_free_jdat, mng_read_jdat, mng_write_jdat, mng_assign_jdat, 0, 0, sizeof(mng_jdat)},
|
---|
522 | {MNG_UINT_JHDR, mng_init_general, mng_free_general, mng_read_jhdr, mng_write_jhdr, mng_assign_general, 0, 0, sizeof(mng_jhdr)},
|
---|
523 | {MNG_UINT_JSEP, mng_init_general, mng_free_general, mng_read_jsep, mng_write_jsep, mng_assign_general, 0, 0, sizeof(mng_jsep)},
|
---|
524 | {MNG_UINT_JdAA, mng_init_general, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0, sizeof(mng_jdaa)},
|
---|
525 | #endif
|
---|
526 | #ifndef MNG_SKIPCHUNK_LOOP
|
---|
527 | {MNG_UINT_LOOP, mng_init_general, mng_free_loop, mng_read_loop, mng_write_loop, mng_assign_loop, 0, 0, sizeof(mng_loop)},
|
---|
528 | #endif
|
---|
529 | #ifndef MNG_SKIPCHUNK_MAGN
|
---|
530 | {MNG_UINT_MAGN, mng_init_general, mng_free_general, mng_read_magn, mng_write_magn, mng_assign_general, 0, 0, sizeof(mng_magn)},
|
---|
531 | #endif
|
---|
532 | {MNG_UINT_MEND, mng_init_general, mng_free_general, mng_read_mend, mng_write_mend, mng_assign_general, 0, 0, sizeof(mng_mend)},
|
---|
533 | {MNG_UINT_MHDR, mng_init_general, mng_free_general, mng_read_mhdr, mng_write_mhdr, mng_assign_general, 0, 0, sizeof(mng_mhdr)},
|
---|
534 | #ifndef MNG_SKIPCHUNK_MOVE
|
---|
535 | {MNG_UINT_MOVE, mng_init_general, mng_free_general, mng_read_move, mng_write_move, mng_assign_general, 0, 0, sizeof(mng_move)},
|
---|
536 | #endif
|
---|
537 | #ifndef MNG_NO_DELTA_PNG
|
---|
538 | #ifndef MNG_SKIPCHUNK_ORDR
|
---|
539 | {MNG_UINT_ORDR, mng_init_general, mng_free_ordr, mng_read_ordr, mng_write_ordr, mng_assign_ordr, 0, 0, sizeof(mng_ordr)},
|
---|
540 | #endif
|
---|
541 | #endif
|
---|
542 | #ifndef MNG_SKIPCHUNK_PAST
|
---|
543 | {MNG_UINT_PAST, mng_init_general, mng_free_past, mng_read_past, mng_write_past, mng_assign_past, 0, 0, sizeof(mng_past)},
|
---|
544 | #endif
|
---|
545 | {MNG_UINT_PLTE, mng_init_general, mng_free_general, mng_read_plte, mng_write_plte, mng_assign_general, 0, 0, sizeof(mng_plte)},
|
---|
546 | #ifndef MNG_NO_DELTA_PNG
|
---|
547 | {MNG_UINT_PPLT, mng_init_general, mng_free_general, mng_read_pplt, mng_write_pplt, mng_assign_general, 0, 0, sizeof(mng_pplt)},
|
---|
548 | {MNG_UINT_PROM, mng_init_general, mng_free_general, mng_read_prom, mng_write_prom, mng_assign_general, 0, 0, sizeof(mng_prom)},
|
---|
549 | #endif
|
---|
550 | #ifndef MNG_SKIPCHUNK_SAVE
|
---|
551 | {MNG_UINT_SAVE, mng_init_general, mng_free_save, mng_read_save, mng_write_save, mng_assign_save, 0, 0, sizeof(mng_save)},
|
---|
552 | #endif
|
---|
553 | #ifndef MNG_SKIPCHUNK_SEEK
|
---|
554 | {MNG_UINT_SEEK, mng_init_general, mng_free_seek, mng_read_seek, mng_write_seek, mng_assign_seek, 0, 0, sizeof(mng_seek)},
|
---|
555 | #endif
|
---|
556 | #ifndef MNG_SKIPCHUNK_SHOW
|
---|
557 | {MNG_UINT_SHOW, mng_init_general, mng_free_general, mng_read_show, mng_write_show, mng_assign_general, 0, 0, sizeof(mng_show)},
|
---|
558 | #endif
|
---|
559 | #ifndef MNG_SKIPCHUNK_TERM
|
---|
560 | {MNG_UINT_TERM, mng_init_general, mng_free_general, mng_read_term, mng_write_term, mng_assign_general, 0, 0, sizeof(mng_term)},
|
---|
561 | #endif
|
---|
562 | #ifndef MNG_SKIPCHUNK_bKGD
|
---|
563 | {MNG_UINT_bKGD, mng_init_general, mng_free_general, mng_read_bkgd, mng_write_bkgd, mng_assign_general, 0, 0, sizeof(mng_bkgd)},
|
---|
564 | #endif
|
---|
565 | #ifndef MNG_SKIPCHUNK_cHRM
|
---|
566 | {MNG_UINT_cHRM, mng_init_general, mng_free_general, mng_read_chrm, mng_write_chrm, mng_assign_general, 0, 0, sizeof(mng_chrm)},
|
---|
567 | #endif
|
---|
568 | #ifndef MNG_SKIPCHUNK_eXPI
|
---|
569 | {MNG_UINT_eXPI, mng_init_general, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_expi, 0, 0, sizeof(mng_expi)},
|
---|
570 | #endif
|
---|
571 | #ifndef MNG_SKIPCHUNK_evNT
|
---|
572 | {MNG_UINT_evNT, mng_init_general, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0, sizeof(mng_evnt)},
|
---|
573 | #endif
|
---|
574 | #ifndef MNG_SKIPCHUNK_fPRI
|
---|
575 | {MNG_UINT_fPRI, mng_init_general, mng_free_general, mng_read_fpri, mng_write_fpri, mng_assign_general, 0, 0, sizeof(mng_fpri)},
|
---|
576 | #endif
|
---|
577 | #ifndef MNG_SKIPCHUNK_gAMA
|
---|
578 | {MNG_UINT_gAMA, mng_init_general, mng_free_general, mng_read_gama, mng_write_gama, mng_assign_general, 0, 0, sizeof(mng_gama)},
|
---|
579 | #endif
|
---|
580 | #ifndef MNG_SKIPCHUNK_hIST
|
---|
581 | {MNG_UINT_hIST, mng_init_general, mng_free_general, mng_read_hist, mng_write_hist, mng_assign_general, 0, 0, sizeof(mng_hist)},
|
---|
582 | #endif
|
---|
583 | #ifndef MNG_SKIPCHUNK_iCCP
|
---|
584 | {MNG_UINT_iCCP, mng_init_general, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0, sizeof(mng_iccp)},
|
---|
585 | #endif
|
---|
586 | #ifndef MNG_SKIPCHUNK_iTXt
|
---|
587 | {MNG_UINT_iTXt, mng_init_general, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0, sizeof(mng_itxt)},
|
---|
588 | #endif
|
---|
589 | #ifdef MNG_INCLUDE_MPNG_PROPOSAL
|
---|
590 | {MNG_UINT_mpNG, mng_init_general, mng_free_mpng, mng_read_mpng, mng_write_mpng, mng_assign_mpng, 0, 0, sizeof(mng_mpng)},
|
---|
591 | #endif
|
---|
592 | #ifndef MNG_SKIPCHUNK_nEED
|
---|
593 | {MNG_UINT_nEED, mng_init_general, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0, sizeof(mng_need)},
|
---|
594 | #endif
|
---|
595 | /* TODO: {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0}, */
|
---|
596 | /* TODO: {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0}, */
|
---|
597 | #ifndef MNG_SKIPCHUNK_pHYg
|
---|
598 | {MNG_UINT_pHYg, mng_init_general, mng_free_general, mng_read_phyg, mng_write_phyg, mng_assign_general, 0, 0, sizeof(mng_phyg)},
|
---|
599 | #endif
|
---|
600 | #ifndef MNG_SKIPCHUNK_pHYs
|
---|
601 | {MNG_UINT_pHYs, mng_init_general, mng_free_general, mng_read_phys, mng_write_phys, mng_assign_general, 0, 0, sizeof(mng_phys)},
|
---|
602 | #endif
|
---|
603 | #ifndef MNG_SKIPCHUNK_sBIT
|
---|
604 | {MNG_UINT_sBIT, mng_init_general, mng_free_general, mng_read_sbit, mng_write_sbit, mng_assign_general, 0, 0, sizeof(mng_sbit)},
|
---|
605 | #endif
|
---|
606 | /* TODO: {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0}, */
|
---|
607 | #ifndef MNG_SKIPCHUNK_sPLT
|
---|
608 | {MNG_UINT_sPLT, mng_init_general, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0, sizeof(mng_splt)},
|
---|
609 | #endif
|
---|
610 | {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)},
|
---|
611 | #ifndef MNG_SKIPCHUNK_tEXt
|
---|
612 | {MNG_UINT_tEXt, mng_init_general, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0, sizeof(mng_text)},
|
---|
613 | #endif
|
---|
614 | #ifndef MNG_SKIPCHUNK_tIME
|
---|
615 | {MNG_UINT_tIME, mng_init_general, mng_free_general, mng_read_time, mng_write_time, mng_assign_general, 0, 0, sizeof(mng_time)},
|
---|
616 | #endif
|
---|
617 | {MNG_UINT_tRNS, mng_init_general, mng_free_general, mng_read_trns, mng_write_trns, mng_assign_general, 0, 0, sizeof(mng_trns)},
|
---|
618 | #ifndef MNG_SKIPCHUNK_zTXt
|
---|
619 | {MNG_UINT_zTXt, mng_init_general, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0, sizeof(mng_ztxt)},
|
---|
620 | #endif
|
---|
621 | };
|
---|
622 |
|
---|
623 | #else /* MNG_OPTIMIZE_CHUNKINITFREE */
|
---|
624 |
|
---|
625 | mng_chunk_header mng_chunk_table [] =
|
---|
626 | {
|
---|
627 | #ifndef MNG_SKIPCHUNK_BACK
|
---|
628 | {MNG_UINT_BACK, mng_init_back, mng_free_back, mng_read_back, mng_write_back, mng_assign_back, 0, 0},
|
---|
629 | #endif
|
---|
630 | #ifndef MNG_SKIPCHUNK_BASI
|
---|
631 | {MNG_UINT_BASI, mng_init_basi, mng_free_basi, mng_read_basi, mng_write_basi, mng_assign_basi, 0, 0},
|
---|
632 | #endif
|
---|
633 | #ifndef MNG_SKIPCHUNK_CLIP
|
---|
634 | {MNG_UINT_CLIP, mng_init_clip, mng_free_clip, mng_read_clip, mng_write_clip, mng_assign_clip, 0, 0},
|
---|
635 | #endif
|
---|
636 | #ifndef MNG_SKIPCHUNK_CLON
|
---|
637 | {MNG_UINT_CLON, mng_init_clon, mng_free_clon, mng_read_clon, mng_write_clon, mng_assign_clon, 0, 0},
|
---|
638 | #endif
|
---|
639 | #ifndef MNG_NO_DELTA_PNG
|
---|
640 | #ifndef MNG_SKIPCHUNK_DBYK
|
---|
641 | {MNG_UINT_DBYK, mng_init_dbyk, mng_free_dbyk, mng_read_dbyk, mng_write_dbyk, mng_assign_dbyk, 0, 0},
|
---|
642 | #endif
|
---|
643 | #endif
|
---|
644 | #ifndef MNG_SKIPCHUNK_DEFI
|
---|
645 | {MNG_UINT_DEFI, mng_init_defi, mng_free_defi, mng_read_defi, mng_write_defi, mng_assign_defi, 0, 0},
|
---|
646 | #endif
|
---|
647 | #ifndef MNG_NO_DELTA_PNG
|
---|
648 | {MNG_UINT_DHDR, mng_init_dhdr, mng_free_dhdr, mng_read_dhdr, mng_write_dhdr, mng_assign_dhdr, 0, 0},
|
---|
649 | #endif
|
---|
650 | #ifndef MNG_SKIPCHUNK_DISC
|
---|
651 | {MNG_UINT_DISC, mng_init_disc, mng_free_disc, mng_read_disc, mng_write_disc, mng_assign_disc, 0, 0},
|
---|
652 | #endif
|
---|
653 | #ifndef MNG_NO_DELTA_PNG
|
---|
654 | #ifndef MNG_SKIPCHUNK_DROP
|
---|
655 | {MNG_UINT_DROP, mng_init_drop, mng_free_drop, mng_read_drop, mng_write_drop, mng_assign_drop, 0, 0},
|
---|
656 | #endif
|
---|
657 | #endif
|
---|
658 | #ifndef MNG_SKIPCHUNK_LOOP
|
---|
659 | {MNG_UINT_ENDL, mng_init_endl, mng_free_endl, mng_read_endl, mng_write_endl, mng_assign_endl, 0, 0},
|
---|
660 | #endif
|
---|
661 | #ifndef MNG_SKIPCHUNK_FRAM
|
---|
662 | {MNG_UINT_FRAM, mng_init_fram, mng_free_fram, mng_read_fram, mng_write_fram, mng_assign_fram, 0, 0},
|
---|
663 | #endif
|
---|
664 | {MNG_UINT_IDAT, mng_init_idat, mng_free_idat, mng_read_idat, mng_write_idat, mng_assign_idat, 0, 0}, /* 12-th element! */
|
---|
665 | {MNG_UINT_IEND, mng_init_iend, mng_free_iend, mng_read_iend, mng_write_iend, mng_assign_iend, 0, 0},
|
---|
666 | {MNG_UINT_IHDR, mng_init_ihdr, mng_free_ihdr, mng_read_ihdr, mng_write_ihdr, mng_assign_ihdr, 0, 0},
|
---|
667 | #ifndef MNG_NO_DELTA_PNG
|
---|
668 | #ifdef MNG_INCLUDE_JNG
|
---|
669 | {MNG_UINT_IJNG, mng_init_ijng, mng_free_ijng, mng_read_ijng, mng_write_ijng, mng_assign_ijng, 0, 0},
|
---|
670 | #endif
|
---|
671 | {MNG_UINT_IPNG, mng_init_ipng, mng_free_ipng, mng_read_ipng, mng_write_ipng, mng_assign_ipng, 0, 0},
|
---|
672 | #endif
|
---|
673 | #ifdef MNG_INCLUDE_JNG
|
---|
674 | {MNG_UINT_JDAA, mng_init_jdaa, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0},
|
---|
675 | {MNG_UINT_JDAT, mng_init_jdat, mng_free_jdat, mng_read_jdat, mng_write_jdat, mng_assign_jdat, 0, 0},
|
---|
676 | {MNG_UINT_JHDR, mng_init_jhdr, mng_free_jhdr, mng_read_jhdr, mng_write_jhdr, mng_assign_jhdr, 0, 0},
|
---|
677 | {MNG_UINT_JSEP, mng_init_jsep, mng_free_jsep, mng_read_jsep, mng_write_jsep, mng_assign_jsep, 0, 0},
|
---|
678 | {MNG_UINT_JdAA, mng_init_jdaa, mng_free_jdaa, mng_read_jdaa, mng_write_jdaa, mng_assign_jdaa, 0, 0},
|
---|
679 | #endif
|
---|
680 | #ifndef MNG_SKIPCHUNK_LOOP
|
---|
681 | {MNG_UINT_LOOP, mng_init_loop, mng_free_loop, mng_read_loop, mng_write_loop, mng_assign_loop, 0, 0},
|
---|
682 | #endif
|
---|
683 | #ifndef MNG_SKIPCHUNK_MAGN
|
---|
684 | {MNG_UINT_MAGN, mng_init_magn, mng_free_magn, mng_read_magn, mng_write_magn, mng_assign_magn, 0, 0},
|
---|
685 | #endif
|
---|
686 | {MNG_UINT_MEND, mng_init_mend, mng_free_mend, mng_read_mend, mng_write_mend, mng_assign_mend, 0, 0},
|
---|
687 | {MNG_UINT_MHDR, mng_init_mhdr, mng_free_mhdr, mng_read_mhdr, mng_write_mhdr, mng_assign_mhdr, 0, 0},
|
---|
688 | #ifndef MNG_SKIPCHUNK_MOVE
|
---|
689 | {MNG_UINT_MOVE, mng_init_move, mng_free_move, mng_read_move, mng_write_move, mng_assign_move, 0, 0},
|
---|
690 | #endif
|
---|
691 | #ifndef MNG_NO_DELTA_PNG
|
---|
692 | #ifndef MNG_SKIPCHUNK_ORDR
|
---|
693 | {MNG_UINT_ORDR, mng_init_ordr, mng_free_ordr, mng_read_ordr, mng_write_ordr, mng_assign_ordr, 0, 0},
|
---|
694 | #endif
|
---|
695 | #endif
|
---|
696 | #ifndef MNG_SKIPCHUNK_PAST
|
---|
697 | {MNG_UINT_PAST, mng_init_past, mng_free_past, mng_read_past, mng_write_past, mng_assign_past, 0, 0},
|
---|
698 | #endif
|
---|
699 | {MNG_UINT_PLTE, mng_init_plte, mng_free_plte, mng_read_plte, mng_write_plte, mng_assign_plte, 0, 0},
|
---|
700 | #ifndef MNG_NO_DELTA_PNG
|
---|
701 | {MNG_UINT_PPLT, mng_init_pplt, mng_free_pplt, mng_read_pplt, mng_write_pplt, mng_assign_pplt, 0, 0},
|
---|
702 | {MNG_UINT_PROM, mng_init_prom, mng_free_prom, mng_read_prom, mng_write_prom, mng_assign_prom, 0, 0},
|
---|
703 | #endif
|
---|
704 | #ifndef MNG_SKIPCHUNK_SAVE
|
---|
705 | {MNG_UINT_SAVE, mng_init_save, mng_free_save, mng_read_save, mng_write_save, mng_assign_save, 0, 0},
|
---|
706 | #endif
|
---|
707 | #ifndef MNG_SKIPCHUNK_SEEK
|
---|
708 | {MNG_UINT_SEEK, mng_init_seek, mng_free_seek, mng_read_seek, mng_write_seek, mng_assign_seek, 0, 0},
|
---|
709 | #endif
|
---|
710 | #ifndef MNG_SKIPCHUNK_SHOW
|
---|
711 | {MNG_UINT_SHOW, mng_init_show, mng_free_show, mng_read_show, mng_write_show, mng_assign_show, 0, 0},
|
---|
712 | #endif
|
---|
713 | #ifndef MNG_SKIPCHUNK_TERM
|
---|
714 | {MNG_UINT_TERM, mng_init_term, mng_free_term, mng_read_term, mng_write_term, mng_assign_term, 0, 0},
|
---|
715 | #endif
|
---|
716 | #ifndef MNG_SKIPCHUNK_bKGD
|
---|
717 | {MNG_UINT_bKGD, mng_init_bkgd, mng_free_bkgd, mng_read_bkgd, mng_write_bkgd, mng_assign_bkgd, 0, 0},
|
---|
718 | #endif
|
---|
719 | #ifndef MNG_SKIPCHUNK_cHRM
|
---|
720 | {MNG_UINT_cHRM, mng_init_chrm, mng_free_chrm, mng_read_chrm, mng_write_chrm, mng_assign_chrm, 0, 0},
|
---|
721 | #endif
|
---|
722 | #ifndef MNG_SKIPCHUNK_eXPI
|
---|
723 | {MNG_UINT_eXPI, mng_init_expi, mng_free_expi, mng_read_expi, mng_write_expi, mng_assign_expi, 0, 0},
|
---|
724 | #endif
|
---|
725 | #ifndef MNG_SKIPCHUNK_evNT
|
---|
726 | {MNG_UINT_evNT, mng_init_evnt, mng_free_evnt, mng_read_evnt, mng_write_evnt, mng_assign_evnt, 0, 0},
|
---|
727 | #endif
|
---|
728 | #ifndef MNG_SKIPCHUNK_fPRI
|
---|
729 | {MNG_UINT_fPRI, mng_init_fpri, mng_free_fpri, mng_read_fpri, mng_write_fpri, mng_assign_fpri, 0, 0},
|
---|
730 | #endif
|
---|
731 | #ifndef MNG_SKIPCHUNK_gAMA
|
---|
732 | {MNG_UINT_gAMA, mng_init_gama, mng_free_gama, mng_read_gama, mng_write_gama, mng_assign_gama, 0, 0},
|
---|
733 | #endif
|
---|
734 | #ifndef MNG_SKIPCHUNK_hIST
|
---|
735 | {MNG_UINT_hIST, mng_init_hist, mng_free_hist, mng_read_hist, mng_write_hist, mng_assign_hist, 0, 0},
|
---|
736 | #endif
|
---|
737 | #ifndef MNG_SKIPCHUNK_iCCP
|
---|
738 | {MNG_UINT_iCCP, mng_init_iccp, mng_free_iccp, mng_read_iccp, mng_write_iccp, mng_assign_iccp, 0, 0},
|
---|
739 | #endif
|
---|
740 | #ifndef MNG_SKIPCHUNK_iTXt
|
---|
741 | {MNG_UINT_iTXt, mng_init_itxt, mng_free_itxt, mng_read_itxt, mng_write_itxt, mng_assign_itxt, 0, 0},
|
---|
742 | #endif
|
---|
743 | #ifndef MNG_SKIPCHUNK_nEED
|
---|
744 | {MNG_UINT_nEED, mng_init_need, mng_free_need, mng_read_need, mng_write_need, mng_assign_need, 0, 0},
|
---|
745 | #endif
|
---|
746 | /* TODO: {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0}, */
|
---|
747 | /* TODO: {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0}, */
|
---|
748 | #ifndef MNG_SKIPCHUNK_pHYg
|
---|
749 | {MNG_UINT_pHYg, mng_init_phyg, mng_free_phyg, mng_read_phyg, mng_write_phyg, mng_assign_phyg, 0, 0},
|
---|
750 | #endif
|
---|
751 | #ifndef MNG_SKIPCHUNK_pHYs
|
---|
752 | {MNG_UINT_pHYs, mng_init_phys, mng_free_phys, mng_read_phys, mng_write_phys, mng_assign_phys, 0, 0},
|
---|
753 | #endif
|
---|
754 | #ifndef MNG_SKIPCHUNK_sBIT
|
---|
755 | {MNG_UINT_sBIT, mng_init_sbit, mng_free_sbit, mng_read_sbit, mng_write_sbit, mng_assign_sbit, 0, 0},
|
---|
756 | #endif
|
---|
757 | /* TODO: {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0}, */
|
---|
758 | #ifndef MNG_SKIPCHUNK_sPLT
|
---|
759 | {MNG_UINT_sPLT, mng_init_splt, mng_free_splt, mng_read_splt, mng_write_splt, mng_assign_splt, 0, 0},
|
---|
760 | #endif
|
---|
761 | {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0},
|
---|
762 | #ifndef MNG_SKIPCHUNK_tEXt
|
---|
763 | {MNG_UINT_tEXt, mng_init_text, mng_free_text, mng_read_text, mng_write_text, mng_assign_text, 0, 0},
|
---|
764 | #endif
|
---|
765 | #ifndef MNG_SKIPCHUNK_tIME
|
---|
766 | {MNG_UINT_tIME, mng_init_time, mng_free_time, mng_read_time, mng_write_time, mng_assign_time, 0, 0},
|
---|
767 | #endif
|
---|
768 | {MNG_UINT_tRNS, mng_init_trns, mng_free_trns, mng_read_trns, mng_write_trns, mng_assign_trns, 0, 0},
|
---|
769 | #ifndef MNG_SKIPCHUNK_zTXt
|
---|
770 | {MNG_UINT_zTXt, mng_init_ztxt, mng_free_ztxt, mng_read_ztxt, mng_write_ztxt, mng_assign_ztxt, 0, 0},
|
---|
771 | #endif
|
---|
772 | };
|
---|
773 |
|
---|
774 | #endif /* MNG_OPTIMIZE_CHUNKINITFREE */
|
---|
775 |
|
---|
776 | /* binary search variables */
|
---|
777 | mng_int32 iTop, iLower, iUpper, iMiddle;
|
---|
778 | mng_chunk_headerp pEntry; /* pointer to found entry */
|
---|
779 | #else
|
---|
780 | mng_chunk_header sEntry; /* temp chunk-header */
|
---|
781 | #endif /* MNG_OPTIMIZE_CHUNKREADER */
|
---|
782 |
|
---|
783 | mng_chunkid iChunkname; /* the chunk's tag */
|
---|
784 | mng_chunkp pChunk; /* chunk structure (if #define MNG_STORE_CHUNKS) */
|
---|
785 | mng_retcode iRetcode; /* temporary error-code */
|
---|
786 |
|
---|
787 | #ifdef MNG_SUPPORT_TRACE
|
---|
788 | MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_START);
|
---|
789 | #endif
|
---|
790 | /* reset timer indicator on read-cycle */
|
---|
791 | if ((pData->bReading) && (!pData->bDisplaying))
|
---|
792 | pData->bTimerset = MNG_FALSE;
|
---|
793 | /* get the chunkname */
|
---|
794 | iChunkname = (mng_chunkid)(mng_get_uint32 (pBuf));
|
---|
795 |
|
---|
796 | pBuf += sizeof (mng_chunkid); /* adjust the buffer */
|
---|
797 | iBuflen -= sizeof (mng_chunkid);
|
---|
798 | pChunk = 0;
|
---|
799 |
|
---|
800 | #ifndef MNG_OPTIMIZE_CHUNKREADER
|
---|
801 | /* determine max index of table */
|
---|
802 | iTop = (sizeof (mng_chunk_table) / sizeof (mng_chunk_table [0])) - 1;
|
---|
803 |
|
---|
804 | /* binary search; with 54 chunks, worst-case is 7 comparisons */
|
---|
805 | iLower = 0;
|
---|
806 | #ifndef MNG_NO_DELTA_PNG
|
---|
807 | iMiddle = 11; /* start with the IDAT entry */
|
---|
808 | #else
|
---|
809 | iMiddle = 8;
|
---|
810 | #endif
|
---|
811 | iUpper = iTop;
|
---|
812 | pEntry = 0; /* no goods yet! */
|
---|
813 |
|
---|
814 | do /* the binary search itself */
|
---|
815 | {
|
---|
816 | if (mng_chunk_table [iMiddle].iChunkname < iChunkname)
|
---|
817 | iLower = iMiddle + 1;
|
---|
818 | else if (mng_chunk_table [iMiddle].iChunkname > iChunkname)
|
---|
819 | iUpper = iMiddle - 1;
|
---|
820 | else
|
---|
821 | {
|
---|
822 | pEntry = &mng_chunk_table [iMiddle];
|
---|
823 | break;
|
---|
824 | }
|
---|
825 |
|
---|
826 | iMiddle = (iLower + iUpper) >> 1;
|
---|
827 | }
|
---|
828 | while (iLower <= iUpper);
|
---|
829 |
|
---|
830 | if (!pEntry) /* unknown chunk ? */
|
---|
831 | pEntry = &mng_chunk_unknown; /* make it so! */
|
---|
832 |
|
---|
833 | #else /* MNG_OPTIMIZE_CHUNKREADER */
|
---|
834 |
|
---|
835 | mng_get_chunkheader (iChunkname, &sEntry);
|
---|
836 |
|
---|
837 | #endif /* MNG_OPTIMIZE_CHUNKREADER */
|
---|
838 |
|
---|
839 | pData->iChunkname = iChunkname; /* keep track of where we are */
|
---|
840 | pData->iChunkseq++;
|
---|
841 |
|
---|
842 | #ifndef MNG_OPTIMIZE_CHUNKREADER
|
---|
843 | if (pEntry->fRead) /* read-callback available ? */
|
---|
844 | {
|
---|
845 | iRetcode = pEntry->fRead (pData, pEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
|
---|
846 |
|
---|
847 | if (!iRetcode) /* everything oke ? */
|
---|
848 | { /* remember unknown chunk's id */
|
---|
849 | if ((pChunk) && (pEntry->iChunkname == MNG_UINT_HUH))
|
---|
850 | ((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
|
---|
851 | }
|
---|
852 | }
|
---|
853 | #else /* MNG_OPTIMIZE_CHUNKREADER */
|
---|
854 | if (sEntry.fRead) /* read-callback available ? */
|
---|
855 | {
|
---|
856 | iRetcode = sEntry.fRead (pData, &sEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
|
---|
857 |
|
---|
858 | #ifndef MNG_OPTIMIZE_CHUNKREADER
|
---|
859 | if (!iRetcode) /* everything oke ? */
|
---|
860 | { /* remember unknown chunk's id */
|
---|
861 | if ((pChunk) && (sEntry.iChunkname == MNG_UINT_HUH))
|
---|
862 | ((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
|
---|
863 | }
|
---|
864 | #endif
|
---|
865 | }
|
---|
866 | #endif /* MNG_OPTIMIZE_CHUNKREADER */
|
---|
867 | else
|
---|
868 | iRetcode = MNG_NOERROR;
|
---|
869 |
|
---|
870 | if (pChunk) /* store this chunk ? */
|
---|
871 | mng_add_chunk (pData, pChunk); /* do it */
|
---|
872 |
|
---|
873 | #ifdef MNG_INCLUDE_JNG /* implicit EOF ? */
|
---|
874 | if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && (!pData->bHasJHDR))
|
---|
875 | #else
|
---|
876 | if ((!pData->bHasMHDR) && (!pData->bHasIHDR))
|
---|
877 | #endif
|
---|
878 | iRetcode = mng_process_eof (pData);/* then do some EOF processing */
|
---|
879 |
|
---|
880 | if (iRetcode) /* on error bail out */
|
---|
881 | return iRetcode;
|
---|
882 |
|
---|
883 | #ifdef MNG_SUPPORT_TRACE
|
---|
884 | MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_END);
|
---|
885 | #endif
|
---|
886 |
|
---|
887 | return MNG_NOERROR;
|
---|
888 | }
|
---|
889 |
|
---|
890 | /* ************************************************************************** */
|
---|
891 |
|
---|
892 | MNG_LOCAL mng_retcode check_chunk_crc (mng_datap pData,
|
---|
893 | mng_uint8p pBuf,
|
---|
894 | mng_uint32 iBuflen)
|
---|
895 | {
|
---|
896 | mng_uint32 iCrc; /* calculated CRC */
|
---|
897 | mng_bool bDiscard = MNG_FALSE;
|
---|
898 | mng_retcode iRetcode = MNG_NOERROR;
|
---|
899 |
|
---|
900 | #ifdef MNG_SUPPORT_TRACE
|
---|
901 | MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_START);
|
---|
902 | #endif
|
---|
903 |
|
---|
904 | if (pData->iCrcmode & MNG_CRC_INPUT) /* crc included ? */
|
---|
905 | {
|
---|
906 | mng_bool bCritical = (mng_bool)((*pBuf & 0x20) == 0);
|
---|
907 | mng_uint32 iL = iBuflen - (mng_uint32)(sizeof (iCrc));
|
---|
908 |
|
---|
909 | if (((bCritical ) && (pData->iCrcmode & MNG_CRC_CRITICAL )) ||
|
---|
910 | ((!bCritical) && (pData->iCrcmode & MNG_CRC_ANCILLARY)))
|
---|
911 | { /* calculate the crc */
|
---|
912 | iCrc = mng_crc (pData, pBuf, iL);
|
---|
913 | /* and check it */
|
---|
914 | if (!(iCrc == mng_get_uint32 (pBuf + iL)))
|
---|
915 | {
|
---|
916 | mng_bool bWarning = MNG_FALSE;
|
---|
917 | mng_bool bError = MNG_FALSE;
|
---|
918 |
|
---|
919 | if (bCritical)
|
---|
920 | {
|
---|
921 | switch (pData->iCrcmode & MNG_CRC_CRITICAL)
|
---|
922 | {
|
---|
923 | case MNG_CRC_CRITICAL_WARNING : { bWarning = MNG_TRUE; break; }
|
---|
924 | case MNG_CRC_CRITICAL_ERROR : { bError = MNG_TRUE; break; }
|
---|
925 | }
|
---|
926 | }
|
---|
927 | else
|
---|
928 | {
|
---|
929 | switch (pData->iCrcmode & MNG_CRC_ANCILLARY)
|
---|
930 | {
|
---|
931 | case MNG_CRC_ANCILLARY_DISCARD : { bDiscard = MNG_TRUE; break; }
|
---|
932 | case MNG_CRC_ANCILLARY_WARNING : { bWarning = MNG_TRUE; break; }
|
---|
933 | case MNG_CRC_ANCILLARY_ERROR : { bError = MNG_TRUE; break; }
|
---|
934 | }
|
---|
935 | }
|
---|
936 |
|
---|
937 | if (bWarning)
|
---|
938 | MNG_WARNING (pData, MNG_INVALIDCRC);
|
---|
939 | if (bError)
|
---|
940 | MNG_ERROR (pData, MNG_INVALIDCRC);
|
---|
941 | }
|
---|
942 | }
|
---|
943 |
|
---|
944 | if (!bDiscard) /* still processing ? */
|
---|
945 | iRetcode = process_raw_chunk (pData, pBuf, iL);
|
---|
946 | }
|
---|
947 | else
|
---|
948 | { /* no crc => straight onto processing */
|
---|
949 | iRetcode = process_raw_chunk (pData, pBuf, iBuflen);
|
---|
950 | }
|
---|
951 |
|
---|
952 | #ifdef MNG_SUPPORT_TRACE
|
---|
953 | MNG_TRACE (pData, MNG_FN_READ_CHUNK_CRC, MNG_LC_END);
|
---|
954 | #endif
|
---|
955 |
|
---|
956 | return iRetcode;
|
---|
957 | }
|
---|
958 |
|
---|
959 | /* ************************************************************************** */
|
---|
960 |
|
---|
961 | MNG_LOCAL mng_retcode read_chunk (mng_datap pData)
|
---|
962 | {
|
---|
963 | mng_uint32 iBufmax = pData->iReadbufsize;
|
---|
964 | mng_uint8p pBuf = pData->pReadbuf;
|
---|
965 | mng_uint32 iBuflen = 0; /* number of bytes requested */
|
---|
966 | mng_uint32 iRead = 0; /* number of bytes read */
|
---|
967 | mng_retcode iRetcode = MNG_NOERROR;
|
---|
968 |
|
---|
969 | #ifdef MNG_SUPPORT_TRACE
|
---|
970 | MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_START);
|
---|
971 | #endif
|
---|
972 |
|
---|
973 | #ifdef MNG_SUPPORT_DISPLAY
|
---|
974 | if (pData->pCurraniobj) /* processing an animation object ? */
|
---|
975 | {
|
---|
976 | do /* process it then */
|
---|
977 | {
|
---|
978 | iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
|
---|
979 | /* refresh needed ? */
|
---|
980 | /* if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
|
---|
981 | iRetcode = display_progressive_refresh (pData, 1); */
|
---|
982 | /* can we advance to next object ? */
|
---|
983 | if ((!iRetcode) && (pData->pCurraniobj) &&
|
---|
984 | (!pData->bTimerset) && (!pData->bSectionwait))
|
---|
985 | { /* reset timer indicator on read-cycle */
|
---|
986 | if ((pData->bReading) && (!pData->bDisplaying))
|
---|
987 | pData->bTimerset = MNG_FALSE;
|
---|
988 |
|
---|
989 | pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
|
---|
990 | /* TERM processing to be done ? */
|
---|
991 | if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
|
---|
992 | iRetcode = mng_process_display_mend (pData);
|
---|
993 | }
|
---|
994 | } /* until error or a break or no more objects */
|
---|
995 | while ((!iRetcode) && (pData->pCurraniobj) &&
|
---|
996 | (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
|
---|
997 | }
|
---|
998 | else
|
---|
999 | {
|
---|
1000 | if (pData->iBreakpoint) /* do we need to finish something first ? */
|
---|
1001 | {
|
---|
1002 | switch (pData->iBreakpoint) /* return to broken display routine */
|
---|
1003 | {
|
---|
1004 | #ifndef MNG_SKIPCHUNK_FRAM
|
---|
1005 | case 1 : { iRetcode = mng_process_display_fram2 (pData); break; }
|
---|
1006 | #endif
|
---|
1007 | case 2 : { iRetcode = mng_process_display_ihdr (pData); break; }
|
---|
1008 | #ifndef MNG_SKIPCHUNK_SHOW
|
---|
1009 | case 3 : ; /* same as 4 !!! */
|
---|
1010 | case 4 : { iRetcode = mng_process_display_show (pData); break; }
|
---|
1011 | #endif
|
---|
1012 | #ifndef MNG_SKIPCHUNK_CLON
|
---|
1013 | case 5 : { iRetcode = mng_process_display_clon2 (pData); break; }
|
---|
1014 | #endif
|
---|
1015 | #ifdef MNG_INCLUDE_JNG
|
---|
1016 | case 7 : { iRetcode = mng_process_display_jhdr (pData); break; }
|
---|
1017 | #endif
|
---|
1018 | case 6 : ; /* same as 8 !!! */
|
---|
1019 | case 8 : { iRetcode = mng_process_display_iend (pData); break; }
|
---|
1020 | #ifndef MNG_SKIPCHUNK_MAGN
|
---|
1021 | case 9 : { iRetcode = mng_process_display_magn2 (pData); break; }
|
---|
1022 | #endif
|
---|
1023 | case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
|
---|
1024 | #ifndef MNG_SKIPCHUNK_PAST
|
---|
1025 | case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
|
---|
1026 | #endif
|
---|
1027 | }
|
---|
1028 | }
|
---|
1029 | }
|
---|
1030 |
|
---|
1031 | if (iRetcode) /* on error bail out */
|
---|
1032 | return iRetcode;
|
---|
1033 |
|
---|
1034 | #endif /* MNG_SUPPORT_DISPLAY */
|
---|
1035 | /* can we continue processing now, or do we */
|
---|
1036 | /* need to wait for the timer to finish (again) ? */
|
---|
1037 | #ifdef MNG_SUPPORT_DISPLAY
|
---|
1038 | if ((!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bEOF))
|
---|
1039 | #else
|
---|
1040 | if (!pData->bEOF)
|
---|
1041 | #endif
|
---|
1042 | {
|
---|
1043 | #ifdef MNG_SUPPORT_DISPLAY
|
---|
1044 | /* freezing in progress ? */
|
---|
1045 | if ((pData->bFreezing) && (pData->iSuspendpoint == 0))
|
---|
1046 | pData->bRunning = MNG_FALSE; /* then this is the right moment to do it */
|
---|
1047 | #endif
|
---|
1048 |
|
---|
1049 | if (pData->iSuspendpoint <= 2)
|
---|
1050 | {
|
---|
1051 | iBuflen = sizeof (mng_uint32); /* read length */
|
---|
1052 | iRetcode = read_databuffer (pData, pBuf, &pData->pReadbufnext, iBuflen, &iRead);
|
---|
1053 |
|
---|
1054 | if (iRetcode) /* bail on errors */
|
---|
1055 | return iRetcode;
|
---|
1056 |
|
---|
1057 | if (pData->bSuspended) /* suspended ? */
|
---|
1058 | pData->iSuspendpoint = 2;
|
---|
1059 | else /* save the length */
|
---|
1060 | {
|
---|
1061 | pData->iChunklen = mng_get_uint32 (pBuf);
|
---|
1062 | if (pData->iChunklen > 0x7ffffff)
|
---|
1063 | return MNG_INVALIDLENGTH;
|
---|
1064 | }
|
---|
1065 |
|
---|
1066 | }
|
---|
1067 |
|
---|
1068 | if (!pData->bSuspended) /* still going ? */
|
---|
1069 | { /* previously suspended or not eof ? */
|
---|
1070 | if ((pData->iSuspendpoint > 2) || (iRead == iBuflen))
|
---|
1071 | { /* determine length chunkname + data (+ crc) */
|
---|
1072 | if (pData->iCrcmode & MNG_CRC_INPUT)
|
---|
1073 | iBuflen = pData->iChunklen + (mng_uint32)(sizeof (mng_chunkid) + sizeof (mng_uint32));
|
---|
1074 | else
|
---|
1075 | iBuflen = pData->iChunklen + (mng_uint32)(sizeof (mng_chunkid));
|
---|
1076 |
|
---|
1077 | /* do we have enough data in the current push buffer ? */
|
---|
1078 | if ((pData->pFirstpushdata) && (iBuflen <= pData->pFirstpushdata->iRemaining))
|
---|
1079 | {
|
---|
1080 | mng_pushdatap pPush = pData->pFirstpushdata;
|
---|
1081 | pBuf = pPush->pDatanext;
|
---|
1082 | pPush->pDatanext += iBuflen;
|
---|
1083 | pPush->iRemaining -= iBuflen;
|
---|
1084 | pData->iSuspendpoint = 0; /* safely reset this here ! */
|
---|
1085 |
|
---|
1086 | iRetcode = check_chunk_crc (pData, pBuf, iBuflen);
|
---|
1087 | if (iRetcode)
|
---|
1088 | return iRetcode;
|
---|
1089 |
|
---|
1090 | if (!pPush->iRemaining) /* buffer depleted? then release it */
|
---|
1091 | iRetcode = mng_release_pushdata (pData);
|
---|
1092 | }
|
---|
1093 | else
|
---|
1094 | {
|
---|
1095 | if (iBuflen < iBufmax) /* does it fit in default buffer ? */
|
---|
1096 | { /* note that we don't use the full size
|
---|
1097 | so there's always a zero-byte at the
|
---|
1098 | very end !!! */
|
---|
1099 | iRetcode = read_databuffer (pData, pBuf, &pData->pReadbufnext, iBuflen, &iRead);
|
---|
1100 | if (iRetcode) /* bail on errors */
|
---|
1101 | return iRetcode;
|
---|
1102 |
|
---|
1103 | if (pData->bSuspended) /* suspended ? */
|
---|
1104 | pData->iSuspendpoint = 3;
|
---|
1105 | else
|
---|
1106 | {
|
---|
1107 | if (iRead != iBuflen) /* did we get all the data ? */
|
---|
1108 | MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
|
---|
1109 | iRetcode = check_chunk_crc (pData, pBuf, iBuflen);
|
---|
1110 | }
|
---|
1111 | }
|
---|
1112 | else
|
---|
1113 | {
|
---|
1114 | if (iBuflen > 16777216) /* is the length incredible? */
|
---|
1115 | MNG_ERROR (pData, MNG_IMPROBABLELENGTH);
|
---|
1116 |
|
---|
1117 | if (!pData->iSuspendpoint) /* create additional large buffer ? */
|
---|
1118 | { /* again reserve space for the last zero-byte */
|
---|
1119 | pData->iLargebufsize = iBuflen + 1;
|
---|
1120 | pData->pLargebufnext = MNG_NULL;
|
---|
1121 | MNG_ALLOC (pData, pData->pLargebuf, pData->iLargebufsize);
|
---|
1122 | }
|
---|
1123 |
|
---|
1124 | iRetcode = read_databuffer (pData, pData->pLargebuf, &pData->pLargebufnext, iBuflen, &iRead);
|
---|
1125 | if (iRetcode)
|
---|
1126 | return iRetcode;
|
---|
1127 |
|
---|
1128 | if (pData->bSuspended) /* suspended ? */
|
---|
1129 | pData->iSuspendpoint = 4;
|
---|
1130 | else
|
---|
1131 | {
|
---|
1132 | if (iRead != iBuflen) /* did we get all the data ? */
|
---|
1133 | MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
|
---|
1134 | iRetcode = check_chunk_crc (pData, pData->pLargebuf, iBuflen);
|
---|
1135 | /* cleanup additional large buffer */
|
---|
1136 | MNG_FREE (pData, pData->pLargebuf, pData->iLargebufsize);
|
---|
1137 | }
|
---|
1138 | }
|
---|
1139 | }
|
---|
1140 |
|
---|
1141 | if (iRetcode) /* on error bail out */
|
---|
1142 | return iRetcode;
|
---|
1143 |
|
---|
1144 | }
|
---|
1145 | else
|
---|
1146 | { /* that's final */
|
---|
1147 | iRetcode = mng_process_eof (pData);
|
---|
1148 |
|
---|
1149 | if (iRetcode) /* on error bail out */
|
---|
1150 | return iRetcode;
|
---|
1151 |
|
---|
1152 | if ((iRead != 0) || /* did we get an unexpected eof ? */
|
---|
1153 | #ifdef MNG_INCLUDE_JNG
|
---|
1154 | (pData->bHasIHDR || pData->bHasMHDR || pData->bHasJHDR))
|
---|
1155 | #else
|
---|
1156 | (pData->bHasIHDR || pData->bHasMHDR))
|
---|
1157 | #endif
|
---|
1158 | MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
|
---|
1159 | }
|
---|
1160 | }
|
---|
1161 | }
|
---|
1162 |
|
---|
1163 | #ifdef MNG_SUPPORT_DISPLAY /* refresh needed ? */
|
---|
1164 | if ((!pData->bTimerset) && (!pData->bSuspended) && (pData->bNeedrefresh))
|
---|
1165 | {
|
---|
1166 | iRetcode = mng_display_progressive_refresh (pData, 1);
|
---|
1167 |
|
---|
1168 | if (iRetcode) /* on error bail out */
|
---|
1169 | return iRetcode;
|
---|
1170 | }
|
---|
1171 | #endif
|
---|
1172 |
|
---|
1173 | #ifdef MNG_SUPPORT_TRACE
|
---|
1174 | MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_END);
|
---|
1175 | #endif
|
---|
1176 |
|
---|
1177 | return MNG_NOERROR;
|
---|
1178 | }
|
---|
1179 |
|
---|
1180 | /* ************************************************************************** */
|
---|
1181 |
|
---|
1182 | MNG_LOCAL mng_retcode process_pushedchunk (mng_datap pData)
|
---|
1183 | {
|
---|
1184 | mng_pushdatap pPush;
|
---|
1185 | mng_retcode iRetcode = MNG_NOERROR;
|
---|
1186 |
|
---|
1187 | #ifdef MNG_SUPPORT_DISPLAY
|
---|
1188 | if (pData->pCurraniobj) /* processing an animation object ? */
|
---|
1189 | {
|
---|
1190 | do /* process it then */
|
---|
1191 | {
|
---|
1192 | iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
|
---|
1193 | /* refresh needed ? */
|
---|
1194 | /* if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
|
---|
1195 | iRetcode = display_progressive_refresh (pData, 1); */
|
---|
1196 | /* can we advance to next object ? */
|
---|
1197 | if ((!iRetcode) && (pData->pCurraniobj) &&
|
---|
1198 | (!pData->bTimerset) && (!pData->bSectionwait))
|
---|
1199 | { /* reset timer indicator on read-cycle */
|
---|
1200 | if ((pData->bReading) && (!pData->bDisplaying))
|
---|
1201 | pData->bTimerset = MNG_FALSE;
|
---|
1202 |
|
---|
1203 | pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
|
---|
1204 | /* TERM processing to be done ? */
|
---|
1205 | if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
|
---|
1206 | iRetcode = mng_process_display_mend (pData);
|
---|
1207 | }
|
---|
1208 | } /* until error or a break or no more objects */
|
---|
1209 | while ((!iRetcode) && (pData->pCurraniobj) &&
|
---|
1210 | (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
|
---|
1211 | }
|
---|
1212 | else
|
---|
1213 | {
|
---|
1214 | if (pData->iBreakpoint) /* do we need to finish something first ? */
|
---|
1215 | {
|
---|
1216 | switch (pData->iBreakpoint) /* return to broken display routine */
|
---|
1217 | {
|
---|
1218 | #ifndef MNG_SKIPCHUNK_FRAM
|
---|
1219 | case 1 : { iRetcode = mng_process_display_fram2 (pData); break; }
|
---|
1220 | #endif
|
---|
1221 | case 2 : { iRetcode = mng_process_display_ihdr (pData); break; }
|
---|
1222 | #ifndef MNG_SKIPCHUNK_SHOW
|
---|
1223 | case 3 : ; /* same as 4 !!! */
|
---|
1224 | case 4 : { iRetcode = mng_process_display_show (pData); break; }
|
---|
1225 | #endif
|
---|
1226 | #ifndef MNG_SKIPCHUNK_CLON
|
---|
1227 | case 5 : { iRetcode = mng_process_display_clon2 (pData); break; }
|
---|
1228 | #endif
|
---|
1229 | #ifdef MNG_INCLUDE_JNG
|
---|
1230 | case 7 : { iRetcode = mng_process_display_jhdr (pData); break; }
|
---|
1231 | #endif
|
---|
1232 | case 6 : ; /* same as 8 !!! */
|
---|
1233 | case 8 : { iRetcode = mng_process_display_iend (pData); break; }
|
---|
1234 | #ifndef MNG_SKIPCHUNK_MAGN
|
---|
1235 | case 9 : { iRetcode = mng_process_display_magn2 (pData); break; }
|
---|
1236 | #endif
|
---|
1237 | case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
|
---|
1238 | #ifndef MNG_SKIPCHUNK_PAST
|
---|
1239 | case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
|
---|
1240 | #endif
|
---|
1241 | }
|
---|
1242 | }
|
---|
1243 | }
|
---|
1244 |
|
---|
1245 | if (iRetcode) /* on error bail out */
|
---|
1246 | return iRetcode;
|
---|
1247 |
|
---|
1248 | #endif /* MNG_SUPPORT_DISPLAY */
|
---|
1249 | /* can we continue processing now, or do we */
|
---|
1250 | /* need to wait for the timer to finish (again) ? */
|
---|
1251 | #ifdef MNG_SUPPORT_DISPLAY
|
---|
1252 | if ((!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bEOF))
|
---|
1253 | #else
|
---|
1254 | if (!pData->bEOF)
|
---|
1255 | #endif
|
---|
1256 | {
|
---|
1257 | pData->iSuspendpoint = 0; /* safely reset it here ! */
|
---|
1258 | pPush = pData->pFirstpushchunk;
|
---|
1259 |
|
---|
1260 | iRetcode = process_raw_chunk (pData, pPush->pData, pPush->iLength);
|
---|
1261 | if (iRetcode)
|
---|
1262 | return iRetcode;
|
---|
1263 |
|
---|
1264 | #ifdef MNG_SUPPORT_DISPLAY /* refresh needed ? */
|
---|
1265 | if ((!pData->bTimerset) && (!pData->bSuspended) && (pData->bNeedrefresh))
|
---|
1266 | {
|
---|
1267 | iRetcode = mng_display_progressive_refresh (pData, 1);
|
---|
1268 | if (iRetcode) /* on error bail out */
|
---|
1269 | return iRetcode;
|
---|
1270 | }
|
---|
1271 | #endif
|
---|
1272 | }
|
---|
1273 |
|
---|
1274 | return mng_release_pushchunk (pData);
|
---|
1275 | }
|
---|
1276 |
|
---|
1277 | /* ************************************************************************** */
|
---|
1278 |
|
---|
1279 | mng_retcode mng_read_graphic (mng_datap pData)
|
---|
1280 | {
|
---|
1281 | mng_uint32 iBuflen; /* number of bytes requested */
|
---|
1282 | mng_uint32 iRead; /* number of bytes read */
|
---|
1283 | mng_retcode iRetcode; /* temporary error-code */
|
---|
1284 |
|
---|
1285 | #ifdef MNG_SUPPORT_TRACE
|
---|
1286 | MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_START);
|
---|
1287 | #endif
|
---|
1288 |
|
---|
1289 | if (!pData->pReadbuf) /* buffer allocated ? */
|
---|
1290 | {
|
---|
1291 | pData->iReadbufsize = 4200; /* allocate a default read buffer */
|
---|
1292 | MNG_ALLOC (pData, pData->pReadbuf, pData->iReadbufsize);
|
---|
1293 | }
|
---|
1294 | /* haven't processed the signature ? */
|
---|
1295 | if ((!pData->bHavesig) || (pData->iSuspendpoint == 1))
|
---|
1296 | {
|
---|
1297 | iBuflen = 2 * sizeof (mng_uint32); /* read signature */
|
---|
1298 |
|
---|
1299 | iRetcode = read_databuffer (pData, pData->pReadbuf, &pData->pReadbufnext, iBuflen, &iRead);
|
---|
1300 |
|
---|
1301 | if (iRetcode)
|
---|
1302 | return iRetcode;
|
---|
1303 |
|
---|
1304 | if (pData->bSuspended) /* input suspension ? */
|
---|
1305 | pData->iSuspendpoint = 1;
|
---|
1306 | else
|
---|
1307 | {
|
---|
1308 | if (iRead != iBuflen) /* full signature received ? */
|
---|
1309 | MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
|
---|
1310 | /* is it a valid signature ? */
|
---|
1311 | if (mng_get_uint32 (pData->pReadbuf) == PNG_SIG)
|
---|
1312 | pData->eSigtype = mng_it_png;
|
---|
1313 | else
|
---|
1314 | #ifdef MNG_INCLUDE_JNG
|
---|
1315 | if (mng_get_uint32 (pData->pReadbuf) == JNG_SIG)
|
---|
1316 | pData->eSigtype = mng_it_jng;
|
---|
1317 | else
|
---|
1318 | #endif
|
---|
1319 | if (mng_get_uint32 (pData->pReadbuf) == MNG_SIG)
|
---|
1320 | pData->eSigtype = mng_it_mng;
|
---|
1321 | else
|
---|
1322 | MNG_ERROR (pData, MNG_INVALIDSIG);
|
---|
1323 | /* all of it ? */
|
---|
1324 | if (mng_get_uint32 (pData->pReadbuf+4) != POST_SIG)
|
---|
1325 | MNG_ERROR (pData, MNG_INVALIDSIG);
|
---|
1326 |
|
---|
1327 | pData->bHavesig = MNG_TRUE;
|
---|
1328 | }
|
---|
1329 | }
|
---|
1330 |
|
---|
1331 | if (!pData->bSuspended) /* still going ? */
|
---|
1332 | {
|
---|
1333 | do
|
---|
1334 | { /* reset timer during mng_read() ? */
|
---|
1335 | if ((pData->bReading) && (!pData->bDisplaying))
|
---|
1336 | pData->bTimerset = MNG_FALSE;
|
---|
1337 |
|
---|
1338 | if (pData->pFirstpushchunk) /* chunks pushed ? */
|
---|
1339 | iRetcode = process_pushedchunk (pData); /* process the pushed chunk */
|
---|
1340 | else
|
---|
1341 | iRetcode = read_chunk (pData); /* read & process a chunk */
|
---|
1342 |
|
---|
1343 | if (iRetcode) /* on error bail out */
|
---|
1344 | return iRetcode;
|
---|
1345 | }
|
---|
1346 | #ifdef MNG_SUPPORT_DISPLAY /* until EOF or a break-request */
|
---|
1347 | while (((!pData->bEOF) || (pData->pCurraniobj)) &&
|
---|
1348 | (!pData->bSuspended) && (!pData->bSectionwait) &&
|
---|
1349 | ((!pData->bTimerset) || ((pData->bReading) && (!pData->bDisplaying))));
|
---|
1350 | #else
|
---|
1351 | while ((!pData->bEOF) && (!pData->bSuspended));
|
---|
1352 | #endif
|
---|
1353 | }
|
---|
1354 |
|
---|
1355 | #ifdef MNG_SUPPORT_TRACE
|
---|
1356 | MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_END);
|
---|
1357 | #endif
|
---|
1358 |
|
---|
1359 | return MNG_NOERROR;
|
---|
1360 | }
|
---|
1361 |
|
---|
1362 | /* ************************************************************************** */
|
---|
1363 |
|
---|
1364 | #endif /* MNG_INCLUDE_READ_PROCS */
|
---|
1365 |
|
---|
1366 | /* ************************************************************************** */
|
---|
1367 | /* * end of file * */
|
---|
1368 | /* ************************************************************************** */
|
---|
1369 |
|
---|