Completed
Push — master ( 61d444...b3f358 )
by Jan
16s queued 14s
created

src/frames/frame-apic.ts   A

Complexity

Total Complexity 8
Complexity/F 0

Size

Lines of Code 79
Function Count 0

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 62
mnd 8
bc 8
fnc 0
dl 0
loc 79
rs 10
bpm 0
cpm 0
noi 0
c 0
b 0
f 0
1
import fs = require('fs')
2
import { FrameBuilder } from "../FrameBuilder"
3
import { FrameReader } from "../FrameReader"
4
import { APIC_TYPES } from '../definitions/PictureTypes'
5
import { TagConstants } from '../definitions/TagConstants'
6
import * as ID3Util from "../ID3Util"
7
import { isString } from '../util'
8
import { TextEncoding } from '../definitions/Encoding'
9
import type { Data } from "./type"
10
11
export const APIC = {
12
    create: (data: Data) => {
13
        try {
14
            if (data instanceof Buffer) {
15
                data = {
16
                    imageBuffer: Buffer.from(data)
17
                }
18
            } else if (isString(data)) {
19
                data = {
20
                    imageBuffer: fs.readFileSync(data)
21
                }
22
            } else if (!data.imageBuffer) {
23
                return Buffer.alloc(0)
24
            }
25
26
            let mime_type = data.mime
27
28
            if(!mime_type) {
29
                mime_type = ID3Util.getPictureMimeTypeFromBuffer(data.imageBuffer)
30
            }
31
32
            const pictureType = data.type || {}
33
            const pictureTypeId = pictureType.id === undefined
34
                ? TagConstants.AttachedPicture.PictureType.FRONT_COVER
35
                : pictureType.id
36
37
            /*
38
             * Fix a bug in iTunes where the artwork is not recognized when the description is empty using UTF-16.
39
             * Instead, if the description is empty, use encoding 0x00 (ISO-8859-1).
40
             */
41
            const { description = '' } = data
42
            const encoding = description ?
43
                TextEncoding.UTF_16_WITH_BOM : TextEncoding.ISO_8859_1
44
            return new FrameBuilder('APIC')
45
              .appendNumber(encoding, 1)
46
              .appendNullTerminatedValue(mime_type)
47
              .appendNumber(pictureTypeId, 1)
48
              .appendNullTerminatedValue(description, encoding)
49
              .appendValue(data.imageBuffer)
50
              .getBuffer()
51
        } catch(error) {
52
            return null
53
        }
54
    },
55
    read: (buffer: Buffer, version: number) => {
56
        const reader = new FrameReader(buffer, 0)
57
        let mime
58
        if(version === 2) {
59
            mime = reader.consumeStaticValue('string', 3, 0x00)
60
        } else {
61
            mime = reader.consumeNullTerminatedValue('string', 0x00)
62
        }
63
64
        const typeId = reader.consumeStaticValue('number', 1)
65
        const description = reader.consumeNullTerminatedValue('string')
66
        const imageBuffer = reader.consumeStaticValue()
67
68
        return {
69
            mime: mime,
70
            type: {
71
                id: typeId,
72
                name: APIC_TYPES[typeId]
73
            },
74
            description: description,
75
            imageBuffer: imageBuffer
76
        }
77
    }
78
}
79