Skip to content

Commit

Permalink
Windows compatibility #19
Browse files Browse the repository at this point in the history
Hide WebP format and normalise option

Separate test runners for node and iojs
  • Loading branch information
lovell committed Apr 21, 2015
1 parent 8926ebc commit 1e52c2d
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 206 deletions.
13 changes: 10 additions & 3 deletions README.md
Expand Up @@ -88,9 +88,12 @@ The _gettext_ dependency of _libvips_ [can lead](https://github.com/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. [Download](http://www.vips.ecs.soton.ac.uk/supported/current/win32/) and unzip `vips-dev.x.y.z.zip`.
2. Set the `VIPS_HOME` environment variable to the full path of the `vips-dev-x.y.z` directory.
3. Add `vips-dev-x.y.z\bin` to `PATH`.
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

Expand Down Expand Up @@ -678,6 +681,10 @@ A [guide for contributors](https://github.com/lovell/sharp/blob/master/CONTRIBUT

[![Centos 6.5 Build Status](https://snap-ci.com/lovell/sharp/branch/master/build_image)](https://snap-ci.com/lovell/sharp/branch/master)

#### Windows Server 2012

[![Windows Server 2012 Build Status](https://ci.appveyor.com/api/projects/status/pgtul704nkhhg6sg)](https://ci.appveyor.com/project/lovell/sharp)

### Benchmark tests

```
Expand Down
6 changes: 3 additions & 3 deletions appveyor.yml
@@ -1,17 +1,17 @@
os: Visual Studio 2014 CTP4
platform: x86
environment:
VIPS_VERSION_MAJOR_MINOR: 7.42
VIPS_VERSION_PATCH: 3
VIPS_WARNING: 0
install:
- ps: $env:VIPS_VERSION = "$env:VIPS_VERSION_MAJOR_MINOR.$env:VIPS_VERSION_PATCH"
- ps: Write-Output "VIPS_VERSION=$env:VIPS_VERSION"
- ps: Write-Output "Fetching http://www.vips.ecs.soton.ac.uk/supported/$env:VIPS_VERSION_MAJOR_MINOR/win32/vips-dev-$env:VIPS_VERSION.zip"
- ps: Start-FileDownload http://www.vips.ecs.soton.ac.uk/supported/$env:VIPS_VERSION_MAJOR_MINOR/win32/vips-dev-$env:VIPS_VERSION.zip -FileName c:\vips-dev-$env:VIPS_VERSION.zip
- ps: Write-Output "Extracting c:\vips-dev-$env:VIPS_VERSION.zip"
- ps: Invoke-Expression "& 7z -y x c:\vips-dev-$env:VIPS_VERSION.zip -oc:\ | FIND /V `"ing `""
- ps: $env:VIPS_HOME = "c:\vips-dev-$env:VIPS_VERSION"
- ps: $env:PATH = "$env:VIPS_HOME\bin;$env:PATH"
- ps: Install-Product node 0 x86
- npm install --msvs_version=2013
test_script:
- npm test
- npm run-script test-win32-node
8 changes: 6 additions & 2 deletions index.js
Expand Up @@ -349,10 +349,14 @@ Sharp.prototype.gamma = function(gamma) {
};

/*
Normalize histogram
Enhance output image contrast by stretching its luminance to cover the full dynamic range
*/
Sharp.prototype.normalize = function(normalize) {
this.options.normalize = (typeof normalize === 'boolean') ? normalize : true;
if (process.platform !== 'win32') {
this.options.normalize = (typeof normalize === 'boolean') ? normalize : true;
} else {
console.error('normalize unavailable on win32 platform');
}
return this;
};
Sharp.prototype.normalise = Sharp.prototype.normalize;
Expand Down
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -20,7 +20,9 @@
],
"description": "High performance Node.js module to resize JPEG, PNG, WebP and TIFF images using the libvips library",
"scripts": {
"test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=10000 ./test/unit/*.js"
"test": "VIPS_WARNING=0 node ./node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha -- --slow=5000 --timeout=15000 ./test/unit/*.js",
"test-win32-node": "node ./node_modules/mocha/bin/mocha --slow=5000 --timeout=15000 ./test/unit/*.js",
"test-win32-iojs": "iojs ./node_modules/mocha/bin/mocha --slow=5000 --timeout=15000 ./test/unit/*.js"
},
"main": "index.js",
"repository": {
Expand Down
2 changes: 2 additions & 0 deletions src/resize.cc
Expand Up @@ -708,6 +708,7 @@ class ResizeWorker : public NanAsyncWorker {
image = gammaDecoded;
}

#ifndef _WIN32
// Apply normalization
if (baton->normalize) {
VipsInterpretation typeBeforeNormalize = image->Type;
Expand Down Expand Up @@ -787,6 +788,7 @@ class ResizeWorker : public NanAsyncWorker {
image = normalized;
}
}
#endif

// Convert image to sRGB, if not already
if (image->Type != VIPS_INTERPRETATION_sRGB) {
Expand Down
4 changes: 4 additions & 0 deletions src/sharp.cc
Expand Up @@ -8,6 +8,10 @@
#include "resize.h"
#include "utilities.h"

#ifdef _WIN64
#error Windows 64-bit currently unsupported - see https://github.com/lovell/sharp#windows
#endif

extern "C" void init(v8::Handle<v8::Object> target) {
NanScope();
vips_init("sharp");
Expand Down
22 changes: 12 additions & 10 deletions test/unit/colourspace.js
Expand Up @@ -31,16 +31,18 @@ describe('Colour space conversion', function() {
.toFile(fixtures.path('output.greyscale-not.jpg'), done);
});

it('From 1-bit TIFF to sRGB WebP [slow]', function(done) {
sharp(fixtures.inputTiff)
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
done();
});
});
if (sharp.format.webp.output.buffer) {
it('From 1-bit TIFF to sRGB WebP [slow]', function(done) {
sharp(fixtures.inputTiff)
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
done();
});
});
}

it('From CMYK to sRGB', function(done) {
sharp(fixtures.inputJpgWithCmykProfile)
Expand Down
65 changes: 34 additions & 31 deletions test/unit/cpplint.js
Expand Up @@ -8,39 +8,42 @@ var cpplint = require('node-cpplint/lib/');

describe('cpplint', function() {

// List C++ source files
fs.readdirSync(path.join(__dirname, '..', '..', 'src')).forEach(function (source) {
var file = path.join('src', source);
it(file, function(done) {
// Lint each source file
cpplint({
files: [file],
linelength: 140,
filters: {
legal: {
copyright: false
},
build: {
include: false,
include_order: false
},
whitespace: {
blank_line: false,
comments: false,
parens: false
// Ignore cpplint failures, possibly newline-related, on Windows
if (process.platform !== 'win32') {
// List C++ source files
fs.readdirSync(path.join(__dirname, '..', '..', 'src')).forEach(function (source) {
var file = path.join('src', source);
it(file, function(done) {
// Lint each source file
cpplint({
files: [file],
linelength: 140,
filters: {
legal: {
copyright: false
},
build: {
include: false,
include_order: false
},
whitespace: {
blank_line: false,
comments: false,
parens: false
}
}
}
}, function(err, report) {
if (err) {
throw err;
}
var expected = {};
expected[file] = [];
assert.deepEqual(expected, report);
done();
}, function(err, report) {
if (err) {
throw err;
}
var expected = {};
expected[file] = [];
assert.deepEqual(expected, report);
done();
});
});
});

});
});
}

});
36 changes: 19 additions & 17 deletions test/unit/embed.js
Expand Up @@ -28,24 +28,26 @@ describe('Embed', function() {
});
});

it('JPEG within WebP, to include alpha channel', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.background({r: 0, g: 0, b: 0, a: 0})
.embed()
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
sharp(data).metadata(function(err, metadata) {
if (sharp.format.webp.output.buffer) {
it('JPEG within WebP, to include alpha channel', function(done) {
sharp(fixtures.inputJpg)
.resize(320, 240)
.background({r: 0, g: 0, b: 0, a: 0})
.embed()
.webp()
.toBuffer(function(err, data, info) {
if (err) throw err;
assert.strictEqual(4, metadata.channels);
done();
assert.strictEqual(true, data.length > 0);
assert.strictEqual('webp', info.format);
assert.strictEqual(320, info.width);
assert.strictEqual(240, info.height);
sharp(data).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual(4, metadata.channels);
done();
});
});
});
});
});
}

});
22 changes: 12 additions & 10 deletions test/unit/extract.js
Expand Up @@ -31,16 +31,18 @@ describe('Partial image extraction', function() {
});
});

it('WebP', function(done) {
sharp(fixtures.inputWebP)
.extract(50, 100, 125, 200)
.toFile(fixtures.path('output.extract.webp'), function(err, info) {
if (err) throw err;
assert.strictEqual(125, info.width);
assert.strictEqual(200, info.height);
done();
});
});
if (sharp.format.webp.output.file) {
it('WebP', function(done) {
sharp(fixtures.inputWebP)
.extract(50, 100, 125, 200)
.toFile(fixtures.path('output.extract.webp'), function(err, info) {
if (err) throw err;
assert.strictEqual(125, info.width);
assert.strictEqual(200, info.height);
done();
});
});
}

it('TIFF', function(done) {
sharp(fixtures.inputTiff)
Expand Down
6 changes: 4 additions & 2 deletions test/unit/io.js
Expand Up @@ -806,8 +806,10 @@ describe('Input/output', function() {
.toBuffer(function(err) {
sharp.queue.removeListener('change', queueListener);
if (err) throw err;
assert.strictEqual(2, eventCounter);
done();
process.nextTick(function() {
assert.strictEqual(2, eventCounter);
done();
});
});
});

Expand Down
26 changes: 14 additions & 12 deletions test/unit/metadata.js
Expand Up @@ -82,19 +82,21 @@ describe('Image metadata', function() {
});
});

it('WebP', function(done) {
sharp(fixtures.inputWebP).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('webp', metadata.format);
assert.strictEqual(1024, metadata.width);
assert.strictEqual(772, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha);
done();
if (sharp.format.webp.input.file) {
it('WebP', function(done) {
sharp(fixtures.inputWebP).metadata(function(err, metadata) {
if (err) throw err;
assert.strictEqual('webp', metadata.format);
assert.strictEqual(1024, metadata.width);
assert.strictEqual(772, metadata.height);
assert.strictEqual('srgb', metadata.space);
assert.strictEqual(3, metadata.channels);
assert.strictEqual(false, metadata.hasProfile);
assert.strictEqual(false, metadata.hasAlpha);
done();
});
});
});
}

it('GIF via libmagick', function(done) {
sharp(fixtures.inputGif).metadata(function(err, metadata) {
Expand Down

0 comments on commit 1e52c2d

Please sign in to comment.