Completed
Push — master ( 4a50f5...b7cf3e )
by Rafael S.
01:57
created

riff-chunks.js ➔ getSubChunkIndex_   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 16
nc 2
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
nop 2
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.js';
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