'f'
mh-two-thousand-and-two
2024-04-12 26f2711ef9461961fb953e2b497bd314ef95e345
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*jslint browser: true, devel: true, bitwise: false, debug: true, eqeq: false, es5: true, evil: false, forin: false, newcap: false, nomen: true, plusplus: true, regexp: false, unparam: false, sloppy: true, stupid: false, sub: false, todo: true, vars: true, white: true */
 
module.exports = {
    parseSections: function(stream, iterator) {
        var len, markerType;
        stream.setBigEndian(true);
        //stop reading the stream at the SOS (Start of Stream) marker,
        //because its length is not stored in the header so we can't
        //know where to jump to. The only marker after that is just EOI (End Of Image) anyway
        while(stream.remainingLength() > 0 && markerType !== 0xDA) {
            if(stream.nextUInt8() !== 0xFF) {
                throw new Error('Invalid JPEG section offset');
            }
            markerType = stream.nextUInt8();
            //don't read size from markers that have no datas
            if((markerType >= 0xD0 && markerType <= 0xD9) || markerType === 0xDA) {
                len = 0;
            } else {
                len = stream.nextUInt16() - 2;
            }
            iterator(markerType, stream.branch(0, len));
            stream.skip(len);
        }
    },
    //stream should be located after SOF section size and in big endian mode, like passed to parseSections iterator
    getSizeFromSOFSection: function(stream) {
        stream.skip(1);
        return {
            height: stream.nextUInt16(),
            width: stream.nextUInt16()
        };
    },
    getSectionName: function(markerType) {
        var name, index;
        switch(markerType) {
            case 0xD8: name = 'SOI'; break;
            case 0xC4: name = 'DHT'; break;
            case 0xDB: name = 'DQT'; break;
            case 0xDD: name = 'DRI'; break;
            case 0xDA: name = 'SOS'; break;
            case 0xFE: name = 'COM'; break;
            case 0xD9: name = 'EOI'; break;
            default:
                if(markerType >= 0xE0 && markerType <= 0xEF) {
                    name = 'APP';
                    index = markerType - 0xE0;
                }
                else if(markerType >= 0xC0 && markerType <= 0xCF && markerType !== 0xC4 && markerType !== 0xC8 && markerType !== 0xCC) {
                    name = 'SOF';
                    index = markerType - 0xC0;
                }
                else if(markerType >= 0xD0 && markerType <= 0xD7) {
                    name = 'RST';
                    index = markerType - 0xD0;
                }
                break;
        }
        var nameStruct = {
            name: name
        };
        if(typeof index === 'number') {
            nameStruct.index = index;
        }
        return nameStruct;
    }
};