Back to index

php5  5.3.10
Defines | Functions | Variables
iptc.c File Reference
#include "php.h"
#include "php_iptc.h"
#include "ext/standard/head.h"
#include <sys/stat.h>

Go to the source code of this file.

Defines

#define M_SOF0   0xC0 /* Start Of Frame N */
#define M_SOF1   0xC1 /* N indicates which compression process */
#define M_SOF2   0xC2 /* Only SOF0-SOF2 are now in common use */
#define M_SOF3   0xC3
#define M_SOF5   0xC5 /* NB: codes C4 and CC are NOT SOF markers */
#define M_SOF6   0xC6
#define M_SOF7   0xC7
#define M_SOF9   0xC9
#define M_SOF10   0xCA
#define M_SOF11   0xCB
#define M_SOF13   0xCD
#define M_SOF14   0xCE
#define M_SOF15   0xCF
#define M_SOI   0xD8
#define M_EOI   0xD9 /* End Of Image (end of datastream) */
#define M_SOS   0xDA /* Start Of Scan (begins compressed data) */
#define M_APP0   0xe0
#define M_APP1   0xe1
#define M_APP2   0xe2
#define M_APP3   0xe3
#define M_APP4   0xe4
#define M_APP5   0xe5
#define M_APP6   0xe6
#define M_APP7   0xe7
#define M_APP8   0xe8
#define M_APP9   0xe9
#define M_APP10   0xea
#define M_APP11   0xeb
#define M_APP12   0xec
#define M_APP13   0xed
#define M_APP14   0xee
#define M_APP15   0xef

Functions

static int php_iptc_put1 (FILE *fp, int spool, unsigned char c, unsigned char **spoolbuf TSRMLS_DC)
static int php_iptc_get1 (FILE *fp, int spool, unsigned char **spoolbuf TSRMLS_DC)
static int php_iptc_read_remaining (FILE *fp, int spool, unsigned char **spoolbuf TSRMLS_DC)
static int php_iptc_skip_variable (FILE *fp, int spool, unsigned char **spoolbuf TSRMLS_DC)
static int php_iptc_next_marker (FILE *fp, int spool, unsigned char **spoolbuf TSRMLS_DC)
 PHP_FUNCTION (iptcembed)
 PHP_FUNCTION (iptcparse)

Variables

static char psheader [] = "\xFF\xED\0\0Photoshop 3.0\08BIM\x04\x04\0\0\0\0"

Define Documentation

#define M_APP0   0xe0

Definition at line 59 of file iptc.c.

#define M_APP1   0xe1

Definition at line 60 of file iptc.c.

#define M_APP10   0xea

Definition at line 69 of file iptc.c.

#define M_APP11   0xeb

Definition at line 70 of file iptc.c.

#define M_APP12   0xec

Definition at line 71 of file iptc.c.

#define M_APP13   0xed

Definition at line 72 of file iptc.c.

#define M_APP14   0xee

Definition at line 73 of file iptc.c.

#define M_APP15   0xef

Definition at line 74 of file iptc.c.

#define M_APP2   0xe2

Definition at line 61 of file iptc.c.

#define M_APP3   0xe3

Definition at line 62 of file iptc.c.

#define M_APP4   0xe4

Definition at line 63 of file iptc.c.

#define M_APP5   0xe5

Definition at line 64 of file iptc.c.

#define M_APP6   0xe6

Definition at line 65 of file iptc.c.

#define M_APP7   0xe7

Definition at line 66 of file iptc.c.

#define M_APP8   0xe8

Definition at line 67 of file iptc.c.

#define M_APP9   0xe9

Definition at line 68 of file iptc.c.

#define M_EOI   0xD9 /* End Of Image (end of datastream) */

Definition at line 57 of file iptc.c.

#define M_SOF0   0xC0 /* Start Of Frame N */

Definition at line 43 of file iptc.c.

#define M_SOF1   0xC1 /* N indicates which compression process */

Definition at line 44 of file iptc.c.

#define M_SOF10   0xCA

Definition at line 51 of file iptc.c.

#define M_SOF11   0xCB

Definition at line 52 of file iptc.c.

#define M_SOF13   0xCD

Definition at line 53 of file iptc.c.

#define M_SOF14   0xCE

Definition at line 54 of file iptc.c.

#define M_SOF15   0xCF

Definition at line 55 of file iptc.c.

#define M_SOF2   0xC2 /* Only SOF0-SOF2 are now in common use */

Definition at line 45 of file iptc.c.

#define M_SOF3   0xC3

Definition at line 46 of file iptc.c.

#define M_SOF5   0xC5 /* NB: codes C4 and CC are NOT SOF markers */

Definition at line 47 of file iptc.c.

#define M_SOF6   0xC6

Definition at line 48 of file iptc.c.

#define M_SOF7   0xC7

Definition at line 49 of file iptc.c.

#define M_SOF9   0xC9

Definition at line 50 of file iptc.c.

#define M_SOI   0xD8

Definition at line 56 of file iptc.c.

#define M_SOS   0xDA /* Start Of Scan (begins compressed data) */

Definition at line 58 of file iptc.c.


Function Documentation

PHP_FUNCTION ( iptcembed  )

Definition at line 178 of file iptc.c.

{
       char *iptcdata, *jpeg_file;
       int iptcdata_len, jpeg_file_len;
       long spool = 0;
       FILE *fp;
       unsigned int marker, done = 0, inx;
       unsigned char *spoolbuf = NULL, *poi = NULL;
       struct stat sb;
       zend_bool written = 0;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &iptcdata, &iptcdata_len, &jpeg_file, &jpeg_file_len, &spool) != SUCCESS) {
              return;
       }

       if (strlen(jpeg_file) != jpeg_file_len) {
              RETURN_FALSE;
       }

       if (PG(safe_mode) && (!php_checkuid(jpeg_file, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
              RETURN_FALSE;
       }

       if (php_check_open_basedir(jpeg_file TSRMLS_CC)) {
              RETURN_FALSE;
       }

       if ((fp = VCWD_FOPEN(jpeg_file, "rb")) == 0) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open %s", jpeg_file);
              RETURN_FALSE;
       }

       if (spool < 2) {
              fstat(fileno(fp), &sb);

              poi = spoolbuf = safe_emalloc(1, iptcdata_len + sizeof(psheader) + sb.st_size + 1024, 1);
              memset(poi, 0, iptcdata_len + sizeof(psheader) + sb.st_size + 1024 + 1);
       } 

       if (php_iptc_get1(fp, spool, poi?&poi:0 TSRMLS_CC) != 0xFF) {
              fclose(fp);
              if (spoolbuf) {
                     efree(spoolbuf);
              }
              RETURN_FALSE;
       }

       if (php_iptc_get1(fp, spool, poi?&poi:0 TSRMLS_CC) != 0xD8) {
              fclose(fp);
              if (spoolbuf) {
                     efree(spoolbuf);
              }
              RETURN_FALSE;
       }

       while (!done) {
              marker = php_iptc_next_marker(fp, spool, poi?&poi:0 TSRMLS_CC);

              if (marker == M_EOI) { /* EOF */
                     break;
              } else if (marker != M_APP13) { 
                     php_iptc_put1(fp, spool, (unsigned char)marker, poi?&poi:0 TSRMLS_CC);
              }

              switch (marker) {
                     case M_APP13:
                            /* we are going to write a new APP13 marker, so don't output the old one */
                            php_iptc_skip_variable(fp, 0, 0 TSRMLS_CC);    
                            php_iptc_read_remaining(fp, spool, poi?&poi:0 TSRMLS_CC);
                            done = 1;
                            break;

                     case M_APP0:
                            /* APP0 is in each and every JPEG, so when we hit APP0 we insert our new APP13! */
                     case M_APP1:
                            if (written) {
                                   /* don't try to write the data twice */
                                   break;
                            }
                            written = 1;

                            php_iptc_skip_variable(fp, spool, poi?&poi:0 TSRMLS_CC);

                            if (iptcdata_len & 1) {
                                   iptcdata_len++; /* make the length even */
                            }

                            psheader[ 2 ] = (iptcdata_len+28)>>8;
                            psheader[ 3 ] = (iptcdata_len+28)&0xff;

                            for (inx = 0; inx < 28; inx++) {
                                   php_iptc_put1(fp, spool, psheader[inx], poi?&poi:0 TSRMLS_CC);
                            }

                            php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len>>8), poi?&poi:0 TSRMLS_CC);
                            php_iptc_put1(fp, spool, (unsigned char)(iptcdata_len&0xff), poi?&poi:0 TSRMLS_CC);

                            for (inx = 0; inx < iptcdata_len; inx++) {
                                   php_iptc_put1(fp, spool, iptcdata[inx], poi?&poi:0 TSRMLS_CC);
                            }
                            break;

                     case M_SOS:                                                    
                            /* we hit data, no more marker-inserting can be done! */
                            php_iptc_read_remaining(fp, spool, poi?&poi:0 TSRMLS_CC);
                            done = 1;
                            break;

                     default:
                            php_iptc_skip_variable(fp, spool, poi?&poi:0 TSRMLS_CC);
                            break;
              }
       }

       fclose(fp);

       if (spool < 2) {
              RETVAL_STRINGL(spoolbuf, poi - spoolbuf, 0);
       } else {
              RETURN_TRUE;
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( iptcparse  )

Definition at line 304 of file iptc.c.

{
       unsigned int inx = 0, len, tagsfound = 0;
       unsigned char *buffer, recnum, dataset, key[ 16 ];
       char *str;
       int str_len;
       zval *values, **element;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) != SUCCESS) {
              return;
       }

       buffer = (unsigned char *)str;

       while (inx < str_len) { /* find 1st tag */
              if ((buffer[inx] == 0x1c) && ((buffer[inx+1] == 0x01) || (buffer[inx+1] == 0x02))){ 
                     break;
              } else {
                     inx++;
              }
       }

       while (inx < str_len) {
              if (buffer[ inx++ ] != 0x1c) {
                     break;   /* we ran against some data which does not conform to IPTC - stop parsing! */
              } 
              
              if ((inx + 4) >= str_len)
                     break;

              dataset = buffer[ inx++ ];
              recnum = buffer[ inx++ ];

              if (buffer[ inx ] & (unsigned char) 0x80) { /* long tag */
                     len = (((long) buffer[ inx + 2 ]) << 24) + (((long) buffer[ inx + 3 ]) << 16) + 
                              (((long) buffer[ inx + 4 ]) <<  8) + (((long) buffer[ inx + 5 ]));
                     inx += 6;
              } else { /* short tag */
                     len = (((unsigned short) buffer[ inx ])<<8) | (unsigned short)buffer[ inx+1 ];
                     inx += 2;
              }

              snprintf(key, sizeof(key), "%d#%03d", (unsigned int) dataset, (unsigned int) recnum);

              if ((len > str_len) || (inx + len) > str_len) {
                     break;
              }

              if (tagsfound == 0) { /* found the 1st tag - initialize the return array */
                     array_init(return_value);
              }

              if (zend_hash_find(Z_ARRVAL_P(return_value), key, strlen(key) + 1, (void **) &element) == FAILURE) {
                     MAKE_STD_ZVAL(values);
                     array_init(values);
                     
                     zend_hash_update(Z_ARRVAL_P(return_value), key, strlen(key) + 1, (void *) &values, sizeof(zval*), (void **) &element);
              } 
                     
              add_next_index_stringl(*element, buffer+inx, len, 1);
              inx += len;
              tagsfound++;
       }

       if (! tagsfound) {
              RETURN_FALSE;
       }
}

Here is the call graph for this function:

static int php_iptc_get1 ( FILE *  fp,
int  spool,
unsigned char **spoolbuf  TSRMLS_DC 
) [static]

Definition at line 91 of file iptc.c.

{      
       int c;
       char cc;

       c = getc(fp);

       if (c == EOF) return EOF;

       if (spool > 0) {
              cc = c;
              PUTC(cc);
       }

       if (spoolbuf) *(*spoolbuf)++ = c;

       return c;
}

Here is the caller graph for this function:

static int php_iptc_next_marker ( FILE *  fp,
int  spool,
unsigned char **spoolbuf  TSRMLS_DC 
) [static]

Definition at line 145 of file iptc.c.

{
    int c;

    /* skip unimportant stuff */

    c = php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC);

       if (c == EOF) return M_EOI;

    while (c != 0xff) {
        if ((c = php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC)) == EOF)
            return M_EOI; /* we hit EOF */
    }

    /* get marker byte, swallowing possible padding */
    do {
        c = php_iptc_get1(fp, 0, 0 TSRMLS_CC);
              if (c == EOF)
            return M_EOI;       /* we hit EOF */
              else
              if (c == 0xff)
                     php_iptc_put1(fp, spool, (unsigned char)c, spoolbuf TSRMLS_CC);
    } while (c == 0xff);

    return (unsigned int) c;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int php_iptc_put1 ( FILE *  fp,
int  spool,
unsigned char  c,
unsigned char **spoolbuf  TSRMLS_DC 
) [static]

Definition at line 78 of file iptc.c.

{ 
       if (spool > 0)
              PUTC(c);

       if (spoolbuf) *(*spoolbuf)++ = c;

       return c;
}

Here is the caller graph for this function:

static int php_iptc_read_remaining ( FILE *  fp,
int  spool,
unsigned char **spoolbuf  TSRMLS_DC 
) [static]

Definition at line 113 of file iptc.c.

{
       while (php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC) != EOF) continue;

       return M_EOI;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int php_iptc_skip_variable ( FILE *  fp,
int  spool,
unsigned char **spoolbuf  TSRMLS_DC 
) [static]

Definition at line 123 of file iptc.c.

{ 
       unsigned int  length;
       int c1, c2;

    if ((c1 = php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC)) == EOF) return M_EOI;

    if ((c2 = php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC)) == EOF) return M_EOI;

       length = (((unsigned char) c1) << 8) + ((unsigned char) c2);

       length -= 2;

       while (length--)
              if (php_iptc_get1(fp, spool, spoolbuf TSRMLS_CC) == EOF) return M_EOI;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char psheader[] = "\xFF\xED\0\0Photoshop 3.0\08BIM\x04\x04\0\0\0\0" [static]

Definition at line 174 of file iptc.c.