1
0
Fork 0
mirror of https://github.com/codedread/bitjs synced 2025-10-03 17:49:16 +02:00

PngParser: Handle gAMA chunk

This commit is contained in:
Jeff Schiller 2024-01-16 08:19:58 -08:00
parent b359f92251
commit 1d0abcaee8
3 changed files with 41 additions and 1 deletions

View file

@ -14,12 +14,14 @@ import { ByteStream } from '../../io/bytestream.js';
// https://en.wikipedia.org/wiki/PNG#File_format // https://en.wikipedia.org/wiki/PNG#File_format
// https://www.w3.org/TR/2003/REC-PNG-20031110 // https://www.w3.org/TR/2003/REC-PNG-20031110
// let DEBUG = true;
let DEBUG = false; let DEBUG = false;
const SIG = new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]); const SIG = new Uint8Array([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
/** @enum {string} */ /** @enum {string} */
export const PngParseEventType = { export const PngParseEventType = {
IHDR: 'image_header', IHDR: 'image_header',
gAMA: 'image_gamma',
PLTE: 'palette', PLTE: 'palette',
IDAT: 'image_data', IDAT: 'image_data',
}; };
@ -59,6 +61,15 @@ export class PngImageHeaderEvent extends Event {
} }
} }
export class PngImageGammaEvent extends Event {
/** @param {number} */
constructor(gamma) {
super(PngParseEventType.gAMA);
/** @type {number} */
this.gamma = gamma;
}
}
/** /**
* @typedef PngColor * @typedef PngColor
* @property {number} red * @property {number} red
@ -132,6 +143,16 @@ export class PngParser extends EventTarget {
return this; return this;
} }
/**
* Type-safe way to bind a listener for a PngImageGammaEvent.
* @param {function(PngImageGammaEvent): void} listener
* @returns {PngParser} for chaining
*/
onGamma(listener) {
super.addEventListener(PngParseEventType.gAMA, listener);
return this;
}
/** /**
* Type-safe way to bind a listener for a PngPaletteEvent. * Type-safe way to bind a listener for a PngPaletteEvent.
* @param {function(PngPaletteEvent): void} listener * @param {function(PngPaletteEvent): void} listener
@ -204,6 +225,12 @@ export class PngParser extends EventTarget {
this.dispatchEvent(new PngImageHeaderEvent(header)); this.dispatchEvent(new PngImageHeaderEvent(header));
break; break;
// https://www.w3.org/TR/2003/REC-PNG-20031110/#11gAMA
case 'gAMA':
if (length !== 4) throw `Bad length for gAMA: ${length}`;
this.dispatchEvent(new PngImageGammaEvent(chStream.readNumber(4)));
break;
// https://www.w3.org/TR/2003/REC-PNG-20031110/#11PLTE // https://www.w3.org/TR/2003/REC-PNG-20031110/#11PLTE
case 'PLTE': case 'PLTE':
if (this.colorType === undefined) throw `PLTE before IHDR`; if (this.colorType === undefined) throw `PLTE before IHDR`;
@ -282,8 +309,11 @@ async function main() {
parser.onImageHeader(evt => { parser.onImageHeader(evt => {
// console.dir(evt.imageHeader); // console.dir(evt.imageHeader);
}); });
parser.onGamma(evt => {
// console.dir(evt.imageGamma);
});
parser.onPalette(evt => { parser.onPalette(evt => {
console.dir(evt.palette); // console.dir(evt.palette);
}); });
parser.onImageData(evt => { parser.onImageData(evt => {
// console.dir(evt); // console.dir(evt);

View file

@ -5,6 +5,7 @@ import { PngColorType, PngInterlaceMethod, PngParser } from '../image/parsers/pn
/** @typedef {import('../image/parsers/png.js').PngImageHeader} PngImageHeader */ /** @typedef {import('../image/parsers/png.js').PngImageHeader} PngImageHeader */
/** @typedef {import('../image/parsers/png.js').PngImageData} PngImageData */ /** @typedef {import('../image/parsers/png.js').PngImageData} PngImageData */
/** @typedef {import('../image/parsers/png.js').PngImageGamma} PngImageGamma */
/** @typedef {import('../image/parsers/png.js').PngPalette} PngPalette */ /** @typedef {import('../image/parsers/png.js').PngPalette} PngPalette */
function getPngParser(fileName) { function getPngParser(fileName) {
@ -47,6 +48,15 @@ describe('bitjs.image.parsers.PngParser', () => {
}); });
}); });
it('extracts gAMA', async () => {
/** @type {number} */
let gamma;
await getPngParser('tests/image-testfiles/g05n3p04.png')
.onGamma(evt => gamma = evt.gamma)
.start();
expect(gamma).equals(55000);
});
it('extracts PLTE', async () => { it('extracts PLTE', async () => {
/** @type {PngPalette} */ /** @type {PngPalette} */
let palette; let palette;

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B