OSDN Git Service

open
[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             [colors addObject:key];
57             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"red"]];
58             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"green"]];
59             [colors addObject:[NSString stringWithFormat:@"%@ %@", key, @"blue"]];
60             [self setEffectTrueValueForTime:
61              [NSString stringWithFormat:@"%@ %@", key, @"red"] value:1.0 time:QTZeroTime];
62             [self setEffectTrueValueForTime:
63              [NSString stringWithFormat:@"%@ %@", key, @"green"] value:1.0 time:QTZeroTime];
64             [self setEffectTrueValueForTime:
65              [NSString stringWithFormat:@"%@ %@", key, @"blue"] value:1.0 time:QTZeroTime];
66         }
67         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"CIVector"]){
68             [vecs addObject:key];
69             [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"X"]];
70             [vecs addObject:[NSString stringWithFormat:@"%@ %@", key, @"Y"]];
71             [self setEffectTrueValueForTime:
72              [NSString stringWithFormat:@"%@ %@", key, @"X"] value:[[input valueForKey:kCIAttributeDefault] X] time:QTZeroTime];
73             [self setEffectTrueValueForTime:
74              [NSString stringWithFormat:@"%@ %@", key, @"Y"] value:[[input valueForKey:kCIAttributeDefault] Y] time:QTZeroTime];
75         }
76         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSAffineTransform"]){
77             [affine addObject:key];
78             [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Scale"]];
79             [affine addObject:[NSString stringWithFormat:@"%@ %@", key, @"Angle"]];
80             [self setEffectTrueValueForTime:
81              [NSString stringWithFormat:@"%@ %@", key, @"Scale"] value:1.0 time:QTZeroTime];
82             [self setEffectTrueValueForTime:
83              [NSString stringWithFormat:@"%@ %@", key, @"Angle"] value:0.0 time:QTZeroTime];
84         }
85         else if([[[attrs valueForKey:key] valueForKey:kCIAttributeClass] isEqualToString:@"NSNumber"]){  
86             [self setEffectTrueValueForTime:key value:[[input valueForKey:kCIAttributeDefault] floatValue] time:QTZeroTime];
87         }
88     }   
89     
90     name = [attrs valueForKey:kCIAttributeFilterDisplayName];
91     //    [inputKeys release];
92     
93     return self;
94 }
95
96 - (void)setEffectValue:(NSString*)key value:(id)v
97 {
98     [filter setValue:v forKey:key];
99 }
100
101 // valueは0.0 ~ 1.0。
102 - (void)setEffectValueForTime:(NSString *)key value:(float)v time:(QTTime)time
103 {
104     ElisKeyframe *k;
105     float max, min;
106     if([colors indexOfObject:key] != NSNotFound){
107         max = 255.0;
108         min = 0.0;
109     }else if([vecs indexOfObject:key] != NSNotFound){
110         max = ProjectMovieSize.size.width*2;
111         min = -ProjectMovieSize.size.width*2;
112     }else if([affine indexOfObject:key] != NSNotFound){
113         if([key isEqualToString:@"inputTransform Angle"]){
114             max = ANGLE_MAX;
115             min = ANGLE_MIN;
116         } else {
117             max = 5.0;
118             min = 0.1;
119         }
120     }else{
121         max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue];
122         min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue];
123     }
124     
125     // 適切な値へマップする。
126     v = (max - min)*v + min;
127     
128     if([params valueForKey:key]){
129         k = [params valueForKey:key];
130         [k setValueForTime:v time:time];
131     }
132     else{
133         k = [[ElisKeyframe alloc] init];
134         [k setValueForTime:v time:time];
135         [params setValue:k forKey:key];
136     }
137 }
138
139 // valueは生の値を渡す。
140 - (void)setEffectTrueValueForTime:(NSString *)key value:(float)v time:(QTTime)time
141 {
142     ElisKeyframe *k;
143     float max, min;
144     if([colors indexOfObject:key] != NSNotFound){
145         max = 255.0;
146         min = 0.0;
147     }else if([vecs indexOfObject:key] != NSNotFound){
148         max = ProjectMovieSize.size.width*2;
149         min = -ProjectMovieSize.size.width*2;
150     }else if([affine indexOfObject:key] != NSNotFound){
151         if([key isEqualToString:@"inputTransform Angle"]){
152             max = ANGLE_MAX;
153             min = ANGLE_MIN;
154         } else {
155             max = 5.0;
156             min = 0.1;
157         }
158     }else{
159         max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue];
160         min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue];
161     } 
162     
163     // min-maxに収まるようマップ
164     if(v < min) v = min;
165     if(v > max) v = max;
166     
167     if([params valueForKey:key]){
168         k = [params valueForKey:key];
169         [k setValueForTime:v time:time];
170     }
171     else{
172         k = [[ElisKeyframe alloc] init];
173         [k setValueForTime:v time:time];
174         [params setValue:k forKey:key];
175     }
176 }
177
178
179 - (float)getEffectValue:(NSString*)key forTime:(QTTime)time
180 {
181     float max, min;
182     if([colors indexOfObject:key] != NSNotFound){
183         max = 255.0;
184         min = 0.0;
185     }else if([vecs indexOfObject:key] != NSNotFound){
186         max = ProjectMovieSize.size.width*2;
187         min = -ProjectMovieSize.size.width*2;
188     }else if([affine indexOfObject:key] != NSNotFound){
189         if([key isEqualToString:@"inputTransform Angle"]){
190             max = ANGLE_MAX;
191             min = ANGLE_MIN;
192         } else {
193             max = 5.0;
194             min = 0.1;
195         }
196     }else{
197         max = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMax] floatValue];
198         min = [[[attrs valueForKey:key] valueForKey:kCIAttributeSliderMin] floatValue];
199     }
200     
201     if([params valueForKey:key])
202         return ([[params valueForKey:key] getValueForTime:time] - min)/(max - min);
203     
204     return 0;
205 }
206
207 - (float)getEffectTrueValue:(NSString*)key forTime:(QTTime)time
208 {
209     if([params valueForKey:key])
210         return [[params valueForKey:key] getValueForTime:time];
211     
212     return 0;
213 }
214
215 - (void)setInputImage:(CIImage*)cm
216 {
217     if(!generator)
218         [filter setValue:cm forKey:@"inputImage"];
219 }
220
221 - (CIImage*)getImage:(QTTime)time
222 {
223     NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
224     NSString *key, *sub;
225     CIColor *col;
226     CIVector* vec;
227     int i, size = [colors count];
228     for(i = 0; i < size; i += 4){
229         key = [colors objectAtIndex:i];
230         col = [CIColor colorWithRed:[[params valueForKey:[colors objectAtIndex:i+1]] getValueForTime:time]/255.0 
231                               green:[[params valueForKey:[colors objectAtIndex:i+2]] getValueForTime:time]/255.0
232                                blue:[[params valueForKey:[colors objectAtIndex:i+3]] getValueForTime:time]/255.0];
233         [filter setValue:col forKey:key];
234     }
235     size = [vecs count];
236     for(i = 0; i < size; i += 3){
237         key = [vecs objectAtIndex:i];
238         vec = [CIVector vectorWithX:[[params valueForKey:[vecs objectAtIndex:i+1]] getValueForTime:time]
239                                   Y:[[params valueForKey:[vecs objectAtIndex:i+2]] getValueForTime:time]];
240         [filter setValue:vec forKey:key];
241     }
242     size = [affine count];
243     for(i = 0; i < size; i += 3){
244         key = [affine objectAtIndex:i];
245         NSAffineTransform* aft = [NSAffineTransform transform];
246         [aft scaleBy:[[params valueForKey:[affine objectAtIndex:i+1]] getValueForTime:time]];
247         [aft rotateByDegrees:[[params valueForKey:[affine objectAtIndex:i+2]] getValueForTime:time]*ANGLE_MAX*2];
248         [filter setValue:aft forKey:key];
249     }
250     
251     for(key in params){
252         if([colors indexOfObject:key] == NSNotFound && [vecs indexOfObject:key] == NSNotFound && [affine indexOfObject:key] == NSNotFound)
253             [filter setValue:[NSNumber numberWithFloat:[[params valueForKey:key] getValueForTime:time]] forKey:key];
254     }
255     [pool release];
256     return [filter valueForKey:@"outputImage"];
257 }
258
259 - (NSMutableDictionary*)getParamDictionary
260 {
261     return params;
262 }
263
264 - (NSString*)getName
265 {
266     return name;
267 }
268
269 - (void)removeKeyframe:(NSString*)key
270 {
271     float v = [[params valueForKey:key] getValueForTime:QTZeroTime];
272     ElisKeyframe* k = [[ElisKeyframe alloc] init];
273     [k setValueForTime:v time:QTZeroTime];
274     [params setValue:k forKey:key];
275 }
276
277 - (void)encodeWithCoder:(NSCoder*)encoder
278 {
279     [encoder encodeObject:[attrs valueForKey:kCIAttributeFilterName] forKey:@"filterName"];
280     [encoder encodeObject:name forKey:@"name"];
281     [encoder encodeObject:attrs forKey:@"attrs"];
282     [encoder encodeObject:colors forKey:@"colors"];
283     [encoder encodeObject:vecs forKey:@"vecs"];
284     [encoder encodeObject:affine forKey:@"affine"];
285     [encoder encodeObject:params forKey:@"params"];
286     [encoder encodeBool:generator forKey:@"generator"];
287 }
288
289 - (id)initWithCoder:(NSCoder*)coder
290 {
291     name = [coder decodeObjectForKey:@"name"];
292     attrs = [coder decodeObjectForKey:@"attrs"];
293     colors = [coder decodeObjectForKey:@"colors"];
294     vecs = [coder decodeObjectForKey:@"vecs"];
295     affine = [coder decodeObjectForKey:@"affine"];
296     params = [coder decodeObjectForKey:@"params"];
297     generator = [coder decodeBoolForKey:@"generator"];
298     
299     NSString* filterName = [coder decodeObjectForKey:@"filterName"];
300     filter = [[CIFilter filterWithName:filterName] retain];
301     [filter setDefaults];
302     
303     return self;
304 }
305
306
307 @end