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 - (void) SetHandle: (hb_handle_t *) handle
25 fHasQE = CGDisplayUsesOpenGLAcceleration( kCGDirectMainDisplay );
33 [fWidthStepper setValueWraps: NO];
34 [fWidthStepper setIncrement: 16];
35 [fWidthStepper setMinValue: 64];
36 [fHeightStepper setValueWraps: NO];
37 [fHeightStepper setIncrement: 16];
38 [fHeightStepper setMinValue: 64];
40 [fCropTopStepper setIncrement: 2];
41 [fCropTopStepper setMinValue: 0];
42 [fCropBottomStepper setIncrement: 2];
43 [fCropBottomStepper setMinValue: 0];
44 [fCropLeftStepper setIncrement: 2];
45 [fCropLeftStepper setMinValue: 0];
46 [fCropRightStepper setIncrement: 2];
47 [fCropRightStepper setMinValue: 0];
50 - (void) SetTitle: (hb_title_t *) title
52 hb_job_t * job = title->job;
56 /* Make sure we have big enough buffers */
58 newSize = ( title->width + 2 ) * (title->height + 2 ) * 4;
59 if( fBufferSize < newSize )
61 fBufferSize = newSize;
62 fBuffer = (uint8_t *) realloc( fBuffer, fBufferSize );
66 newSize = ( GetAlignedSize( title->width + 2 ) *
67 GetAlignedSize( title->height + 2 ) * 4 );
69 if( fTexBufSize < newSize )
71 fTexBufSize = newSize;
72 fTexBuf[0] = (uint8_t *) realloc( fTexBuf[0], fTexBufSize );
73 fTexBuf[1] = (uint8_t *) realloc( fTexBuf[1], fTexBufSize );
77 [fWidthStepper setMaxValue: title->width];
78 [fWidthStepper setIntValue: job->width];
79 [fWidthField setIntValue: job->width];
80 [fHeightStepper setMaxValue: title->height];
81 [fHeightStepper setIntValue: job->height];
82 [fHeightField setIntValue: job->height];
83 [fRatioCheck setState: job->keep_ratio ? NSOnState : NSOffState];
84 [fCropTopStepper setMaxValue: title->height/2-2];
85 [fCropBottomStepper setMaxValue: title->height/2-2];
86 [fCropLeftStepper setMaxValue: title->width/2-2];
87 [fCropRightStepper setMaxValue: title->width/2-2];
90 /* we use a popup to show the deinterlace settings */
91 [fDeinterlacePopUp removeAllItems];
92 [fDeinterlacePopUp addItemWithTitle: @"None"];
93 [fDeinterlacePopUp addItemWithTitle: @"Fast"];
94 [fDeinterlacePopUp addItemWithTitle: @"Slow"];
95 [fDeinterlacePopUp addItemWithTitle: @"Slower"];
96 [fDeinterlacePopUp addItemWithTitle: @"Slowest"];
98 /* Set deinterlaces level according to the integer in the main window */
99 [fDeinterlacePopUp selectItemAtIndex: [fDeinterlaceLevelMainWindow intValue]];
102 [fPARCheck setState: job->pixel_ratio ? NSOnState : NSOffState];
103 if ([fAutoCropMainWindow intValue] == 0)
105 [fCropMatrix selectCellAtRow: 1 column:0];
106 /* If auto, lets set the crop steppers according to current job->crop values */
107 [fCropTopStepper setIntValue: job->crop[0]];
108 [fCropTopField setIntValue: job->crop[0]];
109 [fCropBottomStepper setIntValue: job->crop[1]];
110 [fCropBottomField setIntValue: job->crop[1]];
111 [fCropLeftStepper setIntValue: job->crop[2]];
112 [fCropLeftField setIntValue: job->crop[2]];
113 [fCropRightStepper setIntValue: job->crop[3]];
114 [fCropRightField setIntValue: job->crop[3]];
118 [fCropMatrix selectCellAtRow: 0 column:0];
121 /* set the detelecine state according to the state in main window */
122 /* if framerate is 23.976 we do not allow detelecine, otherwise, enable and set according to fDetelecineMainWindow outlet */
123 if (fTitle->rate_base == 1126125 || [[fVidFrameRatePopUpMainWindow titleOfSelectedItem] isEqualToString: @"23.976 (NTSC Film)"])
125 [fDetelecineMainWindow setStringValue: @"No"];
126 [fDetelecineCheck setEnabled: NO];
127 [fDetelecineCheck setState: NSOffState];
132 [fDetelecineCheck setEnabled: YES];
133 if ([[fDetelecineMainWindow stringValue] isEqualToString: @"Yes"])
135 [fDetelecineCheck setState: NSOnState];
139 [fDetelecineCheck setState: NSOffState];
144 /* we use a popup to show the denoise settings */
145 [fDenoisePopUp removeAllItems];
146 [fDenoisePopUp addItemWithTitle: @"None"];
147 [fDenoisePopUp addItemWithTitle: @"Weak"];
148 [fDenoisePopUp addItemWithTitle: @"Medium"];
149 [fDenoisePopUp addItemWithTitle: @"Strong"];
150 /* Set deinterlaces level according to the integer in the main window */
151 [fDenoisePopUp selectItemAtIndex: [fDenoiseMainWindow intValue]];
153 MaxOutputWidth = job->width;
154 MaxOutputHeight = job->height;
156 [self SettingsChanged: nil];
159 - (void) Display: (int) anim
161 hb_get_preview( fHandle, fTitle, fPicture, fBuffer );
163 /* Backup previous picture (for effects) */
164 memcpy( fTexBuf[1], fTexBuf[0], fTexBufSize );
169 memcpy( fTexBuf[0], fBuffer, fTexBufSize );
173 /* Copy line by line */
174 uint8_t * in = fBuffer;
175 uint8_t * out = fTexBuf[0];
177 for( int i = fTitle->height + 2; i--; )
179 memcpy( out, in, 4 * ( fTitle->width + 2 ) );
180 in += 4 * ( fTitle->width + 2 );
181 out += 4 * GetAlignedSize( fTitle->width + 2 );
186 if( [fEffectsCheck state] == NSOffState )
188 anim = HB_ANIMATE_NONE;
190 else if( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask )
192 anim |= HB_ANIMATE_SLOW;
195 [fPictureGLView Display: anim buffer1: fTexBuf[0]
196 buffer2: fTexBuf[1] width: ( fTitle->width + 2 )
197 height: ( fTitle->height + 2 )];
199 /* Set the Output Display below the Preview Picture*/
200 int titlewidth = fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3];
201 int arpwidth = fTitle->job->pixel_aspect_width;
202 int arpheight = fTitle->job->pixel_aspect_height;
203 int displayparwidth = titlewidth * arpwidth / arpheight;
204 int displayparheight = fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1];
205 if (fTitle->job->pixel_ratio == 1)
208 [fInfoField setStringValue: [NSString stringWithFormat:
209 @"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d", fTitle->width, fTitle->height,
210 titlewidth, displayparheight, displayparwidth,
217 [fInfoField setStringValue: [NSString stringWithFormat:
218 @"Source: %dx%d, Output: %dx%d", fTitle->width, fTitle->height,
219 fTitle->job->width, fTitle->job->height]];
223 [fPrevButton setEnabled: ( fPicture > 0 )];
224 [fNextButton setEnabled: ( fPicture < 9 )];
227 - (IBAction) SettingsChanged: (id) sender
229 hb_job_t * job = fTitle->job;
231 if ([fPARCheck state] == 1 )
233 [fWidthStepper setIntValue: MaxOutputWidth];
234 [fWidthField setIntValue: MaxOutputWidth];
236 /* This will show correct anamorphic height values, but
237 show distorted preview picture ratio */
238 [fHeightStepper setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
239 [fHeightField setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
241 /* This will show wrong anamorphic height values, but
242 show proper preview picture ratio */
243 //[fHeightStepper setIntValue: MaxOutputHeight];
244 //[fHeightField setIntValue: MaxOutputHeight];
245 [fRatioCheck setState: 0];
247 [fWidthStepper setEnabled: NO];
248 [fWidthField setEnabled: NO];
249 [fHeightStepper setEnabled: NO];
250 [fHeightField setEnabled: NO];
251 [fRatioCheck setEnabled: NO];
257 [fWidthStepper setEnabled: YES];
258 [fWidthField setEnabled: YES];
259 [fHeightStepper setEnabled: YES];
260 [fHeightField setEnabled: YES];
261 [fRatioCheck setEnabled: YES];
266 job->width = [fWidthStepper intValue];
267 job->height = [fHeightStepper intValue];
268 job->keep_ratio = ( [fRatioCheck state] == NSOnState );
270 /* multilevel deinterlacing popup */
271 [fDeinterlaceLevelMainWindow setStringValue: [NSString stringWithFormat: @"%d",[fDeinterlacePopUp indexOfSelectedItem]]];
272 if ([fDeinterlacePopUp indexOfSelectedItem] == 0)
274 job->deinterlace = 0;
278 job->deinterlace = 1;
281 /* set the detelecine state according to the integer set in the main window field */
282 if ([fDetelecineCheck state] == 1)
284 [fDetelecineMainWindow setStringValue: @"Yes"];
288 [fDetelecineMainWindow setStringValue: @"No"];
291 /* new multilevel deinterlacing popup */
292 [fDenoiseMainWindow setStringValue: [NSString stringWithFormat: @"%d",[fDenoisePopUp indexOfSelectedItem]]];
293 job->pixel_ratio = ( [fPARCheck state] == NSOnState );
297 bool autocrop = ( [fCropMatrix selectedRow] == 0 );
298 [fCropTopStepper setEnabled: !autocrop];
299 [fCropBottomStepper setEnabled: !autocrop];
300 [fCropLeftStepper setEnabled: !autocrop];
301 [fCropRightStepper setEnabled: !autocrop];
302 [fAutoCropMainWindow setStringValue: [NSString stringWithFormat:@"%d",autocrop]];
305 memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
309 job->crop[0] = [fCropTopStepper intValue];
310 job->crop[1] = [fCropBottomStepper intValue];
311 job->crop[2] = [fCropLeftStepper intValue];
312 job->crop[3] = [fCropRightStepper intValue];
315 if( job->keep_ratio )
317 if( sender == fWidthStepper || sender == fRatioCheck ||
318 sender == fCropTopStepper || sender == fCropBottomStepper )
320 hb_fix_aspect( job, HB_KEEP_WIDTH );
321 if( job->height > fTitle->height )
323 job->height = fTitle->height;
324 hb_fix_aspect( job, HB_KEEP_HEIGHT );
329 hb_fix_aspect( job, HB_KEEP_HEIGHT );
330 if( job->width > fTitle->width )
332 job->width = fTitle->width;
333 hb_fix_aspect( job, HB_KEEP_WIDTH );
338 [fWidthStepper setIntValue: job->width];
339 [fWidthField setIntValue: job->width];
340 [fHeightStepper setIntValue: job->height];
341 [fHeightField setIntValue: job->height];
342 [fCropTopStepper setIntValue: job->crop[0]];
343 [fCropTopField setIntValue: job->crop[0]];
344 [fCropBottomStepper setIntValue: job->crop[1]];
345 [fCropBottomField setIntValue: job->crop[1]];
346 [fCropLeftStepper setIntValue: job->crop[2]];
347 [fCropLeftField setIntValue: job->crop[2]];
348 [fCropRightStepper setIntValue: job->crop[3]];
349 [fCropRightField setIntValue: job->crop[3]];
350 /* Sanity Check Here for < 16 px preview to avoid
351 crashing hb_get_preview. In fact, just for kicks
352 lets getting previews at a min limit of 32, since
353 no human can see any meaningful detail below that */
354 if (job->width >= 64 && job->height >= 64)
356 [self Display: HB_ANIMATE_NONE];
361 - (IBAction) PreviousPicture: (id) sender
368 [self Display: HB_ANIMATE_BACKWARD];
371 - (IBAction) NextPicture: (id) sender
378 [self Display: HB_ANIMATE_FORWARD];
381 - (IBAction) ClosePanel: (id) sender