diff options
author | noyau@chromium.org <noyau@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-15 21:02:22 +0000 |
---|---|---|
committer | noyau@chromium.org <noyau@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-15 21:02:22 +0000 |
commit | 5ff37a94fb9991db202d5a87782c5ebfd581df8b (patch) | |
tree | 9ce2e72a9a41cd331d7f2af7915be7b3f3c54e53 /skia | |
parent | d4ab94717965952e4ed26def870c4365a294a16c (diff) | |
download | chromium_src-5ff37a94fb9991db202d5a87782c5ebfd581df8b.zip chromium_src-5ff37a94fb9991db202d5a87782c5ebfd581df8b.tar.gz chromium_src-5ff37a94fb9991db202d5a87782c5ebfd581df8b.tar.bz2 |
Adding iOS native support to load multi-resolution images
BUG=None
Review URL: https://chromiumcodereview.appspot.com/11366217
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168030 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r-- | skia/ext/skia_utils_ios.h | 7 | ||||
-rw-r--r-- | skia/ext/skia_utils_ios.mm | 27 | ||||
-rw-r--r-- | skia/ext/skia_utils_ios_unittest.mm | 157 | ||||
-rw-r--r-- | skia/skia.gyp | 5 |
4 files changed, 196 insertions, 0 deletions
diff --git a/skia/ext/skia_utils_ios.h b/skia/ext/skia_utils_ios.h index f213cf0..6a854ce 100644 --- a/skia/ext/skia_utils_ios.h +++ b/skia/ext/skia_utils_ios.h @@ -12,8 +12,10 @@ #ifdef __OBJC__ @class UIImage; +@class NSData; #else class UIImage; +class NSData; #endif namespace gfx { @@ -28,6 +30,11 @@ SK_API UIImage* SkBitmapToUIImageWithColorSpace(const SkBitmap& skia_bitmap, CGFloat scale, CGColorSpaceRef color_space); +// Decodes all image representations inside the data into a vector of SkBitmaps. +// Returns a vector of all the successfully decoded representations or an empty +// vector if none can be decoded. +SK_API std::vector<SkBitmap> ImageDataToSkBitmaps(NSData* image_data); + } // namespace gfx #endif // SKIA_EXT_SKIA_UTILS_IOS_H_ diff --git a/skia/ext/skia_utils_ios.mm b/skia/ext/skia_utils_ios.mm index 1952fa0..72c69a0 100644 --- a/skia/ext/skia_utils_ios.mm +++ b/skia/ext/skia_utils_ios.mm @@ -4,6 +4,7 @@ #include "skia/ext/skia_utils_ios.h" +#import <ImageIO/ImageIO.h> #import <UIKit/UIKit.h> #include "base/logging.h" @@ -70,4 +71,30 @@ UIImage* SkBitmapToUIImageWithColorSpace(const SkBitmap& skia_bitmap, orientation:UIImageOrientationUp]; } +std::vector<SkBitmap> ImageDataToSkBitmaps(NSData* image_data) { + DCHECK(image_data); + base::mac::ScopedCFTypeRef<CFDictionaryRef> empty_dictionary( + CFDictionaryCreate(NULL, NULL, NULL, 0, NULL, NULL)); + std::vector<SkBitmap> frames; + + base::mac::ScopedCFTypeRef<CGImageSourceRef> source( + CGImageSourceCreateWithData((CFDataRef)image_data, empty_dictionary)); + + size_t count = CGImageSourceGetCount(source); + for (size_t index = 0; index < count; ++index) { + base::mac::ScopedCFTypeRef<CGImageRef> cg_image( + CGImageSourceCreateImageAtIndex(source, index, empty_dictionary)); + + CGSize size = CGSizeMake(CGImageGetWidth(cg_image), + CGImageGetHeight(cg_image)); + const SkBitmap bitmap = CGImageToSkBitmap(cg_image, size, false); + if (!bitmap.empty()) + frames.push_back(bitmap); + } + + DLOG_IF(WARNING, frames.size() != count) << "Only decoded " << frames.size() + << " frames for " << count << " expected."; + return frames; +} + } // namespace gfx diff --git a/skia/ext/skia_utils_ios_unittest.mm b/skia/ext/skia_utils_ios_unittest.mm new file mode 100644 index 0000000..c26e688 --- /dev/null +++ b/skia/ext/skia_utils_ios_unittest.mm @@ -0,0 +1,157 @@ +// Copyright (c) 2012 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. + +#import <UIKit/UIKit.h> + +#include "base/base64.h" +#include "skia/ext/skia_utils_ios.mm" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +typedef testing::Test SkiaUtilsIosTest; + +// This is a base64 encoded version of google.com ico file. generated by +// curl http://www.google.com/favicon.ico | base64 -b 76 +const char kIcoEncodedData[] = + "AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA" + "AAAEAAASCwAAEgsAAAAAAAAAAAAA9IVCSvSFQuf0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hULk9IVCSvSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQuf0hUL/9IVC//SFQv/0hUL/9Y1O//rI" + "q//+7+f//eXX//vUvf/7z7X/96Fu//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//vYwv/97OH/9ZRZ//SFQv/0hUL/9IhG//zbx//3om7/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/97uX/+buW//SFQv/0hUL/9IVC//SFQv/5upT/+9O6//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/+b6b//zezP/0iEf/9IVC//SFQv/1klf//ezh//vPtP/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/3qXr/+siq//m8lv/5wqD//vTu//3t4//1klb/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0h0b//vbx//zi0//1j1H/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/2nmn/+bmS/////v/4" + "sIX/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/5uJH///v5//eo" + "ef/1jU//+82y//afav/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vXw" + "//vOs//0hUL/9IVC//ekcf/96+D/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//728v/4sIX/9IVC//SFQv/4s4n///v4//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/6yKn/+byX//SFQv/0hkT//eTV//vWv//0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IZE//m6lP/5u5b//OHQ///+/f/6y6//96d3//SFQv/0hUL/9IVC" + "//SFQv/0hULm9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hULm9IVCSfSFQub0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hULm9IVCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAASCwAAEgsA" + "AAAAAAAAAAAA9IVCAPSFQif0hUKt9IVC8vSFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQvL0hUKt9IVCJ/SFQgD0hUIo9IVC7/SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hULv9IVCKPSFQq30hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVC8fSF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQvP0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9YtL//i2jv/8" + "28f//vLr///7+P///Pv//vTu//3n2v/6zbH/96Nw//SFQ//0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//ekcv/+8+z////////////+9fD/+9K5//m9mf/4to7/+buV//vSuf/++PT//OPT//aYYP/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/2l13///r3/////////fv/+b2Z//SIRv/0hUL/9IVC//SFQv/0hUL/9IVC//WN" + "T//84M///vXv//aZYf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//vPtP////////////i0i//0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//WQUv///Pr//OPU//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//eTV///////+9O7/9IVD//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//3m2P//////9ppi//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/718H/" + "//////3s4f/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL//vDn///////4" + "soj/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//erff////////38//WTWP/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//iziv////////////iwhf/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//rMsP///////eXW//WSVv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/4sYb///z7/////////Pv/9ZFV//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//ixhv/+8Of//vn1" + "//rMsP/4rH//9plh//WQUv/1j1L/+s2x//////////////////m9mf/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SGQ//2nmn/+buW//vNsv/82sb//e3j/////////////////////v/5wZ//9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/83Mj////////////++fb/" + "+K+C//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9ZRZ////" + "/////////vTt//aaYv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/1lFr////////////6xqf/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//ehbf/70bj//end//3o2////v3///////3l1//0iEb/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/5wqD////////////96t7/96Z2//WOUP/2nWf//NvH//zcyP/1" + "i0z/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/96l6/////////////vLr//WPUf/0hUL/9IVC" + "//SFQv/0h0b//end//3k1f/0iUn/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/8387////////////4" + "sYf/9IVC//SFQv/0hUL/9IVC//SFQv/6w6L///////nBn//0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "///69////////vj1//SIR//0hUL/9IVC//SFQv/0hUL/9IVC//m+mv///////e3j//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL///r3///////8387/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/+syw////" + "///++fb/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/95NX///////vUvP/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/97OH///////7y6//0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//i2jv///////N/O//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/96Nx////////////+s2x//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IdF//zh0P//+/j/9ZJW//SFQv/0hUL/9IVC//SKSv/96t7///////738v/1k1f/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9YxN//vUvf/96+D/96Z0//WNT//3om///ebY/////////Pv/+LKI" + "//WVW//0h0X/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//agbP/7zbL//enc//749P//" + "//////////////////////////3r4P/3p3f/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC8/SFQq30hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0" + "hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUKt9IVCJ/SFQu/0hUL/9IVC//SFQv/0hUL/9IVC" + "//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/" + "9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC7/SFQif0hUIA9IVCJfSFQq30" + "hULx9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SF" + "Qv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC//SFQv/0hUL/9IVC8fSFQq30hUIl9IVC" + "AIAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAACAAAAB"; + +NSData* IcoData() { + std::string output; + EXPECT_TRUE(base::Base64Decode(kIcoEncodedData, &output)); + return [NSData dataWithBytes:output.data() length:output.length()]; +} + +NSData* InvalidData(NSUInteger length) { + NSMutableData* data=[NSMutableData dataWithLength:length]; + memset([data mutableBytes], 0xFF, length); + return data; +} + +TEST_F(SkiaUtilsIosTest, ImageDataToSkBitmaps) { + std::vector<SkBitmap> bitmaps(gfx::ImageDataToSkBitmaps(IcoData())); + + EXPECT_EQ(2UL, bitmaps.size()); + EXPECT_EQ(32, bitmaps[0].width()); + EXPECT_EQ(32, bitmaps[0].height()); + EXPECT_EQ(16, bitmaps[1].width()); + EXPECT_EQ(16, bitmaps[1].height()); +} + +TEST_F(SkiaUtilsIosTest, InvalidDataFailure) { + std::vector<SkBitmap> bitmaps1(gfx::ImageDataToSkBitmaps(InvalidData(1))); + EXPECT_EQ(0UL, bitmaps1.size()); + std::vector<SkBitmap> bitmaps2(gfx::ImageDataToSkBitmaps(InvalidData(10))); + EXPECT_EQ(0UL, bitmaps2.size()); + std::vector<SkBitmap> bitmaps3(gfx::ImageDataToSkBitmaps(InvalidData(100))); + EXPECT_EQ(0UL, bitmaps3.size()); + std::vector<SkBitmap> bitmaps4(gfx::ImageDataToSkBitmaps(InvalidData(1000))); + EXPECT_EQ(0UL, bitmaps4.size()); + std::vector<SkBitmap> bitmaps5(gfx::ImageDataToSkBitmaps(InvalidData(5000))); + EXPECT_EQ(0UL, bitmaps5.size()); +} + +TEST_F(SkiaUtilsIosTest, EmptyDataFailure) { + std::vector<SkBitmap> bitmaps(gfx::ImageDataToSkBitmaps([NSData data])); + + EXPECT_EQ(0UL, bitmaps.size()); +} + +} // namespace + diff --git a/skia/skia.gyp b/skia/skia.gyp index e4c8063..96bac5b 100644 --- a/skia/skia.gyp +++ b/skia/skia.gyp @@ -445,6 +445,11 @@ '../third_party/skia/include/utils/ios', '../third_party/skia/include/utils/mac', ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/ImageIO.framework', + ], + }, 'dependencies': [ 'skia_opts_ios', ], |