Skip to content

Commit b9cbecb

Browse files
committed
png: IDX support
(cherry picked from commit 9a9a8e7)
1 parent 36e24ba commit b9cbecb

1 file changed

Lines changed: 31 additions & 14 deletions

File tree

‎utils/png.js‎

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ export async function decode(array) {
7373
const width = view.getUint32(16);
7474
const height = view.getUint32(20);
7575
const bpc = array[24];
76-
const channels = ({2: 3, 6: 4, 0: 1, 4: 2})[array[25]];
76+
const pixel_type = array[25];
77+
let channels = ({3: 1, 0: 1, 4: 2, 2: 3, 6: 4})[pixel_type];
7778
const bytespp = channels * bpc / 8;
7879

7980
const row_length = width * bytespp;
@@ -85,13 +86,20 @@ export async function decode(array) {
8586
let c_offset = 33;
8687
const chunks = [];
8788

89+
let palette;
90+
if (array[25] === 3)
91+
palette = new Uint32Array(2 ** bpc);
8892
let type;
8993
while (type !== 1229278788) {
9094
type = view.getUint32(4 + c_offset);
9195

9296
// IDAT
9397
if (type === 1229209940)
9498
chunks.push(array.subarray(8 + c_offset, 8 + c_offset + view.getUint32(c_offset)));
99+
else if (type === 1347179589) {
100+
for (let pxlOffset = 0; pxlOffset < palette.length * 8; pxlOffset += 3)
101+
palette[pxlOffset / 3] = array[8 + c_offset + pxlOffset] << 24 | array[8 + c_offset + pxlOffset + 1] << 16 | array[8 + c_offset + pxlOffset + 2] << 8 | 0xff;
102+
}
95103

96104
c_offset += 4 + 4 + 4 + view.getUint32(c_offset);
97105
}
@@ -111,24 +119,33 @@ export async function decode(array) {
111119
p_offset += row_length;
112120
}
113121

122+
if (channels === 1 && palette) {
123+
channels = 4;
124+
const newPixels = new Uint8Array(width * height * 4);
125+
const pixelView = new DataView(newPixels.buffer, newPixels.byteOffset, newPixels.byteLength);
126+
for (let i = 0; i < pixels.length; i++)
127+
pixelView.setUint32(i * 4, palette[pixels[i]], false);
128+
pixels = newPixels;
129+
}
130+
114131
if (bpc !== 8) {
115-
const newPixels = new Uint8Array(pixels.length / bpc * 8);
116-
for (let i = 0; i < pixels.length; i += 2)
117-
newPixels[i / 2] = pixels[i];
118-
pixels = newPixels;
119-
}
132+
const newPixels = new Uint8Array(pixels.length / bpc * 8);
133+
for (let i = 0; i < pixels.length; i += 2)
134+
newPixels[i / 2] = pixels[i];
135+
pixels = newPixels;
136+
}
120137

121-
if (channels !== 4) {
138+
if (channels !== 4) {
122139
const newPixels = new Uint8Array(width * height * 4);
123140
const view = new DataView(newPixels.buffer);
124141

125-
if (channels === 1) {
126-
for (let i = 0; i < width * height; i++) {
127-
const pixel = pixels[i];
128-
view.setUint32(i * 4, pixel << 24 | pixel << 16 | pixel << 8 | 0xff, false);
129-
}
130-
} else if (channels === 2) {
131-
for (let i = 0; i < width * height * 2; i += 2) {
142+
if (channels === 1) {
143+
for (let i = 0; i < width * height; i++) {
144+
const pixel = pixels[i];
145+
view.setUint32(i * 4, pixel << 24 | pixel << 16 | pixel << 8 | 0xff, false);
146+
}
147+
} else if (channels === 2) {
148+
for (let i = 0; i < width * height * 2; i += 2) {
132149
const pixel = pixels[i];
133150
view.setUint32(i * 2, pixel << 24 | pixel << 16 | pixel << 8 | pixels[i + 1], false);
134151
}

0 commit comments

Comments
 (0)