├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── bench
└── bench.js
├── bin
└── tiletype.js
├── index.d.ts
├── index.js
├── package.json
├── readme.md
└── test
├── fixtures
├── 0.gif
├── 0.jpeg
├── 0.png
├── 0.vector.pbf
├── 0.vector.pbfz
├── 0.webp
├── gif-990x1050.gif
├── jpg-640x400.jpg
├── png-640x400.png
├── tux.webp
├── tux_alpha.webp
├── unknown.txt
└── webp-550x368.webp
├── test.js
└── types.ts
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint-config-unstyled"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | sudo: false
4 |
5 | node_js:
6 | - "0.10"
7 | - "4"
8 | - "6"
9 |
10 | after_success:
11 | - if [[ ${TRAVIS_NODE_VERSION} == "0.10" ]]; then npm run coverage; fi
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) MapBox
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | - Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 | - Redistributions in binary form must reproduce the above copyright notice, this
10 | list of conditions and the following disclaimer in the documentation and/or
11 | other materials provided with the distribution.
12 | - Neither the name "MapBox" nor the names of its contributors may be
13 | used to endorse or promote products derived from this software without
14 | specific prior written permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 |
--------------------------------------------------------------------------------
/bench/bench.js:
--------------------------------------------------------------------------------
1 | var Benchmark = require('benchmark');
2 | var suite = new Benchmark.Suite();
3 | var assert = require('assert');
4 | var tiletype = require('..');
5 | var fs = require('fs');
6 | var data = fs.readFileSync(__dirname + '/../test/fixtures/0.vector.pbf');
7 |
8 | suite.add('tiletype.type', function() {
9 | assert.equal('pbf', tiletype.type(data));
10 | })
11 | .on('cycle', function(event) {
12 | console.log(String(event.target));
13 | })
14 | .run();
15 |
--------------------------------------------------------------------------------
/bin/tiletype.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var path = require('path');
4 | var fs = require('fs');
5 | var tiletype = require('..').type;
6 |
7 | var args = process.argv.slice(2);
8 | var filepath = args.shift();
9 | filepath = filepath ? path.resolve(filepath) : '';
10 |
11 | fs.readFile(filepath, function(err, buf) {
12 | if (err) {
13 | console.error(err.toString());
14 | process.exit(1);
15 | }
16 | if (!tiletype(buf)) {
17 | console.error('Could not determine tile type');
18 | process.exit(3);
19 | }
20 | console.log(tiletype(buf));
21 | });
22 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | export interface Header {
4 | 'Content-Type'?: string
5 | 'Content-Encoding'?: string
6 | }
7 |
8 | export type extensions = 'png' | 'pbf' | 'jpg' | 'webp'
9 |
10 | /**
11 | * Given a buffer of unknown data, return either a format as an extension
12 | * string or false if the type cannot be determined.
13 | *
14 | * Potential options are:
15 | *
16 | * * png
17 | * * pbf
18 | * * jpg
19 | * * webp
20 | *
21 | * @param {Buffer} buffer input
22 | * @returns {String|boolean} identifier
23 | */
24 | export function type(buffer: Buffer): extensions | boolean
25 |
26 | /**
27 | * Return headers - Content-Type and Content-Encoding -
28 | * for a response containing this kind of image.
29 | *
30 | * @param {Buffer} buffer input
31 | * @returns {Object} headers
32 | */
33 | export function headers(buffer: Buffer): Header
34 |
35 | /**
36 | * Determine the width and height of an image contained in a buffer,
37 | * returned as a [x, y] array.
38 | *
39 | * @param {Buffer} buffer input
40 | * @returns {Array|boolean} dimensions
41 | */
42 | export function dimensions(buffer: Buffer): [number, number] | boolean
43 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = {};
2 | module.exports.type = type;
3 | module.exports.headers = headers;
4 | module.exports.dimensions = dimensions;
5 |
6 | /**
7 | * Given a buffer of unknown data, return either a format as an extension
8 | * string or false if the type cannot be determined.
9 | *
10 | * Potential options are:
11 | *
12 | * * png
13 | * * pbf
14 | * * jpg
15 | * * webp
16 | *
17 | * @param {Buffer} buffer input
18 | * @returns {String|boolean} identifier
19 | */
20 | function type(buffer) {
21 | if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E &&
22 | buffer[3] === 0x47 && buffer[4] === 0x0D && buffer[5] === 0x0A &&
23 | buffer[6] === 0x1A && buffer[7] === 0x0A) {
24 | return 'png';
25 | } else if (buffer[0] === 0xFF && buffer[1] === 0xD8 &&
26 | buffer[buffer.length - 2] === 0xFF && buffer[buffer.length - 1] === 0xD9) {
27 | return 'jpg';
28 | } else if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46 &&
29 | buffer[3] === 0x38 && (buffer[4] === 0x39 || buffer[4] === 0x37) &&
30 | buffer[5] === 0x61) {
31 | return 'gif';
32 | } else if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46 &&
33 | buffer[8] === 0x57 && buffer[9] === 0x45 && buffer[10] === 0x42 && buffer[11] === 0x50) {
34 | return 'webp';
35 | // deflate: recklessly assumes contents are PBF.
36 | } else if (buffer[0] === 0x78 && buffer[1] === 0x9C) {
37 | return 'pbf';
38 | // gzip: recklessly assumes contents are PBF.
39 | } else if (buffer[0] === 0x1F && buffer[1] === 0x8B) {
40 | return 'pbf';
41 | }
42 | return false;
43 | }
44 |
45 | /**
46 | * Return headers - Content-Type and Content-Encoding -
47 | * for a response containing this kind of image.
48 | *
49 | * @param {Buffer} buffer input
50 | * @returns {Object} headers
51 | */
52 | function headers(buffer) {
53 | var head = {};
54 | if (buffer[0] === 0x89 && buffer[1] === 0x50 && buffer[2] === 0x4E &&
55 | buffer[3] === 0x47 && buffer[4] === 0x0D && buffer[5] === 0x0A &&
56 | buffer[6] === 0x1A && buffer[7] === 0x0A) {
57 | head['Content-Type'] = 'image/png';
58 | } else if (buffer[0] === 0xFF && buffer[1] === 0xD8 &&
59 | buffer[buffer.length - 2] === 0xFF && buffer[buffer.length - 1] === 0xD9) {
60 | head['Content-Type'] = 'image/jpeg';
61 | } else if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46 &&
62 | buffer[3] === 0x38 && (buffer[4] === 0x39 || buffer[4] === 0x37) &&
63 | buffer[5] === 0x61) {
64 | head['Content-Type'] = 'image/gif';
65 | } else if (buffer[0] === 0x52 && buffer[1] === 0x49 && buffer[2] === 0x46 && buffer[3] === 0x46 &&
66 | buffer[8] === 0x57 && buffer[9] === 0x45 && buffer[10] === 0x42 && buffer[11] === 0x50) {
67 | head['Content-Type'] = 'image/webp';
68 | // deflate: recklessly assumes contents are PBF.
69 | } else if (buffer[0] === 0x78 && buffer[1] === 0x9C) {
70 | head['Content-Type'] = 'application/x-protobuf';
71 | head['Content-Encoding'] = 'deflate';
72 | // gzip: recklessly assumes contents are PBF.
73 | } else if (buffer[0] === 0x1F && buffer[1] === 0x8B) {
74 | head['Content-Type'] = 'application/x-protobuf';
75 | head['Content-Encoding'] = 'gzip';
76 | }
77 | return head;
78 | }
79 |
80 | /**
81 | * Determine the width and height of an image contained in a buffer,
82 | * returned as a [x, y] array.
83 | *
84 | * @param {Buffer} buffer input
85 | * @returns {Array|boolean} dimensions
86 | */
87 | function dimensions(buffer) {
88 | var mp28 = Math.pow(2,8);
89 | switch (type(buffer)) {
90 | case 'png':
91 | var i = 8;
92 | while (i < buffer.length) {
93 | var length = buffer.readUInt32BE(i);
94 | var chunktype = buffer.toString('ascii', i + 4, i + 8);
95 | // Invalid chunk.
96 | if (!(length || chunktype === 'IEND')) return false;
97 | // Length + type.
98 | i += 8;
99 | if (chunktype === 'IHDR') {
100 | var w = (buffer[i+0]*Math.pow(2,32)) + (buffer[i+1]*Math.pow(2,16)) + (buffer[i+2]*Math.pow(2,8)) + buffer[i+3];
101 | var h = (buffer[i+4]*Math.pow(2,32)) + (buffer[i+5]*Math.pow(2,16)) + (buffer[i+6]*Math.pow(2,8)) + buffer[i+7];
102 | return [w,h];
103 | }
104 | // Skip CRC.
105 | i += length + 4;
106 | }
107 | break;
108 | case 'jpg':
109 | var i = 2;
110 | while (i < buffer.length) {
111 | // Invalid chunk.
112 | if (buffer[i] !== 0xff) return false;
113 | var chunktype = buffer[i+1];
114 | var length = (buffer[i+2]*mp28) + (buffer[i+3]);
115 | // Entropy-encoded begins after this chunk. Bail.
116 | if (chunktype === 0xda) {
117 | return false;
118 | } else if (chunktype === 0xc0) {
119 | var h = (buffer[i+5]*Math.pow(2,8)) + buffer[i+6];
120 | var w = (buffer[i+7]*Math.pow(2,8)) + buffer[i+8];
121 | return [w,h];
122 | }
123 | i += 2 + length;
124 | }
125 | break;
126 | case 'gif':
127 | var w = (buffer[7]*Math.pow(2,8)) + buffer[6];
128 | var h = (buffer[9]*Math.pow(2,8)) + buffer[8];
129 | return [w,h];
130 | break;
131 | case 'webp':
132 | var chunktype = buffer.toString('ascii', 12, 16);
133 | if (chunktype === 'VP8 ') {
134 | // Invalid chunk.
135 | if (buffer[23] !== 0x9d || buffer[24] !== 0x01 || buffer[25] !== 0x2a) return false;
136 | var w = buffer[26] | (buffer[27] << 8);
137 | var h = buffer[28] | (buffer[29] << 8);
138 | return [w,h];
139 | }
140 | else if (chunktype === 'VP8L') {
141 | var w = 1 + (buffer[21] | (buffer[22] & 0x3F) << 8);
142 | var h = 1 + (((buffer[22] & 0xC0) >> 6) | (buffer[23] << 2) | ((buffer[24] & 0xF) << 10));
143 | return [w,h];
144 | }
145 | else if (chunktype === 'VP8X') {
146 | var w = 1 + (buffer[24] | buffer[25] << 8 | buffer[26] << 16);
147 | var h = 1 + (buffer[27] | buffer[28] << 8 | buffer[29] << 16);
148 |
149 | return [w,h];
150 | }
151 | return false;
152 | break;
153 | }
154 | return false;
155 | }
156 |
157 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@mapbox/tiletype",
3 | "description": "detect common map tile formats from a buffer",
4 | "version": "0.3.1",
5 | "url": "http://github.com/mapbox/tiletype",
6 | "author": {
7 | "name": "Mapbox",
8 | "url": "https://www.mapbox.com/",
9 | "email": "info@mapbox.com"
10 | },
11 | "licenses": [
12 | {
13 | "type": "BSD"
14 | }
15 | ],
16 | "devDependencies": {
17 | "benchmark": "1.0.x",
18 | "dox": "^0.7.0",
19 | "doxme": "^1.8.2",
20 | "istanbul": "~0.3.17",
21 | "coveralls": "~2.11.2",
22 | "tape": "2.13.x",
23 | "eslint": "~1.00.0",
24 | "eslint-config-unstyled": "^1.1.0",
25 | "@types/node": "^6.0.52",
26 | "typescript": "^2.1.4"
27 | },
28 | "main": "./index.js",
29 | "scripts": {
30 | "test": "eslint index.js && node test/test.js",
31 | "doc": "dox -r < index.js | doxme --readme > README.md",
32 | "coverage": "istanbul cover tape test/*test.js && coveralls < ./coverage/lcov.info",
33 | "types": "tsc test/types.ts"
34 | },
35 | "bin": {
36 | "tiletype": "bin/tiletype.js"
37 | },
38 | "types": "index.d.ts",
39 | "repository": {
40 | "type": "git",
41 | "url": "git@github.com:mapbox/tiletype.git"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # tiletype
2 |
3 | [](http://travis-ci.com/mapbox/tiletype)
4 | [](https://coveralls.io/github/mapbox/tiletype?branch=coverage)
5 |
6 | detect common map tile formats from a buffer
7 |
8 |
9 | ### `type(buffer)`
10 |
11 | Given a buffer of unknown data, return either a format as an extension
12 | string or false if the type cannot be determined.
13 |
14 | Potential options are:
15 |
16 | * png
17 | * pbf
18 | * jpg
19 | * webp
20 |
21 |
22 | ### Parameters
23 |
24 | | parameter | type | description |
25 | | --------- | ------ | ----------- |
26 | | `buffer` | Buffer | input |
27 |
28 |
29 |
30 | **Returns** `String,boolean`, identifier
31 |
32 |
33 | ### `headers(buffer)`
34 |
35 | Return headers - Content-Type and Content-Encoding -
36 | for a response containing this kind of image.
37 |
38 |
39 | ### Parameters
40 |
41 | | parameter | type | description |
42 | | --------- | ------ | ----------- |
43 | | `buffer` | Buffer | input |
44 |
45 |
46 |
47 | **Returns** `Object`, headers
48 |
49 |
50 | ### `dimensions(buffer, dimensions)`
51 |
52 | Determine the width and height of an image contained in a buffer,
53 | returned as a [x, y] array.
54 |
55 |
56 | ### Parameters
57 |
58 | | parameter | type | description |
59 | | ------------ | -------------- | ----------- |
60 | | `buffer` | Buffer | input |
61 | | `dimensions` | Array\,boolean | |
62 |
63 |
64 | ## Installation
65 |
66 | Requires [nodejs](http://nodejs.org/).
67 |
68 | ```sh
69 | $ npm install @mapbox/tiletype
70 | ```
71 |
72 | ## Tests
73 |
74 | ```sh
75 | $ npm test
76 | ```
77 |
78 |
79 |
--------------------------------------------------------------------------------
/test/fixtures/0.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.gif
--------------------------------------------------------------------------------
/test/fixtures/0.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.jpeg
--------------------------------------------------------------------------------
/test/fixtures/0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.png
--------------------------------------------------------------------------------
/test/fixtures/0.vector.pbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.vector.pbf
--------------------------------------------------------------------------------
/test/fixtures/0.vector.pbfz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.vector.pbfz
--------------------------------------------------------------------------------
/test/fixtures/0.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/0.webp
--------------------------------------------------------------------------------
/test/fixtures/gif-990x1050.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/gif-990x1050.gif
--------------------------------------------------------------------------------
/test/fixtures/jpg-640x400.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/jpg-640x400.jpg
--------------------------------------------------------------------------------
/test/fixtures/png-640x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/png-640x400.png
--------------------------------------------------------------------------------
/test/fixtures/tux.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/tux.webp
--------------------------------------------------------------------------------
/test/fixtures/tux_alpha.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/tux_alpha.webp
--------------------------------------------------------------------------------
/test/fixtures/unknown.txt:
--------------------------------------------------------------------------------
1 | qTXN2gcIkBTRNRaObUf4BMxkaN99daF1VhvJUftOEnoelzfIiWmhY/3n3Y5XkoJk
2 | L8PITDzvCEVsiz+nyqRV0OIfd4zjyvGQCrzMR7RUfoKmt7+y6VZ/ZGE7+w4tll2U
3 | FnUwwtMv+jGENJDNS35Pbk5seozZM0zQor8byRHUa4+jFKk1bonpcJsyqxiR8sgn
4 | LSNZaEXa3zmu2BNsN/458/RiiXNA/dCLdR4YSdV1Ev9O8tvYib0AZAKrA/kXxIRO
5 | lf8Gg2QCJizQ6cOQ1Iug/HpC0IdA/IRWU/GfbB1a+iOeUzlV9mkyataWmjS35mzM
6 | g7zqZGTLansLBEoamVdjT5KFxzxPnM0qNd4KNbiJp076fjKyzsYDV6QLlsJu+R2l
7 | Ss00hIm+LUB8wxG3eXFV1c5J9ZsnyZ8VKa9ZOLOBZvpoPD8N5B5N8Dl1yEpoP73q
8 | 9JXrFbjE91vQnuuNbUFrNXKs+TKLsaXtj90o3m6GDYbd1x/tWdPu3fnzz3J6UFT/
9 | 1Jovl8wdcrdFTT24UUSSWnXtyWjWKa+hVVxkdRzJYIl+YcpRCBARZ/EfNpidpG6Z
10 | au2lMs5mmx+rckdTS+g/79cUUn5jfcRtNxcVVK+SNr3BL04XCNoJ1hUvKH969i8m
11 | 2YhQ/ps1itXv1v67VnpW15T1ps9XltLTW2k1GDURqDHLY7O5CzHjo8KKZ07CihWm
12 | 7fAiFinrapyBxLVSv6p/uPRkMxwpugujX9ZLpDP5O9AxJkhMYJImkZJ7HgtosWlE
13 | yP+HMo5+zDKt327MpZAY/TMd48hVYV55ZP1swS11p9QWGCXT6Rsyeyz9Pj1kXQYj
14 | mvKKDjXhUFADlJw9Mu+CYt8oW+JapyVTX5VJEwQ2H9BknwDxs0Evx8peZ6DWSOvE
15 | 1aVzFb1/GdLTd4UPpx87+1UI9zncjcVYXglMEokouWdUI/DJiNXsDBAOKe0sMV72
16 | Os7GdHlVDVS6Cot17eyaO+uy+x/QpKVjz1ypuTaWHmA8kEJhiYnLV16VHK5gq7q6
17 | 7hvmhc1RDCHGprpoqJFaeUtxPjldzgBKKZLwKjU191t8IZyVLgkTKKeE9kJo38rm
18 | TUVja2US/ChYGXsUCADWlSyH3G0fxE9YxOayCNdSKomTTTOS6Wgj8xWKwJWE2LJW
19 | cNw7EcFMjWAbvLHWM3FH0MqNkKNlOuhotvD2zx/KJDIiqBvDZzPYVNCB1SHBuvUF
20 | 86tqY50dR+9N7kjoAWvIjP9ejr5ZStlfRyOjicR2ceAfYxDitgxE2uHqdHLMiQJn
21 | uIq/NKL59TtawGPPVLMl8BzEYvc28GY+oL1GXOYaP24q9e0PbZm2BA==
22 |
--------------------------------------------------------------------------------
/test/fixtures/webp-550x368.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mapbox/tiletype/0632405c008302c15dfdefb104789baac1c10d30/test/fixtures/webp-550x368.webp
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | var tiletype = require('..');
2 | var assert = require('assert');
3 | var tape = require('tape');
4 | var path = require('path');
5 | var fs = require('fs');
6 | var exec = require('child_process').exec;
7 | var cmd = path.resolve(__dirname, '..', 'bin', 'tiletype.js');
8 |
9 | var files = {
10 | 'jpg': fs.readFileSync(__dirname + '/fixtures/0.jpeg'),
11 | 'png': fs.readFileSync(__dirname + '/fixtures/0.png'),
12 | 'gif': fs.readFileSync(__dirname + '/fixtures/0.gif'),
13 | 'webp': fs.readFileSync(__dirname + '/fixtures/0.webp'),
14 | 'pbf': fs.readFileSync(__dirname + '/fixtures/0.vector.pbf'),
15 | 'pbfz': fs.readFileSync(__dirname + '/fixtures/0.vector.pbfz'),
16 | 'unknown': fs.readFileSync(__dirname + '/fixtures/unknown.txt'),
17 | 'webpLossless': fs.readFileSync(__dirname + '/fixtures/tux.webp'),
18 | 'webpExtended': fs.readFileSync(__dirname + '/fixtures/tux_alpha.webp')
19 | };
20 |
21 | tape('type', function(t) {
22 | t.equal('jpg', tiletype.type(files.jpg), 'jpg');
23 | t.equal('png', tiletype.type(files.png), 'png');
24 | t.equal('gif', tiletype.type(files.gif), 'gif');
25 | t.equal('webp', tiletype.type(files.webp), 'webp');
26 | t.equal('webp', tiletype.type(files.webpLossless), 'webpLossless');
27 | t.equal('webp', tiletype.type(files.webpExtended), 'webpExtended');
28 | t.equal('pbf', tiletype.type(files.pbf), 'pbf');
29 | t.equal('pbf', tiletype.type(files.pbfz), 'pbf');
30 | t.equal(false, tiletype.type(files.unknown));
31 | t.end();
32 | });
33 |
34 | tape('headers', function(t) {
35 | t.deepEqual({'Content-Type':'image/jpeg'}, tiletype.headers(files.jpg));
36 | t.deepEqual({'Content-Type':'image/png'}, tiletype.headers(files.png));
37 | t.deepEqual({'Content-Type':'image/gif'}, tiletype.headers(files.gif));
38 | t.deepEqual({'Content-Type':'image/webp'}, tiletype.headers(files.webp));
39 | t.deepEqual({'Content-Type':'application/x-protobuf','Content-Encoding':'deflate'}, tiletype.headers(files.pbf));
40 | t.deepEqual({'Content-Type':'application/x-protobuf','Content-Encoding':'gzip'}, tiletype.headers(files.pbfz));
41 | t.deepEqual({}, tiletype.headers(false));
42 | t.end();
43 | });
44 |
45 | tape('dimensions', function(t) {
46 | t.deepEqual([256,256], tiletype.dimensions(files.png));
47 | t.deepEqual([640,400], tiletype.dimensions(fs.readFileSync(__dirname + '/fixtures/png-640x400.png')));
48 | t.deepEqual([256,256], tiletype.dimensions(files.jpg));
49 | t.deepEqual([640,400], tiletype.dimensions(fs.readFileSync(__dirname + '/fixtures/jpg-640x400.jpg')));
50 | t.deepEqual([256,256], tiletype.dimensions(files.gif));
51 | t.deepEqual([990,1050], tiletype.dimensions(fs.readFileSync(__dirname + '/fixtures/gif-990x1050.gif')));
52 | t.deepEqual([256,256], tiletype.dimensions(files.webp));
53 | t.deepEqual([550,368], tiletype.dimensions(fs.readFileSync(__dirname + '/fixtures/webp-550x368.webp')));
54 |
55 | t.deepEqual([386,395], tiletype.dimensions(files.webpLossless));
56 | t.deepEqual([386,395], tiletype.dimensions(files.webpExtended));
57 | t.end();
58 | });
59 |
60 | tape('executable: success', function(t) {
61 | exec(cmd + ' ' + path.resolve(__dirname + '/fixtures/0.vector.pbf'), function(err, stdout, stderr) {
62 | t.ifError(err, 'detected');
63 | t.equal(stdout, 'pbf\n', 'determined type');
64 | t.notOk(stderr, 'no stderr');
65 | t.end();
66 | });
67 | });
68 |
69 | tape('executable: unknown', function(t) {
70 | exec(cmd + ' ' + path.resolve(__dirname + '/fixtures/unknown.txt'), function(err, stdout, stderr) {
71 | t.equal(err.code, 3, 'exit 3');
72 | t.notOk(stdout, 'no stdout');
73 | t.equal(stderr, 'Could not determine tile type\n', 'expected stderr');
74 | t.end();
75 | });
76 | });
77 |
78 | tape('executable: no file', function(t) {
79 | exec(cmd, function(err, stdout, stderr) {
80 | t.equal(err.code, 1, 'exit 1');
81 | t.notOk(stdout, 'no stdout');
82 | t.ok(stderr === 'Error: ENOENT, open \'\'\n' ||
83 | stderr === 'Error: ENOENT: no such file or directory, open \'\'\n', 'expected stderr');
84 | t.end();
85 | });
86 | });
87 |
--------------------------------------------------------------------------------
/test/types.ts:
--------------------------------------------------------------------------------
1 | import * as fs from 'fs'
2 | import * as tiletype from '../'
3 |
4 | const dimensions = tiletype.dimensions(fs.readFileSync(__dirname + '/fixtures/0.jpeg'))
5 | const header = tiletype.headers(fs.readFileSync(__dirname + '/fixtures/0.jpeg'))
6 | const type = tiletype.type(fs.readFileSync(__dirname + '/fixtures/0.jpeg'))
--------------------------------------------------------------------------------