bare-media 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/client.js +15 -10
- package/package.json +7 -12
- package/shared/codecs.js +2 -2
- package/shared/spec/hrpc/hrpc.json +1 -1
- package/shared/spec/hrpc/index.js +49 -21
- package/shared/spec/hrpc/messages.js +62 -53
- package/shared/spec/schema/index.js +62 -53
- package/shared/spec/schema/schema.json +1 -1
- package/shared/spec/schema.js +103 -89
- package/worker/media.js +58 -16
- package/worker/util.js +1 -1
package/README.md
CHANGED
|
@@ -29,15 +29,14 @@ const data = await worker.createPreview({ path, maxWidth, maxHeight })
|
|
|
29
29
|
|
|
30
30
|
> NOTE: A worker spawns when an operation is requested and it stays running until the parent process is killed.
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
Terminate the worker:
|
|
33
33
|
|
|
34
34
|
```js
|
|
35
|
-
|
|
35
|
+
worker.close()
|
|
36
36
|
|
|
37
37
|
worker.onClose = () => {
|
|
38
|
-
// worker
|
|
38
|
+
// worker terminated
|
|
39
39
|
}
|
|
40
|
-
|
|
41
40
|
```
|
|
42
41
|
|
|
43
42
|
Call the methods directly without a worker:
|
|
@@ -50,10 +49,10 @@ const data = await createPreview({ path, maxWidth, maxHeight })
|
|
|
50
49
|
|
|
51
50
|
## API
|
|
52
51
|
|
|
53
|
-
| Method
|
|
54
|
-
|
|
55
|
-
| `createPreview`
|
|
56
|
-
| `decodeImage`
|
|
52
|
+
| Method | Parameters | Return Value | Description |
|
|
53
|
+
| --------------- | ------------------------------------------------------- | ------------------- | ---------------------------------- |
|
|
54
|
+
| `createPreview` | `path, mimetype, maxWidth, maxHeight, format, encoding` | `metadata, preview` | Create a preview from a media file |
|
|
55
|
+
| `decodeImage` | `path`, `httpLink, mimetype` | `metadata, data` | Decode an image to RGBA |
|
|
57
56
|
|
|
58
57
|
> See [schema.js](shared/spec/schema.js) for the complete reference of parameters
|
|
59
58
|
|
package/client.js
CHANGED
|
@@ -9,21 +9,22 @@ export class WorkerClient extends ReadyResource {
|
|
|
9
9
|
rpc = null
|
|
10
10
|
opts = null
|
|
11
11
|
|
|
12
|
-
constructor
|
|
12
|
+
constructor(opts) {
|
|
13
13
|
super()
|
|
14
14
|
this.initialize(opts)
|
|
15
15
|
this.#attachMethods()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
initialize
|
|
18
|
+
initialize({
|
|
19
|
+
filename = 'node_modules/bare-media/worker/index.js',
|
|
20
|
+
requireSource,
|
|
21
|
+
args
|
|
22
|
+
} = {}) {
|
|
19
23
|
this.opts = { filename, requireSource, args }
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
#attachMethods
|
|
23
|
-
const methods = [
|
|
24
|
-
'createPreview',
|
|
25
|
-
'decodeImage'
|
|
26
|
-
]
|
|
26
|
+
#attachMethods() {
|
|
27
|
+
const methods = ['createPreview', 'decodeImage']
|
|
27
28
|
|
|
28
29
|
for (const method of methods) {
|
|
29
30
|
this[method] = async (...args) => {
|
|
@@ -33,11 +34,15 @@ export class WorkerClient extends ReadyResource {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
async _open
|
|
37
|
+
async _open() {
|
|
37
38
|
await this.#run()
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
async
|
|
41
|
+
async _close() {
|
|
42
|
+
this.worker?.IPC.end()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async #run() {
|
|
41
46
|
const { filename, requireSource, args } = this.opts
|
|
42
47
|
const source = requireSource?.()
|
|
43
48
|
this.worker = await spawn(filename, source, args)
|
|
@@ -50,7 +55,7 @@ export class WorkerClient extends ReadyResource {
|
|
|
50
55
|
this.rpc = new HRPC(ipc)
|
|
51
56
|
}
|
|
52
57
|
|
|
53
|
-
isCodecSupported
|
|
58
|
+
isCodecSupported(mimetype) {
|
|
54
59
|
return isCodecSupported(mimetype)
|
|
55
60
|
}
|
|
56
61
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-media",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build:rpc": "cd shared/spec && bare ./build.js",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"test": "npm run
|
|
8
|
+
"format": "prettier --write .",
|
|
9
|
+
"format:check": "prettier --check .",
|
|
10
|
+
"test": "npm run format:check && brittle-bare test/index.js"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [],
|
|
13
13
|
"author": "Holepunch Inc",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"corestore": "^7.4.5",
|
|
36
36
|
"hyperblobs": "^2.8.0",
|
|
37
37
|
"hypercore-blob-server": "^1.11.0",
|
|
38
|
-
"
|
|
38
|
+
"prettier": "^3.6.2",
|
|
39
|
+
"prettier-config-holepunch": "^1.0.0",
|
|
39
40
|
"test-tmp": "^1.4.0"
|
|
40
41
|
},
|
|
41
42
|
"files": [
|
|
@@ -43,11 +44,5 @@
|
|
|
43
44
|
"worker",
|
|
44
45
|
"client.js",
|
|
45
46
|
"index.js"
|
|
46
|
-
]
|
|
47
|
-
"standard": {
|
|
48
|
-
"globals": [
|
|
49
|
-
"Bare",
|
|
50
|
-
"Pear"
|
|
51
|
-
]
|
|
52
|
-
}
|
|
47
|
+
]
|
|
53
48
|
}
|
package/shared/codecs.js
CHANGED
|
@@ -10,11 +10,11 @@ export const codecs = {
|
|
|
10
10
|
'image/tiff': () => import('bare-tiff')
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function isCodecSupported
|
|
13
|
+
export function isCodecSupported(mimetype) {
|
|
14
14
|
return mimetype in codecs
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export async function importCodec
|
|
17
|
+
export async function importCodec(mimetype) {
|
|
18
18
|
const codecImport = codecs[mimetype]
|
|
19
19
|
if (!codecImport) throw new Error(`No codec for ${mimetype}`)
|
|
20
20
|
return await codecImport()
|
|
@@ -12,7 +12,7 @@ const methods = new Map([
|
|
|
12
12
|
])
|
|
13
13
|
|
|
14
14
|
class HRPC {
|
|
15
|
-
constructor
|
|
15
|
+
constructor(stream) {
|
|
16
16
|
this._stream = stream
|
|
17
17
|
this._handlers = []
|
|
18
18
|
this._requestEncodings = new Map([
|
|
@@ -39,23 +39,40 @@ class HRPC {
|
|
|
39
39
|
}
|
|
40
40
|
if (!this._requestIsStream(command) && this._responseIsStream(command)) {
|
|
41
41
|
const request = req.data ? c.decode(requestEncoding, req.data) : null
|
|
42
|
-
const responseStream = new RPCStream(
|
|
42
|
+
const responseStream = new RPCStream(
|
|
43
|
+
null,
|
|
44
|
+
null,
|
|
45
|
+
req.createResponseStream(),
|
|
46
|
+
responseEncoding
|
|
47
|
+
)
|
|
43
48
|
responseStream.data = request
|
|
44
49
|
await this._handlers[command](responseStream)
|
|
45
50
|
}
|
|
46
51
|
if (this._requestIsStream(command) && !this._responseIsStream(command)) {
|
|
47
|
-
const requestStream = new RPCRequestStream(
|
|
52
|
+
const requestStream = new RPCRequestStream(
|
|
53
|
+
req,
|
|
54
|
+
responseEncoding,
|
|
55
|
+
req.createRequestStream(),
|
|
56
|
+
requestEncoding
|
|
57
|
+
)
|
|
48
58
|
const response = await this._handlers[command](requestStream)
|
|
49
59
|
req.reply(c.encode(responseEncoding, response))
|
|
50
60
|
}
|
|
51
61
|
if (this._requestIsStream(command) && this._responseIsStream(command)) {
|
|
52
|
-
const requestStream = new RPCRequestStream(
|
|
62
|
+
const requestStream = new RPCRequestStream(
|
|
63
|
+
req,
|
|
64
|
+
responseEncoding,
|
|
65
|
+
req.createRequestStream(),
|
|
66
|
+
requestEncoding,
|
|
67
|
+
req.createResponseStream(),
|
|
68
|
+
responseEncoding
|
|
69
|
+
)
|
|
53
70
|
await this._handlers[command](requestStream)
|
|
54
71
|
}
|
|
55
72
|
})
|
|
56
73
|
}
|
|
57
74
|
|
|
58
|
-
async _call
|
|
75
|
+
async _call(name, args) {
|
|
59
76
|
const requestEncoding = this._requestEncodings.get(name)
|
|
60
77
|
const responseEncoding = this._responseEncodings.get(name)
|
|
61
78
|
const request = this._rpc.request(methods.get(name))
|
|
@@ -64,7 +81,7 @@ class HRPC {
|
|
|
64
81
|
return c.decode(responseEncoding, await request.reply())
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
_callSync
|
|
84
|
+
_callSync(name, args) {
|
|
68
85
|
const requestEncoding = this._requestEncodings.get(name)
|
|
69
86
|
const responseEncoding = this._responseEncodings.get(name)
|
|
70
87
|
const request = this._rpc.request(methods.get(name))
|
|
@@ -78,42 +95,53 @@ class HRPC {
|
|
|
78
95
|
return new RPCStream(request.createResponseStream(), responseEncoding)
|
|
79
96
|
}
|
|
80
97
|
if (this._requestIsStream(name) && !this._responseIsStream(name)) {
|
|
81
|
-
return new RPCRequestStream(
|
|
98
|
+
return new RPCRequestStream(
|
|
99
|
+
request,
|
|
100
|
+
responseEncoding,
|
|
101
|
+
null,
|
|
102
|
+
null,
|
|
103
|
+
request.createRequestStream(),
|
|
104
|
+
requestEncoding
|
|
105
|
+
)
|
|
82
106
|
}
|
|
83
107
|
if (this._requestIsStream(name) && this._responseIsStream(name)) {
|
|
84
|
-
return new RPCRequestStream(
|
|
108
|
+
return new RPCRequestStream(
|
|
109
|
+
request,
|
|
110
|
+
responseEncoding,
|
|
111
|
+
request.createResponseStream(),
|
|
112
|
+
responseEncoding,
|
|
113
|
+
request.createRequestStream(),
|
|
114
|
+
requestEncoding
|
|
115
|
+
)
|
|
85
116
|
}
|
|
86
117
|
}
|
|
87
118
|
|
|
88
|
-
async createPreview
|
|
119
|
+
async createPreview(args) {
|
|
89
120
|
return this._call('@media/create-preview', args)
|
|
90
121
|
}
|
|
91
122
|
|
|
92
|
-
async decodeImage
|
|
123
|
+
async decodeImage(args) {
|
|
93
124
|
return this._call('@media/decode-image', args)
|
|
94
125
|
}
|
|
95
126
|
|
|
96
|
-
onCreatePreview
|
|
127
|
+
onCreatePreview(responseFn) {
|
|
97
128
|
this._handlers['@media/create-preview'] = responseFn
|
|
98
129
|
}
|
|
99
130
|
|
|
100
|
-
onDecodeImage
|
|
131
|
+
onDecodeImage(responseFn) {
|
|
101
132
|
this._handlers['@media/decode-image'] = responseFn
|
|
102
133
|
}
|
|
103
134
|
|
|
104
|
-
_requestIsStream
|
|
105
|
-
return [
|
|
106
|
-
].includes(command)
|
|
135
|
+
_requestIsStream(command) {
|
|
136
|
+
return [].includes(command)
|
|
107
137
|
}
|
|
108
138
|
|
|
109
|
-
_responseIsStream
|
|
110
|
-
return [
|
|
111
|
-
].includes(command)
|
|
139
|
+
_responseIsStream(command) {
|
|
140
|
+
return [].includes(command)
|
|
112
141
|
}
|
|
113
142
|
|
|
114
|
-
_requestIsSend
|
|
115
|
-
return [
|
|
116
|
-
].includes(command)
|
|
143
|
+
_requestIsSend(command) {
|
|
144
|
+
return [].includes(command)
|
|
117
145
|
}
|
|
118
146
|
}
|
|
119
147
|
|
|
@@ -12,15 +12,15 @@ let version = VERSION
|
|
|
12
12
|
|
|
13
13
|
// @media/dimensions
|
|
14
14
|
const encoding0 = {
|
|
15
|
-
preencode
|
|
15
|
+
preencode(state, m) {
|
|
16
16
|
c.uint.preencode(state, m.width)
|
|
17
17
|
c.uint.preencode(state, m.height)
|
|
18
18
|
},
|
|
19
|
-
encode
|
|
19
|
+
encode(state, m) {
|
|
20
20
|
c.uint.encode(state, m.width)
|
|
21
21
|
c.uint.encode(state, m.height)
|
|
22
22
|
},
|
|
23
|
-
decode
|
|
23
|
+
decode(state) {
|
|
24
24
|
const r0 = c.uint.decode(state)
|
|
25
25
|
const r1 = c.uint.decode(state)
|
|
26
26
|
|
|
@@ -36,18 +36,16 @@ const encoding1_1 = c.frame(encoding0)
|
|
|
36
36
|
|
|
37
37
|
// @media/metadata
|
|
38
38
|
const encoding1 = {
|
|
39
|
-
preencode
|
|
39
|
+
preencode(state, m) {
|
|
40
40
|
state.end++ // max flag is 4 so always one byte
|
|
41
41
|
|
|
42
42
|
if (m.mimetype) c.string.preencode(state, m.mimetype)
|
|
43
43
|
if (m.dimensions) encoding1_1.preencode(state, m.dimensions)
|
|
44
44
|
if (m.duration) c.uint.preencode(state, m.duration)
|
|
45
45
|
},
|
|
46
|
-
encode
|
|
46
|
+
encode(state, m) {
|
|
47
47
|
const flags =
|
|
48
|
-
(m.mimetype ? 1 : 0) |
|
|
49
|
-
(m.dimensions ? 2 : 0) |
|
|
50
|
-
(m.duration ? 4 : 0)
|
|
48
|
+
(m.mimetype ? 1 : 0) | (m.dimensions ? 2 : 0) | (m.duration ? 4 : 0)
|
|
51
49
|
|
|
52
50
|
c.uint.encode(state, flags)
|
|
53
51
|
|
|
@@ -55,7 +53,7 @@ const encoding1 = {
|
|
|
55
53
|
if (m.dimensions) encoding1_1.encode(state, m.dimensions)
|
|
56
54
|
if (m.duration) c.uint.encode(state, m.duration)
|
|
57
55
|
},
|
|
58
|
-
decode
|
|
56
|
+
decode(state) {
|
|
59
57
|
const flags = c.uint.decode(state)
|
|
60
58
|
|
|
61
59
|
return {
|
|
@@ -71,18 +69,16 @@ const encoding2_0 = c.frame(encoding1)
|
|
|
71
69
|
|
|
72
70
|
// @media/file
|
|
73
71
|
const encoding2 = {
|
|
74
|
-
preencode
|
|
72
|
+
preencode(state, m) {
|
|
75
73
|
state.end++ // max flag is 4 so always one byte
|
|
76
74
|
|
|
77
75
|
if (m.metadata) encoding2_0.preencode(state, m.metadata)
|
|
78
76
|
if (m.inlined) c.string.preencode(state, m.inlined)
|
|
79
77
|
if (m.buffer) c.buffer.preencode(state, m.buffer)
|
|
80
78
|
},
|
|
81
|
-
encode
|
|
79
|
+
encode(state, m) {
|
|
82
80
|
const flags =
|
|
83
|
-
(m.metadata ? 1 : 0) |
|
|
84
|
-
(m.inlined ? 2 : 0) |
|
|
85
|
-
(m.buffer ? 4 : 0)
|
|
81
|
+
(m.metadata ? 1 : 0) | (m.inlined ? 2 : 0) | (m.buffer ? 4 : 0)
|
|
86
82
|
|
|
87
83
|
c.uint.encode(state, flags)
|
|
88
84
|
|
|
@@ -90,7 +86,7 @@ const encoding2 = {
|
|
|
90
86
|
if (m.inlined) c.string.encode(state, m.inlined)
|
|
91
87
|
if (m.buffer) c.buffer.encode(state, m.buffer)
|
|
92
88
|
},
|
|
93
|
-
decode
|
|
89
|
+
decode(state) {
|
|
94
90
|
const flags = c.uint.decode(state)
|
|
95
91
|
|
|
96
92
|
return {
|
|
@@ -103,7 +99,7 @@ const encoding2 = {
|
|
|
103
99
|
|
|
104
100
|
// @media/create-preview-request
|
|
105
101
|
const encoding3 = {
|
|
106
|
-
preencode
|
|
102
|
+
preencode(state, m) {
|
|
107
103
|
c.string.preencode(state, m.path)
|
|
108
104
|
state.end++ // max flag is 16 so always one byte
|
|
109
105
|
|
|
@@ -113,7 +109,7 @@ const encoding3 = {
|
|
|
113
109
|
if (m.format) c.string.preencode(state, m.format)
|
|
114
110
|
if (m.encoding) c.string.preencode(state, m.encoding)
|
|
115
111
|
},
|
|
116
|
-
encode
|
|
112
|
+
encode(state, m) {
|
|
117
113
|
const flags =
|
|
118
114
|
(m.mimetype ? 1 : 0) |
|
|
119
115
|
(m.maxWidth ? 2 : 0) |
|
|
@@ -130,7 +126,7 @@ const encoding3 = {
|
|
|
130
126
|
if (m.format) c.string.encode(state, m.format)
|
|
131
127
|
if (m.encoding) c.string.encode(state, m.encoding)
|
|
132
128
|
},
|
|
133
|
-
decode
|
|
129
|
+
decode(state) {
|
|
134
130
|
const r0 = c.string.decode(state)
|
|
135
131
|
const flags = c.uint.decode(state)
|
|
136
132
|
|
|
@@ -152,15 +148,15 @@ const encoding4_1 = c.frame(encoding2)
|
|
|
152
148
|
|
|
153
149
|
// @media/create-preview-response
|
|
154
150
|
const encoding4 = {
|
|
155
|
-
preencode
|
|
151
|
+
preencode(state, m) {
|
|
156
152
|
encoding4_0.preencode(state, m.metadata)
|
|
157
153
|
encoding4_1.preencode(state, m.preview)
|
|
158
154
|
},
|
|
159
|
-
encode
|
|
155
|
+
encode(state, m) {
|
|
160
156
|
encoding4_0.encode(state, m.metadata)
|
|
161
157
|
encoding4_1.encode(state, m.preview)
|
|
162
158
|
},
|
|
163
|
-
decode
|
|
159
|
+
decode(state) {
|
|
164
160
|
const r0 = encoding4_0.decode(state)
|
|
165
161
|
const r1 = encoding4_1.decode(state)
|
|
166
162
|
|
|
@@ -173,18 +169,15 @@ const encoding4 = {
|
|
|
173
169
|
|
|
174
170
|
// @media/decode-image-request
|
|
175
171
|
const encoding5 = {
|
|
176
|
-
preencode
|
|
172
|
+
preencode(state, m) {
|
|
177
173
|
state.end++ // max flag is 4 so always one byte
|
|
178
174
|
|
|
179
175
|
if (m.path) c.string.preencode(state, m.path)
|
|
180
176
|
if (m.httpLink) c.string.preencode(state, m.httpLink)
|
|
181
177
|
if (m.mimetype) c.string.preencode(state, m.mimetype)
|
|
182
178
|
},
|
|
183
|
-
encode
|
|
184
|
-
const flags =
|
|
185
|
-
(m.path ? 1 : 0) |
|
|
186
|
-
(m.httpLink ? 2 : 0) |
|
|
187
|
-
(m.mimetype ? 4 : 0)
|
|
179
|
+
encode(state, m) {
|
|
180
|
+
const flags = (m.path ? 1 : 0) | (m.httpLink ? 2 : 0) | (m.mimetype ? 4 : 0)
|
|
188
181
|
|
|
189
182
|
c.uint.encode(state, flags)
|
|
190
183
|
|
|
@@ -192,7 +185,7 @@ const encoding5 = {
|
|
|
192
185
|
if (m.httpLink) c.string.encode(state, m.httpLink)
|
|
193
186
|
if (m.mimetype) c.string.encode(state, m.mimetype)
|
|
194
187
|
},
|
|
195
|
-
decode
|
|
188
|
+
decode(state) {
|
|
196
189
|
const flags = c.uint.decode(state)
|
|
197
190
|
|
|
198
191
|
return {
|
|
@@ -208,23 +201,21 @@ const encoding6_0 = encoding2_0
|
|
|
208
201
|
|
|
209
202
|
// @media/decode-image-response
|
|
210
203
|
const encoding6 = {
|
|
211
|
-
preencode
|
|
204
|
+
preencode(state, m) {
|
|
212
205
|
state.end++ // max flag is 2 so always one byte
|
|
213
206
|
|
|
214
207
|
if (m.metadata) encoding6_0.preencode(state, m.metadata)
|
|
215
208
|
if (m.data) c.buffer.preencode(state, m.data)
|
|
216
209
|
},
|
|
217
|
-
encode
|
|
218
|
-
const flags =
|
|
219
|
-
(m.metadata ? 1 : 0) |
|
|
220
|
-
(m.data ? 2 : 0)
|
|
210
|
+
encode(state, m) {
|
|
211
|
+
const flags = (m.metadata ? 1 : 0) | (m.data ? 2 : 0)
|
|
221
212
|
|
|
222
213
|
c.uint.encode(state, flags)
|
|
223
214
|
|
|
224
215
|
if (m.metadata) encoding6_0.encode(state, m.metadata)
|
|
225
216
|
if (m.data) c.buffer.encode(state, m.data)
|
|
226
217
|
},
|
|
227
|
-
decode
|
|
218
|
+
decode(state) {
|
|
228
219
|
const flags = c.uint.decode(state)
|
|
229
220
|
|
|
230
221
|
return {
|
|
@@ -234,51 +225,60 @@ const encoding6 = {
|
|
|
234
225
|
}
|
|
235
226
|
}
|
|
236
227
|
|
|
237
|
-
function setVersion
|
|
228
|
+
function setVersion(v) {
|
|
238
229
|
version = v
|
|
239
230
|
}
|
|
240
231
|
|
|
241
|
-
function encode
|
|
232
|
+
function encode(name, value, v = VERSION) {
|
|
242
233
|
version = v
|
|
243
234
|
return c.encode(getEncoding(name), value)
|
|
244
235
|
}
|
|
245
236
|
|
|
246
|
-
function decode
|
|
237
|
+
function decode(name, buffer, v = VERSION) {
|
|
247
238
|
version = v
|
|
248
239
|
return c.decode(getEncoding(name), buffer)
|
|
249
240
|
}
|
|
250
241
|
|
|
251
|
-
function getEnum
|
|
242
|
+
function getEnum(name) {
|
|
252
243
|
switch (name) {
|
|
253
|
-
default:
|
|
244
|
+
default:
|
|
245
|
+
throw new Error('Enum not found ' + name)
|
|
254
246
|
}
|
|
255
247
|
}
|
|
256
248
|
|
|
257
|
-
function getEncoding
|
|
249
|
+
function getEncoding(name) {
|
|
258
250
|
switch (name) {
|
|
259
|
-
case '@media/dimensions':
|
|
260
|
-
|
|
261
|
-
case '@media/
|
|
262
|
-
|
|
263
|
-
case '@media/
|
|
264
|
-
|
|
265
|
-
case '@media/
|
|
266
|
-
|
|
251
|
+
case '@media/dimensions':
|
|
252
|
+
return encoding0
|
|
253
|
+
case '@media/metadata':
|
|
254
|
+
return encoding1
|
|
255
|
+
case '@media/file':
|
|
256
|
+
return encoding2
|
|
257
|
+
case '@media/create-preview-request':
|
|
258
|
+
return encoding3
|
|
259
|
+
case '@media/create-preview-response':
|
|
260
|
+
return encoding4
|
|
261
|
+
case '@media/decode-image-request':
|
|
262
|
+
return encoding5
|
|
263
|
+
case '@media/decode-image-response':
|
|
264
|
+
return encoding6
|
|
265
|
+
default:
|
|
266
|
+
throw new Error('Encoder not found ' + name)
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
function getStruct
|
|
270
|
+
function getStruct(name, v = VERSION) {
|
|
271
271
|
const enc = getEncoding(name)
|
|
272
272
|
return {
|
|
273
|
-
preencode
|
|
273
|
+
preencode(state, m) {
|
|
274
274
|
version = v
|
|
275
275
|
enc.preencode(state, m)
|
|
276
276
|
},
|
|
277
|
-
encode
|
|
277
|
+
encode(state, m) {
|
|
278
278
|
version = v
|
|
279
279
|
enc.encode(state, m)
|
|
280
280
|
},
|
|
281
|
-
decode
|
|
281
|
+
decode(state) {
|
|
282
282
|
version = v
|
|
283
283
|
return enc.decode(state)
|
|
284
284
|
}
|
|
@@ -287,4 +287,13 @@ function getStruct (name, v = VERSION) {
|
|
|
287
287
|
|
|
288
288
|
const resolveStruct = getStruct // compat
|
|
289
289
|
|
|
290
|
-
export {
|
|
290
|
+
export {
|
|
291
|
+
resolveStruct,
|
|
292
|
+
getStruct,
|
|
293
|
+
getEnum,
|
|
294
|
+
getEncoding,
|
|
295
|
+
encode,
|
|
296
|
+
decode,
|
|
297
|
+
setVersion,
|
|
298
|
+
version
|
|
299
|
+
}
|
|
@@ -12,15 +12,15 @@ let version = VERSION
|
|
|
12
12
|
|
|
13
13
|
// @media/dimensions
|
|
14
14
|
const encoding0 = {
|
|
15
|
-
preencode
|
|
15
|
+
preencode(state, m) {
|
|
16
16
|
c.uint.preencode(state, m.width)
|
|
17
17
|
c.uint.preencode(state, m.height)
|
|
18
18
|
},
|
|
19
|
-
encode
|
|
19
|
+
encode(state, m) {
|
|
20
20
|
c.uint.encode(state, m.width)
|
|
21
21
|
c.uint.encode(state, m.height)
|
|
22
22
|
},
|
|
23
|
-
decode
|
|
23
|
+
decode(state) {
|
|
24
24
|
const r0 = c.uint.decode(state)
|
|
25
25
|
const r1 = c.uint.decode(state)
|
|
26
26
|
|
|
@@ -36,18 +36,16 @@ const encoding1_1 = c.frame(encoding0)
|
|
|
36
36
|
|
|
37
37
|
// @media/metadata
|
|
38
38
|
const encoding1 = {
|
|
39
|
-
preencode
|
|
39
|
+
preencode(state, m) {
|
|
40
40
|
state.end++ // max flag is 4 so always one byte
|
|
41
41
|
|
|
42
42
|
if (m.mimetype) c.string.preencode(state, m.mimetype)
|
|
43
43
|
if (m.dimensions) encoding1_1.preencode(state, m.dimensions)
|
|
44
44
|
if (m.duration) c.uint.preencode(state, m.duration)
|
|
45
45
|
},
|
|
46
|
-
encode
|
|
46
|
+
encode(state, m) {
|
|
47
47
|
const flags =
|
|
48
|
-
(m.mimetype ? 1 : 0) |
|
|
49
|
-
(m.dimensions ? 2 : 0) |
|
|
50
|
-
(m.duration ? 4 : 0)
|
|
48
|
+
(m.mimetype ? 1 : 0) | (m.dimensions ? 2 : 0) | (m.duration ? 4 : 0)
|
|
51
49
|
|
|
52
50
|
c.uint.encode(state, flags)
|
|
53
51
|
|
|
@@ -55,7 +53,7 @@ const encoding1 = {
|
|
|
55
53
|
if (m.dimensions) encoding1_1.encode(state, m.dimensions)
|
|
56
54
|
if (m.duration) c.uint.encode(state, m.duration)
|
|
57
55
|
},
|
|
58
|
-
decode
|
|
56
|
+
decode(state) {
|
|
59
57
|
const flags = c.uint.decode(state)
|
|
60
58
|
|
|
61
59
|
return {
|
|
@@ -71,18 +69,16 @@ const encoding2_0 = c.frame(encoding1)
|
|
|
71
69
|
|
|
72
70
|
// @media/file
|
|
73
71
|
const encoding2 = {
|
|
74
|
-
preencode
|
|
72
|
+
preencode(state, m) {
|
|
75
73
|
state.end++ // max flag is 4 so always one byte
|
|
76
74
|
|
|
77
75
|
if (m.metadata) encoding2_0.preencode(state, m.metadata)
|
|
78
76
|
if (m.inlined) c.string.preencode(state, m.inlined)
|
|
79
77
|
if (m.buffer) c.buffer.preencode(state, m.buffer)
|
|
80
78
|
},
|
|
81
|
-
encode
|
|
79
|
+
encode(state, m) {
|
|
82
80
|
const flags =
|
|
83
|
-
(m.metadata ? 1 : 0) |
|
|
84
|
-
(m.inlined ? 2 : 0) |
|
|
85
|
-
(m.buffer ? 4 : 0)
|
|
81
|
+
(m.metadata ? 1 : 0) | (m.inlined ? 2 : 0) | (m.buffer ? 4 : 0)
|
|
86
82
|
|
|
87
83
|
c.uint.encode(state, flags)
|
|
88
84
|
|
|
@@ -90,7 +86,7 @@ const encoding2 = {
|
|
|
90
86
|
if (m.inlined) c.string.encode(state, m.inlined)
|
|
91
87
|
if (m.buffer) c.buffer.encode(state, m.buffer)
|
|
92
88
|
},
|
|
93
|
-
decode
|
|
89
|
+
decode(state) {
|
|
94
90
|
const flags = c.uint.decode(state)
|
|
95
91
|
|
|
96
92
|
return {
|
|
@@ -103,7 +99,7 @@ const encoding2 = {
|
|
|
103
99
|
|
|
104
100
|
// @media/create-preview-request
|
|
105
101
|
const encoding3 = {
|
|
106
|
-
preencode
|
|
102
|
+
preencode(state, m) {
|
|
107
103
|
c.string.preencode(state, m.path)
|
|
108
104
|
state.end++ // max flag is 16 so always one byte
|
|
109
105
|
|
|
@@ -113,7 +109,7 @@ const encoding3 = {
|
|
|
113
109
|
if (m.format) c.string.preencode(state, m.format)
|
|
114
110
|
if (m.encoding) c.string.preencode(state, m.encoding)
|
|
115
111
|
},
|
|
116
|
-
encode
|
|
112
|
+
encode(state, m) {
|
|
117
113
|
const flags =
|
|
118
114
|
(m.mimetype ? 1 : 0) |
|
|
119
115
|
(m.maxWidth ? 2 : 0) |
|
|
@@ -130,7 +126,7 @@ const encoding3 = {
|
|
|
130
126
|
if (m.format) c.string.encode(state, m.format)
|
|
131
127
|
if (m.encoding) c.string.encode(state, m.encoding)
|
|
132
128
|
},
|
|
133
|
-
decode
|
|
129
|
+
decode(state) {
|
|
134
130
|
const r0 = c.string.decode(state)
|
|
135
131
|
const flags = c.uint.decode(state)
|
|
136
132
|
|
|
@@ -152,15 +148,15 @@ const encoding4_1 = c.frame(encoding2)
|
|
|
152
148
|
|
|
153
149
|
// @media/create-preview-response
|
|
154
150
|
const encoding4 = {
|
|
155
|
-
preencode
|
|
151
|
+
preencode(state, m) {
|
|
156
152
|
encoding4_0.preencode(state, m.metadata)
|
|
157
153
|
encoding4_1.preencode(state, m.preview)
|
|
158
154
|
},
|
|
159
|
-
encode
|
|
155
|
+
encode(state, m) {
|
|
160
156
|
encoding4_0.encode(state, m.metadata)
|
|
161
157
|
encoding4_1.encode(state, m.preview)
|
|
162
158
|
},
|
|
163
|
-
decode
|
|
159
|
+
decode(state) {
|
|
164
160
|
const r0 = encoding4_0.decode(state)
|
|
165
161
|
const r1 = encoding4_1.decode(state)
|
|
166
162
|
|
|
@@ -173,18 +169,15 @@ const encoding4 = {
|
|
|
173
169
|
|
|
174
170
|
// @media/decode-image-request
|
|
175
171
|
const encoding5 = {
|
|
176
|
-
preencode
|
|
172
|
+
preencode(state, m) {
|
|
177
173
|
state.end++ // max flag is 4 so always one byte
|
|
178
174
|
|
|
179
175
|
if (m.path) c.string.preencode(state, m.path)
|
|
180
176
|
if (m.httpLink) c.string.preencode(state, m.httpLink)
|
|
181
177
|
if (m.mimetype) c.string.preencode(state, m.mimetype)
|
|
182
178
|
},
|
|
183
|
-
encode
|
|
184
|
-
const flags =
|
|
185
|
-
(m.path ? 1 : 0) |
|
|
186
|
-
(m.httpLink ? 2 : 0) |
|
|
187
|
-
(m.mimetype ? 4 : 0)
|
|
179
|
+
encode(state, m) {
|
|
180
|
+
const flags = (m.path ? 1 : 0) | (m.httpLink ? 2 : 0) | (m.mimetype ? 4 : 0)
|
|
188
181
|
|
|
189
182
|
c.uint.encode(state, flags)
|
|
190
183
|
|
|
@@ -192,7 +185,7 @@ const encoding5 = {
|
|
|
192
185
|
if (m.httpLink) c.string.encode(state, m.httpLink)
|
|
193
186
|
if (m.mimetype) c.string.encode(state, m.mimetype)
|
|
194
187
|
},
|
|
195
|
-
decode
|
|
188
|
+
decode(state) {
|
|
196
189
|
const flags = c.uint.decode(state)
|
|
197
190
|
|
|
198
191
|
return {
|
|
@@ -208,23 +201,21 @@ const encoding6_0 = encoding2_0
|
|
|
208
201
|
|
|
209
202
|
// @media/decode-image-response
|
|
210
203
|
const encoding6 = {
|
|
211
|
-
preencode
|
|
204
|
+
preencode(state, m) {
|
|
212
205
|
state.end++ // max flag is 2 so always one byte
|
|
213
206
|
|
|
214
207
|
if (m.metadata) encoding6_0.preencode(state, m.metadata)
|
|
215
208
|
if (m.data) c.buffer.preencode(state, m.data)
|
|
216
209
|
},
|
|
217
|
-
encode
|
|
218
|
-
const flags =
|
|
219
|
-
(m.metadata ? 1 : 0) |
|
|
220
|
-
(m.data ? 2 : 0)
|
|
210
|
+
encode(state, m) {
|
|
211
|
+
const flags = (m.metadata ? 1 : 0) | (m.data ? 2 : 0)
|
|
221
212
|
|
|
222
213
|
c.uint.encode(state, flags)
|
|
223
214
|
|
|
224
215
|
if (m.metadata) encoding6_0.encode(state, m.metadata)
|
|
225
216
|
if (m.data) c.buffer.encode(state, m.data)
|
|
226
217
|
},
|
|
227
|
-
decode
|
|
218
|
+
decode(state) {
|
|
228
219
|
const flags = c.uint.decode(state)
|
|
229
220
|
|
|
230
221
|
return {
|
|
@@ -234,51 +225,60 @@ const encoding6 = {
|
|
|
234
225
|
}
|
|
235
226
|
}
|
|
236
227
|
|
|
237
|
-
function setVersion
|
|
228
|
+
function setVersion(v) {
|
|
238
229
|
version = v
|
|
239
230
|
}
|
|
240
231
|
|
|
241
|
-
function encode
|
|
232
|
+
function encode(name, value, v = VERSION) {
|
|
242
233
|
version = v
|
|
243
234
|
return c.encode(getEncoding(name), value)
|
|
244
235
|
}
|
|
245
236
|
|
|
246
|
-
function decode
|
|
237
|
+
function decode(name, buffer, v = VERSION) {
|
|
247
238
|
version = v
|
|
248
239
|
return c.decode(getEncoding(name), buffer)
|
|
249
240
|
}
|
|
250
241
|
|
|
251
|
-
function getEnum
|
|
242
|
+
function getEnum(name) {
|
|
252
243
|
switch (name) {
|
|
253
|
-
default:
|
|
244
|
+
default:
|
|
245
|
+
throw new Error('Enum not found ' + name)
|
|
254
246
|
}
|
|
255
247
|
}
|
|
256
248
|
|
|
257
|
-
function getEncoding
|
|
249
|
+
function getEncoding(name) {
|
|
258
250
|
switch (name) {
|
|
259
|
-
case '@media/dimensions':
|
|
260
|
-
|
|
261
|
-
case '@media/
|
|
262
|
-
|
|
263
|
-
case '@media/
|
|
264
|
-
|
|
265
|
-
case '@media/
|
|
266
|
-
|
|
251
|
+
case '@media/dimensions':
|
|
252
|
+
return encoding0
|
|
253
|
+
case '@media/metadata':
|
|
254
|
+
return encoding1
|
|
255
|
+
case '@media/file':
|
|
256
|
+
return encoding2
|
|
257
|
+
case '@media/create-preview-request':
|
|
258
|
+
return encoding3
|
|
259
|
+
case '@media/create-preview-response':
|
|
260
|
+
return encoding4
|
|
261
|
+
case '@media/decode-image-request':
|
|
262
|
+
return encoding5
|
|
263
|
+
case '@media/decode-image-response':
|
|
264
|
+
return encoding6
|
|
265
|
+
default:
|
|
266
|
+
throw new Error('Encoder not found ' + name)
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
function getStruct
|
|
270
|
+
function getStruct(name, v = VERSION) {
|
|
271
271
|
const enc = getEncoding(name)
|
|
272
272
|
return {
|
|
273
|
-
preencode
|
|
273
|
+
preencode(state, m) {
|
|
274
274
|
version = v
|
|
275
275
|
enc.preencode(state, m)
|
|
276
276
|
},
|
|
277
|
-
encode
|
|
277
|
+
encode(state, m) {
|
|
278
278
|
version = v
|
|
279
279
|
enc.encode(state, m)
|
|
280
280
|
},
|
|
281
|
-
decode
|
|
281
|
+
decode(state) {
|
|
282
282
|
version = v
|
|
283
283
|
return enc.decode(state)
|
|
284
284
|
}
|
|
@@ -287,4 +287,13 @@ function getStruct (name, v = VERSION) {
|
|
|
287
287
|
|
|
288
288
|
const resolveStruct = getStruct // compat
|
|
289
289
|
|
|
290
|
-
export {
|
|
290
|
+
export {
|
|
291
|
+
resolveStruct,
|
|
292
|
+
getStruct,
|
|
293
|
+
getEnum,
|
|
294
|
+
getEncoding,
|
|
295
|
+
encode,
|
|
296
|
+
decode,
|
|
297
|
+
setVersion,
|
|
298
|
+
version
|
|
299
|
+
}
|
package/shared/spec/schema.js
CHANGED
|
@@ -7,117 +7,131 @@ const media = schema.namespace('media')
|
|
|
7
7
|
|
|
8
8
|
media.register({
|
|
9
9
|
name: 'dimensions',
|
|
10
|
-
fields: [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
fields: [
|
|
11
|
+
{
|
|
12
|
+
name: 'width',
|
|
13
|
+
type: 'uint',
|
|
14
|
+
required: true
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'height',
|
|
18
|
+
type: 'uint',
|
|
19
|
+
required: true
|
|
20
|
+
}
|
|
21
|
+
]
|
|
20
22
|
})
|
|
21
23
|
|
|
22
24
|
media.register({
|
|
23
25
|
name: 'metadata',
|
|
24
|
-
fields: [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
fields: [
|
|
27
|
+
{
|
|
28
|
+
name: 'mimetype',
|
|
29
|
+
type: 'string'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'dimensions',
|
|
33
|
+
type: '@media/dimensions'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'duration',
|
|
37
|
+
type: 'uint'
|
|
38
|
+
}
|
|
39
|
+
]
|
|
36
40
|
})
|
|
37
41
|
|
|
38
42
|
media.register({
|
|
39
43
|
name: 'file',
|
|
40
|
-
fields: [
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
fields: [
|
|
45
|
+
{
|
|
46
|
+
name: 'metadata',
|
|
47
|
+
type: '@media/metadata'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'inlined',
|
|
51
|
+
type: 'string'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'buffer',
|
|
55
|
+
type: 'buffer'
|
|
56
|
+
}
|
|
57
|
+
]
|
|
52
58
|
})
|
|
53
59
|
|
|
54
60
|
media.register({
|
|
55
61
|
name: 'create-preview-request',
|
|
56
|
-
fields: [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
62
|
+
fields: [
|
|
63
|
+
{
|
|
64
|
+
name: 'path',
|
|
65
|
+
type: 'string',
|
|
66
|
+
required: true
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'mimetype',
|
|
70
|
+
type: 'string'
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'maxWidth',
|
|
74
|
+
type: 'uint'
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'maxHeight',
|
|
78
|
+
type: 'uint'
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'format',
|
|
82
|
+
type: 'string'
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: 'encoding',
|
|
86
|
+
type: 'string'
|
|
87
|
+
}
|
|
88
|
+
]
|
|
81
89
|
})
|
|
82
90
|
|
|
83
91
|
media.register({
|
|
84
92
|
name: 'create-preview-response',
|
|
85
|
-
fields: [
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
fields: [
|
|
94
|
+
{
|
|
95
|
+
name: 'metadata',
|
|
96
|
+
type: '@media/metadata',
|
|
97
|
+
required: true
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'preview',
|
|
101
|
+
type: '@media/file',
|
|
102
|
+
required: true
|
|
103
|
+
}
|
|
104
|
+
]
|
|
95
105
|
})
|
|
96
106
|
|
|
97
107
|
media.register({
|
|
98
108
|
name: 'decode-image-request',
|
|
99
|
-
fields: [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
fields: [
|
|
110
|
+
{
|
|
111
|
+
name: 'path',
|
|
112
|
+
type: 'string'
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
name: 'httpLink',
|
|
116
|
+
type: 'string'
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: 'mimetype',
|
|
120
|
+
type: 'string'
|
|
121
|
+
}
|
|
122
|
+
]
|
|
111
123
|
})
|
|
112
124
|
|
|
113
125
|
media.register({
|
|
114
126
|
name: 'decode-image-response',
|
|
115
|
-
fields: [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
fields: [
|
|
128
|
+
{
|
|
129
|
+
name: 'metadata',
|
|
130
|
+
type: '@media/metadata'
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'data',
|
|
134
|
+
type: 'buffer'
|
|
135
|
+
}
|
|
136
|
+
]
|
|
123
137
|
})
|
package/worker/media.js
CHANGED
|
@@ -10,7 +10,14 @@ const DEFAULT_PREVIEW_FORMAT = 'image/webp'
|
|
|
10
10
|
|
|
11
11
|
const animatableMimetypes = ['image/webp']
|
|
12
12
|
|
|
13
|
-
export async function createPreview
|
|
13
|
+
export async function createPreview({
|
|
14
|
+
path,
|
|
15
|
+
mimetype,
|
|
16
|
+
maxWidth,
|
|
17
|
+
maxHeight,
|
|
18
|
+
format,
|
|
19
|
+
encoding
|
|
20
|
+
}) {
|
|
14
21
|
mimetype = mimetype || getMimeType(path)
|
|
15
22
|
format = format || DEFAULT_PREVIEW_FORMAT
|
|
16
23
|
|
|
@@ -18,7 +25,7 @@ export async function createPreview ({ path, mimetype, maxWidth, maxHeight, form
|
|
|
18
25
|
const rgba = await decodeImageToRGBA(buffer, mimetype)
|
|
19
26
|
const { width, height } = rgba
|
|
20
27
|
|
|
21
|
-
const
|
|
28
|
+
const maybeResizedRGBA = await resizeRGBA(rgba, maxWidth, maxHeight)
|
|
22
29
|
|
|
23
30
|
const encoded = await encodeImageFromRGBA(maybeResizedRGBA, format, encoding)
|
|
24
31
|
|
|
@@ -27,13 +34,19 @@ export async function createPreview ({ path, mimetype, maxWidth, maxHeight, form
|
|
|
27
34
|
dimensions: { width, height }
|
|
28
35
|
},
|
|
29
36
|
preview: {
|
|
30
|
-
metadata: {
|
|
37
|
+
metadata: {
|
|
38
|
+
mimetype: format,
|
|
39
|
+
dimensions: {
|
|
40
|
+
width: maybeResizedRGBA.width,
|
|
41
|
+
height: maybeResizedRGBA.height
|
|
42
|
+
}
|
|
43
|
+
},
|
|
31
44
|
...encoded
|
|
32
45
|
}
|
|
33
46
|
}
|
|
34
47
|
}
|
|
35
48
|
|
|
36
|
-
export async function decodeImage
|
|
49
|
+
export async function decodeImage({ path, httpLink, mimetype }) {
|
|
37
50
|
let buffer
|
|
38
51
|
|
|
39
52
|
if (path) {
|
|
@@ -54,15 +67,18 @@ export async function decodeImage ({ path, httpLink, mimetype }) {
|
|
|
54
67
|
}
|
|
55
68
|
}
|
|
56
69
|
|
|
57
|
-
async function decodeImageToRGBA
|
|
70
|
+
async function decodeImageToRGBA(buffer, mimetype) {
|
|
58
71
|
let rgba
|
|
59
72
|
|
|
60
73
|
const codec = await importCodec(mimetype)
|
|
61
74
|
|
|
62
75
|
if (animatableMimetypes.includes(mimetype)) {
|
|
63
|
-
const {
|
|
64
|
-
const
|
|
65
|
-
|
|
76
|
+
const { width, height, loops, frames } = codec.decodeAnimated(buffer)
|
|
77
|
+
const data = []
|
|
78
|
+
for (const frame of frames) {
|
|
79
|
+
data.push(frame)
|
|
80
|
+
}
|
|
81
|
+
rgba = { width, height, loops, frames: data }
|
|
66
82
|
} else {
|
|
67
83
|
rgba = codec.decode(buffer)
|
|
68
84
|
}
|
|
@@ -70,26 +86,52 @@ async function decodeImageToRGBA (buffer, mimetype) {
|
|
|
70
86
|
return rgba
|
|
71
87
|
}
|
|
72
88
|
|
|
73
|
-
async function encodeImageFromRGBA
|
|
89
|
+
async function encodeImageFromRGBA(rgba, format, encoding) {
|
|
74
90
|
const codec = await importCodec(format)
|
|
75
|
-
|
|
91
|
+
|
|
92
|
+
let encoded
|
|
93
|
+
if (Array.isArray(rgba.frames)) {
|
|
94
|
+
encoded = codec.encodeAnimated(rgba)
|
|
95
|
+
} else {
|
|
96
|
+
encoded = codec.encode(rgba)
|
|
97
|
+
}
|
|
76
98
|
|
|
77
99
|
return encoding === 'base64'
|
|
78
100
|
? { inlined: b4a.toString(encoded, 'base64') }
|
|
79
101
|
: { buffer: encoded }
|
|
80
102
|
}
|
|
81
103
|
|
|
82
|
-
async function resizeRGBA
|
|
83
|
-
|
|
104
|
+
async function resizeRGBA(rgba, maxWidth, maxHeight) {
|
|
105
|
+
const { width, height } = rgba
|
|
106
|
+
|
|
107
|
+
let maybeResizedRGBA
|
|
84
108
|
|
|
85
109
|
if (maxWidth && maxHeight && (width > maxWidth || height > maxHeight)) {
|
|
86
110
|
const { resize } = await import('bare-image-resample')
|
|
87
|
-
dimensions = calculateFitDimensions(
|
|
88
|
-
|
|
111
|
+
const dimensions = calculateFitDimensions(
|
|
112
|
+
width,
|
|
113
|
+
height,
|
|
114
|
+
maxWidth,
|
|
115
|
+
maxHeight
|
|
116
|
+
)
|
|
117
|
+
if (Array.isArray(rgba.frames)) {
|
|
118
|
+
const frames = []
|
|
119
|
+
for (const frame of rgba.frames) {
|
|
120
|
+
const resized = resize(frame, dimensions.width, dimensions.height)
|
|
121
|
+
frames.push({ ...resized, timestamp: frame.timestamp })
|
|
122
|
+
}
|
|
123
|
+
maybeResizedRGBA = {
|
|
124
|
+
width: frames[0].width,
|
|
125
|
+
height: frames[0].height,
|
|
126
|
+
loops: rgba.loops,
|
|
127
|
+
frames
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
maybeResizedRGBA = resize(rgba, dimensions.width, dimensions.height)
|
|
131
|
+
}
|
|
89
132
|
} else {
|
|
90
|
-
dimensions = { width, height }
|
|
91
133
|
maybeResizedRGBA = rgba
|
|
92
134
|
}
|
|
93
135
|
|
|
94
|
-
return
|
|
136
|
+
return maybeResizedRGBA
|
|
95
137
|
}
|
package/worker/util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const log = (...args) => console.log('[bare-media]', ...args)
|
|
2
2
|
|
|
3
|
-
export function calculateFitDimensions
|
|
3
|
+
export function calculateFitDimensions(width, height, maxWidth, maxHeight) {
|
|
4
4
|
if (width <= maxWidth && height <= maxHeight) {
|
|
5
5
|
return { width, height }
|
|
6
6
|
}
|