Commit a27b85e6 authored by mathp's avatar mathp Committed by Commit bot

[Suggestions] Introduce a different image encoder/decoder for iOS

This introduces the new files and dependencies (not used yet). A further improvement will be to switch to use gfx::Image.

TBR=senorblanco
BUG=409156

Review URL: https://codereview.chromium.org/641513003

Cr-Commit-Position: refs/heads/master@{#299158}
parent 9750bbaa
......@@ -544,6 +544,7 @@
['include', '^search_provider_logos/'],
['include', '^signin/'],
['exclude', '^signin/core/browser/mutable_profile_oauth2_token_service_unittest\\.cc$'],
['include', '^suggestions/'],
['include', '^sync_driver/'],
['include', '^translate/'],
['include', '^url_fixer/'],
......
......@@ -43,6 +43,19 @@
'proto_out_dir': 'components/suggestions/proto',
},
'includes': [ '../build/protoc.gypi' ],
'conditions': [
['OS == "ios"', {
'sources': [
'suggestions/image_encoder_ios.h',
'suggestions/image_encoder_ios.mm',
]
}, { # 'OS != "ios"'
'sources': [
'suggestions/image_encoder.cc',
'suggestions/image_encoder.h',
]
}
]]
},
],
}
......@@ -30,4 +30,16 @@ static_library("suggestions") {
"//ui/gfx",
"//url",
]
if (is_ios) {
sources += [
"image_encoder_ios.h",
"image_encoder_ios.mm",
]
} else {
sources += [
"image_encoder.cc",
"image_encoder.h",
]
}
}
......@@ -4,6 +4,7 @@ include_rules = [
"+components/pref_registry",
"+components/variations",
"+net",
"+skia/ext",
"+ui",
"+url",
]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/suggestions/image_encoder.h"
#include "ui/gfx/codec/jpeg_codec.h"
#include "ui/gfx/image/image_skia.h"
namespace suggestions {
SkBitmap* DecodeJPEGToSkBitmap(const std::vector<unsigned char>& encoded_data) {
return gfx::JPEGCodec::Decode(&encoded_data[0], encoded_data.size());
}
bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
std::vector<unsigned char>* dest) {
SkAutoLockPixels bitmap_lock(bitmap);
if (!bitmap.readyToDraw() || bitmap.isNull()) {
return false;
}
return gfx::JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
gfx::JPEGCodec::FORMAT_SkBitmap, bitmap.width(), bitmap.height(),
bitmap.rowBytes(), 100, dest);
}
} // namespace suggestions
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_H_
#define COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_H_
#include <vector>
class SkBitmap;
namespace suggestions {
// From encoded bytes to SkBitmap. It's the caller's responsibility to delete
// the bitmap.
SkBitmap* DecodeJPEGToSkBitmap(const std::vector<unsigned char>& encoded_data);
// From SkBitmap to a vector of JPEG-encoded bytes, |dst|.
bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
std::vector<unsigned char>* dest);
} // namespace suggestions
#endif // COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_IOS_H_
#define COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_IOS_H_
#include <vector>
class SkBitmap;
namespace suggestions {
// From encoded bytes to SkBitmap. It's the caller's responsibility to delete
// the bitmap.
SkBitmap* DecodeJPEGToSkBitmap(const std::vector<unsigned char>& encoded_data);
// From SkBitmap to a vector of JPEG-encoded bytes, |dst|.
bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
std::vector<unsigned char>* dest);
} // namespace suggestions
#endif // COMPONENTS_SUGGESTIONS_IMAGE_ENCODER_IOS_H_
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/suggestions/image_encoder_ios.h"
#import <UIKit/UIKit.h>
#include "base/mac/scoped_cftyperef.h"
#include "skia/ext/skia_utils_ios.h"
namespace suggestions {
SkBitmap* DecodeJPEGToSkBitmap(const std::vector<unsigned char>& encoded_data) {
NSData* data =
[NSData dataWithBytes:encoded_data.data() length:encoded_data.size()];
UIImage* image =
[UIImage imageWithData:data scale:1.0];
return new SkBitmap(gfx::CGImageToSkBitmap(image.CGImage, [image size], YES));
}
bool EncodeSkBitmapToJPEG(const SkBitmap& bitmap,
std::vector<unsigned char>* dest) {
base::ScopedCFTypeRef<CGColorSpaceRef> color_space(
CGColorSpaceCreateDeviceRGB());
UIImage* image =
gfx::SkBitmapToUIImageWithColorSpace(bitmap, 1 /* scale */, color_space);
NSData* data = UIImageJPEGRepresentation(image, 1.0);
const char* bytes = reinterpret_cast<const char*>([data bytes]);
dest->assign(bytes, bytes + [data length]);
return true;
}
} // namespace suggestions
......@@ -6,18 +6,14 @@
#include "base/bind.h"
#include "components/suggestions/image_fetcher.h"
#include "ui/gfx/codec/jpeg_codec.h"
using leveldb_proto::ProtoDatabase;
namespace {
// From JPEG-encoded bytes to SkBitmap.
SkBitmap* DecodeImage(const std::vector<unsigned char>& encoded_data) {
return gfx::JPEGCodec::Decode(&encoded_data[0], encoded_data.size());
}
#if defined(OS_IOS)
#include "components/suggestions/image_encoder_ios.h"
#else
#include "components/suggestions/image_encoder.h"
#endif
} // namespace
using leveldb_proto::ProtoDatabase;
namespace suggestions {
......@@ -139,7 +135,7 @@ void ImageManager::SaveImage(const GURL& url, const SkBitmap& bitmap) {
// Attempt to save a JPEG representation to the database. If not successful,
// the fetched bitmap will still be inserted in the cache, above.
std::vector<unsigned char> encoded_data;
if (EncodeImage(bitmap, &encoded_data)) {
if (EncodeSkBitmapToJPEG(bitmap, &encoded_data)) {
// Save the resulting bitmap to the database.
ImageData data;
data.set_url(url.spec());
......@@ -194,7 +190,7 @@ void ImageManager::LoadEntriesInCache(scoped_ptr<ImageDataVector> entries) {
std::vector<unsigned char> encoded_data(it->data().begin(),
it->data().end());
scoped_ptr<SkBitmap> bitmap(DecodeImage(encoded_data));
scoped_ptr<SkBitmap> bitmap(DecodeJPEGToSkBitmap(encoded_data));
if (bitmap.get()) {
image_map_.insert(std::make_pair(it->url(), *bitmap));
}
......@@ -212,17 +208,4 @@ void ImageManager::ServePendingCacheRequests() {
}
}
// static
bool ImageManager::EncodeImage(const SkBitmap& bitmap,
std::vector<unsigned char>* dest) {
SkAutoLockPixels bitmap_lock(bitmap);
if (!bitmap.readyToDraw() || bitmap.isNull()) {
return false;
}
return gfx::JPEGCodec::Encode(
reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
gfx::JPEGCodec::FORMAT_SkBitmap, bitmap.width(), bitmap.height(),
bitmap.rowBytes(), 100, dest);
}
} // namespace suggestions
......@@ -119,11 +119,6 @@ class ImageManager : public ImageFetcherDelegate {
void ServePendingCacheRequests();
// From SkBitmap to the vector of JPEG-encoded bytes, |dst|. Visible only for
// testing.
static bool EncodeImage(const SkBitmap& bitmap,
std::vector<unsigned char>* dest);
// Map from URL to image URL. Should be kept up to date when a new
// SuggestionsProfile is available.
std::map<GURL, GURL> image_url_map_;
......
......@@ -17,6 +17,12 @@
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
#if defined(OS_IOS)
#include "components/suggestions/image_encoder_ios.h"
#else
#include "components/suggestions/image_encoder.h"
#endif
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;
......@@ -92,7 +98,7 @@ class ImageManagerTest : public testing::Test {
ImageData data;
data.set_url(url);
std::vector<unsigned char> encoded;
EXPECT_TRUE(ImageManager::EncodeImage(bm, &encoded));
EXPECT_TRUE(EncodeSkBitmapToJPEG(bm, &encoded));
data.set_data(std::string(encoded.begin(), encoded.end()));
return data;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment