Index: src/wp-admin/includes/image.php
===================================================================
--- src/wp-admin/includes/image.php	(revision 36627)
+++ src/wp-admin/includes/image.php	(working copy)
@@ -78,7 +78,18 @@
 
 	$metadata = array();
 	$support = false;
-	if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
+	$mime_type = get_post_mime_type( $attachment );
+
+	/** 
+	 * Filter attachment mime-types that support thumbnail fallback. 
+	 * 
+	 * @since 4.5.0 
+	 * 
+	 * @param array $mime_types An array of mime-types. 
+	 */ 
+	$attachment_fallback_mimetypes = apply_filters( 'attachment_fallback_mimetypes', array( 'application/pdf' ) );
+
+	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image($file) ) {
 		$imagesize = getimagesize( $file );
 		$metadata['width'] = $imagesize[0];
 		$metadata['height'] = $imagesize[1];
@@ -192,7 +203,28 @@
 			}
 		}
 	}
+	// Check to see if we support a fallback thumbnail for this mime-type.
+	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' );
+			unset( $uploaded['path'] );
+
+			if ( ! is_wp_error( $uploaded ) ) {
+				$metadata['sizes'] = $editor->multi_resize( $sizes );
+				$metadata['sizes']['full'] = $uploaded;
+			}
+		}
+	}
+
 	// Remove the blob of binary data from the array.
 	if ( $metadata ) {
 		unset( $metadata['image']['data'] );
Index: src/wp-admin/includes/media.php
===================================================================
--- src/wp-admin/includes/media.php	(revision 36627)
+++ 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 36627)
+++ 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="" />
@@ -454,6 +454,8 @@
 					<div class="centered">
 						<# if ( data.image && data.image.src && data.image.src !== data.icon ) { #>
 							<img src="{{ data.image.src }}" class="thumbnail" draggable="false" alt="" />
+						<# } else if ( data.sizes && data.sizes.full ) { #>
+							<img src="{{ data.sizes.full.url }}" class="thumbnail" draggable="false" alt="" />
 						<# } else { #>
 							<img src="{{ data.icon }}" class="icon" draggable="false" alt="" />
 						<# } #>
Index: src/wp-includes/media.php
===================================================================
--- src/wp-includes/media.php	(revision 36627)
+++ src/wp-includes/media.php	(working copy)
@@ -163,33 +163,45 @@
  *                     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);
 
+	if ( ! $is_image ) {
+		$img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
+		$img_url_basename = $meta['sizes']['full']['file'];
+		$width = $meta['sizes']['full']['width'];
+		$height = $meta['sizes']['full']['height'];
+	}
+
 	// try for a new style intermediate size
 	if ( $intermediate = image_get_intermediate_size($id, $size) ) {
 		$img_url = str_replace($img_url_basename, $intermediate['file'], $img_url);
@@ -206,6 +218,7 @@
 			$is_intermediate = true;
 		}
 	}
+
 	if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) {
 		// any other type: use the real image
 		$width = $meta['width'];
@@ -637,6 +650,11 @@
 	if ( is_array($size) && !empty($imagedata['sizes']) ) {
 		$candidates = array();
 
+		if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) {
+			$imagedata['height'] = $imagedata['sizes']['full']['height'];
+			$imagedata['width']  = $imagedata['sizes']['full']['width'];
+		}
+
 		foreach ( $imagedata['sizes'] as $_size => $data ) {
 			// If there's an exact match to an existing image size, short circuit.
 			if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) {
@@ -682,7 +700,7 @@
 
 	$data = $imagedata['sizes'][$size];
 	// include the full filesystem path of the intermediate file
-	if ( empty($data['path']) && !empty($data['file']) ) {
+	if ( empty($data['path']) && ! empty($data['file']) && ! empty($imagedata['file'] ) ) {
 		$file_url = wp_get_attachment_url($post_id);
 		$data['path'] = path_join( dirname($imagedata['file']), $data['file'] );
 		$data['url'] = path_join( dirname($file_url), $data['file'] );
@@ -985,7 +1003,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;
 	}
 
@@ -3069,7 +3087,7 @@
 	if ( current_user_can( 'delete_post', $attachment->ID ) )
 		$response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
 
-	if ( $meta && 'image' === $type ) {
+	if ( $meta && ! empty($meta['sizes']) ) {
 		$sizes = array();
 
 		/** This filter is documented in wp-admin/includes/media.php */
@@ -3117,16 +3135,30 @@
 			}
 		}
 
-		$sizes['full'] = array( 'url' => $attachment_url );
+		if ( 'image' === $type ) {
+			$sizes['full'] = array( 'url' => $attachment_url );
 
-		if ( isset( $meta['height'], $meta['width'] ) ) {
-			$sizes['full']['height'] = $meta['height'];
-			$sizes['full']['width'] = $meta['width'];
-			$sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
+			if ( isset( $meta['height'], $meta['width'] ) ) {
+				$sizes['full']['height'] = $meta['height'];
+				$sizes['full']['width'] = $meta['width'];
+				$sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
+			}
+
+			array_merge( $response, $sizes['full'] );
 		}
+		else if( $meta['sizes']['full']['file'] ) {
+			$sizes['full'] = array(
+				'url'         => $base_url . $meta['sizes']['full']['file'],
+				'height'      => $meta['sizes']['full']['height'],
+				'width'       => $meta['sizes']['full']['width'],
+				'orientation' => $meta['sizes']['full']['height'] < $meta['sizes']['full']['width'] ? 'portrait' : 'landscape'
+			);
+		}
 
-		$response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] );
-	} elseif ( $meta && 'video' === $type ) {
+		$response = array_merge( $response, array( 'sizes' => $sizes ) );
+	}
+
+	if ( $meta && 'video' === $type ) {
 		if ( isset( $meta['width'] ) )
 			$response['width'] = (int) $meta['width'];
 		if ( isset( $meta['height'] ) )
