source: branches/perian-1.1/Subtitles/SubContext.m @ 923

Revision 923, 8.2 KB checked in by astrange, 6 years ago (diff)

Merge trunk to the branch.
Disable ssse3 qpel stuff ( https://roundup.mplayerhq.hu/roundup/ffmpeg/issue463)

Line 
1//
2//  SubContext.m
3//  SSARender2
4//
5//  Created by Alexander Strange on 7/28/07.
6//  Copyright 2007 __MyCompanyName__. All rights reserved.
7//
8
9#import "SubContext.h"
10#import "SubParsing.h"
11
12@implementation SubStyle
13
14SubRGBAColor ParseSSAColor(unsigned rgb)
15{
16        unsigned char r, g, b, a;
17       
18        a = (rgb >> 24) & 0xff;
19        b = (rgb >> 16) & 0xff;
20        g = (rgb >> 8) & 0xff;
21        r = rgb & 0xff;
22       
23        a = 255-a;
24       
25        return (SubRGBAColor){r/255.,g/255.,b/255.,a/255.};
26}
27
28static SubRGBAColor ParseSSAColorString(NSString *c)
29{
30        const char *c_ = [c UTF8String];
31        unsigned int rgb;
32       
33        if (c_[0] == '&') {
34                rgb = strtoul(&c_[2],NULL,16);
35        } else {
36                rgb = strtol(c_,NULL,0);
37        }
38       
39        return ParseSSAColor(rgb);
40}
41
42UInt8 SSA2ASSAlignment(UInt8 a)
43{
44    int h = 1, v = 0;
45        if (a >= 9 && a <= 11) {v = kSubAlignmentMiddle; h = a-8;}
46        if (a >= 5 && a <= 7)  {v = kSubAlignmentTop;    h = a-4;}
47        if (a >= 1 && a <= 3)  {v = kSubAlignmentBottom; h = a;}
48        return v * 3 + h;
49}
50
51void ParseASSAlignment(UInt8 a, UInt8 *alignH, UInt8 *alignV)
52{
53        switch (a) {
54                default: case 1 ... 3: *alignV = kSubAlignmentBottom; break;
55                case 4 ... 6: *alignV = kSubAlignmentMiddle; break;
56                case 7 ... 9: *alignV = kSubAlignmentTop; break;
57        }
58       
59        switch (a) {
60                case 1: case 4: case 7: *alignH = kSubAlignmentLeft; break;
61                default: case 2: case 5: case 8: *alignH = kSubAlignmentCenter; break;
62                case 3: case 6: case 9: *alignH = kSubAlignmentRight; break;
63        }
64}
65
66BOOL ParseFontVerticality(NSString **fontname)
67{
68        if ([*fontname characterAtIndex:0] == '@') {
69                *fontname = [*fontname substringFromIndex:1];
70                return YES;
71        }
72        return NO;
73}
74
75+(SubStyle*)defaultStyleWithDelegate:(SubRenderer*)delegate
76{
77        SubStyle *sty = [[[SubStyle alloc] init] autorelease];
78       
79        sty->name = @"*Default";
80        sty->fontname = @"Helvetica";
81        sty->platformSizeScale = 1;
82        sty->size = 32 * sqrt([delegate aspectRatio] / (4./3.));
83        sty->primaryColor = (SubRGBAColor){1,1,1,1};
84        sty->outlineColor = (SubRGBAColor){0,0,0,1};
85        sty->shadowColor = (SubRGBAColor){0,0,0,1};
86        sty->scaleX = sty->scaleY = 100;
87        sty->tracking = sty->angle = 0;
88        sty->outlineRadius = 1.5;
89        sty->shadowDist = 2;
90        sty->marginL = sty->marginR = sty->marginV = 20;
91        sty->bold = YES;
92        sty->italic = sty->underline = sty->strikeout = NO;
93        sty->alignH = kSubAlignmentCenter;
94        sty->alignV = kSubAlignmentBottom;
95        sty->borderStyle = kSubBorderStyleNormal;
96        sty->ex = [delegate completedStyleParsing:sty];
97        sty->delegate = delegate;
98        return sty;
99}
100
101-(SubStyle*)initWithDictionary:(NSDictionary *)s scriptVersion:(UInt8)version delegate:(SubRenderer*)delegate_
102{
103        if (self = [super init]) {
104                NSString *tmp;
105                delegate = delegate_;
106                NSString *sv;
107                               
108#define sv(fn, n) fn = [[s objectForKey: @""#n] retain]
109#define fv(fn, n) sv = [s objectForKey:@""#n]; fn = sv ? [sv floatValue] : 0.;
110#define iv(fn, n) fn = [[s objectForKey:@""#n] intValue]
111#define bv(fn, n) fn = [[s objectForKey:@""#n] intValue] != 0
112#define cv(fn, n) tmp = [s objectForKey:@""#n]; if (tmp) fn = ParseSSAColorString(tmp);
113               
114                sv(name, Name);
115                sv(fontname, Fontname);
116                fv(size, Fontsize);
117                cv(primaryColor, PrimaryColour);
118                cv(secondaryColor, SecondaryColour);
119                tmp = [s objectForKey:@"BackColour"];
120                if (tmp) outlineColor = shadowColor = ParseSSAColorString(tmp);
121                cv(outlineColor, OutlineColour);
122                cv(shadowColor, ShadowColour);
123                bv(bold, Bold);
124                bv(italic, Italic);
125                bv(underline, Underline);
126                bv(strikeout, Strikeout);
127                fv(scaleX, ScaleX);
128                fv(scaleY, ScaleY);
129                fv(tracking, Spacing);
130                fv(angle, Angle);
131                fv(outlineRadius, Outline);
132                fv(shadowDist, Shadow);
133                iv(marginL, MarginL);
134                iv(marginR, MarginR);
135                iv(marginV, MarginV);
136                iv(borderStyle, BorderStyle);
137               
138                if (!scaleX) scaleX = 100;
139                if (!scaleY) scaleY = 100;
140
141                UInt8 align = [[s objectForKey:@"Alignment"] intValue];
142                if (version == kSubTypeSSA) align = SSA2ASSAlignment(align);
143               
144                ParseASSAlignment(align, &alignH, &alignV);
145               
146                platformSizeScale = 0;
147                ex = [delegate completedStyleParsing:self];
148        }
149       
150        return self;
151}
152
153static NSString *yes(int i) {return i ? @"yes" : @"no";}
154
155static NSString *ColorString(SubRGBAColor *c)
156{
157        return [NSString stringWithFormat:@"{R: %d G: %d B: %d A: %d}", (int)(c->red * 255),
158                                         (int)(c->green * 255), (int)(c->blue * 255), (int)(c->alpha * 255)];
159}
160
161-(NSString *)description
162{
163        static const NSString *alignHStr[] = {@"left", @"center", @"right"};
164        static const NSString *alignVStr[] = {@"bottom", @"middle", @"top"};
165        static const NSString *bstyle[] = {@"normal", @"box"};
166       
167        return [NSString stringWithFormat:@""
168                                         "SubStyle named \"%@\"\n"
169                                         "-Font: %f pt %@\n"
170                                         "-Primary color: %@\n"
171                                         "-Secondary color: %@\n"
172                                         "-Outline: %f px %@\n"
173                                         "-Shadow: %f px %@\n"
174                                         "-Margin: %d px left, %d px right, %d px vertical\n"
175                                         "-Bold: %@ Italic: %@ Underline: %@ Strikeout: %@\n"
176                                         "-Alignment: %@ %@\n"
177                                         "-Border style: %@\n"
178                                         "-Per-font scale: %f\n",
179                                         name, size, fontname, ColorString(&primaryColor),
180                                         ColorString(&secondaryColor), outlineRadius, ColorString(&outlineColor),
181                                         shadowDist, ColorString(&shadowColor), marginL, marginR, marginV,
182                                         yes(bold), yes(italic), yes(underline), yes(strikeout), alignHStr[alignH],
183                                         alignVStr[alignV], bstyle[borderStyle], platformSizeScale];
184}
185
186-(void)dealloc
187{
188        [name release];
189        [fontname release];
190        [delegate releaseStyleExtra:ex];
191        [super dealloc];
192}
193
194-(void)finalize
195{
196        [delegate releaseStyleExtra:ex];
197        [super finalize];
198}
199@end
200
201@implementation SubContext
202
203BOOL IsScriptASS(NSDictionary *headers)
204{       
205        return [[[headers objectForKey:@"ScriptType"] lowercaseString] isEqualToString:@"v4.00+"];
206}
207
208-(void)readHeaders
209{
210        scriptType = IsScriptASS(headers) ? kSubTypeASS : kSubTypeSSA;
211        collisions = [[headers objectForKey:@"Collisions"] isEqualToString:@"Reverse"] ? kSubCollisionsReverse : kSubCollisionsNormal;
212        wrapStyle = [[headers objectForKey:@"WrapStyle"] intValue];
213       
214        NSString *resXS = [headers objectForKey:@"PlayResX"], *resYS = [headers objectForKey:@"PlayResY"];
215       
216        if (resXS) resX = [resXS floatValue];
217        if (resYS) resY = [resYS floatValue];
218       
219        // obscure res rules copied from VSFilter
220        if ((!resXS && !resYS) || (!resX && !resY)) {
221                resX = 384; resY = 288;
222        } else if (!resYS) {
223                resY = (resX == 1280) ? 1024 : (resX / (4./3.));
224        } else if (!resXS) {
225                resX = (resY == 1024) ? 1280 : (resY * (4./3.));
226        }
227}
228
229-(SubContext*)initWithHeaders:(NSDictionary *)headers_ styles:(NSArray *)styles_ extraData:(NSString *)ed delegate:(SubRenderer*)delegate
230{
231        if (self = [super init]) {
232                headertext = [ed retain];
233                headers = [headers_ retain];
234                [self readHeaders];
235               
236                [delegate completedHeaderParsing:self];
237               
238                styles = nil;
239                if (styles_) {
240                        int i, nstyles = [styles_ count];
241                        NSMutableDictionary *sdict = [[NSMutableDictionary alloc] initWithCapacity:nstyles];
242                       
243                        for (i=0; i < nstyles; i++) {
244                                NSDictionary *style = [styles_ objectAtIndex:i];
245                                [sdict setObject:[[[SubStyle alloc] initWithDictionary:style scriptVersion:scriptType delegate:delegate] autorelease]
246                                                                                                forKey:[style objectForKey:@"Name"]];
247                        }
248                       
249                        styles = sdict;
250                }
251               
252                defaultStyle = [styles objectForKey:@"Default"];
253                if (!defaultStyle) defaultStyle = [SubStyle defaultStyleWithDelegate:delegate];
254                [defaultStyle retain];
255               
256        }
257       
258        return self;
259}
260
261-(SubContext*)initWithNonSSAType:(UInt8)type delegate:(SubRenderer*)delegate
262{
263        if (self = [super init]) {
264                resX = 640;
265                resY = 480;
266                scriptType = type;
267                collisions = kSubCollisionsNormal;
268                wrapStyle = kSubLineWrapBottomWider;
269                styles = headers = nil;
270                headertext = nil;
271                [delegate completedHeaderParsing:self];
272
273                defaultStyle = [[SubStyle defaultStyleWithDelegate:delegate] retain];           
274        }
275       
276        return self;
277}
278
279-(void)dealloc
280{
281        [styles release];
282        [defaultStyle release];
283        [headers release];
284        [headertext release];
285        [super dealloc];
286}
287
288-(SubStyle*)styleForName:(NSString *)name
289{
290        SubStyle *sty = [styles objectForKey:name];
291        return sty ? sty : defaultStyle;
292}
293@end
294
295@implementation SubRenderer
296-(void*)completedStyleParsing:(SubStyle*)s {return nil;}
297-(void)completedHeaderParsing:(SubContext*)sc {}
298-(void*)spanExtraFromRenderDiv:(SubRenderDiv*)div {return nil;}
299-(void*)cloneSpanExtra:(SubRenderSpan*)span {return span->ex;}
300-(void)spanChangedTag:(SSATagType)tag span:(SubRenderSpan*)span div:(SubRenderDiv*)div param:(void*)p {}
301-(void)releaseStyleExtra:(void*)ex {}
302-(void)releaseSpanExtra:(void*)ex {}
303-(float)aspectRatio {return 4./3.;}
304@end
Note: See TracBrowser for help on using the repository browser.