xine-lib
1.2.10
xine-lib-1.2.10
src
demuxers
iff.h
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2004-2008 the xine project
3
*
4
* This file is part of xine, a free video player.
5
*
6
* xine is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* xine is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19
*/
20
21
/*
22
* IFF header file by Manfred Tremmel (Manfred.Tremmel@iiv.de)
23
* Based on the information of the Amiga Developer CD
24
*/
25
26
#ifndef IFFP_IFF_H
27
#define IFFP_IFF_H
28
29
#define IFF_OKAY 0L
30
#define IFF_CLIENT_ERROR 1L
31
#define IFF_NOFILE 5L
32
33
#define FOURCC_CHUNK BE_FOURCC
34
#define IFF_16SV_CHUNK FOURCC_CHUNK('1', '6', 'S', 'V')
35
#define IFF_8SVX_CHUNK FOURCC_CHUNK('8', 'S', 'V', 'X')
36
#define IFF_ANFI_CHUNK FOURCC_CHUNK('A', 'N', 'F', 'I')
37
#define IFF_ANHD_CHUNK FOURCC_CHUNK('A', 'N', 'H', 'D')
38
#define IFF_ANIM_CHUNK FOURCC_CHUNK('A', 'N', 'I', 'M')
39
#define IFF_ANNO_CHUNK FOURCC_CHUNK('A', 'N', 'N', 'O')
40
#define IFF_ANSQ_CHUNK FOURCC_CHUNK('A', 'N', 'S', 'Q')
41
#define IFF_ATAK_CHUNK FOURCC_CHUNK('A', 'T', 'A', 'K')
42
#define IFF_AUTH_CHUNK FOURCC_CHUNK('A', 'U', 'T', 'H')
43
#define IFF_BMHD_CHUNK FOURCC_CHUNK('B', 'M', 'H', 'D')
44
#define IFF_BODY_CHUNK FOURCC_CHUNK('B', 'O', 'D', 'Y')
45
#define IFF_CAMG_CHUNK FOURCC_CHUNK('C', 'A', 'M', 'G')
46
#define IFF_CCRT_CHUNK FOURCC_CHUNK('C', 'C', 'R', 'T')
47
#define IFF_CHAN_CHUNK FOURCC_CHUNK('C', 'H', 'A', 'N')
48
#define IFF_CMAP_CHUNK FOURCC_CHUNK('C', 'M', 'A', 'P')
49
#define IFF_COPY_CHUNK FOURCC_CHUNK('(', 'c', ')', ' ')
50
#define IFF_CRNG_CHUNK FOURCC_CHUNK('C', 'R', 'N', 'G')
51
#define IFF_DEST_CHUNK FOURCC_CHUNK('D', 'E', 'S', 'T')
52
#define IFF_DLTA_CHUNK FOURCC_CHUNK('D', 'L', 'T', 'A')
53
#define IFF_DPAN_CHUNK FOURCC_CHUNK('D', 'P', 'A', 'N')
54
#define IFF_DPI_CHUNK FOURCC_CHUNK('D', 'P', 'I', ' ')
55
#define IFF_DPPS_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'S')
56
#define IFF_DPPV_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'V')
57
#define IFF_DRNG_CHUNK FOURCC_CHUNK('D', 'R', 'N', 'G')
58
#define IFF_FACE_CHUNK FOURCC_CHUNK('F', 'A', 'C', 'E')
59
#define IFF_FADE_CHUNK FOURCC_CHUNK('F', 'A', 'D', 'E')
60
#define IFF_FORM_CHUNK FOURCC_CHUNK('F', 'O', 'R', 'M')
61
#define IFF_FVER_CHUNK FOURCC_CHUNK('F', 'V', 'E', 'R')
62
#define IFF_GRAB_CHUNK FOURCC_CHUNK('G', 'R', 'A', 'B')
63
#define IFF_ILBM_CHUNK FOURCC_CHUNK('I', 'L', 'B', 'M')
64
#define IFF_INS1_CHUNK FOURCC_CHUNK('I', 'N', 'S', '1')
65
#define IFF_IMRT_CHUNK FOURCC_CHUNK('I', 'M', 'R', 'T')
66
#define IFF_JUNK_CHUNK FOURCC_CHUNK('J', 'U', 'N', 'K')
67
#define IFF_LIST_CHUNK FOURCC_CHUNK('L', 'I', 'S', 'T')
68
#define IFF_MHDR_CHUNK FOURCC_CHUNK('M', 'H', 'D', 'R')
69
#define IFF_NAME_CHUNK FOURCC_CHUNK('N', 'A', 'M', 'E')
70
#define IFF_PAN_CHUNK FOURCC_CHUNK('P', 'A', 'N', ' ')
71
#define IFF_PROP_CHUNK FOURCC_CHUNK('P', 'R', 'O', 'P')
72
#define IFF_RLSE_CHUNK FOURCC_CHUNK('R', 'L', 'S', 'E')
73
#define IFF_SAMP_CHUNK FOURCC_CHUNK('S', 'A', 'M', 'P')
74
#define IFF_SEQN_CHUNK FOURCC_CHUNK('S', 'E', 'Q', 'N')
75
#define IFF_SHDR_CHUNK FOURCC_CHUNK('S', 'H', 'D', 'R')
76
#define IFF_SMUS_CHUNK FOURCC_CHUNK('S', 'M', 'U', 'S')
77
#define IFF_SPRT_CHUNK FOURCC_CHUNK('S', 'P', 'R', 'T')
78
#define IFF_TEXT_CHUNK FOURCC_CHUNK('T', 'E', 'X', 'T')
79
#define IFF_TINY_CHUNK FOURCC_CHUNK('T', 'I', 'N', 'Y')
80
#define IFF_TRAK_CHUNK FOURCC_CHUNK('T', 'R', 'A', 'K')
81
#define IFF_VHDR_CHUNK FOURCC_CHUNK('V', 'H', 'D', 'R')
82
83
/* IFF-ILBM Definitions */
84
85
/* Use this constant instead of sizeof(ColorRegister). */
86
#define PIC_SIZE_OF_COLOR_REGISTER 3
87
88
/* Maximum number of bitplanes storable in BitMap structure */
89
#define PIC_MAXAMDEPTH 8
90
91
/* Maximum planes we can save */
92
#define PIC_MAXSAVEDEPTH 24
93
94
/* Masking techniques */
95
#define PIC_MASK_NONE 0
96
#define PIC_MASK_HASMASK 1
97
#define PIC_MASK_HASTRANSPARENTMASK 2
98
#define PIC_MASK_LASSO 3
99
100
/* Compression techniques */
101
#define PIC_COMPRESSION_NONE 0
102
#define PIC_COMPRESSION_BYTERUN1 1
103
104
#define VIDEOBUFSIZE 128*1024
105
106
#define CAMG_LACE 0x0004
/* Interlaced Modi */
107
#define CAMG_EHB 0x0080
/* extra halfe brite */
108
#define CAMG_HAM 0x0800
/* hold and modify */
109
#define CAMG_HIRES 0x8000
/* Hires Modi */
110
111
#define CAMG_PAL 0x00021000
/* Hires Modi */
112
#define CAMG_NTSC 0x00011000
/* Hires Modi */
113
114
#define HAMBITS_CMAP 0
/* take color from colormap */
115
#define HAMBITS_BLUE 1
/* modify blue component */
116
#define HAMBITS_RED 2
/* modify red component */
117
#define HAMBITS_GREEN 3
/* modify green component */
118
119
static
const
int
bitplainoffeset
[] = {
120
1, 2, 4, 8,
121
16, 32, 64, 128,
122
1, 2, 4, 8,
123
16, 32, 64, 128,
124
1, 2, 4, 8,
125
16, 32, 64, 128
126
};
127
128
/* ---------- BitMapHeader ---------------------------------------------*/
129
/* Required Bitmap header (BMHD) structure describes an ILBM */
130
typedef
struct
{
131
uint16_t
w
;
/* raster width in pixels */
132
uint16_t
h
;
/* raster height in pixels */
133
int16_t
x
;
/* raster width in pixels */
134
int16_t
y
;
/* raster height in pixels */
135
uint8_t
nplanes
;
/* # source bitplanes */
136
uint8_t
masking
;
/* masking technique */
137
uint8_t
compression
;
/* compression algoithm */
138
uint8_t
pad1
;
/* UNUSED. For consistency, put 0 here. */
139
uint16_t
transparentColor
;
/* transparent "colour number" */
140
uint8_t
xaspect
;
/* aspect ratio, a rational number x/y */
141
uint8_t
yaspect
;
/* aspect ratio, a rational number x/y */
142
int16_t
pagewidth
;
/* source "page" size in pixels */
143
int16_t
pageheight
;
/* source "page" size in pixels */
144
}
BitMapHeader
;
145
146
/* ---------- ColorRegister --------------------------------------------*/
147
/* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */
148
typedef
struct
{
149
uint8_t
cmap_red
;
/* red color component */
150
uint8_t
cmap_green
;
/* green color component */
151
uint8_t
cmap_blue
;
/* blue color component */
152
}
ColorRegister
;
153
154
/* ---------- Point2D --------------------------------------------------*/
155
/* A Point2D is stored in a GRAB chunk. */
156
typedef
struct
{
157
int16_t
x
;
/* coordinates x pixels */
158
int16_t
y
;
/* coordinates y pixels */
159
}
Point2D
;
160
161
/* ---------- DestMerge ------------------------------------------------*/
162
/* A DestMerge is stored in a DEST chunk. */
163
typedef
struct
{
164
uint8_t
depth
;
/* # bitplanes in the original source */
165
uint8_t
pad1
;
/* UNUSED; for consistency store 0 here */
166
uint16_t
plane_pick
;
/* how to scatter source bitplanes into destination */
167
uint16_t
plane_onoff
;
/* default bitplane data for planePick */
168
uint16_t
plane_mask
;
/* selects which bitplanes to store into */
169
}
DestMerge
;
170
171
/* ---------- SpritePrecedence -----------------------------------------*/
172
/* A SpritePrecedence is stored in a SPRT chunk. */
173
typedef
uint16_t
SpritePrecedence
;
174
175
/* ---------- Camg Amiga Viewport Mode Display ID ----------------------*/
176
/* The CAMG chunk is used to store the Amiga display mode in which
177
* an ILBM is meant to be displayed. This is very important, especially
178
* for special display modes such as HAM and HALFBRITE where the
179
* pixels are interpreted differently.
180
* Under V37 and higher, store a 32-bit Amiga DisplayID (aka. ModeID)
181
* in the ULONG ViewModes CAMG variable (from GetVPModeID(viewport)).
182
* Pre-V37, instead store the 16-bit viewport->Modes.
183
* See the current IFF manual for information on screening for bad CAMG
184
* chunks when interpreting a CAMG as a 32-bit DisplayID or 16-bit ViewMode.
185
* The chunk's content is declared as a ULONG.
186
*/
187
typedef
struct
{
188
uint32_t
view_modes
;
189
}
CamgChunk
;
190
191
/* ---------- CRange cycling chunk -------------------------------------*/
192
#define RNG_NORATE 36
/* Dpaint uses this rate to mean non-active */
193
/* A CRange is store in a CRNG chunk. */
194
typedef
struct
{
195
int16_t
pad1
;
/* reserved for future use; store 0 here */
196
int16_t
rate
;
/* 60/sec=16384, 30/sec=8192, 1/sec=16384/60=273 */
197
int16_t
active
;
/* bit0 set = active, bit 1 set = reverse */
198
uint8_t
low
;
/* lower color registers selected */
199
uint8_t
high
;
/* upper color registers selected */
200
}
CRange
;
201
202
/* ---------- Ccrt (Graphicraft) cycling chunk -------------------------*/
203
/* A Ccrt is stored in a CCRT chunk. */
204
typedef
struct
{
205
int16_t
direction
;
/* 0=don't cycle, 1=forward, -1=backwards */
206
uint8_t
start
;
/* range lower */
207
uint8_t
end
;
/* range upper */
208
int32_t
seconds
;
/* seconds between cycling */
209
int32_t
microseconds
;
/* msecs between cycling */
210
int16_t
pad
;
/* future exp - store 0 here */
211
}
CcrtChunk
;
212
213
/* ---------- DPIHeader chunk ------------------------------------------*/
214
/* A DPIHeader is stored in a DPI chunk. */
215
typedef
struct
{
216
int16_t
x
;
217
int16_t
y
;
218
}
DPIHeader
;
219
220
/* IFF-8SVX/16SV Definitions */
221
222
#define MONO 0L
223
#define PAN 1L
224
#define LEFT 2L
225
#define RIGHT 4L
226
#define STEREO 6L
227
228
#define SND_COMPRESSION_NONE 0
229
#define SND_COMPRESSION_FIBONACCI 1
230
#define SND_COMPRESSION_EXPONENTIAL 2
231
232
#define PREAMBLE_SIZE 8
233
#define IFF_JUNK_SIZE 8
234
#define IFF_SIGNATURE_SIZE 12
235
#define PCM_BLOCK_ALIGN 1024
236
237
#define max_volume 65536
/* Unity = Fixed 1.0 = maximum volume */
238
239
static
const
int8_t
fibonacci
[] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 };
240
241
static
const
int8_t
exponential
[] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 };
242
243
typedef
struct
{
244
uint32_t
oneShotHiSamples
;
/* # samples in the high octave 1-shot part */
245
uint32_t
repeatHiSamples
;
/* # samples in the high octave repeat part */
246
uint32_t
samplesPerHiCycle
;
/* # samples/cycle in high octave, else 0 */
247
uint16_t
samplesPerSec
;
/* data sampling rate */
248
uint8_t
ctOctave
;
/* # of octaves of waveforms */
249
uint8_t
sCompression
;
/* data compression technique used */
250
uint32_t
volume
;
/* playback nominal volume from 0 to Unity
251
* (full volume). Map this value into
252
* the output hardware's dynamic range.
253
*/
254
}
Voice8Header
;
255
256
typedef
struct
{
257
uint16_t
duration
;
/* segment duration in milliseconds */
258
uint32_t
dest
;
/* destination volume factor */
259
}
EGPoint
;
260
261
/* IFF-ANIM Definitions */
262
263
#define IFF_ANHD_ILBM 0
264
#define IFF_ANHD_XOR 1
265
#define IFF_ANHD_LDELTA 2
266
#define IFF_ANHD_SDELTA 3
267
#define IFF_ANHD_SLDELTA 4
268
#define IFF_ANHD_BVDELTA 5
269
#define IFF_ANHD_STEREOO5 6
270
#define IFF_ANHD_OPT7 7
271
#define IFF_ANHD_OPT8 8
272
#define IFF_ANHD_ASCIIJ 74
273
274
/* ---------- AnimHeader ----------------------------------------------*/
275
/* Required Anim Header (anhd) structure describes an ANIM-Frame */
276
typedef
struct
{
277
uint8_t
operation
;
/* The compression method:
278
* 0 set directly (normal ILBM BODY),
279
* 1 XOR ILBM mode,
280
* 2 Long Delta mode,
281
* 3 Short Delta mode,
282
* 4 Generalized short/long Delta mode,
283
* 5 Byte Vertical Delta mode
284
* 6 Stereo op 5 (third party)
285
* 74 (ascii 'J') reserved for Eric Graham's
286
* compression technique
287
*/
288
uint8_t
mask
;
/* (XOR mode only - plane mask where each
289
* bit is set =1 if there is data and =0
290
* if not.)
291
*/
292
uint16_t
w
;
/* (XOR mode only - width and height of the */
293
uint16_t
h
;
/* area represented by the BODY to eliminate */
294
/* unnecessary un-changed data) */
295
int16_t
x
;
/* (XOR mode only - position of rectangular */
296
int16_t
y
;
/* area representd by the BODY) */
297
uint32_t
abs_time
;
/* (currently unused - timing for a frame */
298
/* relative to the time the first frame */
299
/* was displayed - in jiffies (1/60 sec)) */
300
uint32_t
rel_time
;
/* (timing for frame relative to time */
301
/* previous frame was displayed - in */
302
/* jiffies (1/60 sec)) */
303
uint8_t
interleave
;
/* (unused so far - indicates how may frames */
304
/* back this data is to modify. =0 defaults */
305
/* to indicate two frames back (for double */
306
/* buffering). =n indicates n frames back. */
307
/* The main intent here is to allow values */
308
/* of =1 for special applications where */
309
/* frame data would modify the immediately */
310
/* previous frame) */
311
uint8_t
pad0
;
/* Pad byte, not used at present. */
312
uint32_t
bits
;
/* 32 option bits used by options=4 and 5. */
313
/* At present only 6 are identified, but the */
314
/* rest are set =0 so they can be used to */
315
/* implement future ideas. These are defined*/
316
/* for option 4 only at this point. It is */
317
/* recommended that all bits be set =0 for */
318
/* option 5 and that any bit settings */
319
/* used in the future (such as for XOR mode) */
320
/* be compatible with the option 4 */
321
/* bit settings. Player code should check */
322
/*undefined bits in options 4 and 5 to assure*/
323
/* they are zero. */
324
/* */
325
/* The six bits for current use are: */
326
/* */
327
/* bit # set =0 set =1 */
328
/* ========================================= */
329
/* 0 short data long data */
330
/* 1 set XOR */
331
/* 2 separate info one info list */
332
/* for each plane for all planes*/
333
/* 3 not RLC RLC(run length c.)*/
334
/* 4 horizontal vertical */
335
/* 5 short info offsets long info offs.*/
336
uint8_t pad[16];
/* This is a pad for future use for future */
337
/* compression modes. */
338
}
AnimHeader
;
339
340
/* ---------- DPAnim-Chunk ----------------------------------------------*/
341
/* Deluxe Paint Anim (DPAN) Chunk */
342
typedef
struct
{
343
uint16_t
version
;
/* Version */
344
uint16_t
nframes
;
/* number of frames in the animation.*/
345
uint8_t
fps
;
/* frames per second */
346
uint8_t
unused1
;
347
uint8_t
unused2
;
348
uint8_t
unused3
;
349
}
DPAnimChunk
;
350
351
#endif
/* IFFP_IFF_H */
AnimHeader::operation
uint8_t operation
Definition:
iff.h:277
Voice8Header::ctOctave
uint8_t ctOctave
Definition:
iff.h:248
BitMapHeader::xaspect
uint8_t xaspect
Definition:
iff.h:140
Voice8Header
Definition:
iff.h:243
DPAnimChunk
Definition:
iff.h:342
CRange::active
int16_t active
Definition:
iff.h:197
BitMapHeader::transparentColor
uint16_t transparentColor
Definition:
iff.h:139
AnimHeader::y
int16_t y
Definition:
iff.h:296
ColorRegister::cmap_blue
uint8_t cmap_blue
Definition:
iff.h:151
Voice8Header::samplesPerSec
uint16_t samplesPerSec
Definition:
iff.h:247
AnimHeader::bits
uint32_t bits
Definition:
iff.h:312
CamgChunk::view_modes
uint32_t view_modes
Definition:
iff.h:188
DestMerge
Definition:
iff.h:163
CRange
Definition:
iff.h:194
ColorRegister::cmap_red
uint8_t cmap_red
Definition:
iff.h:149
CamgChunk
Definition:
iff.h:187
DPAnimChunk::unused1
uint8_t unused1
Definition:
iff.h:346
AnimHeader::abs_time
uint32_t abs_time
Definition:
iff.h:297
ColorRegister
Definition:
iff.h:148
BitMapHeader::nplanes
uint8_t nplanes
Definition:
iff.h:135
EGPoint::dest
uint32_t dest
Definition:
iff.h:258
BitMapHeader::yaspect
uint8_t yaspect
Definition:
iff.h:141
CcrtChunk::end
uint8_t end
Definition:
iff.h:207
Voice8Header::samplesPerHiCycle
uint32_t samplesPerHiCycle
Definition:
iff.h:246
Point2D
Definition:
iff.h:156
AnimHeader::w
uint16_t w
Definition:
iff.h:292
Point2D::y
int16_t y
Definition:
iff.h:158
DestMerge::pad1
uint8_t pad1
Definition:
iff.h:165
Voice8Header::sCompression
uint8_t sCompression
Definition:
iff.h:249
AnimHeader::interleave
uint8_t interleave
Definition:
iff.h:303
DPAnimChunk::unused3
uint8_t unused3
Definition:
iff.h:348
bitplainoffeset
static const int bitplainoffeset[]
Definition:
iff.h:119
DestMerge::depth
uint8_t depth
Definition:
iff.h:164
BitMapHeader::pad1
uint8_t pad1
Definition:
iff.h:138
AnimHeader::pad0
uint8_t pad0
Definition:
iff.h:311
DPIHeader::y
int16_t y
Definition:
iff.h:217
BitMapHeader::pagewidth
int16_t pagewidth
Definition:
iff.h:142
BitMapHeader::pageheight
int16_t pageheight
Definition:
iff.h:143
CRange::rate
int16_t rate
Definition:
iff.h:196
AnimHeader::rel_time
uint32_t rel_time
Definition:
iff.h:300
exponential
static const int8_t exponential[]
Definition:
iff.h:241
ColorRegister::cmap_green
uint8_t cmap_green
Definition:
iff.h:150
CcrtChunk::start
uint8_t start
Definition:
iff.h:206
DPIHeader
Definition:
iff.h:215
BitMapHeader
Definition:
iff.h:130
AnimHeader::h
uint16_t h
Definition:
iff.h:293
DPIHeader::x
int16_t x
Definition:
iff.h:216
DestMerge::plane_pick
uint16_t plane_pick
Definition:
iff.h:166
fibonacci
static const int8_t fibonacci[]
Definition:
iff.h:239
DPAnimChunk::version
uint16_t version
Definition:
iff.h:343
AnimHeader
Definition:
iff.h:276
CcrtChunk::seconds
int32_t seconds
Definition:
iff.h:208
CRange::low
uint8_t low
Definition:
iff.h:198
CcrtChunk
Definition:
iff.h:204
DestMerge::plane_mask
uint16_t plane_mask
Definition:
iff.h:168
DestMerge::plane_onoff
uint16_t plane_onoff
Definition:
iff.h:167
BitMapHeader::w
uint16_t w
Definition:
iff.h:131
CcrtChunk::pad
int16_t pad
Definition:
iff.h:210
DPAnimChunk::fps
uint8_t fps
Definition:
iff.h:345
CcrtChunk::direction
int16_t direction
Definition:
iff.h:205
Point2D::x
int16_t x
Definition:
iff.h:157
Voice8Header::volume
uint32_t volume
Definition:
iff.h:250
CRange::high
uint8_t high
Definition:
iff.h:199
AnimHeader::x
int16_t x
Definition:
iff.h:295
CRange::pad1
int16_t pad1
Definition:
iff.h:195
DPAnimChunk::nframes
uint16_t nframes
Definition:
iff.h:344
BitMapHeader::compression
uint8_t compression
Definition:
iff.h:137
Voice8Header::oneShotHiSamples
uint32_t oneShotHiSamples
Definition:
iff.h:244
EGPoint
Definition:
iff.h:256
BitMapHeader::h
uint16_t h
Definition:
iff.h:132
Voice8Header::repeatHiSamples
uint32_t repeatHiSamples
Definition:
iff.h:245
SpritePrecedence
uint16_t SpritePrecedence
Definition:
iff.h:173
BitMapHeader::masking
uint8_t masking
Definition:
iff.h:136
BitMapHeader::y
int16_t y
Definition:
iff.h:134
CcrtChunk::microseconds
int32_t microseconds
Definition:
iff.h:209
BitMapHeader::x
int16_t x
Definition:
iff.h:133
AnimHeader::mask
uint8_t mask
Definition:
iff.h:288
EGPoint::duration
uint16_t duration
Definition:
iff.h:257
DPAnimChunk::unused2
uint8_t unused2
Definition:
iff.h:347
Generated by
1.8.17