OSDN Git Service

de87a4a11f372baf49fd44a8fac5e55e1f62258a
[eliscolors/main.git] / ElisEffect.m
1 //  Copyright (c) 2009 Yanagi Asakura
2 //
3 //  This software is provided 'as-is', without any express or implied
4 //  warranty. In no event will the authors be held liable for any damages
5 //  arising from the use of this software.
6 //
7 //  Permission is granted to anyone to use this software for any purpose,
8 //  including commercial applications, and to alter it and redistribute it
9 //  freely, subject to the following restrictions:
10 //
11 //  1. The origin of this software must not be misrepresented; you must not
12 //  claim that you wrote the original software. If you use this software
13 //  in a product, an acknowledgment in the product documentation would be
14 //  appreciated but is not required.
15 //
16 //  2. Altered source versions must be plainly marked as such, and must not be
17 //  misrepresented as being the original software.
18 //
19 //  3. This notice may not be removed or altered from any source
20 //  distribution.
21
22 //
23 //  ElisEffect.m
24 //  Elis Colors
25 //
26 //  Created by 柳 on 09/09/15.
27 //  Copyright 2009 __MyCompanyName__. All rights reserved.
28 //
29
30 #import "ElisEffect.h"
31
32
33 @implementation ElisEffect
34
35 // Elisでは、種類がエフェクトを隠蔽する!
36 - (id)initWithName:(NSString*)aname
37 {
38     [super init];
39     filter = [[CIFilter filterWithName:aname] retain];
40     [filter setDefaults];
41     params = [[NSMutableDictionary alloc] init];
42     attrs = [filter attributes];
43     generator = YES;
44     colors = [[NSMutableArray alloc] init];
45     vecs = [[NSMutableArray alloc] init];
46     affine = [[NSMutableArray alloc] init]; // アフィン変換なエフェクトなんて一つしか使わないのに、これってどうなの。
47     NSDictionary* inputKeys = [filter inputKeys];
48     id key, input;
49     for(key in inputKeys){
50         if([key isEqualToString:@"inputImage"]){
51             generator = NO;
52             continue;
53         }
54         input = [attrs valueForKey:key];
55         if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"CIColor"]){    
56             [self setEffectTrueValueForTime:
57              [NSString stringWithFormat:@"%@ %@", key, @"red"] value:1.0 time:QTZeroTime];
58             [self setEffectTrueValueForTime:
59              [NSString stringWithFormat:@"%@ %@", key, @"green"] value:1.0 time:QTZeroTime];
60             [self setEffectTrueValueForTime:
61              [NSString stringWithFormat:@"%@ %@", key, @"blue"] value:1.0 time:QTZeroTime];
62             [colors addObject:key];
63             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"red"]];
64             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"green"]];
65             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"blue"]];
66         }
67         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"CIVector"]){
68             [self setEffectTrueValueForTime:
69              [NSString stringWithFormat:@"%@ %@", key, @"X"] value:[[input valueForKey:kCIAttributeDefault] X] time:QTZeroTime];
70             [self setEffectTrueValueForTime:
71              [NSString stringWithFormat:@"%@ %@", key, @"Y"] value:[[input valueForKey:kCIAttributeDefault] Y] time:QTZeroTime];
72             [vecs addObject:key];
73             [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"X"]];
74             [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"Y"]];
75         }
76         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSAffineTransform"]){
77 //            [self setEffectTrueValueForTime:
78 //             [NSString stringWithFormat:@"%@ %@", key, @"Position X"] value:0.0 time:QTZeroTime];
79             [self setEffectTrueValueForTime:
80              [NSString stringWithFormat:@"%@ %@", key, @"Scale"] value:1.0 time:QTZeroTime];
81             [self setEffectTrueValueForTime:
82              [NSString stringWithFormat:@"%@ %@", key, @"Angle"] value:0.0 time:QTZeroTime];
83             [affine addObject:key];
84 //            [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Position X"]];
85             [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Scale"]];
86             [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Angle"]];
87         }
88         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSNumber"]){  
89             [self setEffectTrueValueForTime:key value:[[input valueForKey:kCIAttributeDefault] floatValue] time:QTZeroTime];
90         }
91     }   
92     
93     name = [attrs valueForKey:kCIAttributeFilterDisplayName];
94     //    [inputKeys release];
95     
96     return self;
97 }
98
99 - (void)setEffectValue:(NSString*)key value:(id)v
100 {
101     [filter setValue:v forKey:key];
102 }
103
104 // valueは0.0 ~ 1.0。
105 - (void)setEffectValueForTime:(NSString *)key value:(float)v time:(QTTime)time
106 {
107     ElisKeyframe *k;
108     float max, min;
109     if([colors indexOfObject:key] != NSNotFound){
110         max = 255.0;
111         min = 0.0;
112     }else if([vecs indexOfObject:key] != NSNotFound){
113         max = ProjectMovieSize.size.width*2;
114         min = -ProjectMovieSize.size.width*2;
115     }else if([affine indexOfObject:key] != NSNotFound){
116         if([key isEqualToString:@"inputTransform Angle"]){
117             max = ANGLE_MAX;
118             min = ANGLE_MIN;
119         } else {
120             max = 5.0;
121             min = 0.1;
122         }
123     }else{
124         max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue];
125         min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue];
126     }
127     
128     // 適切な値へマップする。
129     v = (max - min)*v + min;
130     
131     if([params valueForKey:key]){
132         k = [params valueForKey:key];
133         [k setValueForTime:v time:time];
134     }
135     else{
136         k = [[ElisKeyframe alloc] init];
137         [k setValueForTime:v time:time];
138         [params setValue:k forKey:key];
139     }
140 }
141
142 // valueは生の値を渡す。
143 - (void)setEffectTrueValueForTime:(NSString *)key value:(float)v time:(QTTime)time
144 {
145     ElisKeyframe *k;
146     
147     if([params valueForKey:key]){
148         k = [params valueForKey:key];
149         [k setValueForTime:v time:time];
150     }
151     else{
152         k = [[ElisKeyframe alloc] init];
153         [k setValueForTime:v time:time];
154         [params setValue:k forKey:key];
155     }
156 }
157
158
159 - (float)getEffectValue:(NSString*)key forTime:(QTTime)time
160 {
161     float max, min;
162     if([colors indexOfObject:key] != NSNotFound){
163         max = 255.0;
164         min = 0.0;
165     }else if([vecs indexOfObject:key] != NSNotFound){
166         max = ProjectMovieSize.size.width*2;
167         min = -ProjectMovieSize.size.width*2;
168     }else if([affine indexOfObject:key] != NSNotFound){
169         if([key isEqualToString:@"inputTransform Angle"]){
170             max = ANGLE_MAX;
171             min = ANGLE_MIN;
172         } else {
173             max = 5.0;
174             min = 0.1;
175         }
176     }else{
177         max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue];
178         min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue];
179     }
180     
181     if([params valueForKey:key])
182         return ([[params valueForKey:key] getValueForTime:time] - min)/(max - min);
183     
184     return 0;
185 }
186
187 - (float)getEffectTrueValue:(NSString*)key forTime:(QTTime)time
188 {
189     if([params valueForKey:key])
190         return [[params valueForKey:key] getValueForTime:time];
191     
192     return 0;
193 }
194
195 - (void)setInputImage:(CIImage*)cm
196 {
197     if(!generator)
198         [filter setValue:cm forKey:@"inputImage"];
199 }
200
201 - (CIImage*)getImage:(QTTime)time
202 {
203     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
204     NSString *key, *sub;
205     CIColor *col;
206     CIVector* vec;
207     int i, size = [colors count];
208     for(i = 0; i < size; i += 4){
209         key = [colors objectAtIndex:i];
210         col = [CIColor colorWithRed:[[params valueForKey:[colors objectAtIndex:i+1]] getValueForTime:time]/255.0 
211                               green:[[params valueForKey:[colors objectAtIndex:i+2]] getValueForTime:time]/255.0
212                                blue:[[params valueForKey:[colors objectAtIndex:i+3]] getValueForTime:time]/255.0];
213         [filter setValue:col forKey:key];
214     }
215     size = [vecs count];
216     for(i = 0; i < size; i += 3){
217         key = [vecs objectAtIndex:i];
218         vec = [CIVector vectorWithX:[[params valueForKey:[vecs objectAtIndex:i+1]] getValueForTime:time]
219                                   Y:[[params valueForKey:[vecs objectAtIndex:i+2]] getValueForTime:time]];
220         [filter setValue:vec forKey:key];
221     }
222     size = [affine count];
223     for(i = 0; i < size; i += 3){
224         key = [affine objectAtIndex:i];
225         NSAffineTransform* aft = [NSAffineTransform transform];
226         [aft scaleBy:[[params valueForKey:[affine objectAtIndex:i+1]] getValueForTime:time]];
227         [aft rotateByDegrees:[[params valueForKey:[affine objectAtIndex:i+2]] getValueForTime:time]*ANGLE_MAX*2];
228         [filter setValue:aft forKey:key];
229     }
230     
231     for(key in params){
232         if([colors indexOfObject:key] == NSNotFound && [vecs indexOfObject:key] == NSNotFound && [affine indexOfObject:key] == NSNotFound)
233             [filter setValue:[NSNumber numberWithFloat:[[params valueForKey:key] getValueForTime:time]] forKey:key];
234     }
235     [pool release];
236     return [filter valueForKey:@"outputImage"];
237 }
238
239 - (NSMutableDictionary*)getParamDictionary
240 {
241     return params;
242 }
243
244 - (NSString*)getName
245 {
246     return name;
247 }
248
249 - (void)removeKeyframe:(NSString*)key
250 {
251     float v = [[params valueForKey:key] getValueForTime:QTZeroTime];
252     ElisKeyframe* k = [[ElisKeyframe alloc] init];
253     [k setValueForTime:v time:QTZeroTime];
254     [params setValue:k forKey:key];
255 }
256
257 - (void)encodeWithCoder:(NSCoder*)encoder
258 {
259     [encoder encodeObject:[attrs valueForKey:kCIAttributeFilterName] forKey:@"filterName"];
260     [encoder encodeObject:name forKey:@"name"];
261     [encoder encodeObject:attrs forKey:@"attrs"];
262     [encoder encodeObject:colors forKey:@"colors"];
263     [encoder encodeObject:vecs forKey:@"vecs"];
264     [encoder encodeObject:affine forKey:@"affine"];
265     [encoder encodeObject:params forKey:@"params"];
266     [encoder encodeBool:generator forKey:@"generator"];
267 }
268
269 - (id)initWithCoder:(NSCoder*)coder
270 {
271     name = [coder decodeObjectForKey:@"name"];
272     attrs = [coder decodeObjectForKey:@"attrs"];
273     colors = [coder decodeObjectForKey:@"colors"];
274     vecs = [coder decodeObjectForKey:@"vecs"];
275     affine = [coder decodeObjectForKey:@"affine"];
276     params = [coder decodeObjectForKey:@"params"];
277     generator = [coder decodeBoolForKey:@"generator"];
278     
279     NSString* filterName = [coder decodeObjectForKey:@"filterName"];
280     filter = [[CIFilter filterWithName:filterName] retain];
281     [filter setDefaults];
282     
283     return self;
284 }
285
286
287 @end