byte-codec 0.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +43 -0
  2. package/dist/bytes/crc32-BVCBBYa3.d.cts +4 -0
  3. package/dist/bytes/crc32-BVCBBYa3.d.ts +4 -0
  4. package/dist/bytes/crc32.cjs +21 -0
  5. package/dist/bytes/crc32.js +20 -0
  6. package/dist/bytes/flate-CbSD2OU9.d.cts +12 -0
  7. package/dist/bytes/flate-CbSD2OU9.d.ts +12 -0
  8. package/dist/bytes/flate.cjs +53 -0
  9. package/dist/bytes/flate.js +49 -0
  10. package/dist/bytes/reader-CDx_NmAQ.d.cts +20 -0
  11. package/dist/bytes/reader-CDx_NmAQ.d.ts +20 -0
  12. package/dist/bytes/reader.cjs +60 -0
  13. package/dist/bytes/reader.js +58 -0
  14. package/dist/bytes/writer-B9uaqo-B.d.cts +13 -0
  15. package/dist/bytes/writer-B9uaqo-B.d.ts +13 -0
  16. package/dist/bytes/writer.cjs +37 -0
  17. package/dist/bytes/writer.js +35 -0
  18. package/dist/image/jpeg-info-Dh6D8PRh.d.cts +12 -0
  19. package/dist/image/jpeg-info-Dh6D8PRh.d.ts +12 -0
  20. package/dist/image/jpeg-info.cjs +71 -0
  21. package/dist/image/jpeg-info.js +70 -0
  22. package/dist/image/png-decode-Dvizumot.d.cts +14 -0
  23. package/dist/image/png-decode-Dvizumot.d.ts +14 -0
  24. package/dist/image/png-decode.cjs +181 -0
  25. package/dist/image/png-decode.js +180 -0
  26. package/dist/image/png-encode-C5Jj9gBX.d.ts +9 -0
  27. package/dist/image/png-encode-CpwBOmkg.d.cts +9 -0
  28. package/dist/image/png-encode.cjs +64 -0
  29. package/dist/image/png-encode.js +63 -0
  30. package/dist/image/png-filter-5L1Q0PDF.d.cts +6 -0
  31. package/dist/image/png-filter-5L1Q0PDF.d.ts +6 -0
  32. package/dist/image/png-filter.cjs +95 -0
  33. package/dist/image/png-filter.js +93 -0
  34. package/dist/index-VKR9nd94.d.ts +9 -0
  35. package/dist/index-v-4chATX.d.cts +9 -0
  36. package/dist/index.cjs +23 -0
  37. package/dist/index.js +9 -0
  38. package/package.json +67 -2
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # byte-codec
2
+
3
+ [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/byte-codec) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/byte-codec) [![Release](https://img.shields.io/github/v/release/ExaDev/byte-codec)](https://github.com/ExaDev/byte-codec/releases/latest)
4
+
5
+ > Generic byte-level primitives (ByteWriter, ByteReader, CRC-32, deflate/inflate) and PNG/JPEG image encoding/decoding with zero PDF knowledge — the shared utility package for the documents.js family.
6
+
7
+ Extracted from [pdf-codec](https://github.com/ExaDev/pdf-codec), where these utilities lived as a directory-isolated subgraph under `src/bytes/` + `src/image/` with no PDF imports. Both pdf-codec and documents.js consume them from this neutral home rather than one fetching byte utilities from a backend.
8
+
9
+ ## Getting started
10
+
11
+ Requires Node.js `>=20` and pnpm `11.6.0`.
12
+
13
+ ```sh
14
+ pnpm install
15
+ pnpm build # tsdown -> dist/ (ESM + CJS + .d.ts)
16
+ pnpm test # vitest
17
+ pnpm typecheck # tsc --noEmit
18
+ ```
19
+
20
+ ## What it provides
21
+
22
+ | Module | Exports |
23
+ |---|---|
24
+ | `bytes/writer` | `ByteWriter` (chunked growable byte-output builder), `concatBytes` |
25
+ | `bytes/reader` | `ByteReader` (sequential big/little-endian byte reader), `isAsciiWhitespace` |
26
+ | `bytes/crc32` | `crc32` (IEEE 802.3 / ZIP / PNG polynomial table-driven CRC-32) |
27
+ | `bytes/flate` | `deflate`, `inflate`, `inflateTolerant` (fflate-backed DEFLATE compression/decompression with a safety cap) |
28
+ | `image/png-encode` | `encodePng` (raw RGB/RGBA pixels → PNG bytes) |
29
+ | `image/png-decode` | `decodePng` (PNG bytes → raw pixels), `RawImage` |
30
+ | `image/png-filter` | `filterScanlines`, `unfilterScanlines` (the five PNG scanline filters) |
31
+ | `image/jpeg-info` | `readJpegInfo` (JPEG header reader: dimensions, components, progressive flag — no sample decoding) |
32
+
33
+ ## Install
34
+
35
+ ```sh
36
+ pnpm add byte-codec
37
+ # or
38
+ npm install byte-codec
39
+ ```
40
+
41
+ ## License
42
+
43
+ MIT
@@ -0,0 +1,4 @@
1
+ //#region src/bytes/crc32.d.ts
2
+ declare function crc32(bytes: Uint8Array<ArrayBuffer>): number;
3
+ //#endregion
4
+ export { crc32 };
@@ -0,0 +1,4 @@
1
+ //#region src/bytes/crc32.d.ts
2
+ declare function crc32(bytes: Uint8Array<ArrayBuffer>): number;
3
+ //#endregion
4
+ export { crc32 };
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/bytes/crc32.ts
3
+ const CRC32_POLYNOMIAL = 3988292384;
4
+ const BYTE_VALUES = 256;
5
+ const BITS_PER_BYTE = 8;
6
+ const CRC32_TABLE = (() => {
7
+ const table = new Uint32Array(BYTE_VALUES);
8
+ for (let n = 0; n < BYTE_VALUES; n++) {
9
+ let c = n;
10
+ for (let k = 0; k < BITS_PER_BYTE; k++) c = (c & 1) === 1 ? CRC32_POLYNOMIAL ^ c >>> 1 : c >>> 1;
11
+ table[n] = c >>> 0;
12
+ }
13
+ return table;
14
+ })();
15
+ function crc32(bytes) {
16
+ let crc = 4294967295;
17
+ for (const byte of bytes) crc = CRC32_TABLE[(crc ^ byte) & 255] ^ crc >>> 8;
18
+ return (crc ^ 4294967295) >>> 0;
19
+ }
20
+ //#endregion
21
+ exports.crc32 = crc32;
@@ -0,0 +1,20 @@
1
+ //#region src/bytes/crc32.ts
2
+ const CRC32_POLYNOMIAL = 3988292384;
3
+ const BYTE_VALUES = 256;
4
+ const BITS_PER_BYTE = 8;
5
+ const CRC32_TABLE = (() => {
6
+ const table = new Uint32Array(BYTE_VALUES);
7
+ for (let n = 0; n < BYTE_VALUES; n++) {
8
+ let c = n;
9
+ for (let k = 0; k < BITS_PER_BYTE; k++) c = (c & 1) === 1 ? CRC32_POLYNOMIAL ^ c >>> 1 : c >>> 1;
10
+ table[n] = c >>> 0;
11
+ }
12
+ return table;
13
+ })();
14
+ function crc32(bytes) {
15
+ let crc = 4294967295;
16
+ for (const byte of bytes) crc = CRC32_TABLE[(crc ^ byte) & 255] ^ crc >>> 8;
17
+ return (crc ^ 4294967295) >>> 0;
18
+ }
19
+ //#endregion
20
+ export { crc32 };
@@ -0,0 +1,12 @@
1
+ //#region src/bytes/flate.d.ts
2
+ declare const MAX_INFLATE_OUTPUT_BYTES: number;
3
+ type DeflateLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
4
+ declare function deflate(data: Uint8Array<ArrayBuffer>, level?: DeflateLevel): Uint8Array<ArrayBuffer>;
5
+ declare function inflate(data: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;
6
+ interface InflateResult {
7
+ readonly bytes: Uint8Array<ArrayBuffer>;
8
+ readonly recovered: boolean;
9
+ }
10
+ declare function inflateTolerant(data: Uint8Array<ArrayBuffer>): InflateResult;
11
+ //#endregion
12
+ export { DeflateLevel, InflateResult, MAX_INFLATE_OUTPUT_BYTES, deflate, inflate, inflateTolerant };
@@ -0,0 +1,12 @@
1
+ //#region src/bytes/flate.d.ts
2
+ declare const MAX_INFLATE_OUTPUT_BYTES: number;
3
+ type DeflateLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
4
+ declare function deflate(data: Uint8Array<ArrayBuffer>, level?: DeflateLevel): Uint8Array<ArrayBuffer>;
5
+ declare function inflate(data: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;
6
+ interface InflateResult {
7
+ readonly bytes: Uint8Array<ArrayBuffer>;
8
+ readonly recovered: boolean;
9
+ }
10
+ declare function inflateTolerant(data: Uint8Array<ArrayBuffer>): InflateResult;
11
+ //#endregion
12
+ export { DeflateLevel, InflateResult, MAX_INFLATE_OUTPUT_BYTES, deflate, inflate, inflateTolerant };
@@ -0,0 +1,53 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_bytes_writer = require("./writer.cjs");
3
+ const require_bytes_reader = require("./reader.cjs");
4
+ let fflate = require("fflate");
5
+ //#region src/bytes/flate.ts
6
+ const MAX_INFLATE_OUTPUT_BYTES = 536870912;
7
+ function deflate(data, level) {
8
+ return (0, fflate.zlibSync)(data, level === void 0 ? void 0 : { level });
9
+ }
10
+ function inflate(data) {
11
+ const out = (0, fflate.unzlibSync)(data);
12
+ if (out.length > 536870912) throw new Error(`inflated output exceeds the ${MAX_INFLATE_OUTPUT_BYTES}-byte limit`);
13
+ return out;
14
+ }
15
+ function inflateTolerant(data) {
16
+ try {
17
+ return {
18
+ bytes: inflate(data),
19
+ recovered: false
20
+ };
21
+ } catch {}
22
+ let offset = 0;
23
+ while (offset < data.length && require_bytes_reader.isAsciiWhitespace(data[offset])) offset++;
24
+ if (offset > 0) try {
25
+ return {
26
+ bytes: inflate(data.subarray(offset)),
27
+ recovered: true
28
+ };
29
+ } catch {}
30
+ try {
31
+ return {
32
+ bytes: (0, fflate.inflateSync)(data),
33
+ recovered: true
34
+ };
35
+ } catch {}
36
+ const chunks = [];
37
+ const unzlib = new fflate.Unzlib((chunk) => {
38
+ chunks.push(chunk);
39
+ });
40
+ try {
41
+ unzlib.push(data, false);
42
+ } catch {}
43
+ if (chunks.length === 0) throw new Error("unable to inflate stream: no data could be recovered");
44
+ return {
45
+ bytes: require_bytes_writer.concatBytes(chunks),
46
+ recovered: true
47
+ };
48
+ }
49
+ //#endregion
50
+ exports.MAX_INFLATE_OUTPUT_BYTES = MAX_INFLATE_OUTPUT_BYTES;
51
+ exports.deflate = deflate;
52
+ exports.inflate = inflate;
53
+ exports.inflateTolerant = inflateTolerant;
@@ -0,0 +1,49 @@
1
+ import { concatBytes } from "./writer.js";
2
+ import { isAsciiWhitespace } from "./reader.js";
3
+ import { Unzlib, inflateSync, unzlibSync, zlibSync } from "fflate";
4
+ //#region src/bytes/flate.ts
5
+ const MAX_INFLATE_OUTPUT_BYTES = 536870912;
6
+ function deflate(data, level) {
7
+ return zlibSync(data, level === void 0 ? void 0 : { level });
8
+ }
9
+ function inflate(data) {
10
+ const out = unzlibSync(data);
11
+ if (out.length > 536870912) throw new Error(`inflated output exceeds the ${MAX_INFLATE_OUTPUT_BYTES}-byte limit`);
12
+ return out;
13
+ }
14
+ function inflateTolerant(data) {
15
+ try {
16
+ return {
17
+ bytes: inflate(data),
18
+ recovered: false
19
+ };
20
+ } catch {}
21
+ let offset = 0;
22
+ while (offset < data.length && isAsciiWhitespace(data[offset])) offset++;
23
+ if (offset > 0) try {
24
+ return {
25
+ bytes: inflate(data.subarray(offset)),
26
+ recovered: true
27
+ };
28
+ } catch {}
29
+ try {
30
+ return {
31
+ bytes: inflateSync(data),
32
+ recovered: true
33
+ };
34
+ } catch {}
35
+ const chunks = [];
36
+ const unzlib = new Unzlib((chunk) => {
37
+ chunks.push(chunk);
38
+ });
39
+ try {
40
+ unzlib.push(data, false);
41
+ } catch {}
42
+ if (chunks.length === 0) throw new Error("unable to inflate stream: no data could be recovered");
43
+ return {
44
+ bytes: concatBytes(chunks),
45
+ recovered: true
46
+ };
47
+ }
48
+ //#endregion
49
+ export { MAX_INFLATE_OUTPUT_BYTES, deflate, inflate, inflateTolerant };
@@ -0,0 +1,20 @@
1
+ //#region src/bytes/reader.d.ts
2
+ declare function isAsciiWhitespace(byte: number | undefined): boolean;
3
+ declare class ByteReader {
4
+ private readonly bytes;
5
+ private position;
6
+ constructor(bytes: Uint8Array<ArrayBuffer>);
7
+ get offset(): number;
8
+ get length(): number;
9
+ atEnd(): boolean;
10
+ peek(aheadBy?: number): number | undefined;
11
+ next(): number | undefined;
12
+ mark(): number;
13
+ reset(mark: number): void;
14
+ seek(offset: number): void;
15
+ slice(start: number, end: number): Uint8Array<ArrayBuffer>;
16
+ skipWhitespace(): void;
17
+ matchKeyword(keyword: string): boolean;
18
+ }
19
+ //#endregion
20
+ export { ByteReader, isAsciiWhitespace };
@@ -0,0 +1,20 @@
1
+ //#region src/bytes/reader.d.ts
2
+ declare function isAsciiWhitespace(byte: number | undefined): boolean;
3
+ declare class ByteReader {
4
+ private readonly bytes;
5
+ private position;
6
+ constructor(bytes: Uint8Array<ArrayBuffer>);
7
+ get offset(): number;
8
+ get length(): number;
9
+ atEnd(): boolean;
10
+ peek(aheadBy?: number): number | undefined;
11
+ next(): number | undefined;
12
+ mark(): number;
13
+ reset(mark: number): void;
14
+ seek(offset: number): void;
15
+ slice(start: number, end: number): Uint8Array<ArrayBuffer>;
16
+ skipWhitespace(): void;
17
+ matchKeyword(keyword: string): boolean;
18
+ }
19
+ //#endregion
20
+ export { ByteReader, isAsciiWhitespace };
@@ -0,0 +1,60 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/bytes/reader.ts
3
+ const ASCII_WHITESPACE_BYTES = /* @__PURE__ */ new Set([
4
+ 0,
5
+ 9,
6
+ 10,
7
+ 12,
8
+ 13,
9
+ 32
10
+ ]);
11
+ function isAsciiWhitespace(byte) {
12
+ return byte !== void 0 && ASCII_WHITESPACE_BYTES.has(byte);
13
+ }
14
+ var ByteReader = class {
15
+ bytes;
16
+ position = 0;
17
+ constructor(bytes) {
18
+ this.bytes = bytes;
19
+ }
20
+ get offset() {
21
+ return this.position;
22
+ }
23
+ get length() {
24
+ return this.bytes.length;
25
+ }
26
+ atEnd() {
27
+ return this.position >= this.bytes.length;
28
+ }
29
+ peek(aheadBy = 0) {
30
+ return this.bytes[this.position + aheadBy];
31
+ }
32
+ next() {
33
+ const byte = this.bytes[this.position];
34
+ if (byte !== void 0) this.position++;
35
+ return byte;
36
+ }
37
+ mark() {
38
+ return this.position;
39
+ }
40
+ reset(mark) {
41
+ this.position = mark;
42
+ }
43
+ seek(offset) {
44
+ this.position = offset;
45
+ }
46
+ slice(start, end) {
47
+ return this.bytes.subarray(start, end);
48
+ }
49
+ skipWhitespace() {
50
+ while (isAsciiWhitespace(this.peek())) this.position++;
51
+ }
52
+ matchKeyword(keyword) {
53
+ for (let i = 0; i < keyword.length; i++) if (this.peek(i) !== keyword.charCodeAt(i)) return false;
54
+ this.position += keyword.length;
55
+ return true;
56
+ }
57
+ };
58
+ //#endregion
59
+ exports.ByteReader = ByteReader;
60
+ exports.isAsciiWhitespace = isAsciiWhitespace;
@@ -0,0 +1,58 @@
1
+ //#region src/bytes/reader.ts
2
+ const ASCII_WHITESPACE_BYTES = /* @__PURE__ */ new Set([
3
+ 0,
4
+ 9,
5
+ 10,
6
+ 12,
7
+ 13,
8
+ 32
9
+ ]);
10
+ function isAsciiWhitespace(byte) {
11
+ return byte !== void 0 && ASCII_WHITESPACE_BYTES.has(byte);
12
+ }
13
+ var ByteReader = class {
14
+ bytes;
15
+ position = 0;
16
+ constructor(bytes) {
17
+ this.bytes = bytes;
18
+ }
19
+ get offset() {
20
+ return this.position;
21
+ }
22
+ get length() {
23
+ return this.bytes.length;
24
+ }
25
+ atEnd() {
26
+ return this.position >= this.bytes.length;
27
+ }
28
+ peek(aheadBy = 0) {
29
+ return this.bytes[this.position + aheadBy];
30
+ }
31
+ next() {
32
+ const byte = this.bytes[this.position];
33
+ if (byte !== void 0) this.position++;
34
+ return byte;
35
+ }
36
+ mark() {
37
+ return this.position;
38
+ }
39
+ reset(mark) {
40
+ this.position = mark;
41
+ }
42
+ seek(offset) {
43
+ this.position = offset;
44
+ }
45
+ slice(start, end) {
46
+ return this.bytes.subarray(start, end);
47
+ }
48
+ skipWhitespace() {
49
+ while (isAsciiWhitespace(this.peek())) this.position++;
50
+ }
51
+ matchKeyword(keyword) {
52
+ for (let i = 0; i < keyword.length; i++) if (this.peek(i) !== keyword.charCodeAt(i)) return false;
53
+ this.position += keyword.length;
54
+ return true;
55
+ }
56
+ };
57
+ //#endregion
58
+ export { ByteReader, isAsciiWhitespace };
@@ -0,0 +1,13 @@
1
+ //#region src/bytes/writer.d.ts
2
+ declare class ByteWriter {
3
+ private readonly chunks;
4
+ private byteLength;
5
+ get length(): number;
6
+ writeBytes(bytes: Uint8Array<ArrayBuffer>): void;
7
+ writeByte(byte: number): void;
8
+ writeAscii(text: string): void;
9
+ toBytes(): Uint8Array<ArrayBuffer>;
10
+ }
11
+ declare function concatBytes(chunks: readonly Uint8Array<ArrayBuffer>[]): Uint8Array<ArrayBuffer>;
12
+ //#endregion
13
+ export { ByteWriter, concatBytes };
@@ -0,0 +1,13 @@
1
+ //#region src/bytes/writer.d.ts
2
+ declare class ByteWriter {
3
+ private readonly chunks;
4
+ private byteLength;
5
+ get length(): number;
6
+ writeBytes(bytes: Uint8Array<ArrayBuffer>): void;
7
+ writeByte(byte: number): void;
8
+ writeAscii(text: string): void;
9
+ toBytes(): Uint8Array<ArrayBuffer>;
10
+ }
11
+ declare function concatBytes(chunks: readonly Uint8Array<ArrayBuffer>[]): Uint8Array<ArrayBuffer>;
12
+ //#endregion
13
+ export { ByteWriter, concatBytes };
@@ -0,0 +1,37 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/bytes/writer.ts
3
+ var ByteWriter = class {
4
+ chunks = [];
5
+ byteLength = 0;
6
+ get length() {
7
+ return this.byteLength;
8
+ }
9
+ writeBytes(bytes) {
10
+ if (bytes.length === 0) return;
11
+ this.chunks.push(bytes);
12
+ this.byteLength += bytes.length;
13
+ }
14
+ writeByte(byte) {
15
+ this.writeBytes(new Uint8Array([byte]));
16
+ }
17
+ writeAscii(text) {
18
+ this.writeBytes(new TextEncoder().encode(text));
19
+ }
20
+ toBytes() {
21
+ const out = new Uint8Array(this.byteLength);
22
+ let offset = 0;
23
+ for (const chunk of this.chunks) {
24
+ out.set(chunk, offset);
25
+ offset += chunk.length;
26
+ }
27
+ return out;
28
+ }
29
+ };
30
+ function concatBytes(chunks) {
31
+ const writer = new ByteWriter();
32
+ for (const chunk of chunks) writer.writeBytes(chunk);
33
+ return writer.toBytes();
34
+ }
35
+ //#endregion
36
+ exports.ByteWriter = ByteWriter;
37
+ exports.concatBytes = concatBytes;
@@ -0,0 +1,35 @@
1
+ //#region src/bytes/writer.ts
2
+ var ByteWriter = class {
3
+ chunks = [];
4
+ byteLength = 0;
5
+ get length() {
6
+ return this.byteLength;
7
+ }
8
+ writeBytes(bytes) {
9
+ if (bytes.length === 0) return;
10
+ this.chunks.push(bytes);
11
+ this.byteLength += bytes.length;
12
+ }
13
+ writeByte(byte) {
14
+ this.writeBytes(new Uint8Array([byte]));
15
+ }
16
+ writeAscii(text) {
17
+ this.writeBytes(new TextEncoder().encode(text));
18
+ }
19
+ toBytes() {
20
+ const out = new Uint8Array(this.byteLength);
21
+ let offset = 0;
22
+ for (const chunk of this.chunks) {
23
+ out.set(chunk, offset);
24
+ offset += chunk.length;
25
+ }
26
+ return out;
27
+ }
28
+ };
29
+ function concatBytes(chunks) {
30
+ const writer = new ByteWriter();
31
+ for (const chunk of chunks) writer.writeBytes(chunk);
32
+ return writer.toBytes();
33
+ }
34
+ //#endregion
35
+ export { ByteWriter, concatBytes };
@@ -0,0 +1,12 @@
1
+ //#region src/image/jpeg-info.d.ts
2
+ interface JpegInfo {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ readonly components: number;
6
+ readonly precision: number;
7
+ readonly progressive: boolean;
8
+ readonly adobeTransform: number | undefined;
9
+ }
10
+ declare function readJpegInfo(bytes: Uint8Array<ArrayBuffer>): JpegInfo;
11
+ //#endregion
12
+ export { JpegInfo, readJpegInfo };
@@ -0,0 +1,12 @@
1
+ //#region src/image/jpeg-info.d.ts
2
+ interface JpegInfo {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ readonly components: number;
6
+ readonly precision: number;
7
+ readonly progressive: boolean;
8
+ readonly adobeTransform: number | undefined;
9
+ }
10
+ declare function readJpegInfo(bytes: Uint8Array<ArrayBuffer>): JpegInfo;
11
+ //#endregion
12
+ export { JpegInfo, readJpegInfo };
@@ -0,0 +1,71 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/image/jpeg-info.ts
3
+ const SOI = 216;
4
+ const EOI = 217;
5
+ const APP14 = 238;
6
+ const SOF_MARKERS = /* @__PURE__ */ new Set([
7
+ 192,
8
+ 193,
9
+ 194,
10
+ 201,
11
+ 202
12
+ ]);
13
+ const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([194, 202]);
14
+ const NO_PAYLOAD_MARKERS = /* @__PURE__ */ new Set([
15
+ 1,
16
+ 216,
17
+ 217,
18
+ 208,
19
+ 209,
20
+ 210,
21
+ 211,
22
+ 212,
23
+ 213,
24
+ 214,
25
+ 215
26
+ ]);
27
+ function requireByte(bytes, index) {
28
+ const value = bytes[index];
29
+ if (value === void 0) throw new Error("unexpected end of JPEG data");
30
+ return value;
31
+ }
32
+ function readUint16BE(bytes, offset) {
33
+ return requireByte(bytes, offset) << 8 | requireByte(bytes, offset + 1);
34
+ }
35
+ function readJpegInfo(bytes) {
36
+ if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
37
+ let offset = 2;
38
+ let adobeTransform;
39
+ while (offset < bytes.length) {
40
+ if (bytes[offset] !== 255) {
41
+ offset++;
42
+ continue;
43
+ }
44
+ let markerOffset = offset + 1;
45
+ while (bytes[markerOffset] === 255) markerOffset++;
46
+ const marker = bytes[markerOffset];
47
+ if (marker === void 0) break;
48
+ offset = markerOffset + 1;
49
+ if (marker === EOI) break;
50
+ if (NO_PAYLOAD_MARKERS.has(marker)) continue;
51
+ const segmentLength = readUint16BE(bytes, offset);
52
+ if (marker === APP14 && segmentLength >= 14) adobeTransform = requireByte(bytes, offset + 2 + 11);
53
+ if (SOF_MARKERS.has(marker)) {
54
+ const p = offset + 2;
55
+ const precision = requireByte(bytes, p);
56
+ const height = readUint16BE(bytes, p + 1);
57
+ return {
58
+ width: readUint16BE(bytes, p + 3),
59
+ height,
60
+ components: requireByte(bytes, p + 5),
61
+ precision,
62
+ progressive: PROGRESSIVE_SOF_MARKERS.has(marker),
63
+ adobeTransform
64
+ };
65
+ }
66
+ offset += segmentLength;
67
+ }
68
+ throw new Error("no SOF marker found in JPEG file");
69
+ }
70
+ //#endregion
71
+ exports.readJpegInfo = readJpegInfo;
@@ -0,0 +1,70 @@
1
+ //#region src/image/jpeg-info.ts
2
+ const SOI = 216;
3
+ const EOI = 217;
4
+ const APP14 = 238;
5
+ const SOF_MARKERS = /* @__PURE__ */ new Set([
6
+ 192,
7
+ 193,
8
+ 194,
9
+ 201,
10
+ 202
11
+ ]);
12
+ const PROGRESSIVE_SOF_MARKERS = /* @__PURE__ */ new Set([194, 202]);
13
+ const NO_PAYLOAD_MARKERS = /* @__PURE__ */ new Set([
14
+ 1,
15
+ 216,
16
+ 217,
17
+ 208,
18
+ 209,
19
+ 210,
20
+ 211,
21
+ 212,
22
+ 213,
23
+ 214,
24
+ 215
25
+ ]);
26
+ function requireByte(bytes, index) {
27
+ const value = bytes[index];
28
+ if (value === void 0) throw new Error("unexpected end of JPEG data");
29
+ return value;
30
+ }
31
+ function readUint16BE(bytes, offset) {
32
+ return requireByte(bytes, offset) << 8 | requireByte(bytes, offset + 1);
33
+ }
34
+ function readJpegInfo(bytes) {
35
+ if (requireByte(bytes, 0) !== 255 || requireByte(bytes, 1) !== SOI) throw new Error("not a valid JPEG file: missing SOI marker");
36
+ let offset = 2;
37
+ let adobeTransform;
38
+ while (offset < bytes.length) {
39
+ if (bytes[offset] !== 255) {
40
+ offset++;
41
+ continue;
42
+ }
43
+ let markerOffset = offset + 1;
44
+ while (bytes[markerOffset] === 255) markerOffset++;
45
+ const marker = bytes[markerOffset];
46
+ if (marker === void 0) break;
47
+ offset = markerOffset + 1;
48
+ if (marker === EOI) break;
49
+ if (NO_PAYLOAD_MARKERS.has(marker)) continue;
50
+ const segmentLength = readUint16BE(bytes, offset);
51
+ if (marker === APP14 && segmentLength >= 14) adobeTransform = requireByte(bytes, offset + 2 + 11);
52
+ if (SOF_MARKERS.has(marker)) {
53
+ const p = offset + 2;
54
+ const precision = requireByte(bytes, p);
55
+ const height = readUint16BE(bytes, p + 1);
56
+ return {
57
+ width: readUint16BE(bytes, p + 3),
58
+ height,
59
+ components: requireByte(bytes, p + 5),
60
+ precision,
61
+ progressive: PROGRESSIVE_SOF_MARKERS.has(marker),
62
+ adobeTransform
63
+ };
64
+ }
65
+ offset += segmentLength;
66
+ }
67
+ throw new Error("no SOF marker found in JPEG file");
68
+ }
69
+ //#endregion
70
+ export { readJpegInfo };
@@ -0,0 +1,14 @@
1
+ //#region src/image/png-decode.d.ts
2
+ interface RawImage {
3
+ readonly width: number;
4
+ readonly height: number;
5
+ readonly channels: 1 | 3;
6
+ readonly data: Uint8Array<ArrayBuffer>;
7
+ readonly alpha?: Uint8Array<ArrayBuffer>;
8
+ }
9
+ interface PngDecodeOptions {
10
+ readonly onWarning?: (message: string) => void;
11
+ }
12
+ declare function decodePng(bytes: Uint8Array<ArrayBuffer>, options?: PngDecodeOptions): RawImage;
13
+ //#endregion
14
+ export { PngDecodeOptions, RawImage, decodePng };