Comparing version 1.0.0 to 2.0.0
74
index.js
@@ -10,3 +10,4 @@ 'use strict'; | ||
0x04000000: '4.0', | ||
0x04200000: '4.2' | ||
0x04200000: '4.2', | ||
0x04300000: '4.3' | ||
}; | ||
@@ -23,23 +24,23 @@ | ||
// Device | ||
'scnr': 'Scanner', | ||
'mntr': 'Monitor', | ||
'prtr': 'Printer', | ||
'link': 'Link', | ||
'abst': 'Abstract', | ||
'spac': 'Space', | ||
'nmcl': 'Named color', | ||
scnr: 'Scanner', | ||
mntr: 'Monitor', | ||
prtr: 'Printer', | ||
link: 'Link', | ||
abst: 'Abstract', | ||
spac: 'Space', | ||
nmcl: 'Named color', | ||
// Platform | ||
'appl': 'Apple', | ||
'adbe': 'Adobe', | ||
'msft': 'Microsoft', | ||
'sunw': 'Sun Microsystems', | ||
'sgi': 'Silicon Graphics', | ||
'tgnt': 'Taligent' | ||
appl: 'Apple', | ||
adbe: 'Adobe', | ||
msft: 'Microsoft', | ||
sunw: 'Sun Microsystems', | ||
sgi: 'Silicon Graphics', | ||
tgnt: 'Taligent' | ||
}; | ||
const tagMap = { | ||
'desc': 'description', | ||
'cprt': 'copyright', | ||
'dmdd': 'deviceModelDescription', | ||
'vued': 'viewingConditionsDescription' | ||
desc: 'description', | ||
cprt: 'copyright', | ||
dmdd: 'deviceModelDescription', | ||
vued: 'viewingConditionsDescription' | ||
}; | ||
@@ -54,2 +55,13 @@ | ||
const readStringUTF16BE = (buffer, start, end) => { | ||
const data = buffer.slice(start, end); | ||
let value = ''; | ||
for (let i = 0; i < data.length; i += 2) { | ||
value += String.fromCharCode((data[i] * 256) + data[i + 1]); | ||
} | ||
return value; | ||
}; | ||
const invalid = (reason) => new Error(`Invalid ICC profile: ${reason}`); | ||
module.exports.parse = (buffer) => { | ||
@@ -59,3 +71,3 @@ // Verify expected length | ||
if (size !== buffer.length) { | ||
throw new Error('Invalid ICC profile: length mismatch'); | ||
throw invalid('length mismatch'); | ||
} | ||
@@ -65,3 +77,3 @@ // Verify 'acsp' signature | ||
if (signature !== 'acsp') { | ||
throw new Error('Invalid ICC profile: missing signature'); | ||
throw invalid('missing signature'); | ||
} | ||
@@ -97,3 +109,3 @@ // Integer attributes | ||
if (tagOffset > buffer.length) { | ||
throw new Error('Invalid ICC profile: Tag offset out of bounds'); | ||
throw invalid('tag offset out of bounds'); | ||
} | ||
@@ -105,3 +117,3 @@ const tagType = getContentAtOffsetAsString(buffer, tagOffset); | ||
if (tagValueSize > tagSize) { | ||
throw new Error('Invalid ICC profile: Description tag value size out of bounds for ' + tagSignature); | ||
throw invalid(`description tag value size out of bounds for ${tagSignature}`); | ||
} | ||
@@ -114,2 +126,20 @@ profile[tagMap[tagSignature]] = buffer.slice(tagOffset + 12, tagOffset + tagValueSize + 11).toString(); | ||
} | ||
if (tagType === 'mluc' && tagSignature in tagMap) { | ||
// 4 bytes signature, 4 bytes reserved (must be 0), 4 bytes number of names, 4 bytes name record size (must be 12) | ||
const numberOfNames = buffer.readUInt32BE(tagOffset + 8); | ||
const nameRecordSize = buffer.readUInt32BE(tagOffset + 12); | ||
if (nameRecordSize !== 12) { | ||
throw invalid(`mluc name record size must be 12 for tag ${tagSignature}`); | ||
} | ||
if (numberOfNames > 0) { | ||
// Entry: 2 bytes language code, 2 bytes country code, 4 bytes length, 4 bytes offset from start of tag | ||
// const languageCode = buffer.slice(tagOffset + 16, tagOffset + 18).toString(); | ||
// const countryCode = buffer.slice(tagOffset + 18, tagOffset + 20).toString(); | ||
const nameLength = buffer.readUInt32BE(tagOffset + 20); | ||
const nameOffset = buffer.readUInt32BE(tagOffset + 24); | ||
const nameStart = tagOffset + nameOffset; | ||
const nameStop = nameStart + nameLength; | ||
profile[tagMap[tagSignature]] = readStringUTF16BE(buffer, nameStart, nameStop); | ||
} | ||
} | ||
} | ||
@@ -116,0 +146,0 @@ tagHeaderOffset = tagHeaderOffset + 12; |
{ | ||
"name": "icc", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"author": "Lovell Fuller <npm@lovell.info>", | ||
"description": "Parse International Color Consortium (ICC) profiles", | ||
"scripts": { | ||
"test": "semistandard && mocha" | ||
"test": "semistandard && nyc mocha" | ||
}, | ||
@@ -21,8 +21,9 @@ "main": "index.js", | ||
"devDependencies": { | ||
"mocha": "^3.2.0", | ||
"semistandard": "^9.2.1" | ||
"mocha": "^8.0.1", | ||
"nyc": "^15.1.0", | ||
"semistandard": "^14.2.2" | ||
}, | ||
"license": "Apache-2.0", | ||
"engines": { | ||
"node": ">=4" | ||
"node": ">=10" | ||
}, | ||
@@ -33,3 +34,10 @@ "semistandard": { | ||
] | ||
}, | ||
"nyc": { | ||
"check-coverage": true, | ||
"statements": 95, | ||
"branches": 84, | ||
"functions": 100, | ||
"lines": 94 | ||
} | ||
} |
@@ -38,3 +38,3 @@ # icc | ||
Copyright 2015, 2017 Lovell Fuller | ||
Copyright 2015, 2017, 2020 Lovell Fuller | ||
@@ -41,0 +41,0 @@ Licensed under the Apache License, Version 2.0 (the "License"); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18023
131
3
4