diff --git a/.npmignore b/.npmignore
index 6ce83015..0132a284 100644
--- a/.npmignore
+++ b/.npmignore
@@ -7,3 +7,4 @@ coverage
test
.travis.yml
appveyor.yml
+mkdocs.yml
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
old mode 100755
new mode 100644
index 94830175..740b4b3e
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -34,7 +34,12 @@ To test C++ changes, you can compile the module using `npm install` and then run
## Submit a Pull Request with a new feature
-Please add JavaScript [unit tests](https://github.com/lovell/sharp/tree/master/test/unit) to cover your new feature. A test coverage report for the JavaScript code is generated in the `coverage/lcov-report` directory.
+Please add JavaScript [unit tests](https://github.com/lovell/sharp/tree/master/test/unit) to cover your new feature.
+A test coverage report for the JavaScript code is generated in the `coverage/lcov-report` directory.
+
+Where possible, the functional tests use gradient-based perceptual hashes
+based on [dHash](http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html)
+to compare expected vs actual images.
You deserve to add your details to the [list of contributors](https://github.com/lovell/sharp/blob/master/package.json#L5).
diff --git a/README.md b/README.md
old mode 100755
new mode 100644
index e9569ad2..efcb9089
--- a/README.md
+++ b/README.md
@@ -1,831 +1,30 @@
# sharp
-* [Installation](https://github.com/lovell/sharp#installation)
-* [Usage examples](https://github.com/lovell/sharp#usage-examples)
-* [API](https://github.com/lovell/sharp#api)
-* [Contributing](https://github.com/lovell/sharp#contributing)
-* [Testing](https://github.com/lovell/sharp#testing)
-* [Performance](https://github.com/lovell/sharp#performance)
-* [Thanks](https://github.com/lovell/sharp#thanks)
-* [Licence](https://github.com/lovell/sharp#licence)
-
-The typical use case for this high speed Node.js module is to convert large images of many formats to smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
-
-This module supports reading and writing JPEG, PNG and WebP images to and from Streams, Buffer objects and the filesystem.
-It also supports reading images of many other formats from the filesystem via libmagick, libgraphicsmagick or [OpenSlide](http://openslide.org/) if present.
-
-Deep Zoom image pyramids can be generated, suitable for use with "slippy map" tile viewers like
-[OpenSeadragon](https://github.com/openseadragon/openseadragon) and [Leaflet](https://github.com/turban/Leaflet.Zoomify).
-
-Colour spaces, embedded ICC profiles and alpha transparency channels are all handled correctly.
-
-Only small regions of uncompressed image data are held in memory and processed at a time, taking full advantage of multiple CPU cores and L1/L2/L3 cache. Resizing an image is typically 4x faster than using the quickest ImageMagick and GraphicsMagick settings.
-
-Huffman tables are optimised when generating JPEG output images without having to use separate command line tools like [jpegoptim](https://github.com/tjko/jpegoptim) and [jpegtran](http://jpegclub.org/jpegtran/). PNG filtering can be disabled, which for diagrams and line art often produces the same result as [pngcrush](http://pmt.sourceforge.net/pngcrush/).
-
-Everything remains non-blocking thanks to _libuv_, no child processes are spawned and Promises/A+ are supported.
-
-Anyone who has used the Node.js bindings for [GraphicsMagick](https://github.com/aheckmann/gm) will find the API similarly fluent.
-
-This module is powered by the blazingly fast [libvips](https://github.com/jcupitt/libvips) image processing library, originally created in 1989 at Birkbeck College and currently maintained by [John Cupitt](https://github.com/jcupitt).
-
-## Installation
-
- npm install sharp
-
-### Prerequisites
-
-* Node.js v0.10+ or io.js
-* [libvips](https://github.com/jcupitt/libvips) v7.40.0+ (7.42.0+ recommended)
-* C++11 compatible compiler such as gcc 4.6+, clang 3.0+ or MSVC 2013
-
-To install the most suitable version of libvips on the following Operating Systems:
-
-* Mac OS
- * Homebrew
- * MacPorts
-* Debian Linux
- * Debian 7, 8
- * Ubuntu 12.04, 14.04, 14.10, 15.04
- * Mint 13, 17
-* Red Hat Linux
- * RHEL/Centos/Scientific 6, 7
- * Fedora 21, 22
- * Amazon Linux 2014.09
-* OpenSuse Linux
- * OpenSuse 13.1, 13.2
-
-run the following as a user with `sudo` access:
-
- curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -
-
-or run the following as `root`:
-
- curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | bash -
-
-The [preinstall.sh](https://github.com/lovell/sharp/blob/master/preinstall.sh) script requires `curl` and `pkg-config`.
-
-Add `--with-openslide` to enable OpenSlide support:
-
- curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -s -- --with-openslide
-
-### Mac OS tips
-
-Manual install via homebrew:
-
- brew install homebrew/science/vips --with-webp --with-graphicsmagick
-
-A missing or incorrectly configured _Xcode Command Line Tools_ installation [can lead](https://github.com/lovell/sharp/issues/80) to a `library not found for -ljpeg` error. If so, please try:
-
- xcode-select --install
-
-The _gettext_ dependency of _libvips_ [can lead](https://github.com/lovell/sharp/issues/9) to a `library not found for -lintl` error. If so, please try:
-
- brew link gettext --force
-
-### Windows
-
-Requires x86 32-bit Node.js or io.js (use `iojs.exe` rather than `node.exe`).
-The WebP format is currently unsupported.
-
-1. Ensure the [node-gyp prerequisites](https://github.com/TooTallNate/node-gyp#installation) are met.
-2. [Download](http://www.vips.ecs.soton.ac.uk/supported/current/win32/) and unzip `vips-dev.x.y.z.zip`.
-3. Set the `VIPS_HOME` environment variable to the full path of the `vips-dev-x.y.z` directory.
-4. Add `vips-dev-x.y.z\bin` to `PATH`.
-
-Versions of MSVC more recent than 2013 may require the use of `npm install --arch=ia32 --msvs_version=2013`.
-
-### Heroku
-
-[Alessandro Tagliapietra](https://github.com/alex88) maintains an [Heroku buildpack for libvips](https://github.com/alex88/heroku-buildpack-vips) and its dependencies.
-
-### Docker
-
-[Marc Bachmann](https://github.com/marcbachmann) maintains a [Dockerfile for libvips](https://github.com/marcbachmann/dockerfile-libvips).
-
- docker pull marcbachmann/libvips
-
-### Build tools
-
-* [gulp-responsive](https://www.npmjs.com/package/gulp-responsive)
-* [gulp-sharp](https://www.npmjs.com/package/gulp-sharp)
-* [grunt-sharp](https://www.npmjs.com/package/grunt-sharp)
-
-## Usage examples
-
-```javascript
-var sharp = require('sharp');
-```
-
-```javascript
-sharp('input.jpg').resize(300, 200).toFile('output.jpg', function(err) {
- if (err) {
- throw err;
- }
- // output.jpg is a 300 pixels wide and 200 pixels high image
- // containing a scaled and cropped version of input.jpg
-});
-```
-
-```javascript
-var transformer = sharp()
- .resize(300, 200)
- .crop(sharp.gravity.north)
- .on('error', function(err) {
- console.log(err);
- });
-// Read image data from readableStream, resize and write image data to writableStream
-readableStream.pipe(transformer).pipe(writableStream);
-```
-
-```javascript
-var image = sharp(inputJpg);
-image.metadata(function(err, metadata) {
- image.resize(Math.floor(metadata.width / 2)).webp().toBuffer(function(err, outputBuffer, info) {
- // outputBuffer contains a WebP image half the width and height of the original JPEG
- });
-});
-```
-
-```javascript
-var pipeline = sharp()
- .rotate()
- .resize(null, 200)
- .progressive()
- .toBuffer(function(err, outputBuffer, info) {
- if (err) {
- throw err;
- }
- // outputBuffer contains 200px high progressive JPEG image data,
- // auto-rotated using EXIF Orientation tag
- // info.width and info.height contain the dimensions of the resized image
- });
-readableStream.pipe(pipeline);
-```
-
-```javascript
-var pipeline = sharp().rotate();
-pipeline.clone().resize(800, 600).pipe(firstWritableStream);
-pipeline.clone().extract(20, 20, 100, 100).pipe(secondWritableStream);
-readableStream.pipe(pipeline);
-// firstWritableStream receives auto-rotated, resized readableStream
-// secondWritableStream receives auto-rotated, extracted region of readableStream
-```
-
-```javascript
-sharp('input.png')
- .rotate(180)
- .resize(300)
- .flatten()
- .background('#ff6600')
- .overlayWith('overlay.png')
- .sharpen()
- .withMetadata()
- .quality(90)
- .webp()
- .toBuffer()
- .then(function(outputBuffer) {
- // outputBuffer contains upside down, 300px wide, alpha channel flattened
- // onto orange background, composited with `overlay.png`, sharpened,
- // with metadata, 90% quality WebP image data
- });
-```
-
-```javascript
-http.createServer(function(request, response) {
- response.writeHead(200, {'Content-Type': 'image/webp'});
- sharp('input.jpg').rotate().resize(200).webp().pipe(response);
-}).listen(8000);
-// Create HTTP server that always returns auto-rotated 'input.jpg',
-// resized to 200 pixels wide, in WebP format
-```
-
-```javascript
-sharp(input)
- .extract(top, left, width, height)
- .toFile(output);
- // Extract a region of the input image, saving in the same format.
-```
-
-```javascript
-sharp(input)
- .extract(topOffsetPre, leftOffsetPre, widthPre, heightPre)
- .resize(width, height)
- .extract(topOffsetPost, leftOffsetPost, widthPost, heightPost)
- .toFile(output);
- // Extract a region, resize, then extract from the resized image
-```
-
-```javascript
-sharp(inputBuffer)
- .resize(200, 300)
- .interpolateWith(sharp.interpolator.nohalo)
- .background('white')
- .embed()
- .toFile('output.tiff')
- .then(function() {
- // output.tiff is a 200 pixels wide and 300 pixels high image
- // containing a nohalo scaled version, embedded on a white canvas,
- // of the image data in inputBuffer
- });
-```
-
-```javascript
-sharp('input.gif')
- .resize(200, 300)
- .background({r: 0, g: 0, b: 0, a: 0})
- .embed()
- .toFormat(sharp.format.webp)
- .toBuffer(function(err, outputBuffer) {
- if (err) {
- throw err;
- }
- // outputBuffer contains WebP image data of a 200 pixels wide and 300 pixels high
- // containing a scaled version, embedded on a transparent canvas, of input.gif
- });
-```
-
-```javascript
-sharp(inputBuffer)
- .resize(200, 200)
- .max()
- .toFormat('jpeg')
- .toBuffer().then(function(outputBuffer) {
- // outputBuffer contains JPEG image data no wider than 200 pixels and no higher
- // than 200 pixels regardless of the inputBuffer image dimensions
- });
-```
-
-```javascript
-sharp('input.tiff').tile(256).toFile('output.dzi', function(err, info) {
- // The output.dzi file is the XML format Deep Zoom definition
- // The output_files directory contains 256x256 pixel tiles grouped by zoom level
-});
-```
-
-```javascript
-// Runtime discovery of available formats
-console.dir(sharp.format);
-```
-
-## API
-
-### Attributes
-
-#### format
-
-An Object containing nested boolean values
-representing the available input and output formats/methods,
-for example:
-
-```javascript
-{ jpeg: { id: 'jpeg',
- input: { file: true, buffer: true, stream: true },
- output: { file: true, buffer: true, stream: true } },
- png: { id: 'png',
- input: { file: true, buffer: true, stream: true },
- output: { file: true, buffer: true, stream: true } },
- webp: { id: 'webp',
- input: { file: true, buffer: true, stream: true },
- output: { file: true, buffer: true, stream: true } },
- tiff: { id: 'tiff',
- input: { file: true, buffer: true, stream: true },
- output: { file: true, buffer: false, stream: false } },
- magick: { id: 'magick',
- input: { file: true, buffer: true, stream: true },
- output: { file: false, buffer: false, stream: false } },
- raw: { id: 'raw',
- input: { file: false, buffer: false, stream: false },
- output: { file: false, buffer: true, stream: true } } }
-```
-
-#### queue
-
-An EventEmitter that emits a `change` event when a task is either:
-
-* queued, waiting for _libuv_ to provide a worker thread
-* complete
-
-```javascript
-sharp.queue.on('change', function(queueLength) {
- console.log('Queue contains ' + queueLength + ' task(s)');
-});
-```
-
-### Input methods
-
-#### sharp([input])
-
-Constructor to which further methods are chained. `input`, if present, can be one of:
-
-* Buffer containing JPEG, PNG, WebP, GIF* or TIFF image data, or
-* String containing the filename of an image, with most major formats supported.
-
-The object returned implements the [stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
-
-JPEG, PNG, WebP, GIF* or TIFF format image data can be streamed into the object when `input` is not provided.
-
-JPEG, PNG or WebP format image data can be streamed out from this object.
-
-\* libvips 8.0.0+ is required for Buffer/Stream input of GIF and other `magick` formats.
-
-#### metadata([callback])
-
-Fast access to image metadata without decoding any compressed image data.
-
-`callback`, if present, gets the arguments `(err, metadata)` where `metadata` has the attributes:
-
-* `format`: Name of decoder to be used to decompress image data e.g. `jpeg`, `png`, `webp` (for file-based input additionally `tiff`, `magick` and `openslide`)
-* `width`: Number of pixels wide
-* `height`: Number of pixels high
-* `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `scrgb`, `cmyk`, `lab`, `xyz`, `b-w` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L522)
-* `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
-* `hasProfile`: Boolean indicating the presence of an embedded ICC profile
-* `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
-* `orientation`: Number value of the EXIF Orientation header, if present
-* `exif`: Buffer containing raw EXIF data, if present
-* `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
-
-A Promises/A+ promise is returned when `callback` is not provided.
-
-#### sequentialRead()
-
-An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`. This will reduce memory usage and can improve performance on some systems.
-
-#### limitInputPixels(pixels)
-
-Do not process input images where the number of pixels (width * height) exceeds this limit.
-
-`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF).
-
-#### clone()
-
-Takes a "snapshot" of the instance, returning a new instance.
-Cloned instances inherit the input of their parent instance.
-This allows multiple output Streams
-and therefore multiple processing pipelines
-to share a single input Stream.
-
-### Image transformation options
-
-#### resize(width, [height])
-
-Scale output to `width` x `height`. By default, the resized image is cropped to the exact size specified.
-
-`width` is the integral Number of pixels wide the resultant image should be, between 1 and 16383 (0x3FFF). Use `null` or `undefined` to auto-scale the width to match the height.
-
-`height` is the integral Number of pixels high the resultant image should be, between 1 and 16383. Use `null` or `undefined` to auto-scale the height to match the width.
-
-#### extract(top, left, width, height)
-
-Extract a region of the image. Can be used with or without a `resize` operation.
-
-`top` and `left` are the offset, in pixels, from the top-left corner.
-
-`width` and `height` are the dimensions of the extracted image.
-
-Use `extract` before `resize` for pre-resize extraction. Use `extract` after `resize` for post-resize extraction. Use `extract` before and after for both.
-
-#### crop([gravity])
-
-Crop the resized image to the exact size specified, the default behaviour.
-
-`gravity`, if present, is an attribute of the `sharp.gravity` Object e.g. `sharp.gravity.north`.
-
-Possible values are `north`, `east`, `south`, `west`, `center` and `centre`. The default gravity is `center`/`centre`.
-
-#### max()
-
-Preserving aspect ratio,
-resize the image to be as large as possible
-while ensuring its dimensions are less than or equal to
-the `width` and `height` specified.
-
-Both `width` and `height` must be provided via `resize` otherwise the behaviour will default to `crop`.
-
-#### min()
-
-Preserving aspect ratio,
-resize the image to be as small as possible
-while ensuring its dimensions are greater than or equal to
-the `width` and `height` specified.
-
-Both `width` and `height` must be provided via `resize` otherwise the behaviour will default to `crop`.
-
-#### ignoreAspectRatio()
-
-Ignoring the aspect ratio of the input, stretch the image to the exact `width` and/or `height` provided via `resize`.
-
-#### background(rgba)
-
-Set the background for the `embed` and `flatten` operations.
-
-`rgba` is parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
-
-The alpha value is a float between `0` (transparent) and `1` (opaque).
-
-The default background is `{r: 0, g: 0, b: 0, a: 1}`, black without transparency.
-
-#### embed()
-
-Preserving aspect ratio, resize the image to the maximum `width` or `height` specified then embed on a background of the exact `width` and `height` specified.
-
-If the background contains an alpha value then WebP and PNG format output images will contain an alpha channel, even when the input image does not.
-
-#### flatten()
-
-Merge alpha transparency channel, if any, with `background`.
-
-#### rotate([angle])
-
-Rotate the output image by either an explicit angle or auto-orient based on the EXIF `Orientation` tag.
-
-`angle`, if present, is a Number with a value of `0`, `90`, `180` or `270`.
-
-Use this method without `angle` to determine the angle from EXIF data. Mirroring is supported and may infer the use of a `flip` operation.
-
-Method order is important when both rotating and extracting regions, for example `rotate(x).extract(y)` will produce a different result to `extract(y).rotate(x)`.
-
-The use of `rotate` implies the removal of the EXIF `Orientation` tag, if any.
-
-#### flip()
-
-Flip the image about the vertical Y axis. This always occurs after rotation, if any.
-The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
-
-#### flop()
-
-Flop the image about the horizontal X axis. This always occurs after rotation, if any.
-The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
-
-#### withoutEnlargement()
-
-Do not enlarge the output image if the input image width *or* height are already less than the required dimensions.
-
-This is equivalent to GraphicsMagick's `>` geometry option: "change the dimensions of the image only if its width or height exceeds the geometry specification".
-
-#### blur([sigma])
-
-When used without parameters, performs a fast, mild blur of the output image. This typically reduces performance by 10%.
-
-When a `sigma` is provided, performs a slower, more accurate Gaussian blur. This typically reduces performance by 25%.
-
-* `sigma`, if present, is a Number between 0.3 and 1000 representing the approximate blur radius in pixels.
-
-#### sharpen([radius], [flat], [jagged])
-
-When used without parameters, performs a fast, mild sharpen of the output image. This typically reduces performance by 10%.
-
-When a `radius` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space. Separate control over the level of sharpening in "flat" and "jagged" areas is available. This typically reduces performance by 50%.
-
-* `radius`, if present, is an integral Number representing the sharpen mask radius in pixels.
-* `flat`, if present, is a Number representing the level of sharpening to apply to "flat" areas, defaulting to a value of 1.0.
-* `jagged`, if present, is a Number representing the level of sharpening to apply to "jagged" areas, defaulting to a value of 2.0.
-
-#### interpolateWith(interpolator)
-
-Use the given interpolator for image resizing, where `interpolator` is an attribute of the `sharp.interpolator` Object e.g. `sharp.interpolator.bicubic`.
-
-Possible interpolators, in order of performance, are:
-
-* `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation), suitable for image enlargement only.
-* `bilinear`: Use [bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation), the default and fastest image reduction interpolation.
-* `bicubic`: Use [bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation), which typically reduces performance by 5%.
-* `vertexSplitQuadraticBasisSpline`: Use [VSQBS interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/vsqbs.cpp#L48), which prevents "staircasing" and typically reduces performance by 5%.
-* `locallyBoundedBicubic`: Use [LBB interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/lbb.cpp#L100), which prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" and typically reduces performance by a factor of 2.
-* `nohalo`: Use [Nohalo interpolation](http://eprints.soton.ac.uk/268086/), which prevents acutance and typically reduces performance by a factor of 3.
-
-#### gamma([gamma])
-
-Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma` then increasing the encoding (brighten) post-resize at a factor of `gamma`.
-
-`gamma`, if present, is a Number betweem 1 and 3. The default value is `2.2`, a suitable approximation for sRGB images.
-
-This can improve the perceived brightness of a resized image in non-linear colour spaces.
-
-JPEG input images will not take advantage of the shrink-on-load performance optimisation when applying a gamma correction.
-
-#### grayscale() / greyscale()
-
-Convert to 8-bit greyscale; 256 shades of grey.
-
-This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
-
-The output image will still be web-friendly sRGB and contain three (identical) channels.
-
-#### normalize() / normalise()
-
-Enhance output image contrast by stretching its luminance to cover the full dynamic range. This typically reduces performance by 30%.
-
-#### overlayWith(filename)
-
-_Experimental_
-
-Alpha composite `filename` over the processed (resized, extracted) image. The dimensions of the two images must match.
-
-* `filename` is a String containing the filename of an image with an alpha channel.
-
-### Output options
-
-#### jpeg()
-
-Use JPEG format for the output image.
-
-#### png()
-
-Use PNG format for the output image.
-
-#### webp()
-
-Use WebP format for the output image.
-
-#### raw()
-
-_Requires libvips 7.42.0+_
-
-Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
-
-The number of channels depends on the input image and selected options.
-
-* 1 channel for images converted to `greyscale()`, with each byte representing one pixel.
-* 3 channels for colour images without alpha transparency, with bytes ordered \[red, green, blue, red, green, blue, etc.\]).
-* 4 channels for colour images with alpha transparency, with bytes ordered \[red, green, blue, alpha, red, green, blue, alpha, etc.\].
-
-#### toFormat(format)
-
-Convenience method for the above output format methods, where `format` is either:
-
-* an attribute of the `sharp.format` Object e.g. `sharp.format.jpeg`, or
-* a String containing `jpeg`, `png`, `webp` or `raw`.
-
-#### quality(quality)
-
-The output quality to use for lossy JPEG, WebP and TIFF output formats. The default quality is `80`.
-
-`quality` is a Number between 1 and 100.
-
-#### progressive()
-
-Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed.
-
-#### withMetadata([metadata])
-
-Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
-This will also convert to and add the latest web-friendly v2 sRGB ICC profile.
-
-The optional `metadata` parameter, if present, is an Object with the attributes to update.
-New attributes cannot be inserted, only existing attributes updated.
-
-* `orientation` is an integral Number between 0 and 7, used to update the value of the EXIF `Orientation` tag.
-This has no effect if the input image does not have an EXIF `Orientation` tag.
-
-The default behaviour, when `withMetadata` is not used, is to strip all metadata and convert to the device-independent sRGB colour space.
-
-#### tile([size], [overlap])
-
-The size and overlap, in pixels, of square Deep Zoom image pyramid tiles.
-
-* `size` is an integral Number between 1 and 8192. The default value is 256 pixels.
-* `overlap` is an integral Number between 0 and 8192. The default value is 0 pixels.
-
-#### withoutChromaSubsampling()
-
-Disable the use of [chroma subsampling](http://en.wikipedia.org/wiki/Chroma_subsampling) with JPEG output (4:4:4).
-
-This can improve colour representation at higher quality settings (90+),
-but usually increases output file size and typically reduces performance by 25%.
-
-The default behaviour is to use chroma subsampling (4:2:0).
-
-#### trellisQuantisation() / trellisQuantization()
-
-_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
-
-An advanced setting to apply the use of
-[trellis quantisation](http://en.wikipedia.org/wiki/Trellis_quantization) with JPEG output.
-Reduces file size and slightly increases relative quality at the cost of increased compression time.
-
-#### overshootDeringing()
-
-_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
-
-An advanced setting to reduce the effects of
-[ringing](http://en.wikipedia.org/wiki/Ringing_%28signal%29) in JPEG output,
-in particular where black text appears on a white background (or vice versa).
-
-#### optimiseScans() / optimizeScans()
-
-_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
-
-An advanced setting for progressive (interlace) JPEG output.
-Calculates which spectrum of DCT coefficients uses the fewest bits.
-Usually reduces file size at the cost of increased compression time.
-
-#### compressionLevel(compressionLevel)
-
-An advanced setting for the _zlib_ compression level of the lossless PNG output format. The default level is `6`.
-
-`compressionLevel` is a Number between 0 and 9.
-
-#### withoutAdaptiveFiltering()
-
-_Requires libvips 7.42.0+_
-
-An advanced setting to disable adaptive row filtering for the lossless PNG output format.
-
-### Output methods
-
-#### toFile(filename, [callback])
-
-`filename` is a String containing the filename to write the image data to. The format is inferred from the extension, with JPEG, PNG, WebP, TIFF and DZI supported.
-
-`callback`, if present, is called with two arguments `(err, info)` where:
-
-* `err` contains an error message, if any.
-* `info` contains the output image `format`, `size` (bytes), `width` and `height`.
-
-A Promises/A+ promise is returned when `callback` is not provided.
-
-#### toBuffer([callback])
-
-Write image data to a Buffer, the format of which will match the input image by default. JPEG, PNG and WebP are supported.
-
-`callback`, if present, gets three arguments `(err, buffer, info)` where:
-
-* `err` is an error message, if any.
-* `buffer` is the output image data.
-* `info` contains the output image `format`, `size` (bytes), `width` and `height`.
-
-A Promises/A+ promise is returned when `callback` is not provided.
-
-### Utility methods
-
-#### sharp.cache([memory], [items])
-
-If `memory` or `items` are provided, set the limits of _libvips'_ operation cache.
-
-* `memory` is the maximum memory in MB to use for this cache, with a default value of 100
-* `items` is the maximum number of operations to cache, with a default value of 500
-
-This method always returns cache statistics, useful for determining how much working memory is required for a particular task.
-
-```javascript
-var stats = sharp.cache(); // { current: 75, high: 99, memory: 100, items: 500 }
-sharp.cache(200); // { current: 75, high: 99, memory: 200, items: 500 }
-sharp.cache(50, 200); // { current: 49, high: 99, memory: 50, items: 200}
-```
-
-#### sharp.concurrency([threads])
-
-`threads`, if provided, is the Number of threads _libvips'_ should create for processing each image. The default value is the number of CPU cores. A value of `0` will reset to this default.
-
-This method always returns the current concurrency.
-
-```javascript
-var threads = sharp.concurrency(); // 4
-sharp.concurrency(2); // 2
-sharp.concurrency(0); // 4
-```
-
-The maximum number of images that can be processed in parallel is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
-
-#### sharp.counters()
-
-Provides access to internal task counters.
-
-* `queue` is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
-* `process` is the number of resize tasks currently being processed.
-
-```javascript
-var counters = sharp.counters(); // { queue: 2, process: 4 }
-```
-
-## Contributing
-
-A [guide for contributors](https://github.com/lovell/sharp/blob/master/CONTRIBUTING.md) covers reporting bugs, requesting features and submitting code changes.
-
-## Testing
-
-### Functional tests
-
-Where possible, the functional tests use gradient-based perceptual hashes
-based on [dHash](http://www.hackerfactor.com/blog/index.php?/archives/529-Kind-of-Like-That.html)
-to compare expected vs actual images.
-
-#### Coverage
+The typical use case for this high speed Node.js module
+is to convert large images of many formats to
+smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
[](https://coveralls.io/r/lovell/sharp?branch=master)
-#### Ubuntu 12.04
+### Documentation
-[](https://travis-ci.org/lovell/sharp)
+Visit [sharp.dimens.io](http://sharp.dimens.io/) for
+complete installation instructions, API documentation,
+benchmark tests and a changelog.
-#### Centos 6.5
+### Contributing
-[](https://snap-ci.com/lovell/sharp/branch/master)
+A [guide for contributors](https://github.com/lovell/sharp/blob/master/CONTRIBUTING.md)
+covers reporting bugs, requesting features and submitting code changes.
-#### Windows Server 2012
-
-[](https://ci.appveyor.com/project/lovell/sharp)
-
-#### OS X 10.9.5
-
-[](https://travis-ci.org/lovell/sharp-osx-ci)
-
-### Benchmark tests
-
-```
-cd sharp/test/bench
-npm install
-npm test
-```
-
-Requires both _ImageMagick_ and _GraphicsMagick_:
-
-```
-brew install imagemagick
-brew install graphicsmagick
-```
-
-```
-sudo apt-get install -qq imagemagick graphicsmagick libmagick++-dev
-```
-
-```
-sudo yum install ImageMagick
-sudo yum install -y http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
-sudo yum install -y --enablerepo=epel GraphicsMagick
-```
-
-## Performance
-
-### Test environment
-
-* AWS EC2 [c4.xlarge](http://aws.amazon.com/ec2/instance-types/#c4)
-* Ubuntu 15.04
-* Node.js 0.12.7
-* libvips 8.0.2
-* liborc 0.4.22
-
-### The contenders
-
-* [lwip](https://www.npmjs.com/package/lwip) 0.0.7 - Wrapper around CImg, compiles dependencies from source
-* [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) git@45d4e2e - Supports Buffers only
-* [imagemagick](https://www.npmjs.com/package/imagemagick) 0.1.3 - Supports filesystem only and "has been unmaintained for a long time".
-* [gm](https://www.npmjs.com/package/gm) 1.18.1 - Fully featured wrapper around GraphicsMagick.
-* sharp 0.11.0 - Caching within libvips disabled to ensure a fair comparison.
-
-### The task
-
-Decompress a 2725x2225 JPEG image, resize to 720x480 using bilinear interpolation, then compress to JPEG.
-
-### Results
-
-| Module | Input | Output | Ops/sec | Speed-up |
-| :----------------- | :----- | :----- | ------: | -------: |
-| lwip | file | file | 1.75 | 1 |
-| lwip | buffer | buffer | 2.21 | 1.3 |
-| imagemagick-native | buffer | buffer | 7.13 | 4.1 |
-| gm | buffer | buffer | 7.27 | 4.2 |
-| gm | file | file | 7.33 | 4.2 |
-| imagemagick | file | file | 10.04 | 5.7 |
-| sharp | stream | stream | 23.12 | 13.2 |
-| sharp | file | file | 24.43 | 14.0 |
-| sharp | file | buffer | 24.55 | 14.0 |
-| sharp | buffer | file | 24.86 | 14.2 |
-| sharp | buffer | buffer | 24.92 | 14.2 |
-
-You can expect greater performance with caching enabled (default) and using 8+ core machines.
-
-## Thanks
-
-This module would never have been possible without the help and code contributions of the following people:
-
-* [John Cupitt](https://github.com/jcupitt)
-* [Pierre Inglebert](https://github.com/pierreinglebert)
-* [Jonathan Ong](https://github.com/jonathanong)
-* [Chanon Sajjamanochai](https://github.com/chanon)
-* [Juliano Julio](https://github.com/julianojulio)
-* [Daniel Gasienica](https://github.com/gasi)
-* [Julian Walker](https://github.com/julianwa)
-* [Amit Pitaru](https://github.com/apitaru)
-* [Brandon Aaron](https://github.com/brandonaaron)
-* [Andreas Lind](https://github.com/papandreou)
-* [Maurus Cuelenaere](https://github.com/mcuelenaere)
-* [Linus Unnebäck](https://github.com/LinusU)
-* [Victor Mateevitsi](https://github.com/mvictoras)
-* [Alaric Holloway](https://github.com/skedastik)
-* [Bernhard K. Weisshuhn](https://github.com/bkw)
-
-Thank you!
-
-## Licence
+### Licence
Copyright 2013, 2014, 2015 Lovell Fuller and contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
-You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
+You may obtain a copy of the License at
+[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/docs/api.md b/docs/api.md
new file mode 100644
index 00000000..bfe5770b
--- /dev/null
+++ b/docs/api.md
@@ -0,0 +1,597 @@
+# API
+
+```javascript
+var sharp = require('sharp');
+```
+
+### Input
+
+#### sharp([input])
+
+Constructor to which further methods are chained. `input`, if present, can be one of:
+
+* Buffer containing JPEG, PNG, WebP, GIF* or TIFF image data, or
+* String containing the filename of an image, with most major formats supported.
+
+The object returned implements the
+[stream.Duplex](http://nodejs.org/api/stream.html#stream_class_stream_duplex) class.
+
+JPEG, PNG, WebP, GIF* or TIFF format image data
+can be streamed into the object when `input` is not provided.
+
+JPEG, PNG or WebP format image data can be streamed out from this object.
+
+\* libvips 8.0.0+ is required for Buffer/Stream input of GIF and other `magick` formats.
+
+```javascript
+sharp('input.jpg')
+ .resize(300, 200)
+ .toFile('output.jpg', function(err) {
+ // output.jpg is a 300 pixels wide and 200 pixels high image
+ // containing a scaled and cropped version of input.jpg
+ });
+```
+
+#### metadata([callback])
+
+Fast access to image metadata without decoding any compressed image data.
+
+`callback`, if present, gets the arguments `(err, metadata)` where `metadata` has the attributes:
+
+* `format`: Name of decoder to be used to decompress image data e.g. `jpeg`, `png`, `webp` (for file-based input additionally `tiff`, `magick` and `openslide`)
+* `width`: Number of pixels wide
+* `height`: Number of pixels high
+* `space`: Name of colour space interpretation e.g. `srgb`, `rgb`, `scrgb`, `cmyk`, `lab`, `xyz`, `b-w` [...](https://github.com/jcupitt/libvips/blob/master/libvips/iofuncs/enumtypes.c#L522)
+* `channels`: Number of bands e.g. `3` for sRGB, `4` for CMYK
+* `hasProfile`: Boolean indicating the presence of an embedded ICC profile
+* `hasAlpha`: Boolean indicating the presence of an alpha transparency channel
+* `orientation`: Number value of the EXIF Orientation header, if present
+* `exif`: Buffer containing raw EXIF data, if present
+* `icc`: Buffer containing raw [ICC](https://www.npmjs.com/package/icc) profile data, if present
+
+A Promises/A+ promise is returned when `callback` is not provided.
+
+```javascript
+var image = sharp(inputJpg);
+image
+ .metadata()
+ .then(function(metadata) {
+ return image
+ .resize(Math.round(metadata.width / 2))
+ .webp()
+ .toBuffer();
+ })
+ .then(function(data) {
+ // data contains a WebP image half the width and height of the original JPEG
+ });
+```
+
+#### clone()
+
+Takes a "snapshot" of the instance, returning a new instance.
+Cloned instances inherit the input of their parent instance.
+
+This allows multiple output Streams
+and therefore multiple processing pipelines
+to share a single input Stream.
+
+```javascript
+var pipeline = sharp().rotate();
+pipeline.clone().resize(800, 600).pipe(firstWritableStream);
+pipeline.clone().extract(20, 20, 100, 100).pipe(secondWritableStream);
+readableStream.pipe(pipeline);
+// firstWritableStream receives auto-rotated, resized readableStream
+// secondWritableStream receives auto-rotated, extracted region of readableStream
+```
+
+#### sequentialRead()
+
+An advanced setting that switches the libvips access method to `VIPS_ACCESS_SEQUENTIAL`.
+This will reduce memory usage and can improve performance on some systems.
+
+#### limitInputPixels(pixels)
+
+Do not process input images where the number of pixels (width * height) exceeds this limit.
+
+`pixels` is the integral Number of pixels, with a value between 1 and the default 268402689 (0x3FFF * 0x3FFF).
+
+### Resizing
+
+#### resize([width], [height])
+
+Scale output to `width` x `height`. By default, the resized image is cropped to the exact size specified.
+
+`width` is the integral Number of pixels wide the resultant image should be, between 1 and 16383 (0x3FFF). Use `null` or `undefined` to auto-scale the width to match the height.
+
+`height` is the integral Number of pixels high the resultant image should be, between 1 and 16383. Use `null` or `undefined` to auto-scale the height to match the width.
+
+#### crop([gravity])
+
+Crop the resized image to the exact size specified, the default behaviour.
+
+`gravity`, if present, is an attribute of the `sharp.gravity` Object e.g. `sharp.gravity.north`.
+
+Possible values are `north`, `east`, `south`, `west`, `center` and `centre`. The default gravity is `center`/`centre`.
+
+```javascript
+var transformer = sharp()
+ .resize(300, 200)
+ .crop(sharp.gravity.north)
+ .on('error', function(err) {
+ console.log(err);
+ });
+// Read image data from readableStream, resize and write image data to writableStream
+readableStream.pipe(transformer).pipe(writableStream);
+```
+
+#### embed()
+
+Preserving aspect ratio, resize the image to the
+maximum `width` or `height` specified
+then embed on a background of the exact
+`width` and `height` specified.
+
+If the background contains an alpha value
+then WebP and PNG format output images will
+contain an alpha channel,
+even when the input image does not.
+
+```javascript
+sharp('input.gif')
+ .resize(200, 300)
+ .background({r: 0, g: 0, b: 0, a: 0})
+ .embed()
+ .toFormat(sharp.format.webp)
+ .toBuffer(function(err, outputBuffer) {
+ if (err) {
+ throw err;
+ }
+ // outputBuffer contains WebP image data of a 200 pixels wide and 300 pixels high
+ // containing a scaled version, embedded on a transparent canvas, of input.gif
+ });
+```
+
+#### max()
+
+Preserving aspect ratio,
+resize the image to be as large as possible
+while ensuring its dimensions are less than or equal to
+the `width` and `height` specified.
+
+Both `width` and `height` must be provided via
+`resize` otherwise the behaviour will default to `crop`.
+
+```javascript
+sharp(inputBuffer)
+ .resize(200, 200)
+ .max()
+ .toFormat('jpeg')
+ .toBuffer()
+ .then(function(outputBuffer) {
+ // outputBuffer contains JPEG image data no wider than 200 pixels and no higher
+ // than 200 pixels regardless of the inputBuffer image dimensions
+ });
+```
+
+#### min()
+
+Preserving aspect ratio,
+resize the image to be as small as possible
+while ensuring its dimensions are greater than or equal to
+the `width` and `height` specified.
+
+Both `width` and `height` must be provided via `resize` otherwise the behaviour will default to `crop`.
+
+#### withoutEnlargement()
+
+Do not enlarge the output image
+if the input image width *or* height
+are already less than the required dimensions.
+
+This is equivalent to GraphicsMagick's `>` geometry option:
+"*change the dimensions of the image only
+if its width or height exceeds the geometry specification*".
+
+#### ignoreAspectRatio()
+
+Ignoring the aspect ratio of the input, stretch the image to the exact `width` and/or `height` provided via `resize`.
+
+#### interpolateWith(interpolator)
+
+Use the given interpolator for image resizing, where `interpolator` is an attribute of the `sharp.interpolator` Object e.g. `sharp.interpolator.bicubic`.
+
+Possible interpolators, in order of performance, are:
+
+* `nearest`: Use [nearest neighbour interpolation](http://en.wikipedia.org/wiki/Nearest-neighbor_interpolation), suitable for image enlargement only.
+* `bilinear`: Use [bilinear interpolation](http://en.wikipedia.org/wiki/Bilinear_interpolation), the default and fastest image reduction interpolation.
+* `bicubic`: Use [bicubic interpolation](http://en.wikipedia.org/wiki/Bicubic_interpolation), which typically reduces performance by 5%.
+* `vertexSplitQuadraticBasisSpline`: Use [VSQBS interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/vsqbs.cpp#L48), which prevents "staircasing" and typically reduces performance by 5%.
+* `locallyBoundedBicubic`: Use [LBB interpolation](https://github.com/jcupitt/libvips/blob/master/libvips/resample/lbb.cpp#L100), which prevents some "[acutance](http://en.wikipedia.org/wiki/Acutance)" and typically reduces performance by a factor of 2.
+* `nohalo`: Use [Nohalo interpolation](http://eprints.soton.ac.uk/268086/), which prevents acutance and typically reduces performance by a factor of 3.
+
+```javascript
+sharp(inputBuffer)
+ .resize(200, 300)
+ .interpolateWith(sharp.interpolator.nohalo)
+ .background('white')
+ .embed()
+ .toFile('output.tiff')
+ .then(function() {
+ // output.tiff is a 200 pixels wide and 300 pixels high image
+ // containing a nohalo scaled version, embedded on a white canvas,
+ // of the image data in inputBuffer
+ });
+```
+
+### Operations
+
+#### extract(top, left, width, height)
+
+Extract a region of the image. Can be used with or without a `resize` operation.
+
+`top` and `left` are the offset, in pixels, from the top-left corner.
+
+`width` and `height` are the dimensions of the extracted image.
+
+Use `extract` before `resize` for pre-resize extraction. Use `extract` after `resize` for post-resize extraction. Use `extract` before and after for both.
+
+```javascript
+sharp(input)
+ .extract(top, left, width, height)
+ .toFile(output, function(err) {
+ // Extract a region of the input image, saving in the same format.
+ });
+```
+
+```javascript
+sharp(input)
+ .extract(topOffsetPre, leftOffsetPre, widthPre, heightPre)
+ .resize(width, height)
+ .extract(topOffsetPost, leftOffsetPost, widthPost, heightPost)
+ .toFile(output, function(err) {
+ // Extract a region, resize, then extract from the resized image
+ });
+```
+
+#### background(rgba)
+
+Set the background for the `embed` and `flatten` operations.
+
+`rgba` is parsed by the [color](https://www.npmjs.org/package/color) module to extract values for red, green, blue and alpha.
+
+The alpha value is a float between `0` (transparent) and `1` (opaque).
+
+The default background is `{r: 0, g: 0, b: 0, a: 1}`, black without transparency.
+
+#### flatten()
+
+Merge alpha transparency channel, if any, with `background`.
+
+#### rotate([angle])
+
+Rotate the output image by either an explicit angle or auto-orient based on the EXIF `Orientation` tag.
+
+`angle`, if present, is a Number with a value of `0`, `90`, `180` or `270`.
+
+Use this method without `angle` to determine the angle from EXIF data. Mirroring is supported and may infer the use of a `flip` operation.
+
+Method order is important when both rotating and extracting regions, for example `rotate(x).extract(y)` will produce a different result to `extract(y).rotate(x)`.
+
+The use of `rotate` implies the removal of the EXIF `Orientation` tag, if any.
+
+```javascript
+var pipeline = sharp()
+ .rotate()
+ .resize(null, 200)
+ .progressive()
+ .toBuffer(function(err, outputBuffer, info) {
+ if (err) {
+ throw err;
+ }
+ // outputBuffer contains 200px high progressive JPEG image data,
+ // auto-rotated using EXIF Orientation tag
+ // info.width and info.height contain the dimensions of the resized image
+ });
+readableStream.pipe(pipeline);
+```
+
+#### flip()
+
+Flip the image about the vertical Y axis. This always occurs after rotation, if any.
+The use of `flip` implies the removal of the EXIF `Orientation` tag, if any.
+
+#### flop()
+
+Flop the image about the horizontal X axis. This always occurs after rotation, if any.
+The use of `flop` implies the removal of the EXIF `Orientation` tag, if any.
+
+#### blur([sigma])
+
+When used without parameters, performs a fast, mild blur of the output image. This typically reduces performance by 10%.
+
+When a `sigma` is provided, performs a slower, more accurate Gaussian blur. This typically reduces performance by 25%.
+
+* `sigma`, if present, is a Number between 0.3 and 1000 representing the approximate blur radius in pixels.
+
+#### sharpen([radius], [flat], [jagged])
+
+When used without parameters, performs a fast, mild sharpen of the output image. This typically reduces performance by 10%.
+
+When a `radius` is provided, performs a slower, more accurate sharpen of the L channel in the LAB colour space. Separate control over the level of sharpening in "flat" and "jagged" areas is available. This typically reduces performance by 50%.
+
+* `radius`, if present, is an integral Number representing the sharpen mask radius in pixels.
+* `flat`, if present, is a Number representing the level of sharpening to apply to "flat" areas, defaulting to a value of 1.0.
+* `jagged`, if present, is a Number representing the level of sharpening to apply to "jagged" areas, defaulting to a value of 2.0.
+
+#### gamma([gamma])
+
+Apply a gamma correction by reducing the encoding (darken) pre-resize at a factor of `1/gamma` then increasing the encoding (brighten) post-resize at a factor of `gamma`.
+
+`gamma`, if present, is a Number betweem 1 and 3. The default value is `2.2`, a suitable approximation for sRGB images.
+
+This can improve the perceived brightness of a resized image in non-linear colour spaces.
+
+JPEG input images will not take advantage of the shrink-on-load performance optimisation when applying a gamma correction.
+
+#### grayscale() / greyscale()
+
+Convert to 8-bit greyscale; 256 shades of grey.
+
+This is a linear operation. If the input image is in a non-linear colour space such as sRGB, use `gamma()` with `greyscale()` for the best results.
+
+The output image will still be web-friendly sRGB and contain three (identical) channels.
+
+#### normalize() / normalise()
+
+Enhance output image contrast by stretching its luminance to cover the full dynamic range. This typically reduces performance by 30%.
+
+#### overlayWith(filename)
+
+_Experimental_
+
+Alpha composite `filename` over the processed (resized, extracted) image. The dimensions of the two images must match.
+
+* `filename` is a String containing the filename of an image with an alpha channel.
+
+```javascript
+sharp('input.png')
+ .rotate(180)
+ .resize(300)
+ .flatten()
+ .background('#ff6600')
+ .overlayWith('overlay.png')
+ .sharpen()
+ .withMetadata()
+ .quality(90)
+ .webp()
+ .toBuffer()
+ .then(function(outputBuffer) {
+ // outputBuffer contains upside down, 300px wide, alpha channel flattened
+ // onto orange background, composited with overlay.png, sharpened,
+ // with metadata, 90% quality WebP image data. Phew!
+ });
+```
+
+### Output
+
+#### toFile(filename, [callback])
+
+`filename` is a String containing the filename to write the image data to. The format is inferred from the extension, with JPEG, PNG, WebP, TIFF and DZI supported.
+
+`callback`, if present, is called with two arguments `(err, info)` where:
+
+* `err` contains an error message, if any.
+* `info` contains the output image `format`, `size` (bytes), `width` and `height`.
+
+A Promises/A+ promise is returned when `callback` is not provided.
+
+#### toBuffer([callback])
+
+Write image data to a Buffer, the format of which will match the input image by default. JPEG, PNG and WebP are supported.
+
+`callback`, if present, gets three arguments `(err, buffer, info)` where:
+
+* `err` is an error message, if any.
+* `buffer` is the output image data.
+* `info` contains the output image `format`, `size` (bytes), `width` and `height`.
+
+A Promises/A+ promise is returned when `callback` is not provided.
+
+#### jpeg()
+
+Use JPEG format for the output image.
+
+#### png()
+
+Use PNG format for the output image.
+
+#### webp()
+
+Use WebP format for the output image.
+
+#### raw()
+
+_Requires libvips 7.42.0+_
+
+Provide raw, uncompressed uint8 (unsigned char) image data for Buffer and Stream based output.
+
+The number of channels depends on the input image and selected options.
+
+* 1 channel for images converted to `greyscale()`, with each byte representing one pixel.
+* 3 channels for colour images without alpha transparency, with bytes ordered \[red, green, blue, red, green, blue, etc.\]).
+* 4 channels for colour images with alpha transparency, with bytes ordered \[red, green, blue, alpha, red, green, blue, alpha, etc.\].
+
+#### toFormat(format)
+
+Convenience method for the above output format methods, where `format` is either:
+
+* an attribute of the `sharp.format` Object e.g. `sharp.format.jpeg`, or
+* a String containing `jpeg`, `png`, `webp` or `raw`.
+
+#### quality(quality)
+
+The output quality to use for lossy JPEG, WebP and TIFF output formats. The default quality is `80`.
+
+`quality` is a Number between 1 and 100.
+
+#### progressive()
+
+Use progressive (interlace) scan for JPEG and PNG output. This typically reduces compression performance by 30% but results in an image that can be rendered sooner when decompressed.
+
+#### withMetadata([metadata])
+
+Include all metadata (EXIF, XMP, IPTC) from the input image in the output image.
+This will also convert to and add the latest web-friendly v2 sRGB ICC profile.
+
+The optional `metadata` parameter, if present, is an Object with the attributes to update.
+New attributes cannot be inserted, only existing attributes updated.
+
+* `orientation` is an integral Number between 0 and 7, used to update the value of the EXIF `Orientation` tag.
+This has no effect if the input image does not have an EXIF `Orientation` tag.
+
+The default behaviour, when `withMetadata` is not used, is to strip all metadata and convert to the device-independent sRGB colour space.
+
+#### tile([size], [overlap])
+
+The size and overlap, in pixels, of square Deep Zoom image pyramid tiles.
+
+* `size` is an integral Number between 1 and 8192. The default value is 256 pixels.
+* `overlap` is an integral Number between 0 and 8192. The default value is 0 pixels.
+
+```javascript
+sharp('input.tiff').tile(256).toFile('output.dzi', function(err, info) {
+ // The output.dzi file is the XML format Deep Zoom definition
+ // The output_files directory contains 256x256 pixel tiles grouped by zoom level
+});
+```
+
+#### withoutChromaSubsampling()
+
+Disable the use of [chroma subsampling](http://en.wikipedia.org/wiki/Chroma_subsampling) with JPEG output (4:4:4).
+
+This can improve colour representation at higher quality settings (90+),
+but usually increases output file size and typically reduces performance by 25%.
+
+The default behaviour is to use chroma subsampling (4:2:0).
+
+#### compressionLevel(compressionLevel)
+
+An advanced setting for the _zlib_ compression level of the lossless PNG output format. The default level is `6`.
+
+`compressionLevel` is a Number between 0 and 9.
+
+#### withoutAdaptiveFiltering()
+
+_Requires libvips 7.42.0+_
+
+An advanced setting to disable adaptive row filtering for the lossless PNG output format.
+
+#### trellisQuantisation() / trellisQuantization()
+
+_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
+
+An advanced setting to apply the use of
+[trellis quantisation](http://en.wikipedia.org/wiki/Trellis_quantization) with JPEG output.
+Reduces file size and slightly increases relative quality at the cost of increased compression time.
+
+#### overshootDeringing()
+
+_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
+
+An advanced setting to reduce the effects of
+[ringing](http://en.wikipedia.org/wiki/Ringing_%28signal%29) in JPEG output,
+in particular where black text appears on a white background (or vice versa).
+
+#### optimiseScans() / optimizeScans()
+
+_Requires libvips 8.0.0+ compiled against mozjpeg 3.0+_
+
+An advanced setting for progressive (interlace) JPEG output.
+Calculates which spectrum of DCT coefficients uses the fewest bits.
+Usually reduces file size at the cost of increased compression time.
+
+### Attributes
+
+#### format
+
+An Object containing nested boolean values
+representing the available input and output formats/methods,
+for example:
+
+```javascript
+> console.dir(sharp.format);
+
+{ jpeg: { id: 'jpeg',
+ input: { file: true, buffer: true, stream: true },
+ output: { file: true, buffer: true, stream: true } },
+ png: { id: 'png',
+ input: { file: true, buffer: true, stream: true },
+ output: { file: true, buffer: true, stream: true } },
+ webp: { id: 'webp',
+ input: { file: true, buffer: true, stream: true },
+ output: { file: true, buffer: true, stream: true } },
+ tiff: { id: 'tiff',
+ input: { file: true, buffer: true, stream: true },
+ output: { file: true, buffer: false, stream: false } },
+ magick: { id: 'magick',
+ input: { file: true, buffer: true, stream: true },
+ output: { file: false, buffer: false, stream: false } },
+ raw: { id: 'raw',
+ input: { file: false, buffer: false, stream: false },
+ output: { file: false, buffer: true, stream: true } } }
+```
+
+#### queue
+
+An EventEmitter that emits a `change` event when a task is either:
+
+* queued, waiting for _libuv_ to provide a worker thread
+* complete
+
+```javascript
+sharp.queue.on('change', function(queueLength) {
+ console.log('Queue contains ' + queueLength + ' task(s)');
+});
+```
+
+### Utilities
+
+#### sharp.cache([memory], [items])
+
+If `memory` or `items` are provided, set the limits of _libvips'_ operation cache.
+
+* `memory` is the maximum memory in MB to use for this cache, with a default value of 100
+* `items` is the maximum number of operations to cache, with a default value of 500
+
+This method always returns cache statistics, useful for determining how much working memory is required for a particular task.
+
+```javascript
+var stats = sharp.cache(); // { current: 75, high: 99, memory: 100, items: 500 }
+sharp.cache(200); // { current: 75, high: 99, memory: 200, items: 500 }
+sharp.cache(50, 200); // { current: 49, high: 99, memory: 50, items: 200}
+```
+
+#### sharp.concurrency([threads])
+
+`threads`, if provided, is the Number of threads _libvips'_ should create for processing each image. The default value is the number of CPU cores. A value of `0` will reset to this default.
+
+This method always returns the current concurrency.
+
+```javascript
+var threads = sharp.concurrency(); // 4
+sharp.concurrency(2); // 2
+sharp.concurrency(0); // 4
+```
+
+The maximum number of images that can be processed in parallel is limited by libuv's `UV_THREADPOOL_SIZE` environment variable.
+
+#### sharp.counters()
+
+Provides access to internal task counters.
+
+* `queue` is the number of tasks this module has queued waiting for _libuv_ to provide a worker thread from its pool.
+* `process` is the number of resize tasks currently being processed.
+
+```javascript
+var counters = sharp.counters(); // { queue: 2, process: 4 }
+```
diff --git a/docs/changelog.md b/docs/changelog.md
new file mode 100644
index 00000000..984abcff
--- /dev/null
+++ b/docs/changelog.md
@@ -0,0 +1,63 @@
+# Changelog
+
+### v0.11 - "*knife*"
+
+#### v0.11.0 - 15th July 2015
+
+* Allow alpha transparency compositing via new `overlayWith` method.
+ [#97](https://github.com/lovell/sharp/issues/97)
+ [@gasi](https://github.com/gasi)
+
+* Expose raw ICC profile data as a Buffer when using `metadata`.
+ [#129](https://github.com/lovell/sharp/issues/129)
+ [@homerjam](https://github.com/homerjam)
+
+* Allow image header updates via a parameter passed to existing `withMetadata` method.
+ Provide initial support for EXIF `Orientation` tag,
+ which if present is now removed when using `rotate`, `flip` or `flop`.
+ [#189](https://github.com/lovell/sharp/issues/189)
+ [@h2non](https://github.com/h2non)
+
+* Tighten constructor parameter checks.
+ [#221](https://github.com/lovell/sharp/issues/221)
+ [@mikemorris](https://github.com/mikemorris)
+
+* Allow one input Stream to be shared with two or more output Streams via new `clone` method.
+ [#235](https://github.com/lovell/sharp/issues/235)
+ [@jaubourg](https://github.com/jaubourg)
+
+* Use `round` instead of `floor` when auto-scaling dimensions to avoid floating-point rounding errors.
+ [#238](https://github.com/lovell/sharp/issues/238)
+ [@richardadjogah](https://github.com/richardadjogah)
+
+### v0.10 - "*judgment*"
+
+#### v0.10.1 - 1st June 2015
+
+* Allow embed of image with alpha transparency onto non-transparent background.
+ [#204](https://github.com/lovell/sharp/issues/204)
+ [@mikemliu](https://github.com/mikemliu)
+
+* Include C standard library for `atoi` as Xcode 6.3 appears to no longer do this.
+ [#228](https://github.com/lovell/sharp/issues/228)
+ [@doggan](https://github.com/doggan)
+
+#### v0.10.0 - 23rd April 2015
+
+* Add support for Windows (x86).
+ [#19](https://github.com/lovell/sharp/issues/19)
+ [@DullReferenceException](https://github.com/DullReferenceException)
+ [@itsananderson](https://github.com/itsananderson)
+
+* Add support for Openslide input and DeepZoom output.
+ [#146](https://github.com/lovell/sharp/issues/146)
+ [@mvictoras](https://github.com/mvictoras)
+
+* Allow arbitrary aspect ratios when resizing images via new `ignoreAspectRatio` method.
+ [#192](https://github.com/lovell/sharp/issues/192)
+ [@skedastik](https://github.com/skedastik)
+
+* Enhance output image contrast by stretching its luminance to cover the full dynamic range via new `normalize` method.
+ [#194](https://github.com/lovell/sharp/issues/194)
+ [@bkw](https://github.com/bkw)
+ [@codingforce](https://github.com/codingforce)
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..7b010b08
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,103 @@
+# sharp
+
+The typical use case for this high speed Node.js module
+is to convert large images of many formats to
+smaller, web-friendly JPEG, PNG and WebP images of varying dimensions.
+
+Resizing an image is typically 4x faster than using
+the quickest ImageMagick and GraphicsMagick settings.
+
+[](https://coveralls.io/r/lovell/sharp?branch=master)
+
+### Formats
+
+This module supports reading JPEG, PNG, WebP, TIFF, OpenSlide,
+GIF and other libmagick-supported formats.
+
+Output images can be in JPEG, PNG and WebP formats as well as uncompressed raw pixel data.
+
+Streams, Buffer objects and the filesystem can be used for input and output.
+
+A single input Stream can be split into multiple processing pipelines and output Streams.
+
+Deep Zoom image pyramids can be generated,
+suitable for use with "slippy map" tile viewers like
+[OpenSeadragon](https://github.com/openseadragon/openseadragon)
+and [Leaflet](https://github.com/turban/Leaflet.Zoomify).
+
+### Features
+
+As well as image resizing, operations such as
+rotation, extraction, compositing and gamma correction are available.
+
+Colour spaces, embedded ICC profiles and alpha transparency channels
+are all handled correctly.
+
+### Fast
+
+This module is powered by the blazingly fast
+[libvips](https://github.com/jcupitt/libvips) image processing library,
+originally created in 1989 at Birkbeck College
+and currently maintained by
+[John Cupitt](https://github.com/jcupitt).
+
+Only small regions of uncompressed image data
+are held in memory and processed at a time,
+taking full advantage of multiple CPU cores and L1/L2/L3 cache.
+
+Everything remains non-blocking thanks to _libuv_,
+no child processes are spawned and Promises/A+ are supported.
+
+### Optimal
+
+Huffman tables are optimised when generating JPEG output images
+without having to use separate command line tools like
+[jpegoptim](https://github.com/tjko/jpegoptim) and
+[jpegtran](http://jpegclub.org/jpegtran/).
+
+PNG filtering can be disabled,
+which for diagrams and line art often produces the same result
+as [pngcrush](http://pmt.sourceforge.net/pngcrush/).
+
+### Contributing
+
+A [guide for contributors](https://github.com/lovell/sharp/blob/master/CONTRIBUTING.md)
+covers reporting bugs, requesting features and submitting code changes.
+
+### Credits
+
+This module would never have been possible without
+the help and code contributions of the following people:
+
+* [John Cupitt](https://github.com/jcupitt)
+* [Pierre Inglebert](https://github.com/pierreinglebert)
+* [Jonathan Ong](https://github.com/jonathanong)
+* [Chanon Sajjamanochai](https://github.com/chanon)
+* [Juliano Julio](https://github.com/julianojulio)
+* [Daniel Gasienica](https://github.com/gasi)
+* [Julian Walker](https://github.com/julianwa)
+* [Amit Pitaru](https://github.com/apitaru)
+* [Brandon Aaron](https://github.com/brandonaaron)
+* [Andreas Lind](https://github.com/papandreou)
+* [Maurus Cuelenaere](https://github.com/mcuelenaere)
+* [Linus Unnebäck](https://github.com/LinusU)
+* [Victor Mateevitsi](https://github.com/mvictoras)
+* [Alaric Holloway](https://github.com/skedastik)
+* [Bernhard K. Weisshuhn](https://github.com/bkw)
+
+Thank you!
+
+### Licence
+
+Copyright 2013, 2014, 2015 Lovell Fuller and contributors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/docs/install.md b/docs/install.md
new file mode 100644
index 00000000..d0f5a3e6
--- /dev/null
+++ b/docs/install.md
@@ -0,0 +1,104 @@
+# Installation
+
+```sh
+npm install sharp
+```
+
+### Prerequisites
+
+* Node.js v0.10+ or io.js
+* [libvips](https://github.com/jcupitt/libvips) v7.40.0+ (7.42.0+ recommended)
+* C++11 compatible compiler such as gcc 4.6+, clang 3.0+ or MSVC 2013
+
+### Linux
+
+[](https://travis-ci.org/lovell/sharp)
+[](https://snap-ci.com/lovell/sharp/branch/master)
+
+For a system-wide installation of the most suitable version of
+libvips and its dependencies on the following Operating Systems:
+
+* Debian 7, 8
+* Ubuntu 12.04, 14.04, 14.10, 15.04
+* Mint 13, 17
+* RHEL/Centos/Scientific 6, 7
+* Fedora 21, 22
+* Amazon Linux 2014.09, 2015.03
+* OpenSuse 13
+* Mac OS
+
+run the following as a user with `sudo` access:
+
+```sh
+curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -
+```
+
+or run the following as `root`:
+
+```sh
+curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | bash -
+```
+
+The [preinstall.sh](https://github.com/lovell/sharp/blob/master/preinstall.sh) script requires `curl` and `pkg-config`.
+
+Add `--with-openslide` to enable OpenSlide support:
+
+```sh
+curl -s https://raw.githubusercontent.com/lovell/sharp/master/preinstall.sh | sudo bash -s -- --with-openslide
+```
+
+### Mac OS
+
+[](https://travis-ci.org/lovell/sharp-osx-ci)
+
+Manual install via homebrew:
+
+```sh
+brew install homebrew/science/vips --with-webp --with-graphicsmagick
+```
+
+A missing or incorrectly configured _Xcode Command Line Tools_ installation
+[can lead](https://github.com/lovell/sharp/issues/80) to a
+`library not found for -ljpeg` error.
+If so, please try: `xcode-select --install`.
+
+The _gettext_ dependency of _libvips_
+[can lead](https://github.com/lovell/sharp/issues/9)
+to a `library not found for -lintl` error.
+If so, please try `brew link gettext --force`.
+
+### Windows
+
+[](https://ci.appveyor.com/project/lovell/sharp)
+
+Requires x86 32-bit Node.js or io.js (use `iojs.exe` rather than `node.exe`).
+
+The WebP format is currently unsupported.
+
+1. Ensure the [node-gyp prerequisites](https://github.com/TooTallNate/node-gyp#installation) are met.
+2. [Download](http://www.vips.ecs.soton.ac.uk/supported/current/win32/) and unzip `vips-dev.x.y.z.zip`.
+3. Set the `VIPS_HOME` environment variable to the full path of the `vips-dev-x.y.z` directory.
+4. Add `vips-dev-x.y.z\bin` to `PATH`.
+
+Versions of MSVC more recent than 2013 may require the use of `npm install --arch=ia32 --msvs_version=2013`.
+
+### Heroku
+
+[Alessandro Tagliapietra](https://github.com/alex88) maintains an
+[Heroku buildpack for libvips](https://github.com/alex88/heroku-buildpack-vips)
+and its dependencies.
+
+### Docker
+
+[Marc Bachmann](https://github.com/marcbachmann) maintains a
+[Dockerfile for libvips](https://github.com/marcbachmann/dockerfile-libvips).
+
+```sh
+docker pull marcbachmann/libvips
+```
+
+### Build tools
+
+* [gulp-responsive](https://www.npmjs.com/package/gulp-responsive)
+* [gulp-sharp](https://www.npmjs.com/package/gulp-sharp)
+* [grunt-sharp](https://www.npmjs.com/package/grunt-sharp)
diff --git a/docs/performance.md b/docs/performance.md
new file mode 100644
index 00000000..57dd23fd
--- /dev/null
+++ b/docs/performance.md
@@ -0,0 +1,63 @@
+# Performance
+
+### Test environment
+
+* AWS EC2 [c4.xlarge](http://aws.amazon.com/ec2/instance-types/#c4)
+* Ubuntu 15.04
+* Node.js 0.12.7
+* libvips 8.0.2
+* liborc 0.4.22
+
+### The contenders
+
+* [lwip](https://www.npmjs.com/package/lwip) 0.0.7 - Wrapper around CImg, compiles dependencies from source
+* [imagemagick-native](https://www.npmjs.com/package/imagemagick-native) git@45d4e2e - Wrapper around libmagick++, supports Buffers only.
+* [imagemagick](https://www.npmjs.com/package/imagemagick) 0.1.3 - Supports filesystem only and "*has been unmaintained for a long time*".
+* [gm](https://www.npmjs.com/package/gm) 1.18.1 - Fully featured wrapper around GraphicsMagick's `convert` command line utility.
+* sharp 0.11.0 - Caching within libvips disabled to ensure a fair comparison.
+
+### The task
+
+Decompress a 2725x2225 JPEG image, resize to 720x480 using bilinear interpolation, then compress to JPEG.
+
+### Results
+
+| Module | Input | Output | Ops/sec | Speed-up |
+| :----------------- | :----- | :----- | ------: | -------: |
+| lwip | file | file | 1.75 | 1 |
+| lwip | buffer | buffer | 2.21 | 1.3 |
+| imagemagick-native | buffer | buffer | 7.13 | 4.1 |
+| gm | buffer | buffer | 7.27 | 4.2 |
+| gm | file | file | 7.33 | 4.2 |
+| imagemagick | file | file | 10.04 | 5.7 |
+| sharp | stream | stream | 23.12 | 13.2 |
+| sharp | file | file | 24.43 | 14.0 |
+| sharp | file | buffer | 24.55 | 14.0 |
+| sharp | buffer | file | 24.86 | 14.2 |
+| sharp | buffer | buffer | 24.92 | 14.2 |
+
+Greater performance can be expected with caching enabled (default) and using 8+ core machines.
+
+The I/O limits of the relevant (de)compression library will generally determine maximum throughput.
+
+### Benchmark test prerequisites
+
+Requires both _ImageMagick_ and _GraphicsMagick_:
+
+```sh
+brew install imagemagick
+brew install graphicsmagick
+```
+
+```sh
+sudo apt-get install imagemagick graphicsmagick libmagick++-dev
+```
+
+### Running the benchmark test
+
+```sh
+git clone https://github.com/lovell/sharp.git
+cd sharp/test/bench
+npm install
+npm test
+```
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..89aa1069
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,17 @@
+site_name: sharp
+site_url: http://sharp.dimens.io/
+repo_url: https://github.com/lovell/sharp
+site_description: The fastest Node.js module for resizing JPEG, PNG, WebP and TIFF images. Uses the libvips library.
+copyright: dimens.io
+google_analytics: ['UA-13034748-12', 'sharp.dimens.io']
+theme: flatly
+dev_addr: 0.0.0.0:10101
+markdown_extensions:
+ - toc:
+ permalink: " ♯"
+pages:
+ - Home: index.md
+ - Installation: install.md
+ - API: api.md
+ - Performance: performance.md
+ - Changelog: changelog.md