• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

heiglandreas / Org_Heigl_Ghostscript / 10202661446

01 Aug 2024 05:07PM UTC coverage: 78.392% (+0.3%) from 78.125%
10202661446

push

github

web-flow
Merge pull request #24 from heiglandreas/send-coverage-to-codecov

SEnd coverage to coveralls

156 of 199 relevant lines covered (78.39%)

5.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.13
/src/Ghostscript.php
1
<?php
2
/**
3
 * Copyright (c) Andreas Heigl<andreas@heigl.org>
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a copy
6
 * of this software and associated documentation files (the "Software"), to deal
7
 * in the Software without restriction, including without limitation the rights
8
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
 * copies of the Software, and to permit persons to whom the Software is
10
 * furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be included in
13
 * all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 *
23
 * @author    Andreas Heigl <andreas@heigl.org>
24
 * @copyright Andreas Heigl<andreas@heigl.org>
25
 * @license   http://www.opensource.org/licenses/mit-license.php MIT-License
26
 */
27

28
namespace Org_Heigl\Ghostscript;
29

30
use Org_Heigl\Ghostscript\Device\DeviceInterface;
31

32
/**
33
 * This class contains a wrapper around the Ghostscript-Application.
34
 *
35
 * This needs the Ghostscript application to be installed on the server. If the
36
 * gs-executable is not available the class will not be able to execute anything
37
 *
38
 * A working example might look like the following code:
39
 * <code>
40
 *
41
 * // First we describe the output-format
42
 * $device = new Org_Heigl_Ghostscript_Device_Jpeg ();
43
 *
44
 * // Set the JPEG-Quality to 100
45
 * $device -> setQuality ( 100 );
46
 *
47
 * // Next we Create the ghostscript-Wrapper
48
 * $gs = new Org_Heigl_Ghostscript ();
49
 *
50
 * // Set the device
51
 * $gs -> setDevice ( $device )
52
 * // Set the input file
53
 *     -> setInputFile ( 'path/to/my/ps/or/pdf/file' )
54
 * // Set the output file that will be created in the same directory as the input
55
 *     -> setOutputFile ( 'output' )
56
 * // Set the resolution to 96 pixel per inch
57
 *     -> setResolution ( 96 )
58
 * // Set Text-antialiasing to the highest level
59
 *     -> setTextAntiAliasing ( Org_Heigl_Ghostscript::ANTIALIASING_HIGH );
60
 *
61
 * // convert the input file to an image
62
 * if ( true === $gs -> render () ) {
63
 *     echo 'success';
64
 * } else {
65
 *     echo 'some error occured';
66
 * }
67
 * </code>
68
 *
69
 * Alternatively the example could read as follows
70
 * <code>
71
 *
72
 * // Create the ghostscript-Wrapper
73
 * $gs = new Org_Heigl_Ghostscript ();
74
 *
75
 * // Set the device
76
 * $gs -> setDevice ( 'jpeg' )
77
 * // Set the input file
78
 *     -> setInputFile ( 'path/to/my/ps/or/pdf/file' )
79
 * // Set the output file that will be created in the same directory as the input
80
 *     -> setOutputFile ( 'output' )
81
 * // Set the resolution to 96 pixel per inch
82
 *     -> setResolution ( 96 )
83
 * // Set Text-antialiasing to the highest level
84
 *     -> setTextAntiAliasing ( Org_Heigl_Ghostscript::ANTIALIASING_HIGH );
85
 *
86
 * // Set the jpeg-quality to 100
87
 * $gs -> getDevice () -> setQuality ( 100 );
88
 *
89
 * // convert the input file to an image
90
 * if ( true === $gs -> render () ) {
91
 *     echo 'success';
92
 * } else {
93
 *     echo 'some error occured';
94
 * }
95
 * </code>
96
 *
97
 * @category  Org_Heigl
98
 * @package   Org_Heigl_Ghostscript
99
 * @author    Andreas Heigl <andreas@heigl.org>
100
 * @copyright 2008 Andreas Heigl<andreas@heigl.org>
101
 * @license   http://www.opensource.org/licenses/mit-license.php MIT-License
102
 * @version   SVN: $Revision$
103
 * @since     03.06.2009
104
 */
105
class Ghostscript
106
{
107
    /**
108
     * No Anti-Aliasing
109
     *
110
     * @var int
111
     */
112
    const ANTIALIASING_NONE   = 1;
113

114
    /**
115
     * Low Anti-Aliasing
116
     *
117
     * @var int
118
     */
119
    const ANTIALIASING_LOW    = 2;
120

121
    /**
122
     * Medium Anti-Aliasing
123
     *
124
     * @var int
125
     * @deprecated As there is no "Medium" Anti-Aliasing. Only None, low and
126
     * high
127
     */
128
    const ANTIALIASING_MEDIUM = 2;
129

130
    /**
131
     * High Anti-Aliasing
132
     *
133
     * @var int
134
     */
135
    const ANTIALIASING_HIGH   = 4;
136

137
    /**
138
     * This property stores the output-device
139
     *
140
     * @var string $device
141
     */
142
    protected $device;
143

144
    /**
145
     * Store the resolution
146
     *
147
     * @var string $_resolution
148
     */
149
    protected $resolution = 72;
150

151
    /**
152
     * This property stores the file to process.
153
     *
154
     * @var SplFileInfo $_infile
155
     */
156
    protected $infile = null;
157

158
    /**
159
     * This property stores the output-filename.
160
     *
161
     * This is NOT necessarily the filename that can be used for retrieving the
162
     * file as Ghostscript can use this name for more than one file if a
163
     * placeholder is defined.
164
     *
165
     * @var string $_outfile
166
     */
167
    protected $outfile = 'output';
168

169
    /**
170
     * Stores the anti aliasing level
171
     *
172
     * @var int $_graphicsAntiAliasing
173
     */
174
    protected $graphicsAntiAliasing = 0;
175

176
    /**
177
     * Stores the anti aliasing level
178
     *
179
     * @var int $_textAntiAliasing
180
     */
181
    protected $textAntiAliasing = 0;
182

183
    /**
184
     * Store whether to use CIE for color conversion or not
185
     *
186
     * @var boolean $_useCie
187
     */
188
    protected $useCie = false;
189

190
    /**
191
     * Store any default input-profiles
192
     *
193
     * @var array $_defaultProfile
194
     */
195
    protected $defaultProfile = [];
196

197
    /**
198
     * Store the deviceProfile to use for oputput
199
     *
200
     * @var string|null $_deviceProfile
201
     */
202
    protected $deviceProfile = null;
203

204
    /**
205
     * Which box shall be used for rendering?
206
     *
207
     * @var string|null $_useBox
208
     */
209
    protected $useBox = null;
210

211
    /**
212
     * On which page shall we start rendering?
213
     *
214
     * If NULL this will be ignored
215
     *
216
     * @var int $_pageStart
217
     */
218
    protected $pageStart = null;
219

220
    /**
221
     * On which page shall we stop rendering?
222
     *
223
     * If NULL, this will be ignored
224
     *
225
     * @var int $_pageEnd
226
     */
227
    protected $pageEnd = null;
228

229
    /**
230
     * Which MIME-Types are supported
231
     *
232
     * @var array $supportedMimeTypes
233
     */
234
    private static $supportedMimeTypes = [
235
        'application/postscript',
236
        'application/eps',
237
        'application/pdf',
238
        'application/ps',
239
    ];
240

241
    /**
242
     * This property contains the path to the Ghostscript-Application
243
     *
244
     * This is set when the class is first loaded
245
     *
246
     * @var string PATH
247
     */
248
    private static $PATH = null;
249

250
    /**
251
     * Create a new Instance of the Ghostscript wrapper.
252
     *
253
     * The new Instance will use a jpeg-device as default
254
     *
255
     * @return void
256
     */
257
    public function __construct()
258
    {
259
        $this->setDevice('png');
23✔
260
    }
261

262
    /**
263
     * Set the path to the gs-executable and return it.
264
     *
265
     * This method will be called on load of the class and needs not to be
266
     * called during normal operation.
267
     *
268
     * If you have Ghostscript installed in a non-standard-location that can not
269
     * be found via the 'which gs' command, you have to set the path manualy
270
     *
271
     * @param string|null $path The path to set
272
     *
273
     * @return string
274
     */
275
    public static function setGsPath($path = null)
276
    {
277
        if (null === $path) {
29✔
278
            exec('which gs', $output);
29✔
279
            if (! $output) {
29✔
280
                throw new \UnexpectedValueException(
×
281
                    'No Ghostscript-instance found or running on windows. ' .
×
282
                    'Please provide Path to the Ghostscript-executable'
×
283
                );
×
284
            }
285
            $path = $output[0];
29✔
286
        }
287

288
        if (! $path) {
29✔
289
            throw new \UnexpectedValueException('No path found');
×
290
        }
291

292
        if (! is_executable($path)) {
29✔
293
            throw new \InvalidArgumentException('The given file is not executable');
1✔
294
        }
295

296
        @exec('"' . $path . '" -v', $result);
29✔
297
        $content = implode("\n", $result);
29✔
298
        if (false === stripos($content, 'ghostscript')) {
29✔
299
            throw new \InvalidArgumentException('No valid Ghostscript found');
1✔
300
        }
301

302
        self::$PATH = $path;
29✔
303

304
        return self::$PATH;
29✔
305
    }
306

307
    /**
308
     * Get the currently set path for the ghostscript-app
309
     *
310
     * @return string
311
     */
312
    public static function getGsPath()
313
    {
314
        if (! self::$PATH) {
10✔
315
            throw new \InvalidArgumentException('No GS-Path set');
×
316
        }
317

318
        return self::$PATH;
10✔
319
    }
320

321

322
    /**
323
     * Set the file that shall be processes
324
     *
325
     * This should be a PostScript (ps), Enhanced Postscript (eps) or
326
     * PortableDocumentformat (pdf) File.
327
     *
328
     * @param string|SplFileInfo $file The File to use as input.
329
     *
330
     * @throws InvalidArgumentException when the provided file is not supported
331
     * @return self
332
     */
333
    public function setInputFile($file)
334
    {
335
        if (! $file instanceof \SplFileInfo) {
8✔
336
            $file = new \SplFileInfo((string) $file);
8✔
337
        }
338
        if (extension_loaded('fileinfo') && file_exists($file)) {
8✔
339
            $finfo = new \finfo();
7✔
340
            $mime = $finfo->file($file->getPathName(), FILEINFO_MIME);
7✔
341
            $mime = explode(';', $mime);
7✔
342
            if (! in_array($mime[0], self::$supportedMimeTypes)) {
7✔
343
                throw new \InvalidArgumentException('The provided file seems not to be of a supported MIME-Type');
1✔
344
            }
345
        }
346
        $this->infile = $file;
7✔
347

348
        return $this;
7✔
349
    }
350

351
    /**
352
     * Get the file that shall be processed
353
     *
354
     * @return SplFileInfo
355
     */
356
    public function getInputFile()
357
    {
358
        return $this->infile;
6✔
359
    }
360

361
    /**
362
     * Set the name of the output file(s)
363
     *
364
     * This name does not need a file-extension as that is set from the output
365
     * format.
366
     *
367
     * The name can contain a placeholder like '%d' or '%02d'. This will be
368
     * replaced by the pagenumber of the processed page. For more information
369
     * on the format see the PHP documentation for sprintf
370
     *
371
     * @param string $name The filename
372
     *
373
     * @return Ghostscript
374
     */
375
    public function setOutputFile($name = 'output')
376
    {
377
        if ($this->isRelative($name)) {
9✔
378
            $name = $this->getBasePath() . DIRECTORY_SEPARATOR . $name;
7✔
379
        }
380

381
        $this->outfile = $name;
9✔
382
        
383
        return $this;
9✔
384
    }
385

386
    /**
387
     * Get the output filename.
388
     *
389
     * This is NOT the name the file can be retrieved with as Ghostscript can
390
     * modify the filename, but the returned string containes the directory the
391
     * file(s) reside in.
392
     *
393
     * @return string
394
     */
395
    public function getOutputFile()
396
    {
397
        if ($this->isRelative($this->outfile)) {
11✔
398
            return $this->getBasePath() . DIRECTORY_SEPARATOR . $this->outfile;
2✔
399
        }
400

401
        return $this->outfile;
9✔
402
    }
403

404
    /**
405
     * Get the basepath of the execution.
406
     *
407
     * Thisis set to the directory containing <var>$_infile</var>.
408
     *
409
     * If <var>$_infile</var> is not set, it is set to the systems default
410
     * tmp-directory.
411
     *
412
     * @return string
413
     */
414
    public function getBasePath()
415
    {
416
        if (null !== $this->infile) {
9✔
417
            return dirname($this->infile);
5✔
418
        }
419
        return sys_get_temp_dir();
5✔
420
    }
421

422
    /**
423
     * Render the input file via Ghostscript
424
     *
425
     * @return bool
426
     */
427
    public function render()
428
    {
429
        $renderString = $this->getRenderString();
1✔
430

431
        // We can't render anything without a render string
432
        if ('' == $renderString) {
1✔
433
            return false;
1✔
434
        }
435

436
        exec($renderString, $returnArray, $returnValue);
1✔
437

438
        if (0 !== $returnValue) {
1✔
439
            return false;
×
440
        }
441

442
        return true;
1✔
443
    }
444

445
    /**
446
     * Get the command-line that can be executed via exec
447
     *
448
     * @return string
449
     */
450
    public function getRenderString()
451
    {
452
        if (null === $this->getInputFile()) {
6✔
453
            return '';
2✔
454
        }
455
        $string  = '"' . self::getGsPath() . '"';
6✔
456
        $string .= ' -dSAFER -dQUIET -dNOPLATFONTS -dNOPAUSE -dBATCH';
6✔
457
        $string .= ' -sOutputFile="' . $this->getOutputFileName() . '"';
6✔
458
        $string .= $this->getDevice()->getParameterString();
6✔
459
        $string .= ' -r' . $this->getResolution();
6✔
460
        if ($this->isTextAntiAliasingSet()) {
6✔
461
            $string .= ' -dTextAlphaBits=' . $this->getTextAntiAliasing();
1✔
462
        }
463
        if ($this->isGraphicsAntiAliasingSet()) {
6✔
464
            $string .= ' -dGraphicsAlphaBits=' . $this->getGraphicsAntiAliasing();
1✔
465
        }
466

467

468
        if (true === $this->useCie()) {
6✔
469
            $string .= ' -dUseCIEColor';
×
470
        }
471

472
        // Set the Rendered Box.
473
        $box = $this->getBox();
6✔
474
        if (null !== $box) {
6✔
475
            $string .= ' -dUse' . ucfirst($box) . 'Box';
×
476
        }
477

478
        // Set files for ColorManagement.
479
        // As of GS 8.71 there should be a different way to do that.
480
        if ($this->defaultProfile) {
6✔
481
            foreach ($this->defaultProfile as $profile) {
×
482
                $string .= ' "' . $profile . '"';
×
483
            }
484
        }
485
        $deviceProfile = $this->getDeviceProfile();
6✔
486
        if (false !== $deviceProfile) {
6✔
487
            $string .= ' "' . $deviceProfile . '"';
×
488
        }
489

490
        $string .= $this->getPageRangeString();
6✔
491

492
        $string .= ' "' . $this->getInputFile() . '"';
6✔
493
        return $string;
6✔
494
    }
495

496
    public function getPageRangeString()
497
    {
498
        if (null === $this->pageStart) {
7✔
499
            return '';
7✔
500
        }
501

502
        $string = ' -dFirstPage=%d -dLastPage=%d';
1✔
503

504
        $pageStart = $this->pageStart;
1✔
505
        $pageEnd = $this->pageEnd;
1✔
506
        if (null === $this->pageEnd) {
1✔
507
            $pageEnd = $this->pageStart;
1✔
508
        }
509

510
        return sprintf($string, $pageStart, $pageEnd);
1✔
511
    }
512

513
    /**
514
     * Check whether Anti ALiasing for graphics is set
515
     *
516
     * @return boolean
517
     */
518
    public function isGraphicsAntiAliasingSet()
519
    {
520
        if (0 < $this->graphicsAntiAliasing) {
7✔
521
            return true;
2✔
522
        }
523

524
        return false;
7✔
525
    }
526

527
    /**
528
     * Set graphics-AntiAliasing
529
     *
530
     * @param int $level The AntiaAliasing level to set.
531
     *
532
     * @return self
533
     */
534
    public function setGraphicsAntiAliasing($level)
535
    {
536
        if ($level === 0 || $level === 1 || $level === 2 || $level === 4) {
2✔
537
            $this->graphicsAntiAliasing = $level;
2✔
538
        }
539

540
        return $this;
2✔
541
    }
542

543

544

545
    /**
546
     * Get the text-AntiAliasing level
547
     *
548
     * @return int
549
     */
550
    public function getGraphicsAntiAliasing()
551
    {
552
        return $this->graphicsAntiAliasing;
2✔
553
    }
554

555

556
    /**
557
     * Check whether Anti ALiasing for text is set
558
     *
559
     * @return boolean
560
     */
561
    public function isTextAntiAliasingSet()
562
    {
563
        if (0 < $this->textAntiAliasing) {
7✔
564
            return true;
2✔
565
        }
566

567
        return false;
7✔
568
    }
569

570
    /**
571
     * Set text-AntiAliasing
572
     *
573
     * @param int $level The AntiaAliasing level to set.
574
     *
575
     * @return self
576
     */
577
    public function setTextAntiAliasing($level)
578
    {
579
        if ($level === 0 || $level === 1 || $level === 2 || $level === 4) {
2✔
580
            $this->textAntiAliasing = $level;
2✔
581
        }
582

583
        return $this;
2✔
584
    }
585

586
    /**
587
     * Get the text-AntiAliasing level
588
     *
589
     * @return int
590
     */
591
    public function getTextAntiAliasing()
592
    {
593
        return $this->textAntiAliasing;
2✔
594
    }
595

596
    /**
597
     * Set the resolution for the rendering
598
     *
599
     * @param int The horizontal resolution to set
600
     * @param int The vertical resolution to set
601
     *
602
     * @return self
603
     */
604
    public function setResolution($horizontal, $vertical = null)
605
    {
606
        if (null !== $vertical) {
1✔
607
            $this->resolution = $horizontal . 'x' . $vertical;
1✔
608
        } else {
609
            $this->resolution = $horizontal;
1✔
610
        }
611

612
        return $this;
1✔
613
    }
614

615
    /**
616
     * Get the resolution
617
     *
618
     * @return string
619
     */
620
    public function getResolution()
621
    {
622
        return $this->resolution;
7✔
623
    }
624

625
    /**
626
     * Set the output-device
627
     *
628
     * @param DeviceInterface|string $device
629
     *
630
     * @return self
631
     */
632
    public function setDevice($device)
633
    {
634
        if (! $device instanceof DeviceInterface) {
23✔
635
            $classname = 'Org_Heigl\\Ghostscript\\Device\\' . ucfirst(strtolower($device));
23✔
636
            $device = new $classname();
23✔
637
        }
638
        $this->device = $device;
23✔
639

640
        return $this;
23✔
641
    }
642

643
    /**
644
     * Get the device-object
645
     *
646
     * @return DeviceInterface
647
     */
648
    public function getDevice()
649
    {
650
        return $this->device;
9✔
651
    }
652

653
    /**
654
     * Set whether to use the CIE-Map for conversion between CMYK and RGB or not
655
     *
656
     * @param boolean $useCIE
657
     *
658
     * @return self
659
     */
660
    public function setUseCie($useCie = true)
661
    {
662
        $this->useCie = (bool) $useCie;
1✔
663

664
        return $this;
1✔
665
    }
666

667
    /**
668
     * Shall we use the CIE map for color-conversions?
669
     *
670
     * @return boolean
671
     */
672
    public function useCie()
673
    {
674
        return (bool) $this->useCie;
7✔
675
    }
676

677
    /**
678
     * Which Box shall be used to generate the output from.
679
     *
680
     * This can be one of
681
     *  - crop
682
     *  - media
683
     *
684
     *  @param string $box The box to use
685
     *
686
     *  @return self
687
     */
688
    public function useBox($box)
689
    {
690
        $box = strtolower($box);
×
691
        switch ($box) {
692
            case 'crop':
×
693
            case 'media':
×
694
            case 'trim':
×
695
                $this->useBox = $box;
×
696
                break;
×
697
            default:
698
                $this->useBox = null;
×
699
                break;
×
700
        }
701

702
        return $this;
×
703
    }
704

705
    /**
706
     * Get the name of the box to be used for rendering
707
     *
708
     * This returns either 'crop' or 'media' if one of these boxes shall be
709
     * rendered or NULL if the switch shall not be set.
710
     *
711
     * @return string|null
712
     */
713
    public function getBox()
714
    {
715
        return $this->useBox;
6✔
716
    }
717

718
    /**
719
     * Add the given Profile for Color-Management as Input-Profile.
720
     *
721
     * The Profile will be added as CSA-File to perform the translation of
722
     * Colors from the Input-File to the Internal ProcessColosSpace.
723
     *
724
     * The CSA-File can be created via the OpenSource-Tool icc2ps from the
725
     * littleCMS-Package available at http://www.littlecms.org
726
     *
727
     * The CSA-File can be generated via the following command from any
728
     * icc-file:
729
     * <code>
730
     * icc2ps -i <input.icc> > output.csa
731
     * </code>
732
     * This gerneated CSA-File has to be adapted according to the following
733
     * example:
734
     * <code>
735
     * currentglobal true setglobal
736
     * /DefaultCMYK
737
     * [ /CIEBasedDEFG
738
     * <<
739
     *  ...
740
     *  ...
741
     * >>
742
     * ] /ColorSpace defineresource pop
743
     * setglobal
744
     * </code>
745
     * where the Part in the brackets is the part that is generated from the
746
     * icc2ps-tool.
747
     *
748
     * For more Information on Color-Conversion and Color-Management refer to
749
     * the Homepage of ghostscript, the ICC or have a look at a Search-Engine.
750
     *
751
     * @param string $profile The Name of the CSA-Profile to use or the complete
752
     * path to an appropriate CSA-File.
753
     * @param string $space   The Color-Space to set the profile for. This can
754
     * be one of 'rgb', 'cmyk' or 'gray'. This parameter is currently not
755
     * supported!
756
     *
757
     * @see http://www.littlecms.org
758
     * @see http://www.ghostscript.com
759
     * @return self
760
     */
761
    public function setDefaultProfile($profile, $space = null)
762
    {
763
        $space = strtolower($space);
×
764
        if (! in_array($space, [ 'cmyk', 'rgb', 'gray' ])) {
×
765
            $space = 'cmyk';
×
766
        }
767
        if (file_exists($profile)) {
×
768
            $this->defaultProfile[$space] = $profile;
×
769
        }
770

771
        return $this;
×
772
    }
773

774
    /**
775
     * Get the default Input-Profile
776
     *
777
     * @return string|false
778
     */
779
    public function getDefaultProfile($space = 'cmyk')
780
    {
781
        if (isset($this->defaultProfile[$space])) {
×
782
            return $this->defautProfile[$space];
×
783
        }
784

785
        return false;
×
786
    }
787

788
    /**
789
     * Add the given Profile for Color-Management as Device-Output-Profile.
790
     *
791
     * The Profile will be added as CRD-File to perform the translation of
792
     * Colors from the Internal ProcessColorSpace to the Output-File.
793
     *
794
     * The CRD-File can be created via the OpenSource-Tool icc2ps from the
795
     * littleCMS-Package available at http://www.littlecms.org
796
     *
797
     * The CRD-File can be generated via the following command from any
798
     * icc-file:
799
     * <code>
800
     * icc2ps -o <input.icc> > output.crd
801
     * </code>
802
     * This gerneated CRD-File has to be adapted by appeding the following
803
     * line to it:
804
     * <code>
805
     * /Current /ColorRendering findresource setcolorrendering
806
     * </code>
807
     *
808
     * For more Information on Color-Conversion and Color-Management refer to
809
     * the Homepage of ghostscript, the ICC or have a look at a Search-Engine.
810
     *
811
     * @param string $profile The Name of the CRD-Profile to use or the complete
812
     * path to an appropriate CRD-File.
813
     *
814
     * @see http://www.littlecms.org
815
     * @see http://www.ghostscript.com
816
     * @return self
817
     */
818
    public function setDeviceProfile($profile)
819
    {
820
        if (file_exists($profile)) {
×
821
            $this->deviceProfile = $profile;
×
822
        }
823

824
        return $this;
×
825
    }
826

827
    /**
828
     * Get the currently set device-Profile
829
     *
830
     * @return string|false
831
     */
832
    public function getDeviceProfile()
833
    {
834
        if (null === $this->deviceProfile) {
6✔
835
            return false;
6✔
836
        }
837

838
        return $this->deviceProfile;
×
839
    }
840

841
    /**
842
     * Set the page to start rendering
843
     *
844
     * @param int $page
845
     *
846
     * @return self
847
     */
848
    public function setPageStart($page)
849
    {
850
        if (null !== $page) {
×
851
            $page = (int) $page;
×
852
        }
853
        $this->pageStart = $page;
×
854

855
        return $this;
×
856
    }
857

858
    /**
859
     * Set the page to stop rendering
860
     *
861
     * @param int $page
862
     *
863
     * @return self
864
     */
865
    public function setPageEnd($page)
866
    {
867
        if (null !== $page) {
×
868
            $page = (int) $page;
×
869
        }
870
        $this->pageEnd = $page;
×
871

872
        return $this;
×
873
    }
874

875
    /**
876
     * Set a page-Range
877
     *
878
     * @param $startPage
879
     * @param $endPage
880
     *
881
     * @return self
882
     */
883
    public function setPages($startPage, $endPage = null)
884
    {
885
        $this->pageStart = (int) $startPage;
1✔
886

887
        if (null !== $endPage) {
1✔
888
            $this->pageEnd = (int) $endPage;
1✔
889
        }
890

891
        return $this;
1✔
892
    }
893

894
    public function getOutputFileName()
895
    {
896
        $basename = $this->getOutputFile();
10✔
897
        $lastDot = strrpos(basename($basename), '.');
10✔
898
        if (false === $lastDot) {
10✔
899
            return $basename . '.' . $this->getDevice()->getFileEnding();
6✔
900
        }
901

902
        return $basename;
4✔
903
    }
904

905
    private function isRelative($path)
906
    {
907
        if (0 === strpos($path, DIRECTORY_SEPARATOR)) {
16✔
908
            return false;
10✔
909
        }
910

911
        if (1 === strpos($path, ':\\') && preg_match('/^[A-Za-z]/', $path)) {
13✔
912
            return false;
1✔
913
        }
914

915
        return true;
12✔
916
    }
917
}
918

919
try {
920
    Ghostscript::setGsPath();
1✔
921
} catch (\UnexpectedValueException $e) {
×
922
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc