summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gtk/src/hb-backend.c77
-rw-r--r--libhb/common.h5
-rw-r--r--libhb/hb.c122
3 files changed, 136 insertions, 68 deletions
diff --git a/gtk/src/hb-backend.c b/gtk/src/hb-backend.c
index 25fb09ba1..88e7a89a1 100644
--- a/gtk/src/hb-backend.c
+++ b/gtk/src/hb-backend.c
@@ -3883,9 +3883,10 @@ get_preview_geometry(signal_user_data_t *ud, const hb_title_t *title,
srcGeo->par = title->geometry.par;
uiGeo->mode = ghb_settings_combo_int(ud->settings, "PicturePAR");
- uiGeo->keep = ghb_dict_get_bool(ud->settings, "PictureKeepRatio") ||
- uiGeo->mode == HB_ANAMORPHIC_STRICT ||
- uiGeo->mode == HB_ANAMORPHIC_LOOSE;
+ uiGeo->keep = (ghb_dict_get_bool(ud->settings, "PictureKeepRatio") ||
+ uiGeo->mode == HB_ANAMORPHIC_STRICT ||
+ uiGeo->mode == HB_ANAMORPHIC_LOOSE) ?
+ HB_KEEP_DISPLAY_ASPECT : 0;
uiGeo->itu_par = 0;
uiGeo->modulus = ghb_settings_combo_int(ud->settings, "PictureModulus");
uiGeo->crop[0] = ghb_dict_get_int(ud->settings, "PictureTopCrop");
@@ -4517,33 +4518,6 @@ ghb_get_preview_image(
uiGeo.geometry.par.num = 1;
uiGeo.geometry.par.den = 1;
- GdkScreen *ss;
- gint s_w, s_h;
-
- ss = gdk_screen_get_default();
- s_w = gdk_screen_get_width(ss);
- s_h = gdk_screen_get_height(ss);
-
- if (uiGeo.geometry.width > s_w * 2 ||
- uiGeo.geometry.height > s_h * 2)
- {
- double factor = 1.;
-
- // Image is of extreme size > twice the screen dimensions.
- // In some extreme cases (very lopsided PAR), this can cause
- // hb_get_preview2 to crash or hang.
- if (uiGeo.geometry.width > s_w)
- {
- factor = (double)s_w / uiGeo.geometry.width;
- }
- if (uiGeo.geometry.height * factor > s_h)
- {
- factor = (double)s_h / uiGeo.geometry.height;
- }
- uiGeo.geometry.width *= factor;
- uiGeo.geometry.height *= factor;
- }
-
GdkPixbuf *preview;
hb_image_t *image;
image = hb_get_preview2(h_scan, title->index, index, &uiGeo, deinterlace);
@@ -4586,9 +4560,11 @@ ghb_get_preview_image(
src_line += image->plane[0].stride;
dst += stride;
}
- gint w = ghb_dict_get_int(ud->settings, "scale_width");
- gint h = ghb_dict_get_int(ud->settings, "scale_height");
- ghb_par_scale(ud, &w, &h, resultGeo.par.num, resultGeo.par.den);
+
+ *out_width = ghb_dict_get_int(ud->settings, "scale_width");
+ *out_height = ghb_dict_get_int(ud->settings, "scale_height");
+ ghb_par_scale(ud, out_width, out_height,
+ resultGeo.par.num, resultGeo.par.den);
gint c0, c1, c2, c3;
c0 = ghb_dict_get_int(ud->settings, "PictureTopCrop");
@@ -4596,11 +4572,17 @@ ghb_get_preview_image(
c2 = ghb_dict_get_int(ud->settings, "PictureLeftCrop");
c3 = ghb_dict_get_int(ud->settings, "PictureRightCrop");
- gdouble xscale = (gdouble)w / (gdouble)(title->geometry.width - c2 - c3);
- gdouble yscale = (gdouble)h / (gdouble)(title->geometry.height - c0 - c1);
-
- *out_width = w;
- *out_height = h;
+ gdouble xscale, yscale;
+ if (ghb_dict_get_bool(ud->prefs, "preview_show_crop"))
+ {
+ xscale = (gdouble)image->width / title->geometry.width;
+ yscale = (gdouble)image->height / title->geometry.height;
+ }
+ else
+ {
+ xscale = (gdouble)image->width / (title->geometry.width - c2 - c3);
+ yscale = (gdouble)image->height / (title->geometry.height - c0 - c1);
+ }
int previewWidth = image->width;
int previewHeight = image->height;
@@ -4615,6 +4597,13 @@ ghb_get_preview_image(
factor = 100;
}
+ GdkScreen *ss;
+ gint s_w, s_h;
+
+ ss = gdk_screen_get_default();
+ s_w = gdk_screen_get_width(ss);
+ s_h = gdk_screen_get_height(ss);
+
if (previewWidth > s_w * factor / 100 ||
previewHeight > s_h * factor / 100)
{
@@ -4634,28 +4623,28 @@ ghb_get_preview_image(
}
xscale *= (gdouble)previewWidth / orig_w;
yscale *= (gdouble)previewHeight / orig_h;
- w *= (gdouble)previewWidth / orig_w;
- h *= (gdouble)previewHeight / orig_h;
scaled_preview = gdk_pixbuf_scale_simple(preview,
previewWidth, previewHeight, GDK_INTERP_HYPER);
g_object_unref(preview);
preview = scaled_preview;
}
}
+
if (ghb_dict_get_bool(ud->prefs, "preview_show_crop"))
{
c0 *= yscale;
c1 *= yscale;
c2 *= xscale;
c3 *= xscale;
+
// Top
- hash_pixbuf(preview, c2, 0, w, c0, 32, 0);
+ hash_pixbuf(preview, 0, 0, previewWidth, c0, 32, 0);
// Bottom
- hash_pixbuf(preview, c2, previewHeight-c1, w, c1, 32, 0);
+ hash_pixbuf(preview, 0, previewHeight-c1, previewWidth, c1, 32, 0);
// Left
- hash_pixbuf(preview, 0, c0, c2, h, 32, 1);
+ hash_pixbuf(preview, 0, 0, c2, previewHeight, 32, 1);
// Right
- hash_pixbuf(preview, previewWidth-c3, c0, c3, h, 32, 1);
+ hash_pixbuf(preview, previewWidth-c3, 0, c3, previewHeight, 32, 1);
}
hb_image_close(&image);
return preview;
diff --git a/libhb/common.h b/libhb/common.h
index 6811e1eca..4d377f8f1 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -72,6 +72,11 @@
#define HB_DVD_READ_BUFFER_SIZE 2048
+#define HB_MIN_WIDTH 32
+#define HB_MIN_HEIGHT 32
+#define HB_MAX_WIDTH 10240
+#define HB_MAX_HEIGHT 10240
+
typedef struct hb_handle_s hb_handle_t;
typedef struct hb_hwd_s hb_hwd_t;
typedef struct hb_list_s hb_list_t;
diff --git a/libhb/hb.c b/libhb/hb.c
index 0665f1b51..2a90726ce 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -768,16 +768,14 @@ hb_image_t* hb_get_preview2(hb_handle_t * h, int title_idx, int picture,
geo->geometry.par.num / geo->geometry.par.den;
int height = geo->geometry.height;
- // Set minimum dimensions to prevent failure to initialize
- // sws context
- if (width < 32)
- {
- width = 32;
- }
- if (height < 32)
- {
- height = 32;
- }
+ // Set min/max dimensions to prevent failure to initialize
+ // sws context and absurd sizes.
+ //
+ // This means output image size may not match requested image size!
+ int ww = width, hh = height;
+ width = MIN(MAX(width, HB_MIN_WIDTH), HB_MAX_WIDTH);
+ height = MIN(MAX(height * width / ww, HB_MIN_HEIGHT), HB_MAX_HEIGHT);
+ width = MIN(MAX(width * height / hh, HB_MIN_WIDTH), HB_MAX_WIDTH);
swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
@@ -1053,12 +1051,24 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
int width, height;
int maxWidth, maxHeight;
- maxWidth = MULTIPLE_MOD_DOWN(geo->maxWidth, mod);
- maxHeight = MULTIPLE_MOD_DOWN(geo->maxHeight, mod);
- if (maxWidth && maxWidth < 32)
- maxWidth = 32;
- if (maxHeight && maxHeight < 32)
- maxHeight = 32;
+ if (geo->maxWidth > 0)
+ {
+ maxWidth = MIN(MAX(MULTIPLE_MOD_DOWN(geo->maxWidth, mod),
+ HB_MIN_WIDTH), HB_MAX_WIDTH);
+ }
+ else
+ {
+ maxWidth = HB_MAX_WIDTH;
+ }
+ if (geo->maxHeight > 0)
+ {
+ maxHeight = MIN(MAX(MULTIPLE_MOD_DOWN(geo->maxHeight, mod),
+ HB_MIN_HEIGHT), HB_MAX_HEIGHT);
+ }
+ else
+ {
+ maxHeight = HB_MAX_HEIGHT;
+ }
switch (geo->mode)
{
@@ -1091,7 +1101,25 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
width = MULTIPLE_MOD_UP(geo->geometry.width, mod);
height = MULTIPLE_MOD_UP(geo->geometry.height, mod);
}
- if (maxWidth && (width > maxWidth))
+
+ // Limit to min/max dimensions
+ if (width < HB_MIN_WIDTH)
+ {
+ width = HB_MIN_WIDTH;
+ if (keep_display_aspect)
+ {
+ height = MULTIPLE_MOD(width / dar, mod);
+ }
+ }
+ if (height < HB_MIN_HEIGHT)
+ {
+ height = HB_MIN_HEIGHT;
+ if (keep_display_aspect)
+ {
+ width = MULTIPLE_MOD(height * dar, mod);
+ }
+ }
+ if (width > maxWidth)
{
width = maxWidth;
if (keep_display_aspect)
@@ -1099,7 +1127,7 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
height = MULTIPLE_MOD(width / dar, mod);
}
}
- if (maxHeight && (height > maxHeight))
+ if (height > maxHeight)
{
height = maxHeight;
if (keep_display_aspect)
@@ -1154,13 +1182,23 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
width = MULTIPLE_MOD_UP(height * storage_aspect + 0.5, mod);
}
- if (maxWidth && (maxWidth < width))
+ // Limit to min/max dimensions
+ if (width < HB_MIN_WIDTH)
+ {
+ width = HB_MIN_WIDTH;
+ height = MULTIPLE_MOD(width / storage_aspect + 0.5, mod);
+ }
+ if (height < HB_MIN_HEIGHT)
+ {
+ height = HB_MIN_HEIGHT;
+ width = MULTIPLE_MOD(height * storage_aspect + 0.5, mod);
+ }
+ if (width > maxWidth)
{
width = maxWidth;
height = MULTIPLE_MOD(width / storage_aspect + 0.5, mod);
}
-
- if (maxHeight && (maxHeight < height))
+ if (height > maxHeight)
{
height = maxHeight;
width = MULTIPLE_MOD(height * storage_aspect + 0.5, mod);
@@ -1181,12 +1219,20 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
width = MULTIPLE_MOD_UP(geo->geometry.width, mod);
height = MULTIPLE_MOD_UP(geo->geometry.height, mod);
- /* Bind to max dimensions */
- if (maxWidth && width > maxWidth)
+ // Limit to min/max dimensions
+ if (width < HB_MIN_WIDTH)
+ {
+ width = HB_MIN_WIDTH;
+ }
+ if (height < HB_MIN_HEIGHT)
+ {
+ height = HB_MIN_HEIGHT;
+ }
+ if (width > maxWidth)
{
width = maxWidth;
}
- if (maxHeight && height > maxHeight)
+ if (height > maxHeight)
{
height = maxHeight;
}
@@ -1203,6 +1249,34 @@ void hb_set_anamorphic_size2(hb_geometry_t *src_geo,
}
} break;
}
+ if (width < HB_MIN_WIDTH || height < HB_MIN_HEIGHT ||
+ width > maxWidth || height > maxHeight)
+ {
+ // All limits set above also attempted to keep PAR and DAR.
+ // If we are still outside limits, enforce them and modify
+ // PAR to keep DAR
+ if (width < HB_MIN_WIDTH)
+ {
+ width = HB_MIN_WIDTH;
+ }
+ if (height < HB_MIN_HEIGHT)
+ {
+ height = HB_MIN_HEIGHT;
+ }
+ if (width > maxWidth)
+ {
+ width = maxWidth;
+ }
+ if (height > maxHeight)
+ {
+ height = maxHeight;
+ }
+ if (keep_display_aspect && geo->mode != HB_ANAMORPHIC_NONE)
+ {
+ dst_par_num = (int64_t)height * cropped_width * src_par.num;
+ dst_par_den = (int64_t)width * cropped_height * src_par.den;
+ }
+ }
/* Pass the results back to the caller */
result->width = width;