Skip to content

Commit

Permalink
promisify and lipstickify (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
SamVerschueren authored and sindresorhus committed May 11, 2016
1 parent 8b06376 commit 081c975
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 197 deletions.
3 changes: 0 additions & 3 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,3 @@ insert_final_newline = true
[{package.json,*.yml}]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
sudo: false
language: node_js
node_js:
- 'stable'
- '0.12'
- '0.10'
- '6'
- '4'
56 changes: 31 additions & 25 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,41 @@
#!/usr/bin/env node
'use strict';
var path = require('path');
var meow = require('meow');
var logSymbols = require('log-symbols');
var arrify = require('arrify');
var isProgressive = require('./');

var cli = meow([
'Usage',
' $ is-progressive <file> ...',
' $ is-progressive < <file>',
'',
'Example',
' $ is-progressive baseline.jpg progressive.jpg',
' ✖ baseline.jpg',
' ✔ progressive.jpg'
]);

function init(input) {
var exitCode = 0;

arrify(input).forEach(function (x) {
var p = isProgressive.fileSync(x);
const path = require('path');
const meow = require('meow');
const logSymbols = require('log-symbols');
const arrify = require('arrify');
const isProgressive = require('./');

const cli = meow(`
Usage
$ is-progressive <file> ...
$ is-progressive < <file>
Example
$ is-progressive baseline.jpg progressive.jpg
✖ baseline.jpg
✔ progressive.jpg
`);

const log = (p, x) => {
console.log(p ? logSymbols.success : logSymbols.error, path.relative(process.cwd(), x));
};

const init = input => {
let exitCode = 0;

arrify(input).forEach(x => {
const p = isProgressive.fileSync(x);

if (!p) {
exitCode = 1;
}

console.log(p ? logSymbols.success : logSymbols.error, path.relative(process.cwd(), x));
log(p, x);
});

process.exit(exitCode);
}
};

if (process.stdin.isTTY) {
if (cli.input.length === 0) {
Expand All @@ -41,5 +45,7 @@ if (process.stdin.isTTY) {

init(cli.input);
} else {
process.stdin.pipe(isProgressive.stream(init));
isProgressive.stream(process.stdin).then(p => {
log(p, 'stdin');
});
}
97 changes: 37 additions & 60 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,97 +1,74 @@
'use strict';
var fs = require('fs');
var readChunk = require('read-chunk');
var through = require('through2');
const fs = require('fs');
const readChunk = require('read-chunk');

// http://en.wikipedia.org/wiki/JPEG
// SOF2 [0xFF, 0xC2] = Start Of Frame (Progressive DCT)
var SOF2 = 0xc2;
const SOF2 = 0xc2;

function search(buf) {
var currByte;
var prevByte;

for (var i = 0; i < buf.length; i++) {
currByte = buf[i];
prevByte = buf[i - 1];
const search = buf => {
let prevByte;

for (const currByte of buf) {
if (prevByte !== 0xff) {
prevByte = currByte;
continue;
}

if (currByte === SOF2) {
return true;
}

prevByte = currByte;
}

return false;
}

exports.buffer = function (buf) {
return search(buf);
};

exports.stream = function (cb) {
var prevLastByte = new Buffer(1);
var searchDone = false;
exports.buffer = search;

return through(function (data, enc, cb2) {
if (searchDone) {
cb(null, data);
return;
}

prevLastByte = new Buffer(data[data.length - 1]);
exports.stream = stream => new Promise((resolve, reject) => {
let prevLastByte = new Buffer(1);

var res = exports.buffer(Buffer.concat([prevLastByte, data]), true);
const end = () => {
resolve(false);
};

if (res === true) {
searchDone = true;
cb(true);
}
stream.on('data', data => {
prevLastByte = new Buffer(data[data.length - 1]);

cb2(null, data);
}, function (cb2) {
if (!searchDone) {
cb(false);
if (search(Buffer.concat([prevLastByte, data]))) {
resolve(true);
stream.removeListener('end', end);
}

cb2();
});
};

exports.file = function (filepath, cb) {
// the metadata section has a maximum size of 65535 bytes
readChunk(filepath, 0, 65535, function (err, buf) {
if (err) {
cb(err);
return;
}
stream.on('error', reject);

cb(null, exports.buffer(buf));
});
};
stream.on('end', end);
});

// the metadata section has a maximum size of 65535 bytes
exports.file = filepath => readChunk(filepath, 0, 65535).then(search);

exports.fileSync = function (filepath) {
exports.fileSync = filepath => {
// we read one byte at the time here as it usually appears
// early in the file and reading 65535 would be wasteful
var currByte;
var prevByte;
var BUF_LENGTH = 1;
var buf = new Buffer(BUF_LENGTH);
var bytesRead = BUF_LENGTH;
var read = fs.openSync(filepath, 'r');
var isProgressive = false;
const BUF_LENGTH = 1;
const buf = new Buffer(BUF_LENGTH);
const read = fs.openSync(filepath, 'r');
let bytesRead = BUF_LENGTH;
let currByte;
let prevByte;
let isProgressive = false;

while (bytesRead === BUF_LENGTH) {
bytesRead = fs.readSync(read, buf, 0, 1);
currByte = buf[0];

if (prevByte === 0xff) {
if (currByte === SOF2) {
isProgressive = true;
break;
}
if (prevByte === 0xff && currByte === SOF2) {
isProgressive = true;
break;
}

prevByte = currByte;
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"bin": "cli.js",
"engines": {
"node": ">=0.10.0"
"node": ">=4"
},
"scripts": {
"test": "xo && ava"
Expand Down Expand Up @@ -44,11 +44,13 @@
"arrify": "^1.0.0",
"log-symbols": "^1.0.1",
"meow": "^3.6.0",
"read-chunk": "^1.0.0",
"through2": "^2.0.0"
"read-chunk": "^2.0.0"
},
"devDependencies": {
"ava": "*",
"xo": "*"
},
"xo": {
"esnext": true
}
}
Loading

0 comments on commit 081c975

Please sign in to comment.