mirror of
https://github.com/codedread/bitjs
synced 2025-10-03 01:29:17 +02:00
PngParser: Add support for hIST chunk
This commit is contained in:
parent
aeb5bb2f10
commit
7b1906a91b
3 changed files with 44 additions and 3 deletions
|
@ -2,5 +2,5 @@ General-purpose, event-based parsers for digital images.
|
|||
|
||||
Currently supports GIF, JPEG, and PNG.
|
||||
|
||||
Some nice implementations of Exif parsing for PNG, HEIF, TIFF here:
|
||||
Some nice implementations of Exif parsing for HEIF, TIFF here:
|
||||
https://github.com/MikeKovarik/exifr/tree/master/src/file-parsers
|
|
@ -17,7 +17,7 @@ import { getExifProfile } from './exif.js';
|
|||
// https://www.w3.org/TR/png-3/
|
||||
// https://en.wikipedia.org/wiki/PNG#File_format
|
||||
|
||||
// TODO: Ancillary chunks: hIST, sPLT.
|
||||
// TODO: Ancillary chunks: sPLT.
|
||||
|
||||
// let DEBUG = true;
|
||||
let DEBUG = false;
|
||||
|
@ -35,6 +35,7 @@ export const PngParseEventType = {
|
|||
cHRM: 'chromaticities_white_point',
|
||||
eXIf: 'exif_profile',
|
||||
gAMA: 'image_gamma',
|
||||
hIST: 'histogram',
|
||||
iTXt: 'intl_text_data',
|
||||
pHYs: 'physical_pixel_dims',
|
||||
sBIT: 'significant_bits',
|
||||
|
@ -299,6 +300,20 @@ export class PngExifProfileEvent extends Event {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef PngHistogram
|
||||
* @property {number[]} frequencies The # of frequencies matches the # of palette entries.
|
||||
*/
|
||||
|
||||
export class PngHistogramEvent extends Event {
|
||||
/** @param {PngHistogram} histogram */
|
||||
constructor(histogram) {
|
||||
super(PngParseEventType.hIST);
|
||||
/** @type {PngHistogram} */
|
||||
this.histogram = histogram;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef PngChunk Internal use only.
|
||||
* @property {number} length
|
||||
|
@ -326,7 +341,6 @@ export class PngParser extends EventTarget {
|
|||
*/
|
||||
palette;
|
||||
|
||||
|
||||
/** @param {ArrayBuffer} ab */
|
||||
constructor(ab) {
|
||||
super();
|
||||
|
@ -384,6 +398,16 @@ export class PngParser extends EventTarget {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe way to bind a listener for a PngHistogramEvent.
|
||||
* @param {function(PngHistogramEvent): void} listener
|
||||
* @returns {PngParser} for chaining
|
||||
*/
|
||||
onHistogram(listener) {
|
||||
super.addEventListener(PngParseEventType.hIST, listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe way to bind a listener for a PngImageDataEvent.
|
||||
* @param {function(PngImageDataEvent): void} listener
|
||||
|
@ -746,6 +770,20 @@ export class PngParser extends EventTarget {
|
|||
this.dispatchEvent(new PngExifProfileEvent(exifValueMap));
|
||||
break;
|
||||
|
||||
// https://www.w3.org/TR/png-3/#11hIST
|
||||
case 'hIST':
|
||||
if (!this.palette) throw `hIST before PLTE`;
|
||||
if (length !== this.palette.entries.length * 2) throw `Bad # of hIST frequencies: ${length / 2}`;
|
||||
|
||||
/** @type {PngHistogram} */
|
||||
const hist = { frequencies: [] };
|
||||
for (let f = 0; f < this.palette.entries.length; ++f) {
|
||||
hist.frequencies.push(chStream.readNumber(2));
|
||||
}
|
||||
|
||||
this.dispatchEvent(new PngHistogramEvent(hist));
|
||||
break;
|
||||
|
||||
// https://www.w3.org/TR/png-3/#11IDAT
|
||||
case 'IDAT':
|
||||
/** @type {PngImageData} */
|
||||
|
@ -836,6 +874,9 @@ async function main() {
|
|||
parser.onExifProfile(evt => {
|
||||
// console.dir(evt.exifProfile);
|
||||
});
|
||||
parser.onHistogram(evt => {
|
||||
// console.dir(evt.histogram);
|
||||
});
|
||||
|
||||
try {
|
||||
await parser.start();
|
||||
|
|
BIN
tests/image-testfiles/ch1n3p04.png
Normal file
BIN
tests/image-testfiles/ch1n3p04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 258 B |
Loading…
Add table
Add a link
Reference in a new issue