Skip to content

Commit

Permalink
chore: apply automated fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
autofix-ci[bot] authored Oct 18, 2023
1 parent ba415b3 commit 8dd0714
Show file tree
Hide file tree
Showing 13 changed files with 221 additions and 218 deletions.
8 changes: 4 additions & 4 deletions src/types/bmp.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { IImage } from './interface'
import { toUTF8String, readInt32LE, readUInt32LE } from './utils'
import type { IImage } from "./interface";
import { toUTF8String, readInt32LE, readUInt32LE } from "./utils";

export const BMP: IImage = {
validate: (input) => toUTF8String(input, 0, 2) === 'BM',
validate: (input) => toUTF8String(input, 0, 2) === "BM",

calculate: (input) => ({
height: Math.abs(readInt32LE(input, 22)),
width: readUInt32LE(input, 18),
}),
}
};
22 changes: 12 additions & 10 deletions src/types/cur.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import type { IImage } from './interface'
import { ICO } from './ico'
import { readUInt16LE } from './utils'
import type { IImage } from "./interface";
import { ICO } from "./ico";
import { readUInt16LE } from "./utils";

const TYPE_CURSOR = 2
const TYPE_CURSOR = 2;
export const CUR: IImage = {
validate(input) {
const reserved = readUInt16LE(input, 0)
const imageCount = readUInt16LE(input, 4)
if (reserved !== 0 || imageCount === 0) { return false }
const reserved = readUInt16LE(input, 0);
const imageCount = readUInt16LE(input, 4);
if (reserved !== 0 || imageCount === 0) {
return false;
}

const imageType = readUInt16LE(input, 2)
return imageType === TYPE_CURSOR
const imageType = readUInt16LE(input, 2);
return imageType === TYPE_CURSOR;
},

calculate: (input) => ICO.calculate(input),
}
};
6 changes: 3 additions & 3 deletions src/types/dds.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IImage } from './interface'
import { readUInt32LE } from './utils'
import type { IImage } from "./interface";
import { readUInt32LE } from "./utils";

export const DDS: IImage = {
validate: (input) => readUInt32LE(input, 0) === 0x20_53_44_44,
Expand All @@ -8,4 +8,4 @@ export const DDS: IImage = {
height: readUInt32LE(input, 12),
width: readUInt32LE(input, 16),
}),
}
};
8 changes: 4 additions & 4 deletions src/types/gif.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { IImage } from './interface'
import { toUTF8String, readUInt16LE } from './utils'
import type { IImage } from "./interface";
import { toUTF8String, readUInt16LE } from "./utils";

const gifRegexp = /^GIF8[79]a/
const gifRegexp = /^GIF8[79]a/;
export const GIF: IImage = {
validate: (input) => gifRegexp.test(toUTF8String(input, 0, 6)),

calculate: (input) => ({
height: readUInt16LE(input, 8),
width: readUInt16LE(input, 6),
}),
}
};
97 changes: 49 additions & 48 deletions src/types/jp2.ts
Original file line number Diff line number Diff line change
@@ -1,69 +1,70 @@
import type { IImage, ISize } from './interface'
import { toHexString, toUTF8String, readUInt32BE, readUInt16BE } from './utils'
import type { IImage, ISize } from "./interface";
import { toHexString, toUTF8String, readUInt32BE, readUInt16BE } from "./utils";

const BoxTypes = {
ftyp: '66747970',
ihdr: '69686472',
jp2h: '6a703268',
jp__: '6a502020',
rreq: '72726571',
xml_: '786d6c20',
}
ftyp: "66747970",
ihdr: "69686472",
jp2h: "6a703268",
jp__: "6a502020",
rreq: "72726571",
xml_: "786d6c20",
};

const calculateRREQLength = (box: Uint8Array): number => {
const unit = box[0]
let offset = 1 + 2 * unit
const numStdFlags = readUInt16BE(box, offset)
const flagsLength = numStdFlags * (2 + unit)
offset = offset + 2 + flagsLength
const numVendorFeatures = readUInt16BE(box, offset)
const featuresLength = numVendorFeatures * (16 + unit)
return offset + 2 + featuresLength
}
const unit = box[0];
let offset = 1 + 2 * unit;
const numStdFlags = readUInt16BE(box, offset);
const flagsLength = numStdFlags * (2 + unit);
offset = offset + 2 + flagsLength;
const numVendorFeatures = readUInt16BE(box, offset);
const featuresLength = numVendorFeatures * (16 + unit);
return offset + 2 + featuresLength;
};

const parseIHDR = (box: Uint8Array): ISize => {
return {
height: readUInt32BE(box, 4),
width: readUInt32BE(box, 8),
}
}
};
};

export const JP2: IImage = {
validate(input) {
const signature = toHexString(input, 4, 8)
const signatureLength = readUInt32BE(input, 0)
const signature = toHexString(input, 4, 8);
const signatureLength = readUInt32BE(input, 0);
if (signature !== BoxTypes.jp__ || signatureLength < 1) {
return false
return false;
}

const ftypeBoxStart = signatureLength + 4
const ftypBoxLength = readUInt32BE(input, signatureLength)
const ftypBox = input.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength)
return toHexString(ftypBox, 0, 4) === BoxTypes.ftyp
const ftypeBoxStart = signatureLength + 4;
const ftypBoxLength = readUInt32BE(input, signatureLength);
const ftypBox = input.slice(ftypeBoxStart, ftypeBoxStart + ftypBoxLength);
return toHexString(ftypBox, 0, 4) === BoxTypes.ftyp;
},

calculate(input) {
const signatureLength = readUInt32BE(input, 0)
const ftypBoxLength = readUInt16BE(input, signatureLength + 2)
let offset = signatureLength + 4 + ftypBoxLength
const nextBoxType = toHexString(input, offset, offset + 4)
const signatureLength = readUInt32BE(input, 0);
const ftypBoxLength = readUInt16BE(input, signatureLength + 2);
let offset = signatureLength + 4 + ftypBoxLength;
const nextBoxType = toHexString(input, offset, offset + 4);
switch (nextBoxType) {
case BoxTypes.rreq: {
// WHAT ARE THESE 4 BYTES?????
// eslint-disable-next-line no-case-declarations
const MAGIC = 4
offset =
offset + 4 + MAGIC + calculateRREQLength(input.slice(offset + 4))
return parseIHDR(input.slice(offset + 8, offset + 24))
}
case BoxTypes.jp2h: {
return parseIHDR(input.slice(offset + 8, offset + 24))
}
default: {
throw new TypeError(
'Unsupported header found: ' + toUTF8String(input, offset, offset + 4)
)
}
case BoxTypes.rreq: {
// WHAT ARE THESE 4 BYTES?????
// eslint-disable-next-line no-case-declarations
const MAGIC = 4;
offset =
offset + 4 + MAGIC + calculateRREQLength(input.slice(offset + 4));
return parseIHDR(input.slice(offset + 8, offset + 24));
}
case BoxTypes.jp2h: {
return parseIHDR(input.slice(offset + 8, offset + 24));
}
default: {
throw new TypeError(
"Unsupported header found: " +
toUTF8String(input, offset, offset + 4),
);
}
}
},
}
};
94 changes: 47 additions & 47 deletions src/types/jpg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@
// with a maximum size of 4096 bytes. so if the SOF marker is outside
// if this range we can't detect the file size correctly.

import type { IImage, ISize } from './interface'
import { readUInt, readUInt16BE, toHexString } from './utils'
import type { IImage, ISize } from "./interface";
import { readUInt, readUInt16BE, toHexString } from "./utils";

const EXIF_MARKER = '45786966'
const APP1_DATA_SIZE_BYTES = 2
const EXIF_HEADER_BYTES = 6
const TIFF_BYTE_ALIGN_BYTES = 2
const BIG_ENDIAN_BYTE_ALIGN = '4d4d'
const LITTLE_ENDIAN_BYTE_ALIGN = '4949'
const EXIF_MARKER = "45786966";
const APP1_DATA_SIZE_BYTES = 2;
const EXIF_HEADER_BYTES = 6;
const TIFF_BYTE_ALIGN_BYTES = 2;
const BIG_ENDIAN_BYTE_ALIGN = "4d4d";
const LITTLE_ENDIAN_BYTE_ALIGN = "4949";

// Each entry is exactly 12 bytes
const IDF_ENTRY_BYTES = 12
const NUM_DIRECTORY_ENTRIES_BYTES = 2
const IDF_ENTRY_BYTES = 12;
const NUM_DIRECTORY_ENTRIES_BYTES = 2;

function isEXIF(input: Uint8Array): boolean {
return toHexString(input, 2, 6) === EXIF_MARKER
return toHexString(input, 2, 6) === EXIF_MARKER;
}

function extractSize(input: Uint8Array, index: number): ISize {
return {
height: readUInt16BE(input, index),
width: readUInt16BE(input, index + 2),
}
};
}

function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean) {
Expand All @@ -34,13 +34,13 @@ function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean) {
// let TIFF_IMAGE_FILE_DIRECTORY_BYTES = 4

// TODO: derive from TIFF_IMAGE_FILE_DIRECTORY_BYTES
const idfOffset = 8
const idfOffset = 8;

// IDF osset works from right after the header bytes
// (so the offset includes the tiff byte align)
const offset = EXIF_HEADER_BYTES + idfOffset
const offset = EXIF_HEADER_BYTES + idfOffset;

const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian)
const idfDirectoryEntries = readUInt(exifBlock, 16, offset, isBigEndian);

for (
let directoryEntryNumber = 0;
Expand All @@ -50,110 +50,110 @@ function extractOrientation(exifBlock: Uint8Array, isBigEndian: boolean) {
const start =
offset +
NUM_DIRECTORY_ENTRIES_BYTES +
directoryEntryNumber * IDF_ENTRY_BYTES
const end = start + IDF_ENTRY_BYTES
directoryEntryNumber * IDF_ENTRY_BYTES;
const end = start + IDF_ENTRY_BYTES;

// Skip on corrupt EXIF blocks
if (start > exifBlock.length) {
return
return;
}

const block = exifBlock.slice(start, end)
const tagNumber = readUInt(block, 16, 0, isBigEndian)
const block = exifBlock.slice(start, end);
const tagNumber = readUInt(block, 16, 0, isBigEndian);

// 0x0112 (decimal: 274) is the `orientation` tag ID
if (tagNumber === 274) {
const dataFormat = readUInt(block, 16, 2, isBigEndian)
const dataFormat = readUInt(block, 16, 2, isBigEndian);
if (dataFormat !== 3) {
return
return;
}

// unsinged int has 2 bytes per component
// if there would more than 4 bytes in total it's a pointer
const numberOfComponents = readUInt(block, 32, 4, isBigEndian)
const numberOfComponents = readUInt(block, 32, 4, isBigEndian);
if (numberOfComponents !== 1) {
return
return;
}

return readUInt(block, 16, 8, isBigEndian)
return readUInt(block, 16, 8, isBigEndian);
}
}
}

function validateExifBlock(input: Uint8Array, index: number) {
// Skip APP1 Data Size
const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index)
const exifBlock = input.slice(APP1_DATA_SIZE_BYTES, index);

// Consider byte alignment
const byteAlign = toHexString(
exifBlock,
EXIF_HEADER_BYTES,
EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES
)
EXIF_HEADER_BYTES + TIFF_BYTE_ALIGN_BYTES,
);

// Ignore Empty EXIF. Validate byte alignment
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN
const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN
const isBigEndian = byteAlign === BIG_ENDIAN_BYTE_ALIGN;
const isLittleEndian = byteAlign === LITTLE_ENDIAN_BYTE_ALIGN;

if (isBigEndian || isLittleEndian) {
return extractOrientation(exifBlock, isBigEndian)
return extractOrientation(exifBlock, isBigEndian);
}
}

function validateInput(input: Uint8Array, index: number): void {
// index should be within buffer limits
if (index > input.length) {
throw new TypeError('Corrupt JPG, exceeded buffer limits')
throw new TypeError("Corrupt JPG, exceeded buffer limits");
}
// Every JPEG block must begin with a 0xFF
if (input[index] !== 0xff) {
throw new TypeError('Invalid JPG, marker table corrupted')
throw new TypeError("Invalid JPG, marker table corrupted");
}
}

export const JPG: IImage = {
validate: (input) => toHexString(input, 0, 2) === 'ffd8',
validate: (input) => toHexString(input, 0, 2) === "ffd8",

calculate(input) {
// Skip 4 chars, they are for signature
input = input.slice(4)
input = input.slice(4);

let orientation: number | undefined
let next: number
let orientation: number | undefined;
let next: number;
while (input.length > 0) {
// read length of the next block
const i = readUInt16BE(input, 0)
const i = readUInt16BE(input, 0);

if (isEXIF(input)) {
orientation = validateExifBlock(input, i)
orientation = validateExifBlock(input, i);
}

// ensure correct format
validateInput(input, i)
validateInput(input, i);

// 0xFFC0 is baseline standard(SOF)
// 0xFFC1 is baseline optimized(SOF)
// 0xFFC2 is progressive(SOF2)
next = input[i + 1]
next = input[i + 1];
if (next === 0xc0 || next === 0xc1 || next === 0xc2) {
const size = extractSize(input, i + 5)
const size = extractSize(input, i + 5);

// TODO: is orientation=0 a valid answer here?
if (!orientation) {
return size
return size;
}

return {
height: size.height,
orientation,
width: size.width,
}
};
}

// move to the next block
input = input.slice(i + 2)
input = input.slice(i + 2);
}

throw new TypeError('Invalid JPG, no size found')
throw new TypeError("Invalid JPG, no size found");
},
}
};
Loading

0 comments on commit 8dd0714

Please sign in to comment.