Index: src/wp-includes/media.php
===================================================================
--- src/wp-includes/media.php	(revision 35390)
+++ src/wp-includes/media.php	(working copy)
@@ -812,10 +812,15 @@
 		$attr = wp_parse_args($attr, $default_attr);
 
 		// Generate srcset and sizes if not already present.
-		if ( empty( $attr['srcset'] ) && ( $srcset = wp_get_attachment_image_srcset( $attachment_id, $size ) ) && ( $sizes = wp_get_attachment_image_sizes( $attachment_id, $size, $width ) ) ) {
-			$attr['srcset'] = $srcset;
+		if ( empty( $attr['srcset'] ) ) {
+			$image_meta = wp_get_attachment_metadata( $attachment_id );
+			$size_array = array( absint( $width ), absint( $height ) );
 
-			if ( empty( $attr['sizes'] ) ) {
+			if ( $srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id ) ) {
+				$attr['srcset'] = $srcset;
+			}
+
+			if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
 				$attr['sizes'] = $sizes;
 			}
 		}
@@ -859,6 +864,40 @@
 }
 
 /**
+ * Private, do not use
+ */
+function _wp_upload_dir_baseurl() {
+	static $baseurl = null;
+
+	if ( ! $baseurl ) {
+		$uploads_dir = wp_upload_dir();
+		$baseurl = $uploads_dir['baseurl'];
+	}
+
+	return $baseurl;
+}
+
+// TODO: needed??
+/**
+ * Private, do not use
+ */
+function _wp_get_image_size_from_meta( $size, $image_meta ) {
+	if ( $size === 'full' ) {
+		return array(
+			absint( $image_meta['width'] ),
+			absint( $image_meta['height'] ),
+		);
+	} elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
+		return array(
+			absint( $image_meta['sizes'][$size]['width'] ),
+			absint( $image_meta['sizes'][$size]['height'] ),
+		);
+	}
+
+	return false;
+}
+
+/**
  * Retrieves an array of URLs and pixel widths representing sizes of an image.
  *
  * The purpose is to populate a source set when creating responsive image markup.
@@ -865,9 +904,10 @@
  *
  * @since 4.4.0
  *
- * @param int          $attachment_id Image attachment ID.
- * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
- *                                    values in pixels (in that order). Default 'medium'.
+ * @param array $size_array    Array of width and height values in pixels (in that order).
+ * @param array $image_meta    The image meta data.
+ * @param int   $attachment_id Optional. Image attachment ID. Used only for the filter.
+ *
  * @return array|bool $sources {
  *     Array image candidate values containing a URL, descriptor type, and
  *     descriptor value. False if none exist.
@@ -881,43 +921,36 @@
  * }
  *
  */
-function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
-	// Get the intermediate size.
-	$image = image_get_intermediate_size( $attachment_id, $size );
-
-	// Get the post meta.
-	$img_meta = wp_get_attachment_metadata( $attachment_id );
-	if ( ! is_array( $img_meta ) ) {
+function wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id = 0 ) {
+	if ( empty( $image_meta['sizes'] ) ) {
 		return false;
 	}
 
-	// Extract the height and width from the intermediate or the full size.
-	$img_width  = ( $image ) ? $image['width']  : $img_meta['width'];
-	$img_height = ( $image ) ? $image['height'] : $img_meta['height'];
+	$img_sizes = $image_meta['sizes'];
 
-	// Bail early if the width isn't greater than zero.
-	if ( ! $img_width > 0 ) {
+	// Get the height and width for the image.
+	$img_width = (int) $size_array[0];
+	$img_height = (int) $size_array[1];
+
+	// Bail early if error/no width.
+	if ( $img_width < 1 ) {
 		return false;
 	}
 
-	// Use the URL from the intermediate size or build the url from the metadata.
-	if ( ! empty( $image['url'] ) ) {
-		$img_url = $image['url'];
-	} else {
-		$uploads_dir = wp_upload_dir();
-		$img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
-		$img_url = $uploads_dir['baseurl'] . '/' . $img_file;
-	}
-
-	$img_sizes = $img_meta['sizes'];
-
 	// Add full size to the img_sizes array.
 	$img_sizes['full'] = array(
-		'width'  => $img_meta['width'],
-		'height' => $img_meta['height'],
-		'file'   => wp_basename( $img_meta['file'] )
+		'width'  => $image_meta['width'],
+		'height' => $image_meta['height'],
+		'file'   => wp_basename( $image_meta['file'] ),
 	);
 
+	$img_baseurl = _wp_upload_dir_baseurl();
+	$dirname = dirname( $image_meta['file'] );
+
+	if ( $dirname !== '.' ) {
+		$img_baseurl = path_join( $img_baseurl, $dirname );
+	}
+
 	// Calculate the image aspect ratio.
 	$img_ratio = $img_height / $img_width;
 
@@ -926,7 +959,7 @@
 	 * contain a unique hash. Look for that hash and use it later to filter
 	 * out images that are leftovers from previous versions.
 	 */
-	$img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
+	$img_edited = preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash );
 
 	/**
 	 * Filter the maximum width included in a srcset attribute.
@@ -933,23 +966,20 @@
 	 *
 	 * @since 4.4.0
 	 *
-	 * @param array|string $size Size of image, either array or string.
+	 * @param array|string $size_array Size of image, either array or string.
 	 */
-	$max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
+	$max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
 
-	/*
-	 * Set up arrays to hold url candidates and matched image sources so
-	 * we can avoid duplicates without looping through the full sources array
-	 */
-	$candidates = $sources = array();
+	// Array to hold url candidates.
+	$sources = array();
 
 	/*
-	 * Loop through available images and only use images that are resized
+	 * Loop through available images. Only use images that are resized
 	 * versions of the same rendition.
 	 */
 	foreach ( $img_sizes as $img ) {
 
-		// Filter out images that are leftovers from previous renditions.
+		// Filter out images that are from previous renditions.
 		if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
 			continue;
 		}
@@ -959,7 +989,7 @@
 			continue;
 		}
 
-		$candidate_url = path_join( dirname( $img_url ), $img['file'] );
+		$candidate_url = path_join( $img_baseurl, $img['file'] );
 
 		// Calculate the new image ratio.
 		if ( $img['width'] ) {
@@ -969,12 +999,9 @@
 		}
 
 		// If the new ratio differs by less than 0.01, use it.
-		if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
-			// Add the URL to our list of candidates.
-			$candidates[] = $candidate_url;
-
+		if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
 			// Add the url, descriptor, and value to the sources array to be returned.
-			$sources[] = array(
+			$sources[ $candidate_url ] = array(
 				'url'        => $candidate_url,
 				'descriptor' => 'w',
 				'value'      => $img['width'],
@@ -987,12 +1014,12 @@
 	 *
 	 * @since 4.4.0
 	 *
-	 * @param array        $sources       An array of image urls and widths.
-	 * @param int          $attachment_id Attachment ID for image.
-	 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
-	 *                                    values in pixels (in that order). Default 'medium'.
+	 * @param array $sources       An array of image urls and widths.
+	 * @param array $size_array    Image size. Array of width and height values in pixels (in that order).
+	 * @param array $image_meta    The image meta data.
+	 * @param int   $attachment_id Attachment ID for image.
 	 */
-	return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
+	return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $size_array, $image_meta, $attachment_id );
 }
 
 /**
@@ -1000,16 +1027,15 @@
  *
  * @since 4.4.0
  *
- * @param int          $attachment_id Image attachment ID.
- * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
- *                                    values in pixels (in that order). Default 'medium'.
- * @return string|bool A 'srcset' value string or false.
+ * @param  int   $image_meta The image meta data.
+ * @param  array $size_array Image size. An array of width and height values in pixels (in that order).
+ * @return string|bool       A 'srcset' value string or false.
  */
-function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
-	$srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
+function wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id = 0 ) {
+	$srcset_array = wp_get_attachment_image_srcset_array( $size_array, $image_meta, $attachment_id );
 
 	// Only return a srcset value if there is more than one source.
-	if ( count( $srcset_array ) <= 1 ) {
+	if ( count( $srcset_array ) < 2 ) {
 		return false;
 	}
 
@@ -1023,45 +1049,40 @@
 	 *
 	 * @since 4.4.0
 	 *
-	 * @param string       $srcset        A source set formated for a `srcset` attribute.
-	 * @param int          $attachment_id Attachment ID for image.
-	 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
-	 *                                    values in pixels (in that order). Default 'medium'.
+	 * @param string $srcset        A source set formated for a `srcset` attribute.
+	 * @param array  $size_array    Image size. Array of width and height values in pixels (in that order).
+	 * @param array  $image_meta    The image meta data.
+	 * @param int    $attachment_id Image attachment ID.
 	 */
-	return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
+	return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $size_array, $image_meta, $attachment_id );
 }
 
 /**
- * Retrieves a source size attribute for an image from an array of values.
+ * Create `sizes` attribute value for an image.
  *
  * @since 4.4.0
  *
- * @param int          $attachment_id Image attachment ID.
- * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
- *                                    values in pixels (in that order). Default 'medium'.
- * @param int          $width         Optional. Display width of the image.
+ * @param int|array $size          The width of the image or an array( $width, $height ).
+ * @param array     $image_meta    Optional. The image meta data.
+ * @param int       $attachment_id Optional. Image attachment ID.
+ *
  * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
  */
-function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
-	// Try to get the image width from $args parameter.
-	if ( is_numeric( $width ) ) {
-		$img_width = (int) $width;
-	// Next, use see if a width value was passed in the $size parameter.
+function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
+	$width = 0;
+
+	if ( is_numeric( $size ) ) {
+		$width = absint( $size );
 	} elseif ( is_array( $size ) ) {
-		$img_width = $size[0];
-	// Finally, use the $size name to return the width of the image.
-	} else {
-		$image = image_get_intermediate_size( $attachment_id, $size );
-		$img_width = $image ? $image['width'] : false;
+		$width = absint( $size[0] );
 	}
 
-	// Bail early if $image_width isn't set.
-	if ( ! $img_width ) {
+	if ( ! $width ) {
 		return false;
 	}
 
 	// Setup the default sizes attribute.
-	$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
+	$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
 
 	/**
 	 * Filter the output of wp_get_attachment_image_sizes().
@@ -1074,7 +1095,7 @@
 	 *                                    values in pixels (in that order). Default 'medium'.
 	 * @param int          $width         Display width of the image.
 	 */
-	return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
+	return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $width, $image_meta, $attachment_id );
 }
 
 /**
@@ -1082,7 +1103,7 @@
  *
  * @since 4.4.0
  *
- * @see wp_img_add_srcset_and_sizes()
+ * @see wp_image_add_srcset_and_sizes()
  *
  * @param string $content The raw post content to be filtered.
  * @return string Converted content with 'srcset' and 'sizes' attributes added to images.
@@ -1090,31 +1111,15 @@
 function wp_make_content_images_responsive( $content ) {
 	$images = get_media_embedded_in_content( $content, 'img' );
 
-	$attachment_ids = array();
+	foreach( $images as $image ) {
+		if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
+			( $attachment_id = absint( $class_id[1] ) ) ) {
 
-	foreach( $images as $image ) {
-		if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
-			$attachment_id = (int) $class_id[1];
-			if ( $attachment_id ) {
-				$attachment_ids[] = $attachment_id;
-			}
+			$image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+			$content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
 		}
 	}
 
-	if ( 0 < count( $attachment_ids ) ) {
-		/*
-		 * Warm object caches for use with wp_get_attachment_metadata.
-		 *
-		 * To avoid making a database call for each image, a single query
-		 * warms the object cache with the meta information for all images.
-		 */
-		_prime_post_caches( $attachment_ids, false, true );
-	}
-
-	foreach( $images as $image ) {
-		$content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
-	}
-
 	return $content;
 }
 
@@ -1126,67 +1131,71 @@
  * @see wp_get_attachment_image_srcset()
  * @see wp_get_attachment_image_sizes()
  *
- * @param string $image An HTML 'img' element to be filtered.
+ * @param string $image         An HTML 'img' element to be filtered.
+ * @param array  $image_meta    The image meta data.
+ * @param int    $attachment_id Image attachment ID.
  * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
  */
-function wp_img_add_srcset_and_sizes( $image ) {
-	// Return early if a 'srcset' attribute already exists.
-	if ( false !== strpos( $image, ' srcset="' ) ) {
+function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
+	// Ensure the image meta exists
+	if ( empty( $image_meta['sizes'] ) ) {
 		return $image;
 	}
 
-	// Parse id, size, width, and height from the `img` element.
-	$id     = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id     ) ? (int) $match_id[1]     : false;
-	$size   = preg_match( '/size-([^\s|"]+)/i',   $image, $match_size   ) ? $match_size[1]         : false;
-	$width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : false;
+	$src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
+	list( $src ) = explode( '?', $src );
 
-	if ( $id && false === $size ) {
-		$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
+	// Return early if we coudn't get the image source.
+	if ( ! $src ) {
+		return $image;
+	}
 
-		if ( $width && $height ) {
-			$size = array( $width, $height );
-		}
+	// Bail early when an image has been inserted and later edited.
+	// We don't have the previous image meta to generate srcset.
+	if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
+		strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
+
+		return $image;
 	}
 
-	/*
-	 * If attempts to parse the size value failed, attempt to use the image
-	 * metadata to match the 'src' against the available sizes for an attachment.
-	 */
-	if ( ! $size && ! empty( $id ) && is_array( $meta = wp_get_attachment_metadata( $id ) ) ) {
-		// Parse the image src value from the img element.
-		$src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
+	$width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
+	$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
 
-		// Return early if the src value is empty.
-		if ( ! $src ) {
-			return $image;
-		}
-
+	if ( ! $width || ! $height ) {
 		/*
-		 * First, see if the file is the full size image. If not, loop through
-		 * the intermediate sizes until we find a file that matches.
+		 * If attempts to parse the size value failed, attempt to use the image
+		 * metadata to match the 'src' against the available sizes for an attachment.
 		 */
 		$image_filename = wp_basename( $src );
 
-		if ( $image_filename === basename( $meta['file'] ) ) {
-			$size = 'full';
+		if ( $image_filename === basename( $image_meta['file'] ) ) {
+			$width = (int) $image_meta['width'];
+			$height = (int) $image_meta['height'];
 		} else {
-			foreach( $meta['sizes'] as $image_size => $image_size_data ) {
+			foreach( $image_meta['sizes'] as $image_size_data ) {
 				if ( $image_filename === $image_size_data['file'] ) {
-					$size = $image_size;
+					$width = (int) $image_size_data['width'];
+					$height = (int) $image_size_data['height'];
 					break;
 				}
 			}
 		}
+	}
 
+	if ( ! $width || ! $height ) {
+		return $image;
 	}
 
-	// If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
-	if ( $id && $size && ( $srcset = wp_get_attachment_image_srcset( $id, $size ) ) && ( $sizes = wp_get_attachment_image_sizes( $id, $size, $width ) ) ) {
+	$size_array = array( $width, $height );
+	$srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, $attachment_id );
+	$sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
+
+	if ( $srcset && $sizes ) {
 		// Format the srcset and sizes string and escape attributes.
-		$srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
+		$srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
 
 		// Add srcset and sizes attributes to the image markup.
-		$image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
+		$image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
 	}
 
 	return $image;
Index: tests/phpunit/tests/media.php
===================================================================
--- tests/phpunit/tests/media.php	(revision 35390)
+++ tests/phpunit/tests/media.php	(working copy)
@@ -716,27 +716,45 @@
 	}
 
 	/**
+	 * Helper function to get image size array from size "name"
+	 */
+	function _get_image_size_array_from_name( $size_name ) {
+		switch ( $size_name ) {
+			case 'thumbnail':
+				return array( 150, 150 );
+			case 'medium':
+				return array( 300, 225 );
+			case 'large':
+				return array( 1024, 768 );
+			case 'full':
+				return array( 1600, 1200 ); // actual size of ../data/images/test-image-large.png
+			default:
+				return array( 800, 600 ); // soft-resized image
+		}
+	}
+
+	/**
 	 * @ticket 33641
 	 */
 	function test_wp_get_attachment_image_srcset_array() {
 		$year_month = date('Y/m');
-		$image = wp_get_attachment_metadata( self::$large_id );
+		$image_meta = wp_get_attachment_metadata( self::$large_id );
 
 		$expected = array(
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['medium']['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['medium']['file'],
 				'descriptor' => 'w',
-				'value'      => $image['sizes']['medium']['width'],
+				'value'      => $image_meta['sizes']['medium']['width'],
 			),
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image['sizes']['large']['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['large']['file'],
 				'descriptor' => 'w',
-				'value'      => $image['sizes']['large']['width'],
+				'value'      => $image_meta['sizes']['large']['width'],
 			),
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
 				'descriptor' => 'w',
-				'value'      => $image['width'],
+				'value'      => $image_meta['width'],
 			),
 		);
 
@@ -744,7 +762,8 @@
 		$sizes = array( 'medium', 'large', 'full', 'yoav' );
 
 		foreach ( $sizes as $size ) {
-			$this->assertSame( $expected, wp_get_attachment_image_srcset_array( self::$large_id, $size ) );
+			$size_array = $this->_get_image_size_array_from_name( $size );
+			$this->assertSame( $expected, wp_get_attachment_image_srcset_array( $size_array, $image_meta, $id ) );
 		}
 	}
 
@@ -762,23 +781,23 @@
 		$filename = DIR_TESTDATA . '/images/test-image-large.png';
 		$id = self::factory()->attachment->create_upload_object( $filename );
 
-		$image = wp_get_attachment_metadata( $id );
+		$image_meta = wp_get_attachment_metadata( $id );
 
 		$expected = array(
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['medium']['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['medium']['file'],
 				'descriptor' => 'w',
-				'value'      => $image['sizes']['medium']['width'],
+				'value'      => $image_meta['sizes']['medium']['width'],
 			),
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['sizes']['large']['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file'],
 				'descriptor' => 'w',
-				'value'      => $image['sizes']['large']['width'],
+				'value'      => $image_meta['sizes']['large']['width'],
 			),
 			array(
-				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'],
+				'url'        => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'],
 				'descriptor' => 'w',
-				'value'      => $image['width'],
+				'value'      => $image_meta['width'],
 			),
 		);
 
@@ -786,7 +805,8 @@
 		$sizes = array( 'medium', 'large', 'full', 'yoav' );
 
 		foreach ( $sizes as $size ) {
-			$this->assertSame( $expected, wp_get_attachment_image_srcset_array( $id, $size ) );
+			$size_array = $this->_get_image_size_array_from_name( $size );
+			$this->assertSame( $expected, wp_get_attachment_image_srcset_array( $size_array, $image_meta, $id ) );
 		}
 
 		// Leave the uploads option the way you found it.
@@ -799,21 +819,20 @@
 	function test_wp_get_attachment_image_srcset_array_with_edits() {
 		// For this test we're going to mock metadata changes from an edit.
 		// Start by getting the attachment metadata.
-		$meta = wp_get_attachment_metadata( self::$large_id );
+		$image_meta = wp_get_attachment_metadata( self::$large_id );
+		$size_array = $this->_get_image_size_array_from_name( 'medium' );
 
 		// Copy hash generation method used in wp_save_image().
 		$hash = 'e' . time() . rand(100, 999);
 
 		// Replace file paths for full and medium sizes with hashed versions.
-		$filename_base = basename( $meta['file'], '.png' );
-		$meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['file'] );
-		$meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['sizes']['medium']['file'] );
+		$filename_base = basename( $image_meta['file'], '.png' );
+		$image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] );
+		$image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] );
+		$image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] );
 
-		// Save edited metadata.
-		wp_update_attachment_metadata( self::$large_id, $meta );
-
 		// Calculate a srcset array.
-		$sizes = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
+		$sizes = wp_get_attachment_image_srcset_array( $size_array, $image_meta, self::$large_id );
 
 		// Test to confirm all sources in the array include the same edit hash.
 		foreach ( $sizes as $size ) {
@@ -825,7 +844,7 @@
 	 * @ticket 33641
 	 */
 	function test_wp_get_attachment_image_srcset_array_false() {
-		$sizes = wp_get_attachment_image_srcset_array( 99999, 'foo' );
+		$sizes = wp_get_attachment_image_srcset_array( array( 400, 300 ), array(), 99999 );
 
 		// For canola.jpg we should return
 		$this->assertFalse( $sizes );
@@ -835,18 +854,18 @@
 	 * @ticket 33641
 	 */
 	function test_wp_get_attachment_image_srcset_array_no_width() {
-		// Filter image_downsize() output.
-		add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_wp_get_attachment_image_srcset_array_no_width_filter' ) );
-
-		$old_meta = get_post_meta( self::$large_id, '_wp_attachment_metadata', true );
 		$file = get_attached_file( self::$large_id );
+		$image_meta = wp_generate_attachment_metadata( self::$large_id, $file );
 
-		$data = wp_generate_attachment_metadata( self::$large_id, $file );
-		wp_update_attachment_metadata( self::$large_id, $data );
+		// Remove the sizes for 'large' and 'full'
+		$image_meta['width'] = 0;
+		$image_meta['height'] = 0;
+		$image_meta['sizes']['large']['width'] = 0;
+		$image_meta['sizes']['large']['height'] = 0;
 
-		$srcset = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' );
+		$size_array = $this->_get_image_size_array_from_name( 'medium' );
 
-		update_post_meta( self::$large_id, '_wp_attachment_metadata', $old_meta );
+		$srcset = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
 
 		// The srcset should be false.
 		$this->assertFalse( $srcset );
@@ -853,30 +872,21 @@
 	}
 
 	/**
-	 * Helper function to filter image_downsize and return zero values for width and height.
-	 */
-	public function _test_wp_get_attachment_image_srcset_array_no_width_filter( $meta ) {
-		remove_filter( 'wp_generate_attachment_metadata', array( $this, __FUNCTION__ ) );
-
-		$meta['sizes']['medium']['width'] = 0;
-		$meta['sizes']['medium']['height'] = 0;
-		return $meta;
-	}
-
-	/**
 	 * @ticket 33641
 	 */
 	function test_wp_get_attachment_image_srcset() {
-		$sizes = wp_get_attachment_image_srcset( self::$large_id, 'full-size' );
+		$image_meta = wp_get_attachment_metadata( self::$large_id );
+		$size_array = array( 1600, 1200 ); // full size
 
-		$image = wp_get_attachment_metadata( self::$large_id );
+		$sizes = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
+
 		$year_month = date('Y/m');
 
 		$expected = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
-			. $image['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, ';
+			. $image_meta['sizes']['medium']['file'] . ' ' . $image_meta['sizes']['medium']['width'] . 'w, ';
 		$expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/'
-			. $image['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w, ';
-		$expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image['file'] . ' ' . $image['width'] .'w';
+			. $image_meta['sizes']['large']['file'] . ' ' . $image_meta['sizes']['large']['width'] . 'w, ';
+		$expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'] . ' ' . $image_meta['width'] .'w';
 
 		$this->assertSame( $expected, $sizes );
 	}
@@ -885,11 +895,13 @@
 	 * @ticket 33641
 	 */
 	function test_wp_get_attachment_image_srcset_single_srcset() {
+		$image_meta = wp_get_attachment_metadata( self::$large_id );
+		$size_array = array( 150, 150 );
 		/*
 		 * In our tests, thumbnails will only return a single srcset candidate,
 		 * so we shouldn't return a srcset value in order to avoid unneeded markup.
 		 */
-		$sizes = wp_get_attachment_image_srcset( self::$large_id, 'thumbnail' );
+		$sizes = wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id );
 
 		$this->assertFalse( $sizes );
 	}
@@ -899,15 +911,16 @@
 	 */
 	function test_wp_get_attachment_image_sizes() {
 		// Test sizes against the default WP sizes.
-		$intermediates = array('thumbnail', 'medium', 'large');
+		$intermediates = array( 'thumbnail', 'medium', 'large' );
 
-		foreach( $intermediates as $int ) {
-			$width = get_option( $int . '_size_w' );
+		foreach( $intermediates as $int_size ) {
+			$size_array = $this->_get_image_size_array_from_name( $int_size );
+			list( $width, $height ) = $size_array;
 
 			$expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
-			$sizes = wp_get_attachment_image_sizes( self::$large_id, $int );
+			$sizes = wp_get_attachment_image_sizes( $size_array );
 
-			$this->assertSame($expected, $sizes);
+			$this->assertSame( $expected, $sizes );
 		}
 	}
 
@@ -914,22 +927,13 @@
 	/**
 	 * @ticket 33641
 	 */
-	function test_wp_get_attachment_image_sizes_with_width() {
-		$width = 350;
+	function test_wp_make_content_images_responsive() {
+		$image_meta = wp_get_attachment_metadata( self::$large_id );
+		$size_array = $this->_get_image_size_array_from_name( 'medium' );
 
-		$expected = '(max-width: 350px) 100vw, 350px';
-		$sizes = wp_get_attachment_image_sizes( self::$large_id, 'medium', $width );
+		$srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( $size_array, $image_meta, self::$large_id ) );
+		$sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( $size_array, $image_meta, self::$large_id ) );
 
-		$this->assertSame( $expected, $sizes );
-	}
-
-	/**
-	 * @ticket 33641
-	 */
-	function test_wp_make_content_images_responsive() {
-		$srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, 'medium' ) );
-		$sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, 'medium' ) );
-
 		// Function used to build HTML for the editor.
 		$img = get_image_tag( self::$large_id, '', '', '', 'medium' );
 		$img_no_size = str_replace( 'size-', '', $img );
