UNPKG

pdf-lib

Version:

Library for creating and modifying PDF files in JavaScript

93 lines (92 loc) 3.43 kB
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;