summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libhb/common.h58
-rw-r--r--libhb/hb.c382
-rw-r--r--libhb/hb.h3
-rw-r--r--macosx/HBPreviewController.m94
-rw-r--r--macosx/PictureController.m635
5 files changed, 543 insertions, 629 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 236f96895..a5ba78730 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -78,6 +78,9 @@ typedef struct hb_dither_s hb_dither_t;
typedef struct hb_mixdown_s hb_mixdown_t;
typedef struct hb_encoder_s hb_encoder_t;
typedef struct hb_container_s hb_container_t;
+typedef struct hb_rational_s hb_rational_t;
+typedef struct hb_geometry_s hb_geometry_t;
+typedef struct hb_ui_geometry_s hb_ui_geometry_t;
typedef struct hb_job_s hb_job_t;
typedef struct hb_title_set_s hb_title_set_t;
typedef struct hb_title_s hb_title_t;
@@ -133,8 +136,9 @@ void hb_reduce( int *x, int *y, int num, int den );
void hb_reduce64( int64_t *x, int64_t *y, int64_t num, int64_t den );
void hb_limit_rational64( int64_t *x, int64_t *y, int64_t num, int64_t den, int64_t limit );
-#define HB_KEEP_WIDTH 0
-#define HB_KEEP_HEIGHT 1
+#define HB_KEEP_WIDTH 0x01
+#define HB_KEEP_HEIGHT 0x02
+#define HB_KEEP_DISPLAY_ASPECT 0x04
void hb_fix_aspect( hb_job_t * job, int keep );
void hb_job_set_encoder_preset (hb_job_t *job, const char *preset);
@@ -232,6 +236,34 @@ struct hb_container_s
int format;
};
+struct hb_rational_s
+{
+ int num;
+ int den;
+};
+
+struct hb_geometry_s
+{
+ int width;
+ int height;
+ hb_rational_t par;
+};
+
+struct hb_ui_geometry_s
+{
+ int mode; // Anamorphic mode, see job struct anamorphic
+ int keep; // Specifies settings that shouldn't be changed
+ int itu_par; // use dvd dimensions to determine PAR
+ int modulus; // pixel alignment for loose anamorphic
+ int crop[4]; // Pixels cropped from source before scaling
+ int width; // destination storage width
+ int height; // destination storage height
+ int maxWidth; // max destination storage width
+ int maxHeight; // max destination storage height
+ hb_rational_t par; // Pixel aspect used in custom anamorphic
+ hb_rational_t dar; // Display aspect used in custom anamorphic
+};
+
// Update win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_subtitle_config_s.cs when changing this struct
struct hb_subtitle_config_s
{
@@ -379,6 +411,14 @@ struct hb_title_set_s
extern int hb_gui_use_hwd_flag;
+typedef enum
+{
+ HB_ANAMORPHIC_NONE,
+ HB_ANAMORPHIC_STRICT,
+ HB_ANAMORPHIC_LOOSE,
+ HB_ANAMORPHIC_CUSTOM
+} hb_anamorphic_mode_t;
+
/******************************************************************************
* hb_job_t: settings to be filled by the UI
* Update win/CS/HandBrake.Interop/HandBrakeInterop/HbLib/hb_job_s.cs when changing this struct
@@ -422,13 +462,13 @@ struct hb_job_s
struct
{
- int mode;
- int itu_par;
- int par_width;
- int par_height;
- int dar_width; // 0 if normal
- int dar_height; // 0 if normal
- int keep_display_aspect;
+ hb_anamorphic_mode_t mode;
+ int itu_par;
+ int par_width;
+ int par_height;
+ int dar_width; // 0 if normal
+ int dar_height; // 0 if normal
+ int keep_display_aspect;
} anamorphic;
int modulus;
diff --git a/libhb/hb.c b/libhb/hb.c
index 303781cc5..d1e494195 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -913,77 +913,78 @@ int hb_detect_comb( hb_buffer_t * buf, int color_equal, int color_diff, int thre
}
/**
- * Calculates job width and height for anamorphic content,
+ * Calculates destination width and height for anamorphic content
*
- * @param job Handle to hb_job_t
- * @param output_width Pointer to returned storage width
- * @param output_height Pointer to returned storage height
- * @param output_par_width Pointer to returned pixel width
- * @param output_par_height Pointer to returned pixel height
+ * Returns calculated geometry
+ * @param source_geometry - Pointer to source geometry info
+ * @param ui_geometry - Pointer to requested destination parameters
*/
-void hb_set_anamorphic_size( hb_job_t * job,
- int *output_width, int *output_height,
- int *output_par_width, int *output_par_height )
+void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
+ hb_ui_geometry_t *ui_geo,
+ hb_geometry_t *result)
{
+ hb_rational_t in_par, out_par;
+ int keep_display_aspect = !!(ui_geo->keep & HB_KEEP_DISPLAY_ASPECT);
+ int keep_height = !!(ui_geo->keep & HB_KEEP_HEIGHT);
+
/* Set up some variables to make the math easier to follow. */
- hb_title_t * title = job->title;
- int cropped_width = title->width - job->crop[2] - job->crop[3] ;
- int cropped_height = title->height - job->crop[0] - job->crop[1] ;
- double storage_aspect = (double)cropped_width / (double)cropped_height;
- int mod = job->modulus ? job->modulus : 16;
- double aspect = title->aspect;
-
- int64_t pixel_aspect_width = job->anamorphic.par_width;
- int64_t pixel_aspect_height = job->anamorphic.par_height;
+ int cropped_width = src_geo->width - ui_geo->crop[2] - ui_geo->crop[3];
+ int cropped_height = src_geo->height - ui_geo->crop[0] - ui_geo->crop[1];
+ double storage_aspect = (double)cropped_width / cropped_height;
+ int mod = ui_geo->modulus ? EVEN(ui_geo->modulus) : 16;
+
+ // Use 64 bits to avoid overflow till the final hb_reduce() call
+ hb_reduce(&in_par.num, &in_par.den, ui_geo->par.num, ui_geo->par.den);
+ int64_t dst_par_num = in_par.num;
+ int64_t dst_par_den = in_par.den;
+
+ hb_rational_t src_par = src_geo->par;
/* If a source was really NTSC or PAL and the user specified ITU PAR
values, replace the standard PAR values with the ITU broadcast ones. */
- if( title->width == 720 && job->anamorphic.itu_par )
+ if (src_geo->width == 720 && ui_geo->itu_par)
{
// convert aspect to a scaled integer so we can test for 16:9 & 4:3
// aspect ratios ignoring insignificant differences in the LSBs of
// the floating point representation.
- int iaspect = aspect * 9.;
+ int iaspect = src_geo->width * src_par.num * 9. /
+ (src_geo->height * src_par.den);
/* Handle ITU PARs */
- if (title->height == 480)
+ if (src_geo->height == 480)
{
/* It's NTSC */
if (iaspect == 16)
{
/* It's widescreen */
- pixel_aspect_width = 40;
- pixel_aspect_height = 33;
+ dst_par_num = 40;
+ dst_par_den = 33;
}
else if (iaspect == 12)
{
/* It's 4:3 */
- pixel_aspect_width = 10;
- pixel_aspect_height = 11;
+ dst_par_num = 10;
+ dst_par_den = 11;
}
}
- else if (title->height == 576)
+ else if (src_geo->height == 576)
{
/* It's PAL */
- if(iaspect == 16)
+ if (iaspect == 16)
{
/* It's widescreen */
- pixel_aspect_width = 16;
- pixel_aspect_height = 11;
+ dst_par_num = 16;
+ dst_par_den = 11;
}
else if (iaspect == 12)
{
/* It's 4:3 */
- pixel_aspect_width = 12;
- pixel_aspect_height = 11;
+ dst_par_num = 12;
+ dst_par_den = 11;
}
}
}
- /* Figure out what width the source would display at. */
- int source_display_width = cropped_width * (double)pixel_aspect_width /
- (double)pixel_aspect_height ;
-
/*
3 different ways of deciding output dimensions:
- 1: Strict anamorphic, preserve source dimensions
@@ -993,82 +994,135 @@ void hb_set_anamorphic_size( hb_job_t * job,
int width, height;
int maxWidth, maxHeight;
- maxWidth = MULTIPLE_MOD_DOWN( job->maxWidth, mod );
- maxHeight = MULTIPLE_MOD_DOWN( job->maxHeight, mod );
+ maxWidth = MULTIPLE_MOD_DOWN(ui_geo->maxWidth, mod);
+ maxHeight = MULTIPLE_MOD_DOWN(ui_geo->maxHeight, mod);
+ if (maxWidth && maxWidth < 32)
+ maxWidth = 32;
+ if (maxHeight && maxHeight < 32)
+ maxHeight = 32;
- switch( job->anamorphic.mode )
+ switch (ui_geo->mode)
{
- case 1:
- /* Strict anamorphic */
- *output_width = MULTIPLE_MOD( cropped_width, 2 );
- *output_height = MULTIPLE_MOD( cropped_height, 2 );
- // adjust the source PAR for new width/height
- // new PAR = source PAR * ( old width / new_width ) * ( new_height / old_height )
- pixel_aspect_width = (int64_t)title->pixel_aspect_width * cropped_width * (*output_height);
- pixel_aspect_height = (int64_t)title->pixel_aspect_height * (*output_width) * cropped_height;
- break;
-
- case 2:
+ case HB_ANAMORPHIC_NONE:
+ {
+ double par, cropped_sar, dar;
+ par = (double)src_geo->par.num / src_geo->par.den;
+ cropped_sar = (double)cropped_width / cropped_height;
+ dar = par * cropped_sar;
+
+ /* "None" anamorphic. a.k.a. non-anamorphic
+ * - Uses mod-compliant dimensions, set by user
+ * - Allows users to set the either width *or* height
+ */
+ if (keep_display_aspect)
+ {
+ if (!keep_height)
+ {
+ width = ui_geo->width;
+ height = MULTIPLE_MOD((int)(width / dar), mod);
+ }
+ else
+ {
+ height = ui_geo->height;
+ width = MULTIPLE_MOD((int)(height * dar), mod);
+ }
+ }
+ else
+ {
+ width = ui_geo->width;
+ height = ui_geo->height;
+ }
+ if (maxWidth && (width > maxWidth))
+ {
+ width = maxWidth;
+ height = MULTIPLE_MOD((int)(width / dar), mod);
+ }
+ if (maxHeight && (height > maxHeight))
+ {
+ height = maxHeight;
+ width = MULTIPLE_MOD((int)(height * dar), mod);
+ }
+ dst_par_num = dst_par_den = 1;
+ } break;
+
+ default:
+ case HB_ANAMORPHIC_STRICT:
+ {
+ /* "Strict" anamorphic.
+ * - Uses mod2-compliant dimensions,
+ * - Forces title - crop dimensions
+ */
+ width = MULTIPLE_MOD(cropped_width, 2);
+ height = MULTIPLE_MOD(cropped_height, 2);
+
+ /* Adjust the output PAR for new width/height
+ * Film AR is the source display width / cropped source height.
+ * Output display width is the output height * film AR.
+ * Output PAR is the output display width / output storage width.
+ *
+ * i.e.
+ * source_display_width = cropped_width * source PAR
+ * AR = source_display_width / cropped_height;
+ * output_display_width = height * AR;
+ * par = output_display_width / width;
+ *
+ * When these terms are reduced, you get the following...
+ */
+ dst_par_num = (int64_t)height * cropped_width * src_par.num;
+ dst_par_den = (int64_t)width * cropped_height * src_par.den;
+ } break;
+
+ case HB_ANAMORPHIC_LOOSE:
+ {
/* "Loose" anamorphic.
- - Uses mod16-compliant dimensions,
- - Allows users to set the width
- */
- width = job->width;
- // height: Gets set later, ignore user job->height value
-
- /* Gotta handle bounding dimensions.
- If the width is too big, just reset it with no rescaling.
- Instead of using the aspect-scaled job height,
- we need to see if the job width divided by the storage aspect
- is bigger than the max. If so, set it to the max (this is sloppy).
- If not, set job height to job width divided by storage aspect.
- */
-
- /* Time to get picture width that divide cleanly.*/
- width = MULTIPLE_MOD( width, mod);
-
- if ( maxWidth && (maxWidth < job->width) )
- width = maxWidth;
+ * - Uses mod-compliant dimensions, set by user
+ * - Allows users to set the either width *or* height
+ */
+ if (!keep_height)
+ {
+ width = MULTIPLE_MOD(ui_geo->width, mod);
+ height = MULTIPLE_MOD((int)(width / storage_aspect + 0.5), mod);
+ }
+ else
+ {
+ height = MULTIPLE_MOD(ui_geo->height, mod);
+ width = MULTIPLE_MOD((int)(height * storage_aspect + 0.5), mod);
+ }
- /* Verify these new dimensions don't violate max height and width settings */
- height = ((double)width / storage_aspect) + 0.5;
+ if (maxWidth && (maxWidth < width))
+ {
+ width = maxWidth;
+ height = MULTIPLE_MOD((int)(width / storage_aspect + 0.5), mod);
+ }
- /* Time to get picture height that divide cleanly.*/
- height = MULTIPLE_MOD( height, mod);
-
- if ( maxHeight && (maxHeight < height) )
+ if (maxHeight && (maxHeight < height))
{
height = maxHeight;
- width = ((double)height * storage_aspect) + 0.5;
- width = MULTIPLE_MOD( width, mod);
+ width = MULTIPLE_MOD((int)(height * storage_aspect + 0.5), mod);
}
- /* The film AR is the source's display width / cropped source height.
- The output display width is the output height * film AR.
- The output PAR is the output display width / output storage width. */
- pixel_aspect_width = (int64_t)height * cropped_width * pixel_aspect_width;
- pixel_aspect_height = (int64_t)width * cropped_height * pixel_aspect_height;
-
- /* Pass the results back to the caller */
- *output_width = width;
- *output_height = height;
- break;
-
- case 3:
+ /* Adjust the output PAR for new width/height
+ See comment in HB_ANAMORPHIC_STRICT */
+ dst_par_num = (int64_t)height * cropped_width * src_par.num;
+ dst_par_den = (int64_t)width * cropped_height * src_par.den;
+ } break;
+
+ case HB_ANAMORPHIC_CUSTOM:
+ {
/* Anamorphic 3: Power User Jamboree
- Set everything based on specified values */
-
+
/* Use specified storage dimensions */
- storage_aspect = (double)job->width / (double)job->height;
- width = job->width;
- height = job->height;
-
+ storage_aspect = (double)ui_geo->width / ui_geo->height;
+ width = ui_geo->width;
+ height = ui_geo->height;
+
/* Time to get picture dimensions that divide cleanly.*/
- width = MULTIPLE_MOD( width, mod);
- height = MULTIPLE_MOD( height, mod);
-
+ width = MULTIPLE_MOD(width, mod);
+ height = MULTIPLE_MOD(height, mod);
+
/* Bind to max dimensions */
- if( maxWidth && width > maxWidth )
+ if (maxWidth && width > maxWidth)
{
width = maxWidth;
// If we are keeping the display aspect, then we are going
@@ -1079,64 +1133,128 @@ void hb_set_anamorphic_size( hb_job_t * job,
// But otherwise, PAR and DAR will change the least
// if we stay as close as possible to the requested
// storage aspect.
- if ( !job->anamorphic.keep_display_aspect )
+ if (!keep_display_aspect)
{
- height = ((double)width / storage_aspect) + 0.5;
- height = MULTIPLE_MOD( height, mod);
+ height = width / storage_aspect + 0.5;
+ height = MULTIPLE_MOD(height, mod);
}
}
- if( maxHeight && height > maxHeight )
+ if (maxHeight && height > maxHeight)
{
height = maxHeight;
// Ditto, see comment above
- if ( !job->anamorphic.keep_display_aspect )
+ if (!keep_display_aspect)
{
- width = ((double)height * storage_aspect) + 0.5;
- width = MULTIPLE_MOD( width, mod);
+ width = height * storage_aspect + 0.5;
+ width = MULTIPLE_MOD(width, mod);
}
}
-
- /* That finishes the storage dimensions. On to display. */
- if( job->anamorphic.dar_width && job->anamorphic.dar_height )
+
+ /* That finishes the storage dimensions. On to display. */
+ if (ui_geo->dar.num && ui_geo->dar.den)
{
/* We need to adjust the PAR to produce this aspect. */
- pixel_aspect_width = (int64_t)height * job->anamorphic.dar_width / job->anamorphic.dar_height;
- pixel_aspect_height = width;
+ dst_par_num = (int64_t)height * ui_geo->dar.num /
+ ui_geo->dar.den;
+ dst_par_den = width;
}
else
{
- /* If we're doing ana 3 and not specifying a DAR, care needs to be taken.
- This indicates a PAR is potentially being set by the interface. But
- this is an output PAR, to correct a source, and it should not be assumed
- that it properly creates a display aspect ratio when applied to the source,
- which could easily be stored in a different resolution. */
- if( job->anamorphic.keep_display_aspect )
+ if (keep_display_aspect)
{
- /* We can ignore the possibility of a PAR change */
- pixel_aspect_width = (int64_t)height * ( (double)source_display_width / (double)cropped_height );
- pixel_aspect_height = width;
+ /* We can ignore the possibility of a PAR change
+ * Adjust the output PAR for new width/height
+ * See comment in HB_ANAMORPHIC_STRICT
+ */
+ dst_par_num = (int64_t)height * cropped_width *
+ src_par.num;
+ dst_par_den = (int64_t)width * cropped_height *
+ src_par.den;
}
else
{
- int output_display_width = width * (double)pixel_aspect_width /
- (double)pixel_aspect_height;
- pixel_aspect_width = output_display_width;
- pixel_aspect_height = width;
+ /* If the dimensions were changed by the modulus
+ * or by maxWidth/maxHeight, we also change the
+ * output PAR so that the DAR is unchanged.
+ *
+ * PAR is the requested output display width / storage width
+ * requested output display width is the original
+ * requested width * original requested PAR
+ */
+ dst_par_num = ui_geo->width * dst_par_num;
+ dst_par_den = width * dst_par_den;
}
}
-
- /* Back to caller */
- *output_width = width;
- *output_height = height;
- break;
+ } break;
}
-
+
+ /* Pass the results back to the caller */
+ result->width = width;
+ result->height = height;
+
/* While x264 is smart enough to reduce fractions on its own, libavcodec
* needs some help with the math, so lose superfluous factors. */
- hb_limit_rational64( &pixel_aspect_width, &pixel_aspect_height,
- pixel_aspect_width, pixel_aspect_height, 65535 );
- hb_reduce( output_par_width, output_par_height,
- pixel_aspect_width, pixel_aspect_height );
+ hb_limit_rational64(&dst_par_num, &dst_par_den,
+ dst_par_num, dst_par_den, 65535);
+
+ /* If the user is directling updating PAR, don't override his values */
+ hb_reduce(&out_par.num, &out_par.den, dst_par_num, dst_par_den);
+ if (ui_geo->mode == HB_ANAMORPHIC_CUSTOM && !keep_display_aspect &&
+ out_par.num == in_par.num && out_par.den == in_par.den)
+ {
+ result->par.num = ui_geo->par.num;
+ result->par.den = ui_geo->par.den;
+ }
+ else
+ {
+ hb_reduce(&result->par.num, &result->par.den, dst_par_num, dst_par_den);
+ }
+}
+
+/**
+ * Calculates job width and height for anamorphic content,
+ *
+ * @param job Handle to hb_job_t
+ * @param output_width Pointer to returned storage width
+ * @param output_height Pointer to returned storage height
+ * @param output_par_width Pointer to returned pixel width
+ * @param output_par_height Pointer to returned pixel height
+ */
+void hb_set_anamorphic_size( hb_job_t * job,
+ int *output_width, int *output_height,
+ int *output_par_width, int *output_par_height )
+{
+ hb_geometry_t result;
+ hb_geometry_t src;
+ hb_ui_geometry_t ui_geo;
+
+ src.width = job->title->width;
+ src.height = job->title->height;
+ src.par.num = job->title->pixel_aspect_width;
+ src.par.den = job->title->pixel_aspect_height;
+
+ ui_geo.width = job->width;
+ ui_geo.height = job->height;
+ ui_geo.par.num = job->anamorphic.par_width;
+ ui_geo.par.den = job->anamorphic.par_height;
+
+ ui_geo.modulus = job->modulus;
+ memcpy(ui_geo.crop, job->crop, sizeof(int[4]));
+ ui_geo.maxWidth = job->maxWidth;
+ ui_geo.maxHeight = job->maxHeight;
+ ui_geo.mode = job->anamorphic.mode;
+ ui_geo.keep = 0;
+ if (job->anamorphic.keep_display_aspect)
+ ui_geo.keep = HB_KEEP_DISPLAY_ASPECT;
+ ui_geo.itu_par = job->anamorphic.itu_par;
+ ui_geo.dar.num = job->anamorphic.dar_width;
+ ui_geo.dar.den = job->anamorphic.dar_height;
+
+ hb_set_anamorphic_size2(&src, &ui_geo, &result);
+ *output_width = result.width;
+ *output_height = result.height;
+ *output_par_width = result.par.num;
+ *output_par_height = result.par.den;
}
/**
diff --git a/libhb/hb.h b/libhb/hb.h
index 6939d8082..e958d68d9 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -72,6 +72,9 @@ hb_buffer_t * hb_read_preview( hb_handle_t * h, int title_idx, int preview );
void hb_get_preview( hb_handle_t *, hb_job_t *, int,
uint8_t * );
void hb_set_size( hb_job_t *, double ratio, int pixels );
+void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
+ hb_ui_geometry_t *ui_geo,
+ hb_geometry_t *result);
void hb_set_anamorphic_size( hb_job_t *,
int *output_width, int *output_height,
int *output_par_width, int *output_par_height );
diff --git a/macosx/HBPreviewController.m b/macosx/HBPreviewController.m
index 9d9d2c6fd..d71f996c3 100644
--- a/macosx/HBPreviewController.m
+++ b/macosx/HBPreviewController.m
@@ -54,8 +54,9 @@
#endif
#define BORDER_SIZE 2.0
-#define MIN_WIDTH 480.0
-#define MIN_HEIGHT 360.0
+// make min width and height of preview window large enough for hud
+#define MIN_WIDTH 460.0
+#define MIN_HEIGHT 128.0
#define ANIMATION_DUR 0.2
@@ -356,13 +357,14 @@ typedef enum ViewMode : NSUInteger {
*/
- (void) resizeWindowForViewSize: (NSSize) viewSize
{
- // Figure out the deltas for the new frame area
NSSize currentSize = [[[self window] contentView] frame].size;
- CGFloat deltaX = viewSize.width - currentSize.width;
- CGFloat deltaY = viewSize.height - currentSize.height;
-
- // Now resize the whole panel by those same deltas, but don't exceed the min
NSRect frame = [[self window] frame];
+
+ // Calculate border around content region of the frame
+ int borderX = frame.size.width - currentSize.width;
+ int borderY = frame.size.height - currentSize.height;
+
+ // Make sure the frame is smaller than the screen
NSSize maxSize = [[[self window] screen] visibleFrame].size;
/* if we are not Scale To Screen, put an 10% of visible screen on the window */
@@ -372,40 +374,22 @@ typedef enum ViewMode : NSUInteger {
maxSize.height = maxSize.height * 0.90;
}
- /* Set our min size to the storage size */
- NSSize minSize;
- minSize.width = self.title->width / self.backingScaleFactor;
- minSize.height = self.title->height / self.backingScaleFactor;
+ // Set the new frame size
+ // Add the border to the new frame size so that the content region
+ // of the frame is large enough to accomodate the preview image
+ frame.size.width = viewSize.width + borderX;
+ frame.size.height = viewSize.height + borderY;
- frame.size.width += deltaX;
- frame.size.height += deltaY;
- if( frame.size.width < minSize.width )
- {
- frame.size.width = minSize.width;
- deltaX = frame.size.width - currentSize.width;
- }
- if( frame.size.height < minSize.height )
- {
- frame.size.height = minSize.height;
- //deltaY = frame.size.height - currentSize.height;
- }
/* compare frame to max size of screen */
-
if( frame.size.width > maxSize.width )
{
frame.size.width = maxSize.width;
}
-
if( frame.size.height > maxSize.height )
{
frame.size.height = maxSize.height;
}
- // But now the sheet is off-center, so also shift the origin to center it and
- // keep the top aligned.
- if (frame.size.width != [[self window] frame].size.width)
- frame.origin.x -= (deltaX / 2.0);
-
/* Since upon launch we can open up the preview window if it was open
* the last time we quit (and at the size it was) we want to make
* sure that upon resize we do not have the window off the screen
@@ -414,14 +398,6 @@ typedef enum ViewMode : NSUInteger {
*/
NSSize screenSize = [[[self window] screen] visibleFrame].size;
NSPoint screenOrigin = [[[self window] screen] visibleFrame].origin;
- if (screenSize.height < frame.size.height)
- {
- frame.size.height = screenSize.height;
- }
- if (screenSize.width < frame.size.width)
- {
- frame.size.width = screenSize.width;
- }
/* our origin is off the screen to the left*/
if (frame.origin.x < screenOrigin.x)
@@ -643,58 +619,36 @@ typedef enum ViewMode : NSUInteger {
NSString *sizeInfoString;
/* Set the picture size display fields below the Preview Picture*/
- int output_width, output_height, output_par_width, output_par_height;
int display_width;
+ display_width = title->job->width * title->job->anamorphic.par_width / title->job->anamorphic.par_height;
if( title->job->anamorphic.mode == 1 ) // Original PAR Implementation
{
- output_width = title->width-title->job->crop[2]-title->job->crop[3];
- output_height = title->height-title->job->crop[0]-title->job->crop[1];
- display_width = output_width * title->job->anamorphic.par_width / title->job->anamorphic.par_height;
sizeInfoString = [NSString stringWithFormat:
@"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Strict",
- title->width, title->height, output_width, output_height, display_width, output_height];
-
- displaySize.width = display_width;
- displaySize.height = title->height;
- imageScaledSize.width = display_width;
- imageScaledSize.height = output_height;
+ title->width, title->height, title->job->width, title->job->height, display_width, title->job->height];
}
else if (title->job->anamorphic.mode == 2) // Loose Anamorphic
{
- hb_set_anamorphic_size(title->job, &output_width, &output_height, &output_par_width, &output_par_height);
- display_width = output_width * output_par_width / output_par_height;
sizeInfoString = [NSString stringWithFormat:
@"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Loose",
- title->width, title->height, output_width, output_height, display_width, output_height];
-
- displaySize.width = display_width;
- displaySize.height = title->height;
- imageScaledSize.width = display_width;
- imageScaledSize.height = output_height;
+ title->width, title->height, title->job->width, title->job->height, display_width, title->job->height];
}
else if (title->job->anamorphic.mode == 3) // Custom Anamorphic
{
- hb_set_anamorphic_size(title->job, &output_width, &output_height, &output_par_width, &output_par_height);
sizeInfoString = [NSString stringWithFormat:
@"Source: %dx%d, Output: %dx%d, Anamorphic: %dx%d Custom",
- title->width, title->height, output_width, output_height, title->job->anamorphic.dar_width, title->job->anamorphic.dar_height];
-
- displaySize.width = title->job->anamorphic.dar_width + title->job->crop[2] + title->job->crop[3] ;
- displaySize.height = title->job->anamorphic.dar_height + title->job->crop[0] + title->job->crop[1];
- imageScaledSize.width = (int)title->job->anamorphic.dar_width;
- imageScaledSize.height = (int)title->job->height;
+ title->width, title->height, title->job->width, title->job->height, display_width, title->job->height];
}
else // No Anamorphic
{
sizeInfoString = [NSString stringWithFormat:
- @"Source: %dx%d, Output: %dx%d", title->width, title->height,
- title->job->width, title->job->height];
-
- displaySize.width = title->width;
- displaySize.height = title->height;
- imageScaledSize.width = title->job->width;
- imageScaledSize.height = title->job->height;
+ @"Source: %dx%d, Output: %dx%d",
+ title->width, title->height, title->job->width, title->job->height];
}
+ displaySize.width = display_width;
+ displaySize.height = title->job->height;
+ imageScaledSize.width = display_width;
+ imageScaledSize.height = title->job->height;
if (self.backingScaleFactor != 1.0)
{
diff --git a/macosx/PictureController.m b/macosx/PictureController.m
index 7bf9bf404..2387f689d 100644
--- a/macosx/PictureController.m
+++ b/macosx/PictureController.m
@@ -46,25 +46,9 @@
IBOutlet NSTextField * fParWidthLabel;
IBOutlet NSTextField * fParHeightLabel;
- /* for now we setup some values to remember our pars and dars
- * from scan
- */
- int titleParWidth;
- int titleParHeight;
- float dar;
-
IBOutlet NSPopUpButton * fAnamorphicPopUp;
IBOutlet NSTextField * fSizeInfoField;
- int output_width, output_height, output_par_width, output_par_height;
- int display_width;
-
- /* used to track the previous state of the keep aspect
- ratio checkbox when turning anamorphic on, so it can be
- returned to the previous state when anamorphic is turned
- off */
- BOOL keepAspectRatioPreviousState;
-
/* Video Filters */
IBOutlet NSBox * fDetelecineBox;
IBOutlet NSPopUpButton * fDetelecinePopUp;
@@ -208,35 +192,49 @@
fTitle = title;
- [fWidthStepper setMaxValue: title->width];
- [fWidthStepper setIntValue: job->width];
- [fWidthField setIntValue: job->width];
- [fHeightStepper setMaxValue: title->height];
- [fHeightStepper setIntValue: job->height];
- [fHeightField setIntValue: job->height];
- [fRatioCheck setState: job->keep_ratio ? NSOnState : NSOffState];
- [fCropTopStepper setMaxValue: title->height/2-2];
- [fCropBottomStepper setMaxValue: title->height/2-2];
- [fCropLeftStepper setMaxValue: title->width/2-2];
- [fCropRightStepper setMaxValue: title->width/2-2];
-
[fAnamorphicPopUp selectItemAtIndex: job->anamorphic.mode];
+ if (job->anamorphic.mode == HB_ANAMORPHIC_STRICT)
+ {
+ [fWidthStepper setEnabled: NO];
+ [fHeightStepper setEnabled: NO];
+ }
+ else
+ {
+ [fWidthStepper setEnabled: YES];
+ [fHeightStepper setEnabled: YES];
+ }
+ if (job->anamorphic.mode == HB_ANAMORPHIC_STRICT ||
+ job->anamorphic.mode == HB_ANAMORPHIC_LOOSE)
+ {
+ job->anamorphic.keep_display_aspect = 1;
+ [fRatioCheck setState: NSOnState];
+ [fRatioCheck setEnabled: NO];
+ }
+ else
+ {
+ [fRatioCheck setEnabled: YES];
+ [fRatioCheck setState: job->anamorphic.keep_display_aspect ?
+ NSOnState : NSOffState];
+ }
+ [fParWidthField setEnabled: !job->anamorphic.keep_display_aspect];
+ [fParHeightField setEnabled: !job->anamorphic.keep_display_aspect];
+ [fDisplayWidthField setEnabled: !job->anamorphic.keep_display_aspect];
if (job->modulus)
{
[fModulusPopUp selectItemWithTitle: [NSString stringWithFormat:@"%d",job->modulus]];
+ [fWidthStepper setIncrement: job->modulus];
+ [fHeightStepper setIncrement: job->modulus];
}
else
{
[fModulusPopUp selectItemAtIndex: 0];
+ [fWidthStepper setIncrement: 16];
+ [fHeightStepper setIncrement: 16];
}
-
- /* We initially set the previous state of keep ar to on */
- keepAspectRatioPreviousState = 1;
- if (!self.autoCrop)
- {
+ if (!self.autoCrop)
+ {
[fCropMatrix selectCellAtRow: 1 column:0];
- /* If auto, lets set the crop steppers according to current job->crop values */
[fCropTopStepper setIntValue: job->crop[0]];
[fCropTopField setIntValue: job->crop[0]];
[fCropBottomStepper setIntValue: job->crop[1]];
@@ -245,11 +243,47 @@
[fCropLeftField setIntValue: job->crop[2]];
[fCropRightStepper setIntValue: job->crop[3]];
[fCropRightField setIntValue: job->crop[3]];
- }
- else
- {
+ }
+ else
+ {
[fCropMatrix selectCellAtRow: 0 column:0];
- }
+
+ [fCropTopStepper setEnabled: !self.autoCrop];
+ [fCropBottomStepper setEnabled: !self.autoCrop];
+ [fCropLeftStepper setEnabled: !self.autoCrop];
+ [fCropRightStepper setEnabled: !self.autoCrop];
+
+ /* If auto, lets set the crop steppers according to
+ * current fTitle->crop values */
+ memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+ [fCropTopStepper setIntValue: fTitle->crop[0]];
+ [fCropTopField setIntValue: fTitle->crop[0]];
+ [fCropBottomStepper setIntValue: fTitle->crop[1]];
+ [fCropBottomField setIntValue: fTitle->crop[1]];
+ [fCropLeftStepper setIntValue: fTitle->crop[2]];
+ [fCropLeftField setIntValue: fTitle->crop[2]];
+ [fCropRightStepper setIntValue: fTitle->crop[3]];
+ [fCropRightField setIntValue: fTitle->crop[3]];
+ }
+ [fWidthStepper setMaxValue: title->width - job->crop[2] - job->crop[3]];
+ [fWidthStepper setIntValue: job->width];
+ [fWidthField setIntValue: job->width];
+ [fHeightStepper setMaxValue: title->height - job->crop[0] - job->crop[1]];
+ [fHeightStepper setIntValue: job->height];
+ [fHeightField setIntValue: job->height];
+ [fCropTopStepper setMaxValue: title->height/2-2];
+ [fCropBottomStepper setMaxValue: title->height/2-2];
+ [fCropLeftStepper setMaxValue: title->width/2-2];
+ [fCropRightStepper setMaxValue: title->width/2-2];
+
+ [fParWidthField setIntValue: job->anamorphic.par_width];
+ [fParHeightField setIntValue: job->anamorphic.par_height];
+
+ int display_width;
+ display_width = job->width * job->anamorphic.par_width /
+ job->anamorphic.par_height;
+ [fDisplayWidthField setIntValue: display_width];
+
/* Set filters widgets according to the filters struct */
[fDetelecinePopUp selectItemAtIndex:self.detelecine];
@@ -261,9 +295,6 @@
[self deblockSliderChanged: nil];
- titleParWidth = job->anamorphic.par_width;
- titleParHeight = job->anamorphic.par_height;
-
[fPreviewController setTitle:title];
[self FilterSettingsChanged:nil];
@@ -334,8 +365,8 @@
NSSize pictureCropBoxSize = [fPictureCropBox frame].size;
NSPoint fPictureCropBoxOrigin = [fPictureCropBox frame].origin;
- if ([fAnamorphicPopUp indexOfSelectedItem] == 3) // custom / power user jamboree
- {
+ if ([fAnamorphicPopUp indexOfSelectedItem] == HB_ANAMORPHIC_CUSTOM)
+ { // custom / power user jamboree
pictureSizingBoxSize.width = 350;
/* Set visibility of capuj widgets */
@@ -360,13 +391,16 @@
}
/* Check to see if we have changed the size from current */
- if (pictureSizingBoxSize.height != [fPictureSizeBox frame].size.height || pictureSizingBoxSize.width != [fPictureSizeBox frame].size.width)
+ if (pictureSizingBoxSize.height != [fPictureSizeBox frame].size.height ||
+ pictureSizingBoxSize.width != [fPictureSizeBox frame].size.width)
{
/* Get our delta for the change in picture size box height */
- CGFloat deltaYSizeBoxShift = pictureSizingBoxSize.height - [fPictureSizeBox frame].size.height;
+ CGFloat deltaYSizeBoxShift = pictureSizingBoxSize.height -
+ [fPictureSizeBox frame].size.height;
fPictureSizeBoxOrigin.y -= deltaYSizeBoxShift;
/* Get our delta for the change in picture size box width */
- CGFloat deltaXSizeBoxShift = pictureSizingBoxSize.width - [fPictureSizeBox frame].size.width;
+ CGFloat deltaXSizeBoxShift = pictureSizingBoxSize.width -
+ [fPictureSizeBox frame].size.width;
//fPictureSizeBoxOrigin.x += deltaXSizeBoxShift;
/* set our new Picture size box size */
[fPictureSizeBox setFrameSize:pictureSizingBoxSize];
@@ -582,409 +616,174 @@
return;
hb_job_t * job = fTitle->job;
+ int keep = 0, dar_updated = 0;
- /* if we are anything but strict anamorphic */
- if ([fAnamorphicPopUp indexOfSelectedItem] != 1)
+ if (sender == fAnamorphicPopUp)
{
- [fModulusLabel setHidden:NO];
- [fModulusPopUp setHidden:NO];
- if (sender == fModulusPopUp)
+ job->anamorphic.mode = (int)[fAnamorphicPopUp indexOfSelectedItem];
+ if (job->anamorphic.mode == HB_ANAMORPHIC_STRICT)
{
- /* do a dry run with hb_fix aspect to get new modulus */
- job->modulus = [[fModulusPopUp titleOfSelectedItem] intValue];
- job->keep_ratio = 1;
- hb_fix_aspect( job, HB_KEEP_WIDTH );
- if( job->height > fTitle->height )
- {
- job->height = fTitle->height;
- hb_fix_aspect( job, HB_KEEP_HEIGHT );
- }
- [fWidthStepper setIntValue: job->width];
- [fWidthField setIntValue: job->width];
- if( [fAnamorphicPopUp indexOfSelectedItem] != 2) // if we are not loose or custom
- {
- [fHeightStepper setIntValue: job->height];
- [fHeightField setIntValue: job->height];
- }
+ [fModulusLabel setHidden: YES];
+ [fModulusPopUp setHidden: YES];
+ [fWidthStepper setEnabled: NO];
+ [fHeightStepper setEnabled: NO];
+ }
+ else
+ {
+ [fModulusLabel setHidden: NO];
+ [fModulusPopUp setHidden: NO];
+ [fWidthStepper setEnabled: YES];
+ [fHeightStepper setEnabled: YES];
+ }
+ if (job->anamorphic.mode == HB_ANAMORPHIC_STRICT ||
+ job->anamorphic.mode == HB_ANAMORPHIC_LOOSE)
+ {
+ job->anamorphic.keep_display_aspect = 1;
+ [fRatioCheck setState: NSOnState];
+ [fRatioCheck setEnabled: NO];
+ }
+ else
+ {
+ [fRatioCheck setEnabled: YES];
+ [fRatioCheck setState: job->anamorphic.keep_display_aspect ?
+ NSOnState : NSOffState];
}
}
- else
+ else if (sender == fModulusPopUp)
{
- /* we are strict so hide the mod popup since libhb uses mod 2 for strict anamorphic*/
- [fModulusLabel setHidden:YES];
- [fModulusPopUp setHidden:YES];
+ job->modulus = [[fModulusPopUp titleOfSelectedItem] intValue];
+ [fWidthStepper setIncrement: job->modulus];
+ [fHeightStepper setIncrement: job->modulus];
}
- job->modulus = [[fModulusPopUp titleOfSelectedItem] intValue];
-
- [fWidthStepper setIncrement: job->modulus];
- [fHeightStepper setIncrement: job->modulus];
-
- /* Since custom anamorphic allows for a height setting > fTitle->height
- * check to make sure it is returned to fTitle->height for all other modes
- */
- [fHeightStepper setMaxValue: fTitle->height];
-
- self.autoCrop = ( [fCropMatrix selectedRow] == 0 );
- [fCropTopStepper setEnabled: !self.autoCrop];
- [fCropBottomStepper setEnabled: !self.autoCrop];
- [fCropLeftStepper setEnabled: !self.autoCrop];
- [fCropRightStepper setEnabled: !self.autoCrop];
-
- if( self.autoCrop )
+ if (sender == fRatioCheck)
{
- memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+ job->anamorphic.keep_display_aspect = [fRatioCheck state] == NSOnState;
+ [fParWidthField setEnabled: !job->anamorphic.keep_display_aspect];
+ [fParHeightField setEnabled: !job->anamorphic.keep_display_aspect];
+ [fDisplayWidthField setEnabled: !job->anamorphic.keep_display_aspect];
}
- else
+
+ if (sender == fHeightStepper)
{
- job->crop[0] = [fCropTopStepper intValue];
- job->crop[1] = [fCropBottomStepper intValue];
- job->crop[2] = [fCropLeftStepper intValue];
- job->crop[3] = [fCropRightStepper intValue];
+ keep |= HB_KEEP_HEIGHT;
+ job->height = [fHeightStepper intValue];
}
- [fRatioCheck setEnabled: YES];
-
- [fParWidthField setEnabled: NO];
- [fParHeightField setEnabled: NO];
- [fDisplayWidthField setEnabled: NO];
-
- /* If we are not custom anamorphic, make sure we retain the orginal par */
- if( [fAnamorphicPopUp indexOfSelectedItem] != 3 )
+ if (sender == fWidthStepper)
{
- job->anamorphic.par_width = titleParWidth;
- job->anamorphic.par_height = titleParHeight;
- [fRatioLabel setHidden: NO];
+ keep |= HB_KEEP_WIDTH;
+ job->width = [fWidthStepper intValue];
}
- if( [fAnamorphicPopUp indexOfSelectedItem] > 0 )
- {
- if ([fAnamorphicPopUp indexOfSelectedItem] == 1) // strict
- {
- [fWidthStepper setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
- [fWidthField setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
-
- /* This will show correct anamorphic height values, but
- show distorted preview picture ratio */
- [fHeightStepper setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
- [fHeightField setIntValue: fTitle->height-fTitle->job->crop[0]-fTitle->job->crop[1]];
- job->width = [fWidthStepper intValue];
- job->height = [fHeightStepper intValue];
-
- job->anamorphic.mode = 1;
- [fWidthStepper setEnabled: NO];
- [fWidthField setEnabled: NO];
- [fHeightStepper setEnabled: NO];
- [fHeightField setEnabled: NO];
- [fRatioCheck setEnabled: NO];
- }
- else if ([fAnamorphicPopUp indexOfSelectedItem] == 2) // Loose anamorphic
- {
- job->anamorphic.mode = 2;
- [fWidthStepper setEnabled: YES];
- [fWidthField setEnabled: YES];
- [fRatioCheck setEnabled: NO];
- [fHeightStepper setEnabled: NO];
- [fHeightField setEnabled: NO];
- /* We set job->width and call hb_set_anamorphic_size in libhb to do a "dry run" to get
- * the values to be used by libhb for loose anamorphic
- */
- /* if the sender is the anamorphic popup, then we know that loose anamorphic has just
- * been turned on, so snap the width to full width for the source.
- */
- if (sender == fAnamorphicPopUp)
- {
- [fWidthStepper setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
- [fWidthField setIntValue: fTitle->width-fTitle->job->crop[2]-fTitle->job->crop[3]];
- }
- job->width = [fWidthStepper intValue];
- hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
- [fHeightStepper setIntValue: output_height];
- [fHeightField setIntValue: output_height];
- job->height = [fHeightStepper intValue];
-
- }
- else if ([fAnamorphicPopUp indexOfSelectedItem] == 3) // custom / power user jamboree
- {
- job->anamorphic.mode = 3;
-
- /* Set the status of our custom ana only widgets accordingly */
- [fModulusPopUp setEnabled:YES];
-
- [fWidthStepper setEnabled: YES];
- [fWidthField setEnabled: YES];
-
- [fHeightStepper setEnabled: YES];
- /* for capuj the storage field is immaterial */
- [fHeightField setEnabled: YES];
-
- [fRatioCheck setEnabled: YES];
- if (sender == fRatioCheck)
- {
- if ([fRatioCheck state] == NSOnState)
- {
- [fParWidthField setEnabled: NO];
- [fParHeightField setEnabled: NO];
- }
- else
- {
- [fParWidthField setEnabled: YES];
- [fParHeightField setEnabled: YES];
- }
- }
-
- [fParWidthField setEnabled: YES];
- [fParHeightField setEnabled: YES];
-
- [fDisplayWidthField setEnabled: YES];
-
-
- /* If we are coming into custom anamorphic we reset the par to original
- * which gives us a way back if things get hosed up.
- */
-
- if (sender == fAnamorphicPopUp)
- {
- /* When entering custom anamorphic, we start with keep ar on */
- [fRatioCheck setState: NSOnState];
- /*
- KEEPING ASPECT RATIO
- Disable editing: PIXEL WIDTH, PIXEL HEIGHT
- */
- [fParWidthField setEnabled: NO];
- [fParHeightField setEnabled: NO];
-
- job->width = [fWidthStepper intValue];
- job->height = [fHeightStepper intValue];
-
- /* make sure our par is set back to original */
- job->anamorphic.par_width = titleParWidth;
- job->anamorphic.par_height = titleParHeight;
-
- [fParWidthField setIntValue: titleParWidth];
- [fParHeightField setIntValue: titleParHeight];
-
- /* modify our par dims from our storage dims */
- hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
- float par_display_width = (float)output_width * (float)output_par_width / (float)output_par_height;
-
- /* go ahead and mod the display dims */
- [fDisplayWidthField setStringValue: [NSString stringWithFormat:@"%.2f", par_display_width]];
-
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- job->anamorphic.dar_height = (float)[fHeightStepper intValue];
-
- /* Set our dar here assuming we are just coming into capuj mode */
- dar = [fDisplayWidthField floatValue] / (float)[fHeightField intValue];
-
- }
-
- /* For capuj we disable these fields if we are keeping the dispay aspect */
- if ([fRatioCheck state] == NSOnState)
- {
- /*
- KEEPING ASPECT RATIO
- DAR = DISPLAY WIDTH / DISPLAY HEIGHT (cache after every modification) */
- /*Disable editing: PIXEL WIDTH, PIXEL HEIGHT */
-
- [fParWidthField setEnabled: NO];
- [fParHeightField setEnabled: NO];
-
- /* Changing DISPLAY WIDTH: */
- if (sender == fDisplayWidthField)
- {
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- /* Changes HEIGHT to keep DAR */
- /* calculate the height to retain the dar */
- int raw_calulated_height = (int)((int)[fDisplayWidthField floatValue] / dar);
- /* now use the modulus to go lower if there is a remainder */
- /* Note to me, raw_calulated_height % [[fModulusPopUp titleOfSelectedItem] intValue]
- * gives me the remainder we are not mod (whatever our modulus is) subtract that from
- * the actual calculated value derived from the dar to round down to the nearest mod value.
- * This should be desireable over rounding up to the next mod value
- */
- int modulus_height = raw_calulated_height - (raw_calulated_height % [[fModulusPopUp titleOfSelectedItem] intValue]);
- if (modulus_height > fTitle->height)
- {
- [fHeightStepper setMaxValue: modulus_height];
- }
- [fHeightStepper setIntValue: modulus_height];
- job->anamorphic.dar_height = (float)[fHeightStepper intValue];
- job->height = [fHeightStepper intValue];
-
- /* Changes PIXEL WIDTH to new DISPLAY WIDTH */
- [fParWidthField setIntValue: [fDisplayWidthField intValue]];
- job->anamorphic.par_width = [fParWidthField intValue];
- /* Changes PIXEL HEIGHT to STORAGE WIDTH */
- [fParHeightField setIntValue: [fWidthField intValue]];
- job->anamorphic.par_height = [fParHeightField intValue];
-
- }
- /* Changing HEIGHT: */
- if (sender == fHeightStepper)
- {
- job->anamorphic.dar_height = (float)[fHeightStepper intValue];
- job->height = [fHeightStepper intValue];
-
- /* Changes DISPLAY WIDTH to keep DAR*/
- [fDisplayWidthField setStringValue: [NSString stringWithFormat: @"%.2f",[fHeightStepper intValue] * dar]];
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- /* Changes PIXEL WIDTH to new DISPLAY WIDTH */
- [fParWidthField setIntValue: [fDisplayWidthField intValue]];
- job->anamorphic.par_width = [fParWidthField intValue];
- /* Changes PIXEL HEIGHT to STORAGE WIDTH */
- [fParHeightField setIntValue: [fWidthField intValue]];
- job->anamorphic.par_height = [fParHeightField intValue];
- }
- /* Changing STORAGE_WIDTH: */
- if (sender == fWidthStepper)
- {
- job->width = [fWidthStepper intValue];
-
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- job->anamorphic.dar_height = [fHeightStepper floatValue];
-
- /* Changes PIXEL WIDTH to DISPLAY WIDTH */
- [fParWidthField setIntValue: [fDisplayWidthField intValue]];
- job->anamorphic.par_width = [fParWidthField intValue];
- /* Changes PIXEL HEIGHT to new STORAGE WIDTH */
- [fParHeightField setIntValue: [fWidthStepper intValue]];
- job->anamorphic.par_height = [fParHeightField intValue];
- }
- }
- else if ([fRatioCheck state] == NSOffState)
- {
- /* Changing STORAGE_WIDTH: */
- if (sender == fWidthStepper)
- {
- job->width = [fWidthStepper intValue];
- /* changes DISPLAY WIDTH to STORAGE WIDTH * PIXEL WIDTH / PIXEL HEIGHT */
- [fDisplayWidthField setStringValue: [NSString stringWithFormat: @"%.2f",(float)[fWidthStepper intValue] * [fParWidthField intValue] / [fParHeightField intValue]]];
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- }
- /* Changing PIXEL dimensions */
- if (sender == fParWidthField || sender == fParHeightField)
- {
- job->anamorphic.par_width = [fParWidthField intValue];
- job->anamorphic.par_height = [fParHeightField intValue];
- /* changes DISPLAY WIDTH to STORAGE WIDTH * PIXEL WIDTH / PIXEL HEIGHT */
- [fDisplayWidthField setStringValue: [NSString stringWithFormat: @"%.2f",(float)[fWidthStepper intValue] * [fParWidthField intValue] / [fParHeightField intValue]]];
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- }
- /* Changing DISPLAY WIDTH: */
- if (sender == fDisplayWidthField)
- {
- job->anamorphic.dar_width = [fDisplayWidthField floatValue];
- job->anamorphic.dar_height = (float)[fHeightStepper intValue];
- /* changes PIXEL WIDTH to DISPLAY WIDTH and PIXEL HEIGHT to STORAGE WIDTH */
- [fParWidthField setIntValue: [fDisplayWidthField intValue]];
- job->anamorphic.par_width = [fParWidthField intValue];
-
- [fParHeightField setIntValue: [fWidthField intValue]];
- job->anamorphic.par_height = [fParHeightField intValue];
- hb_set_anamorphic_size(job, &output_width, &output_height, &output_par_width, &output_par_height);
- }
- /* Changing HEIGHT: */
- if (sender == fHeightStepper)
- {
- /* just....changes the height.*/
- job->anamorphic.dar_height = [fHeightStepper intValue];
- job->height = [fHeightStepper intValue];
- }
-
- }
- }
-
- /* if the sender is the Anamorphic checkbox, record the state
- of KeepAspect Ratio so it can be reset if Anamorphic is unchecked again */
- if (sender == fAnamorphicPopUp)
- {
- keepAspectRatioPreviousState = [fRatioCheck state];
- }
- if ([fAnamorphicPopUp indexOfSelectedItem] != 3)
- {
- [fRatioCheck setState:NSOffState];
- }
+ if (sender == fParWidthField || sender == fParHeightField)
+ {
+ job->anamorphic.par_width = [fParWidthField intValue];
+ job->anamorphic.par_height = [fParHeightField intValue];
+ }
+ if (sender == fDisplayWidthField)
+ {
+ dar_updated = 1;
+ job->anamorphic.dar_width = [fDisplayWidthField intValue];
+ job->anamorphic.dar_height = [fHeightStepper intValue];
}
- else
- {
- job->width = [fWidthStepper intValue];
- job->height = [fHeightStepper intValue];
- job->anamorphic.mode = 0;
- [fWidthStepper setEnabled: YES];
- [fWidthField setEnabled: YES];
- [fHeightStepper setEnabled: YES];
- [fHeightField setEnabled: YES];
- [fRatioCheck setEnabled: YES];
- /* if the sender is the Anamorphic checkbox, we return the
- keep AR checkbox to its previous state */
- if (sender == fAnamorphicPopUp)
- {
- [fRatioCheck setState:keepAspectRatioPreviousState];
- }
- }
- if ([fAnamorphicPopUp indexOfSelectedItem] != 3)
+ if (sender == fCropMatrix)
{
- job->keep_ratio = ( [fRatioCheck state] == NSOnState );
- if( job->keep_ratio )
+ if (self.autoCrop != ( [fCropMatrix selectedRow] == 0 ))
{
- if( sender == fWidthStepper || sender == fRatioCheck ||
- sender == fCropTopStepper || sender == fCropBottomStepper||
- sender == fCropMatrix || sender == nil )
- {
- hb_fix_aspect( job, HB_KEEP_WIDTH );
- if( job->height > fTitle->height )
- {
- job->height = fTitle->height;
- hb_fix_aspect( job, HB_KEEP_HEIGHT );
- }
- }
- else
+ self.autoCrop = !self.autoCrop;
+ if (self.autoCrop)
{
- hb_fix_aspect( job, HB_KEEP_HEIGHT );
- if( job->width > fTitle->width )
- {
- job->width = fTitle->width;
- hb_fix_aspect( job, HB_KEEP_WIDTH );
- }
+ /* If auto, lets set the crop steppers according to
+ * current fTitle->crop values */
+ memcpy( job->crop, fTitle->crop, 4 * sizeof( int ) );
+ [fCropTopStepper setIntValue: fTitle->crop[0]];
+ [fCropTopField setIntValue: fTitle->crop[0]];
+ [fCropBottomStepper setIntValue: fTitle->crop[1]];
+ [fCropBottomField setIntValue: fTitle->crop[1]];
+ [fCropLeftStepper setIntValue: fTitle->crop[2]];
+ [fCropLeftField setIntValue: fTitle->crop[2]];
+ [fCropRightStepper setIntValue: fTitle->crop[3]];
+ [fCropRightField setIntValue: fTitle->crop[3]];
}
-
+ [fCropTopStepper setEnabled: !self.autoCrop];
+ [fCropBottomStepper setEnabled: !self.autoCrop];
+ [fCropLeftStepper setEnabled: !self.autoCrop];
+ [fCropRightStepper setEnabled: !self.autoCrop];
}
}
-
- // hb_get_preview can't handle sizes that are larger than the original title
- if ([fAnamorphicPopUp indexOfSelectedItem] != 3)
+ if (sender == fCropTopStepper)
{
- // dimensions
- if( job->width > fTitle->width )
- {
- job->width = fTitle->width;
- }
-
- if( job->height > fTitle->height )
- {
- job->height = fTitle->height;
- }
+ job->crop[0] = [fCropTopStepper intValue];
+ [fCropTopField setIntValue: job->crop[0]];
+ [fHeightStepper setMaxValue: fTitle->height - job->crop[0] - job->crop[1]];
+ }
+ if (sender == fCropBottomStepper)
+ {
+ job->crop[1] = [fCropBottomStepper intValue];
+ [fCropBottomField setIntValue: job->crop[1]];
+ [fHeightStepper setMaxValue: fTitle->height - job->crop[0] - job->crop[1]];
+ }
+ if (sender == fCropLeftStepper)
+ {
+ job->crop[2] = [fCropLeftStepper intValue];
+ [fCropLeftField setIntValue: job->crop[2]];
+ [fWidthStepper setMaxValue: fTitle->width - job->crop[2] - job->crop[3]];
+ }
+ if (sender == fCropRightStepper)
+ {
+ job->crop[3] = [fCropRightStepper intValue];
+ [fCropRightField setIntValue: job->crop[3]];
+ [fWidthStepper setMaxValue: fTitle->width - job->crop[2] - job->crop[3]];
}
- [fWidthStepper setIntValue: job->width];
- [fWidthField setIntValue: job->width];
- if( [fAnamorphicPopUp indexOfSelectedItem] != 2) // if we are not loose or custom
+ keep |= !!job->anamorphic.keep_display_aspect * HB_KEEP_DISPLAY_ASPECT;
+
+ hb_geometry_t srcGeo, resultGeo;
+ hb_ui_geometry_t uiGeo;
+
+ srcGeo.width = fTitle->width;
+ srcGeo.height = fTitle->height;
+ srcGeo.par.num = fTitle->pixel_aspect_width;
+ srcGeo.par.den = fTitle->pixel_aspect_height;
+
+ uiGeo.mode = job->anamorphic.mode;
+ uiGeo.keep = keep;
+ uiGeo.itu_par = 0;
+ uiGeo.modulus = job->modulus;
+ memcpy(uiGeo.crop, job->crop, sizeof(int[4]));
+ uiGeo.width = job->width;
+ uiGeo.height = job->height;
+ uiGeo.maxWidth = fTitle->width - job->crop[2] - job->crop[3];
+ uiGeo.maxHeight = fTitle->height - job->crop[0] - job->crop[1];
+ uiGeo.par.num = job->anamorphic.par_width;
+ uiGeo.par.den = job->anamorphic.par_height;
+ uiGeo.dar.num = 0;
+ uiGeo.dar.den = 0;
+ if (job->anamorphic.mode == HB_ANAMORPHIC_CUSTOM && dar_updated)
{
- [fHeightStepper setIntValue: job->height];
- [fHeightField setIntValue: job->height];
+ uiGeo.dar.num = job->anamorphic.dar_width;
+ uiGeo.dar.den = job->anamorphic.dar_height;
}
+ hb_set_anamorphic_size2(&srcGeo, &uiGeo, &resultGeo);
- [fCropTopStepper setIntValue: job->crop[0]];
- [fCropTopField setIntValue: job->crop[0]];
- [fCropBottomStepper setIntValue: job->crop[1]];
- [fCropBottomField setIntValue: job->crop[1]];
- [fCropLeftStepper setIntValue: job->crop[2]];
- [fCropLeftField setIntValue: job->crop[2]];
- [fCropRightStepper setIntValue: job->crop[3]];
- [fCropRightField setIntValue: job->crop[3]];
+ job->width = resultGeo.width;
+ job->height = resultGeo.height;
+ job->anamorphic.par_width = resultGeo.par.num;
+ job->anamorphic.par_height = resultGeo.par.den;
+
+ int display_width;
+ display_width = resultGeo.width * resultGeo.par.num / resultGeo.par.den;
+
+ [fWidthStepper setIntValue: resultGeo.width];
+ [fWidthField setIntValue: resultGeo.width];
+ [fHeightStepper setIntValue: resultGeo.height];
+ [fHeightField setIntValue: resultGeo.height];
+ [fParWidthField setIntValue: resultGeo.par.num];
+ [fParHeightField setIntValue: resultGeo.par.den];
+ [fDisplayWidthField setIntValue: display_width];
/*
* Sanity-check here for previews < 16 pixels to avoid crashing