| Index: chrome/utility/media_galleries/media_metadata_parser.cc | 
| diff --git a/chrome/utility/media_galleries/media_metadata_parser.cc b/chrome/utility/media_galleries/media_metadata_parser.cc | 
| index d5df856295a2977644cf74eaff4cc06b134be03f..3d6e733149318678911d4d85634434a97dde97e3 100644 | 
| --- a/chrome/utility/media_galleries/media_metadata_parser.cc | 
| +++ b/chrome/utility/media_galleries/media_metadata_parser.cc | 
| @@ -12,6 +12,7 @@ | 
| #include "base/strings/string_util.h" | 
| #include "base/task_runner_util.h" | 
| #include "base/threading/thread.h" | 
| +#include "chrome/utility/media_galleries/image_metadata_extractor.h" | 
| #include "media/base/audio_video_metadata_extractor.h" | 
| #include "media/base/data_source.h" | 
| #include "net/base/mime_sniffer.h" | 
| @@ -35,6 +36,17 @@ void SetIntScopedPtr(int value, scoped_ptr<int>* destination) { | 
| destination->reset(new int(value)); | 
| } | 
|  | 
| +void SetDoubleScopedPtr(double value, scoped_ptr<double>* destination) { | 
| +  DCHECK(destination); | 
| +  if (value >= 0) | 
| +    destination->reset(new double(value)); | 
| +} | 
| + | 
| +void SetBoolScopedPtr(bool value, scoped_ptr<bool>* destination) { | 
| +  DCHECK(destination); | 
| +  destination->reset(new bool(value)); | 
| +} | 
| + | 
| // This runs on |media_thread_|, as the underlying FFmpeg operation is | 
| // blocking, and the utility thread must not be blocked, so the media file | 
| // bytes can be sent from the browser process to the utility process. | 
| @@ -112,6 +124,38 @@ void FinishParseAudioVideoMetadata( | 
| callback.Run(*metadata, *attached_images); | 
| } | 
|  | 
| +void FinishParseImageMetadata( | 
| +    ImageMetadataExtractor* extractor, const std::string& mime_type, | 
| +    MediaMetadataParser::MetadataCallback callback, bool extract_success) { | 
| +  DCHECK(extractor); | 
| +  MediaMetadataParser::MediaMetadata metadata; | 
| +  metadata.mime_type = mime_type; | 
| + | 
| +  if (!extract_success) { | 
| +    callback.Run(metadata, std::vector<AttachedImage>()); | 
| +    return; | 
| +  } | 
| + | 
| +  SetIntScopedPtr(extractor->height(), &metadata.height); | 
| +  SetIntScopedPtr(extractor->width(), &metadata.width); | 
| + | 
| +  SetIntScopedPtr(extractor->rotation(), &metadata.rotation); | 
| + | 
| +  SetDoubleScopedPtr(extractor->x_resolution(), &metadata.x_resolution); | 
| +  SetDoubleScopedPtr(extractor->y_resolution(), &metadata.y_resolution); | 
| +  SetBoolScopedPtr(extractor->flash_fired(), &metadata.flash_fired); | 
| +  SetStringScopedPtr(extractor->camera_make(), &metadata.camera_make); | 
| +  SetStringScopedPtr(extractor->camera_model(), &metadata.camera_model); | 
| +  SetDoubleScopedPtr(extractor->exposure_time_sec(), | 
| +                     &metadata.exposure_time_seconds); | 
| + | 
| +  SetDoubleScopedPtr(extractor->f_number(), &metadata.f_number); | 
| +  SetDoubleScopedPtr(extractor->focal_length_mm(), &metadata.focal_length_mm); | 
| +  SetDoubleScopedPtr(extractor->iso_equivalent(), &metadata.iso_equivalent); | 
| + | 
| +  callback.Run(metadata, std::vector<AttachedImage>()); | 
| +} | 
| + | 
| }  // namespace | 
|  | 
| MediaMetadataParser::MediaMetadataParser(media::DataSource* source, | 
| @@ -142,6 +186,15 @@ void MediaMetadataParser::Start(const MetadataCallback& callback) { | 
| return; | 
| } | 
|  | 
| +  if (base::StartsWith(mime_type_, "image/", base::CompareCase::SENSITIVE)) { | 
| +    ImageMetadataExtractor* extractor = new ImageMetadataExtractor; | 
| +    extractor->Extract( | 
| +        source_, | 
| +        base::Bind(&FinishParseImageMetadata, base::Owned(extractor), | 
| +                   mime_type_, callback)); | 
| +    return; | 
| +  } | 
| + | 
| callback.Run(MediaMetadata(), std::vector<AttachedImage>()); | 
| } | 
|  | 
|  |