Completed
Push — master ( 221921...32345e )
by Bhanu
58:02
created

functions.inc.php ➔ dec2roman()   C

Complexity

Conditions 8
Paths 7

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 18
nc 7
nop 1
dl 0
loc 28
rs 5.3846
c 1
b 0
f 0
1
<?php
2
/**
3
 * @package dompdf
4
 * @link    http://dompdf.github.com/
5
 * @author  Benj Carson <[email protected]>
6
 * @author  Helmut Tischer <[email protected]>
7
 * @author  Fabien Ménager <[email protected]>
8
 * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
9
 */
10
11 View Code Duplication
if ( !defined('PHP_VERSION_ID') ) {
12
  $version = explode('.', PHP_VERSION);
13
  define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2]));
14
}
15
16
/**
17
 * Defined a constant if not already defined
18
 *
19
 * @param string $name  The constant name
20
 * @param mixed  $value The value
21
 */
22
function def($name, $value = true) {
23
  if ( !defined($name) ) {
24
    define($name, $value);
25
  }
26
}
27
28
if ( !function_exists("pre_r") ) {
29
/**
30
 * print_r wrapper for html/cli output
31
 *
32
 * Wraps print_r() output in < pre > tags if the current sapi is not 'cli'.
33
 * Returns the output string instead of displaying it if $return is true.
34
 *
35
 * @param mixed $mixed variable or expression to display
36
 * @param bool $return
37
 *
38
 * @return string
39
 */
40
function pre_r($mixed, $return = false) {
41
  if ( $return ) {
42
    return "<pre>" . print_r($mixed, true) . "</pre>";
43
  }
44
45
  if ( php_sapi_name() !== "cli" ) {
46
    echo "<pre>";
47
  }
48
  
49
  print_r($mixed);
50
51
  if ( php_sapi_name() !== "cli" ) {
52
    echo "</pre>";
53
  }
54
  else {
55
    echo "\n";
56
  }
57
  
58
  flush();
59
60
}
61
}
62
63
if ( !function_exists("pre_var_dump") ) {
64
/**
65
 * var_dump wrapper for html/cli output
66
 *
67
 * Wraps var_dump() output in < pre > tags if the current sapi is not 'cli'.
68
 *
69
 * @param mixed $mixed variable or expression to display.
70
 */
71
function pre_var_dump($mixed) {
72
  if ( php_sapi_name() !== "cli" ) {
73
    echo "<pre>";
74
  }
75
    
76
  var_dump($mixed);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($mixed); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
77
  
78
  if ( php_sapi_name() !== "cli" ) {
79
    echo "</pre>";
80
  }
81
}
82
}
83
84
if ( !function_exists("d") ) {
85
/**
86
 * generic debug function
87
 *
88
 * Takes everything and does its best to give a good debug output
89
 *
90
 * @param mixed $mixed variable or expression to display.
91
 */
92
function d($mixed) {
93
  if ( php_sapi_name() !== "cli" ) {
94
    echo "<pre>";
95
  }
96
    
97
  // line
98
  if ( $mixed instanceof Line_Box ) {
99
    echo $mixed;
100
  }
101
  
102
  // other
103
  else {
104
    var_export($mixed);
105
  }
106
  
107
  if ( php_sapi_name() !== "cli" ) {
108
    echo "</pre>";
109
  }
110
}
111
}
112
113
/**
114
 * builds a full url given a protocol, hostname, base path and url
115
 *
116
 * @param string $protocol
117
 * @param string $host
118
 * @param string $base_path
119
 * @param string $url
120
 * @return string
121
 *
122
 * Initially the trailing slash of $base_path was optional, and conditionally appended.
123
 * However on dynamically created sites, where the page is given as url parameter,
124
 * the base path might not end with an url.
125
 * Therefore do not append a slash, and **require** the $base_url to ending in a slash
126
 * when needed.
127
 * Vice versa, on using the local file system path of a file, make sure that the slash
128
 * is appended (o.k. also for Windows)
129
 */
130
function build_url($protocol, $host, $base_path, $url) {
131
  $protocol = mb_strtolower($protocol);
132
  if (strlen($url) == 0) {
133
    //return $protocol . $host . rtrim($base_path, "/\\") . "/";
134
    return $protocol . $host . $base_path;
135
  }
136
  // Is the url already fully qualified or a Data URI?
137
  if (mb_strpos($url, "://") !== false || mb_strpos($url, "data:") === 0) {
138
    return $url;
139
  }
140
  $ret = $protocol;
141
  if (!in_array(mb_strtolower($protocol), array("http://", "https://", "ftp://", "ftps://"))) {
142
    //On Windows local file, an abs path can begin also with a '\' or a drive letter and colon
143
    //drive: followed by a relative path would be a drive specific default folder.
144
    //not known in php app code, treat as abs path
145
    //($url[1] !== ':' || ($url[2]!=='\\' && $url[2]!=='/'))
146
    if ($url[0] !== '/' && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || ($url[0] !== '\\' && $url[1] !== ':'))) {
147
      // For rel path and local acess we ignore the host, and run the path through realpath()
148
      $ret .= realpath($base_path) . '/';
149
    }
150
    $ret .= $url;
151
    $ret = preg_replace('/\?(.*)$/', "", $ret);
152
    return $ret;
153
  }
154
  // Protocol relative urls (e.g. "//example.org/style.css")
155
  if (strpos($url, '//') === 0) {
156
    $ret .= substr($url, 2);
157
    //remote urls with backslash in html/css are not really correct, but lets be genereous
158
  } elseif ($url[0] === '/' || $url[0] === '\\') {
159
    // Absolute path
160
    $ret .= $host . $url;
161
  } else {
162
    // Relative path
163
    //$base_path = $base_path !== "" ? rtrim($base_path, "/\\") . "/" : "";
164
    $ret .= $host . $base_path . $url;
165
  }
166
  return $ret;
167
}
168
169
170
/**
171
 * parse a full url or pathname and return an array(protocol, host, path,
172
 * file + query + fragment)
173
 *
174
 * @param string $url
175
 * @return array
176
 */
177
function explode_url($url) {
178
  $protocol = "";
0 ignored issues
show
Unused Code introduced by
$protocol is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
179
  $host = "";
180
  $path = "";
181
  $file = "";
182
183
  $arr = parse_url($url);
184
  if ( isset($arr["scheme"])) {
185
    $arr["scheme"] == mb_strtolower($arr["scheme"]);
186
  }
187
  
188
  // Exclude windows drive letters...
189
  if ( isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1 ) {
190
    $protocol = $arr["scheme"] . "://";
191
192
    if ( isset($arr["user"]) ) {
193
      $host .= $arr["user"];
194
195
      if ( isset($arr["pass"]) ) {
196
        $host .= ":" . $arr["pass"];
197
      }
198
199
      $host .= "@";
200
    }
201
202
    if ( isset($arr["host"]) ) {
203
      $host .= $arr["host"];
204
    }
205
206
    if ( isset($arr["port"]) ) {
207
      $host .= ":" . $arr["port"];
208
    }
209
210
    if ( isset($arr["path"]) && $arr["path"] !== "" ) {
211
      // Do we have a trailing slash?
212
      if ( $arr["path"][ mb_strlen($arr["path"]) - 1 ] === "/" ) {
213
        $path = $arr["path"];
214
        $file = "";
215
      }
216
      else {
217
        $path = rtrim(dirname($arr["path"]), '/\\') . "/";
218
        $file = basename($arr["path"]);
219
      }
220
    }
221
222
    if ( isset($arr["query"]) ) {
223
      $file .= "?" . $arr["query"];
224
    }
225
226
    if ( isset($arr["fragment"]) ) {
227
      $file .= "#" . $arr["fragment"];
228
    }
229
230
  }
231
  else {
232
233
    $i = mb_stripos($url, "file://");
234
    if ( $i !== false ) {
235
      $url = mb_substr($url, $i + 7);
236
    }
237
238
    $protocol = ""; // "file://"; ? why doesn't this work... It's because of
239
                    // network filenames like //COMPU/SHARENAME
240
241
    $host = ""; // localhost, really
242
    $file = basename($url);
243
244
    $path = dirname($url);
245
246
    // Check that the path exists
247
    if ( $path !== false ) {
248
      $path .= '/';
249
250
    }
251
    else {
252
      // generate a url to access the file if no real path found.
253
      $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
254
255
      $host = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : php_uname("n");
256
257
      if ( substr($arr["path"], 0, 1) === '/' ) {
258
        $path = dirname($arr["path"]);
259
      }
260
      else {
261
        $path = '/' . rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/') . '/' . $arr["path"];
262
      }
263
    }
264
  }
265
266
  $ret = array($protocol, $host, $path, $file,
267
               "protocol" => $protocol,
268
               "host" => $host,
269
               "path" => $path,
270
               "file" => $file);
271
  return $ret;
272
}
273
274
/**
275
 * Converts decimal numbers to roman numerals
276
 *
277
 * @param int $num
278
 *
279
 * @throws DOMPDF_Exception
280
 * @return string
281
 */
282
function dec2roman($num) {
283
284
  static $ones = array("", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix");
285
  static $tens = array("", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc");
286
  static $hund = array("", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm");
287
  static $thou = array("", "m", "mm", "mmm");
288
289
  if ( !is_numeric($num) ) {
290
    throw new DOMPDF_Exception("dec2roman() requires a numeric argument.");
291
  }
292
293
  if ( $num > 4000 || $num < 0 ) {
294
    return "(out of range)";
295
  }
296
297
  $num = strrev((string)$num);
298
299
  $ret = "";
300
  switch (mb_strlen($num)) {
301
    case 4: $ret .= $thou[$num[3]];
302
    case 3: $ret .= $hund[$num[2]];
303
    case 2: $ret .= $tens[$num[1]];
304
    case 1: $ret .= $ones[$num[0]];
305
    default: break;
306
  }
307
  
308
  return $ret;
309
}
310
311
/**
312
 * Determines whether $value is a percentage or not
313
 *
314
 * @param float $value
315
 *
316
 * @return bool
317
 */
318
function is_percent($value) {
319
  return false !== mb_strpos($value, "%");
320
}
321
322
/**
323
 * Parses a data URI scheme
324
 * http://en.wikipedia.org/wiki/Data_URI_scheme
325
 *
326
 * @param string $data_uri The data URI to parse
327
 *
328
 * @return array The result with charset, mime type and decoded data
329
 */
330
function parse_data_uri($data_uri) {
331
  if (!preg_match('/^data:(?P<mime>[a-z0-9\/+-.]+)(;charset=(?P<charset>[a-z0-9-])+)?(?P<base64>;base64)?\,(?P<data>.*)?/i', $data_uri, $match)) {
332
    return false;
333
  }
334
  
335
  $match['data'] = rawurldecode($match['data']);
336
  $result = array(
337
    'charset' => $match['charset'] ? $match['charset'] : 'US-ASCII',
338
    'mime'    => $match['mime'] ? $match['mime'] : 'text/plain',
339
    'data'    => $match['base64'] ? base64_decode($match['data']) : $match['data'],
340
  );
341
  
342
  return $result;
343
}
344
345
/**
346
 * mb_string compatibility
347
 */
348
if (!extension_loaded('mbstring')) {
349
  def('MB_OVERLOAD_MAIL', 1);
350
  def('MB_OVERLOAD_STRING', 2);
351
  def('MB_OVERLOAD_REGEX', 4);
352
  def('MB_CASE_UPPER', 0);
353
  def('MB_CASE_LOWER', 1);
354
  def('MB_CASE_TITLE', 2);
355
356
  if (!function_exists('mb_convert_encoding')) {
357
      function mb_convert_encoding($data, $to_encoding, $from_encoding = 'UTF-8') {
358
      if (str_replace('-', '', strtolower($to_encoding)) === 'utf8') {
359
        return utf8_encode($data);
360
      }
361
      
362
      return utf8_decode($data);
363
    }
364
  }
365
  
366
  if (!function_exists('mb_detect_encoding')) {
367
    function mb_detect_encoding($data, $encoding_list = array('iso-8859-1'), $strict = false) {
368
      return 'iso-8859-1';
369
    }
370
  }
371
  
372
  if (!function_exists('mb_detect_order')) {
373
    function mb_detect_order($encoding_list = array('iso-8859-1')) {
374
      return 'iso-8859-1';
375
    }
376
  }
377
  
378
  if (!function_exists('mb_internal_encoding')) {
379
    function mb_internal_encoding($encoding = null) {
380
      if (isset($encoding)) {
381
        return true;
382
      }
383
      
384
      return 'iso-8859-1';
385
    }
386
  }
387
388
  if (!function_exists('mb_strlen')) {
389
    function mb_strlen($str, $encoding = 'iso-8859-1') {
390
      switch (str_replace('-', '', strtolower($encoding))) {
391
        case "utf8": return strlen(utf8_encode($str));
392
        case "8bit": return strlen($str);
393
        default:     return strlen(utf8_decode($str));
394
      }
395
    }
396
  }
397
  
398
  if (!function_exists('mb_strpos')) {
399
    function mb_strpos($haystack, $needle, $offset = 0) {
400
      return strpos($haystack, $needle, $offset);
401
    }
402
  }
403
  
404
  if (!function_exists('mb_stripos')) {
405
    function mb_stripos($haystack, $needle, $offset = 0) {
406
      return stripos($haystack, $needle, $offset);
407
    }
408
  }
409
  
410
  if (!function_exists('mb_strrpos')) {
411
    function mb_strrpos($haystack, $needle, $offset = 0) {
412
      return strrpos($haystack, $needle, $offset);
413
    }
414
  }
415
  
416
  if (!function_exists('mb_strtolower')) {
417
    function mb_strtolower( $str ) {
418
      return strtolower($str);
419
    }
420
  }
421
  
422
  if (!function_exists('mb_strtoupper')) {
423
    function mb_strtoupper( $str ) {
424
      return strtoupper($str);
425
    }
426
  }
427
  
428
  if (!function_exists('mb_substr')) {
429
    function mb_substr($string, $start, $length = null, $encoding = 'iso-8859-1') {
430
      if ( is_null($length) ) {
431
        return substr($string, $start);
432
      }
433
      
434
      return substr($string, $start, $length);
435
    }
436
  }
437
  
438
  if (!function_exists('mb_substr_count')) {
439
    function mb_substr_count($haystack, $needle, $encoding = 'iso-8859-1') {
440
      return substr_count($haystack, $needle);
441
    }
442
  }
443
  
444
  if (!function_exists('mb_encode_numericentity')) {
445
    function mb_encode_numericentity($str, $convmap, $encoding) {
446
      return htmlspecialchars($str);
447
    }
448
  }
449
  
450
  if (!function_exists('mb_convert_case')) {
451
    function mb_convert_case($str, $mode = MB_CASE_UPPER, $encoding = array()) {
452
      switch($mode) {
453
        case MB_CASE_UPPER: return mb_strtoupper($str);
454
        case MB_CASE_LOWER: return mb_strtolower($str);
455
        case MB_CASE_TITLE: return ucwords(mb_strtolower($str));
456
        default: return $str;
457
      }
458
    }
459
  }
460
  
461
  if (!function_exists('mb_list_encodings')) {
462
    function mb_list_encodings() {
463
      return array(
464
        "ISO-8859-1",
465
        "UTF-8",
466
        "8bit",
467
      );
468
    }
469
  }
470
}
471
472
/** 
473
 * Decoder for RLE8 compression in windows bitmaps
474
 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
475
 *
476
 * @param string  $str   Data to decode
477
 * @param integer $width Image width
478
 *
479
 * @return string
480
 */
481
function rle8_decode ($str, $width){
482
  $lineWidth = $width + (3 - ($width-1) % 4);
483
  $out = '';
484
  $cnt = strlen($str);
485
  
486
  for ($i = 0; $i <$cnt; $i++) {
487
    $o = ord($str[$i]);
488
    switch ($o){
489
      case 0: # ESCAPE
490
        $i++;
491
        switch (ord($str[$i])){
492 View Code Duplication
          case 0: # NEW LINE
493
            $padCnt = $lineWidth - strlen($out)%$lineWidth;
494
            if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
495
            break;
496 View Code Duplication
          case 1: # END OF FILE
497
            $padCnt = $lineWidth - strlen($out)%$lineWidth;
498
            if ($padCnt<$lineWidth) $out .= str_repeat(chr(0), $padCnt); # pad line
499
            break 3;
500
          case 2: # DELTA
501
            $i += 2;
502
            break;
503
          default: # ABSOLUTE MODE
504
            $num = ord($str[$i]);
505
            for ($j = 0; $j < $num; $j++)
506
              $out .= $str[++$i];
507
            if ($num % 2) $i++;
508
        }
509
      break;
510
      default:
511
      $out .= str_repeat($str[++$i], $o);
512
    }
513
  }
514
  return $out;
515
}
516
517
/** 
518
 * Decoder for RLE4 compression in windows bitmaps
519
 * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp
520
 *
521
 * @param string  $str   Data to decode
522
 * @param integer $width Image width
523
 *
524
 * @return string
525
 */
526
function rle4_decode ($str, $width) {
527
  $w = floor($width/2) + ($width % 2);
528
  $lineWidth = $w + (3 - ( ($width-1) / 2) % 4);    
529
  $pixels = array();
530
  $cnt = strlen($str);
531
  $c = 0;
532
  
533
  for ($i = 0; $i < $cnt; $i++) {
534
    $o = ord($str[$i]);
535
    switch ($o) {
536
      case 0: # ESCAPE
537
        $i++;
538
        switch (ord($str[$i])){
539
          case 0: # NEW LINE
540
            while (count($pixels)%$lineWidth != 0) {
541
              $pixels[] = 0;
542
            }
543
            break;
544
          case 1: # END OF FILE
545
            while (count($pixels)%$lineWidth != 0) {
546
              $pixels[] = 0;
547
            }
548
            break 3;
549
          case 2: # DELTA
550
            $i += 2;
551
            break;
552
          default: # ABSOLUTE MODE
553
            $num = ord($str[$i]);
554
            for ($j = 0; $j < $num; $j++) {
555
              if ($j%2 == 0) {
556
                $c = ord($str[++$i]);
557
                $pixels[] = ($c & 240)>>4;
558
              }
559
              else {
560
                $pixels[] = $c & 15;
561
              }
562
            }
563
            
564
            if ($num % 2 == 0) {
565
              $i++;
566
            }
567
       }
568
       break;
569
      default:
570
        $c = ord($str[++$i]);
571
        for ($j = 0; $j < $o; $j++) {
572
          $pixels[] = ($j%2==0 ? ($c & 240)>>4 : $c & 15);
573
        }
574
    }
575
  }
576
  
577
  $out = '';
578
  if (count($pixels)%2) {
579
    $pixels[] = 0;
580
  }
581
  
582
  $cnt = count($pixels)/2;
583
  
584
  for ($i = 0; $i < $cnt; $i++) {
585
    $out .= chr(16*$pixels[2*$i] + $pixels[2*$i+1]);
586
  }
587
    
588
  return $out;
589
} 
590
591
if ( !function_exists("imagecreatefrombmp") ) {
592
593
/**
594
 * Credit goes to mgutt 
595
 * http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm
596
 * Modified by Fabien Menager to support RGB555 BMP format
597
 */
598
function imagecreatefrombmp($filename) {
599
  if (!function_exists("imagecreatetruecolor")) {
600
    trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR);
601
    return false;
602
  }
603
604
  // version 1.00
605
  if (!($fh = fopen($filename, 'rb'))) {
606
    trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING);
607
    return false;
608
  }
609
  
610
  $bytes_read = 0;
611
  
612
  // read file header
613
  $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14));
614
  
615
  // check for bitmap
616 View Code Duplication
  if ($meta['type'] != 19778) {
617
    trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING);
618
    return false;
619
  }
620
  
621
  // read image header
622
  $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40));
623
  $bytes_read += 40;
624
  
625
  // read additional bitfield header
626
  if ($meta['compression'] == 3) {
627
    $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12));
628
    $bytes_read += 12;
629
  }
630
  
631
  // set bytes and padding
632
  $meta['bytes'] = $meta['bits'] / 8;
633
  $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4)- floor($meta['width'] * $meta['bytes'] / 4)));
634
  if ($meta['decal'] == 4) {
635
    $meta['decal'] = 0;
636
  }
637
  
638
  // obtain imagesize
639
  if ($meta['imagesize'] < 1) {
640
    $meta['imagesize'] = $meta['filesize'] - $meta['offset'];
641
    // in rare cases filesize is equal to offset so we need to read physical size
642
    if ($meta['imagesize'] < 1) {
643
      $meta['imagesize'] = @filesize($filename) - $meta['offset'];
644 View Code Duplication
      if ($meta['imagesize'] < 1) {
645
        trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING);
646
        return false;
647
      }
648
    }
649
  }
650
  
651
  // calculate colors
652
  $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors'];
653
  
654
  // read color palette
655
  $palette = array();
656
  if ($meta['bits'] < 16) {
657
    $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4));
658
    // in rare cases the color value is signed
659
    if ($palette[1] < 0) {
660
      foreach ($palette as $i => $color) {
661
        $palette[$i] = $color + 16777216;
662
      }
663
    }
664
  }
665
  
666
  // ignore extra bitmap headers
667
  if ($meta['headersize'] > $bytes_read) {
668
    fread($fh, $meta['headersize'] - $bytes_read);
669
  }
670
  
671
  // create gd image
672
  $im = imagecreatetruecolor($meta['width'], $meta['height']);
673
  $data = fread($fh, $meta['imagesize']);
674
  
675
  // uncompress data
676
  switch ($meta['compression']) {
677
    case 1: $data = rle8_decode($data, $meta['width']); break;
678
    case 2: $data = rle4_decode($data, $meta['width']); break;
679
  }
680
681
  $p = 0;
682
  $vide = chr(0);
683
  $y = $meta['height'] - 1;
684
  $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!';
685
686
  // loop through the image data beginning with the lower left corner
687
  while ($y >= 0) {
688
    $x = 0;
689
    while ($x < $meta['width']) {
690
      switch ($meta['bits']) {
691
        case 32:
692
        case 24:
693 View Code Duplication
          if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) {
694
            trigger_error($error, E_USER_WARNING);
695
            return $im;
696
          }
697
          $color = unpack('V', $part . $vide);
698
          break;
699
        case 16:
700 View Code Duplication
          if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) {
701
            trigger_error($error, E_USER_WARNING);
702
            return $im;
703
          }
704
          $color = unpack('v', $part);
705
706
          if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) {
707
            $color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555
708
          }
709
          else { 
710
            $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565
711
          }
712
          break;
713
        case 8:
714
          $color = unpack('n', $vide . substr($data, $p, 1));
715
          $color[1] = $palette[ $color[1] + 1 ];
716
          break;
717
        case 4:
718
          $color = unpack('n', $vide . substr($data, floor($p), 1));
719
          $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F;
720
          $color[1] = $palette[ $color[1] + 1 ];
721
          break;
722
        case 1:
723
          $color = unpack('n', $vide . substr($data, floor($p), 1));
724
          switch (($p * 8) % 8) {
725
            case 0: $color[1] =  $color[1] >> 7; break;
726
            case 1: $color[1] = ($color[1] & 0x40) >> 6; break;
727
            case 2: $color[1] = ($color[1] & 0x20) >> 5; break;
728
            case 3: $color[1] = ($color[1] & 0x10) >> 4; break;
729
            case 4: $color[1] = ($color[1] & 0x8 ) >> 3; break;
730
            case 5: $color[1] = ($color[1] & 0x4 ) >> 2; break;
731
            case 6: $color[1] = ($color[1] & 0x2 ) >> 1; break;
732
            case 7: $color[1] = ($color[1] & 0x1 );      break;
733
          }
734
          $color[1] = $palette[ $color[1] + 1 ];
735
          break;
736
        default:
737
          trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING);
738
          return false;
739
      }
740
      imagesetpixel($im, $x, $y, $color[1]);
741
      $x++;
742
      $p += $meta['bytes'];
743
    }
744
    $y--;
745
    $p += $meta['decal'];
746
  }
747
  fclose($fh);
748
  return $im;
749
}
750
}
751
752
/**
753
 * getimagesize doesn't give a good size for 32bit BMP image v5
754
 * 
755
 * @param string $filename
756
 * @return array The same format as getimagesize($filename)
757
 */
758
function dompdf_getimagesize($filename, $context = null) {
759
  static $cache = array();
760
  
761
  if ( isset($cache[$filename]) ) {
762
    return $cache[$filename];
763
  }
764
  
765
  list($width, $height, $type) = getimagesize($filename);
766
  
767
  if ( $width == null || $height == null ) {
768
    $data = file_get_contents($filename, null, $context, 0, 26);
769
    
770
    if ( substr($data, 0, 2) === "BM" ) {
771
      $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data);
772
      $width  = (int)$meta['width'];
773
      $height = (int)$meta['height'];
774
      $type   = IMAGETYPE_BMP;
775
    }
776
  }
777
  
778
  return $cache[$filename] = array($width, $height, $type);
779
}
780
781
/**
782
 * Converts a CMYK color to RGB
783
 * 
784
 * @param float|float[] $c
785
 * @param float         $m
786
 * @param float         $y
787
 * @param float         $k
788
 *
789
 * @return float[]
790
 */
791
function cmyk_to_rgb($c, $m = null, $y = null, $k = null) {
792
  if (is_array($c)) {
793
    list($c, $m, $y, $k) = $c;
794
  }
795
  
796
  $c *= 255;
797
  $m *= 255;
798
  $y *= 255;
799
  $k *= 255;
800
  
801
  $r = (1 - round(2.55 * ($c+$k))) ;
802
  $g = (1 - round(2.55 * ($m+$k))) ;
803
  $b = (1 - round(2.55 * ($y+$k))) ;
804
    
805
  if ($r < 0) $r = 0;
806
  if ($g < 0) $g = 0;
807
  if ($b < 0) $b = 0;
808
    
809
  return array(
810
    $r, $g, $b,
811
    "r" => $r, "g" => $g, "b" => $b
812
  );
813
}
814
815
function unichr($c) {
816
  if ($c <= 0x7F) {
817
    return chr($c);
818
  }
819
  else if ($c <= 0x7FF) {
820
    return chr(0xC0 | $c >>  6) . chr(0x80 | $c & 0x3F);
821
  }
822
  else if ($c <= 0xFFFF) {
823
    return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F)
824
                                . chr(0x80 | $c & 0x3F);
825
  }
826
  else if ($c <= 0x10FFFF) {
827
    return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F)
828
                                . chr(0x80 | $c >> 6 & 0x3F)
829
                                . chr(0x80 | $c & 0x3F);
830
  }
831
  return false;
832
}
833
834
if ( !function_exists("date_default_timezone_get") ) {
835
  function date_default_timezone_get() {
836
    return "";
837
  }
838
  
839
  function date_default_timezone_set($timezone_identifier) {
840
    return true;
841
  }
842
}
843
844
/**
845
 * Stores warnings in an array for display later
846
 * This function allows warnings generated by the DomDocument parser
847
 * and CSS loader ({@link Stylesheet}) to be captured and displayed
848
 * later.  Without this function, errors are displayed immediately and
849
 * PDF streaming is impossible.
850
 * @see http://www.php.net/manual/en/function.set-error_handler.php
851
 *
852
 * @param int    $errno
853
 * @param string $errstr
854
 * @param string $errfile
855
 * @param string $errline
856
 *
857
 * @throws DOMPDF_Exception
858
 */
859
function record_warnings($errno, $errstr, $errfile, $errline) {
860
861
  // Not a warning or notice
862
  if ( !($errno & (E_WARNING | E_NOTICE | E_USER_NOTICE | E_USER_WARNING )) ) {
863
    throw new DOMPDF_Exception($errstr . " $errno");
864
  }
865
866
  global $_dompdf_warnings;
867
  global $_dompdf_show_warnings;
868
869
  if ( $_dompdf_show_warnings ) {
870
    echo $errstr . "\n";
871
  }
872
873
  $_dompdf_warnings[] = $errstr;
874
}
875
876
/**
877
 * Print a useful backtrace
878
 */
879
function bt() {
880
  if ( php_sapi_name() !== "cli") {
881
    echo "<pre>";
882
  }
883
    
884
  $bt = debug_backtrace();
885
886
  array_shift($bt); // remove actual bt() call
887
  echo "\n";
888
889
  $i = 0;
890
  foreach ($bt as $call) {
891
    $file = basename($call["file"]) . " (" . $call["line"] . ")";
892
    if ( isset($call["class"]) ) {
893
      $func = $call["class"] . "->" . $call["function"] . "()";
894
    }
895
    else {
896
      $func = $call["function"] . "()";
897
    }
898
899
    echo "#" . str_pad($i, 2, " ", STR_PAD_RIGHT) . ": " . str_pad($file.":", 42) . " $func\n";
900
    $i++;
901
  }
902
  echo "\n";
903
  
904
  if ( php_sapi_name() !== "cli") {
905
    echo "</pre>";
906
  }
907
}
908
909
/**
910
 * Print debug messages
911
 *
912
 * @param string $type The type of debug messages to print
913
 * @param string $msg  The message to show
914
 */
915
function dompdf_debug($type, $msg) {
916
  global $_DOMPDF_DEBUG_TYPES, $_dompdf_show_warnings, $_dompdf_debug;
917
  if ( isset($_DOMPDF_DEBUG_TYPES[$type]) && ($_dompdf_show_warnings || $_dompdf_debug) ) {
918
    $arr = debug_backtrace();
919
920
    echo basename($arr[0]["file"]) . " (" . $arr[0]["line"] ."): " . $arr[1]["function"] . ": ";
921
    pre_r($msg);
922
  }
923
}
924
925
if ( !function_exists("print_memusage") ) {
926
/**
927
 * Dump memory usage
928
 */
929
function print_memusage() {
930
  global $memusage;
931
  echo "Memory Usage\n";
932
  $prev = 0;
933
  $initial = reset($memusage);
934
  echo str_pad("Initial:", 40) . $initial . "\n\n";
935
936
  foreach ($memusage as $key=>$mem) {
937
    $mem -= $initial;
938
    echo str_pad("$key:" , 40);
939
    echo str_pad("$mem", 12) . "(diff: " . ($mem - $prev) . ")\n";
940
    $prev = $mem;
941
  }
942
943
  echo "\n" . str_pad("Total:", 40) . memory_get_usage() . "\n";
944
}
945
}
946
947
if ( !function_exists("enable_mem_profile") ) {
948
/**
949
 * Initialize memory profiling code
950
 */
951
function enable_mem_profile() {
952
  global $memusage;
953
  $memusage = array("Startup" => memory_get_usage());
954
  register_shutdown_function("print_memusage");
955
}
956
}
957
958
if ( !function_exists("mark_memusage") ) {
959
/**
960
 * Record the current memory usage
961
 *
962
 * @param string $location a meaningful location
963
 */
964
function mark_memusage($location) {
965
  global $memusage;
966
  if ( isset($memusage) ) {
967
    $memusage[$location] = memory_get_usage();
968
  }
969
}
970
}
971
972
if ( !function_exists('sys_get_temp_dir')) {
973
/**
974
 * Find the current system temporary directory
975
 *
976
 * @link http://us.php.net/manual/en/function.sys-get-temp-dir.php#85261
977
 */
978
function sys_get_temp_dir() {
979
  if (!empty($_ENV['TMP'])) {
980
    return realpath($_ENV['TMP']);
981
  }
982
  
983
  if (!empty($_ENV['TMPDIR'])) {
984
    return realpath( $_ENV['TMPDIR']);
985
  }
986
  
987
  if (!empty($_ENV['TEMP'])) {
988
    return realpath( $_ENV['TEMP']);
989
  }
990
  
991
  $tempfile=tempnam(uniqid(rand(), true), '');
992
  if (file_exists($tempfile)) {
993
    unlink($tempfile);
994
    return realpath(dirname($tempfile));
995
  }
996
}
997
}
998
999
if ( function_exists("memory_get_peak_usage") ) {
1000
  function DOMPDF_memory_usage(){
1001
    return memory_get_peak_usage(true);
1002
  }
1003
}
1004
else if ( function_exists("memory_get_usage") ) {
1005
  function DOMPDF_memory_usage(){
0 ignored issues
show
Best Practice introduced by
The function DOMPDF_memory_usage() has been defined more than once; this definition is ignored, only the first definition in this file (L1000-1002) is considered.

This check looks for functions that have already been defined in the same file.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
1006
    return memory_get_usage(true);
1007
  }
1008
}
1009
else {
1010
  function DOMPDF_memory_usage(){
0 ignored issues
show
Best Practice introduced by
The function DOMPDF_memory_usage() has been defined more than once; this definition is ignored, only the first definition in this file (L1000-1002) is considered.

This check looks for functions that have already been defined in the same file.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
1011
    return "N/A";
1012
  }
1013
}
1014
1015
1016
/**
1017
 * Affect null to the unused objects
1018
 * @param mixed $object
1019
 */
1020
if ( PHP_VERSION_ID < 50300 ) {
1021
  function clear_object(&$object) {
1022
    if ( is_object($object) ) {
1023
      foreach ($object as &$value) {
1024
        clear_object($value);
1025
      }
1026
    }
1027
    
1028
    $object = null;
1029
    unset($object);
1030
  }
1031
}
1032
else {
1033
  function clear_object(&$object) {
0 ignored issues
show
Best Practice introduced by
The function clear_object() has been defined more than once; this definition is ignored, only the first definition in this file (L1021-1030) is considered.

This check looks for functions that have already been defined in the same file.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
1034
    // void
1035
  } 
1036
}
1037