File: u-iff.h

package info (click to toggle)
rockdodger 1.0.2-1
  • links: PTS
  • area: main
  • in suites: stretch
  • size: 2,352 kB
  • ctags: 852
  • sloc: ansic: 5,790; makefile: 159; sh: 21
file content (175 lines) | stat: -rw-r--r-- 5,471 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#ifndef __MICRO_IFF_H__
#define __MICRO_IFF_H__
#include <stdint.h>
#include <stdio.h>

typedef int32_t IFFP;	/* Status code result from an IFF procedure */
	/* LONG, because must be type compatable with ID for GetChunkHdr.*/
	/* Note that the error codes below are not legal IDs.*/
#define IFF_OKAY   0L	/* Keep going...*/
#define END_MARK  -1L	/* As if there was a chunk at end of group.*/
#define IFF_DONE  -2L	/* clientProc returns this when it has READ enough.
			 * It means return thru all levels. File is Okay.*/
#define DOS_ERROR -3L
#define NOT_IFF   -4L	/* not an IFF file.*/
#define NO_FILE   -5L	/* Tried to open file, DOS didn't find it.*/
#define CLIENT_ERROR -6L /* Client made invalid request, for instance, write
			 * a negative size chunk.*/
#define BAD_FORM  -7L	/* A client read proc complains about FORM semantics;
			 * e.g. valid IFF, but missing a required chunk.*/
#define SHORT_CHUNK -8L	/* Client asked to IFFReadBytes more bytes than left
			 * in the chunk. Could be client bug or bad form.*/
#define BAD_IFF   -9L	/* mal-formed IFF file. [TBD] Expand this into a
			 * range of error codes.*/
#define LAST_ERROR BAD_IFF

// Flags for calling the group find function
#define IFF_FIND_REWIND 1 //!< rewind before searching

/*! \brief Four-character IDentifier builder.*/
#define MakeID(a,b,c,d)  ( (int32_t)(a)<<24L | (int32_t)(b)<<16L | (c)<<8 | (d) )
/* Standard group IDs.  A chunk with one of these IDs contains a
   SubTypeID followed by zero or more chunks.*/
#define FORM MakeID('F','O','R','M')
#define PROP MakeID('P','R','O','P')
#define LIST MakeID('L','I','S','T')
#define CAT  MakeID('C','A','T',' ')
#define FILLER MakeID(' ',' ',' ',' ')
#define JUNK MakeID('J', 'U', 'N', 'K')

typedef int32_t ID;	/*! \brief An ID is four printable ASCII chars
			 *  but stored as a int32_t for efficient copy
			 *  & compare.*/

typedef struct Uiff_CTX {
  FILE *f;
  void *last_data; //!< last data was read here
  ID grID; //!<group id, eg FORM
  ID grsID; //!<group sub id, eg FORM ILBM
  long grbgn; //!<beginning position of group *data* in file
  long grend; //!<begin + grsz
  int32_t grsz; //!<group size

  ID ckID; //!<id of current chunk, eg BMHD
  long ckbgn; //!<beginning of chunk *data*
  long ckend;
  int32_t cksz; //!<chunk size of current chunk
} uiff_ctx_t;

/*! \brief find a chunk in a file
 * 
 * File is positioned on data. If ckID is zero then the next available
 * chunk is found.
 *
 * \param ckID id of the chunk to be found
 * \return chunk size
 */
int32_t uiff_find_chunk(FILE *inf, long length, ID ckID);

/*! \brief find a group in a file
 * 
 * File is positioned on data. If ckID is zero then any of the default
 * group chunks (FORM, LIST, CAT, PROP) is found.
 *
 * \param ckID id of the group chunk, e.g. FORM, etc.
 * \param subID subid of the group, e.g. ILBM, etc.
 * \return chunk size
 */
int32_t uiff_find_group(FILE *inf, long length, ID ckID, ID subID);

/*! \brief group predicate
 *
 */
int uiff_group_p(FILE *inf, ID grID, ID ckID);

/*! \brief read chunk to allocated memory
 *
 * Chunk is read within current context.
 */
void *uiff_reada_chunk_ctx(uiff_ctx_t *inf);

/*! \brief read a 32-bit big endian integer from file
 *
 * \param inf input file
 * \return unsigned integer 32 bit
 */
uint32_t read32(FILE *inf);

/*! \brief read a 16-bit big endian integer from file
 *
 * \param inf input file
 * \return unsigned integer 16 bit
 */
uint16_t read16(FILE *inf);

uiff_ctx_t *uiff_new_ctx(FILE *f, uiff_ctx_t *ctx);

/* \brief Get a context from a file only for true IFF files.
 *
 * This will rewind the file, check if it is an IFF file, and it will
 * return a context with the stream positioned into the main group.
 *
 * \param f a file which is rewound and checked
 * \param grID the group the file shall have, set to zero if any valid IFF file
 * \param subID Which type of IFF file (ILBM, etc.)? Set to zero if any.
 */
uiff_ctx_t *uiff_from_file(FILE *f, ID grID, ID subID);

/*! \brief close an iff context and underlying file
 *
 * \param ctx uiff context
 * \return IFF_OKAY on success
 */
int32_t uiff_close(uiff_ctx_t *ctx);

/*! \brief Find a group chunk
 *
 * If the ckID for the group is equal to zero any type of grouping
 * chunk is found.
 *
 * \param ctx iff context
 * \param flags currently only rewind
 * \param ckID id of the grouping chunk
 * \param subID sub id of the group
 * \return size of the group, is , is < 0 on error
 */
int32_t uiff_find_group_ctx(uiff_ctx_t *ctx, unsigned flags, ID ckID, ID subID);

/*! \brief find a chunk in a group
 *
 * If the ckID for the chunk is equal to zero any type of chunk is
 * found.
 *
 * \param ctx iff context
 * \param ckID id of the chunk
 * \return size of the group, <0 on error
 */
int32_t uiff_find_chunk_ctx(uiff_ctx_t *ctx, ID ckID);

/*! \brief find a chunk in a group with flags
 *
 * If the ckID for the chunk is equal to zero any type of chunk is
 * found.
 *
 * Currently only IFF_FIND_REWIND is supported.
 *
 * \param ctx iff context
 * \param ckID id of the chunk
 * \return size of the group, <0 on error
 */
int32_t uiff_find_chunk_wflags(uiff_ctx_t *ctx, ID ckID, unsigned flags);


/*! \brief skip to end of chunk
 *
 * Will skip to the end of the current chunk.
 *
 * \param ctx micro iff context
 * \return number of bytes skipped or error if < 0
 */
int32_t uiff_skip(uiff_ctx_t *ctx);

/*! \brief rewind to the beginning of the group
 */
void uiff_rewind_group(uiff_ctx_t *ctx);
#endif