Index: wp-admin/custom-header.php
===================================================================
--- wp-admin/custom-header.php	(revision 19736)
+++ wp-admin/custom-header.php	(working copy)
@@ -438,13 +438,11 @@
 		jQuery('img#upload').imgAreaSelect({
 			handles: true,
 			keys: true,
-			aspectRatio: xinit + ':' + yinit,
 			show: true,
 			x1: 0,
 			y1: 0,
 			x2: xinit,
 			y2: yinit,
-			maxHeight: <?php echo HEADER_IMAGE_HEIGHT; ?>,
 			maxWidth: <?php echo HEADER_IMAGE_WIDTH; ?>,
 			onInit: function () {
 				jQuery('#width').val(xinit);
@@ -510,7 +508,16 @@
 <th scope="row"><?php _e( 'Upload Image' ); ?></th>
 <td>
 	<p><?php _e( 'You can upload a custom header image to be shown at the top of your site instead of the default one. On the next screen you will be able to crop the image.' ); ?><br />
-	<?php printf( __( 'Images of exactly <strong>%1$d &times; %2$d pixels</strong> will be used as-is.' ), HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT ); ?></p>
+	<?php
+	$header_support = get_theme_support( 'custom-header' );
+	if ( ! isset( $header_support[ 0 ] ) || empty( $header_support[ 0 ][ 'flex-height' ] ) || !$header_support[ 0 ][ 'flex-height' ] ) {
+		printf( __( 'Images of exactly <strong>%1$d &times; %2$d pixels</strong> will be used as-is.' ), HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT );
+	} else {
+		printf( __( 'Images should be at least <strong>%1$d pixels</strong> wide.' ), HEADER_IMAGE_WIDTH );
+		if ( !empty( $header_support[ 0 ][ 'suggested-height' ] ) )
+			printf( __( ' Suggested height is <strong>%1$d pixels</strong>.' ), absint( $header_support[ 0 ][ 'suggested-height' ] ) );
+	}
+	?></p>
 	<form enctype="multipart/form-data" id="upload-form" method="post" action="<?php echo esc_attr( add_query_arg( 'step', 2 ) ) ?>">
 	<p>
 		<label for="upload"><?php _e( 'Choose an image from your computer:' ); ?></label><br />
@@ -662,7 +669,9 @@
 
 		list($width, $height, $type, $attr) = getimagesize( $file );
 
-		if ( $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
+		$header_support = get_theme_support( 'custom-header' );
+		// If flexible height isn't supported and the image is the exact right size
+		if ( ( !isset( $header_support[ 0 ] ) || empty( $header_support[ 0 ][ 'flex-height' ] ) || !empty( $header_support[ 0 ][ 'flex-height' ] ) ) && $width == HEADER_IMAGE_WIDTH && $height == HEADER_IMAGE_HEIGHT ) {
 			// Add the meta-data
 			wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
 			update_post_meta( $id, '_wp_attachment_is_custom_header', get_option('stylesheet' ) );
@@ -733,7 +742,13 @@
 		$attachment_id = absint( $_POST['attachment_id'] );
 		$original = get_attached_file($attachment_id);
 
-		$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], HEADER_IMAGE_WIDTH, HEADER_IMAGE_HEIGHT );
+		$header_support = get_theme_support( 'custom-header' );
+		if ( isset( $header_support[ 0 ] ) && !empty( $header_support[ 0 ][ 'flex-height' ] ) )
+			$dst_height = (int) $_POST['height'] * ( HEADER_IMAGE_WIDTH / $_POST['width'] );
+		else
+			$dst_height = HEADER_IMAGE_HEIGHT;
+
+		$cropped = wp_crop_image( $attachment_id, (int) $_POST['x1'], (int) $_POST['y1'], (int) $_POST['width'], (int) $_POST['height'], HEADER_IMAGE_WIDTH, $dst_height );
 		if ( is_wp_error( $cropped ) )
 			wp_die( __( 'Image could not be processed. Please go back and try again.' ), __( 'Image Processing Error' ) );
 
Index: wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js
===================================================================
--- wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js	(revision 19736)
+++ wp-includes/js/imgareaselect/jquery.imgareaselect.dev.js	(working copy)
@@ -1,6 +1,6 @@
 /*
  * imgAreaSelect jQuery plugin
- * version 0.9.6
+ * version 0.9.8
  *
  * Copyright (c) 2008-2011 Michal Wojciechowski (odyniec.net)
  *
@@ -55,8 +55,6 @@
 
         scaleX, scaleY,
 
-        resizeMargin = 10,
-
         resize,
 
         minWidth, minHeight, maxWidth, maxHeight,
@@ -134,10 +132,10 @@
         imgOfs.top += ($img.outerHeight() - imgHeight) >> 1;
         imgOfs.left += ($img.outerWidth() - imgWidth) >> 1;
 
-        minWidth = options.minWidth || 0;
-        minHeight = options.minHeight || 0;
-        maxWidth = min(options.maxWidth || 1<<24, imgWidth);
-        maxHeight = min(options.maxHeight || 1<<24, imgHeight);
+        minWidth = round(options.minWidth / scaleX) || 0;
+        minHeight = round(options.minHeight / scaleY) || 0;
+        maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth));
+        maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight));
 
         if ($().jquery == '1.3.2' && position == 'fixed' &&
             !docElem['getBoundingClientRect'])
@@ -146,7 +144,7 @@
             imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft);
         }
 
-        parOfs = $.inArray($parent.css('position'), ['absolute', 'relative']) + 1 ?
+        parOfs = /absolute|relative/.test($parent.css('position')) ?
             { left: round($parent.offset().left) - $parent.scrollLeft(),
                 top: round($parent.offset().top) - $parent.scrollTop() } :
             position == 'fixed' ?
@@ -365,8 +363,8 @@
     }
 
     function selectingMouseMove(event) {
-        x2 = resize == '' || /w|e/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2);
-        y2 = resize == '' || /n|s/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2);
+        x2 = /w|e|^$/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2);
+        y2 = /n|s|^$/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2);
 
         doResize();
 
@@ -408,7 +406,7 @@
 
         resize = '';
 
-        if ($outer.is(':not(:visible)'))
+        if (!$outer.is(':visible'))
             $box.add($outer).hide().fadeIn(options.fadeSpeed||0);
 
         shown = true;
@@ -427,8 +425,10 @@
 
         setSelection(selX(x1), selY(y1), selX(x1), selY(y1));
 
-        options.onSelectChange(img, getSelection());
-        options.onSelectEnd(img, getSelection());
+        if (!this instanceof $.imgAreaSelect) {
+            options.onSelectChange(img, getSelection());
+            options.onSelectEnd(img, getSelection());
+        }
     }
 
     function imgMouseDown(event) {
@@ -606,9 +606,9 @@
         $box.append($area.add($border).add($areaOpera).add($handles));
 
         if ($.browser.msie) {
-            if (o = $outer.css('filter').match(/opacity=([0-9]+)/))
+            if (o = $outer.css('filter').match(/opacity=(\d+)/))
                 $outer.css('opacity', o[1]/100);
-            if (o = $border.css('filter').match(/opacity=([0-9]+)/))
+            if (o = $border.css('filter').match(/opacity=(\d+)/))
                 $border.css('opacity', o[1]/100);
         }
 
@@ -656,6 +656,8 @@
 
     this.setSelection = setSelection;
 
+    this.cancelSelection = cancelSelection;
+
     this.update = doUpdate;
 
     $p = $img;
@@ -689,7 +691,7 @@
     img.complete || img.readyState == 'complete' || !$img.is('img') ?
         imgLoad() : $img.one('load', imgLoad);
 
-    if ($.browser.msie && $.browser.version >= 9)
+   if ($.browser.msie && $.browser.version >= 7)
         img.src = img.src;
 };
 
