pdf-lib
Version:
Library for creating and modifying PDF files in JavaScript
93 lines (92 loc) • 3.43 kB
JavaScript
import { PDFArray, PDFDictionary, PDFName, PDFNumber, PDFRawStream, } from '../../pdf-objects';
import { error } from '../../../utils';
import { isInstance, validate } from '../../../utils/validate';
/** @hidden */
var MARKERS = [
0xffc0,
0xffc1,
0xffc2,
0xffc3,
0xffc5,
0xffc6,
0xffc7,
0xffc8,
0xffc9,
0xffca,
0xffcb,
0xffcc,
0xffcd,
0xffce,
0xffcf,
];
/**
* A note of thanks to the developers of https://github.com/devongovett/pdfkit,
* as this class borrows heavily from:
* https://github.com/devongovett/pdfkit/blob/e71edab0dd4657b5a767804ba86c94c58d01fbca/lib/image/jpeg.coffee
*/
var JPEGXObjectFactory = /** @class */ (function () {
function JPEGXObjectFactory(data) {
var _this = this;
this.embedImageIn = function (document) {
var xObjDict = PDFDictionary.from({
Type: PDFName.from('XObject'),
Subtype: PDFName.from('Image'),
BitsPerComponent: PDFNumber.fromNumber(_this.bits),
Width: PDFNumber.fromNumber(_this.width),
Height: PDFNumber.fromNumber(_this.height),
ColorSpace: PDFName.from(_this.colorSpace),
Filter: PDFName.from('DCTDecode'),
}, document.index);
// 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 === 'DeviceCYMK') {
xObjDict.set('Decode', PDFArray.fromArray([
PDFNumber.fromNumber(1.0),
PDFNumber.fromNumber(0.0),
PDFNumber.fromNumber(1.0),
PDFNumber.fromNumber(0.0),
PDFNumber.fromNumber(1.0),
PDFNumber.fromNumber(0.0),
PDFNumber.fromNumber(1.0),
PDFNumber.fromNumber(0.0),
], document.index));
}
xObjDict.set('Length', PDFNumber.fromNumber(_this.imgData.length));
var xObj = document.register(PDFRawStream.from(xObjDict, _this.imgData));
return xObj;
};
validate(data, isInstance(Uint8Array), '"data" must be a Uint8Array');
this.imgData = data;
var dataView = new DataView(data.buffer);
if (dataView.getUint16(0) !== 0xffd8)
error('SOI not found in JPEG');
var pos = 2;
var marker;
while (pos < dataView.byteLength) {
marker = dataView.getUint16(pos);
pos += 2;
if (MARKERS.includes(marker))
break;
pos += dataView.getUint16(pos);
}
if (!MARKERS.includes(marker))
error('Invalid JPEG');
pos += 2;
this.bits = dataView.getUint8(pos++);
this.height = dataView.getUint16(pos);
pos += 2;
this.width = dataView.getUint16(pos);
pos += 2;
var channelMap = {
1: 'DeviceGray',
3: 'DeviceRGB',
4: 'DeviceCYMK',
};
var channels = dataView.getUint8(pos++);
this.colorSpace = channelMap[channels] || error('Unknown JPEG channel.');
}
JPEGXObjectFactory.for = function (data) { return new JPEGXObjectFactory(data); };
return JPEGXObjectFactory;
}());
export default JPEGXObjectFactory;