mirror of
https://github.com/foliojs/pdfkit.git
synced 2025-12-08 20:15:54 +00:00
557 lines
13 KiB
JavaScript
557 lines
13 KiB
JavaScript
import PDFDocument from '../../lib/document';
|
|
import PDFReference from '../../lib/reference';
|
|
import PNGImage from '../../lib/image/png';
|
|
import fs from 'fs';
|
|
|
|
describe('PNGImage', () => {
|
|
let document;
|
|
|
|
const createImage = fileName => {
|
|
const img = new PNGImage(fs.readFileSync(fileName), 'I1');
|
|
// noop data manipulation methods
|
|
img.loadIndexedAlphaChannel = () => {
|
|
if (img.image.transparency.indexed) {
|
|
img.alphaChannel = {};
|
|
img.finalize();
|
|
}
|
|
};
|
|
img.splitAlphaChannel = () => {
|
|
if (img.image.hasAlphaChannel) {
|
|
img.alphaChannel = {};
|
|
img.finalize();
|
|
}
|
|
};
|
|
img.decodeData = () => {
|
|
img.finalize();
|
|
};
|
|
const finalizeFn = img.finalize;
|
|
jest.spyOn(img, 'finalize').mockImplementation(() => finalizeFn.call(img));
|
|
img.embed(document);
|
|
return img;
|
|
};
|
|
|
|
beforeEach(() => {
|
|
document = new PDFDocument();
|
|
});
|
|
|
|
test('RGB', () => {
|
|
// ImageWidth = 400
|
|
// ImageHeight = 533
|
|
// BitDepth = 8
|
|
// ColorType = 2 (RGB)
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./examples/images/test2.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 533,
|
|
Length: 397011,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 400,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 3,
|
|
Columns: 400,
|
|
Predictor: 15
|
|
});
|
|
});
|
|
|
|
test('RGB white transparent', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 16
|
|
// ColorType = 2
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage(
|
|
'./tests/images/pngsuite-rgb-transparent-white.png'
|
|
);
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 1932,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
Mask: [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255],
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
Colors: 3,
|
|
Columns: 32,
|
|
Predictor: 15
|
|
});
|
|
});
|
|
|
|
test('RGB (8bit) with Alpha', () => {
|
|
// ImageWidth = 409
|
|
// ImageHeight = 400
|
|
// BitDepth = 8
|
|
// ColorType = 6 (RGB with Alpha)
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./tests/images/bee.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 400,
|
|
Length: 47715,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 409,
|
|
SMask: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.SMask.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Decode: [0, 1],
|
|
Filter: 'FlateDecode',
|
|
Height: 400,
|
|
Length: 16,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 409
|
|
});
|
|
});
|
|
|
|
test('RGB (16bit) with Alpha', () => {
|
|
// ImageWidth = 175
|
|
// ImageHeight = 65
|
|
// BitDepth = 16
|
|
// ColorType = 6
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./tests/images/straight.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 65,
|
|
Length: 28537,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 175,
|
|
SMask: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.SMask.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Decode: [0, 1],
|
|
Filter: 'FlateDecode',
|
|
Height: 65,
|
|
Length: 16,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 175
|
|
});
|
|
});
|
|
|
|
test('Pallete', () => {
|
|
// ImageWidth = 980
|
|
// ImageHeight = 540
|
|
// BitDepth = 8
|
|
// ColorType = 3 (Pallete)
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./examples/images/test3.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: ['Indexed', 'DeviceRGB', 255, expect.any(PDFReference)],
|
|
Filter: 'FlateDecode',
|
|
Height: 540,
|
|
Length: 56682,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 980,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 1,
|
|
Columns: 980,
|
|
Predictor: 15
|
|
});
|
|
});
|
|
|
|
test('Pallete indexed transparency', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 8
|
|
// ColorType = 3
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage(
|
|
'./tests/images/pngsuite-palette-transparent-white.png'
|
|
);
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: ['Indexed', 'DeviceRGB', 244, expect.any(PDFReference)],
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 650,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
DecodeParms: expect.any(PDFReference),
|
|
SMask: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 1,
|
|
Columns: 32,
|
|
Predictor: 15
|
|
});
|
|
|
|
expect(img.obj.data.SMask.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Decode: [0, 1],
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 16,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32
|
|
});
|
|
});
|
|
|
|
test('Grayscale', () => {
|
|
// ImageWidth = 428
|
|
// ImageHeight = 320
|
|
// BitDepth = 8
|
|
// ColorType = 0
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./tests/images/glassware-noisy.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Filter: 'FlateDecode',
|
|
Height: 428,
|
|
Length: 82633,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 320,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
});
|
|
|
|
test('Grayscale black transparent', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 4
|
|
// ColorType = 0
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage(
|
|
'./tests/images/pngsuite-gray-transparent-black.png'
|
|
);
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 4,
|
|
ColorSpace: 'DeviceGray',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 328,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
Mask: [0, 0],
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 4,
|
|
Colors: 1,
|
|
Columns: 32,
|
|
Predictor: 15
|
|
});
|
|
});
|
|
|
|
test('Grayscale white transparent', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 16
|
|
// ColorType = 0
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage(
|
|
'./tests/images/pngsuite-gray-transparent-white.png'
|
|
);
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
ColorSpace: 'DeviceGray',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 1212,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
Mask: [255, 255],
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
Colors: 1,
|
|
Columns: 32,
|
|
Predictor: 15
|
|
});
|
|
});
|
|
|
|
test('Grayscale with Alpha', () => {
|
|
// ImageWidth = 112
|
|
// ImageHeight = 112
|
|
// BitDepth = 8
|
|
// ColorType = 4 (Grayscale with Alpha)
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 0
|
|
|
|
const img = createImage('./tests/images/fish.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Filter: 'FlateDecode',
|
|
Height: 112,
|
|
Length: 9922,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 112,
|
|
SMask: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.SMask.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Decode: [0, 1],
|
|
Filter: 'FlateDecode',
|
|
Height: 112,
|
|
Length: 16,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 112
|
|
});
|
|
});
|
|
|
|
test('Interlaced grayscale', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 8
|
|
// ColorType = 0
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 1
|
|
|
|
const img = createImage('./tests/images/interlaced-grayscale-8bit.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceGray',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 181,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 1,
|
|
Columns: 32,
|
|
Predictor: 1
|
|
});
|
|
});
|
|
|
|
test('Interlaced pallete', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 8
|
|
// ColorType = 3
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 1
|
|
|
|
const img = createImage('./tests/images/interlaced-pallete-8bit.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: ['Indexed', 'DeviceRGB', 255, expect.any(PDFReference)],
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 674,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 1,
|
|
Columns: 32,
|
|
Predictor: 1
|
|
});
|
|
});
|
|
|
|
test('Interlaced RGB (8bit)', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 8
|
|
// ColorType = 2
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 1
|
|
|
|
const img = createImage('./tests/images/interlaced-rgb-8bit.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 242,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
Colors: 3,
|
|
Columns: 32,
|
|
Predictor: 1
|
|
});
|
|
});
|
|
|
|
test('Interlaced RGB (16bit)', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 16
|
|
// ColorType = 2
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 1
|
|
|
|
const img = createImage('./tests/images/interlaced-rgb-16bit.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 522,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
DecodeParms: expect.any(PDFReference)
|
|
});
|
|
|
|
expect(img.obj.data.DecodeParms.data).toMatchObject({
|
|
BitsPerComponent: 16,
|
|
Colors: 3,
|
|
Columns: 32,
|
|
Predictor: 1
|
|
});
|
|
});
|
|
|
|
test('Interlaced RGB with alpha', () => {
|
|
// ImageWidth = 32
|
|
// ImageHeight = 32
|
|
// BitDepth = 8
|
|
// ColorType = 6
|
|
// Compression = 0
|
|
// Filter = 0
|
|
// Interlace = 1
|
|
|
|
const img = createImage('./tests/images/interlaced-rgb-alpha-8bit.png');
|
|
|
|
expect(img.finalize).toBeCalledTimes(1);
|
|
|
|
expect(img.obj.data).toMatchObject({
|
|
BitsPerComponent: 8,
|
|
ColorSpace: 'DeviceRGB',
|
|
Filter: 'FlateDecode',
|
|
Height: 32,
|
|
Length: 288,
|
|
Subtype: 'Image',
|
|
Type: 'XObject',
|
|
Width: 32,
|
|
SMask: expect.any(PDFReference)
|
|
});
|
|
});
|
|
});
|