New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / workbench / libs / iffparse / popchunk.c
blobb45a3eeab6b4cb634d36594843a96588acbd0dbe
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "iffparse_intern.h"
8 /*****************************************************************************
10 NAME */
11 #include <proto/iffparse.h>
13 AROS_LH1(LONG, PopChunk,
15 /* SYNOPSIS */
16 AROS_LHA(struct IFFHandle *, iff, A0),
18 /* LOCATION */
19 struct Library *, IFFParseBase, 15, IFFParse)
21 /* FUNCTION
22 Pops a context node of the context stack. Usually called
23 in write mode to signal the end of a chunk.
26 INPUTS
27 iff - pointer to IFFHandle struct.
29 RESULT
30 error - 0 if successfull, IFFERR_#? otherwise.
32 NOTES
34 EXAMPLE
36 BUGS
38 SEE ALSO
39 PushChunk()
41 INTERNALS
43 Frees a contextnode an all its related LCIs and removes it from the stack-list
44 If we are in write mode, we will update the cn_Size in the chunk according
45 t cn_Scan, and we will also insert an align byte if necessary
48 If the stream was of PushChunked() as IFFSIZE_UNKNOWN, we have to seek backwards
49 and write the correct size.
50 Since non RSEEK streams are automagically buffered by
51 WriteStream, we don't have to fiddle with it here.
52 However if the stream is buffered, we MUST see if we are
53 about to pop the chunk that started the Buffering (in PushChunk)
55 *****************************************************************************/
57 AROS_LIBFUNC_INIT
58 AROS_LIBBASE_EXT_DECL(struct Library *,IFFParseBase)
61 struct ContextNode *cn;
63 LONG err;
65 LONG size;
67 UBYTE nullbyte = 0;
69 DEBUG_POPCHUNK(dprintf("PopChunk: iff 0x%lx\n", iff));
71 /* Get current chunk */
72 cn = TopChunk(iff);
74 /* Is the IFFHandle opened in Read or Write mode ? */
75 if (iff->iff_Flags & IFFF_WRITE)
77 /* Write mode. We should update cn_Size *INSIDE the stream,
78 if the chunk was pushed with IFFSIZE_UNKNOWN */
80 if (cn->cn_Size == IFFSIZE_UNKNOWN)
83 err = SeekStream
85 iff,
86 /* minus is for seeking backwards. Remember: evt. chunk types
87 for composite chunks are allready in cn_Scan */
88 - ( cn->cn_Scan + sizeof(ULONG) ),
89 IPB(IFFParseBase)
92 if (err) return (err);
94 size = cn->cn_Scan;
96 /* Write the chunk size */
97 err = WriteStreamLong
99 iff,
100 &size,
101 IPB(IFFParseBase)
104 if (err < 0) return (err);
106 /* Seek towards end of chunk again */
107 err = SeekStream
109 iff,
110 size,
111 IPB(IFFParseBase)
114 if (err) return (err);
117 else /* IFFSIZE known at PushChunk() time */
118 size = cn->cn_Size;
121 /* Write a pad byte if chunk is not word-aligned */
122 if (size % 2)
124 err = WriteStream
126 iff,
127 &nullbyte,
129 IPB(IFFParseBase)
132 if (err < 0) return (err);
133 size++;
138 GetIntIH(iff)->iff_BufferStartDepth
140 iff->iff_Depth
143 /* a routine that writes the buffer to stream and reinstallss the old streamhandler */
145 err = ExitBufferedStream(iff, IPB(IFFParseBase));
146 if (err) return (err);
151 /* Actually pop the top context-node. (Done for both handles in Read & Write mode) */
153 PopContextNode(iff, IPB(IFFParseBase));
155 /* stegerg: is this okay!? */
157 if (iff->iff_Flags & IFFF_WRITE)
159 cn = TopChunk(iff);
161 /* Might work without this check, because there seems to be always at
162 least one contextnode --> see AllocIFF) */
163 if (cn->cn_Node.mln_Succ)
165 cn->cn_Scan += size + sizeof(ULONG) + sizeof(ULONG);
169 return 0;
171 AROS_LIBFUNC_EXIT
172 } /* PopChunk */