mirror of
https://github.com/foliojs/pdfkit.git
synced 2025-12-08 20:15:54 +00:00
84 lines
1.8 KiB
JavaScript
84 lines
1.8 KiB
JavaScript
import exif from 'jpeg-exif';
|
|
|
|
const MARKERS = [
|
|
0xffc0, 0xffc1, 0xffc2, 0xffc3, 0xffc5, 0xffc6, 0xffc7, 0xffc8, 0xffc9,
|
|
0xffca, 0xffcb, 0xffcc, 0xffcd, 0xffce, 0xffcf,
|
|
];
|
|
|
|
const COLOR_SPACE_MAP = {
|
|
1: 'DeviceGray',
|
|
3: 'DeviceRGB',
|
|
4: 'DeviceCMYK',
|
|
};
|
|
|
|
class JPEG {
|
|
constructor(data, label) {
|
|
let marker;
|
|
this.data = data;
|
|
this.label = label;
|
|
if (this.data.readUInt16BE(0) !== 0xffd8) {
|
|
throw 'SOI not found in JPEG';
|
|
}
|
|
|
|
// Parse the EXIF orientation
|
|
this.orientation = exif.fromBuffer(this.data).Orientation || 1;
|
|
|
|
let pos = 2;
|
|
while (pos < this.data.length) {
|
|
marker = this.data.readUInt16BE(pos);
|
|
pos += 2;
|
|
if (MARKERS.includes(marker)) {
|
|
break;
|
|
}
|
|
pos += this.data.readUInt16BE(pos);
|
|
}
|
|
|
|
if (!MARKERS.includes(marker)) {
|
|
throw 'Invalid JPEG.';
|
|
}
|
|
pos += 2;
|
|
|
|
this.bits = this.data[pos++];
|
|
this.height = this.data.readUInt16BE(pos);
|
|
pos += 2;
|
|
|
|
this.width = this.data.readUInt16BE(pos);
|
|
pos += 2;
|
|
|
|
const channels = this.data[pos++];
|
|
this.colorSpace = COLOR_SPACE_MAP[channels];
|
|
|
|
this.obj = null;
|
|
}
|
|
|
|
embed(document) {
|
|
if (this.obj) {
|
|
return;
|
|
}
|
|
|
|
this.obj = document.ref({
|
|
Type: 'XObject',
|
|
Subtype: 'Image',
|
|
BitsPerComponent: this.bits,
|
|
Width: this.width,
|
|
Height: this.height,
|
|
ColorSpace: this.colorSpace,
|
|
Filter: 'DCTDecode',
|
|
});
|
|
|
|
// add extra decode params for CMYK images. By swapping the
|
|
// min and max values from the default, we invert the colors. See
|
|
// section 4.8.4 of the spec.
|
|
if (this.colorSpace === 'DeviceCMYK') {
|
|
this.obj.data['Decode'] = [1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0];
|
|
}
|
|
|
|
this.obj.end(this.data);
|
|
|
|
// free memory
|
|
return (this.data = null);
|
|
}
|
|
}
|
|
|
|
export default JPEG;
|