OSDN Git Service

0.2.1
[eliscolors/main.git] / ElisWriter.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 //  ElisWriter.m
24 //  Elis Colors
25 //
26 //  Created by 柳 on 09/09/17.
27 //  Copyright 2009 __MyCompanyName__. All rights reserved.
28 //
29
30 #import "ElisWriter.h"
31 #import "ElisController.h"
32
33 @implementation ElisWriter
34
35 - (void)awakeFromNib
36 {
37     fps = 30;
38     imageCodec = @"pxlt"; // 8BPS rle pxlt 見つけたぞーッ! pxltの圧縮率マジ最高!!
39     imageQuality = [NSNumber numberWithLong:codecLosslessQuality];
40     gamma_table = malloc(sizeof(unsigned char) * 256);
41 }
42
43 - (void)write:(NSString*)path
44 {
45     int frame, i, size, totalFrames;
46     NSImage* image;
47     float seconds;
48     int w, h;
49     unsigned char *buffer, *pixels;
50     QTTime now;
51     NSRect rect;
52     NSBitmapImageRep* rep;
53     
54     [self initializeMovie:path];
55     seconds = [_mainController getHipTime];
56     totalFrames = seconds * fps;
57     w = ProjectMovieSize.size.width;
58     h = ProjectMovieSize.size.height;
59     rect = *(NSRect*)&ProjectMovieSize;
60     
61     buffer = malloc(w*h*3*sizeof(unsigned char));
62     pixels = malloc(w*h*3*sizeof(unsigned char));
63     
64     attrs = [NSDictionary dictionaryWithObjectsAndKeys:imageCodec, QTAddImageCodecType,
65              imageQuality, QTAddImageCodecQuality, 
66              nil];
67     
68     [self readyGammmaTable];
69     
70     // プログレスバーを表示
71     [NSApp beginSheet:_barSheet modalForWindow:_mainWindow
72         modalDelegate:self didEndSelector:nil contextInfo:NULL];
73     
74     
75     for(frame = 1; frame < totalFrames; frame++){
76         now = QTMakeTime(frame, fps);
77         [_mainView getFrameForQTTime:now];
78         [_mainView getCurrentPixelData:rect buffer:buffer];
79         
80         for(i = 0; i < h; i++) // 富豪的に上下反転。テラ強引
81             memcpy(&pixels[i*w*3], &buffer[(h-1-i)*w*3], w*3*sizeof(unsigned char));
82         
83         [self gammaAdjust:pixels size:w*h*3]; // 色味がシフトする分をガンマ補正。これはひどい。
84         
85         rep = [[NSBitmapImageRep alloc] // RGB RGB RGB ... なバイト列からBitMapImageRepをつくる。
86                initWithBitmapDataPlanes:&pixels
87                pixelsWide:w
88                pixelsHigh:h
89                bitsPerSample:8
90                samplesPerPixel:3
91                hasAlpha:NO
92                isPlanar:NO
93                colorSpaceName:NSCalibratedRGBColorSpace
94                bitmapFormat:NSAlphaNonpremultipliedBitmapFormat
95                bytesPerRow:w*3 
96                bitsPerPixel:24];
97         
98         image = [[NSImage alloc] init];
99         [image addRepresentation:rep];
100         [self performSelectorOnMainThread:@selector(addImage:) withObject:image waitUntilDone:YES];
101 //        [outputMovie addImage:image forDuration:QTMakeTime(1, fps) withAttributes:attrs];
102         [self performSelectorOnMainThread:@selector(changeBarValue:) 
103                                withObject:[NSNumber numberWithDouble:(double)frame/totalFrames] waitUntilDone:YES];
104         
105         if([outputMovie canUpdateMovieFile])
106             [outputMovie updateMovieFile];
107         
108         NSLog(@"%d / %d", frame, totalFrames);
109     }
110     
111     free(buffer);
112     free(pixels);
113     
114     [self addSoundTrack];
115     
116     [outputMovie setVolume:0.2];
117     [outputMovie updateMovieFile];
118     
119     [_barSheet close];
120     [NSApp endSheet:_barSheet];
121 }
122
123 - (void)addImage:(id)image
124 {
125     [outputMovie addImage:image forDuration:QTMakeTime(1, fps) withAttributes:attrs];
126 }
127
128 - (void)initializeMovie:(NSString*)path
129 {
130     outputMovie = [[QTMovie alloc] initToWritableFile:path error:nil];
131 }
132
133 - (void)changeBarValue:(NSNumber*)v
134 {
135     [_bar setDoubleValue:[v doubleValue]];
136 }
137
138 - (void)addSoundTrack
139 {
140     NSMutableArray* soundTrack = [[NSMutableArray alloc] init];
141     QTTrack* track;
142     int i, size;
143     QTTime offset;
144     QTTimeRange mapping;
145     
146     [_mainController getSoundTrack:soundTrack];
147     size = [soundTrack count];
148     
149     for(i = 0; i < size; i += 3){
150         track = [soundTrack objectAtIndex:i];
151         offset = [[soundTrack objectAtIndex:i+1] QTTimeValue];
152         mapping = [[soundTrack objectAtIndex:i+2] QTTimeRangeValue];
153         [outputMovie insertSegmentOfTrack:track timeRange:QTMakeTimeRange(offset, mapping.duration) atTime:mapping.time];
154     }
155 }
156
157 - (void)finalize
158 {
159     free(gamma_table);
160     [super finalize];
161 }
162
163 - (void)readyGammmaTable
164 {
165     int i;
166     
167     for(i = 0; i < 256; i++)
168         gamma_table[i] = (unsigned char)255.0 * pow(i/255.0, 1.0/GAMMA);
169 }
170
171 - (void)gammaAdjust:(unsigned char*)pixels size:(int)s
172 {
173     int i;
174     for(i = 0; i < s; i++)
175         pixels[i] = gamma_table[pixels[i]];
176 }
177
178 @end