diff options
-rw-r--r-- | gtk/src/hb-backend.c | 77 | ||||
-rw-r--r-- | libhb/common.h | 5 | ||||
-rw-r--r-- | libhb/hb.c | 122 |
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; |