Skip to content

Commit 1d0abca

Browse files
committed
PngParser: Handle gAMA chunk
1 parent b359f92 commit 1d0abca

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

image/parsers/png.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ import { ByteStream } from '../../io/bytestream.js';
1414
// https://en.wikipedia.org/wiki/PNG#File_format
1515
// https://www.w3.org/TR/2003/REC-PNG-20031110
1616

17+
// let DEBUG = true;
1718
let DEBUG = false;
1819
const SIG = new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
1920

2021
/** @enum {string} */
2122
export const PngParseEventType = {
2223
IHDR: 'image_header',
24+
gAMA: 'image_gamma',
2325
PLTE: 'palette',
2426
IDAT: 'image_data',
2527
};
@@ -59,6 +61,15 @@ export class PngImageHeaderEvent extends Event {
5961
}
6062
}
6163

64+
export class PngImageGammaEvent extends Event {
65+
/** @param {number} */
66+
constructor(gamma) {
67+
super(PngParseEventType.gAMA);
68+
/** @type {number} */
69+
this.gamma = gamma;
70+
}
71+
}
72+
6273
/**
6374
* @typedef PngColor
6475
* @property {number} red
@@ -132,6 +143,16 @@ export class PngParser extends EventTarget {
132143
return this;
133144
}
134145

146+
/**
147+
* Type-safe way to bind a listener for a PngImageGammaEvent.
148+
* @param {function(PngImageGammaEvent): void} listener
149+
* @returns {PngParser} for chaining
150+
*/
151+
onGamma(listener) {
152+
super.addEventListener(PngParseEventType.gAMA, listener);
153+
return this;
154+
}
155+
135156
/**
136157
* Type-safe way to bind a listener for a PngPaletteEvent.
137158
* @param {function(PngPaletteEvent): void} listener
@@ -204,6 +225,12 @@ export class PngParser extends EventTarget {
204225
this.dispatchEvent(new PngImageHeaderEvent(header));
205226
break;
206227

228+
// https://www.w3.org/TR/2003/REC-PNG-20031110/#11gAMA
229+
case 'gAMA':
230+
if (length !== 4) throw `Bad length for gAMA: ${length}`;
231+
this.dispatchEvent(new PngImageGammaEvent(chStream.readNumber(4)));
232+
break;
233+
207234
// https://www.w3.org/TR/2003/REC-PNG-20031110/#11PLTE
208235
case 'PLTE':
209236
if (this.colorType === undefined) throw `PLTE before IHDR`;
@@ -282,8 +309,11 @@ async function main() {
282309
parser.onImageHeader(evt => {
283310
// console.dir(evt.imageHeader);
284311
});
312+
parser.onGamma(evt => {
313+
// console.dir(evt.imageGamma);
314+
});
285315
parser.onPalette(evt => {
286-
console.dir(evt.palette);
316+
// console.dir(evt.palette);
287317
});
288318
parser.onImageData(evt => {
289319
// console.dir(evt);

tests/image-parsers-png.spec.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { PngColorType, PngInterlaceMethod, PngParser } from '../image/parsers/pn
55

66
/** @typedef {import('../image/parsers/png.js').PngImageHeader} PngImageHeader */
77
/** @typedef {import('../image/parsers/png.js').PngImageData} PngImageData */
8+
/** @typedef {import('../image/parsers/png.js').PngImageGamma} PngImageGamma */
89
/** @typedef {import('../image/parsers/png.js').PngPalette} PngPalette */
910

1011
function getPngParser(fileName) {
@@ -47,6 +48,15 @@ describe('bitjs.image.parsers.PngParser', () => {
4748
});
4849
});
4950

51+
it('extracts gAMA', async () => {
52+
/** @type {number} */
53+
let gamma;
54+
await getPngParser('tests/image-testfiles/g05n3p04.png')
55+
.onGamma(evt => gamma = evt.gamma)
56+
.start();
57+
expect(gamma).equals(55000);
58+
});
59+
5060
it('extracts PLTE', async () => {
5161
/** @type {PngPalette} */
5262
let palette;

tests/image-testfiles/g05n3p04.png

206 Bytes
Loading

0 commit comments

Comments
 (0)