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

LTP GCOV extension - code coverage report
Current view: directory - standard - image.c
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 598
Code covered: 82.3 % Executed lines: 492
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 6                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 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: image.c 286806 2009-08-04 14:34:44Z iliaa $ */
      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                 : 
      34                 : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
      35                 : #include "zlib.h"
      36                 : #endif
      37                 : 
      38                 : /* file type markers */
      39                 : PHPAPI const char php_sig_gif[3] = {'G', 'I', 'F'};
      40                 : PHPAPI const char php_sig_psd[4] = {'8', 'B', 'P', 'S'};
      41                 : PHPAPI const char php_sig_bmp[2] = {'B', 'M'};
      42                 : PHPAPI const char php_sig_swf[3] = {'F', 'W', 'S'};
      43                 : PHPAPI const char php_sig_swc[3] = {'C', 'W', 'S'};
      44                 : PHPAPI const char php_sig_jpg[3] = {(char) 0xff, (char) 0xd8, (char) 0xff};
      45                 : PHPAPI const char php_sig_png[8] = {(char) 0x89, (char) 0x50, (char) 0x4e, (char) 0x47,
      46                 :                                     (char) 0x0d, (char) 0x0a, (char) 0x1a, (char) 0x0a};
      47                 : PHPAPI const char php_sig_tif_ii[4] = {'I','I', (char)0x2A, (char)0x00};
      48                 : PHPAPI const char php_sig_tif_mm[4] = {'M','M', (char)0x00, (char)0x2A};
      49                 : PHPAPI const char php_sig_jpc[3]  = {(char)0xff, (char)0x4f, (char)0xff};
      50                 : PHPAPI const char php_sig_jp2[12] = {(char)0x00, (char)0x00, (char)0x00, (char)0x0c,
      51                 :                                      (char)0x6a, (char)0x50, (char)0x20, (char)0x20,
      52                 :                                      (char)0x0d, (char)0x0a, (char)0x87, (char)0x0a};
      53                 : PHPAPI const char php_sig_iff[4] = {'F','O','R','M'};
      54                 : PHPAPI const char php_sig_ico[3] = {(char)0x00, (char)0x00, (char)0x01};
      55                 : 
      56                 : /* REMEMBER TO ADD MIME-TYPE TO FUNCTION php_image_type_to_mime_type */
      57                 : /* PCX must check first 64bytes and byte 0=0x0a and byte2 < 0x06 */
      58                 : 
      59                 : /* return info as a struct, to make expansion easier */
      60                 : 
      61                 : struct gfxinfo {
      62                 :         unsigned int width;
      63                 :         unsigned int height;
      64                 :         unsigned int bits;
      65                 :         unsigned int channels;
      66                 : };
      67                 : 
      68                 : /* {{{ PHP_MINIT_FUNCTION(imagetypes)
      69                 :  * Register IMAGETYPE_<xxx> constants used by GetImageSize(), image_type_to_mime_type, ext/exif */
      70                 : PHP_MINIT_FUNCTION(imagetypes)
      71           17007 : {
      72           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_GIF",     IMAGE_FILETYPE_GIF,     CONST_CS | CONST_PERSISTENT);
      73           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG",    IMAGE_FILETYPE_JPEG,    CONST_CS | CONST_PERSISTENT);
      74           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_PNG",     IMAGE_FILETYPE_PNG,     CONST_CS | CONST_PERSISTENT);
      75           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_SWF",     IMAGE_FILETYPE_SWF,     CONST_CS | CONST_PERSISTENT);
      76           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_PSD",     IMAGE_FILETYPE_PSD,     CONST_CS | CONST_PERSISTENT);
      77           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_BMP",     IMAGE_FILETYPE_BMP,     CONST_CS | CONST_PERSISTENT);
      78           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_II", IMAGE_FILETYPE_TIFF_II, CONST_CS | CONST_PERSISTENT);
      79           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_TIFF_MM", IMAGE_FILETYPE_TIFF_MM, CONST_CS | CONST_PERSISTENT);
      80           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPC",     IMAGE_FILETYPE_JPC,     CONST_CS | CONST_PERSISTENT);
      81           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JP2",     IMAGE_FILETYPE_JP2,     CONST_CS | CONST_PERSISTENT);
      82           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPX",     IMAGE_FILETYPE_JPX,     CONST_CS | CONST_PERSISTENT);
      83           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JB2",     IMAGE_FILETYPE_JB2,     CONST_CS | CONST_PERSISTENT);
      84                 : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
      85           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_SWC",     IMAGE_FILETYPE_SWC,     CONST_CS | CONST_PERSISTENT);
      86                 : #endif  
      87           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_IFF",     IMAGE_FILETYPE_IFF,     CONST_CS | CONST_PERSISTENT);
      88           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_WBMP",    IMAGE_FILETYPE_WBMP,    CONST_CS | CONST_PERSISTENT);
      89           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_JPEG2000",IMAGE_FILETYPE_JPC,     CONST_CS | CONST_PERSISTENT); /* keep alias */
      90           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_XBM",     IMAGE_FILETYPE_XBM,     CONST_CS | CONST_PERSISTENT);
      91           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_ICO",     IMAGE_FILETYPE_ICO,     CONST_CS | CONST_PERSISTENT);
      92           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_UNKNOWN", IMAGE_FILETYPE_UNKNOWN, CONST_CS | CONST_PERSISTENT);
      93           17007 :         REGISTER_LONG_CONSTANT("IMAGETYPE_COUNT",   IMAGE_FILETYPE_COUNT,   CONST_CS | CONST_PERSISTENT);
      94           17007 :         return SUCCESS;
      95                 : }
      96                 : /* }}} */
      97                 : 
      98                 : /* {{{ php_handle_gif
      99                 :  * routine to handle GIF files. If only everything were that easy... ;} */
     100                 : static struct gfxinfo *php_handle_gif (php_stream * stream TSRMLS_DC)
     101               5 : {
     102               5 :         struct gfxinfo *result = NULL;
     103                 :         unsigned char dim[5];
     104                 : 
     105               5 :         if (php_stream_seek(stream, 3, SEEK_CUR))
     106               0 :                 return NULL;
     107                 : 
     108               5 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     109               0 :                 return NULL;
     110                 : 
     111               5 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     112               5 :         result->width    = (unsigned int)dim[0] | (((unsigned int)dim[1])<<8);
     113               5 :         result->height   = (unsigned int)dim[2] | (((unsigned int)dim[3])<<8);
     114               5 :         result->bits     = dim[4]&0x80 ? ((((unsigned int)dim[4])&0x07) + 1) : 0;
     115               5 :         result->channels = 3; /* allways */
     116                 : 
     117               5 :         return result;
     118                 : }
     119                 : /* }}} */
     120                 : 
     121                 : /* {{{ php_handle_psd
     122                 :  */
     123                 : static struct gfxinfo *php_handle_psd (php_stream * stream TSRMLS_DC)
     124               2 : {
     125               2 :         struct gfxinfo *result = NULL;
     126                 :         unsigned char dim[8];
     127                 : 
     128               2 :         if (php_stream_seek(stream, 11, SEEK_CUR))
     129               0 :                 return NULL;
     130                 : 
     131               2 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     132               0 :                 return NULL;
     133                 : 
     134               2 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     135               2 :         result->height   =  (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]);
     136               2 :         result->width    =  (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]);
     137                 : 
     138               2 :         return result;
     139                 : }
     140                 : /* }}} */
     141                 : 
     142                 : /* {{{ php_handle_bmp
     143                 :  */
     144                 : static struct gfxinfo *php_handle_bmp (php_stream * stream TSRMLS_DC)
     145               3 : {
     146               3 :         struct gfxinfo *result = NULL;
     147                 :         unsigned char dim[16];
     148                 :         int size;
     149                 : 
     150               3 :         if (php_stream_seek(stream, 11, SEEK_CUR))
     151               0 :                 return NULL;
     152                 : 
     153               3 :         if (php_stream_read(stream, (char*)dim, sizeof(dim)) != sizeof(dim))
     154               0 :                 return NULL;
     155                 : 
     156               3 :         size   = (((unsigned int)dim[ 3]) << 24) + (((unsigned int)dim[ 2]) << 16) + (((unsigned int)dim[ 1]) << 8) + ((unsigned int) dim[ 0]);
     157               3 :         if (size == 12) {
     158               0 :                 result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo));
     159               0 :                 result->width    =  (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]);
     160               0 :                 result->height   =  (((unsigned int)dim[ 7]) << 8) + ((unsigned int) dim[ 6]);
     161               0 :                 result->bits     =  ((unsigned int)dim[11]);
     162               6 :         } else if (size > 12 && (size <= 64 || size == 108)) {
     163               3 :                 result = (struct gfxinfo *) ecalloc (1, sizeof(struct gfxinfo));
     164               3 :                 result->width    =  (((unsigned int)dim[ 7]) << 24) + (((unsigned int)dim[ 6]) << 16) + (((unsigned int)dim[ 5]) << 8) + ((unsigned int) dim[ 4]);
     165               3 :                 result->height   =  (((unsigned int)dim[11]) << 24) + (((unsigned int)dim[10]) << 16) + (((unsigned int)dim[ 9]) << 8) + ((unsigned int) dim[ 8]);
     166               3 :                 result->bits     =  (((unsigned int)dim[15]) <<  8) +  ((unsigned int)dim[14]);
     167                 :         } else {
     168               0 :                 return NULL;
     169                 :         }
     170                 : 
     171               3 :         return result;
     172                 : }
     173                 : /* }}} */
     174                 : 
     175                 : /* {{{ php_swf_get_bits
     176                 :  * routines to handle SWF files. */
     177                 : static unsigned long int php_swf_get_bits (unsigned char* buffer, unsigned int pos, unsigned int count)
     178              30 : {
     179                 :         unsigned int loop;
     180              30 :         unsigned long int result = 0;
     181                 : 
     182             412 :         for (loop = pos; loop < pos + count; loop++)
     183                 :         {
     184             382 :                 result = result +
     185                 :                         ((((buffer[loop / 8]) >> (7 - (loop % 8))) & 0x01) << (count - (loop - pos) - 1));
     186                 :         }
     187              30 :         return result;
     188                 : }
     189                 : /* }}} */
     190                 : 
     191                 : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
     192                 : /* {{{ php_handle_swc
     193                 :  */
     194                 : static struct gfxinfo *php_handle_swc(php_stream * stream TSRMLS_DC)
     195               3 : {
     196               3 :         struct gfxinfo *result = NULL;
     197                 : 
     198                 :         long bits;
     199                 :         unsigned char a[64];
     200               3 :         unsigned long len=64, szlength;
     201               3 :         int factor=1,maxfactor=16;
     202               3 :         int slength, status=0;
     203               3 :         unsigned char *b, *buf=NULL, *bufz=NULL;
     204                 : 
     205               3 :         b = ecalloc (1, len + 1);
     206                 : 
     207               3 :         if (php_stream_seek(stream, 5, SEEK_CUR))
     208               0 :                 return NULL;
     209                 : 
     210               3 :         if (php_stream_read(stream, (char*)a, sizeof(a)) != sizeof(a))
     211               0 :                 return NULL;
     212                 : 
     213               3 :         if (uncompress((unsigned char*)b, &len, a, sizeof(a)) != Z_OK) {
     214                 :                 /* failed to decompress the file, will try reading the rest of the file */
     215               3 :                 if (php_stream_seek(stream, 8, SEEK_SET))
     216               0 :                         return NULL;
     217                 : 
     218               3 :                 slength = php_stream_copy_to_mem(stream, (char**)&bufz, PHP_STREAM_COPY_ALL, 0);
     219                 :                 
     220                 :                 /*
     221                 :                  * zlib::uncompress() wants to know the output data length
     222                 :                  * if none was given as a parameter
     223                 :                  * we try from input length * 2 up to input length * 2^8
     224                 :                  * doubling it whenever it wasn't big enough
     225                 :                  * that should be eneugh for all real life cases
     226                 :                 */
     227                 :                 
     228                 :                 do {
     229               3 :                         szlength=slength*(1<<factor++);
     230               3 :                         buf = (unsigned char *) erealloc(buf,szlength);
     231               3 :                         status = uncompress(buf, &szlength, bufz, slength);
     232               3 :                 } while ((status==Z_BUF_ERROR)&&(factor<maxfactor));
     233                 :                 
     234               3 :                 if (bufz) {
     235               3 :                         pefree(bufz, 0);
     236                 :                 }       
     237                 :                 
     238               3 :                 if (status == Z_OK) {
     239               3 :                          memcpy(b, buf, len);
     240                 :                 }
     241                 :                 
     242               3 :                 if (buf) { 
     243               3 :                         efree(buf);
     244                 :                 }       
     245                 :         }
     246                 :         
     247               3 :         if (!status) {
     248               3 :                 result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo));
     249               3 :                 bits = php_swf_get_bits (b, 0, 5);
     250               3 :                 result->width = (php_swf_get_bits (b, 5 + bits, bits) -
     251                 :                         php_swf_get_bits (b, 5, bits)) / 20;
     252               3 :                 result->height = (php_swf_get_bits (b, 5 + (3 * bits), bits) -
     253                 :                         php_swf_get_bits (b, 5 + (2 * bits), bits)) / 20;
     254                 :         } else {
     255               0 :                 result = NULL;
     256                 :         }       
     257                 :                 
     258               3 :         efree (b);
     259               3 :         return result;
     260                 : }
     261                 : /* }}} */
     262                 : #endif
     263                 : 
     264                 : /* {{{ php_handle_swf
     265                 :  */
     266                 : static struct gfxinfo *php_handle_swf (php_stream * stream TSRMLS_DC)
     267               3 : {
     268               3 :         struct gfxinfo *result = NULL;
     269                 :         long bits;
     270                 :         unsigned char a[32];
     271                 : 
     272               3 :         if (php_stream_seek(stream, 5, SEEK_CUR))
     273               0 :                 return NULL;
     274                 : 
     275               3 :         if (php_stream_read(stream, (char*)a, sizeof(a)) != sizeof(a))
     276               0 :                 return NULL;
     277                 : 
     278               3 :         result = (struct gfxinfo *) ecalloc (1, sizeof (struct gfxinfo));
     279               3 :         bits = php_swf_get_bits (a, 0, 5);
     280               3 :         result->width = (php_swf_get_bits (a, 5 + bits, bits) -
     281                 :                 php_swf_get_bits (a, 5, bits)) / 20;
     282               3 :         result->height = (php_swf_get_bits (a, 5 + (3 * bits), bits) -
     283                 :                 php_swf_get_bits (a, 5 + (2 * bits), bits)) / 20;
     284               3 :         result->bits     = 0;
     285               3 :         result->channels = 0;
     286               3 :         return result;
     287                 : }
     288                 : /* }}} */
     289                 : 
     290                 : /* {{{ php_handle_png
     291                 :  * routine to handle PNG files */
     292                 : static struct gfxinfo *php_handle_png (php_stream * stream TSRMLS_DC)
     293               7 : {
     294               7 :         struct gfxinfo *result = NULL;
     295                 :         unsigned char dim[9];
     296                 : /* Width:              4 bytes
     297                 :  * Height:             4 bytes
     298                 :  * Bit depth:          1 byte
     299                 :  * Color type:         1 byte
     300                 :  * Compression method: 1 byte
     301                 :  * Filter method:      1 byte
     302                 :  * Interlace method:   1 byte
     303                 :  */
     304                 : 
     305               7 :         if (php_stream_seek(stream, 8, SEEK_CUR))
     306               0 :                 return NULL;
     307                 : 
     308               7 :         if((php_stream_read(stream, (char*)dim, sizeof(dim))) < sizeof(dim))
     309               0 :                 return NULL;
     310                 : 
     311               7 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     312               7 :         result->width  = (((unsigned int)dim[0]) << 24) + (((unsigned int)dim[1]) << 16) + (((unsigned int)dim[2]) << 8) + ((unsigned int)dim[3]);
     313               7 :         result->height = (((unsigned int)dim[4]) << 24) + (((unsigned int)dim[5]) << 16) + (((unsigned int)dim[6]) << 8) + ((unsigned int)dim[7]);
     314               7 :         result->bits   = (unsigned int)dim[8];
     315               7 :         return result;
     316                 : }
     317                 : /* }}} */
     318                 : 
     319                 : /* routines to handle JPEG data */
     320                 : 
     321                 : /* some defines for the different JPEG block types */
     322                 : #define M_SOF0  0xC0                    /* Start Of Frame N */
     323                 : #define M_SOF1  0xC1                    /* N indicates which compression process */
     324                 : #define M_SOF2  0xC2                    /* Only SOF0-SOF2 are now in common use */
     325                 : #define M_SOF3  0xC3
     326                 : #define M_SOF5  0xC5                    /* NB: codes C4 and CC are NOT SOF markers */
     327                 : #define M_SOF6  0xC6
     328                 : #define M_SOF7  0xC7
     329                 : #define M_SOF9  0xC9
     330                 : #define M_SOF10 0xCA
     331                 : #define M_SOF11 0xCB
     332                 : #define M_SOF13 0xCD
     333                 : #define M_SOF14 0xCE
     334                 : #define M_SOF15 0xCF
     335                 : #define M_SOI   0xD8
     336                 : #define M_EOI   0xD9                    /* End Of Image (end of datastream) */
     337                 : #define M_SOS   0xDA                    /* Start Of Scan (begins compressed data) */
     338                 : #define M_APP0  0xe0
     339                 : #define M_APP1  0xe1
     340                 : #define M_APP2  0xe2
     341                 : #define M_APP3  0xe3
     342                 : #define M_APP4  0xe4
     343                 : #define M_APP5  0xe5
     344                 : #define M_APP6  0xe6
     345                 : #define M_APP7  0xe7
     346                 : #define M_APP8  0xe8
     347                 : #define M_APP9  0xe9
     348                 : #define M_APP10 0xea
     349                 : #define M_APP11 0xeb
     350                 : #define M_APP12 0xec
     351                 : #define M_APP13 0xed
     352                 : #define M_APP14 0xee
     353                 : #define M_APP15 0xef
     354                 : #define M_COM   0xFE            /* COMment                                  */
     355                 : 
     356                 : #define M_PSEUDO 0xFFD8                 /* pseudo marker for start of image(byte 0) */
     357                 : 
     358                 : /* {{{ php_read2
     359                 :  */
     360                 : static unsigned short php_read2(php_stream * stream TSRMLS_DC)
     361             228 : {
     362                 :         unsigned char a[2];
     363                 : 
     364                 :         /* just return 0 if we hit the end-of-file */
     365             228 :         if((php_stream_read(stream, (char*)a, sizeof(a))) <= 0) return 0;
     366                 : 
     367             228 :         return (((unsigned short)a[0]) << 8) + ((unsigned short)a[1]);
     368                 : }
     369                 : /* }}} */
     370                 : 
     371                 : /* {{{ php_next_marker
     372                 :  * get next marker byte from file */
     373                 : static unsigned int php_next_marker(php_stream * stream, int last_marker, int comment_correction, int ff_read TSRMLS_DC)
     374             177 : {
     375             177 :         int a=0, marker;
     376                 : 
     377                 :         /* get marker byte, swallowing possible padding                           */
     378             179 :         if (last_marker==M_COM && comment_correction) {
     379                 :                 /* some software does not count the length bytes of COM section           */
     380                 :                 /* one company doing so is very much envolved in JPEG... so we accept too */
     381                 :                 /* by the way: some of those companies changed their code now...          */
     382               2 :                 comment_correction = 2;
     383                 :         } else {
     384             175 :                 last_marker = 0;
     385             175 :                 comment_correction = 0;
     386                 :         }
     387             177 :         if (ff_read) {
     388              30 :                 a = 1; /* already read 0xff in filetype detection */
     389                 :         }
     390                 :         do {
     391             326 :                 if ((marker = php_stream_getc(stream)) == EOF)
     392                 :                 {
     393               0 :                         return M_EOI;/* we hit EOF */
     394                 :                 }
     395             326 :                 if (last_marker==M_COM && comment_correction>0)
     396                 :                 {
     397               3 :                         if (marker != 0xFF)
     398                 :                         {
     399               2 :                                 marker = 0xff;
     400               2 :                                 comment_correction--;
     401                 :                         } else {
     402               1 :                                 last_marker = M_PSEUDO; /* stop skipping non 0xff for M_COM */
     403                 :                         }
     404                 :                 }
     405             326 :                 if (++a > 25)
     406                 :                 {
     407                 :                         /* who knows the maxim amount of 0xff? though 7 */
     408                 :                         /* but found other implementations              */
     409               0 :                         return M_EOI;
     410                 :                 }
     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                 : static int php_skip_variable(php_stream * stream TSRMLS_DC)
     427              91 : {
     428              91 :         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, (long)length, SEEK_CUR);
     435              91 :         return 1;
     436                 : }
     437                 : /* }}} */
     438                 : 
     439                 : /* {{{ php_read_APP
     440                 :  */
     441                 : static int php_read_APP(php_stream * stream, unsigned int marker, zval *info TSRMLS_DC)
     442              29 : {
     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, (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 (zend_ascii_hash_find(Z_ARRVAL_P(info), markername, strlen(markername)+1, (void **) &tmp) == FAILURE) {
     464                 :                 /* XXX we onyl catch the 1st tag of it's kind! */
     465              29 :                 add_ascii_assoc_rt_stringl(info, markername, buffer, length, 1);
     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                 : static struct gfxinfo *php_handle_jpeg (php_stream * stream, zval *info TSRMLS_DC) 
     476              30 : {
     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                 : static unsigned int php_read4(php_stream * stream TSRMLS_DC)
     565              21 : {
     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              21 :         return (((unsigned int)a[0]) << 24)
     572                 :              + (((unsigned int)a[1]) << 16)
     573                 :              + (((unsigned int)a[2]) <<  8)
     574                 :              + (((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                 : static struct gfxinfo *php_handle_jpc(php_stream * stream TSRMLS_DC)
     605               6 : {
     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 seperate 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 || 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                 : static struct gfxinfo *php_handle_jp2(php_stream *stream TSRMLS_DC)
     677               3 : {
     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                 : static int php_ifd_get16u(void *Short, int motorola_intel)
     762             150 : {
     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                 : static signed short php_ifd_get16s(void *Short, int motorola_intel)
     774               6 : {
     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                 : static int php_ifd_get32s(void *Long, int motorola_intel)
     782              23 : {
     783              23 :         if (motorola_intel) {
     784               8 :                 return  ((( char *)Long)[0] << 24) | (((unsigned char *)Long)[1] << 16)
     785                 :                       | (((unsigned char *)Long)[2] << 8 ) | (((unsigned char *)Long)[3] << 0 );
     786                 :         } else {
     787              15 :                 return  ((( char *)Long)[3] << 24) | (((unsigned char *)Long)[2] << 16)
     788                 :                       | (((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                 : static unsigned php_ifd_get32u(void *Long, int motorola_intel)
     796              17 : {
     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                 : static struct gfxinfo *php_handle_tiff (php_stream * stream, zval *info, int motorola_intel TSRMLS_DC)
     804               4 : {
     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                 :         unsigned char *ifd_data;
     811                 :         char ifd_ptr[4];
     812                 : 
     813               4 :         if (php_stream_read(stream, ifd_ptr, 4) != 4)
     814               0 :                 return NULL;
     815               4 :         ifd_addr = php_ifd_get32u(ifd_ptr, motorola_intel);
     816               4 :         if (php_stream_seek(stream, ifd_addr-8, SEEK_CUR))
     817               0 :                 return NULL;
     818               4 :         ifd_size = 2;
     819               4 :         ifd_data = emalloc(ifd_size);
     820               4 :         if (php_stream_read(stream, (char*)ifd_data, 2) != 2) {
     821               0 :                 efree(ifd_data);
     822               0 :                 return NULL;
     823                 :         }
     824               4 :         num_entries = php_ifd_get16u(ifd_data, motorola_intel);
     825               4 :         dir_size = 2/*num dir entries*/ +12/*length of entry*/*num_entries +4/* offset to next ifd (points to thumbnail or NULL)*/;
     826               4 :         ifd_size = dir_size;
     827               4 :         ifd_data = erealloc(ifd_data,ifd_size);
     828               4 :         if (php_stream_read(stream, (char*)ifd_data+2, dir_size-2) != dir_size-2) {
     829               0 :                 efree(ifd_data);
     830               0 :                 return NULL;
     831                 :         }
     832                 :         /* now we have the directory we can look how long it should be */
     833               4 :         ifd_size = dir_size;
     834              57 :         for(i=0;i<num_entries;i++) {
     835              53 :                 dir_entry        = ifd_data+2+i*12;
     836              53 :                 entry_tag    = php_ifd_get16u(dir_entry+0, motorola_intel);
     837              53 :                 entry_type   = php_ifd_get16u(dir_entry+2, motorola_intel);
     838              53 :                 switch(entry_type) {
     839                 :                         case TAG_FMT_BYTE:
     840                 :                         case TAG_FMT_SBYTE:
     841               0 :                                 entry_value  = (size_t)(dir_entry[8]);
     842               0 :                                 break;
     843                 :                         case TAG_FMT_USHORT:
     844              34 :                                 entry_value  = php_ifd_get16u(dir_entry+8, motorola_intel);
     845              34 :                                 break;
     846                 :                         case TAG_FMT_SSHORT:
     847               0 :                                 entry_value  = php_ifd_get16s(dir_entry+8, motorola_intel);
     848               0 :                                 break;
     849                 :                         case TAG_FMT_ULONG:
     850              13 :                                 entry_value  = php_ifd_get32u(dir_entry+8, motorola_intel);
     851              13 :                                 break;
     852                 :                         case TAG_FMT_SLONG:
     853               0 :                                 entry_value  = php_ifd_get32s(dir_entry+8, motorola_intel);
     854               0 :                                 break;
     855                 :                         default:
     856               6 :                                 continue;
     857                 :                 }
     858              47 :                 switch(entry_tag) {
     859                 :                         case TAG_IMAGEWIDTH:
     860                 :                         case TAG_COMP_IMAGEWIDTH:
     861               4 :                                 width  = entry_value;
     862               4 :                                 break;
     863                 :                         case TAG_IMAGEHEIGHT:
     864                 :                         case TAG_COMP_IMAGEHEIGHT:
     865               4 :                                 height = entry_value;
     866                 :                                 break;
     867                 :                 }
     868                 :         }
     869               4 :         efree(ifd_data);
     870               4 :         if ( width && height) {
     871                 :                 /* not the same when in for-loop */
     872               4 :                 result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     873               4 :                 result->height   = height;
     874               4 :                 result->width    = width;
     875               4 :                 result->bits     = 0;
     876               4 :                 result->channels = 0;
     877               4 :                 return result;
     878                 :         }
     879               0 :         return NULL;
     880                 : }
     881                 : /* }}} */
     882                 : 
     883                 : /* {{{ php_handle_psd
     884                 :  */
     885                 : static struct gfxinfo *php_handle_iff(php_stream * stream TSRMLS_DC)
     886               3 : {
     887                 :         struct gfxinfo * result;
     888                 :         unsigned char a[10];
     889                 :         int chunkId;
     890                 :         int size;
     891                 :         short width, height, bits;
     892                 : 
     893               3 :         if (php_stream_read(stream, (char*)a, 8) != 8) {
     894               0 :                 return NULL;
     895                 :         }
     896               3 :         if (strncmp((char*)a+4, "ILBM", 4) && strncmp((char*)a+4, "PBM ", 4)) {
     897               0 :                 return NULL;
     898                 :         }
     899                 : 
     900                 :         /* loop chunks to find BMHD chunk */
     901                 :         do {
     902               3 :                 if (php_stream_read(stream, (char*)a, 8) != 8) {
     903               0 :                         return NULL;
     904                 :                 }
     905               3 :                 chunkId = php_ifd_get32s(a+0, 1);
     906               3 :                 size    = php_ifd_get32s(a+4, 1);
     907               3 :                 if (size < 0) {
     908               0 :                         return NULL;
     909                 :                 }
     910               3 :                 if ((size & 1) == 1) {
     911               0 :                         size++;
     912                 :                 }
     913               3 :                 if (chunkId == 0x424d4844) { /* BMHD chunk */
     914               3 :                         if (size < 9 || php_stream_read(stream, (char*)a, 9) != 9) {
     915               0 :                                 return NULL;
     916                 :                         }
     917               3 :                         width  = php_ifd_get16s(a+0, 1);
     918               3 :                         height = php_ifd_get16s(a+2, 1);
     919               3 :                         bits   = a[8] & 0xff;
     920               3 :                         if (width > 0 && height > 0 && bits > 0 && bits < 33) {
     921               3 :                                 result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
     922               3 :                                 result->width    = width;
     923               3 :                                 result->height   = height;
     924               3 :                                 result->bits     = bits;
     925               3 :                                 result->channels = 0;
     926               3 :                                 return result;
     927                 :                         }
     928                 :                 } else {
     929               0 :                         if (php_stream_seek(stream, size, SEEK_CUR)) {
     930               0 :                                 return NULL;
     931                 :                         }
     932                 :                 }
     933               0 :         } while (1);
     934                 : }
     935                 : /* }}} */
     936                 : 
     937                 : /* {{{ php_get_wbmp
     938                 :  * int WBMP file format type
     939                 :  * byte Header Type
     940                 :  *      byte Extended Header
     941                 :  *              byte Header Data (type 00 = multibyte)
     942                 :  *              byte Header Data (type 11 = name/pairs)
     943                 :  * int Number of columns
     944                 :  * int Number of rows
     945                 :  */
     946                 : static int php_get_wbmp(php_stream *stream, struct gfxinfo **result, int check TSRMLS_DC)
     947              11 : {
     948              11 :         int i, width = 0, height = 0;
     949                 : 
     950              11 :         if (php_stream_rewind(stream)) {
     951               0 :                 return 0;
     952                 :         }
     953                 : 
     954                 :         /* get type */
     955              11 :         if (php_stream_getc(stream) != 0) {
     956               9 :                 return 0;
     957                 :         }
     958                 : 
     959                 :         /* skip header */
     960                 :         do {
     961               2 :                 i = php_stream_getc(stream);
     962               2 :                 if (i < 0) {
     963               0 :                         return 0;
     964                 :                 }
     965               2 :         } while (i & 0x80);
     966                 : 
     967                 :         /* get width */
     968                 :         do {
     969               2 :                 i = php_stream_getc(stream);
     970               2 :                 if (i < 0) {
     971               0 :                         return 0;
     972                 :                 }
     973               2 :                 width = (width << 7) | (i & 0x7f);
     974               2 :         } while (i & 0x80);
     975                 :         
     976                 :         /* get height */
     977                 :         do {
     978               2 :                 i = php_stream_getc(stream);
     979               2 :                 if (i < 0) {
     980               0 :                         return 0;
     981                 :                 }
     982               2 :                 height = (height << 7) | (i & 0x7f);
     983               2 :         } while (i & 0x80);
     984                 : 
     985                 :         /* maximum valid sizes for wbmp (although 127x127 may be a more accurate one) */
     986               2 :         if (!height || !width || height > 2048 || width > 2048) {
     987               0 :                 return 0;
     988                 :         }
     989                 :         
     990               2 :         if (!check) {
     991               1 :                 (*result)->width = width;
     992               1 :                 (*result)->height = height;
     993                 :         }
     994                 : 
     995               2 :         return IMAGE_FILETYPE_WBMP;
     996                 : }
     997                 : /* }}} */
     998                 : 
     999                 : /* {{{ php_handle_wbmp
    1000                 : */
    1001                 : static struct gfxinfo *php_handle_wbmp(php_stream * stream TSRMLS_DC)
    1002               1 : {
    1003               1 :         struct gfxinfo *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1004                 : 
    1005               1 :         if (!php_get_wbmp(stream, &result, 0 TSRMLS_CC)) {
    1006               0 :                 efree(result);
    1007               0 :                 return NULL;
    1008                 :         }
    1009                 : 
    1010               1 :         return result;
    1011                 : }
    1012                 : /* }}} */
    1013                 : 
    1014                 : /* {{{ php_get_xbm
    1015                 :  */
    1016                 : static int php_get_xbm(php_stream *stream, struct gfxinfo **result TSRMLS_DC)
    1017              10 : {
    1018                 :     char *fline;
    1019                 :     char *iname;
    1020                 :     char *type;
    1021                 :     int value;
    1022              10 :     unsigned int width = 0, height = 0;
    1023                 : 
    1024              10 :         if (result) {
    1025               1 :                 *result = NULL;
    1026                 :         }
    1027              10 :         if (php_stream_rewind(stream)) {
    1028               0 :                 return 0;
    1029                 :         }
    1030              30 :         while ((fline=php_stream_gets(stream, NULL_ZSTR, 0)) != NULL) {
    1031              12 :                 iname = estrdup(fline); /* simple way to get necessary buffer of required size */
    1032              12 :                 if (sscanf(fline, "#define %s %d", iname, &value) == 2) {
    1033               4 :                         if (!(type = strrchr(iname, '_'))) {
    1034               0 :                                 type = iname;
    1035                 :                         } else {
    1036               4 :                                 type++;
    1037                 :                         }
    1038                 :         
    1039               4 :                         if (!strcmp("width", type)) {
    1040               2 :                                 width = (unsigned int) value;
    1041               2 :                                 if (height) {
    1042               0 :                                         efree(iname);
    1043               0 :                                         break;
    1044                 :                                 }
    1045                 :                         }
    1046               4 :                         if (!strcmp("height", type)) {
    1047               2 :                                 height = (unsigned int) value;
    1048               2 :                                 if (width) {
    1049               2 :                                         efree(iname);
    1050               2 :                                         break;
    1051                 :                                 }
    1052                 :                         }
    1053                 :                 }
    1054              10 :                 efree(fline);
    1055              10 :                 efree(iname);
    1056                 :         }
    1057              10 :         if (fline) {
    1058               2 :                 efree(fline);
    1059                 :         }
    1060                 : 
    1061              10 :         if (width && height) {
    1062               2 :                 if (result) {
    1063               1 :                         *result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1064               1 :                         (*result)->width = width;
    1065               1 :                         (*result)->height = height;
    1066                 :                 }
    1067               2 :                 return IMAGE_FILETYPE_XBM;
    1068                 :         }
    1069                 : 
    1070               8 :         return 0;
    1071                 : }
    1072                 : /* }}} */
    1073                 : 
    1074                 : /* {{{ php_handle_xbm
    1075                 :  */
    1076                 : static struct gfxinfo *php_handle_xbm(php_stream * stream TSRMLS_DC)
    1077               1 : {
    1078                 :         struct gfxinfo *result;
    1079               1 :         php_get_xbm(stream, &result TSRMLS_CC);
    1080               1 :         return result;
    1081                 : }
    1082                 : /* }}} */
    1083                 : 
    1084                 : /* {{{ php_handle_ico
    1085                 :  */
    1086                 : static struct gfxinfo *php_handle_ico(php_stream * stream TSRMLS_DC)
    1087               0 : {
    1088               0 :         struct gfxinfo *result = NULL;
    1089                 :         unsigned char dim[16];
    1090               0 :         int num_icons = 0;
    1091                 : 
    1092               0 :         if (php_stream_read(stream, dim, 2) != 2)
    1093               0 :                 return NULL;
    1094                 : 
    1095               0 :         num_icons = (((unsigned int)dim[1]) << 8) + ((unsigned int) dim[0]);
    1096                 : 
    1097               0 :         if (num_icons < 1 || num_icons > 255)
    1098               0 :                 return NULL;
    1099                 : 
    1100               0 :         result = (struct gfxinfo *) ecalloc(1, sizeof(struct gfxinfo));
    1101                 : 
    1102               0 :         while (num_icons > 0)
    1103                 :         {
    1104               0 :                 if (php_stream_read(stream, dim, sizeof(dim)) != sizeof(dim))
    1105               0 :                         break;
    1106                 : 
    1107               0 :                 if ((((unsigned int)dim[7]) <<  8) +  ((unsigned int)dim[6]) >= result->bits)
    1108                 :                 {
    1109               0 :                         result->width    =  (unsigned int)dim[0];
    1110               0 :                         result->height   =  (unsigned int)dim[1];
    1111               0 :                         result->bits     =  (((unsigned int)dim[7]) <<  8) +  ((unsigned int)dim[6]);
    1112                 :                 }
    1113               0 :                 num_icons--;
    1114                 :         }
    1115                 : 
    1116               0 :         return result;
    1117                 : }
    1118                 : /* }}} */
    1119                 : 
    1120                 : /* {{{ php_image_type_to_mime_type
    1121                 :  * Convert internal image_type to mime type */
    1122                 : PHPAPI char * php_image_type_to_mime_type(int image_type)
    1123             189 : {
    1124             189 :         switch( image_type) {
    1125                 :                 case IMAGE_FILETYPE_GIF:
    1126              14 :                         return "image/gif";
    1127                 :                 case IMAGE_FILETYPE_JPEG:
    1128              57 :                         return "image/jpeg";
    1129                 :                 case IMAGE_FILETYPE_PNG:
    1130              11 :                         return "image/png";
    1131                 :                 case IMAGE_FILETYPE_SWF:
    1132                 :                 case IMAGE_FILETYPE_SWC:
    1133              13 :                         return "application/x-shockwave-flash";
    1134                 :                 case IMAGE_FILETYPE_PSD:
    1135               6 :                         return "image/psd";
    1136                 :                 case IMAGE_FILETYPE_BMP:
    1137               7 :                         return "image/x-ms-bmp";
    1138                 :                 case IMAGE_FILETYPE_TIFF_II:
    1139                 :                 case IMAGE_FILETYPE_TIFF_MM:
    1140              21 :                         return "image/tiff";
    1141                 :                 case IMAGE_FILETYPE_IFF:
    1142               7 :                         return "image/iff";
    1143                 :                 case IMAGE_FILETYPE_WBMP:
    1144               4 :                         return "image/vnd.wap.wbmp";
    1145                 :                 case IMAGE_FILETYPE_JPC:
    1146               8 :                         return "application/octet-stream";
    1147                 :                 case IMAGE_FILETYPE_JP2:
    1148               7 :                         return "image/jp2";
    1149                 :                 case IMAGE_FILETYPE_XBM:
    1150               4 :                         return "image/xbm";
    1151                 :                 case IMAGE_FILETYPE_ICO:
    1152               3 :                         return "image/vnd.microsoft.icon";
    1153                 :                 default:
    1154                 :                 case IMAGE_FILETYPE_UNKNOWN:
    1155              27 :                         return "application/octet-stream"; /* suppose binary format */
    1156                 :         }
    1157                 : }
    1158                 : /* }}} */
    1159                 : 
    1160                 : /* {{{ proto string image_type_to_mime_type(int imagetype) U
    1161                 :    Get Mime-Type for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */
    1162                 : PHP_FUNCTION(image_type_to_mime_type)
    1163              99 : {
    1164                 :         long image_type;
    1165                 :         char *temp;
    1166                 : 
    1167              99 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &image_type) == FAILURE) {
    1168               9 :                 return;
    1169                 :         }
    1170                 : 
    1171              90 :         temp = (char*)php_image_type_to_mime_type(image_type);
    1172              90 :         ZVAL_ASCII_STRING(return_value, temp, 1);
    1173                 : }
    1174                 : /* }}} */
    1175                 : 
    1176                 : /* {{{ proto string image_type_to_extension(int imagetype [, bool include_dot]) U
    1177                 :    Get file extension for image-type returned by getimagesize, exif_read_data, exif_thumbnail, exif_imagetype */
    1178                 : PHP_FUNCTION(image_type_to_extension)
    1179              38 : {
    1180                 :         long image_type;
    1181              38 :         zend_bool inc_dot=1;
    1182              38 :         char *temp = NULL;
    1183                 : 
    1184              38 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|b", &image_type, &inc_dot) == FAILURE) {
    1185               4 :                 RETURN_FALSE;
    1186                 :         }
    1187                 : 
    1188              34 :         switch (image_type) {
    1189                 :                 case IMAGE_FILETYPE_GIF:
    1190               2 :                         temp = ".gif";
    1191               2 :                         break;
    1192                 :                         
    1193                 :                 case IMAGE_FILETYPE_JPEG:
    1194               2 :                         temp = ".jpeg";
    1195               2 :                         break;
    1196                 :                         
    1197                 :                 case IMAGE_FILETYPE_PNG:
    1198               2 :                         temp = ".png";
    1199               2 :                         break;
    1200                 :                         
    1201                 :                 case IMAGE_FILETYPE_SWF:
    1202                 :                 case IMAGE_FILETYPE_SWC:
    1203               2 :                         temp = ".swf";
    1204               2 :                         break;
    1205                 :                         
    1206                 :                 case IMAGE_FILETYPE_PSD:
    1207               2 :                         temp = ".psd";
    1208               2 :                         break;
    1209                 :                         
    1210                 :                 case IMAGE_FILETYPE_BMP:
    1211                 :                 case IMAGE_FILETYPE_WBMP:
    1212               4 :                         temp = ".bmp";
    1213               4 :                         break;
    1214                 :                         
    1215                 :                 case IMAGE_FILETYPE_TIFF_II:
    1216                 :                 case IMAGE_FILETYPE_TIFF_MM:
    1217               4 :                         temp = ".tiff";
    1218               4 :                         break;
    1219                 :                         
    1220                 :                 case IMAGE_FILETYPE_IFF:
    1221               2 :                         temp = ".iff";
    1222               2 :                         break;
    1223                 :                         
    1224                 :                 case IMAGE_FILETYPE_JPC:
    1225               4 :                         temp = ".jpc";
    1226               4 :                         break;
    1227                 :                         
    1228                 :                 case IMAGE_FILETYPE_JP2:
    1229               2 :                         temp = ".jp2";
    1230               2 :                         break;
    1231                 :                         
    1232                 :                 case IMAGE_FILETYPE_JPX:
    1233               2 :                         temp = ".jpx";
    1234               2 :                         break;
    1235                 : 
    1236                 :                 case IMAGE_FILETYPE_JB2:
    1237               2 :                         temp = ".jb2";
    1238               2 :                         break;
    1239                 :                         
    1240                 :                 case IMAGE_FILETYPE_XBM:
    1241               2 :                         temp = ".xbm";
    1242               2 :                         break;
    1243                 : 
    1244                 :                 case IMAGE_FILETYPE_ICO:
    1245               0 :                         temp = ".ico";
    1246                 :                         break;
    1247                 :         }
    1248              34 :         if (temp) {
    1249              32 :                 RETURN_ASCII_STRING(temp + !inc_dot, 1);
    1250                 :         }
    1251                 : 
    1252               2 :         RETURN_FALSE;
    1253                 : }
    1254                 : /* }}} */
    1255                 : 
    1256                 : /* {{{ php_imagetype
    1257                 :    detect filetype from first bytes */
    1258                 : PHPAPI int php_getimagetype(php_stream * stream, char *filetype TSRMLS_DC)
    1259              81 : {
    1260                 :         char tmp[12];
    1261                 : 
    1262              81 :         if ( !filetype) filetype = tmp;
    1263              81 :         if((php_stream_read(stream, filetype, 3)) != 3) {
    1264               4 :                 php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Read error!");
    1265               4 :                 return IMAGE_FILETYPE_UNKNOWN;
    1266                 :         }
    1267                 : 
    1268                 : /* BYTES READ: 3 */
    1269              77 :         if (!memcmp(filetype, php_sig_gif, 3)) {
    1270               5 :                 return IMAGE_FILETYPE_GIF;
    1271              72 :         } else if (!memcmp(filetype, php_sig_jpg, 3)) {
    1272              31 :                 return IMAGE_FILETYPE_JPEG;
    1273              41 :         } else if (!memcmp(filetype, php_sig_png, 3)) {
    1274               7 :                 if (php_stream_read(stream, filetype+3, 5) != 5) {
    1275               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
    1276               0 :                         return IMAGE_FILETYPE_UNKNOWN;
    1277                 :                 }
    1278               7 :                 if (!memcmp(filetype, php_sig_png, 8)) {
    1279               7 :                         return IMAGE_FILETYPE_PNG;
    1280                 :                 } else {
    1281               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "PNG file corrupted by ASCII conversion");
    1282               0 :                         return IMAGE_FILETYPE_UNKNOWN;
    1283                 :                 }
    1284              34 :         } else if (!memcmp(filetype, php_sig_swf, 3)) {
    1285               3 :                 return IMAGE_FILETYPE_SWF;
    1286              31 :         } else if (!memcmp(filetype, php_sig_swc, 3)) {
    1287               3 :                 return IMAGE_FILETYPE_SWC;
    1288              28 :         } else if (!memcmp(filetype, php_sig_psd, 3)) {
    1289               2 :                 return IMAGE_FILETYPE_PSD;
    1290              26 :         } else if (!memcmp(filetype, php_sig_bmp, 2)) {
    1291               3 :                 return IMAGE_FILETYPE_BMP;
    1292              23 :         } else if (!memcmp(filetype, php_sig_jpc, 3)) {
    1293               3 :                 return IMAGE_FILETYPE_JPC;
    1294                 :         }
    1295                 : 
    1296              20 :         if (php_stream_read(stream, filetype+3, 1) != 1) {
    1297               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
    1298               0 :                 return IMAGE_FILETYPE_UNKNOWN;
    1299                 :         }
    1300                 : /* BYTES READ: 4 */
    1301              20 :         if (!memcmp(filetype, php_sig_tif_ii, 4)) {
    1302               3 :                 return IMAGE_FILETYPE_TIFF_II;
    1303              17 :         } else if (!memcmp(filetype, php_sig_tif_mm, 4)) {
    1304               1 :                 return IMAGE_FILETYPE_TIFF_MM;
    1305              16 :         } else if (!memcmp(filetype, php_sig_iff, 4)) {
    1306               3 :                 return IMAGE_FILETYPE_IFF;
    1307              13 :         } else if (!memcmp(filetype, php_sig_ico, 3)) {
    1308               0 :                 return IMAGE_FILETYPE_ICO;
    1309                 :         }
    1310                 : 
    1311              13 :         if (php_stream_read(stream, filetype+4, 8) != 8) {
    1312               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Read error!");
    1313               0 :                 return IMAGE_FILETYPE_UNKNOWN;
    1314                 :         }
    1315                 : /* BYTES READ: 12 */
    1316              13 :         if (!memcmp(filetype, php_sig_jp2, 12)) {
    1317               3 :                 return IMAGE_FILETYPE_JP2;
    1318                 :         }
    1319                 : 
    1320                 : /* AFTER ALL ABOVE FAILED */
    1321              10 :         if (php_get_wbmp(stream, NULL, 1 TSRMLS_CC)) {
    1322               1 :                 return IMAGE_FILETYPE_WBMP;
    1323                 :         }
    1324               9 :         if (php_get_xbm(stream, NULL TSRMLS_CC)) {
    1325               1 :                 return IMAGE_FILETYPE_XBM;
    1326                 :         }
    1327               8 :         return IMAGE_FILETYPE_UNKNOWN;
    1328                 : }
    1329                 : /* }}} */
    1330                 : 
    1331                 : /* {{{ proto array getimagesize(string imagefile [, array info]) U
    1332                 :    Get the size of an image as 4-element array */
    1333                 : PHP_FUNCTION(getimagesize)
    1334             111 : {
    1335             111 :         zval **pp_file, *info = NULL;
    1336             111 :         int itype = 0;
    1337                 :         char *temp;
    1338                 :         char *filename;
    1339                 :         int filename_len;
    1340             111 :         struct gfxinfo *result = NULL;
    1341             111 :         php_stream * stream = NULL;
    1342                 : 
    1343             111 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|z", &pp_file, &info) == FAILURE ||
    1344                 :                 php_stream_path_param_encode(pp_file, &filename, &filename_len, REPORT_ERRORS, FG(default_context)) == FAILURE) {
    1345               2 :                 return;
    1346                 :         }
    1347                 : 
    1348             109 :         stream = php_stream_open_wrapper(filename, "rb", STREAM_MUST_SEEK|REPORT_ERRORS|IGNORE_PATH, NULL);
    1349                 : 
    1350             109 :         if (!stream) {
    1351              29 :                 RETURN_FALSE;
    1352                 :         }
    1353                 : 
    1354              80 :         if (info) {
    1355              46 :                 zval_dtor(info);
    1356              46 :                 array_init(info);
    1357                 :         }
    1358                 : 
    1359              80 :         itype = php_getimagetype(stream, NULL TSRMLS_CC);
    1360              80 :         switch( itype) {
    1361                 :                 case IMAGE_FILETYPE_GIF:
    1362               5 :                         result = php_handle_gif (stream TSRMLS_CC);
    1363               5 :                         break;
    1364                 :                 case IMAGE_FILETYPE_JPEG:
    1365              30 :                         if (info) {
    1366              27 :                                 result = php_handle_jpeg(stream, info TSRMLS_CC);
    1367                 :                         } else {
    1368               3 :                                 result = php_handle_jpeg(stream, NULL TSRMLS_CC);
    1369                 :                         }
    1370              30 :                         break;
    1371                 :                 case IMAGE_FILETYPE_PNG:
    1372               7 :                         result = php_handle_png(stream TSRMLS_CC);
    1373               7 :                         break;
    1374                 :                 case IMAGE_FILETYPE_SWF:
    1375               3 :                         result = php_handle_swf(stream TSRMLS_CC);
    1376               3 :                         break;
    1377                 :                 case IMAGE_FILETYPE_SWC:
    1378                 : #if HAVE_ZLIB && !defined(COMPILE_DL_ZLIB)
    1379               3 :                         result = php_handle_swc(stream TSRMLS_CC);
    1380                 : #else
    1381                 :                         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");
    1382                 : 
    1383                 : #endif
    1384               3 :                         break;
    1385                 :                 case IMAGE_FILETYPE_PSD:
    1386               2 :                         result = php_handle_psd(stream TSRMLS_CC);
    1387               2 :                         break;
    1388                 :                 case IMAGE_FILETYPE_BMP:
    1389               3 :                         result = php_handle_bmp(stream TSRMLS_CC);
    1390               3 :                         break;
    1391                 :                 case IMAGE_FILETYPE_TIFF_II:
    1392               3 :                         result = php_handle_tiff(stream, NULL, 0 TSRMLS_CC);
    1393               3 :                         break;
    1394                 :                 case IMAGE_FILETYPE_TIFF_MM:
    1395               1 :                         result = php_handle_tiff(stream, NULL, 1 TSRMLS_CC);
    1396               1 :                         break;
    1397                 :                 case IMAGE_FILETYPE_JPC:
    1398               3 :                         result = php_handle_jpc(stream TSRMLS_CC);
    1399               3 :                         break;
    1400                 :                 case IMAGE_FILETYPE_JP2:
    1401               3 :                         result = php_handle_jp2(stream TSRMLS_CC);
    1402               3 :                         break;
    1403                 :                 case IMAGE_FILETYPE_IFF:
    1404               3 :                         result = php_handle_iff(stream TSRMLS_CC);
    1405               3 :                         break;
    1406                 :                 case IMAGE_FILETYPE_WBMP:
    1407               1 :                         result = php_handle_wbmp(stream TSRMLS_CC);
    1408               1 :                         break;
    1409                 :                 case IMAGE_FILETYPE_XBM:
    1410               1 :                         result = php_handle_xbm(stream TSRMLS_CC);
    1411               1 :                         break;
    1412                 :                 case IMAGE_FILETYPE_ICO:
    1413               0 :                         result = php_handle_ico(stream TSRMLS_CC);
    1414                 :                         break;
    1415                 :                 default:
    1416                 :                 case IMAGE_FILETYPE_UNKNOWN:
    1417                 :                         break;
    1418                 :         }
    1419                 : 
    1420              80 :         php_stream_close(stream);
    1421                 : 
    1422              80 :         if (result) {
    1423              68 :                 array_init(return_value);
    1424              68 :                 add_index_long(return_value, 0, result->width);
    1425              68 :                 add_index_long(return_value, 1, result->height);
    1426              68 :                 add_index_long(return_value, 2, itype);
    1427              68 :                 spprintf(&temp, 0, "width=\"%d\" height=\"%d\"", result->width, result->height);
    1428              68 :                 add_index_ascii_string(return_value, 3, temp, ZSTR_AUTOFREE);
    1429                 : 
    1430              68 :                 if (result->bits != 0) {
    1431              54 :                         add_ascii_assoc_long(return_value, "bits", result->bits);
    1432                 :                 }
    1433              68 :                 if (result->channels != 0) {
    1434              41 :                         add_ascii_assoc_long(return_value, "channels", result->channels);
    1435                 :                 }
    1436              68 :                 temp = (char*)php_image_type_to_mime_type(itype);
    1437              68 :                 add_ascii_assoc_ascii_string(return_value, "mime", temp, 1);
    1438              68 :                 efree(result);
    1439                 :         } else {
    1440              12 :                 RETURN_FALSE;
    1441                 :         }
    1442                 : }
    1443                 : /* }}} */
    1444                 : 
    1445                 : /*
    1446                 :  * Local variables:
    1447                 :  * tab-width: 4
    1448                 :  * c-basic-offset: 4
    1449                 :  * End:
    1450                 :  * vim600: sw=4 ts=4 fdm=marker
    1451                 :  * vim<600: sw=4 ts=4
    1452                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:40 +0000 (35 hours ago)

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