|
1 | 1 | /** @preserve
|
2 |
| - * jsPDF addImage plugin (JPEG only at this time) |
| 2 | + * jsPDF addImage plugin |
3 | 3 | * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
|
4 | 4 | * 2013 Chris Dowling, https://github.com/gingerchris
|
5 | 5 | * 2013 Trinh Ho, https://github.com/ineedfat
|
|
47 | 47 | out('/Subtype /Image')
|
48 | 48 | out('/Width ' + img['w'])
|
49 | 49 | out('/Height ' + img['h'])
|
50 |
| - if (img['cs'] === 'Indexed') { |
| 50 | + if (img['cs'] === this.color_spaces.INDEXED) { |
51 | 51 | out('/ColorSpace [/Indexed /DeviceRGB '
|
52 |
| - + (img['pal'].length / 3 - 1) + ' ' + (objectNumber + 1) |
| 52 | + // if an indexed png defines more than one colour with transparency, we've created a smask |
| 53 | + + (img['pal'].length / 3 - 1) + ' ' + ('smask' in img ? objectNumber + 2 : objectNumber + 1) |
53 | 54 | + ' 0 R]');
|
54 | 55 | } else {
|
55 | 56 | out('/ColorSpace /' + img['cs']);
|
56 |
| - if (img['cs'] === 'DeviceCMYK') { |
| 57 | + if (img['cs'] === this.color_spaces.DEVICE_CMYK) { |
57 | 58 | out('/Decode [1 0 1 0 1 0 1 0]');
|
58 | 59 | }
|
59 | 60 | }
|
|
65 | 66 | out('/DecodeParms <<' + img['dp'] + '>>');
|
66 | 67 | }
|
67 | 68 | if ('trns' in img && img['trns'].constructor == Array) {
|
68 |
| - var trns = ''; |
69 |
| - for ( var i = 0; i < img['trns'].length; i++) |
| 69 | + var trns = '', |
| 70 | + i = 0, |
| 71 | + len = img['trns'].length; |
| 72 | + for (; i < len; i++) |
70 | 73 | trns += (img['trns'][i] + ' ' + img['trns'][i] + ' ');
|
71 | 74 | out('/Mask [' + trns + ']');
|
72 | 75 | }
|
|
81 | 84 |
|
82 | 85 | // Soft mask
|
83 | 86 | if ('smask' in img) {
|
84 |
| - var dp = '/Predictor 15 /Colors 1 /BitsPerComponent 8 /Columns ' + img['w']; |
85 |
| - var smask = {'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': 8, 'dp': dp, 'data': img['smask']}; |
86 |
| - //if ('f' in img) |
87 |
| - //smask.f = img['f']; |
| 87 | + var dp = '/Predictor 15 /Colors 1 /BitsPerComponent ' + img['bpc'] + ' /Columns ' + img['w']; |
| 88 | + var smask = {'w': img['w'], 'h': img['h'], 'cs': 'DeviceGray', 'bpc': img['bpc'], 'dp': dp, 'data': img['smask']}; |
| 89 | + if ('f' in img) |
| 90 | + smask.f = img['f']; |
88 | 91 | putImage.call(this, smask);
|
89 | 92 | }
|
90 | 93 |
|
91 | 94 | //Palette
|
92 |
| - if (img['cs'] === 'Indexed') { |
| 95 | + if (img['cs'] === this.color_spaces.INDEXED) { |
93 | 96 |
|
94 | 97 | this.internal.newObject();
|
95 | 98 | //out('<< /Filter / ' + img['f'] +' /Length ' + img['pal'].length + '>>');
|
|
119 | 122 | )
|
120 | 123 | }
|
121 | 124 | }
|
| 125 | + , checkCompressValue = function(value) { |
| 126 | + if(value && typeof value === 'string') |
| 127 | + value = value.toUpperCase(); |
| 128 | + return value in jsPDFAPI.image_compression ? value : jsPDFAPI.image_compression.NONE; |
| 129 | + } |
122 | 130 | , getImages = function() {
|
123 | 131 | var images = this.internal.collections[namespace + 'images'];
|
124 | 132 | //first run, so initialise stuff
|
|
232 | 240 |
|
233 | 241 |
|
234 | 242 | /**
|
235 |
| - * COLOR SPACE |
| 243 | + * COLOR SPACES |
| 244 | + */ |
| 245 | + jsPDFAPI.color_spaces = { |
| 246 | + DEVICE_RGB:'DeviceRGB', |
| 247 | + DEVICE_GRAY:'DeviceGray', |
| 248 | + DEVICE_CMYK:'DeviceCMYK', |
| 249 | + CAL_GREY:'CalGray', |
| 250 | + CAL_RGB:'CalRGB', |
| 251 | + LAB:'Lab', |
| 252 | + ICC_BASED:'ICCBased', |
| 253 | + INDEXED:'Indexed', |
| 254 | + PATTERN:'Pattern', |
| 255 | + SEPERATION:'Seperation', |
| 256 | + DEVICE_N:'DeviceN' |
| 257 | + }; |
| 258 | + |
| 259 | + /** |
| 260 | + * DECODE METHODS |
236 | 261 | */
|
237 |
| - jsPDFAPI.DEVICE_RGB = 'DeviceRGB'; |
238 |
| - jsPDFAPI.DEVICE_GRAY = 'DeviceGray'; |
239 |
| - jsPDFAPI.DEVICE_CMYK = 'DeviceCMYK'; |
240 |
| - jsPDFAPI.INDEXED = 'Indexed'; |
| 262 | + jsPDFAPI.decode = { |
| 263 | + DCT_DECODE:'DCTDecode', |
| 264 | + FLATE_DECODE:'FlateDecode', |
| 265 | + LZW_DECODE:'LZWDecode', |
| 266 | + JPX_DECODE:'JPXDecode', |
| 267 | + JBIG2_DECODE:'JBIG2Decode', |
| 268 | + ASCII85_DECODE:'ASCII85Decode', |
| 269 | + ASCII_HEX_DECODE:'ASCIIHexDecode', |
| 270 | + RUN_LENGTH_DECODE:'RunLengthDecode', |
| 271 | + CCITT_FAX_DECODE:'CCITTFaxDecode' |
| 272 | + }; |
241 | 273 |
|
242 | 274 | /**
|
243 |
| - * COMPRESSION METHODS |
| 275 | + * IMAGE COMPRESSION TYPES |
244 | 276 | */
|
245 |
| - jsPDFAPI.DCT_DECODE = 'DCTDecode'; |
246 |
| - jsPDFAPI.FLATE_DECODE = 'FlateDecode'; |
247 |
| - jsPDFAPI.LZW_DECODE = 'LZWDecode'; |
| 277 | + jsPDFAPI.image_compression = { |
| 278 | + NONE: 'NONE', |
| 279 | + FAST: 'FAST', |
| 280 | + MEDIUM: 'MEDIUM', |
| 281 | + SLOW: 'SLOW' |
| 282 | + }; |
248 | 283 |
|
249 | 284 |
|
250 | 285 | jsPDFAPI.isString = function(object) {
|
|
333 | 368 | jsPDFAPI.arrayBufferToBinaryString = function(buffer) {
|
334 | 369 | if(this.isArrayBuffer(buffer))
|
335 | 370 | buffer = new Uint8Array(buffer);
|
| 371 | + |
336 | 372 | var binary_string = '';
|
337 | 373 | var len = buffer.byteLength;
|
338 | 374 | for (var i = 0; i < len; i++) {
|
|
342 | 378 | /*
|
343 | 379 | * Another solution is the method below - convert array buffer straight to base64 and then use atob
|
344 | 380 | */
|
345 |
| - //return atob(arrayBufferToBase64(array_buffer)); |
| 381 | + //return atob(this.arrayBufferToBase64(buffer)); |
346 | 382 | };
|
347 | 383 |
|
348 | 384 | /**
|
|
429 | 465 | return info;
|
430 | 466 | };
|
431 | 467 |
|
432 |
| - jsPDFAPI.addImage = function(imageData, format, x, y, w, h, alias, compress) { |
| 468 | + jsPDFAPI.addImage = function(imageData, format, x, y, w, h, alias, compression) { |
433 | 469 | 'use strict'
|
434 | 470 |
|
435 | 471 | if(typeof format === 'number') {
|
|
444 | 480 | var images = getImages.call(this),//initalises internals and events on first run
|
445 | 481 | cached_info,
|
446 | 482 | dataAsBinaryString;
|
447 |
| - |
448 |
| - compress = compress || false; |
| 483 | + |
| 484 | + compression = checkCompressValue(compression); |
449 | 485 | format = format.toLowerCase();
|
450 | 486 |
|
451 | 487 | if(notDefined(alias))
|
|
489 | 525 | info = cached_info;
|
490 | 526 |
|
491 | 527 | if(!info)
|
492 |
| - info = this['process' + format.toUpperCase()](imageData, imageIndex, alias, compress, dataAsBinaryString); |
| 528 | + info = this['process' + format.toUpperCase()](imageData, imageIndex, alias, compression, dataAsBinaryString); |
493 | 529 |
|
494 | 530 | if(!info)
|
495 | 531 | throw new Error('An unkwown error occurred whilst processing the image');
|
|
548 | 584 | };
|
549 | 585 |
|
550 | 586 |
|
551 |
| - jsPDFAPI.processJPEG = function(data, index, alias, compress, dataAsBinaryString) { |
| 587 | + jsPDFAPI.processJPEG = function(data, index, alias, compression, dataAsBinaryString) { |
552 | 588 | 'use strict'
|
553 |
| - var colorSpace = this.DEVICE_RGB, |
554 |
| - filter = this.DCT_DECODE, |
| 589 | + var colorSpace = this.color_spaces.DEVICE_RGB, |
| 590 | + filter = this.decode.DCT_DECODE, |
555 | 591 | bpc = 8,
|
556 | 592 | dims;
|
557 | 593 |
|
|
579 | 615 | return null;
|
580 | 616 | };
|
581 | 617 |
|
582 |
| - jsPDFAPI.processJPG = function(data, index, alias, compress, dataAsBinaryString) { |
583 |
| - return this.processJPEG(data, index, alias, compress, dataAsBinaryString); |
| 618 | + jsPDFAPI.processJPG = function(data, index, alias, compression, dataAsBinaryString) { |
| 619 | + return this.processJPEG(data, index, alias, compression, dataAsBinaryString); |
584 | 620 | }
|
585 | 621 |
|
586 | 622 | })(jsPDF.API);
|
0 commit comments