Skip to content

Commit 0607b6b

Browse files
feat: add 1-bit image decoder
1 parent d8daed2 commit 0607b6b

File tree

10 files changed

+717
-9
lines changed

10 files changed

+717
-9
lines changed

src/BMPDecoder.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { IOBuffer } from 'iobuffer';
2+
3+
import type { ImageCodec } from './BMPEncoder';
4+
5+
export default class BMPDecoder {
6+
bufferData: IOBuffer;
7+
pixelDataOffset: number;
8+
width: number;
9+
height: number;
10+
bitDepth: number;
11+
12+
constructor(bufferData: Buffer) {
13+
this.bufferData = new IOBuffer(bufferData);
14+
const formatCheck = this.bufferData.readBytes(2);
15+
if (formatCheck[0] !== 0x42 && formatCheck[1] !== 0x4d) {
16+
throw new Error(
17+
'This is not a BMP image or the encoding is not correct.'
18+
);
19+
}
20+
this.pixelDataOffset = this.bufferData.skip(8).readUint32();
21+
this.width = this.bufferData.skip(4).readUint32();
22+
this.height = this.bufferData.readUint32();
23+
this.bitDepth = this.bufferData.seek(28).readUint16();
24+
if (this.bitDepth !== 1) {
25+
throw new Error('only bitDepth of 1 is supported');
26+
}
27+
}
28+
29+
decode(): ImageCodec {
30+
this.bufferData.seek(this.pixelDataOffset);
31+
const data = new Uint8Array(this.height * this.width * this.bitDepth);
32+
this.bufferData.setBigEndian();
33+
34+
let currentNumber = 0;
35+
36+
for (let row = 0; row < this.height; row++) {
37+
for (let col = 0; col < this.width; col++) {
38+
const bitIndex = col % 32;
39+
if (bitIndex === 0) {
40+
currentNumber = this.bufferData.readUint32();
41+
}
42+
43+
if (currentNumber & (1 << (31 - bitIndex))) {
44+
data[(this.height - row - 1) * this.width + col] = 1;
45+
}
46+
}
47+
}
48+
49+
const channels = Math.ceil(this.bitDepth / 8);
50+
const components = channels % 2 === 0 ? channels - 1 : channels;
51+
return {
52+
width: this.width,
53+
height: this.height,
54+
bitDepth: this.bitDepth,
55+
channels,
56+
components,
57+
data,
58+
};
59+
}
60+
}

src/BMPEncoder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { IOBuffer } from 'iobuffer';
22

33
import { BITMAPV5HEADER } from './constants';
44

5-
export interface DataToEncode {
5+
export interface ImageCodec {
66
/**
77
* Image bit depth.
88
*/
@@ -41,7 +41,7 @@ export default class BMPEncoder extends IOBuffer {
4141
channels: number;
4242
components: number;
4343
encoded: IOBuffer = new IOBuffer();
44-
constructor(data: DataToEncode) {
44+
constructor(data: ImageCodec) {
4545
if (data.bitDepth !== 1) {
4646
throw new Error('Only bitDepth of 1 is supported');
4747
}

0 commit comments

Comments
 (0)