Example #1
0
/**
 * a_geotag_get_exif_date_from_file:
 * @filename: The image file to process
 * @has_GPS_info: Returns whether the file has existing GPS information
 *
 * Returns: An allocated string with the date and time in EXIF_DATE_FORMAT, otherwise NULL if some kind of failure
 *
 *  Here EXIF processing is used to get time information
 *
 */
gchar* a_geotag_get_exif_date_from_file ( const gchar *filename, gboolean *has_GPS_info )
{
	gchar* datetime = NULL;

	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		return datetime;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		datetime = g_strdup ( str );
	}

	// Check GPS Info
	*has_GPS_info = FALSE;
	
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ee && ee->components == 4 )
		*has_GPS_info = TRUE;

	exif_data_free ( ed );

	return datetime;
}
/**
 * Updates the sensor by reading the current value into it
 */
static void update(CAMERA_STATE *camera, struct sensor *sensor) {
    if (!sensor->enabled)
        return;

    struct state *state = (struct state *) sensor;

    if (!state->loader)
        state->loader = exif_loader_new();

    exif_loader_reset(state->loader);
    exif_loader_write(state->loader, camera->imagedata.buffer, camera->imagedata.pos);
    ExifData *data = exif_loader_get_data(state->loader);
    ExifByteOrder bo = exif_data_get_byte_order(data);

    int valid = get_shutter_speed(data, bo, &state->shutter_speed);

    if (valid)
        valid = get_aperture(data, bo, &state->aperture);

    if (valid)
        valid = getDouble(data, bo, EXIF_TAG_ISO_SPEED_RATINGS, &state->iso);

    exif_data_free(data);

    if (valid) {
        // Calculate the light level
        state->light_level = (2.0 * log(state->aperture) - log(state->shutter_speed) - log(state->iso / 100.0)) / log(2.0);

        // Update the sensor
        sensor_log(camera, &state->sensor, (int) (state->light_level * 1000), "Lvl %.1f", state->light_level);
    }
}
///@todo create a dedicated EXIF class
QString ImageImporter::getExifData(const QString& filename, ExifTag tag)
{
    ExifData* ed = exif_data_new_from_file(filename.ascii());
    ExifContent* c0, * c1, * cExif;

    c0    = ed->ifd[EXIF_IFD_0];
    c1    = ed->ifd[EXIF_IFD_1];
    cExif = ed->ifd[EXIF_IFD_EXIF];

    switch (tag) {
    case EXIF_TAG_MAKE:
    case EXIF_TAG_MODEL:
    case EXIF_TAG_SOFTWARE:
        return getEntry(c0, tag);
        break;

    case EXIF_TAG_EXPOSURE_TIME:
    case EXIF_TAG_FNUMBER:
    case EXIF_TAG_PIXEL_X_DIMENSION:
    case EXIF_TAG_PIXEL_Y_DIMENSION:
    case EXIF_TAG_FLASH:
    case EXIF_TAG_FOCAL_LENGTH_IN_35MM_FILM:
    case EXIF_TAG_ISO_SPEED_RATINGS:
    case EXIF_TAG_DATE_TIME_ORIGINAL:
        return getEntry(cExif, tag);
        break;

    default:
        return "";
        break;
    }

    exif_data_free(ed);
}
Example #4
0
long GalleryUtil::GetNaturalRotation(const unsigned char *buffer, int size)
{
    long rotateAngle = 0;

#ifdef EXIF_SUPPORT
    try
    {
        ExifData *data = exif_data_new_from_data(buffer, size);
        if (data)
        {
            rotateAngle = GetNaturalRotation(data);
            exif_data_free(data);
        }
        else
        {
            LOG(VB_FILE, LOG_ERR, LOC + "Could not load exif data from buffer");
        }
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            "Failed to extract EXIF headers from buffer");
    }
#else
    // Shut the compiler up about the unused argument
    (void)buffer;
    (void)size;
#endif

    return rotateAngle;
}
Example #5
0
void imFileFormatJPEG::iWriteExifAttrib(imAttribTable* attrib_table)
{
  ExifData* exif = exif_data_new();

  ExifByteOrder byte_order;
  if (imBinCPUByteOrder() == IM_LITTLEENDIAN)
    byte_order = EXIF_BYTE_ORDER_INTEL;
  else
    byte_order = EXIF_BYTE_ORDER_MOTOROLA;
    
  exif_data_set_byte_order(exif, byte_order);

  attrib_table->ForEach(exif, (imAttribTableCallback)iExifWriteTag);

  imbyte* data = NULL;
  unsigned int data_size = 0;

  exif_data_save_data(exif, &data, &data_size);

  if (data)
  {
    jpeg_write_marker(&this->cinfo, JPEG_APP0+1, data, data_size);
    free(data);
  }

  exif_data_free(exif);
}
Example #6
0
long GalleryUtil::GetNaturalRotation(const QString &filePathString)
{
    long rotateAngle = 0;

#ifdef EXIF_SUPPORT
    QByteArray filePathBA = filePathString.toLocal8Bit();
    const char *filePath = filePathBA.constData();

    try
    {
        ExifData *data = exif_data_new_from_file(filePath);
        if (data)
        {
            rotateAngle = GetNaturalRotation(data);
            exif_data_free(data);
        }
        else
        {
            LOG(VB_FILE, LOG_ERR, LOC +
                QString("Could not load exif data from '%1'") .arg(filePath));
        }
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to extract EXIF headers from '%1'") .arg(filePath));
    }
#else
    // Shut the compiler up about the unused argument
    (void)filePathString;
#endif

    return rotateAngle;
}
Example #7
0
/**
 * a_geotag_create_waypoint_positioned:
 * @filename: The image file to process
 * @coord:    The location for positioning the Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 *
 * Returns: An allocated Waypoint or NULL if Waypoint could not be generated
 *
 *  Here EXIF processing is used to get non position related information (i.e. just the comment)
 *
 */
VikWaypoint* a_geotag_create_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name )
{
	*name = NULL;
	VikWaypoint *wp = vik_waypoint_new();
	wp->visible = TRUE;
	wp->coord = coord;
	wp->altitude = alt;

	ExifData *ed = exif_data_new_from_file ( filename );

	// Set info from exif values
	if ( ed ) {
		wp->comment = geotag_get_exif_comment ( ed );

		gchar str[128];
		ExifEntry *ee;
		// Name
		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
		if ( ee ) {
			exif_entry_get_value ( ee, str, 128 );
			*name = g_strdup ( str );
		}

		// Finished with EXIF
		exif_data_free ( ed );
	}

	vik_waypoint_set_image ( wp, filename );


	return wp;
}
Example #8
0
// Implementation using libexif
void ImageResolution::readexif(char const *fn) {
  ExifData *ed;
  ed = exif_data_new_from_file(fn);
  if (!ed)
    return;
  ExifByteOrder byte_order = exif_data_get_byte_order(ed);
  
  ExifEntry *xres = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
					   EXIF_TAG_X_RESOLUTION);
  ExifEntry *yres = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
					   EXIF_TAG_Y_RESOLUTION);
  ExifEntry *unit = exif_content_get_entry(ed->ifd[EXIF_IFD_0],
					   EXIF_TAG_RESOLUTION_UNIT);
  if (xres && yres) {
    x_ = exifDouble(xres, byte_order);
    y_ = exifDouble(yres, byte_order);
    if (unit) {
      double u = exifDouble(unit, byte_order);
      if (u==3) {
	x_ *= 2.54;
	y_ *= 2.54;
      }
    }
    ok_ = true;
  }
  exif_data_free(ed);
}
Example #9
0
QPixmap ExifPixmap::createPixmap(QString path)
{
    ExifData *exifData = exif_data_new_from_file(path.toStdString().c_str());
    int orientation = 0;
    if(exifData) {
        ExifByteOrder byteOrder = exif_data_get_byte_order(exifData);
        ExifEntry *exifEntry = exif_data_get_entry(exifData, EXIF_TAG_ORIENTATION);
        if(exifEntry) {
            orientation = exif_get_short(exifEntry->data, byteOrder);
        }
        exif_data_free(exifData);
    }
    QPixmap pic(path);
    /*
              0th Row      0th Column
           1  top          left side
           2  top          right side
           3  bottom       right side
           4  bottom       left side
           5  left side    top
           6  right side   top
           7  right side   bottom
           8  left side    bottom
        */
    QTransform t;
    switch(orientation) { // TODO : test flips
    case 1:
        break;
    case 2:
        t.scale(-1,1);
        break;
    case 3:
        t.rotate(180);
        break;
    case 4:
        t.rotate(180);
        t.scale(-1,1);
        break;
    case 5:
        t.rotate(90);
        t.scale(-1,1);
        break;
    case 6:
        t.rotate(90);
        break;
    case 7:
        t.rotate(-90);
        t.scale(-1,1);
        break;
    case 8:
        t.rotate(-90);
        break;
    default:
        break;
    }

    return pic.transformed(t);
}
Example #10
0
/**
 * a_geotag_get_exif_date_from_file:
 * @filename: The image file to process
 * @has_GPS_info: Returns whether the file has existing GPS information
 *
 * Returns: An allocated string with the date and time in EXIF_DATE_FORMAT, otherwise NULL if some kind of failure
 *
 *  Here EXIF processing is used to get time information
 *
 */
gchar* a_geotag_get_exif_date_from_file ( const gchar *filename, gboolean *has_GPS_info )
{
	gchar* datetime = NULL;
	*has_GPS_info = FALSE;

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
		gdouble lat, lon;
		*has_GPS_info = ( gexiv2_metadata_get_gps_longitude(gemd,&lon) && gexiv2_metadata_get_gps_latitude(gemd,&lat) );

		// Prefer 'Photo' version over 'Image'
		if ( gexiv2_metadata_has_tag ( gemd, "Exif.Photo.DateTimeOriginal" ) )
			datetime = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Photo.DateTimeOriginal" ) );
		else
			datetime = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.DateTimeOriginal" ) );
	}
	metadata_free ( gemd );
#else
#ifdef HAVE_LIBEXIF
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		return datetime;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		datetime = g_strdup ( str );
	}

	// Check GPS Info

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ee && ee->components == 4 )
		*has_GPS_info = TRUE;

	// Check other basic GPS fields exist too
	// I have encountered some images which have just the EXIF_TAG_GPS_VERSION_ID but nothing else
	// So to confirm check more EXIF GPS TAGS:
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( !ee )
		*has_GPS_info = FALSE;
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( !ee )
		*has_GPS_info = FALSE;

	exif_data_free ( ed );
#endif
#endif
	return datetime;
}
void
exif_data_unref (ExifData *data)
{
	if (!data) 
		return;

	data->priv->ref_count--;
	if (!data->priv->ref_count) 
		exif_data_free (data);
}
Example #12
0
/**
 * a_geotag_waypoint_positioned:
 * @filename: The image file to process
 * @coord:    The location for positioning the Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 * @waypoint: An existing waypoint to update (can be NULL to generate a new waypoint)
 *
 * Returns: An allocated waypoint if the input waypoint is NULL,
 *  otherwise the passed in waypoint is updated
 *
 *  Here EXIF processing is used to get non position related information (i.e. just the comment)
 *
 */
VikWaypoint* a_geotag_waypoint_positioned ( const gchar *filename, VikCoord coord, gdouble alt, gchar **name, VikWaypoint *wp )
{
	*name = NULL;
	if ( wp == NULL ) {
		// Need to create waypoint
		wp = vik_waypoint_new();
		wp->visible = TRUE;
	}
	wp->coord = coord;
	wp->altitude = alt;

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
			wp->comment = geotag_get_exif_comment ( gemd );
			if ( gexiv2_metadata_has_tag ( gemd, "Exif.Image.XPTitle" ) )
				*name = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.XPTitle" ) );
	}
	metadata_free ( gemd );
#else
#ifdef HAVE_LIBEXIF
	ExifData *ed = exif_data_new_from_file ( filename );

	// Set info from exif values
	if ( ed ) {
		wp->comment = geotag_get_exif_comment ( ed );

		gchar str[128];
		ExifEntry *ee;
		// Name
		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
		if ( ee ) {
			exif_entry_get_value ( ee, str, 128 );
			*name = g_strdup ( str );
		}

		// Finished with EXIF
		exif_data_free ( ed );
	}
#endif
#endif

	vik_waypoint_set_image ( wp, filename );

	return wp;
}
ExifData *
exif_data_new_mem (ExifMem *mem)
{
	ExifData *data;
	unsigned int i;

	if (!mem) 
		return NULL;

	data = exif_mem_alloc (mem, sizeof (ExifData));
	if (!data) 
		return (NULL);
	data->priv = exif_mem_alloc (mem, sizeof (ExifDataPrivate));
	if (!data->priv) { 
	  	exif_mem_free (mem, data); 
		return (NULL); 
	}
	data->priv->ref_count = 1;

	data->priv->mem = mem;
	exif_mem_ref (mem);

	for (i = 0; i < EXIF_IFD_COUNT; i++) {
		data->ifd[i] = exif_content_new_mem (data->priv->mem);
		if (!data->ifd[i]) {
			exif_data_free (data);
			return (NULL);
		}
		data->ifd[i]->parent = data;
	}

	/* Default options */
#ifndef NO_VERBOSE_TAG_STRINGS
	/*
	 * When the tag list is compiled away, setting this option prevents
	 * any tags from being loaded
	 */
	exif_data_set_option (data, EXIF_DATA_OPTION_IGNORE_UNKNOWN_TAGS);
#endif
	exif_data_set_option (data, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION);

	/* Default data type: none */
	exif_data_set_data_type (data, EXIF_DATA_TYPE_COUNT);

	return (data);
}
Example #14
0
static int
parse_exif( VipsImage *im, void *data, int data_length )
{
#ifdef HAVE_EXIF
    {
        ExifData *ed;
        VipsExif ve;

        if( !(ed = exif_data_new_from_data( data, data_length )) )
            return( -1 );

#ifdef DEBUG_VERBOSE
        show_tags( ed );
        show_values( ed );
#endif /*DEBUG_VERBOSE*/

        /* Attach informational fields for what we find.

        	FIXME ... better to have this in the UI layer?

        	Or we could attach non-human-readable tags here (int,
        	double etc) and then move the human stuff to the UI
        	layer?

         */
        ve.image = im;
        ve.ed = ed;
        exif_data_foreach_content( ed,
        (ExifDataForeachContentFunc) attach_exif_content, &ve );

        /* Look for resolution fields and use them to set the VIPS
         * xres/yres fields.
         */
        res_from_exif( im, ed );

        attach_thumbnail( im, ed );

        exif_data_free( ed );
    }
#endif /*HAVE_EXIF*/

    return( 0 );
}
Example #15
0
/**
 * a_geotag_get_position:
 *
 * @filename: The (JPG) file with EXIF information in it
 *
 * Returns: The position in LatLon format.
 *  It will be 0,0 if some kind of failure occurs.
 */
struct LatLon a_geotag_get_position ( const gchar *filename )
{
	struct LatLon ll = { 0.0, 0.0 };

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
		gdouble lat;
		gdouble lon;
		gdouble alt;
		if ( gexiv2_metadata_get_gps_info ( gemd, &lon, &lat, &alt ) ) {
			ll.lat = lat;
			ll.lon = lon;
		}
	}
	metadata_free  ( gemd );
#else
#ifdef HAVE_LIBEXIF
	// open image with libexif
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		return ll;

	ExifEntry *ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ! ( ee && ee->components == 4 ) )
		goto MyReturn0;

	ll = get_latlon ( ed );

MyReturn0:
	// Finished with EXIF
	exif_data_free ( ed );
#endif
#endif

	return ll;
}
Example #16
0
void psd_image_resource_free(psd_context * context)
{
	psd_int i;
	
	psd_alpha_channel_free(context);
	
	psd_freeif(context->layer_group_id);
	psd_freeif(context->thumbnail_resource.jfif_data);
	psd_freeif(context->thumbnail_resource.thumbnail_data);
	psd_freeif(context->version_info.writer_name);
	psd_freeif(context->version_info.reader_name);
	psd_freeif(context->grid_guides.guide_coordinate);
	psd_freeif(context->grid_guides.guide_direction);
	psd_freeif(context->slices_resource.slices_resource_block);
	psd_freeif(context->color_samplers.resource);

	for (i = 0; i < context->url_list.number_of_urls; i ++)
		psd_freeif(context->url_list.items[i].name);
	psd_freeif(context->url_list.items);

#ifdef PSD_INCLUDDE_LIBEXIF
	exif_data_free((ExifData *)context->exif_data);
#else
	psd_freeif(context->exif_data);
#endif

#ifdef PSD_INCLUDE_LIBXML
	xmlFreeDoc((xmlDocPtr)context->XMP_metadata);
#else
	psd_freeif(context->XMP_metadata);
#endif

#ifdef PSD_GET_PATH_RESOURCE
	psd_path_free(context);
#endif
}
void freeExifData(ExifData* exifData) {
    exif_data_free(exifData);
}
Example #18
0
void imFileFormatJPEG::iReadExifAttrib(unsigned char* data, int data_length, imAttribTable* attrib_table)
{
  ExifData* exif = exif_data_new_from_data(data, data_length);
  if (!exif)
    return;

  void* value = NULL;
  int c, value_size = 0;

  ExifByteOrder byte_order = exif_data_get_byte_order(exif);

  for (int ifd = 0; ifd < EXIF_IFD_COUNT; ifd++)
  {
    if (ifd == EXIF_IFD_1 || ifd == EXIF_IFD_INTEROPERABILITY) // Skip thumbnail and interoperability
      continue;

    ExifContent *content = exif->ifd[ifd];

    if (content && content->count) 
    {
      for (int j = 0; j < (int)content->count; j++) 
      {
        ExifEntry *entry = content->entries[j];
        int type = 0;

        const char* name = exif_tag_get_name_in_ifd(entry->tag, (ExifIfd)ifd);
        if (!name)
          continue;

        if (value_size < (int)entry->size)
        {
          value = realloc(value, entry->size);
          value_size = entry->size;
        }

        int format_size = exif_format_get_size(entry->format);

        if (entry->tag == EXIF_TAG_RESOLUTION_UNIT)
        {
          int res_unit = (int)exif_get_short (entry->data, byte_order);

          if (res_unit == 2)
            attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPI");
          else if (res_unit == 3)
            attrib_table->Set("ResolutionUnit", IM_BYTE, -1, "DPC");

          continue;
        }

        switch (entry->format) 
        {
        case EXIF_FORMAT_UNDEFINED:
        case EXIF_FORMAT_ASCII:
        case EXIF_FORMAT_SBYTE:
        case EXIF_FORMAT_BYTE:
          {
            type = IM_BYTE;
            imbyte *bvalue = (imbyte*)value;
            for (c = 0; c < (int)entry->components; c++) 
              bvalue[c] = entry->data[c];
          }
          break;
        case EXIF_FORMAT_SSHORT:
          {
            type = IM_SHORT;
            short *svalue = (short*)value;
            for (c = 0; c < (int)entry->components; c++) 
              svalue[c] = exif_get_short(entry->data + format_size * c, byte_order);
          }
          break;
        case EXIF_FORMAT_SHORT:
          {
            type = IM_USHORT;
            imushort *usvalue = (imushort*)value;
            for (c = 0; c < (int)entry->components; c++) 
              usvalue[c] = exif_get_short(entry->data + format_size * c, byte_order);
          }
          break;
        case EXIF_FORMAT_LONG:
          {
            type = IM_INT;
            int *ivalue = (int*)value;
            for (c = 0; c < (int)entry->components; c++) 
              ivalue[c] = (int)exif_get_long(entry->data + format_size * c, byte_order);
          }
          break;
        case EXIF_FORMAT_SLONG:
          {
            type = IM_INT;
            int *ivalue = (int*)value;
            for (c = 0; c < (int)entry->components; c++) 
              ivalue[c] = (int)exif_get_slong(entry->data + format_size * c, byte_order);
          }
          break;
        case EXIF_FORMAT_RATIONAL:
          {
            ExifRational v_rat;
            type = IM_FLOAT;
            float *fvalue = (float*)value;
            for (c = 0; c < (int)entry->components; c++) 
            {
              v_rat = exif_get_rational(entry->data + format_size * c, byte_order);
              fvalue[c] = (float)v_rat.numerator / (float)v_rat.denominator;
            }
          }
          break;
        case EXIF_FORMAT_SRATIONAL:
          {
            ExifSRational v_srat;
            type = IM_FLOAT;
            float *fvalue = (float*)value;
            for (c = 0; c < (int)entry->components; c++) 
            {
              v_srat = exif_get_srational(entry->data + format_size * c, byte_order);
              fvalue[c] = (float)v_srat.numerator / (float)v_srat.denominator;
            }
          }
          break;
        case EXIF_FORMAT_FLOAT:  // defined but unsupported in libEXIF
        case EXIF_FORMAT_DOUBLE: // defined but unsupported in libEXIF
          break;
        }

        attrib_table->Set(name, type, entry->components, value);
      }
    }
  }

  if (value) free(value);

  exif_data_free(exif);
}
Example #19
0
long GalleryUtil::GetNaturalRotation(const QString &filePathString)
{
    long rotateAngle = 0;
#ifdef EXIF_SUPPORT
    QByteArray filePathBA = filePathString.toLocal8Bit();
    const char *filePath = filePathBA.constData();

    try
    {
        char *exifvalue = new char[1024];
        ExifData *data = exif_data_new_from_file (filePath);
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                                                        EXIF_TAG_ORIENTATION);
                ExifByteOrder byteorder = exif_data_get_byte_order (data);

                if (entry)
                {
                    ExifShort v_short = exif_get_short (entry->data, byteorder);
                    VERBOSE(VB_GENERAL|VB_EXTRA, QString("Exif entry=%1").arg(v_short));
                    /* See http://sylvana.net/jpegcrop/exif_orientation.html*/
                    if (v_short == 8)
                    {
                        rotateAngle = -90;
                    }
                    else if (v_short == 6)
                    {
                        rotateAngle = 90;
                    }
                    break;
                }
            }
            exif_data_free(data);
        }
        else
        {
            VERBOSE(VB_FILE, LOC_ERR +
                    QString("Could not load exif data from '%1'")
                    .arg(filePath));
        }
        
        delete [] exifvalue;
        
#if 0
        Exiv2::ExifData exifData;
        int rc = exifData.read(filePath);
        if (!rc)
        {
            Exiv2::ExifKey key = Exiv2::ExifKey("Exif.Image.Orientation");
            Exiv2::ExifData::iterator pos = exifData.findKey(key);
            if (pos != exifData.end())
            {
                long orientation = pos->toLong();
                switch (orientation)
                {
                    case 6:
                        rotateAngle = 90;
                        break;
                    case 8:
                        rotateAngle = -90;
                        break;
                    default:
                        rotateAngle = 0;
                        break;
                }
            }
        }
#endif
    }
    catch (...)
    {
        VERBOSE(VB_IMPORTANT, LOC_ERR +
                QString("Failed to extract EXIF headers from '%1'")
                .arg(filePathString));
    }

#else
    // Shut the compiler up about the unused argument
    (void)filePathString;
#endif // EXIF_SUPPORT
    return rotateAngle;
}
Example #20
0
QDateTime GalleryUtil::GetTimestamp(const QString &filePath)
{
    QDateTime timestamp;

    try
    {
#ifdef EXIF_SUPPORT
#if NEW_LIB_EXIF
        char *exifvalue = new char[20];
#endif
        ExifData *data = exif_data_new_from_file(
            filePath.toLocal8Bit().constData());
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                    EXIF_TAG_DATE_TIME_ORIGINAL);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 20);
                    QString formatted = exifvalue;
#else
                    QString formatted = exif_entry_get_value(entry);
#endif
                    timestamp = QDateTime::fromString(formatted,
                        "yyyy:MM:dd hh:mm:ss");
                    if (timestamp.isValid())
                    {
                        // Found one, done
                        break;
                    }
                    else
                    {
                        LOG(VB_FILE, LOG_ERR, LOC +
                            QString("Could not parse exif timestamp from '%1'")
                            .arg(filePath));
                    }
                }
            }
            exif_data_free(data);
        }
        else
        {
           LOG(VB_FILE, LOG_ERR, LOC +
               QString("Could not load exif data from '%1'") .arg(filePath));
        }
#if NEW_LIB_EXIF
        delete [] exifvalue;
#endif
#endif // EXIF_SUPPORT
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to extract EXIF headers from '%1'") .arg(filePath));
    }

    return timestamp;
}
Example #21
0
QString GalleryUtil::GetCaption(const QString &filePath)
{
    QString caption("");

    try
    {
#ifdef EXIF_SUPPORT
#if NEW_LIB_EXIF
        char *exifvalue = new char[1024];
#endif
        ExifData *data = exif_data_new_from_file(
            filePath.toLocal8Bit().constData());
        if (data)
        {
            for (int i = 0; i < EXIF_IFD_COUNT; i++)
            {
                ExifEntry *entry = exif_content_get_entry (data->ifd[i],
                                                    EXIF_TAG_USER_COMMENT);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 1024);
                    caption = exifvalue;
#else
                    caption = exif_entry_get_value(entry);
#endif
                    // Found one, done
                    if(!caption.trimmed().isEmpty())
                       break;
                }

                entry = exif_content_get_entry (data->ifd[i],
                                                EXIF_TAG_IMAGE_DESCRIPTION);
                if (entry)
                {
#if NEW_LIB_EXIF
                    exif_entry_get_value(entry, exifvalue, 1024);
                    caption = exifvalue;
#else
                    caption = exif_entry_get_value(entry);
#endif
                    // Found one, done
                    if(!caption.trimmed().isEmpty())
                       break;
                }
            }
            exif_data_free(data);
        }
        else
        {
           LOG(VB_FILE, LOG_ERR, LOC +
               QString("Could not load exif data from '%1'") .arg(filePath));
        }
#if NEW_LIB_EXIF
        delete [] exifvalue;
#endif
#endif // EXIF_SUPPORT
    }
    catch (...)
    {
        LOG(VB_GENERAL, LOG_ERR, LOC +
            QString("Failed to extract EXIF headers from '%1'") .arg(filePath));
    }

    return caption;
}
Example #22
0
static int
write_exif( Write *write )
{
	unsigned char *data;
	size_t data_length;
	unsigned int idl;
#ifdef HAVE_EXIF
	ExifData *ed;

	/* Either parse from the embedded EXIF, or if there's none, make
	 * some fresh EXIF we can write the resolution to.
	 */
	if( im_header_get_typeof( write->in, IM_META_EXIF_NAME ) ) {
		if( im_meta_get_blob( write->in, IM_META_EXIF_NAME, 
			(void *) &data, &data_length ) )
			return( -1 );

		if( !(ed = exif_data_new_from_data( data, data_length )) )
			return( -1 );
	}
	else 
		ed = exif_data_new();

	/* Update EXIF resolution from VIPS.
	 */
	if( set_exif_resolution( ed, write->in ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Reserialise and write. exif_data_save_data() returns an int for some
	 * reason.
	 */
	exif_data_save_data( ed, &data, &idl );
	if( !idl ) {
		im_error( "im_jpeg2vips", "%s", _( "error saving EXIF" ) );
		exif_data_free( ed );
		return( -1 );
	}
	data_length = idl;

#ifdef DEBUG
	printf( "im_vips2jpeg: attaching %zd bytes of EXIF\n", data_length  );
#endif /*DEBUG*/

	exif_data_free( ed );
	jpeg_write_marker( &write->cinfo, JPEG_APP0 + 1, data, data_length );
	free( data );
#else /*!HAVE_EXIF*/
	/* No libexif ... just copy the embedded EXIF over.
	 */
	if( im_header_get_typeof( write->in, IM_META_EXIF_NAME ) ) {
		if( im_meta_get_blob( write->in, IM_META_EXIF_NAME, 
			(void *) &data, &data_length ) )
			return( -1 );

#ifdef DEBUG
		printf( "im_vips2jpeg: attaching %d bytes of EXIF\n", 
			data_length  );
#endif /*DEBUG*/

		jpeg_write_marker( &write->cinfo, JPEG_APP0 + 1, 
			data, data_length );
	}
#endif /*!HAVE_EXIF*/

	return( 0 );
}
Example #23
0
GstTagList *
gst_droidcamsrc_exif_tags_from_jpeg_data (void *data, size_t size)
{
  GstTagList *tags = NULL;
  ExifMem *mem = exif_mem_new (g_malloc0, g_realloc, g_free);
  ExifData *exif = exif_data_new_mem (mem);
  unsigned char *exif_data = NULL;
  void *_exif_data = NULL;
  unsigned int exif_data_size = 0;
  GstBuffer *buffer;
  ExifEntry *iso;
  int x, i;

  exif_data_load_data (exif, data, size);
  exif_data_set_data_type (exif, EXIF_DATA_TYPE_COMPRESSED);

  exif_data_save_data (exif, &exif_data, &exif_data_size);
  if (!exif_data_size) {
    goto out;
  }

  if (exif_data_size <= 6) {
    goto out;
  }

  /* dump the data. based on libexif code */
  for (x = 0; x < EXIF_IFD_COUNT; x++) {
    if (exif->ifd[x] && exif->ifd[x]->count) {
      for (i = 0; i < exif->ifd[x]->count; i++) {
        char val[1024];
        ExifEntry *e = exif->ifd[x]->entries[i];
        GST_LOG ("Exif IFD: %s. Tag 0x%x (%s) = %s", exif_ifd_get_name (x),
            e->tag, exif_tag_get_name_in_ifd (e->tag, exif_entry_get_ifd (e)),
            exif_entry_get_value (e, val, sizeof (val)));
      }
    }
  }

  _exif_data = exif_data;

  exif_data += 6;
  exif_data_size -= 6;

  buffer = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
      exif_data, exif_data_size, 0, exif_data_size, NULL, NULL);
  tags = gst_tag_list_from_exif_buffer_with_tiff_header (buffer);
  gst_buffer_unref (buffer);

  /* We don't want these tags */
  gst_tag_list_remove_tag (tags, GST_TAG_DEVICE_MANUFACTURER);
  gst_tag_list_remove_tag (tags, GST_TAG_DEVICE_MODEL);
  gst_tag_list_remove_tag (tags, GST_TAG_APPLICATION_NAME);
  gst_tag_list_remove_tag (tags, GST_TAG_DATE_TIME);

  /* we have a mess with ISO so we will just behave as N9 */
  iso = exif_content_get_entry (exif->ifd[EXIF_IFD_EXIF],
      EXIF_TAG_ISO_SPEED_RATINGS);

  if (iso) {
#ifdef __arm__
    guint16 val = exif_get_short (iso->data, EXIF_BYTE_ORDER_MOTOROLA);
#else
    guint16 val = exif_get_short (iso->data, EXIF_BYTE_ORDER_INTEL);
#endif
    gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE,
        GST_TAG_CAPTURING_ISO_SPEED, val, NULL);
  }

  /* TODO: the following are being dropped
   *
   * 0x213  EXIF_TAG_YCBCR_POSITIONING
   * 0x9004 EXIF_TAG_DATE_TIME_DIGITIZED
   * 0x9101 EXIF_TAG_COMPONENTS_CONFIGURATION
   * 0xa001 EXIF_TAG_COLOR_SPACE
   * 0xa002 EXIF_TAG_PIXEL_X_DIMENSION
   * 0xa003 EXIF_TAG_PIXEL_Y_DIMENSION
   * 0xa005 EXIF_TAG_INTEROPERABILITY_IFD_POINTER
   * thumbnail.
   * 0x100 EXIF_TAG_IMAGE_WIDTH
   * 0x101 EXIF_TAG_IMAGE_LENGTH
   * 0x9203 EXIF_TAG_BRIGHTNESS_VALUE
   * 0x9205 EXIF_TAG_MAX_APERTURE_VALUE
   * 0x9206 EXIF_TAG_SUBJECT_DISTANCE
   * 0x9208 EXIF_TAG_LIGHT_SOURCE
   * 0x9286 EXIF_TAG_USER_COMMENT
   */
out:
  if (_exif_data) {
    exif_mem_free (mem, _exif_data);
  }

  if (exif) {
    exif_data_free (exif);
  }

  exif_mem_unref (mem);

  return tags;
}
Example #24
0
LocImageContainer ImageProcessor::process (QString filename)
{
	QImage image (m_data);

	if (!image.isNull()) {
		image = image.scaled(720, 500, Qt::KeepAspectRatioByExpanding);
	}

	LocImageContainer locImageContainer(image);

	locImageContainer.setAltitude(3000.00);

	//get exif data
	ExifData *ed = exif_data_new_from_file (filename.toLocal8Bit().constData());

	if (!ed) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setExifDataAvailable(false);

		return locImageContainer;
	}

	locImageContainer.setExifDataAvailable(true);

	//save temp
	char value[256]={0,};

	// Retrieve make
	QString make;
	ExifEntry *ee = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
	if (!ee) {
		make = "";
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		locImageContainer.setMake (QString(value));
	}

	// Retrieve model
	ee = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
	if (!ee) {
		locImageContainer.setCameraModel ("");
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		locImageContainer.setCameraModel ("Taken with the "+QString(value));
	}

	// Retrieve time
	ee = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if (!ee) {
		locImageContainer.setDateTaken ("");
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		QString dateTime(value);

		QDateTime dateTaken = QDateTime::fromString (dateTime, "yyyy:MM:dd HH:mm:ss");
		locImageContainer.setDateTaken (dateTaken.toString("'on 'dddd d, MMMM yyyy 'at' HH:mm"));
	}

	// Retrieve LATITUDE
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LATITUDE);
	if (!ee) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setLatitude(-9999.99);
	} else {
		if ( ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		{
			double lat = Rational2Double ( ee->data,
					exif_format_get_size(ee->format),
					exif_data_get_byte_order(ed) );

			ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LATITUDE_REF);
			if ( ee ) {
				exif_entry_get_value ( ee, value, 128 );
				if ( value[0] == 'S' )
					lat = -lat;
			}

			locImageContainer.setLocationAvailable(true);
			locImageContainer.setLatitude (lat);
		}
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LONGITUDE);
	if (!ee) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setLongitude(-9999.99);
	} else {
		if ( ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		{
			double lon = Rational2Double ( ee->data,
					exif_format_get_size(ee->format),
					exif_data_get_byte_order(ed) );

			ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LONGITUDE_REF);
			if ( ee ) {
				exif_entry_get_value ( ee, value, 128 );
				if ( value[0] == 'W' )
					lon = -lon;
			}

			locImageContainer.setLocationAvailable(true);
			locImageContainer.setLongitude (lon);
		}
	}

	exif_data_free(ed);

	return locImageContainer;
}
void ThumbGenerator::loadFile(QImage& image, const QFileInfo& fi)
{
    static int sequence = 0;

    if (GalleryUtil::IsMovie(fi.filePath()))
    {
        bool thumbnailCreated = false;
        QDir tmpDir("/tmp/mythgallery");
        if (!tmpDir.exists())
        {
            if (!tmpDir.mkdir(tmpDir.absolutePath()))
            {
                LOG(VB_GENERAL, LOG_ERR,
                    "Unable to create temp dir for movie thumbnail creation: " +
                    tmpDir.absolutePath());
            }
        }

        if (tmpDir.exists())
        {
            QString thumbFile = QString("%1.png")
                .arg(++sequence,8,10,QChar('0'));

            QString cmd = "mythpreviewgen";
            QStringList args;
            args << logPropagateArgs.split(" ", QString::SkipEmptyParts);
            args << "--infile" << '"' + fi.absoluteFilePath() + '"';
            args << "--outfile" << '"' + tmpDir.filePath(thumbFile) + '"';

            MythSystemLegacy ms(cmd, args, kMSRunShell);
            ms.SetDirectory(tmpDir.absolutePath());
            ms.Run();
            if (ms.Wait() == GENERIC_EXIT_OK)
            {
                QFileInfo thumb(tmpDir.filePath(thumbFile));
                if (thumb.exists())
                {
                    QImage img(thumb.absoluteFilePath());
                    image = img;
                    thumbnailCreated = true;
                }
            }
        }

        if (!thumbnailCreated)
        {
            QImage *img = GetMythUI()->LoadScaleImage("gallery-moviethumb.png");
            if (img)
            {
                image = *img;
            }
        }
    }
    else
    {
#ifdef EXIF_SUPPORT
        // Try to get thumbnail from exif data
        ExifData *ed = exif_data_new_from_file(fi.absoluteFilePath()
                                               .toLocal8Bit().constData());
        if (ed && ed->data)
        {
            image.loadFromData(ed->data, ed->size);
        }

        if (ed)
            exif_data_free(ed);

        if (image.width() > m_width && image.height() > m_height)
            return;
#endif

#ifdef DCRAW_SUPPORT
        QString extension = fi.suffix();
        QSet<QString> dcrawFormats = DcrawFormats::getFormats();
        int rotateAngle;

        if (dcrawFormats.contains(extension) &&
            (rotateAngle = DcrawHandler::loadThumbnail(&image,
                                               fi.absoluteFilePath())) != -1 &&
            image.width() > m_width && image.height() > m_height)
        {
            if (rotateAngle != 0)
            {
                QMatrix matrix;
                matrix.rotate(rotateAngle);
                image = image.transformed(matrix);
            }

            return;
        }
#endif

        image.load(fi.absoluteFilePath());
    }
}
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;
}
Example #27
0
/* Examine the metadata tags on the image and update the EXIF block.
 */
int
vips__exif_update( VipsImage *image )
{
	unsigned char *data;
	size_t length;
	unsigned int idl;
	ExifData *ed;

	/* Either parse from the embedded EXIF, or if there's none, make
	 * some fresh EXIF we can write the resolution to.
	 */
	if( vips_image_get_typeof( image, VIPS_META_EXIF_NAME ) ) {
		if( vips_image_get_blob( image, VIPS_META_EXIF_NAME, 
			(void *) &data, &length ) )
			return( -1 );

		if( !(ed = exif_data_new_from_data( data, length )) )
			return( -1 );
	}
	else  {
		ed = exif_data_new();

		exif_data_set_option( ed, 
			EXIF_DATA_OPTION_FOLLOW_SPECIFICATION );
		exif_data_set_data_type( ed, EXIF_DATA_TYPE_COMPRESSED );
		exif_data_set_byte_order( ed, EXIF_BYTE_ORDER_INTEL );
	
		/* Create the mandatory EXIF fields with default data.
		 */
		exif_data_fix( ed );
	}

	/* Update EXIF tags from the image metadata.
	 */
	vips_exif_update( ed, image );

	/* Update EXIF resolution from the vips image header.
	 */
	if( vips_exif_resolution_from_image( ed, image ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Update EXIF image dimensions from the vips image header.
	 */
	if( vips_exif_set_dimensions( ed, image ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Update EXIF orientation from the vips image header.
	 */
	if( vips_exif_set_orientation( ed, image ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Update the thumbnail.
	 */
	if( vips_exif_set_thumbnail( ed, image ) ) {
		exif_data_free( ed );
		return( -1 );
	}

	/* Reserialise and write. exif_data_save_data() returns an int for some
	 * reason.
	 */
	exif_data_save_data( ed, &data, &idl );
	if( !idl ) {
		vips_error( "exif", "%s", _( "error saving EXIF" ) );
		exif_data_free( ed );
		return( -1 );
	}
	length = idl;

#ifdef DEBUG
	printf( "vips__exif_update: generated %zd bytes of EXIF\n", length  );
#endif /*DEBUG*/

	vips_image_set_blob( image, VIPS_META_EXIF_NAME, 
		(VipsCallbackFn) vips_free, data, length );

	exif_data_free( ed );

	return( 0 );
}
Example #28
0
static int
read_exif( IMAGE *im, void *data, int data_length )
{
	char *data_copy;

	/* Horrifyingly, some JPEGs have several APP1 sections. We must only
	 * use the first one that starts "Exif.."
	 */
	if( ((char *) data)[0] != 'E' ||
		((char *) data)[1] != 'x' ||
		((char *) data)[2] != 'i' ||
		((char *) data)[3] != 'f' )
		return( 0 );
	if( im_header_get_typeof( im, IM_META_EXIF_NAME ) ) 
		return( 0 );

	/* Always attach a copy of the unparsed exif data.
	 */
	if( !(data_copy = im_malloc( NULL, data_length )) )
		return( -1 );
	memcpy( data_copy, data, data_length );
	if( im_meta_set_blob( im, IM_META_EXIF_NAME, 
		(im_callback_fn) im_free, data_copy, data_length ) ) {
		im_free( data_copy );
		return( -1 );
	}

#ifdef HAVE_EXIF
{
	ExifData *ed;

	if( !(ed = exif_data_new_from_data( data, data_length )) )
		return( -1 );

	if( ed->size > 0 ) {
#ifdef DEBUG_VERBOSE
		show_tags( ed );
		show_values( ed );
#endif /*DEBUG_VERBOSE*/

		/* Attach informational fields for what we find.

			FIXME ... better to have this in the UI layer?

			Or we could attach non-human-readable tags here (int, 
			double etc) and then move the human stuff to the UI 
			layer?

		 */
		exif_data_foreach_content( ed, 
			(ExifDataForeachContentFunc) attach_exif_content, im );

		/* Look for resolution fields and use them to set the VIPS 
		 * xres/yres fields.
		 */
		set_vips_resolution( im, ed );

		attach_thumbnail( im, ed );
	}

	exif_data_free( ed );
}
#endif /*HAVE_EXIF*/

	return( 0 );
}
Example #29
0
/* Scan the exif block on the image, if any, and make a set of vips metadata 
 * tags for what we find.
 */
int
vips__exif_parse( VipsImage *image )
{
	void *data;
	size_t length;
	ExifData *ed;
	VipsExifParams params;
	const char *str;

	if( !vips_image_get_typeof( image, VIPS_META_EXIF_NAME ) )
		return( 0 );
	if( vips_image_get_blob( image, VIPS_META_EXIF_NAME, &data, &length ) )
		return( -1 ); 
	if( !(ed = vips_exif_load_data_without_fix( data, length )) )
		return( -1 );

#ifdef DEBUG_VERBOSE
	show_tags( ed );
	show_values( ed );
#endif /*DEBUG_VERBOSE*/

	/* Look for resolution fields and use them to set the VIPS xres/yres 
	 * fields.
	 *
	 * If the fields are missing, set them from the image, which will have
	 * previously had them set from something like JFIF. 
	 */
	if( vips_image_resolution_from_exif( image, ed ) &&
		vips_exif_resolution_from_image( ed, image ) ) {
		exif_data_free( ed );
		return( -1 ); 
	}

	/* Make sure all required fields are there before we attach the vips
	 * metadata.
	 */
	exif_data_fix( ed );

	/* Attach informational fields for what we find.
	 */
	params.image = image;
	params.ed = ed;
	exif_data_foreach_content( ed, 
		(ExifDataForeachContentFunc) vips_exif_get_content, &params );

	vips_exif_get_thumbnail( image, ed );
	exif_data_free( ed );

	/* Orientation handling. ifd0 has the Orientation tag for the main
	 * image. 
	 */
	if( vips_image_get_typeof( image, "exif-ifd0-Orientation" ) != 0 &&
		!vips_image_get_string( image, 
			"exif-ifd0-Orientation", &str ) ) {
		int orientation;

		orientation = atoi( str );
		orientation = VIPS_CLIP( 1, orientation, 8 );
		vips_image_set_int( image, VIPS_META_ORIENTATION, orientation );
	}

	return( 0 );
}
Example #30
0
/**
 * a_geotag_create_waypoint_from_file:
 * @filename: The image file to process
 * @vcmode:   The current location mode to use in the positioning of Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 *
 * Returns: An allocated Waypoint or NULL if Waypoint could not be generated (e.g. no EXIF info)
 *
 */
VikWaypoint* a_geotag_create_waypoint_from_file ( const gchar *filename, VikCoordMode vcmode, gchar **name )
{
	// Default return values (for failures)
	*name = NULL;
	VikWaypoint *wp = NULL;

	// TODO use log?
	//ExifLog *log = NULL;

	// open image with libexif
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		// return with no Waypoint
		return wp;

	struct LatLon ll;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ! ( ee && ee->components == 4 ) )
		goto MyReturn;
	// Could test for these versions explicitly but may have byte order issues...
	//if ( ! ( ee->data[0] == 2 && ee->data[2] == 0 && ee->data[3] == 0 ) )
	//	goto MyReturn;


	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_MAP_DATUM);
	if ( ! ( ee && ee->components > 0 && ee->format == EXIF_FORMAT_ASCII ) )
		goto MyReturn;

	// If map datum specified - only deal in WGS-84 - the defacto standard
	if ( ee && ee->components > 0 ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( strncmp (str, "WGS-84", 6) )
			goto MyReturn;
	}

	//
	// Lat & Long is necessary to form a waypoint.
	//
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		goto MyReturn;
  
	ll.lat = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'S' )
			ll.lat = -ll.lat;
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		goto MyReturn;

	ll.lon = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'W' )
			ll.lon = -ll.lon;
	}

	//
	// Not worried if none of the other fields exist, as can default the values to something
	//

	gdouble alt = VIK_DEFAULT_ALTITUDE;
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE);
	if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_RATIONAL ) {
		alt = Rational2Double ( ee->data,
								0,
								exif_data_get_byte_order(ed) );

		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE_REF);
		if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_BYTE && ee->data[0] == 1 )
			alt = -alt;
	}

	// Name
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		*name = g_strdup ( str );
	}

	//
	// Now create Waypoint with acquired information
	//
	wp = vik_waypoint_new();
	wp->visible = TRUE;
	// Set info from exif values
	// Location
	vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll );
	// Altitude
	wp->altitude = alt;

	wp->comment = geotag_get_exif_comment ( ed );

	vik_waypoint_set_image ( wp, filename );

MyReturn:
	// Finished with EXIF
	exif_data_free ( ed );

	return wp;
}