Index: wp-includes/class-wp-image.php
===================================================================
--- wp-includes/class-wp-image.php	(revision 0)
+++ wp-includes/class-wp-image.php	(revision 0)
@@ -0,0 +1,37 @@
+<?php
+
+class WP_Image {
+	private $editor;
+
+	private $file;
+	private $url;
+	private $meta;
+	private $backup_sizes;
+
+	function __construct( $post_id ) {
+		if ( ! wp_attachment_is_image( $post_id ) )
+			return false;
+
+		$this->file         = get_attached_file( $post_id );
+		$this->url          = wp_get_attachment_url( $post_id );
+		$this->meta         = wp_get_attachment_metadata( $post_id );
+		$this->backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true );
+	}
+
+	function get_metadata() {
+		return $this->meta;
+	}
+
+	function load() {
+		return $this->editor->load( $this->file );
+	}
+
+	private function editor() {
+		if( $this->editor )
+			return $this->editor;
+
+		$this->editor = new WP_Image_Editor( $this->url );
+
+		return $this->editor;
+	}
+}
\ No newline at end of file
Index: wp-includes/media.php
===================================================================
--- wp-includes/media.php	(revision 21387)
+++ wp-includes/media.php	(working copy)
@@ -180,9 +180,9 @@
  *
  * @since 2.9.0
  */
-function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
+function add_image_size( $name, $width = 0, $height = 0, $crop = false, $autogenerate = true ) {
 	global $_wp_additional_image_sizes;
-	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
+	$_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop, 'autogenerate' => (bool) $autogenerate );
 }
 
 /**
@@ -191,7 +191,7 @@
  * @since 2.9.0
  */
 function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
-	add_image_size( 'post-thumbnail', $width, $height, $crop );
+	add_image_size( 'post-thumbnail', $width, $height, $crop, false );
 }
 
 /**
@@ -236,34 +236,6 @@
 }
 
 /**
- * Load an image from a string, if PHP supports it.
- *
- * @since 2.1.0
- *
- * @param string $file Filename of the image to load.
- * @return resource The resulting image resource on success, Error string on failure.
- */
-function wp_load_image( $file ) {
-	if ( is_numeric( $file ) )
-		$file = get_attached_file( $file );
-
-	if ( ! file_exists( $file ) )
-		return sprintf(__('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file);
-
-	if ( ! function_exists('imagecreatefromstring') )
-		return __('The GD image library is not installed.');
-
-	// Set artificially high because GD uses uncompressed images in memory
-	@ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
-	$image = imagecreatefromstring( file_get_contents( $file ) );
-
-	if ( !is_resource( $image ) )
-		return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
-
-	return $image;
-}
-
-/**
  * Calculates the new dimensions for a downsampled image.
  *
  * If either width or height are empty, no constraint is applied on
@@ -393,92 +365,6 @@
 }
 
 /**
- * Scale down an image to fit a particular size and save a new copy of the image.
- *
- * The PNG transparency will be preserved using the function, as well as the
- * image type. If the file going in is PNG, then the resized image is going to
- * be PNG. The only supported image types are PNG, GIF, and JPEG.
- *
- * Some functionality requires API to exist, so some PHP version may lose out
- * support. This is not the fault of WordPress (where functionality is
- * downgraded, not actual defects), but of your PHP version.
- *
- * @since 2.5.0
- *
- * @param string $file Image file path.
- * @param int $max_w Maximum width to resize to.
- * @param int $max_h Maximum height to resize to.
- * @param bool $crop Optional. Whether to crop image or resize.
- * @param string $suffix Optional. File suffix.
- * @param string $dest_path Optional. New image file path.
- * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
- * @return mixed WP_Error on failure. String with new destination path.
- */
-function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
-
-	$image = wp_load_image( $file );
-	if ( !is_resource( $image ) )
-		return new WP_Error( 'error_loading_image', $image, $file );
-
-	$size = @getimagesize( $file );
-	if ( !$size )
-		return new WP_Error('invalid_image', __('Could not read image size'), $file);
-	list($orig_w, $orig_h, $orig_type) = $size;
-
-	$dims = image_resize_dimensions($orig_w, $orig_h, $max_w, $max_h, $crop);
-	if ( !$dims )
-		return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
-	list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
-
-	$newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
-
-	imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
-
-	// convert from full colors to index colors, like original PNG.
-	if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
-		imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
-
-	// we don't need the original in memory anymore
-	imagedestroy( $image );
-
-	// $suffix will be appended to the destination filename, just before the extension
-	if ( !$suffix )
-		$suffix = "{$dst_w}x{$dst_h}";
-
-	$info = pathinfo($file);
-	$dir = $info['dirname'];
-	$ext = $info['extension'];
-	$name = wp_basename($file, ".$ext");
-
-	if ( !is_null($dest_path) and $_dest_path = realpath($dest_path) )
-		$dir = $_dest_path;
-	$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
-
-	if ( IMAGETYPE_GIF == $orig_type ) {
-		if ( !imagegif( $newimage, $destfilename ) )
-			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
-	} elseif ( IMAGETYPE_PNG == $orig_type ) {
-		if ( !imagepng( $newimage, $destfilename ) )
-			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
-	} else {
-		// all other formats are converted to jpg
-		if ( 'jpg' != $ext && 'jpeg' != $ext )
-			$destfilename = "{$dir}/{$name}-{$suffix}.jpg";
-		if ( !imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
-			return new WP_Error('resize_path_invalid', __( 'Resize path invalid' ));
-	}
-
-	imagedestroy( $newimage );
-
-	// Set correct file permissions
-	$stat = stat( dirname( $destfilename ));
-	$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
-	@ chmod( $destfilename, $perms );
-
-	return $destfilename;
-}
-
-/**
  * Resize an image to make a thumbnail or intermediate size.
  *
  * The returned array has the file size, the image width, and image height. The
@@ -493,18 +379,17 @@
  * @param bool $crop Optional, default is false. Whether to crop image to specified height and width or resize.
  * @return bool|array False, if no image was created. Metadata array on success.
  */
-function image_make_intermediate_size($file, $width, $height, $crop=false) {
+function image_make_intermediate_size( $file, $width, $height, $crop = sfalse ) {
 	if ( $width || $height ) {
-		$resized_file = image_resize($file, $width, $height, $crop);
-		if ( !is_wp_error($resized_file) && $resized_file && $info = getimagesize($resized_file) ) {
-			$resized_file = apply_filters('image_make_intermediate_size', $resized_file);
-			return array(
-				'file' => wp_basename( $resized_file ),
-				'width' => $info[0],
-				'height' => $info[1],
-			);
+		$editor = new WP_Image_Editor( $file );
+		$resized_file = $editor->resize( $width, $height, $crop );
+		unset( $editor );
+
+		if ( ! is_wp_error( $resized_file ) && $resized_file ) {
+			return $resized_file;
 		}
 	}
+
 	return false;
 }
 
Index: wp-includes/editors/class-wp-image-editor-imagick.php
===================================================================
--- wp-includes/editors/class-wp-image-editor-imagick.php	(revision 0)
+++ wp-includes/editors/class-wp-image-editor-imagick.php	(revision 0)
@@ -0,0 +1,95 @@
+<?php
+
+class WP_Image_Editor_Imagick {
+	function __construct() {
+
+	}
+
+	public static function test( $function ) {
+		if ( ! extension_loaded('imagick') )
+			return false;
+
+		return true;
+	}
+
+	public function load( $file ) {
+		if ( ! file_exists( $file ) )
+			return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file );
+
+		try {
+			$image = new Imagick( $file );
+		}
+		catch ( Exception $e ) {
+			return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
+		}
+
+		if( ! $image->valid() ) {
+			return sprintf(__('File &#8220;%s&#8221; is not an image.'), $file);
+		}
+
+		return $image;
+	}
+
+	public function resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
+		$image = $this->load( $file );
+		if ( ! is_object( $image ) )
+			return new WP_Error( 'error_loading_image', $image, $file );
+
+		$imageprops = $image->getImageGeometry();
+		$orig_type  = $image->getImageFormat();
+		if ( ! $imageprops )
+			return new WP_Error( 'invalid_image', __('Could not read image size'), $file );
+
+		$dims = image_resize_dimensions( $imageprops['width'], $imageprops['height'], $max_w, $max_h, $crop );
+		if ( ! $dims )
+			return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
+		list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
+
+		if( 'JPEG' == $orig_type ) {
+			$image->setImageCompression( imagick::COMPRESSION_JPEG );
+			$image->setImageCompressionQuality( $jpeg_quality );
+		}
+
+		if ( $crop ) {
+			$image->cropImage( $src_w, $src_h, $src_x, $src_y );
+
+			$image->scaleImage( $dst_w, $dst_h, true );
+			//$image->resizeImage( $dst_w, $dst_h, imagick::FILTER_LANCZOS, 1 );
+		}
+		else {
+			//$image->thumbnailImage( $dst_w, $dst_h );
+			$image->scaleImage( $dst_w, $dst_h, true );
+		}
+
+		// $suffix will be appended to the destination filename, just before the extension
+		if ( ! $suffix )
+			$suffix = "{$dst_w}x{$dst_h}";
+
+		$info = pathinfo( $file );
+		$dir  = $info['dirname'];
+		$ext  = $info['extension'];
+		$name = wp_basename( $file, ".$ext" );
+
+		if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) )
+			$dir = $_dest_path;
+		$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
+
+		if( apply_filters( 'wp_editors_stripimage', true ) ) {
+			$image->stripImage();
+		}
+
+		$image->writeImage( $destfilename );
+
+		// Set correct file permissions
+		$stat = stat( dirname( $destfilename ) );
+		$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
+		@ chmod( $destfilename, $perms );
+
+		return array(
+			'path' => $destfilename,
+			'file' => wp_basename(  apply_filters( 'image_make_intermediate_size', $destfilename ) ),
+			'width' => $dst_w,
+			'height' => $dst_h
+		);
+	}
+}
\ No newline at end of file
Index: wp-includes/editors/class-wp-image-editor-gd.php
===================================================================
--- wp-includes/editors/class-wp-image-editor-gd.php	(revision 0)
+++ wp-includes/editors/class-wp-image-editor-gd.php	(revision 0)
@@ -0,0 +1,113 @@
+<?php
+
+class WP_Image_Editor_GD {
+	private $image = false;
+
+	function __construct() {
+
+	}
+
+	function __destruct() {
+		if ( $this->image ) {
+			// we don't need the original in memory anymore
+			imagedestroy( $this->image );
+		}
+	}
+
+	public static function test( $function ) {
+		if ( ! extension_loaded('gd') || ! function_exists('gd_info') )
+			return false;
+
+		return true;
+	}
+
+	public function load( $file ) {
+		if( $this->image ) 
+			$this->image;
+
+		if ( ! file_exists( $file ) )
+			return sprintf( __('File &#8220;%s&#8221; doesn&#8217;t exist?'), $file );
+
+		if ( ! function_exists('imagecreatefromstring') )
+			return __('The GD image library is not installed.');
+
+		// Set artificially high because GD uses uncompressed images in memory
+		@ini_set( 'memory_limit', apply_filters( 'image_memory_limit', WP_MAX_MEMORY_LIMIT ) );
+		$image = imagecreatefromstring( file_get_contents( $file ) );
+
+		if ( ! is_resource( $image ) )
+			return sprintf( __('File &#8220;%s&#8221; is not an image.'), $file );
+
+		$this->image = $image;
+		return $image;
+	}
+
+	public function resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
+		$image = $this->load( $file );
+		if ( ! is_resource( $image ) )
+			return new WP_Error( 'error_loading_image', $image, $file );
+
+		$size = @getimagesize( $file );
+		if ( ! $size )
+			return new WP_Error( 'invalid_image', __('Could not read image size'), $file );
+		list( $orig_w, $orig_h, $orig_type ) = $size;
+
+		$dims = image_resize_dimensions( $orig_w, $orig_h, $max_w, $max_h, $crop );
+		if ( ! $dims )
+			return new WP_Error( 'error_getting_dimensions', __('Could not calculate resized image dimensions') );
+		list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
+
+
+		$newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
+
+		imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );
+
+		// convert from full colors to index colors, like original PNG.
+		if ( IMAGETYPE_PNG == $orig_type && function_exists('imageistruecolor') && !imageistruecolor( $image ) )
+			imagetruecolortopalette( $newimage, false, imagecolorstotal( $image ) );
+
+		// $suffix will be appended to the destination filename, just before the extension
+		if ( ! $suffix )
+			$suffix = "{$dst_w}x{$dst_h}";
+
+		$info = pathinfo( $file );
+		$dir  = $info['dirname'];
+		$ext  = $info['extension'];
+		$name = wp_basename( $file, ".$ext" );
+
+		if ( ! is_null( $dest_path ) && $_dest_path = realpath( $dest_path ) )
+			$dir = $_dest_path;
+		$destfilename = "{$dir}/{$name}-{$suffix}.{$ext}";
+
+		if ( IMAGETYPE_GIF == $orig_type ) {
+			if ( ! imagegif( $newimage, $destfilename ) )
+				return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
+		}
+		elseif ( IMAGETYPE_PNG == $orig_type ) {
+			if ( !imagepng( $newimage, $destfilename ) )
+				return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
+		}
+		else {
+			// all other formats are converted to jpg
+			if ( 'jpg' != $ext && 'jpeg' != $ext )
+				$destfilename = "{$dir}/{$name}-{$suffix}.jpg";
+
+			if ( ! imagejpeg( $newimage, $destfilename, apply_filters( 'jpeg_quality', $jpeg_quality, 'image_resize' ) ) )
+				return new WP_Error( 'resize_path_invalid', __( 'Resize path invalid' ) );
+		}
+
+		imagedestroy( $newimage );
+
+		// Set correct file permissions
+		$stat = stat( dirname( $destfilename ) );
+		$perms = $stat['mode'] & 0000666; //same permissions as parent folder, strip off the executable bits
+		@ chmod( $destfilename, $perms );
+
+		return array(
+			'path' => $destfilename,
+			'file' => wp_basename(  apply_filters( 'image_make_intermediate_size', $destfilename ) ),
+			'width' => $dst_w,
+			'height' => $dst_h
+		);
+	}
+}
\ No newline at end of file
Index: wp-includes/class-wp-image-editor.php
===================================================================
--- wp-includes/class-wp-image-editor.php	(revision 0)
+++ wp-includes/class-wp-image-editor.php	(revision 0)
@@ -0,0 +1,68 @@
+<?php
+
+class WP_Image_Editor {
+	private $file;
+	private $editors;
+
+	function __construct( $file ) {
+		$this->file = $file;
+	}
+
+	/**
+	 * Tests which editors are capable of supporting the request.
+	 *
+	 * @since 3.5.0
+	 * @access private
+	 *
+	 * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request.
+	 */
+	private function get_first_available( $function ) {
+		$request_order = apply_filters( 'wp_editors', array( 'imagick', 'gd' ) );
+
+		// Loop over each editor on each request looking for one which will serve this request's needs
+		foreach ( $request_order as $editor ) {
+			$class = 'WP_Image_Editor_' . $editor;
+
+			// Check to see if this editor is a possibility, calls the editor statically
+			if ( ! call_user_func( array( $class, 'test' ), $function  ) )
+				continue;
+
+			if( ! apply_filters( 'wp_editor_use_' . $editor, true, $function ) )
+				continue;
+
+			if( ! $this->editors[ $class ] ) 
+				$this->editors[ $class ] = new $class;
+
+			return $this->editors[ $class ];
+		}
+
+		return false;
+	}
+
+
+	function load( $file ) {
+		$editor = $this->get_first_available( 'load' );
+
+		if( $editor ) {
+			return $editor->load( $file );
+		}
+
+		return false;
+	}
+
+	function resize( $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
+		$editor = $this->get_first_available( 'resize' );
+
+		if( $editor ) {
+			return $editor->resize( $this->file, $max_w, $max_h, $crop, $suffix, $dest_path, $jpeg_quality );
+		}
+	}
+
+	function rotate() {
+
+	}
+
+	function save() {
+
+	}
+}
\ No newline at end of file
Index: wp-includes/deprecated.php
===================================================================
--- wp-includes/deprecated.php	(revision 21387)
+++ wp-includes/deprecated.php	(working copy)
@@ -3190,3 +3190,58 @@
 	if ( is_sticky( $post_id ) )
 		echo ' sticky';
 }
+
+
+
+
+
+/**
+ * Load an image from a string, if PHP supports it.
+ *
+ * @since 2.1.0
+ * @deprecated 3.5.0
+ * @deprecated wp_get_image_for_editing()
+ *
+ * @param string $file Filename of the image to load.
+ * @return resource The resulting image resource on success, Error string on failure.
+ */
+function wp_load_image( $file ) {
+	_deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' );
+
+	if ( is_numeric( $file ) )
+		$file = get_attached_file( $file );
+
+	$editor = new WP_Image_Editor_GD;
+	$editor->load( $file );
+}
+
+/**
+ * Scale down an image to fit a particular size and save a new copy of the image.
+ *
+ * The PNG transparency will be preserved using the function, as well as the
+ * image type. If the file going in is PNG, then the resized image is going to
+ * be PNG. The only supported image types are PNG, GIF, and JPEG.
+ *
+ * Some functionality requires API to exist, so some PHP version may lose out
+ * support. This is not the fault of WordPress (where functionality is
+ * downgraded, not actual defects), but of your PHP version.
+ *
+ * @since 2.5.0
+ * @deprecated 3.5.0
+ * @deprecated wp_get_image_for_editing()
+ *
+ * @param string $file Image file path.
+ * @param int $max_w Maximum width to resize to.
+ * @param int $max_h Maximum height to resize to.
+ * @param bool $crop Optional. Whether to crop image or resize.
+ * @param string $suffix Optional. File suffix.
+ * @param string $dest_path Optional. New image file path.
+ * @param int $jpeg_quality Optional, default is 90. Image quality percentage.
+ * @return mixed WP_Error on failure. String with new destination path.
+ */
+function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $dest_path = null, $jpeg_quality = 90 ) {
+	_deprecated_function( __FUNCTION__, '3.5', 'wp_get_image_for_editing()' );
+
+	$editor = new WP_Image_Editor_GD;
+	$editor->resize( $file, $max_w, $max_h, $crop, $suffix, $dest_path, $jpeg_quality );
+}
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 21387)
+++ wp-settings.php	(working copy)
@@ -143,6 +143,11 @@
 require( ABSPATH . WPINC . '/nav-menu-template.php' );
 require( ABSPATH . WPINC . '/admin-bar.php' );
 
+require( ABSPATH . WPINC . '/admin-wp-image.php' );
+require( ABSPATH . WPINC . '/admin-wp-image-editor.php' );
+require( ABSPATH . WPINC . '/editors/class-wp-image-editor-gd.php' );
+require( ABSPATH . WPINC . '/editors/class-wp-image-editor-imagick.php' );
+
 // Load multisite-specific files.
 if ( is_multisite() ) {
 	require( ABSPATH . WPINC . '/ms-functions.php' );
Index: wp-admin/includes/image.php
===================================================================
--- wp-admin/includes/image.php	(revision 21387)
+++ wp-admin/includes/image.php	(working copy)
@@ -127,6 +127,9 @@
 		global $_wp_additional_image_sizes;
 
 		foreach ( get_intermediate_image_sizes() as $s ) {
+			if ( isset( $_wp_additional_image_sizes[$s] ) && ! $_wp_additional_image_sizes[$s]['autogenerate'] )
+				continue;
+
 			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
 			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
 				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
@@ -144,12 +147,16 @@
 
 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
 
+		$editor = new WP_Image_Editor( $file );
+
 		foreach ($sizes as $size => $size_data ) {
-			$resized = image_make_intermediate_size( $file, $size_data['width'], $size_data['height'], $size_data['crop'] );
-			if ( $resized )
+			$resized = $editor->resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
+			if ( ! is_wp_error( $resized ) && $resized )
 				$metadata['sizes'][$size] = $resized;
 		}
 
+		unset( $editor );
+
 		// fetch additional metadata from exif/iptc
 		$image_meta = wp_read_image_metadata( $file );
 		if ( $image_meta )
