mirror of
https://github.com/codedread/bitjs
synced 2025-10-04 10:09:16 +02:00
PngParser: Add support for tIME chunk.
This commit is contained in:
parent
9f5b3a4882
commit
1869cd7bfa
3 changed files with 65 additions and 3 deletions
|
@ -14,7 +14,7 @@ import { ByteStream } from '../../io/bytestream.js';
|
|||
// https://www.w3.org/TR/png-3/
|
||||
// https://en.wikipedia.org/wiki/PNG#File_format
|
||||
|
||||
// TODO: Ancillary chunks eXIf, hIST, pHYs, sPLT, tIME.
|
||||
// TODO: Ancillary chunks eXIf, hIST, pHYs, sPLT.
|
||||
|
||||
// let DEBUG = true;
|
||||
let DEBUG = false;
|
||||
|
@ -34,6 +34,7 @@ export const PngParseEventType = {
|
|||
iTXt: 'intl_text_data',
|
||||
sBIT: 'significant_bits',
|
||||
tEXt: 'textual_data',
|
||||
tIME: 'last_mod_time',
|
||||
tRNS: 'transparency',
|
||||
zTXt: 'compressed_textual_data',
|
||||
};
|
||||
|
@ -242,6 +243,25 @@ export class PngBackgroundColorEvent extends Event {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef PngLastModTime
|
||||
* @property {number} year Four-digit year.
|
||||
* @property {number} month One-based. Value from 1-12.
|
||||
* @property {number} day One-based. Value from 1-31.
|
||||
* @property {number} hour Zero-based. Value from 0-23.
|
||||
* @property {number} minute Zero-based. Value from 0-59.
|
||||
* @property {number} second Zero-based. Value from 0-60 to allow for leap-seconds.
|
||||
*/
|
||||
|
||||
export class PngLastModTimeEvent extends Event {
|
||||
/** @param {PngLastModTime} lastModTime */
|
||||
constructor(lastModTime) {
|
||||
super(PngParseEventType.tIME);
|
||||
/** @type {PngLastModTime} */
|
||||
this.lastModTime = lastModTime;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef PngChunk Internal use only.
|
||||
* @property {number} length
|
||||
|
@ -347,6 +367,16 @@ export class PngParser extends EventTarget {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe way to bind a listener for a PngLastModTime.
|
||||
* @param {function(PngLastModTime): void} listener
|
||||
* @returns {PngParser} for chaining
|
||||
*/
|
||||
onLastModTime(listener) {
|
||||
super.addEventListener(PngParseEventType.tIME, listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type-safe way to bind a listener for a PngPaletteEvent.
|
||||
* @param {function(PngPaletteEvent): void} listener
|
||||
|
@ -553,6 +583,20 @@ export class PngParser extends EventTarget {
|
|||
this.dispatchEvent(new PngTextualDataEvent(textualData));
|
||||
break;
|
||||
|
||||
// https://www.w3.org/TR/png-3/#11tIME
|
||||
case 'tIME':
|
||||
/** @type {PngLastModTime} */
|
||||
const lastModTime = {
|
||||
year: chStream.readNumber(2),
|
||||
month: chStream.readNumber(1),
|
||||
day: chStream.readNumber(1),
|
||||
hour: chStream.readNumber(1),
|
||||
minute: chStream.readNumber(1),
|
||||
second: chStream.readNumber(1),
|
||||
};
|
||||
this.dispatchEvent(new PngLastModTimeEvent(lastModTime));
|
||||
break;
|
||||
|
||||
// https://www.w3.org/TR/png-3/#11tRNS
|
||||
case 'tRNS':
|
||||
if (this.colorType === undefined) throw `tRNS before IHDR`;
|
||||
|
@ -704,7 +748,10 @@ async function main() {
|
|||
});
|
||||
parser.onBackgroundColor(evt => {
|
||||
// console.dir(evt.backgroundColor);
|
||||
})
|
||||
});
|
||||
parser.onLastModTime(evt => {
|
||||
console.dir(evt.lastModTime);
|
||||
});
|
||||
|
||||
try {
|
||||
await parser.start();
|
||||
|
@ -714,4 +761,4 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
// main();
|
||||
// main();
|
||||
|
|
|
@ -10,6 +10,7 @@ import { PngColorType, PngInterlaceMethod, PngParser } from '../image/parsers/pn
|
|||
/** @typedef {import('../image/parsers/png.js').PngImageGamma} PngImageGamma */
|
||||
/** @typedef {import('../image/parsers/png.js').PngImageHeader} PngImageHeader */
|
||||
/** @typedef {import('../image/parsers/png.js').PngIntlTextualData} PngIntlTextualData */
|
||||
/** @typedef {import('../image/parsers/png.js').PngLastModTime} PngLastModTime */
|
||||
/** @typedef {import('../image/parsers/png.js').PngPalette} PngPalette */
|
||||
/** @typedef {import('../image/parsers/png.js').PngSignificantBits} PngSignificantBits */
|
||||
/** @typedef {import('../image/parsers/png.js').PngTextualData} PngTextualData */
|
||||
|
@ -233,4 +234,18 @@ describe('bitjs.image.parsers.PngParser', () => {
|
|||
expect(bc.paletteIndex).equals(245);
|
||||
});
|
||||
});
|
||||
|
||||
it('extracts tIME', async () => {
|
||||
/** @type {PngLastModTime} */
|
||||
let lastModTime;
|
||||
await getPngParser('tests/image-testfiles/cm9n0g04.png')
|
||||
.onLastModTime(evt => { lastModTime = evt.lastModTime })
|
||||
.start();
|
||||
expect(lastModTime.year).equals(1999);
|
||||
expect(lastModTime.month).equals(12);
|
||||
expect(lastModTime.day).equals(31);
|
||||
expect(lastModTime.hour).equals(23);
|
||||
expect(lastModTime.minute).equals(59);
|
||||
expect(lastModTime.second).equals(59);
|
||||
});
|
||||
});
|
||||
|
|
BIN
tests/image-testfiles/cm9n0g04.png
Normal file
BIN
tests/image-testfiles/cm9n0g04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 292 B |
Loading…
Add table
Add a link
Reference in a new issue