PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/standard - image.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 492 598 82.3 %
Date: 2014-10-14 Functions: 34 35 97.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
      16             :    |          Marcus Boerger <helly@php.net>                              |
      17             :    +----------------------------------------------------------------------+
      18             :  */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #include "php.h"
      23             : #include <stdio.h>
      24             : #if HAVE_FCNTL_H
      25             : #include <fcntl.h>
      26             : #endif
      27             : #include "fopen_wrappers.h"
      28             : #include "ext/standard/fsock.h"
      29             : #if HAVE_UNISTD_H
      30             : #include <unistd.h>
      31             : #endif
      32             : #include "php_image.h"
      33             : #ifdef PHP_WIN32
      34             : #include "win32/php_stdint.h"
      35             : #endif
      36             : 
      37             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
      38             : #include "zlib.h"
      39             : #endif
      40             : 
      41             : /* file type markers */
      42             : PHPAPI const char php_sig_gif[3] = {'G', 'I', 'F'};
      43             : PHPAPI const char php_sig_psd[4] = {'8', 'B', 'P', 'S'};
      44             : PHPAPI const char php_sig_bmp[2] = {'B', 'M'};
      45             : PHPAPI const char php_sig_swf[3] = {'F', 'W', 'S'};
      46             : PHPAPI const char php_sig_swc[3] = {'C', 'W', 'S'};
      47             : PHPAPI const char php_sig_jpg[3] = {(char) 0xff, (char) 0xd8, (char) 0xff};
      48             : PHPAPI const char php_sig_png[8] = {(char) 0x89, (char) 0x50, (char) 0x4e, (char) 0x47,
      49             :                                     (char) 0x0d, (char) 0x0a, (char) 0x1a, (char) 0x0a};
      50             : PHPAPI const char php_sig_tif_ii[4] = {'I','I', (char)0x2A, (char)0x00};
      51             : PHPAPI const char php_sig_tif_mm[4] = {'M','M', (char)0x00, (char)0x2A};
      52             : PHPAPI const char php_sig_jpc[3]  = {(char)0xff, (char)0x4f, (char)0xff};
      53             : PHPAPI const char php_sig_jp2[12] = {(char)0x00, (char)0x00, (char)0x00, (char)0x0c,
      54             :                                      (char)0x6a, (char)0x50, (char)0x20, (char)0x20,
      55             :                                      (char)0x0d, (char)0x0a, (char)0x87, (char)0x0a};
      56             : PHPAPI const char php_sig_iff[4] = {'F','O','R','M'};
      57             : PHPAPI const char php_sig_ico[4] = {(char)0x00, (char)0x00, (char)0x01, (char)0x00};
      58             : 
      59             : /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */
      60             : /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */
      61             : 
      62             : /* return info as a struct, to make expansion easier */
      63             : 
      64             : struct gfxinfo {
      65             :         unsigned int width;
      66             :         unsigned int height;
      67             :         unsigned int bits;
      68             :         unsigned int channels;
      69             : };
      70             : 
      71             : /* {{{ PHP_MINIT_FUNCTION(imagetypes)
      72             :  * Register IMAGETYPE_<xxx> constants used by GetImageSize(), image_type_to_mime_type, ext/exif */
      73       20401 : PHP_MINIT_FUNCTION(imagetypes)
      74             : {
      75       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_GIF",     IMAGE_FILETYPE_GIF,     CONST_CS | CONST_PERSISTENT);
      76       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG",    IMAGE_FILETYPE_JPEG,    CONST_CS | CONST_PERSISTENT);
      77       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_PNG",     IMAGE_FILETYPE_PNG,     CONST_CS | CONST_PERSISTENT);
      78       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_SWF",     IMAGE_FILETYPE_SWF,     CONST_CS | CONST_PERSISTENT);
      79       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_PSD",     IMAGE_FILETYPE_PSD,     CONST_CS | CONST_PERSISTENT);
      80       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_BMP",     IMAGE_FILETYPE_BMP,     CONST_CS | CONST_PERSISTENT);
      81       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_II", IMAGE_FILETYPE_TIFF_II, CONST_CS | CONST_PERSISTENT);
      82       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_MM", IMAGE_FILETYPE_TIFF_MM, CONST_CS | CONST_PERSISTENT);
      83       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPC",     IMAGE_FILETYPE_JPC,     CONST_CS | CONST_PERSISTENT);
      84       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JP2",     IMAGE_FILETYPE_JP2,     CONST_CS | CONST_PERSISTENT);
      85       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPX",     IMAGE_FILETYPE_JPX,     CONST_CS | CONST_PERSISTENT);
      86       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JB2",     IMAGE_FILETYPE_JB2,     CONST_CS | CONST_PERSISTENT);
      87             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
      88       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_SWC",     IMAGE_FILETYPE_SWC,     CONST_CS | CONST_PERSISTENT);
      89             : #endif  
      90       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_IFF",     IMAGE_FILETYPE_IFF,     CONST_CS | CONST_PERSISTENT);
      91       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_WBMP",    IMAGE_FILETYPE_WBMP,    CONST_CS | CONST_PERSISTENT);
      92       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG2000",IMAGE_FILETYPE_JPC,     CONST_CS | CONST_PERSISTENT); /* keep alias */
      93       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_XBM",     IMAGE_FILETYPE_XBM,     CONST_CS | CONST_PERSISTENT);
      94       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_ICO",     IMAGE_FILETYPE_ICO,     CONST_CS | CONST_PERSISTENT);
      95       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT);
      96       20401 :         REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT",   IMAGE_FILETYPE_COUNT,   CONST_CS | CONST_PERSISTENT);
      97       20401 :         return SUCCESS;
      98             : }
      99             : /* }}} */
     100             : 
     101             : /* {{{ php_handle_gif
     102             :  * routine to handle GIF files. If only everything were that easy... ;} */
     103           7 : static struct gfxinfo *php_handle_gif (php_stream * stream TSRMLS_DC)
     104             : {
     105           7 :         struct gfxinfo *result = NULL;
     106             :         unsigned char dim[5];
     107             : 
     108           7 :         if (php_stream_seek(stream, 3, SEEK_CUR))
     109           0 :                 return NULL;
     110             : 
     111           7 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     112           0 :                 return NULL;
     113             : 
     114           7 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     115           7 :         result->width    = (unsigned int)dim[0] | (((unsigned int)dim[1])<<8);
     116           7 :         result->height   = (unsigned int)dim[2] | (((unsigned int)dim[3])<<8);
     117           7 :         result->bits     = dim[4]&0x80 ? ((((unsigned int)dim[4])&0x07) + 1) : 0;
     118           7 :         result->channels = 3; /* always */
     119             : 
     120           7 :         return result;
     121             : }
     122             : /* }}} */
     123             : 
     124             : /* {{{ php_handle_psd
     125             :  */
     126           2 : static struct gfxinfo *php_handle_psd (php_stream * stream TSRMLS_DC)
     127             : {
     128           2 :         struct gfxinfo *result = NULL;
     129             :         unsigned char dim[8];
     130             : 
     131           2 :         if (php_stream_seek(stream, 11, SEEK_CUR))
     132           0 :                 return NULL;
     133             : 
     134           2 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     135           0 :                 return NULL;
     136             : 
     137           2 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     138           2 :         result->height   =  (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]);
     139           2 :         result->width    =  (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]);
     140             : 
     141           2 :         return result;
     142             : }
     143             : /* }}} */
     144             : 
     145             : /* {{{ php_handle_bmp
     146             :  */
     147           7 : static struct gfxinfo *php_handle_bmp (php_stream * stream TSRMLS_DC)
     148             : {
     149           7 :         struct gfxinfo *result = NULL;
     150             :         unsigned char dim[16];
     151             :         int size;
     152             : 
     153           7 :         if (php_stream_seek(stream, 11, SEEK_CUR))
     154           0 :                 return NULL;
     155             : 
     156           7 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     157           0 :                 return NULL;
     158             : 
     159           7 :         size   = (((unsigned int)dim[ 3]) << 24) + (((unsigned int)dim[ 2]) << 16) + (((unsigned int)dim[ 1]) << 8) + ((unsigned int) dim[ 0]);
     160           7 :         if (size == 12) {
     161           0 :                 result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo));
     162           0 :                 result->width    =  (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]);
     163           0 :                 result->height   =  (((unsigned int)dim[ 7]) << 8) + ((unsigned int) dim[ 6]);
     164           0 :                 result->bits     =  ((unsigned int)dim[11]);
     165          14 :         } else if (size > 12 && (size <= 64 || size == 108 || size == 124)) {
     166           7 :                 result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo));
     167           7 :                 result->width    =  (((unsigned int)dim[ 7]) << 24) + (((unsigned int)dim[ 6]) << 16) + (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]);
     168           7 :                 result->height   =  (((unsigned int)dim[11]) << 24) + (((unsigned int)dim[10]) << 16) + (((unsigned int)dim[ 9]) << 8) + ((unsigned int) dim[ 8]);
     169           7 :                 result->height   =  abs((int32_t)result->height);
     170           7 :                 result->bits     =  (((unsigned int)dim[15]) <<  8) +  ((unsigned int)dim[14]);
     171             :         } else {
     172           0 :                 return NULL;
     173             :         }
     174             : 
     175           7 :         return result;
     176             : }
     177             : /* }}} */
     178             : 
     179             : /* {{{ php_swf_get_bits
     180             :  * routines to handle SWF files. */
     181          30 : static unsigned long int php_swf_get_bits (unsigned char* buffer, unsigned int pos, unsigned int count)
     182             : {
     183             :         unsigned int loop;
     184          30 :         unsigned long int result = 0;
     185             : 
     186         412 :         for (loop = pos; loop < pos + count; loop++)
     187             :         {
     188         382 :                 result = result +
     189         382 :                         ((((buffer[loop / 8]) >> (7 - (loop % 8))) & 0x01) << (count - (loop - pos) - 1));
     190             :         }
     191          30 :         return result;
     192             : }
     193             : /* }}} */
     194             : 
     195             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
     196             : /* {{{ php_handle_swc
     197             :  */
     198           3 : static struct gfxinfo *php_handle_swc(php_stream * stream TSRMLS_DC)
     199             : {
     200           3 :         struct gfxinfo *result = NULL;
     201             : 
     202             :         long bits;
     203             :         unsigned char a[64];
     204           3 :         unsigned long len=64, szlength;
     205           3 :         int factor = 1,maxfactor = 16;
     206           3 :         int status = 0;
     207           3 :         char *b, *buf = NULL;
     208             :         zend_string *bufz;
     209             : 
     210           3 :         b = ecalloc(1, len + 1);
     211             : 
     212           3 :         if (php_stream_seek(stream, 5, SEEK_CUR))
     213           0 :                 return NULL;
     214             : 
     215           3 :         if (php_stream_read(stream, a, sizeof(a)) != sizeof(a))
     216           0 :                 return NULL;
     217             : 
     218           3 :         if (uncompress(b, &len, a, sizeof(a)) != Z_OK) {
     219             :                 /* failed to decompress the file, will try reading the rest of the file */
     220           3 :                 if (php_stream_seek(stream, 8, SEEK_SET))
     221           0 :                         return NULL;
     222             : 
     223           3 :                 bufz = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0);
     224             :                 
     225             :                 /*
     226             :                  * zlib::uncompress() wants to know the output data length
     227             :                  * if none was given as a parameter
     228             :                  * we try from input length * 2 up to input length * 2^8
     229             :                  * doubling it whenever it wasn't big enough
     230             :                  * that should be eneugh for all real life cases
     231             :                 */
     232             :                 
     233             :                 do {
     234           3 :                         szlength = bufz->len * (1<<factor++);
     235           3 :                         buf = (char *) erealloc(buf, szlength);
     236           3 :                         status = uncompress(buf, &szlength, bufz->val, bufz->len);
     237           3 :                 } while ((status==Z_BUF_ERROR)&&(factor<maxfactor));
     238             :                 
     239           3 :                 if (bufz) {
     240             :                         zend_string_release(bufz);
     241             :                 }       
     242             :                 
     243           3 :                 if (status == Z_OK) {
     244           3 :                          memcpy(b, buf, len);
     245             :                 }
     246             :                 
     247           3 :                 if (buf) { 
     248           3 :                         efree(buf);
     249             :                 }       
     250             :         }
     251             :         
     252           3 :         if (!status) {
     253           3 :                 result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo));
     254           3 :                 bits = php_swf_get_bits (b, 0, 5);
     255           3 :                 result->width = (php_swf_get_bits (b, 5 + bits, bits) -
     256             :                         php_swf_get_bits (b, 5, bits)) / 20;
     257           3 :                 result->height = (php_swf_get_bits (b, 5 + (3 * bits), bits) -
     258             :                         php_swf_get_bits (b, 5 + (2 * bits), bits)) / 20;
     259             :         } else {
     260           0 :                 result = NULL;
     261             :         }       
     262             :                 
     263           3 :         efree (b);
     264           3 :         return result;
     265             : }
     266             : /* }}} */
     267             : #endif
     268             : 
     269             : /* {{{ php_handle_swf
     270             :  */
     271           3 : static struct gfxinfo *php_handle_swf (php_stream * stream TSRMLS_DC)
     272             : {
     273           3 :         struct gfxinfo *result = NULL;
     274             :         long bits;
     275             :         unsigned char a[32];
     276             : 
     277           3 :         if (php_stream_seek(stream, 5, SEEK_CUR))
     278           0 :                 return NULL;
     279             : 
     280           3 :         if (php_stream_read(stream, (char*)a, sizeof(a)) != sizeof(a))
     281           0 :                 return NULL;
     282             : 
     283           3 :         result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo));
     284           3 :         bits = php_swf_get_bits (a, 0, 5);
     285           3 :         result->width = (php_swf_get_bits (a, 5 + bits, bits) -
     286             :                 php_swf_get_bits (a, 5, bits)) / 20;
     287           3 :         result->height = (php_swf_get_bits (a, 5 + (3 * bits), bits) -
     288             :                 php_swf_get_bits (a, 5 + (2 * bits), bits)) / 20;
     289           3 :         result->bits     = 0;
     290           3 :         result->channels = 0;
     291           3 :         return result;
     292             : }
     293             : /* }}} */
     294             : 
     295             : /* {{{ php_handle_png
     296             :  * routine to handle PNG files */
     297           7 : static struct gfxinfo *php_handle_png (php_stream * stream TSRMLS_DC)
     298             : {
     299           7 :         struct gfxinfo *result = NULL;
     300             :         unsigned char dim[9];
     301             : /* Width:              4 bytes
     302             :  * Height:             4 bytes
     303             :  * Bit depth:          1 byte
     304             :  * Color type:         1 byte
     305             :  * Compression method: 1 byte
     306             :  * Filter method:      1 byte
     307             :  * Interlace method:   1 byte
     308             :  */
     309             : 
     310           7 :         if (php_stream_seek(stream, 8, SEEK_CUR))
     311           0 :                 return NULL;
     312             : 
     313           7 :         if((php_stream_read(stream, (char*)dim, sizeof(dim))) < sizeof(dim))
     314           0 :                 return NULL;
     315             : 
     316           7 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     317           7 :         result->width  = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]);
     318           7 :         result->height = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]);
     319           7 :         result->bits   = (unsigned int)dim[8];
     320           7 :         return result;
     321             : }
     322             : /* }}} */
     323             : 
     324             : /* routines to handle JPEG data */
     325             : 
     326             : /* some defines for the different JPEG block types */
     327             : #define M_SOF0  0xC0                    /* Start Of Frame N */
     328             : #define M_SOF1  0xC1                    /* N indicates which compression process */
     329             : #define M_SOF2  0xC2                    /* Only SOF0-SOF2 are now in common use */
     330             : #define M_SOF3  0xC3
     331             : #define M_SOF5  0xC5                    /* NB: codes C4 and CC are NOT SOF markers */
     332             : #define M_SOF6  0xC6
     333             : #define M_SOF7  0xC7
     334             : #define M_SOF9  0xC9
     335             : #define M_SOF10 0xCA
     336             : #define M_SOF11 0xCB
     337             : #define M_SOF13 0xCD
     338             : #define M_SOF14 0xCE
     339             : #define M_SOF15 0xCF
     340             : #define M_SOI   0xD8
     341             : #define M_EOI   0xD9                    /* End Of Image (end of datastream) */
     342             : #define M_SOS   0xDA                    /* Start Of Scan (begins compressed data) */
     343             : #define M_APP0  0xe0
     344             : #define M_APP1  0xe1
     345             : #define M_APP2  0xe2
     346             : #define M_APP3  0xe3
     347             : #define M_APP4  0xe4
     348             : #define M_APP5  0xe5
     349             : #define M_APP6  0xe6
     350             : #define M_APP7  0xe7
     351             : #define M_APP8  0xe8
     352             : #define M_APP9  0xe9
     353             : #define M_APP10 0xea
     354             : #define M_APP11 0xeb
     355             : #define M_APP12 0xec
     356             : #define M_APP13 0xed
     357             : #define M_APP14 0xee
     358             : #define M_APP15 0xef
     359             : #define M_COM   0xFE            /* COMment                                  */
     360             : 
     361             : #define M_PSEUDO 0xFFD8                 /* pseudo marker for start of image(byte 0) */
     362             : 
     363             : /* {{{ php_read2
     364             :  */
     365         228 : static unsigned short php_read2(php_stream * stream TSRMLS_DC)
     366             : {
     367             :         unsigned char a[2];
     368             : 
     369             :         /* return 0 if we couldn't read enough data */
     370         228 :         if((php_stream_read(stream, a, sizeof(a))) < sizeof(a)) return 0;
     371             : 
     372         228 :         return (((unsigned short)a[0]) << 8) + ((unsigned short)a[1]);
     373             : }
     374             : /* }}} */
     375             : 
     376             : /* {{{ php_next_marker
     377             :  * get next marker byte from file */
     378         177 : static unsigned int php_next_marker(php_stream * stream, int last_marker, int comment_correction, int ff_read TSRMLS_DC)
     379             : {
     380         177 :         int a=0, marker;
     381             : 
     382             :         /* get marker byte, swallowing possible padding                           */
     383         179 :         if (last_marker==M_COM && comment_correction) {
     384             :                 /* some software does not count the length bytes of COM section           */
     385             :                 /* one company doing so is very much envolved in JPEG... so we accept too */
     386             :                 /* by the way: some of those companies changed their code now...          */
     387           2 :                 comment_correction = 2;
     388             :         } else {
     389         175 :                 last_marker = 0;
     390         175 :                 comment_correction = 0;
     391             :         }
     392         177 :         if (ff_read) {
     393          30 :                 a = 1; /* already read 0xff in filetype detection */
     394             :         }
     395             :         do {
     396         326 :                 if ((marker = php_stream_getc(stream)) == EOF)
     397             :                 {
     398           0 :                         return M_EOI;/* we hit EOF */
     399             :                 }
     400         326 :                 if (last_marker==M_COM && comment_correction>0)
     401             :                 {
     402           3 :                         if (marker != 0xFF)
     403             :                         {
     404           2 :                                 marker = 0xff;
     405           2 :                                 comment_correction--;
     406             :                         } else {
     407           1 :                                 last_marker = M_PSEUDO; /* stop skipping non 0xff for M_COM */
     408             :                         }
     409             :                 }
     410         326 :                 a++;
     411         326 :         } while (marker == 0xff);
     412         177 :         if (a < 2)
     413             :         {
     414           0 :                 return M_EOI; /* at least one 0xff is needed before marker code */
     415             :         }
     416         177 :         if ( last_marker==M_COM && comment_correction)
     417             :         {
     418           0 :                 return M_EOI; /* ah illegal: char after COM section not 0xFF */
     419             :         }
     420         177 :         return (unsigned int)marker;
     421             : }
     422             : /* }}} */
     423             : 
     424             : /* {{{ php_skip_variable
     425             :  * skip over a variable-length block; assumes proper length marker */
     426          91 : static int php_skip_variable(php_stream * stream TSRMLS_DC)
     427             : {
     428          91 :         zend_off_t length = ((unsigned int)php_read2(stream TSRMLS_CC));
     429             : 
     430          91 :         if (length < 2)      {
     431           0 :                 return 0;
     432             :         }
     433          91 :         length = length - 2;
     434          91 :         php_stream_seek(stream, (zend_long)length, SEEK_CUR);
     435          91 :         return 1;
     436             : }
     437             : /* }}} */
     438             : 
     439             : /* {{{ php_read_APP
     440             :  */
     441          29 : static int php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC)
     442             : {
     443             :         unsigned short length;
     444             :         char *buffer;
     445             :         char markername[16];
     446             :         zval *tmp;
     447             : 
     448          29 :         length = php_read2(stream TSRMLS_CC);
     449          29 :         if (length < 2)      {
     450           0 :                 return 0;
     451             :         }
     452          29 :         length -= 2;                            /* length includes itself */
     453             : 
     454          29 :         buffer = emalloc(length);
     455             : 
     456          29 :         if (php_stream_read(stream, buffer, (zend_long) length) <= 0) {
     457           0 :                 efree(buffer);
     458           0 :                 return 0;
     459             :         }
     460             : 
     461          29 :         snprintf(markername, sizeof(markername), "APP%d", marker - M_APP0);
     462             : 
     463          29 :         if ((tmp = zend_hash_str_find(Z_ARRVAL_P(info), markername, strlen(markername))) == NULL) {
     464             :                 /* XXX we onyl catch the 1st tag of it's kind! */
     465          29 :                 add_assoc_stringl(info, markername, buffer, length);
     466             :         }
     467             : 
     468          29 :         efree(buffer);
     469          29 :         return 1;
     470             : }
     471             : /* }}} */
     472             : 
     473             : /* {{{ php_handle_jpeg
     474             :    main loop to parse JPEG structure */
     475          30 : static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info TSRMLS_DC) 
     476             : {
     477          30 :         struct gfxinfo *result = NULL;
     478          30 :         unsigned int marker = M_PSEUDO;
     479          30 :         unsigned short length, ff_read=1;
     480             : 
     481             :         for (;;) {
     482         177 :                 marker = php_next_marker(stream, marker, 1, ff_read TSRMLS_CC);
     483         177 :                 ff_read = 0;
     484         177 :                 switch (marker) {
     485             :                         case M_SOF0:
     486             :                         case M_SOF1:
     487             :                         case M_SOF2:
     488             :                         case M_SOF3:
     489             :                         case M_SOF5:
     490             :                         case M_SOF6:
     491             :                         case M_SOF7:
     492             :                         case M_SOF9:
     493             :                         case M_SOF10:
     494             :                         case M_SOF11:
     495             :                         case M_SOF13:
     496             :                         case M_SOF14:
     497             :                         case M_SOF15:
     498          30 :                                 if (result == NULL) {
     499             :                                         /* handle SOFn block */
     500          30 :                                         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     501          30 :                                         length = php_read2(stream TSRMLS_CC);
     502          30 :                                         result->bits     = php_stream_getc(stream);
     503          30 :                                         result->height   = php_read2(stream TSRMLS_CC);
     504          30 :                                         result->width    = php_read2(stream TSRMLS_CC);
     505          30 :                                         result->channels = php_stream_getc(stream);
     506          30 :                                         if (!info || length < 8) { /* if we don't want an extanded info -> return */
     507           3 :                                                 return result;
     508             :                                         }
     509          27 :                                         if (php_stream_seek(stream, length - 8, SEEK_CUR)) { /* file error after info */
     510           0 :                                                 return result;
     511             :                                         }
     512             :                                 } else {
     513           0 :                                         if (!php_skip_variable(stream TSRMLS_CC)) {
     514           0 :                                                 return result;
     515             :                                         }
     516             :                                 }
     517          27 :                                 break;
     518             : 
     519             :                         case M_APP0:
     520             :                         case M_APP1:
     521             :                         case M_APP2:
     522             :                         case M_APP3:
     523             :                         case M_APP4:
     524             :                         case M_APP5:
     525             :                         case M_APP6:
     526             :                         case M_APP7:
     527             :                         case M_APP8:
     528             :                         case M_APP9:
     529             :                         case M_APP10:
     530             :                         case M_APP11:
     531             :                         case M_APP12:
     532             :                         case M_APP13:
     533             :                         case M_APP14:
     534             :                         case M_APP15:
     535          32 :                                 if (info) {
     536          29 :                                         if (!php_read_APP(stream, marker, info TSRMLS_CC)) { /* read all the app markes... */
     537           0 :                                                 return result;
     538             :                                         }
     539             :                                 } else {
     540           3 :                                         if (!php_skip_variable(stream TSRMLS_CC)) {
     541           0 :                                                 return result;
     542             :                                         }
     543             :                                 }
     544          32 :                                 break;
     545             : 
     546             :                         case M_SOS:
     547             :                         case M_EOI:
     548          27 :                                 return result;  /* we're about to hit image data, or are at EOF. stop processing. */
     549             :                         
     550             :                         default:
     551          88 :                                 if (!php_skip_variable(stream TSRMLS_CC)) { /* anything else isn't interesting */
     552           0 :                                         return result;
     553             :                                 }
     554             :                                 break;
     555             :                 }
     556         147 :         }
     557             : 
     558             :         return result; /* perhaps image broken -> no info but size */
     559             : }
     560             : /* }}} */
     561             : 
     562             : /* {{{ php_read4
     563             :  */
     564          21 : static unsigned int php_read4(php_stream * stream TSRMLS_DC)
     565             : {
     566             :         unsigned char a[4];
     567             : 
     568             :         /* just return 0 if we hit the end-of-file */
     569          21 :         if ((php_stream_read(stream, (char*)a, sizeof(a))) != sizeof(a)) return 0;
     570             : 
     571          42 :         return (((unsigned int)a[0]) << 24)
     572          21 :              + (((unsigned int)a[1]) << 16)
     573          21 :              + (((unsigned int)a[2]) <<  8)
     574          21 :              + (((unsigned int)a[3]));
     575             : }
     576             : /* }}} */
     577             : 
     578             : /* {{{ JPEG 2000 Marker Codes */
     579             : #define JPEG2000_MARKER_PREFIX 0xFF /* All marker codes start with this */
     580             : #define JPEG2000_MARKER_SOC 0x4F /* Start of Codestream */
     581             : #define JPEG2000_MARKER_SOT 0x90 /* Start of Tile part */
     582             : #define JPEG2000_MARKER_SOD 0x93 /* Start of Data */
     583             : #define JPEG2000_MARKER_EOC 0xD9 /* End of Codestream */
     584             : #define JPEG2000_MARKER_SIZ 0x51 /* Image and tile size */
     585             : #define JPEG2000_MARKER_COD 0x52 /* Coding style default */ 
     586             : #define JPEG2000_MARKER_COC 0x53 /* Coding style component */
     587             : #define JPEG2000_MARKER_RGN 0x5E /* Region of interest */
     588             : #define JPEG2000_MARKER_QCD 0x5C /* Quantization default */
     589             : #define JPEG2000_MARKER_QCC 0x5D /* Quantization component */
     590             : #define JPEG2000_MARKER_POC 0x5F /* Progression order change */
     591             : #define JPEG2000_MARKER_TLM 0x55 /* Tile-part lengths */
     592             : #define JPEG2000_MARKER_PLM 0x57 /* Packet length, main header */
     593             : #define JPEG2000_MARKER_PLT 0x58 /* Packet length, tile-part header */
     594             : #define JPEG2000_MARKER_PPM 0x60 /* Packed packet headers, main header */
     595             : #define JPEG2000_MARKER_PPT 0x61 /* Packed packet headers, tile part header */
     596             : #define JPEG2000_MARKER_SOP 0x91 /* Start of packet */
     597             : #define JPEG2000_MARKER_EPH 0x92 /* End of packet header */
     598             : #define JPEG2000_MARKER_CRG 0x63 /* Component registration */
     599             : #define JPEG2000_MARKER_COM 0x64 /* Comment */
     600             : /* }}} */
     601             : 
     602             : /* {{{ php_handle_jpc
     603             :    Main loop to parse JPEG2000 raw codestream structure */
     604           6 : static struct gfxinfo *php_handle_jpc(php_stream * stream TSRMLS_DC)
     605             : {
     606           6 :         struct gfxinfo *result = NULL;
     607             :         unsigned short dummy_short;
     608             :         int highest_bit_depth, bit_depth;
     609             :         unsigned char first_marker_id;
     610             :         unsigned int i;
     611             : 
     612             :         /* JPEG 2000 components can be vastly different from one another.
     613             :            Each component can be sampled at a different resolution, use
     614             :            a different colour space, have a separate colour depth, and
     615             :            be compressed totally differently! This makes giving a single
     616             :            "bit depth" answer somewhat problematic. For this implementation
     617             :            we'll use the highest depth encountered. */
     618             : 
     619             :         /* Get the single byte that remains after the file type indentification */
     620           6 :         first_marker_id = php_stream_getc(stream);
     621             : 
     622             :         /* Ensure that this marker is SIZ (as is mandated by the standard) */
     623           6 :         if (first_marker_id != JPEG2000_MARKER_SIZ) {
     624           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "JPEG2000 codestream corrupt(Expected SIZ marker not found after SOC)");
     625           0 :                 return NULL;
     626             :         }
     627             : 
     628           6 :         result = (struct gfxinfo *)ecalloc(1, sizeof(struct gfxinfo));
     629             : 
     630           6 :         dummy_short = php_read2(stream TSRMLS_CC); /* Lsiz */
     631           6 :         dummy_short = php_read2(stream TSRMLS_CC); /* Rsiz */
     632           6 :         result->width = php_read4(stream TSRMLS_CC); /* Xsiz */
     633           6 :         result->height = php_read4(stream TSRMLS_CC); /* Ysiz */
     634             : 
     635             : #if MBO_0
     636             :         php_read4(stream TSRMLS_CC); /* XOsiz */
     637             :         php_read4(stream TSRMLS_CC); /* YOsiz */
     638             :         php_read4(stream TSRMLS_CC); /* XTsiz */
     639             :         php_read4(stream TSRMLS_CC); /* YTsiz */
     640             :         php_read4(stream TSRMLS_CC); /* XTOsiz */
     641             :         php_read4(stream TSRMLS_CC); /* YTOsiz */
     642             : #else
     643           6 :         if (php_stream_seek(stream, 24, SEEK_CUR)) {
     644           0 :                 efree(result);
     645           0 :                 return NULL;
     646             :         }
     647             : #endif
     648             : 
     649           6 :         result->channels = php_read2(stream TSRMLS_CC); /* Csiz */
     650           6 :         if (result->channels == 0 && php_stream_eof(stream) || result->channels > 256) {
     651           0 :                 efree(result);
     652           0 :                 return NULL;
     653             :         }
     654             : 
     655             :         /* Collect bit depth info */
     656           6 :         highest_bit_depth = 0;
     657          24 :         for (i = 0; i < result->channels; i++) {
     658          18 :                 bit_depth = php_stream_getc(stream); /* Ssiz[i] */
     659          18 :                 bit_depth++;
     660          18 :                 if (bit_depth > highest_bit_depth) {
     661           6 :                         highest_bit_depth = bit_depth;
     662             :                 }
     663             : 
     664          18 :                 php_stream_getc(stream); /* XRsiz[i] */
     665          18 :                 php_stream_getc(stream); /* YRsiz[i] */
     666             :         }
     667             : 
     668           6 :         result->bits = highest_bit_depth;
     669             : 
     670           6 :         return result;
     671             : }
     672             : /* }}} */
     673             : 
     674             : /* {{{ php_handle_jp2
     675             :    main loop to parse JPEG 2000 JP2 wrapper format structure */
     676           3 : static struct gfxinfo *php_handle_jp2(php_stream *stream TSRMLS_DC)
     677             : {
     678           3 :         struct gfxinfo *result = NULL;
     679             :         unsigned int box_length;
     680             :         unsigned int box_type;
     681           3 :         char jp2c_box_id[] = {(char)0x6a, (char)0x70, (char)0x32, (char)0x63};
     682             : 
     683             :         /* JP2 is a wrapper format for JPEG 2000. Data is contained within "boxes".
     684             :            Boxes themselves can be contained within "super-boxes". Super-Boxes can
     685             :            contain super-boxes which provides us with a hierarchical storage system.
     686             : 
     687             :            It is valid for a JP2 file to contain multiple individual codestreams.
     688             :            We'll just look for the first codestream at the root of the box structure
     689             :            and handle that.
     690             :         */
     691             : 
     692             :         for (;;)
     693             :         {
     694           9 :                 box_length = php_read4(stream TSRMLS_CC); /* LBox */
     695             :                 /* TBox */
     696           9 :                 if (php_stream_read(stream, (void *)&box_type, sizeof(box_type)) != sizeof(box_type)) {
     697             :                         /* Use this as a general "out of stream" error */
     698           0 :                         break;
     699             :                 }
     700             : 
     701           9 :                 if (box_length == 1) {
     702             :                         /* We won't handle XLBoxes */
     703           0 :                         return NULL;
     704             :                 }
     705             : 
     706           9 :                 if (!memcmp(&box_type, jp2c_box_id, 4))
     707             :                 {
     708             :                         /* Skip the first 3 bytes to emulate the file type examination */
     709           3 :                         php_stream_seek(stream, 3, SEEK_CUR);
     710             : 
     711           3 :                         result = php_handle_jpc(stream TSRMLS_CC);
     712           3 :                         break;
     713             :                 }
     714             : 
     715             :                 /* Stop if this was the last box */
     716           6 :                 if ((int)box_length <= 0) {
     717           0 :                         break;
     718             :                 }
     719             : 
     720             :                 /* Skip over LBox (Which includes both TBox and LBox itself */
     721           6 :                 if (php_stream_seek(stream, box_length - 8, SEEK_CUR)) {
     722           0 :                         break;
     723             :                 }
     724           6 :         }
     725             : 
     726           3 :         if (result == NULL) {
     727           0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "JP2 file has no codestreams at root level");
     728             :         }
     729             : 
     730           3 :         return result;
     731             : }
     732             : /* }}} */
     733             : 
     734             : /* {{{ tiff constants
     735             :  */
     736             : PHPAPI const int php_tiff_bytes_per_format[] = {0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8};
     737             : 
     738             : /* uncompressed only */
     739             : #define TAG_IMAGEWIDTH              0x0100
     740             : #define TAG_IMAGEHEIGHT             0x0101
     741             : /* compressed images only */
     742             : #define TAG_COMP_IMAGEWIDTH         0xA002
     743             : #define TAG_COMP_IMAGEHEIGHT        0xA003
     744             : 
     745             : #define TAG_FMT_BYTE       1
     746             : #define TAG_FMT_STRING     2
     747             : #define TAG_FMT_USHORT     3
     748             : #define TAG_FMT_ULONG      4
     749             : #define TAG_FMT_URATIONAL  5
     750             : #define TAG_FMT_SBYTE      6
     751             : #define TAG_FMT_UNDEFINED  7
     752             : #define TAG_FMT_SSHORT     8
     753             : #define TAG_FMT_SLONG      9
     754             : #define TAG_FMT_SRATIONAL 10
     755             : #define TAG_FMT_SINGLE    11
     756             : #define TAG_FMT_DOUBLE    12
     757             : /* }}} */
     758             : 
     759             : /* {{{ php_ifd_get16u
     760             :  * Convert a 16 bit unsigned value from file's native byte order */
     761         150 : static int php_ifd_get16u(void *Short, int motorola_intel)
     762             : {
     763         150 :         if (motorola_intel) {
     764          30 :                 return (((unsigned char *)Short)[0] << 8) | ((unsigned char *)Short)[1];
     765             :         } else {
     766         120 :                 return (((unsigned char *)Short)[1] << 8) | ((unsigned char *)Short)[0];
     767             :         }
     768             : }
     769             : /* }}} */
     770             : 
     771             : /* {{{ php_ifd_get16s
     772             :  * Convert a 16 bit signed value from file's native byte order */
     773           6 : static signed short php_ifd_get16s(void *Short, int motorola_intel)
     774             : {
     775           6 :         return (signed short)php_ifd_get16u(Short, motorola_intel);
     776             : }
     777             : /* }}} */
     778             : 
     779             : /* {{{ php_ifd_get32s
     780             :  * Convert a 32 bit signed value from file's native byte order */
     781          23 : static int php_ifd_get32s(void *Long, int motorola_intel)
     782             : {
     783          23 :         if (motorola_intel) {
     784          16 :                 return  ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16)
     785           8 :                       | (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 );
     786             :         } else {
     787          30 :                 return  ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16)
     788          15 :                       | (((unsigned char *)Long)[1] << 8 ) | (((unsigned char *)Long)[0] << 0 );
     789             :         }
     790             : }
     791             : /* }}} */
     792             : 
     793             : /* {{{ php_ifd_get32u
     794             :  * Convert a 32 bit unsigned value from file's native byte order */
     795          17 : static unsigned php_ifd_get32u(void *Long, int motorola_intel)
     796             : {
     797          17 :         return (unsigned)php_ifd_get32s(Long, motorola_intel) & 0xffffffff;
     798             : }
     799             : /* }}} */
     800             : 
     801             : /* {{{ php_handle_tiff
     802             :    main loop to parse TIFF structure */
     803           4 : static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel TSRMLS_DC)
     804             : {
     805           4 :         struct gfxinfo *result = NULL;
     806             :         int i, num_entries;
     807             :         unsigned char *dir_entry;
     808           4 :         size_t ifd_size, dir_size, entry_value, width=0, height=0, ifd_addr;
     809             :         int entry_tag , entry_type;
     810             :         char *ifd_data, ifd_ptr[4];
     811             : 
     812           4 :         if (php_stream_read(stream, ifd_ptr, 4) != 4)
     813           0 :                 return NULL;
     814           4 :         ifd_addr = php_ifd_get32u(ifd_ptr, motorola_intel);
     815           4 :         if (php_stream_seek(stream, ifd_addr-8, SEEK_CUR))
     816           0 :                 return NULL;
     817           4 :         ifd_size = 2;
     818           4 :         ifd_data = emalloc(ifd_size);
     819           4 :         if (php_stream_read(stream, ifd_data, 2) != 2) {
     820           0 :                 efree(ifd_data);
     821           0 :                 return NULL;
     822             :         }
     823           4 :         num_entries = php_ifd_get16u(ifd_data, motorola_intel);
     824           4 :         dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/;
     825           4 :         ifd_size = dir_size;
     826           4 :         ifd_data = erealloc(ifd_data,ifd_size);
     827           4 :         if (php_stream_read(stream, ifd_data+2, dir_size-2) != dir_size-2) {
     828           0 :                 efree(ifd_data);
     829           0 :                 return NULL;
     830             :         }
     831             :         /* now we have the directory we can look how long it should be */
     832           4 :         ifd_size = dir_size;
     833          57 :         for(i=0;i<num_entries;i++) {
     834          53 :                 dir_entry        = ifd_data+2+i*12;
     835          53 :                 entry_tag    = php_ifd_get16u(dir_entry+0, motorola_intel);
     836          53 :                 entry_type   = php_ifd_get16u(dir_entry+2, motorola_intel);
     837          53 :                 switch(entry_type) {
     838             :                         case TAG_FMT_BYTE:
     839             :                         case TAG_FMT_SBYTE:
     840           0 :                                 entry_value  = (size_t)(dir_entry[8]);
     841           0 :                                 break;
     842             :                         case TAG_FMT_USHORT:
     843          34 :                                 entry_value  = php_ifd_get16u(dir_entry+8, motorola_intel);
     844          34 :                                 break;
     845             :                         case TAG_FMT_SSHORT:
     846           0 :                                 entry_value  = php_ifd_get16s(dir_entry+8, motorola_intel);
     847           0 :                                 break;
     848             :                         case TAG_FMT_ULONG:
     849          13 :                                 entry_value  = php_ifd_get32u(dir_entry+8, motorola_intel);
     850          13 :                                 break;
     851             :                         case TAG_FMT_SLONG:
     852           0 :                                 entry_value  = php_ifd_get32s(dir_entry+8, motorola_intel);
     853           0 :                                 break;
     854             :                         default:
     855           6 :                                 continue;
     856             :                 }
     857          47 :                 switch(entry_tag) {
     858             :                         case TAG_IMAGEWIDTH:
     859             :                         case TAG_COMP_IMAGEWIDTH:
     860           4 :                                 width  = entry_value;
     861           4 :                                 break;
     862             :                         case TAG_IMAGEHEIGHT:
     863             :                         case TAG_COMP_IMAGEHEIGHT:
     864           4 :                                 height = entry_value;
     865             :                                 break;
     866             :                 }
     867             :         }
     868           4 :         efree(ifd_data);
     869           4 :         if ( width && height) {
     870             :                 /* not the same when in for-loop */
     871           4 :                 result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     872           4 :                 result->height   = height;
     873           4 :                 result->width    = width;
     874           4 :                 result->bits     = 0;
     875           4 :                 result->channels = 0;
     876           4 :                 return result;
     877             :         }
     878           0 :         return NULL;
     879             : }
     880             : /* }}} */
     881             : 
     882             : /* {{{ php_handle_psd
     883             :  */
     884           3 : static struct gfxinfo *php_handle_iff(php_stream * stream TSRMLS_DC)
     885             : {
     886             :         struct gfxinfo * result;
     887             :         unsigned char a[10];
     888             :         int chunkId;
     889             :         int size;
     890             :         short width, height, bits;
     891             : 
     892           3 :         if (php_stream_read(stream, a, 8) != 8) {
     893           0 :                 return NULL;
     894             :         }
     895           3 :         if (strncmp(a+4, "ILBM", 4) && strncmp(a+4, "PBM ", 4)) {
     896           0 :                 return NULL;
     897             :         }
     898             : 
     899             :         /* loop chunks to find BMHD chunk */
     900             :         do {
     901           3 :                 if (php_stream_read(stream, (char*)a, 8) != 8) {
     902           0 :                         return NULL;
     903             :                 }
     904           3 :                 chunkId = php_ifd_get32s(a+0, 1);
     905           3 :                 size    = php_ifd_get32s(a+4, 1);
     906           3 :                 if (size < 0) {
     907           0 :                         return NULL;
     908             :                 }
     909           3 :                 if ((size & 1) == 1) {
     910           0 :                         size++;
     911             :                 }
     912           3 :                 if (chunkId == 0x424d4844) { /* BMHD chunk */
     913           3 :                         if (size < 9 || php_stream_read(stream, (char*)a, 9) != 9) {
     914           0 :                                 return NULL;
     915             :                         }
     916           3 :                         width  = php_ifd_get16s(a+0, 1);
     917           3 :                         height = php_ifd_get16s(a+2, 1);
     918           3 :                         bits   = a[8] & 0xff;
     919           3 :                         if (width > 0 && height > 0 && bits > 0 && bits < 33) {
     920           3 :                                 result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     921           3 :                                 result->width    = width;
     922           3 :                                 result->height   = height;
     923           3 :                                 result->bits     = bits;
     924           3 :                                 result->channels = 0;
     925           3 :                                 return result;
     926             :                         }
     927             :                 } else {
     928           0 :                         if (php_stream_seek(stream, size, SEEK_CUR)) {
     929           0 :                                 return NULL;
     930             :                         }
     931             :                 }
     932           0 :         } while (1);
     933             : }
     934             : /* }}} */
     935             : 
     936             : /* {{{ php_get_wbmp
     937             :  * int WBMP file format type
     938             :  * byte Header Type
     939             :  *      byte Extended Header
     940             :  *              byte Header Data (type 00 = multibyte)
     941             :  *              byte Header Data (type 11 = name/pairs)
     942             :  * int Number of columns
     943             :  * int Number of rows
     944             :  */
     945          11 : static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check TSRMLS_DC)
     946             : {
     947          11 :         int i, width = 0, height = 0;
     948             : 
     949          11 :         if (php_stream_rewind(stream)) {
     950           0 :                 return 0;
     951             :         }
     952             : 
     953             :         /* get type */
     954          11 :         if (php_stream_getc(stream) != 0) {
     955           9 :                 return 0;
     956             :         }
     957             : 
     958             :         /* skip header */
     959             :         do {
     960           2 :                 i = php_stream_getc(stream);
     961           2 :                 if (i < 0) {
     962           0 :                         return 0;
     963             :                 }
     964           2 :         } while (i & 0x80);
     965             : 
     966             :         /* get width */
     967             :         do {
     968           2 :                 i = php_stream_getc(stream);
     969           2 :                 if (i < 0) {
     970           0 :                         return 0;
     971             :                 }
     972           2 :                 width = (width << 7) | (i & 0x7f);
     973           2 :         } while (i & 0x80);
     974             :         
     975             :         /* get height */
     976             :         do {
     977           2 :                 i = php_stream_getc(stream);
     978           2 :                 if (i < 0) {
     979           0 :                         return 0;
     980             :                 }
     981           2 :                 height = (height << 7) | (i & 0x7f);
     982           2 :         } while (i & 0x80);
     983             : 
     984             :         /* maximum valid sizes for wbmp (although 127x127 may be a more accurate one) */
     985           2 :         if (!height || !width || height > 2048 || width > 2048) {
     986           0 :                 return 0;
     987             :         }
     988             :         
     989           2 :         if (!check) {
     990           1 :                 (*result)->width = width;
     991           1 :                 (*result)->height = height;
     992             :         }
     993             : 
     994           2 :         return IMAGE_FILETYPE_WBMP;
     995             : }
     996             : /* }}} */
     997             : 
     998             : /* {{{ php_handle_wbmp
     999             : */
    1000           1 : static struct gfxinfo *php_handle_wbmp(php_stream * stream TSRMLS_DC)
    1001             : {
    1002           1 :         struct gfxinfo *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1003             : 
    1004           1 :         if (!php_get_wbmp(stream, &result, 0 TSRMLS_CC)) {
    1005           0 :                 efree(result);
    1006           0 :                 return NULL;
    1007             :         }
    1008             : 
    1009           1 :         return result;
    1010             : }
    1011             : /* }}} */
    1012             : 
    1013             : /* {{{ php_get_xbm
    1014             :  */
    1015          10 : static int php_get_xbm(php_stream *stream, struct gfxinfo **result TSRMLS_DC)
    1016             : {
    1017             :     char *fline;
    1018             :     char *iname;
    1019             :     char *type;
    1020             :     int value;
    1021          10 :     unsigned int width = 0, height = 0;
    1022             : 
    1023          10 :         if (result) {
    1024           1 :                 *result = NULL;
    1025             :         }
    1026          10 :         if (php_stream_rewind(stream)) {
    1027           0 :                 return 0;
    1028             :         }
    1029          30 :         while ((fline=php_stream_gets(stream, NULL, 0)) != NULL) {
    1030          12 :                 iname = estrdup(fline); /* simple way to get necessary buffer of required size */
    1031          12 :                 if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
    1032           4 :                         if (!(type = strrchr(iname, '_'))) {
    1033           0 :                                 type = iname;
    1034             :                         } else {
    1035           4 :                                 type++;
    1036             :                         }
    1037             :         
    1038           4 :                         if (!strcmp("width", type)) {
    1039           2 :                                 width = (unsigned int) value;
    1040           2 :                                 if (height) {
    1041           0 :                                         efree(iname);
    1042           0 :                                         break;
    1043             :                                 }
    1044             :                         }
    1045           4 :                         if (!strcmp("height", type)) {
    1046           2 :                                 height = (unsigned int) value;
    1047           2 :                                 if (width) {
    1048           2 :                                         efree(iname);
    1049           2 :                                         break;
    1050             :                                 }
    1051             :                         }
    1052             :                 }
    1053          10 :                 efree(fline);
    1054          10 :                 efree(iname);
    1055             :         }
    1056          10 :         if (fline) {
    1057           2 :                 efree(fline);
    1058             :         }
    1059             : 
    1060          10 :         if (width && height) {
    1061           2 :                 if (result) {
    1062           1 :                         *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1063           1 :                         (*result)->width = width;
    1064           1 :                         (*result)->height = height;
    1065             :                 }
    1066           2 :                 return IMAGE_FILETYPE_XBM;
    1067             :         }
    1068             : 
    1069           8 :         return 0;
    1070             : }
    1071             : /* }}} */
    1072             : 
    1073             : /* {{{ php_handle_xbm
    1074             :  */
    1075           1 : static struct gfxinfo *php_handle_xbm(php_stream * stream TSRMLS_DC)
    1076             : {
    1077             :         struct gfxinfo *result;
    1078           1 :         php_get_xbm(stream, &result TSRMLS_CC);
    1079           1 :         return result;
    1080             : }
    1081             : /* }}} */
    1082             : 
    1083             : /* {{{ php_handle_ico
    1084             :  */
    1085           0 : static struct gfxinfo *php_handle_ico(php_stream * stream TSRMLS_DC)
    1086             : {
    1087           0 :         struct gfxinfo *result = NULL;
    1088             :         unsigned char dim[16];
    1089           0 :         int num_icons = 0;
    1090             : 
    1091           0 :         if (php_stream_read(stream, dim, 2) != 2)
    1092           0 :                 return NULL;
    1093             : 
    1094           0 :         num_icons = (((unsigned int)dim[1]) << 8) + ((unsigned int) dim[0]);
    1095             : 
    1096           0 :         if (num_icons < 1 || num_icons > 255)
    1097           0 :                 return NULL;
    1098             : 
    1099           0 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1100             : 
    1101           0 :         while (num_icons > 0)
    1102             :         {
    1103           0 :                 if (php_stream_read(stream, dim, sizeof(dim)) != sizeof(dim))
    1104           0 :                         break;
    1105             : 
    1106           0 :                 if ((((unsigned int)dim[7]) <<  8) +  ((unsigned int)dim[6]) >= result->bits)
    1107             :                 {
    1108           0 :                         result->width    =  (unsigned int)dim[0];
    1109           0 :                         result->height   =  (unsigned int)dim[1];
    1110           0 :                         result->bits     =  (((unsigned int)dim[7]) <<  8) +  ((unsigned int)dim[6]);
    1111             :                 }
    1112           0 :                 num_icons--;
    1113             :         }
    1114             : 
    1115           0 :         return result;
    1116             : }
    1117             : /* }}} */
    1118             : 
    1119             : /* {{{ php_image_type_to_mime_type
    1120             :  * Convert internal image_type to mime type */
    1121         185 : PHPAPI char * php_image_type_to_mime_type(int image_type)
    1122             : {
    1123         185 :         switch( image_type) {
    1124             :                 case IMAGE_FILETYPE_GIF:
    1125          15 :                         return "image/gif";
    1126             :                 case IMAGE_FILETYPE_JPEG:
    1127          61 :                         return "image/jpeg";
    1128             :                 case IMAGE_FILETYPE_PNG:
    1129          10 :                         return "image/png";
    1130             :                 case IMAGE_FILETYPE_SWF:
    1131             :                 case IMAGE_FILETYPE_SWC:
    1132          11 :                         return "application/x-shockwave-flash";
    1133             :                 case IMAGE_FILETYPE_PSD:
    1134           5 :                         return "image/psd";
    1135             :                 case IMAGE_FILETYPE_BMP:
    1136          12 :                         return "image/x-ms-bmp";
    1137             :                 case IMAGE_FILETYPE_TIFF_II:
    1138             :                 case IMAGE_FILETYPE_TIFF_MM:
    1139          19 :                         return "image/tiff";
    1140             :                 case IMAGE_FILETYPE_IFF:
    1141           6 :                         return "image/iff";
    1142             :                 case IMAGE_FILETYPE_WBMP:
    1143           3 :                         return "image/vnd.wap.wbmp";
    1144             :                 case IMAGE_FILETYPE_JPC:
    1145           7 :                         return "application/octet-stream";
    1146             :                 case IMAGE_FILETYPE_JP2:
    1147           6 :                         return "image/jp2";
    1148             :                 case IMAGE_FILETYPE_XBM:
    1149           3 :                         return "image/xbm";
    1150             :                 case IMAGE_FILETYPE_ICO:
    1151           2 :                         return "image/vnd.microsoft.icon";
    1152             :                 default:
    1153             :                 case IMAGE_FILETYPE_UNKNOWN:
    1154          25 :                         return "application/octet-stream"; /* suppose binary format */
    1155             :         }
    1156             : }
    1157             : /* }}} */
    1158             : 
    1159             : /* {{{ proto string image_type_to_mime_type(int imagetype)
    1160             :    Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */
    1161          84 : PHP_FUNCTION(image_type_to_mime_type)
    1162             : {
    1163             :         zend_long p_image_type;
    1164             : 
    1165          84 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &p_image_type) == FAILURE) {
    1166           9 :                 return;
    1167             :         }
    1168             : 
    1169         150 :         ZVAL_STRING(return_value, (char*)php_image_type_to_mime_type(p_image_type));
    1170             : }
    1171             : /* }}} */
    1172             : 
    1173             : /* {{{ proto string image_type_to_extension(int imagetype [, bool include_dot])
    1174             :    Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */
    1175          38 : PHP_FUNCTION(image_type_to_extension)
    1176             : {
    1177             :         zend_long image_type;
    1178          38 :         zend_bool inc_dot=1;
    1179             : 
    1180          38 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &image_type, &inc_dot) == FAILURE) {
    1181           4 :                 RETURN_FALSE;
    1182             :         }
    1183             : 
    1184          34 :         switch (image_type) {
    1185             :                 case IMAGE_FILETYPE_GIF:
    1186           4 :                         RETURN_STRING(".gif" + !inc_dot);
    1187             :                 case IMAGE_FILETYPE_JPEG:
    1188           4 :                         RETURN_STRING(".jpeg" + !inc_dot);
    1189             :                 case IMAGE_FILETYPE_PNG:
    1190           4 :                         RETURN_STRING(".png" + !inc_dot);
    1191             :                 case IMAGE_FILETYPE_SWF:
    1192             :                 case IMAGE_FILETYPE_SWC:
    1193           4 :                         RETURN_STRING(".swf" + !inc_dot);
    1194             :                 case IMAGE_FILETYPE_PSD:
    1195           4 :                         RETURN_STRING(".psd" + !inc_dot);
    1196             :                 case IMAGE_FILETYPE_BMP:
    1197             :                 case IMAGE_FILETYPE_WBMP:
    1198           8 :                         RETURN_STRING(".bmp" + !inc_dot);
    1199             :                 case IMAGE_FILETYPE_TIFF_II:
    1200             :                 case IMAGE_FILETYPE_TIFF_MM:
    1201           8 :                         RETURN_STRING(".tiff" + !inc_dot);
    1202             :                 case IMAGE_FILETYPE_IFF:
    1203           4 :                         RETURN_STRING(".iff" + !inc_dot);
    1204             :                 case IMAGE_FILETYPE_JPC:
    1205           8 :                         RETURN_STRING(".jpc" + !inc_dot);
    1206             :                 case IMAGE_FILETYPE_JP2:
    1207           4 :                         RETURN_STRING(".jp2" + !inc_dot);
    1208             :                 case IMAGE_FILETYPE_JPX:
    1209           4 :                         RETURN_STRING(".jpx" + !inc_dot);
    1210             :                 case IMAGE_FILETYPE_JB2:
    1211           4 :                         RETURN_STRING(".jb2" + !inc_dot);
    1212             :                 case IMAGE_FILETYPE_XBM:
    1213           4 :                         RETURN_STRING(".xbm" + !inc_dot);
    1214             :                 case IMAGE_FILETYPE_ICO:
    1215           0 :                         RETURN_STRING(".ico" + !inc_dot);
    1216             :         }
    1217             : 
    1218           2 :         RETURN_FALSE;
    1219             : }
    1220             : /* }}} */
    1221             : 
    1222             : /* {{{ php_imagetype
    1223             :    detect filetype from first bytes */
    1224          87 : PHPAPI int php_getimagetype(php_stream * stream, char *filetype TSRMLS_DC)
    1225             : {
    1226             :         char tmp[12];
    1227             : 
    1228          87 :         if ( !filetype) filetype = tmp;
    1229          87 :         if((php_stream_read(stream, filetype, 3)) != 3) {
    1230           4 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Read error!");
    1231           4 :                 return IMAGE_FILETYPE_UNKNOWN;
    1232             :         }
    1233             : 
    1234             : /* BYTES READ: 3 */
    1235          83 :         if (!memcmp(filetype, php_sig_gif, 3)) {
    1236           7 :                 return IMAGE_FILETYPE_GIF;
    1237          76 :         } else if (!memcmp(filetype, php_sig_jpg, 3)) {
    1238          31 :                 return IMAGE_FILETYPE_JPEG;
    1239          45 :         } else if (!memcmp(filetype, php_sig_png, 3)) {
    1240           7 :                 if (php_stream_read(stream, filetype+3, 5) != 5) {
    1241           0 :                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Read error!");
    1242           0 :                         return IMAGE_FILETYPE_UNKNOWN;
    1243             :                 }
    1244           7 :                 if (!memcmp(filetype, php_sig_png, 8)) {
    1245           7 :                         return IMAGE_FILETYPE_PNG;
    1246             :                 } else {
    1247           0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "PNG file corrupted by ASCII conversion");
    1248           0 :                         return IMAGE_FILETYPE_UNKNOWN;
    1249             :                 }
    1250          38 :         } else if (!memcmp(filetype, php_sig_swf, 3)) {
    1251           3 :                 return IMAGE_FILETYPE_SWF;
    1252          35 :         } else if (!memcmp(filetype, php_sig_swc, 3)) {
    1253           3 :                 return IMAGE_FILETYPE_SWC;
    1254          32 :         } else if (!memcmp(filetype, php_sig_psd, 3)) {
    1255           2 :                 return IMAGE_FILETYPE_PSD;
    1256          30 :         } else if (!memcmp(filetype, php_sig_bmp, 2)) {
    1257           7 :                 return IMAGE_FILETYPE_BMP;
    1258          23 :         } else if (!memcmp(filetype, php_sig_jpc, 3)) {
    1259           3 :                 return IMAGE_FILETYPE_JPC;
    1260             :         }
    1261             : 
    1262          20 :         if (php_stream_read(stream, filetype+3, 1) != 1) {
    1263           0 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Read error!");
    1264           0 :                 return IMAGE_FILETYPE_UNKNOWN;
    1265             :         }
    1266             : /* BYTES READ: 4 */
    1267          20 :         if (!memcmp(filetype, php_sig_tif_ii, 4)) {
    1268           3 :                 return IMAGE_FILETYPE_TIFF_II;
    1269          17 :         } else if (!memcmp(filetype, php_sig_tif_mm, 4)) {
    1270           1 :                 return IMAGE_FILETYPE_TIFF_MM;
    1271          16 :         } else if (!memcmp(filetype, php_sig_iff, 4)) {
    1272           3 :                 return IMAGE_FILETYPE_IFF;
    1273          13 :         } else if (!memcmp(filetype, php_sig_ico, 4)) {
    1274           0 :                 return IMAGE_FILETYPE_ICO;
    1275             :         }
    1276             : 
    1277          13 :         if (php_stream_read(stream, filetype+4, 8) != 8) {
    1278           0 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Read error!");
    1279           0 :                 return IMAGE_FILETYPE_UNKNOWN;
    1280             :         }
    1281             : /* BYTES READ: 12 */
    1282          13 :         if (!memcmp(filetype, php_sig_jp2, 12)) {
    1283           3 :                 return IMAGE_FILETYPE_JP2;
    1284             :         }
    1285             : 
    1286             : /* AFTER ALL ABOVE FAILED */
    1287          10 :         if (php_get_wbmp(stream, NULL, 1 TSRMLS_CC)) {
    1288           1 :                 return IMAGE_FILETYPE_WBMP;
    1289             :         }
    1290           9 :         if (php_get_xbm(stream, NULL TSRMLS_CC)) {
    1291           1 :                 return IMAGE_FILETYPE_XBM;
    1292             :         }
    1293           8 :         return IMAGE_FILETYPE_UNKNOWN;
    1294             : }
    1295             : /* }}} */
    1296             : 
    1297          86 : static void php_getimagesize_from_stream(php_stream *stream, zval *info, INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
    1298             : {
    1299          86 :         int itype = 0;
    1300          86 :         struct gfxinfo *result = NULL;
    1301             : 
    1302          86 :         if (!stream) {
    1303           0 :                 RETURN_FALSE;
    1304             :         }
    1305             : 
    1306          86 :         itype = php_getimagetype(stream, NULL TSRMLS_CC);
    1307          86 :         switch( itype) {
    1308             :                 case IMAGE_FILETYPE_GIF:
    1309           7 :                         result = php_handle_gif(stream TSRMLS_CC);
    1310           7 :                         break;
    1311             :                 case IMAGE_FILETYPE_JPEG:
    1312          30 :                         if (info) {
    1313          27 :                                 result = php_handle_jpeg(stream, info TSRMLS_CC);
    1314             :                         } else {
    1315           3 :                                 result = php_handle_jpeg(stream, NULL TSRMLS_CC);
    1316             :                         }
    1317          30 :                         break;
    1318             :                 case IMAGE_FILETYPE_PNG:
    1319           7 :                         result = php_handle_png(stream TSRMLS_CC);
    1320           7 :                         break;
    1321             :                 case IMAGE_FILETYPE_SWF:
    1322           3 :                         result = php_handle_swf(stream TSRMLS_CC);
    1323           3 :                         break;
    1324             :                 case IMAGE_FILETYPE_SWC:
    1325             : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
    1326           3 :                         result = php_handle_swc(stream TSRMLS_CC);
    1327             : #else
    1328             :                         php_error_docref(NULL TSRMLS_CC, E_NOTICE, "The image is a compressed SWF file, but you do not have a static version of the zlib extension enabled");
    1329             : #endif
    1330           3 :                         break;
    1331             :                 case IMAGE_FILETYPE_PSD:
    1332           2 :                         result = php_handle_psd(stream TSRMLS_CC);
    1333           2 :                         break;
    1334             :                 case IMAGE_FILETYPE_BMP:
    1335           7 :                         result = php_handle_bmp(stream TSRMLS_CC);
    1336           7 :                         break;
    1337             :                 case IMAGE_FILETYPE_TIFF_II:
    1338           3 :                         result = php_handle_tiff(stream, NULL, 0 TSRMLS_CC);
    1339           3 :                         break;
    1340             :                 case IMAGE_FILETYPE_TIFF_MM:
    1341           1 :                         result = php_handle_tiff(stream, NULL, 1 TSRMLS_CC);
    1342           1 :                         break;
    1343             :                 case IMAGE_FILETYPE_JPC:
    1344           3 :                         result = php_handle_jpc(stream TSRMLS_CC);
    1345           3 :                         break;
    1346             :                 case IMAGE_FILETYPE_JP2:
    1347           3 :                         result = php_handle_jp2(stream TSRMLS_CC);
    1348           3 :                         break;
    1349             :                 case IMAGE_FILETYPE_IFF:
    1350           3 :                         result = php_handle_iff(stream TSRMLS_CC);
    1351           3 :                         break;
    1352             :                 case IMAGE_FILETYPE_WBMP:
    1353           1 :                         result = php_handle_wbmp(stream TSRMLS_CC);
    1354           1 :                         break;
    1355             :                 case IMAGE_FILETYPE_XBM:
    1356           1 :                         result = php_handle_xbm(stream TSRMLS_CC);
    1357           1 :                         break;
    1358             :                 case IMAGE_FILETYPE_ICO:
    1359           0 :                         result = php_handle_ico(stream TSRMLS_CC);
    1360             :                         break;
    1361             :                 default:
    1362             :                 case IMAGE_FILETYPE_UNKNOWN:
    1363             :                         break;
    1364             :         }
    1365             : 
    1366          86 :         if (result) {
    1367             :                 char temp[MAX_LENGTH_OF_LONG * 2 + sizeof("width=\"\" height=\"\"")];
    1368          74 :                 array_init(return_value);
    1369          74 :                 add_index_long(return_value, 0, result->width);
    1370          74 :                 add_index_long(return_value, 1, result->height);
    1371          74 :                 add_index_long(return_value, 2, itype);
    1372          74 :                 snprintf(temp, sizeof(temp), "width=\"%d\" height=\"%d\"", result->width, result->height);
    1373          74 :                 add_index_string(return_value, 3, temp);
    1374             : 
    1375          74 :                 if (result->bits != 0) {
    1376          60 :                         add_assoc_long(return_value, "bits", result->bits);
    1377             :                 }
    1378          74 :                 if (result->channels != 0) {
    1379          43 :                         add_assoc_long(return_value, "channels", result->channels);
    1380             :                 }
    1381          74 :                 add_assoc_string(return_value, "mime", (char*)php_image_type_to_mime_type(itype));
    1382          74 :                 efree(result);
    1383             :         } else {
    1384          12 :                 RETURN_FALSE;
    1385             :         }
    1386             : }
    1387             : /* }}} */
    1388             : 
    1389             : #define FROM_DATA 0
    1390             : #define FROM_PATH 1
    1391             : 
    1392         117 : static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) {  /* {{{ */
    1393         117 :         zval *info = NULL;
    1394         117 :         php_stream *stream = NULL;
    1395             :         char *input;
    1396             :         size_t input_len;
    1397         117 :         const int argc = ZEND_NUM_ARGS();
    1398             : 
    1399         117 :         if (zend_parse_parameters(argc TSRMLS_CC, "s|z/", &input, &input_len, &info) == FAILURE) {
    1400           8 :                         return;
    1401             :         }
    1402             : 
    1403         109 :         if (argc == 2) {
    1404          67 :                 zval_dtor(info);
    1405          67 :                 array_init(info);
    1406             :         }
    1407             : 
    1408         109 :         if (mode == FROM_PATH) {
    1409         108 :                 stream = php_stream_open_wrapper(input, "rb", STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH, NULL);
    1410             :         } else {
    1411           1 :                 stream = php_stream_memory_open(TEMP_STREAM_READONLY, input, input_len);
    1412             :         }
    1413             : 
    1414         109 :         if (!stream) {
    1415          23 :                    RETURN_FALSE;
    1416             :         }
    1417             : 
    1418          86 :         php_getimagesize_from_stream(stream, info, INTERNAL_FUNCTION_PARAM_PASSTHRU);
    1419          86 :         php_stream_close(stream);
    1420             : }
    1421             : /* }}} */
    1422             : 
    1423             : /* {{{ proto array getimagesize(string imagefile [, array info])
    1424             :    Get the size of an image as 4-element array */
    1425         116 : PHP_FUNCTION(getimagesize)
    1426             : {
    1427         116 :         php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_PATH);
    1428         116 : }
    1429             : /* }}} */
    1430             : 
    1431             : /* {{{ proto array getimagesizefromstring(string data [, array info])
    1432             :    Get the size of an image as 4-element array */
    1433           1 : PHP_FUNCTION(getimagesizefromstring)
    1434             : {
    1435           1 :         php_getimagesize_from_any(INTERNAL_FUNCTION_PARAM_PASSTHRU, FROM_DATA);
    1436           1 : }
    1437             : 
    1438             : /*
    1439             :  * Local variables:
    1440             :  * tab-width: 4
    1441             :  * c-basic-offset: 4
    1442             :  * End:
    1443             :  * vim600: sw=4 ts=4 fdm=marker
    1444             :  * vim<600: sw=4 ts=4
    1445             :  */

Generated by: LCOV version 1.10

Generated at Tue, 14 Oct 2014 07:25:50 +0000 (6 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.