diff --git a/src/core/lib/FileSignatures.mjs b/src/core/lib/FileSignatures.mjs index 50a5e830..d4e19da9 100644 --- a/src/core/lib/FileSignatures.mjs +++ b/src/core/lib/FileSignatures.mjs @@ -57,7 +57,7 @@ export const FILE_SIGNATURES = { 6: 0x1a, 7: 0x0a }, - extractor: null + extractor: extractPNG }, { name: "WEBP Image", @@ -150,7 +150,7 @@ export const FILE_SIGNATURES = { 16: 0x0, 17: 0x0 }, - extractor: null + extractor: extractBMP }, { name: "JPEG Extended Range image", @@ -1233,3 +1233,55 @@ export function extractZIP(bytes, offset) { return stream.carve(); } + + +/** + * PNG extractor. + * + * @param {Uint8Array} bytes + * @param {number} offset + * @returns {Uint8Array} + */ +export function extractPNG(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Move past signature to first chunk + stream.moveForwardsBy(8); + + let chunkSize = 0, + chunkType = ""; + + while (chunkType !== "IEND") { + chunkSize = stream.readInt(4, "be"); + chunkType = stream.readString(4); + + // Chunk data size + CRC checksum + stream.moveForwardsBy(chunkSize + 4); + } + + + return stream.carve(); +} + + +/** + * BMP extractor. + * + * @param {Uint8Array} bytes + * @param {number} offset + * @returns {Uint8Array} + */ +export function extractBMP(bytes, offset) { + const stream = new Stream(bytes.slice(offset)); + + // Move past header + stream.moveForwardsBy(2); + + // Read full file size + const bmpSize = stream.readInt(4, "le"); + + // Move to end of file (file size minus header and size field) + stream.moveForwardsBy(bmpSize - 6); + + return stream.carve(); +}