1 /* $Id: PictureController.mm,v 1.11 2005/08/01 15:10:44 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.m0k.org/>.
5 It may be used under the terms of the GNU General Public License. */
7 #include "PictureController.h"
9 static int GetAlignedSize( int size )
12 while( result < size )
19 @implementation PictureController
21 - (id)initWithDelegate:(id)del
23 if (self = [super init])
30 - (void) SetHandle: (hb_handle_t *) handle
34 fHasQE = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay );
42 [fWidthStepper setValueWraps: NO];
43 [fWidthStepper setIncrement: 16];
44 [fWidthStepper setMinValue: 64];
45 [fHeightStepper setValueWraps: NO];
46 [fHeightStepper setIncrement: 16];
47 [fHeightStepper setMinValue: 64];
49 [fCropTopStepper setIncrement: 2];
50 [fCropTopStepper setMinValue: 0];
51 [fCropBottomStepper setIncrement: 2];
52 [fCropBottomStepper setMinValue: 0];
53 [fCropLeftStepper setIncrement: 2];
54 [fCropLeftStepper setMinValue: 0];
55 [fCropRightStepper setIncrement: 2];
56 [fCropRightStepper setMinValue: 0];
59 - (void) SetTitle: (hb_title_t *) title
61 hb_job_t * job = title->job;
65 /* Make sure we have big enough buffers */
67 newSize = ( title->width + 2 ) * (title->height + 2 ) * 4;
68 if( fBufferSize < newSize )
70 fBufferSize = newSize;
71 fBuffer = (uint8_t *) realloc( fBuffer, fBufferSize );
75 newSize = ( GetAlignedSize( title->width + 2 ) *
76 GetAlignedSize( title->height + 2 ) * 4 );
78 if( fTexBufSize < newSize )
80 fTexBufSize = newSize;
81 fTexBuf[0] = (uint8_t *) realloc( fTexBuf[0], fTexBufSize );
82 fTexBuf[1] = (uint8_t *) realloc( fTexBuf[1], fTexBufSize );
86 [fWidthStepper setMaxValue: title->width];
87 [fWidthStepper setIntValue: job->width];
88 [fWidthField setIntValue: job->width];
89 [fHeightStepper setMaxValue: title->height];
90 [fHeightStepper setIntValue: job->height];
91 [fHeightField setIntValue: job->height];
92 [fRatioCheck setState: job->keep_ratio ? NSOnState : NSOffState];
93 [fCropTopStepper setMaxValue: title->height/2-2];
94 [fCropBottomStepper setMaxValue: title->height/2-2];
95 [fCropLeftStepper setMaxValue: title->width/2-2];
96 [fCropRightStepper setMaxValue: title->width/2-2];
99 /* we use a popup to show the deinterlace settings */
100 [fDeinterlacePopUp removeAllItems];
101 [fDeinterlacePopUp addItemWithTitle: @"None"];
102 [fDeinterlacePopUp addItemWithTitle: @"Fast"];
103 [fDeinterlacePopUp addItemWithTitle: @"Slow"];
104 [fDeinterlacePopUp addItemWithTitle: @"Slower"];
105 [fDeinterlacePopUp addItemWithTitle: @"Slowest"];
107 /* Set deinterlaces level according to the integer in the main window */
108 [fDeinterlacePopUp selectItemAtIndex: fPictureFilterSettings.deinterlace];
111 [fPARCheck setState: job->pixel_ratio ? NSOnState : NSOffState];
115 [fCropMatrix selectCellAtRow: 1 column:0];
116 /* If auto, lets set the crop steppers according to current job->crop values */
117 [fCropTopStepper setIntValue: job->crop[0]];
118 [fCropTopField setIntValue: job->crop[0]];
119 [fCropBottomStepper setIntValue: job->crop[1]];
120 [fCropBottomField setIntValue: job->crop[1]];
121 [fCropLeftStepper setIntValue: job->crop[2]];
122 [fCropLeftField setIntValue: job->crop[2]];
123 [fCropRightStepper setIntValue: job->crop[3]];
124 [fCropRightField setIntValue: job->crop[3]];
128 [fCropMatrix selectCellAtRow: 0 column:0];
131 /* set the detelecine state according to the state in main window */
132 /* if framerate is 23.976 we do not allow detelecine, otherwise, enable and set according to fDetelecineMainWindow outlet */
133 if (fTitle->rate_base == 1126125)
135 [fDetelecineCheck setEnabled: NO];
136 [fDetelecineCheck setState: NSOffState];
141 [fDetelecineCheck setEnabled: YES];
142 [fDetelecineCheck setState: fPictureFilterSettings.detelecine];
145 /* we use a popup to show the denoise settings */
146 [fDenoisePopUp removeAllItems];
147 [fDenoisePopUp addItemWithTitle: @"None"];
148 [fDenoisePopUp addItemWithTitle: @"Weak"];
149 [fDenoisePopUp addItemWithTitle: @"Medium"];
150 [fDenoisePopUp addItemWithTitle: @"Strong"];
151 /* Set denoises level according to the integer in the main window */
152 [fDenoisePopUp selectItemAtIndex: fPictureFilterSettings.denoise];
154 MaxOutputWidth = job->width;
155 MaxOutputHeight = job->height;
157 [self SettingsChanged: nil];
160 - (void) Display: (int) anim
162 hb_get_preview( fHandle, fTitle, fPicture, fBuffer );
164 /* Backup previous picture (for effects) */
165 memcpy( fTexBuf[1], fTexBuf[0], fTexBufSize );
170 memcpy( fTexBuf[0], fBuffer, fTexBufSize );
174 /* Copy line by line */
175 uint8_t * in = fBuffer;
176 uint8_t * out = fTexBuf[0];
178 for( int i = fTitle->height + 2; i--; )
180 memcpy( out, in, 4 * ( fTitle->width + 2 ) );
181 in += 4 * ( fTitle->width + 2 );
182 out += 4 * GetAlignedSize( fTitle->width + 2 );
187 if( [fEffectsCheck state] == NSOffState )
189 anim = HB_ANIMATE_NONE;
191 else if( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask )
193 anim |= HB_ANIMATE_SLOW;
196 [fPictureGLView Display: anim buffer1: fTexBuf[0]
197 buffer2: fTexBuf[1] width: ( fTitle->width + 2 )
198 height: ( fTitle->height + 2 )];
200 /* Set the Output Display below the Preview Picture*/
201 int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
202 int arpwidth = fTitle->job->pixel_aspect_width;
203 int arpheight = fTitle->job->pixel_aspect_height;
204 int displayparwidth = titlewidth * arpwidth / arpheight;
205 int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
206 if (fTitle->job->pixel_ratio == 1)
209 [fInfoField setStringValue: [NSString stringWithFormat:
210 @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", fTitle->width, fTitle->height,
211 titlewidth, displayparheight, displayparwidth,
218 [fInfoField setStringValue: [NSString stringWithFormat:
219 @"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height,
220 fTitle->job->width, fTitle->job->height]];
224 [fPrevButton setEnabled: ( fPicture > 0 )];
225 [fNextButton setEnabled: ( fPicture < 9 )];
228 - (IBAction) SettingsChanged: (id) sender
230 hb_job_t * job = fTitle->job;
232 if ([fPARCheck state] == 1 )
234 [fWidthStepper setIntValue: MaxOutputWidth];
235 [fWidthField setIntValue: MaxOutputWidth];
237 /* This will show correct anamorphic height values, but
238 show distorted preview picture ratio */
239 [fHeightStepper setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
240 [fHeightField setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
242 /* This will show wrong anamorphic height values, but
243 show proper preview picture ratio */
244 //[fHeightStepper setIntValue: MaxOutputHeight];
245 //[fHeightField setIntValue: MaxOutputHeight];
246 [fRatioCheck setState: 0];
248 [fWidthStepper setEnabled: NO];
249 [fWidthField setEnabled: NO];
250 [fHeightStepper setEnabled: NO];
251 [fHeightField setEnabled: NO];
252 [fRatioCheck setEnabled: NO];
257 [fWidthStepper setEnabled: YES];
258 [fWidthField setEnabled: YES];
259 [fHeightStepper setEnabled: YES];
260 [fHeightField setEnabled: YES];
261 [fRatioCheck setEnabled: YES];
264 job->width = [fWidthStepper intValue];
265 job->height = [fHeightStepper intValue];
266 job->keep_ratio = ( [fRatioCheck state] == NSOnState );
267 fPictureFilterSettings.deinterlace = [fDeinterlacePopUp indexOfSelectedItem];
268 fPictureFilterSettings.denoise = [fDenoisePopUp indexOfSelectedItem];
269 fPictureFilterSettings.detelecine = [fDetelecineCheck state];
270 job->pixel_ratio = ( [fPARCheck state] == NSOnState );
272 autoCrop = ( [fCropMatrix selectedRow] == 0 );
273 [fCropTopStepper setEnabled: !autoCrop];
274 [fCropBottomStepper setEnabled: !autoCrop];
275 [fCropLeftStepper setEnabled: !autoCrop];
276 [fCropRightStepper setEnabled: !autoCrop];
277 // [fAutoCropMainWindow setStringValue: [NSString stringWithFormat:@"%d",autocrop]];
280 memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
284 job->crop[0] = [fCropTopStepper intValue];
285 job->crop[1] = [fCropBottomStepper intValue];
286 job->crop[2] = [fCropLeftStepper intValue];
287 job->crop[3] = [fCropRightStepper intValue];
290 if( job->keep_ratio )
292 if( sender == fWidthStepper || sender == fRatioCheck ||
293 sender == fCropTopStepper || sender == fCropBottomStepper )
295 hb_fix_aspect( job, HB_KEEP_WIDTH );
296 if( job->height > fTitle->height )
298 job->height = fTitle->height;
299 hb_fix_aspect( job, HB_KEEP_HEIGHT );
304 hb_fix_aspect( job, HB_KEEP_HEIGHT );
305 if( job->width > fTitle->width )
307 job->width = fTitle->width;
308 hb_fix_aspect( job, HB_KEEP_WIDTH );
313 [fWidthStepper setIntValue: job->width];
314 [fWidthField setIntValue: job->width];
315 [fHeightStepper setIntValue: job->height];
316 [fHeightField setIntValue: job->height];
317 [fCropTopStepper setIntValue: job->crop[0]];
318 [fCropTopField setIntValue: job->crop[0]];
319 [fCropBottomStepper setIntValue: job->crop[1]];
320 [fCropBottomField setIntValue: job->crop[1]];
321 [fCropLeftStepper setIntValue: job->crop[2]];
322 [fCropLeftField setIntValue: job->crop[2]];
323 [fCropRightStepper setIntValue: job->crop[3]];
324 [fCropRightField setIntValue: job->crop[3]];
325 /* Sanity Check Here for < 16 px preview to avoid
326 crashing hb_get_preview. In fact, just for kicks
327 lets getting previews at a min limit of 32, since
328 no human can see any meaningful detail below that */
329 if (job->width >= 64 && job->height >= 64)
331 [self Display: HB_ANIMATE_NONE];
335 - (IBAction) PreviousPicture: (id) sender
342 [self Display: HB_ANIMATE_BACKWARD];
345 - (IBAction) NextPicture: (id) sender
352 [self Display: HB_ANIMATE_FORWARD];
355 - (IBAction) ClosePanel: (id) sender
357 if ([delegate respondsToSelector:@selector(pictureSettingsDidChange)])
358 [delegate pictureSettingsDidChange];
360 [NSApp endSheet: fPicturePanel];
361 [fPicturePanel orderOut: self];
368 - (void) setAutoCrop: (BOOL) setting
375 return fPictureFilterSettings.detelecine;
378 - (void) setDetelecine: (int) setting
380 fPictureFilterSettings.detelecine = setting;
385 return fPictureFilterSettings.deinterlace;
388 - (void) setDeinterlace: (int) setting {
389 fPictureFilterSettings.deinterlace = setting;
394 return fPictureFilterSettings.denoise;
397 - (void) setDenoise: (int) setting
399 fPictureFilterSettings.denoise = setting;
402 - (void) showPanelInWindow: (NSWindow *) fWindow forTitle:(hb_title_t *)title {
403 [self loadMyNibFile];
406 newSize.width = 246 + title->width;
407 newSize.height = 80 + title->height;
408 [fPicturePanel setContentSize: newSize];
410 [self SetTitle: title];
412 [NSApp beginSheet: fPicturePanel modalForWindow: fWindow
413 modalDelegate: NULL didEndSelector: NULL contextInfo: NULL];
416 - (BOOL) loadMyNibFile
418 if(![NSBundle loadNibNamed:@"PictureSettings" owner:self])
420 NSLog(@"Warning! Could not load myNib file.\n");