diff --git a/src/utils.js b/src/utils.js index a2cd09f..61d55bb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -52,6 +52,55 @@ export function parseFfprobeFrameRate(frameRate) { return Number.isFinite(parsedValue) && parsedValue > 0 ? parsedValue : 0; } +/** + * Parses ImageMagick %[b] / %b file-size output into bytes. + * + * ImageMagick can return human-readable values such as "12.3KB"; parseInt() + * would incorrectly report that as 12 bytes. + * + * @param {string|number} size - ImageMagick file-size value + * @returns {number} - Parsed byte count, or 0 for invalid values + */ +export function parseImageMagickFileSize(size) { + if (typeof size === 'number') { + return Number.isFinite(size) && size > 0 ? Math.round(size) : 0; + } + + if (typeof size !== 'string') { + return 0; + } + + const value = size.trim(); + if (!value) { + return 0; + } + + const match = value.match(/^(\d+(?:\.\d+)?)\s*([KMGT]?I?B)?$/i); + if (!match) { + return 0; + } + + const amount = Number(match[1]); + if (!Number.isFinite(amount) || amount < 0) { + return 0; + } + + const unit = (match[2] || 'B').toUpperCase(); + const multipliers = { + B: 1, + KB: 1024, + KIB: 1024, + MB: 1024 ** 2, + MIB: 1024 ** 2, + GB: 1024 ** 3, + GIB: 1024 ** 3, + TB: 1024 ** 4, + TIB: 1024 ** 4 + }; + + return Math.round(amount * (multipliers[unit] || 1)); +} + /** * Gets video metadata using ffprobe * @@ -252,7 +301,7 @@ export async function getImageMetadata(inputPath) { result.format = { filename: inputPath, formatName: format, - size: parseInt(filesize) || 0 + size: parseImageMagickFileSize(filesize) }; // Image metadata diff --git a/test/utils.test.js b/test/utils.test.js index 71e7bb3..823b1ef 100644 --- a/test/utils.test.js +++ b/test/utils.test.js @@ -3,7 +3,7 @@ */ import { expect } from 'chai'; -import { parseFfprobeFrameRate } from '../src/utils.js'; +import { parseFfprobeFrameRate, parseImageMagickFileSize } from '../src/utils.js'; describe('Utils Module', function() { describe('parseFfprobeFrameRate()', function() { @@ -25,4 +25,20 @@ describe('Utils Module', function() { expect(parseFfprobeFrameRate(null)).to.equal(0); }); }); + + describe('parseImageMagickFileSize()', function() { + it('should parse ImageMagick byte and unit-suffixed sizes', function() { + expect(parseImageMagickFileSize('512B')).to.equal(512); + expect(parseImageMagickFileSize('12.5KB')).to.equal(12800); + expect(parseImageMagickFileSize('1.5MB')).to.equal(1572864); + expect(parseImageMagickFileSize('2MiB')).to.equal(2097152); + }); + + it('should reject invalid ImageMagick file-size values', function() { + expect(parseImageMagickFileSize('')).to.equal(0); + expect(parseImageMagickFileSize('abc')).to.equal(0); + expect(parseImageMagickFileSize(null)).to.equal(0); + expect(parseImageMagickFileSize(-1)).to.equal(0); + }); + }); });