Back to index

php5  5.3.10
Functions
php_iptc.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

 PHP_FUNCTION (iptcparse)
 PHP_FUNCTION (iptcembed)

Function Documentation

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:

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: