Index: src/wp-admin/includes/image.php
===================================================================
--- src/wp-admin/includes/image.php	(revision 36486)
+++ src/wp-admin/includes/image.php	(working copy)
@@ -78,7 +78,10 @@
 
 	$metadata = array();
 	$support = false;
-	if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
+	$attachment_fallback_mimetypes = apply_filters( 'attachment_fallback_mimetypes', array( 'application/pdf', 'video/avi' ) );
+	$mime_type = get_post_mime_type( $attachment );
+
+	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image($file) ) {
 		$imagesize = getimagesize( $file );
 		$metadata['width'] = $imagesize[0];
 		$metadata['height'] = $imagesize[1];
@@ -133,13 +136,11 @@
 
 	} elseif ( wp_attachment_is( 'video', $attachment ) ) {
 		$metadata = wp_read_video_metadata( $file );
-		$support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
 	} elseif ( wp_attachment_is( 'audio', $attachment ) ) {
 		$metadata = wp_read_audio_metadata( $file );
-		$support = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
 	}
 
-	if ( $support && ! empty( $metadata['image']['data'] ) ) {
+	if ( ! empty( $metadata['image']['data'] ) ) {
 		// Check for existing cover.
 		$hash = md5( $metadata['image']['data'] );
 		$posts = get_posts( array(
@@ -191,13 +192,34 @@
 				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
 			}
 		}
-	}
 
-	// Remove the blob of binary data from the array.
-	if ( $metadata ) {
+		// Remove the blob of binary data from the array.
 		unset( $metadata['image']['data'] );
 	}
+	else if ( in_array( $mime_type, $attachment_fallback_mimetypes ) ) {
+		$editor = wp_get_image_editor( $file );
+		$sizes = array(
+			'thumbnail' => array(
+				'width'  => get_option( "thumbnail_size_w" ),
+				'height' => get_option( "thumbnail_size_h" ),
+				'crop'   => get_option( "thumbnail_crop" )
+			)
+		);
 
+		if ( ! is_wp_error( $editor ) ) { // No support for this type of file
+			$uploaded = $editor->save( $file . '.jpg' );
+
+			if ( ! is_wp_error( $uploaded ) ) {
+				unset( $uploaded['path'] );
+
+				$metadata = array_merge( $metadata, $uploaded );
+
+				$metadata['sizes'] = $editor->multi_resize( $sizes );
+				$metadata['sizes']['full'] = $uploaded;
+			}
+		}
+	}
+
 	/**
 	 * Filter the generated attachment meta data.
 	 *
Index: src/wp-admin/includes/media.php
===================================================================
--- src/wp-admin/includes/media.php	(revision 36486)
+++ src/wp-admin/includes/media.php	(working copy)
@@ -2753,6 +2753,15 @@
 
 		echo wp_video_shortcode( $attr );
 
+	else :
+		$image = wp_get_attachment_image( $attachment_id, 'full', false, array( 'style' => 'max-width:100%' ) );
+
+		if ( $image ) {
+			echo '<div class="wp_attachment_image wp-clearfix" id="media-head-' . $attachment_id . '">';
+			echo '<p id="thumbnail-head-<?php echo $attachment_id; ?>">' . $image . '</p>';
+			echo '</div>';
+		}
+
 	endif; ?>
 	</div>
 	<div class="wp_attachment_details edit-form-section">
Index: src/wp-includes/media-template.php
===================================================================
--- src/wp-includes/media-template.php	(revision 36486)
+++ src/wp-includes/media-template.php	(working copy)
@@ -290,9 +290,9 @@
 			<div class="thumbnail thumbnail-{{ data.type }}">
 				<# if ( data.uploading ) { #>
 					<div class="media-progress-bar"><div></div></div>
-				<# } else if ( 'image' === data.type && data.sizes && data.sizes.large ) { #>
+				<# } else if ( data.sizes && data.sizes.large ) { #>
 					<img class="details-image" src="{{ data.sizes.large.url }}" draggable="false" alt="" />
-				<# } else if ( 'image' === data.type && data.sizes && data.sizes.full ) { #>
+				<# } else if ( data.sizes && data.sizes.full ) { #>
 					<img class="details-image" src="{{ data.sizes.full.url }}" draggable="false" alt="" />
 				<# } else if ( -1 === jQuery.inArray( data.type, [ 'audio', 'video' ] ) ) { #>
 					<img class="details-image icon" src="{{ data.icon }}" draggable="false" alt="" />
@@ -450,6 +450,10 @@
 					<div class="centered">
 						<img src="{{ data.size.url }}" draggable="false" alt="" />
 					</div>
+				<# } else if ( data.sizes ) { #>
+					<div class="centered">
+						<img src="{{ data.sizes.full.url }}" draggable="false" alt="" />
+					</div>
 				<# } else { #>
 					<div class="centered">
 						<# if ( data.image && data.image.src && data.image.src !== data.icon ) { #>
Index: src/wp-includes/media.php
===================================================================
--- src/wp-includes/media.php	(revision 36486)
+++ src/wp-includes/media.php	(working copy)
@@ -163,29 +163,34 @@
  *                     the image is an intermediate size. False on failure.
  */
 function image_downsize( $id, $size = 'medium' ) {
+	$is_image = wp_attachment_is_image( $id );
 
-	if ( !wp_attachment_is_image($id) )
+	if ( $is_image ) {
+		/**
+		 * Filter whether to preempt the output of image_downsize().
+		 *
+		 * Passing a truthy value to the filter will effectively short-circuit
+		 * down-sizing the image, returning that value as output instead.
+		 *
+		 * @since 2.5.0
+		 *
+		 * @param bool         $downsize Whether to short-circuit the image downsize. Default false.
+		 * @param int          $id       Attachment ID for image.
+		 * @param array|string $size     Size of image. Image size or array of width and height values (in that order).
+		 *                               Default 'medium'.
+		 */
+		if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
+			return $out;
+		}
+	}
+
+	$meta = wp_get_attachment_metadata($id);
+
+	if ( ! $meta || empty( $meta['sizes'] ) ) {
 		return false;
-
-	/**
-	 * Filter whether to preempt the output of image_downsize().
-	 *
-	 * Passing a truthy value to the filter will effectively short-circuit
-	 * down-sizing the image, returning that value as output instead.
-	 *
-	 * @since 2.5.0
-	 *
-	 * @param bool         $downsize Whether to short-circuit the image downsize. Default false.
-	 * @param int          $id       Attachment ID for image.
-	 * @param array|string $size     Size of image. Image size or array of width and height values (in that order).
-	 *                               Default 'medium'.
-	 */
-	if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
-		return $out;
 	}
 
 	$img_url = wp_get_attachment_url($id);
-	$meta = wp_get_attachment_metadata($id);
 	$width = $height = 0;
 	$is_intermediate = false;
 	$img_url_basename = wp_basename($img_url);
@@ -206,6 +211,7 @@
 			$is_intermediate = true;
 		}
 	}
+
 	if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) {
 		// any other type: use the real image
 		$width = $meta['width'];
@@ -1006,7 +1012,7 @@
 	 */
 	$image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );
 
-	if ( empty( $image_meta['sizes'] ) ) {
+	if ( empty( $image_meta['file'] ) || empty( $image_meta['sizes'] ) ) {
 		return false;
 	}
 
@@ -3147,7 +3153,21 @@
 		}
 
 		$response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] );
-	} elseif ( $meta && 'video' === $type ) {
+	}
+	elseif ( isset( $meta['sizes'] ) ) {
+		$base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
+
+		foreach ( $meta['sizes'] as $size => $data ) {
+			$response['sizes'][ $size ] = array(
+				'height'      => $data['height'],
+				'width'       => $data['width'],
+				'url'         => $base_url . $data['file'],
+				'orientation' => $data['height'] > $data['width'] ? 'portrait' : 'landscape',
+			);
+		}
+	}
+
+	if ( $meta && 'video' === $type ) {
 		if ( isset( $meta['width'] ) )
 			$response['width'] = (int) $meta['width'];
 		if ( isset( $meta['height'] ) )
