Skip to content

Commit

Permalink
Merge pull request #15 from SidOfc/patch/reduce-system-reads
Browse files Browse the repository at this point in the history
patch/reduce system reads
  • Loading branch information
SidOfc authored Mar 26, 2023
2 parents 50ee59c + 0b27de1 commit 36c6ce1
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 237 deletions.
2 changes: 1 addition & 1 deletion src/extractors/avi.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {lazystream, roundToPrecision} from '../util.js';
import {lazystream} from '../util.js';

export function attributes(input) {
const stream = lazystream(input);
Expand Down
35 changes: 15 additions & 20 deletions src/extractors/fit.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,24 @@ export function attributes(input) {
mime: 'image/fits',
};

let offset = 0;

while (stream.more()) {
const label = stream
.goto(offset * 80)
.takeUntil(0x20)
.toString();

if (label === 'NAXIS1' || label === 'NAXIS2') {
const property = label === 'NAXIS1' ? 'width' : 'height';
result[property] = parseInt(
stream
.goto(offset * 80)
.skip(24)
.take(8)
.toString()
.trim()
);

if (result.width !== 0 && result.height !== 0) break;
const header = stream.take(30);
const label = header.subarray(0, 8);

if (label.includes('NAXIS1')) {
result.width = parseInt(header.subarray(22, 30));
} else if (label.includes('NAXIS2')) {
result.height = parseInt(header.subarray(22, 30));

break;
} else if (
label.includes('NAXIS') &&
parseInt(header.subarray(22, 30)) < 2
) {
break;
}

offset += 1;
stream.skip(50);
}

stream.close();
Expand Down
22 changes: 10 additions & 12 deletions src/extractors/hdr.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,19 @@ export function attributes(input) {
mime: 'image/vnd.radiance',
};

while (stream.more()) {
const line = stream.takeLine().toString();
for (const chunk of stream.overlappingChunks(64)) {
const content = chunk.buffer.toString();
const matches = content.match(/[-+][xy]\s+\d+\s/gi);

if (line.match(/[-+][xy]/i)) {
const parts = line
.split(' ')
.map((part) => part.replace(/[^a-z0-9]/gi, '').toUpperCase());
if (matches?.length === 2) {
for (const match of matches) {
const cleanMatch = match.toLowerCase().trim().slice(1);
const [axis, stringSize] = cleanMatch.split(/\s+/i);

if (parts[0] === 'Y') {
result.width = parseInt(parts[3], 10);
result.height = parseInt(parts[1], 10);
} else {
result.width = parseInt(parts[1], 10);
result.height = parseInt(parts[3], 10);
if (axis === 'x') result.width = parseInt(stringSize);
if (axis === 'y') result.height = parseInt(stringSize);
}

break;
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/extractors/j2c.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import {lazystream} from '../util.js';

export function attributes(input) {
const stream = lazystream(input);
const height = stream.skip(48).takeUInt32BE();
const width = stream.takeUInt32BE();
const dimensions = stream.skip(48).take(8);
const height = dimensions.readUInt32BE();
const width = dimensions.readUInt32BE(4);
const result = {width, height, size: stream.size(), mime: 'image/jp2'};

stream.close();
Expand Down
14 changes: 9 additions & 5 deletions src/extractors/jpg.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ export function attributes(input) {
stream.skip(4);

while (stream.more()) {
const size = stream.takeUInt16BE();
const mark = stream.skip(size - 2).takeUInt8();
const next = stream.takeUInt8();
stream.skip(stream.takeUInt16BE() - 2);

const header = stream.take(2);
const mark = header.readUInt8();
const next = header.readUInt8(1);

if (mark !== 0xff) break;
if (next === 0xc0 || next === 0xc1 || next === 0xc2) {
result.height = stream.skip(3).takeUInt16BE();
result.width = stream.takeUInt16BE();
const dimensions = stream.skip(3).take(4);

result.height = dimensions.readUInt16BE();
result.width = dimensions.readUInt16BE(2);

break;
}
Expand Down
26 changes: 16 additions & 10 deletions src/extractors/mp4.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,25 @@ export function attributes(input) {

function parse(stream, lastTkhd) {
while (stream.more()) {
const initialSize = stream.takeUInt32BE();
const header = stream.take(4).toString();
const size = initialSize === 1 ? stream.takeUInt64BE() : initialSize;

if (['moov', 'mdia', 'trak'].includes(header)) {
const header = stream.take(8);
const initialSize = header.readUInt32BE();
const type = header.subarray(4, 8).toString();
const size =
initialSize === 1
? stream.takeUInt64BE()
: initialSize === 0
? stream.size() - stream.position() + header.length
: initialSize;

if (['moov', 'mdia', 'trak'].includes(type)) {
const result = parse(stream, lastTkhd);

if (result) return result;
} else if (header === 'tkhd') {
lastTkhd = stream.take(size - 8);
} else if (type === 'tkhd') {
lastTkhd = stream.take(size - header.length);

stream.rewind(size - 8);
} else if (header === 'hdlr') {
stream.rewind(size - header.length);
} else if (type === 'hdlr') {
if (stream.skip(8).take(4).includes('vide')) {
return {
width: lastTkhd.readUInt32BE(lastTkhd.length - 8) / 65536,
Expand All @@ -45,7 +51,7 @@ function parse(stream, lastTkhd) {
stream.rewind(12);
}

stream.skip(size - 8);
stream.skip(size - header.length);
}

return {width: 0, height: 0};
Expand Down
35 changes: 11 additions & 24 deletions src/extractors/png.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,21 @@ import {lazystream} from '../util.js';

export function attributes(input) {
const stream = lazystream(input);
const isMNG = stream.take(4).includes('MNG');
const isFried = stream.skip(8).take(4).includes('CgBI');
const header = stream.take(16);

if (isFried) stream.skip(16);
if (header.includes('CgBI')) stream.skip(16);

const result = {
width: stream.takeUInt32BE(),
height: stream.takeUInt32BE(),
size: stream.size(),
mime: isMNG
? 'video/x-mng'
: isAPNG(stream)
? 'image/apng'
: 'image/png',
};
const dimensions = stream.take(8);
const width = dimensions.readUInt32BE();
const height = dimensions.readUInt32BE(4);
const mime = header.includes('MNG')
? 'video/x-mng'
: stream.take(128).includes('acTL')
? 'image/apng'
: 'image/png';
const result = {width, height, size: stream.size(), mime};

stream.close();

return result;
}

function isAPNG(stream) {
const position = stream.position();
const result = [256, 512, 1024].some((size) =>
stream.take(size).includes('acTL')
);

stream.goto(position);

return result;
}
41 changes: 15 additions & 26 deletions src/extractors/pnm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {lazystream} from '../util.js';

const WHITESPACE = [0x20, 0x09, 0x0d, 0x0a];
const MIME_TYPES = {
['PF']: 'application/x-font-type1',
['P1']: 'image/x-portable-bitmap',
Expand All @@ -14,7 +13,7 @@ const MIME_TYPES = {

export function attributes(input) {
const stream = lazystream(input);
const type = stream.take(2).toString();
const type = stream.take(3).toString().trim();
const attrs = type === 'P7' ? pam(stream) : pnm(stream);
const result = {
...attrs,
Expand All @@ -29,43 +28,33 @@ export function attributes(input) {

function pnm(stream) {
while (stream.more()) {
const byte = stream.take()[0];
const line = stream.takeLine().toString();

if (WHITESPACE.includes(byte)) {
continue;
} else if (byte === 0x23) {
stream.skipLine();
} else {
stream.rewind(1);
if (line.match(/^\d+\s+\d+/)) {
const [widthString, heightString] = line.split(/\s+/);

break;
return {
width: parseInt(widthString),
height: parseInt(heightString),
};
}
}

return {
width: parseInt(stream.takeUntil(WHITESPACE).toString(), 10),
height: parseInt(
stream.skipWhile(WHITESPACE).takeUntil(WHITESPACE).toString(),
10
),
};
}

function pam(stream) {
const result = {width: 0, height: 0};

while (stream.more()) {
const key = stream.takeUntil(WHITESPACE).toString();
const [key, stringSize] = stream
.takeLine()
.toString()
.toLowerCase()
.split(/\s+/i);

if (key === 'WIDTH' || key === 'HEIGHT') {
result[key.toLowerCase()] = parseInt(
stream.skipWhile(WHITESPACE).takeUntil(WHITESPACE).toString(),
10
);
if (key === 'width' || key === 'height') {
result[key] = parseInt(stringSize);

if (result.width && result.height) break;
} else {
stream.skipLine();
}
}

Expand Down
Loading

0 comments on commit 36c6ce1

Please sign in to comment.