Ejemplo n.º 1
0
static void
metadataparse_exif_content_foreach_entry_func (ExifEntry * entry,
    void *user_data)
{
  MEUserData *meudata = (MEUserData *) user_data;
  GType type = G_TYPE_NONE;
  ExifByteOrder byte_order;
  const gchar *tag;

  /* We need the byte order */
  if (!entry || !entry->parent || !entry->parent->parent)
    return;

  tag = metadataparse_exif_get_tag_from_exif (entry->tag, &type);
  byte_order = exif_data_get_byte_order (entry->parent->parent);

  if (metadataparse_handle_unit_tags (entry, meudata, byte_order))
    goto done;

  if (!tag)
    goto done;

  if (type == GST_TYPE_FRACTION) {
    gint numerator = 0;
    gint denominator = 1;

    switch (entry->format) {
      case EXIF_FORMAT_SRATIONAL:
      {
        ExifSRational v_srat;

        v_srat = exif_get_srational (entry->data, byte_order);
        if (v_srat.denominator) {
          numerator = (gint) v_srat.numerator;
          denominator = (gint) v_srat.denominator;
        }
      }
        break;
      case EXIF_FORMAT_RATIONAL:
      {
        ExifRational v_rat;

        v_rat = exif_get_rational (entry->data, byte_order);
        if (v_rat.denominator) {
          numerator = (gint) v_rat.numerator;
          denominator = (gint) v_rat.denominator;
        }
        if (meudata->resolution_unit == 3) {
          /* converts from cm to inches */
          if (entry->tag == EXIF_TAG_X_RESOLUTION
              || entry->tag == EXIF_TAG_Y_RESOLUTION) {
            numerator *= 2;
            denominator *= 5;
          }
        }
      }
        break;
      default:
        GST_ERROR ("Unexpected Tag Type");
        goto done;
        break;
    }
    gst_tag_list_add (meudata->taglist, meudata->mode, tag, numerator,
        denominator, NULL);

  } else if (type == GST_TYPE_BUFFER) {
    GstBuffer *buf = gst_buffer_new_and_alloc (entry->components);

    memcpy (GST_BUFFER_DATA (buf), entry->data, entry->components);
    gst_tag_list_add (meudata->taglist, meudata->mode, tag, buf, NULL);
    gst_buffer_unref (buf);
  } else {
    switch (type) {
      case G_TYPE_STRING:
      {
        char buf[2048];
        const gchar *str = exif_entry_get_value (entry, buf, sizeof (buf));
        GString *value = NULL;

        if (entry->tag == EXIF_TAG_DATE_TIME_DIGITIZED
            || entry->tag == EXIF_TAG_DATE_TIME
            || entry->tag == EXIF_TAG_DATE_TIME_ORIGINAL) {
          value = g_string_new_len (str, 20);
          /* 20 is enough memory to hold "YYYY-MM-DDTHH:MM:SS" */

          if (metadataparse_exif_convert_to_datetime (value)) {
            str = value->str;
          } else {
            GST_ERROR ("Unexpected date & time format for %s", tag);
            str = NULL;
          }

        }
        if (str)
          gst_tag_list_add (meudata->taglist, meudata->mode, tag, str, NULL);
        if (value)
          g_string_free (value, TRUE);
      }
        break;
      case G_TYPE_INT:
        /* fall through */
      case G_TYPE_UINT:
      {
        gint value;

        switch (entry->format) {
          case EXIF_FORMAT_SHORT:
            value = exif_get_short (entry->data, byte_order);
            break;
          case EXIF_FORMAT_LONG:
            value = exif_get_long (entry->data, byte_order);
            break;
          default:
            GST_ERROR ("Unexpected Exif Tag Type (%s - %s)",
                tag, exif_format_get_name (entry->format));
            goto done;
            break;
        }
        if (entry->tag == EXIF_TAG_CONTRAST ||
            entry->tag == EXIF_TAG_SATURATION) {
          switch (value) {
            case 0:
              break;
            case 1:
              value = -67;      /* -100-34 /2 */
              break;
            case 2:
              value = 67;       /* 100+34 /2 */
              break;
            default:
              GST_ERROR ("Unexpected value");
              break;
          }
        }
        gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL);
      }
        break;
      case G_TYPE_DOUBLE:
      {
        gdouble value = 0.0;

        if (entry->tag == EXIF_TAG_GPS_LATITUDE
            || entry->tag == EXIF_TAG_GPS_LONGITUDE) {
          ExifRational *rt = (ExifRational *) entry->data;

          /* DDD - degrees */
          value = (gdouble) rt->numerator / (gdouble) rt->denominator;
          GST_DEBUG ("deg: %lu / %lu", (gulong) rt->numerator,
              (gulong) rt->denominator);
          rt++;

          /* MM - minutes and SS - seconds */
          GST_DEBUG ("min: %lu / %lu", (gulong) rt->numerator,
              (gulong) rt->denominator);
          value += (gdouble) rt->numerator / ((gdouble) rt->denominator * 60.0);
          rt++;
          GST_DEBUG ("sec: %lu / %lu", (gulong) rt->numerator,
              (gulong) rt->denominator);
          value +=
              (gdouble) rt->numerator / ((gdouble) rt->denominator * 3600.0);

          /* apply sign */
          if (entry->tag == EXIF_TAG_GPS_LATITUDE) {
            if (((meudata->latitude_ref == 'S') && (value > 0.0)) ||
                ((meudata->latitude_ref == 'N') && (value < 0.0))) {
              value = -value;
            }
          } else {
            if (((meudata->longitude_ref == 'W') && (value > 0.0)) ||
                ((meudata->longitude_ref == 'E') && (value < 0.0))) {
              value = -value;
            }
          }
          GST_DEBUG ("long/lat : %lf", value);
        }
        if (entry->tag == EXIF_TAG_GPS_ALTITUDE) {
          ExifRational v_rat = exif_get_rational (entry->data, byte_order);
          value = (gdouble) v_rat.numerator / (gdouble) v_rat.denominator;
          if (((meudata->altitude_ref == 1) && (value > 0.0)) ||
              ((meudata->altitude_ref == 0) && (value < 0.0))) {
            value = -value;
          }
          GST_DEBUG ("altitude = %lf", value);
        }
        gst_tag_list_add (meudata->taglist, meudata->mode, tag, value, NULL);
      }
        break;
      default:
        break;
    }
  }


done:
  {
#ifndef GST_DISABLE_GST_DEBUG
    char buf[2048];
    GST_LOG ("\n    Entry %p: %s (%s)\n"
        "      Size, Comps: %d, %d\n"
        "      Value: %s\n"
        "      Title: %s\n"
        "      Description: %s\n",
        entry,
        exif_tag_get_name (entry->tag),
        exif_format_get_name (entry->format),
        entry->size,
        (int) (entry->components),
        exif_entry_get_value (entry, buf, sizeof (buf)),
        exif_tag_get_title (entry->tag), exif_tag_get_description (entry->tag));
#endif
  }
  return;

}
void FileSystemScanner::readEXIF(File* file)
{
    static QString EXIFIFD_NAME_EXIF = exif_ifd_get_name(EXIF_IFD_EXIF);

    int maxDataLength = 255;
    char* charData = new char[maxDataLength];

    ExifData* exifData = exif_data_new_from_file(file->fileInfo()->absFilePath().ascii());
//    exif_data_dump(exifData);

    for (int i = 0; i < EXIF_IFD_COUNT; i++) {
        ExifContent* content = exifData->ifd[i];

        QString group = QString(exif_ifd_get_name((ExifIfd) i));
        if (group == EXIFIFD_NAME_EXIF) {

            for (unsigned int e = 0; e < content->count; e++) {
                ExifEntry* entry = content->entries[e];

                ExifTag exifTagType = entry->tag;
                QString title = QString(exif_tag_get_title(entry->tag));
                QString name = QString(exif_tag_get_name(entry->tag));

                exif_entry_get_value(entry, charData, maxDataLength);
                QString data = QString(charData);

                QString description = QString(exif_tag_get_description(entry->tag));
//                tracer->sdebug(__func__) << "    - " << title << " / " << name << " = " << data << " (" << description << ")" << endl;

                // get the exif tagnode title and the tagnode representing this tag from the engine
                TagNode* exifTagNodeTitle = m_engine->exifTagNodeTitle();
                TagNode* exifTagNodeEntry = exifTagNodeTitle->child(title);

                switch (exifTagType) {
                    case EXIF_TAG_DATE_TIME_ORIGINAL:
                    case EXIF_TAG_DATE_TIME_DIGITIZED: {
                        QDateTime dateTime = readExifDateTime(data);
                        TagNodeDateTime* exifTagNodeEntryDateTime = dynamic_cast<TagNodeDateTime*>(exifTagNodeEntry);
                        if (exifTagNodeEntryDateTime == 0) {
                            // tagnode for this EXIF entry does not exist --> create it
                            exifTagNodeEntryDateTime = dynamic_cast<TagNodeDateTime*>(m_engine->createTag(exifTagNodeTitle, TagNode::TYPE_DATETIME, title, description, QString::null));
                            exifTagNodeEntryDateTime->setReadonly(true);
                        }
                        if (dateTime.isValid()) {
                            // create new assoc
                            new FileTagNodeAssocDateTime(file, exifTagNodeEntryDateTime, dateTime);
                        }

                        break;
                    }
                    default: {
                        TagNodeString* exifTagNodeEntryString = dynamic_cast<TagNodeString*>(exifTagNodeEntry);
                        if (exifTagNodeEntryString == 0) {
                            // tagnode for this EXIF entry does not exist --> create it
                            exifTagNodeEntryString = dynamic_cast<TagNodeString*>(m_engine->createTag(exifTagNodeTitle, TagNode::TYPE_STRING, title, description, QString::null));
                            exifTagNodeEntryString->setReadonly(true);
                        }
                        // create new assoc
                        new FileTagNodeAssocString(file, exifTagNodeEntryString, data);
                    }
                }
            }
        }
    }

    exif_data_free(exifData);
    delete charData;
}