Passed
Push — master ( a08cc1...73bea2 )
by Rafael S.
01:53
created

T_IMPORT ➔ riffChunks   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
dl 0
loc 1
rs 10
c 0
b 0
f 0
nop 1
1
/*
2
 * riff-chunks: Read and write the chunks of RIFF and RIFX files.
3
 * https://github.com/rochars/riff-chunks
4
 *
5
 * Copyright (c) 2017-2018 Rafael da Silva Rocha.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining
8
 * a copy of this software and associated documentation files (the
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sublicense, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 */
27
28
/**
29
 * @fileoverview The riff-chunks API.
30
 */
31
32
/** @module riffChunks */
33
34
import {unpackFrom, unpackString} from 'byte-data';
35
36
/** @private */
37
const uInt32_ = {'bits': 32};
38
/** @type {number} */
39
let head_ = 0;
40
41
/**
42
 * Return the chunks in a RIFF/RIFX file.
43
 * @param {!Uint8Array} buffer The file bytes.
44
 * @return {!Object} The RIFF chunks.
45
 */
46
export default function riffChunks(buffer) {
47
    head_ = 0;
48
    let chunkId = getChunkId_(buffer, 0);
49
    uInt32_['be'] = chunkId == 'RIFX';
50
    let format = unpackString(buffer, 8, 4);
51
    head_ += 4;
52
    return {
53
        'chunkId': chunkId,
54
        'chunkSize': getChunkSize_(buffer, 0),
55
        'format': format,
56
        'subChunks': getSubChunksIndex_(buffer)
57
    };
58
}
59
60
/**
61
 * Return the sub chunks of a RIFF file.
62
 * @param {!Uint8Array} buffer the RIFF file bytes.
63
 * @return {!Array<Object>} The subchunks of a RIFF/RIFX or LIST chunk.
64
 * @private
65
 */
66
function getSubChunksIndex_(buffer) {
67
    let chunks = [];
68
    let i = head_;
69
    while(i <= buffer.length - 8) {
70
        chunks.push(getSubChunkIndex_(buffer, i));
71
        i += 8 + chunks[chunks.length - 1]['chunkSize'];
72
        i = i % 2 ? i + 1 : i;
73
    }
74
    return chunks;
75
}
76
77
/**
78
 * Return a sub chunk from a RIFF file.
79
 * @param {!Uint8Array} buffer the RIFF file bytes.
80
 * @param {number} index The start index of the chunk.
81
 * @return {!Object} A subchunk of a RIFF/RIFX or LIST chunk.
82
 * @private
83
 */
84
function getSubChunkIndex_(buffer, index) {
85
    let chunk = {
86
        'chunkId': getChunkId_(buffer, index),
87
        'chunkSize': getChunkSize_(buffer, index),
88
    };
89
    if (chunk['chunkId'] == 'LIST') {
90
        chunk['format'] = unpackString(buffer, index + 8, 4);
91
        head_ += 4;
92
        chunk['subChunks'] = getSubChunksIndex_(buffer);
93
    } else {
94
        let realChunkSize = chunk['chunkSize'] % 2 ?
95
            chunk['chunkSize'] + 1 : chunk['chunkSize'];
96
        head_ = index + 8 + realChunkSize;
97
        chunk['chunkData'] = {
98
            'start': index + 8,
99
            'end': head_
100
        };
101
    }
102
    return chunk;
103
}
104
105
/**
106
 * Return the fourCC_ of a chunk.
107
 * @param {!Uint8Array} buffer the RIFF file bytes.
108
 * @param {number} index The start index of the chunk.
109
 * @return {string} The id of the chunk.
110
 * @private
111
 */
112
function getChunkId_(buffer, index) {
113
    head_ += 4;
114
    return unpackString(buffer, index, 4);
115
}
116
117
/**
118
 * Return the size of a chunk.
119
 * @param {!Uint8Array} buffer the RIFF file bytes.
120
 * @param {number} index The start index of the chunk.
121
 * @return {number} The size of the chunk without the id and size fields.
122
 * @private
123
 */
124
function getChunkSize_(buffer, index) {
125
    head_ += 4;
126
    return unpackFrom(buffer, uInt32_, index + 4);
127
}
128