forked from CocoaBob/xee
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SWFParser.m
112 lines (82 loc) · 2.25 KB
/
SWFParser.m
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
#import "SWFParser.h"
#import <XADMaster/CSFileHandle.h>
#import <XADMaster/CSZlibHandle.h>
NSString *SWFWrongMagicException=@"SWFWrongMagicException";
NSString *SWFNoMoreTagsException=@"SWFNoMoreTagsException";
@implementation SWFParser
+(SWFParser *)parserWithHandle:(CSHandle *)handle
{
return [[[SWFParser alloc] initWithHandle:handle] autorelease];
}
+(SWFParser *)parserForPath:(NSString *)path
{
CSFileHandle *handle=[CSFileHandle fileHandleForReadingAtPath:path];
return [[[SWFParser alloc] initWithHandle:handle] autorelease];
}
-(id)initWithHandle:(CSHandle *)handle
{
if(self=[super init])
{
fh=[handle retain];
@try { [self parseHeader]; }
@catch(id e) { [self release]; @throw; }
}
return self;
}
-(void)dealloc
{
[fh release];
[super dealloc];
}
-(void)parseHeader
{
uint8_t magic[4];
[fh readBytes:4 toBuffer:magic];
version=magic[3];
totallen=[fh readUInt32LE];
if((magic[0]!='F'&&magic[0]!='C')||magic[1]!='W'||magic[2]!='S')
[NSException raise:SWFWrongMagicException format:@"Not a Shockwave Flash file."];
if(magic[0]=='C')
{
CSZlibHandle *zh=[CSZlibHandle zlibHandleWithHandle:fh];
[fh release];
fh=[zh retain];
}
rect=SWFParseRect(fh);
fps=[fh readUInt16LE];
frames=[fh readUInt16LE];
nexttag=[fh offsetInFile];
currtag=0;
currlen=0;
currframe=0;
}
-(int)version { return version; }
-(SWFRect)rect { return rect; }
-(int)frames { return frames; }
-(int)framesPerSecond { return fps; }
-(int)nextTag
{
if(!nexttag) [NSException raise:SWFNoMoreTagsException format:@"No more tags available in the SWF file."];
if(currtag==SWFShowFrameTag) currframe++;
[fh seekToFileOffset:nexttag];
int tagval=[fh readUInt16LE];
currtag=tagval>>6;
if(currtag==0)
{
nexttag=0;
return 0;
}
currlen=tagval&0x3f;
if(currlen==0x3f) currlen=[fh readUInt32LE];
nexttag=[fh offsetInFile]+currlen;
return currtag;
}
-(int)tag { return currtag; }
-(int)tagLength { return currlen; }
-(int)tagBytesLeft { return nexttag-[fh offsetInFile]; }
-(int)frame { return currframe; }
-(double)time { return (double)currframe/((double)fps/256.0); }
-(CSHandle *)handle { return fh; }
-(CSHandle *)tagHandle { return [fh subHandleOfLength:[self tagBytesLeft]]; }
-(NSData *)tagContents { return [fh readDataOfLength:[self tagBytesLeft]]; }
@end