diff options
author | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 17:36:17 +0000 |
---|---|---|
committer | erg@google.com <erg@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-22 17:36:17 +0000 |
commit | 52d70a7c296f2eeef7343ed94375a7abad4a65dc (patch) | |
tree | 83f282358ee747ae897c440d781ade9d6a0730bc | |
parent | 52bf465e9d660330d267d5b29c36fe3e9ce1d905 (diff) | |
download | chromium_src-52d70a7c296f2eeef7343ed94375a7abad4a65dc.zip chromium_src-52d70a7c296f2eeef7343ed94375a7abad4a65dc.tar.gz chromium_src-52d70a7c296f2eeef7343ed94375a7abad4a65dc.tar.bz2 |
Make PNGCodec::Decode(...) not make an intermediary copy of the decoded data;
instead have it write directly to the returned SkBitmap.
BUG=http://crbug.com/24493
TEST=Perf should get better. On the perf trybot, tab_complex_theme_cold got an average of ~40ms better.
Review URL: http://codereview.chromium.org/305001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29780 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/gfx/codec/png_codec.cc | 197 | ||||
-rw-r--r-- | app/gfx/codec/png_codec.h | 16 | ||||
-rw-r--r-- | app/gfx/codec/png_codec_unittest.cc | 3 | ||||
-rw-r--r-- | app/resource_bundle.cc | 17 | ||||
-rw-r--r-- | chrome/browser/bookmarks/bookmark_model.cc | 2 | ||||
-rw-r--r-- | chrome/browser/browser_theme_provider.cc | 13 | ||||
-rw-r--r-- | chrome/browser/fav_icon_helper.cc | 9 | ||||
-rw-r--r-- | chrome/browser/gtk/list_store_favicon_loader.cc | 12 | ||||
-rw-r--r-- | chrome/browser/jumplist.cc | 8 | ||||
-rw-r--r-- | chrome/browser/possible_url_model.cc | 3 | ||||
-rw-r--r-- | chrome/browser/search_engines/template_url_table_model.cc | 4 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database.cc | 7 | ||||
-rw-r--r-- | chrome/browser/webdata/web_database_unittest.cc | 2 |
13 files changed, 185 insertions, 108 deletions
diff --git a/app/gfx/codec/png_codec.cc b/app/gfx/codec/png_codec.cc index 41057a0..b0799c6 100644 --- a/app/gfx/codec/png_codec.cc +++ b/app/gfx/codec/png_codec.cc @@ -8,6 +8,7 @@ #include "base/scoped_ptr.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkUnPreMultiply.h" +#include "third_party/skia/include/core/SkColorPriv.h" extern "C" { #if defined(USE_SYSTEM_LIBPNG) @@ -23,7 +24,7 @@ namespace { // Converts BGRA->RGBA and RGBA->BGRA. void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, - unsigned char* output) { + unsigned char* output, bool* is_opaque) { for (int x = 0; x < pixel_width; x++) { const unsigned char* pixel_in = &input[x * 4]; unsigned char* pixel_out = &output[x * 4]; @@ -35,7 +36,7 @@ void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width, } void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, - unsigned char* rgb) { + unsigned char* rgb, bool* is_opaque) { for (int x = 0; x < pixel_width; x++) { const unsigned char* pixel_in = &rgba[x * 4]; unsigned char* pixel_out = &rgb[x * 3]; @@ -45,6 +46,34 @@ void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width, } } +void ConvertRGBtoSkia(const unsigned char* rgb, int pixel_width, + unsigned char* rgba, bool* is_opaque) { + for (int x = 0; x < pixel_width; x++) { + const unsigned char* pixel_in = &rgb[x * 3]; + uint32_t* pixel_out = reinterpret_cast<uint32_t*>(&rgba[x * 4]); + *pixel_out = SkPackARGB32(0xFF, pixel_in[0], pixel_in[1], pixel_in[2]); + } +} + +void ConvertRGBAtoSkia(const unsigned char* rgb, int pixel_width, + unsigned char* rgba, bool* is_opaque) { + int total_length = pixel_width * 4; + for (int x = 0; x < total_length; x += 4) { + const unsigned char* pixel_in = &rgb[x]; + uint32_t* pixel_out = reinterpret_cast<uint32_t*>(&rgba[x]); + + unsigned char alpha = pixel_in[3]; + if (alpha != 255) { + *is_opaque = false; + *pixel_out = SkPreMultiplyARGB(alpha, + pixel_in[0], pixel_in[1], pixel_in[2]); + } else { + *pixel_out = SkPackARGB32(alpha, + pixel_in[0], pixel_in[1], pixel_in[2]); + } + } +} + } // namespace // Decoder -------------------------------------------------------------------- @@ -61,9 +90,12 @@ const double kInverseGamma = 1.0 / kDefaultGamma; class PngDecoderState { public: + // Output is a vector<unsigned char>. PngDecoderState(PNGCodec::ColorFormat ofmt, std::vector<unsigned char>* o) : output_format(ofmt), output_channels(0), + bitmap(NULL), + is_opaque(true), output(o), row_converter(NULL), width(0), @@ -71,14 +103,37 @@ class PngDecoderState { done(false) { } + // Output is an SkBitmap. + explicit PngDecoderState(SkBitmap* skbitmap) + : output_format(PNGCodec::FORMAT_SkBitmap), + output_channels(0), + bitmap(skbitmap), + is_opaque(true), + output(NULL), + row_converter(NULL), + width(0), + height(0), + done(false) { + } + PNGCodec::ColorFormat output_format; int output_channels; + // An incoming SkBitmap to write to. If NULL, we write to output instead. + SkBitmap* bitmap; + + // Used during the reading of an SkBitmap. Defaults to true until we see a + // pixel with anything other than an alpha of 255. + bool is_opaque; + + // The other way to decode output, where we write into an intermediary buffer + // instead of directly to an SkBitmap. std::vector<unsigned char>* output; // Called to convert a row from the library to the correct output format. // When NULL, no conversion is necessary. - void (*row_converter)(const unsigned char* in, int w, unsigned char* out); + void (*row_converter)(const unsigned char* in, int w, unsigned char* out, + bool* is_opaque); // Size of the image, set in the info callback. int width; @@ -92,7 +147,7 @@ class PngDecoderState { }; void ConvertRGBtoRGBA(const unsigned char* rgb, int pixel_width, - unsigned char* rgba) { + unsigned char* rgba, bool* is_opaque) { for (int x = 0; x < pixel_width; x++) { const unsigned char* pixel_in = &rgb[x * 3]; unsigned char* pixel_out = &rgba[x * 4]; @@ -104,7 +159,7 @@ void ConvertRGBtoRGBA(const unsigned char* rgb, int pixel_width, } void ConvertRGBtoBGRA(const unsigned char* rgb, int pixel_width, - unsigned char* bgra) { + unsigned char* bgra, bool* is_opaque) { for (int x = 0; x < pixel_width; x++) { const unsigned char* pixel_in = &rgb[x * 3]; unsigned char* pixel_out = &bgra[x * 4]; @@ -192,6 +247,10 @@ void DecodeInfoCallback(png_struct* png_ptr, png_info* info_ptr) { state->row_converter = &ConvertRGBtoBGRA; state->output_channels = 4; break; + case PNGCodec::FORMAT_SkBitmap: + state->row_converter = &ConvertRGBtoSkia; + state->output_channels = 4; + break; default: NOTREACHED() << "Unknown output format"; break; @@ -210,6 +269,10 @@ void DecodeInfoCallback(png_struct* png_ptr, png_info* info_ptr) { state->row_converter = &ConvertBetweenBGRAandRGBA; state->output_channels = 4; break; + case PNGCodec::FORMAT_SkBitmap: + state->row_converter = &ConvertRGBAtoSkia; + state->output_channels = 4; + break; default: NOTREACHED() << "Unknown output format"; break; @@ -219,7 +282,14 @@ void DecodeInfoCallback(png_struct* png_ptr, png_info* info_ptr) { longjmp(png_ptr->jmpbuf, 1); } - state->output->resize(state->width * state->output_channels * state->height); + if (state->bitmap) { + state->bitmap->setConfig(SkBitmap::kARGB_8888_Config, + state->width, state->height); + state->bitmap->allocPixels(); + } else if (state->output) { + state->output->resize( + state->width * state->output_channels * state->height); + } } void DecodeRowCallback(png_struct* png_ptr, png_byte* new_row, @@ -234,10 +304,15 @@ void DecodeRowCallback(png_struct* png_ptr, png_byte* new_row, return; } - unsigned char* dest = &(*state->output)[ - state->width * state->output_channels * row_num]; + unsigned char* base = NULL; + if (state->bitmap) + base = reinterpret_cast<unsigned char*>(state->bitmap->getAddr32(0, 0)); + else if (state->output) + base = &state->output->front(); + + unsigned char* dest = &base[state->width * state->output_channels * row_num]; if (state->row_converter) - state->row_converter(new_row, state->width, dest); + state->row_converter(new_row, state->width, dest, &state->is_opaque); else memcpy(dest, new_row, state->width * state->output_channels); } @@ -265,12 +340,8 @@ class PngReadStructDestroyer { png_info** pi_; }; -} // namespace - -// static -bool PNGCodec::Decode(const unsigned char* input, size_t input_size, - ColorFormat format, std::vector<unsigned char>* output, - int* w, int* h) { +bool BuildPNGStruct(const unsigned char* input, size_t input_size, + png_struct** png_ptr, png_info** info_ptr) { if (input_size < 8) return false; // Input data too small to be a png @@ -278,19 +349,33 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size, if (png_sig_cmp(const_cast<unsigned char*>(input), 0, 8) != 0) return false; - png_struct* png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, - png_voidp_NULL, - png_error_ptr_NULL, - png_error_ptr_NULL); - if (!png_ptr) + *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + png_voidp_NULL, + png_error_ptr_NULL, + png_error_ptr_NULL); + if (!*png_ptr) return false; - png_info* info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, NULL, NULL); + *info_ptr = png_create_info_struct(*png_ptr); + if (!*info_ptr) { + png_destroy_read_struct(png_ptr, NULL, NULL); return false; } + return true; +} + +} // namespace + +// static +bool PNGCodec::Decode(const unsigned char* input, size_t input_size, + ColorFormat format, std::vector<unsigned char>* output, + int* w, int* h) { + png_struct* png_ptr = NULL; + png_info* info_ptr = NULL; + if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr)) + return false; + PngReadStructDestroyer destroyer(&png_ptr, &info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { // The destroyer will ensure that the structures are cleaned up in this @@ -321,38 +406,39 @@ bool PNGCodec::Decode(const unsigned char* input, size_t input_size, } // static -bool PNGCodec::Decode(const std::vector<unsigned char>* data, +bool PNGCodec::Decode(const unsigned char* input, size_t input_size, SkBitmap* bitmap) { DCHECK(bitmap); - if (!data || data->empty()) + png_struct* png_ptr = NULL; + png_info* info_ptr = NULL; + if (!BuildPNGStruct(input, input_size, &png_ptr, &info_ptr)) + return false; + + PngReadStructDestroyer destroyer(&png_ptr, &info_ptr); + if (setjmp(png_jmpbuf(png_ptr))) { + // The destroyer will ensure that the structures are cleaned up in this + // case, even though we may get here as a jump from random parts of the + // PNG library called below. return false; - int width, height; - std::vector<unsigned char> decoded_data; - if (PNGCodec::Decode(&data->front(), data->size(), PNGCodec::FORMAT_BGRA, - &decoded_data, &width, &height)) { - bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); - bitmap->allocPixels(); - unsigned char* bitmap_data = - reinterpret_cast<unsigned char*>(bitmap->getAddr32(0, 0)); - for (int i = width * height * 4 - 4; i >= 0; i -= 4) { - unsigned char alpha = decoded_data[i + 3]; - if (alpha != 0 && alpha != 255) { - SkColor premultiplied = SkPreMultiplyARGB(alpha, - decoded_data[i], decoded_data[i + 1], decoded_data[i + 2]); - bitmap_data[i + 3] = alpha; - bitmap_data[i] = SkColorGetR(premultiplied); - bitmap_data[i + 1] = SkColorGetG(premultiplied); - bitmap_data[i + 2] = SkColorGetB(premultiplied); - } else { - bitmap_data[i + 3] = alpha; - bitmap_data[i] = decoded_data[i]; - bitmap_data[i + 1] = decoded_data[i + 1]; - bitmap_data[i + 2] = decoded_data[i + 2]; - } - } - return true; } - return false; + + PngDecoderState state(bitmap); + + png_set_progressive_read_fn(png_ptr, &state, &DecodeInfoCallback, + &DecodeRowCallback, &DecodeEndCallback); + png_process_data(png_ptr, + info_ptr, + const_cast<unsigned char*>(input), + input_size); + + if (!state.done) { + return false; + } + + // Set the bitmap's opaqueness based on what we saw. + bitmap->setIsOpaque(state.is_opaque); + + return true; } // static @@ -390,7 +476,7 @@ namespace { // Passed around as the io_ptr in the png structs so our callbacks know where // to write data. struct PngEncoderState { - PngEncoderState(std::vector<unsigned char>* o) : out(o) {} + explicit PngEncoderState(std::vector<unsigned char>* o) : out(o) {} std::vector<unsigned char>* out; }; @@ -405,7 +491,7 @@ void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) { } void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width, - unsigned char* rgb) { + unsigned char* rgb, bool* is_opaque) { for (int x = 0; x < pixel_width; x++) { const unsigned char* pixel_in = &bgra[x * 4]; unsigned char* pixel_out = &rgb[x * 3]; @@ -440,7 +526,8 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, std::vector<unsigned char>* output) { // Run to convert an input row into the output row format, NULL means no // conversion is necessary. - void (*converter)(const unsigned char* in, int w, unsigned char* out) = NULL; + void (*converter)(const unsigned char* in, int w, unsigned char* out, + bool* is_opaque) = NULL; int input_color_components, output_color_components; int png_output_color_type; @@ -524,7 +611,7 @@ bool PNGCodec::Encode(const unsigned char* input, ColorFormat format, // Needs conversion using a separate buffer. unsigned char* row = new unsigned char[w * output_color_components]; for (int y = 0; y < h; y ++) { - converter(&input[y * row_byte_width], w, row); + converter(&input[y * row_byte_width], w, row, NULL); png_write_row(png_ptr, row); } delete[] row; diff --git a/app/gfx/codec/png_codec.h b/app/gfx/codec/png_codec.h index 1e07632..6460701 100644 --- a/app/gfx/codec/png_codec.h +++ b/app/gfx/codec/png_codec.h @@ -31,7 +31,11 @@ class PNGCodec { // 4 bytes per pixel, in BGRA order in memory regardless of endianness. // This is the default Windows DIB order. - FORMAT_BGRA + FORMAT_BGRA, + + // 4 bytes per pixel, in pre-multiplied kARGB_8888_Config format. For use + // with directly writing to a skia bitmap. + FORMAT_SkBitmap }; // Encodes the given raw 'input' data, with each pixel being represented as @@ -75,12 +79,16 @@ class PNGCodec { ColorFormat format, std::vector<unsigned char>* output, int* w, int* h); - // A convenience function for decoding PNGs as previously encoded by the PNG - // encoder. Chrome encodes png in the format PNGCodec::FORMAT_BGRA. + // Decodes the PNG data directly into the passed in SkBitmap. This is + // significantly faster than the vector<unsigned char> version of Decode() + // above when dealing with PNG files that are >500K, which a lot of theme + // images are. (There are a lot of themes that have a NTP image of about ~1 + // megabyte, and those require a 7-10 megabyte side buffer.) // // Returns true if data is non-null and can be decoded as a png, false // otherwise. - static bool Decode(const std::vector<unsigned char>* data, SkBitmap* icon); + static bool Decode(const unsigned char* input, size_t input_size, + SkBitmap* bitmap); // Create a SkBitmap from a decoded BGRA DIB. The caller owns the returned // SkBitmap. diff --git a/app/gfx/codec/png_codec_unittest.cc b/app/gfx/codec/png_codec_unittest.cc index d16f519..37734f8 100644 --- a/app/gfx/codec/png_codec_unittest.cc +++ b/app/gfx/codec/png_codec_unittest.cc @@ -234,7 +234,8 @@ TEST(PNGCodec, EncodeBGRASkBitmap) { // Decode the encoded string. SkBitmap decoded_bitmap; - EXPECT_TRUE(PNGCodec::Decode(&encoded, &decoded_bitmap)); + EXPECT_TRUE(PNGCodec::Decode(&encoded.front(), encoded.size(), + &decoded_bitmap)); // Compare the original bitmap and the output bitmap. We use ColorsClose // as SkBitmaps are considered to be pre-multiplied, the unpremultiplication diff --git a/app/resource_bundle.cc b/app/resource_bundle.cc index 7261dfd..28674a8 100644 --- a/app/resource_bundle.cc +++ b/app/resource_bundle.cc @@ -69,27 +69,18 @@ void ResourceBundle::FreeImages() { /* static */ SkBitmap* ResourceBundle::LoadBitmap(DataHandle data_handle, int resource_id) { - std::vector<unsigned char> png_data; - scoped_refptr<RefCountedMemory> memory( LoadResourceBytes(data_handle, resource_id)); if (!memory) return NULL; - // Decode the PNG. - int image_width; - int image_height; - if (!gfx::PNGCodec::Decode( - memory->front(), memory->size(), - gfx::PNGCodec::FORMAT_BGRA, - &png_data, &image_width, &image_height)) { - NOTREACHED() << "Unable to decode image resource " << resource_id; + SkBitmap bitmap; + if (!gfx::PNGCodec::Decode(memory->front(), memory->size(), &bitmap)) { + NOTREACHED() << "Unable to decode theme image resource " << resource_id; return NULL; } - return gfx::PNGCodec::CreateSkBitmapFromBGRAFormat(png_data, - image_width, - image_height); + return new SkBitmap(bitmap); } std::string ResourceBundle::GetDataResource(int resource_id) { diff --git a/chrome/browser/bookmarks/bookmark_model.cc b/chrome/browser/bookmarks/bookmark_model.cc index a6cc083..60c1cd4 100644 --- a/chrome/browser/bookmarks/bookmark_model.cc +++ b/chrome/browser/bookmarks/bookmark_model.cc @@ -649,7 +649,7 @@ void BookmarkModel::OnFavIconDataAvailable( DCHECK(node); node->set_favicon_load_handle(0); if (know_favicon && data.get() && - gfx::PNGCodec::Decode(&data->data, &fav_icon)) { + gfx::PNGCodec::Decode(data->front(), data->size(), &fav_icon)) { node->set_favicon(fav_icon); FavIconLoaded(node); } diff --git a/chrome/browser/browser_theme_provider.cc b/chrome/browser/browser_theme_provider.cc index eb7aeb4..c127cab 100644 --- a/chrome/browser/browser_theme_provider.cc +++ b/chrome/browser/browser_theme_provider.cc @@ -840,22 +840,15 @@ SkBitmap* BrowserThemeProvider::LoadThemeBitmap(int id) const { raw_data = ReadThemeFileData(id); if (raw_data) { - std::vector<unsigned char> png_data; - // Decode the PNG. - int image_width = 0; - int image_height = 0; - + SkBitmap bitmap; if (!gfx::PNGCodec::Decode(raw_data->front(), raw_data->size(), - gfx::PNGCodec::FORMAT_BGRA, &png_data, - &image_width, &image_height)) { + &bitmap)) { NOTREACHED() << "Unable to decode theme image resource " << id; return NULL; } - return gfx::PNGCodec::CreateSkBitmapFromBGRAFormat(png_data, - image_width, - image_height); + return new SkBitmap(bitmap); } else { // TODO(glen): File no-longer exists, we're out of date. We should // clear the theme (or maybe just the pref that points to this diff --git a/chrome/browser/fav_icon_helper.cc b/chrome/browser/fav_icon_helper.cc index f0d7d64..3563406 100644 --- a/chrome/browser/fav_icon_helper.cc +++ b/chrome/browser/fav_icon_helper.cc @@ -87,7 +87,7 @@ void FavIconHelper::FavIconDownloadFailed(int download_id) { void FavIconHelper::UpdateFavIcon(NavigationEntry* entry, const std::vector<unsigned char>& data) { SkBitmap image; - gfx::PNGCodec::Decode(&data, &image); + gfx::PNGCodec::Decode(&data.front(), data.size(), &image); UpdateFavIcon(entry, image); } @@ -187,12 +187,13 @@ void FavIconHelper::OnFavIconDataForInitialURL( // favicon or its expired. Continue on to DownloadFavIconOrAskHistory to // either download or check history again. DownloadFavIconOrAskHistory(entry); - } // else we haven't got the icon url. When we get it we'll ask the - // renderer to download the icon. + } + // else we haven't got the icon url. When we get it we'll ask the + // renderer to download the icon. } void FavIconHelper::DownloadFavIconOrAskHistory(NavigationEntry* entry) { - DCHECK(entry); // We should only get here if entry is valid. + DCHECK(entry); // We should only get here if entry is valid. if (fav_icon_expired_) { // We have the mapping, but the favicon is out of date. Download it now. ScheduleDownload(entry); diff --git a/chrome/browser/gtk/list_store_favicon_loader.cc b/chrome/browser/gtk/list_store_favicon_loader.cc index f0a146b..a4995db 100644 --- a/chrome/browser/gtk/list_store_favicon_loader.cc +++ b/chrome/browser/gtk/list_store_favicon_loader.cc @@ -69,17 +69,9 @@ void ListStoreFavIconLoader::OnGotFavIcon( favicon_handle_col_, 0, -1); if (know_fav_icon && image_data.get() && !image_data->data.empty()) { - int width, height; - std::vector<unsigned char> decoded_data; + SkBitmap icon; if (gfx::PNGCodec::Decode(&image_data->data.front(), - image_data->data.size(), - gfx::PNGCodec::FORMAT_BGRA, &decoded_data, - &width, &height)) { - SkBitmap icon; - icon.setConfig(SkBitmap::kARGB_8888_Config, width, height); - icon.allocPixels(); - memcpy(icon.getPixels(), &decoded_data.front(), - width * height * 4); + image_data->data.size(), &icon)) { GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&icon); gtk_list_store_set(list_store_, &iter, favicon_col_, pixbuf, diff --git a/chrome/browser/jumplist.cc b/chrome/browser/jumplist.cc index 3dd2c55..1af060b 100644 --- a/chrome/browser/jumplist.cc +++ b/chrome/browser/jumplist.cc @@ -497,7 +497,9 @@ void JumpListUpdateTask::Run() { item != most_visited_pages_.end(); ++item) { SkBitmap icon_bitmap; if ((*item)->data().get() && - gfx::PNGCodec::Decode(&(*item)->data()->data, &icon_bitmap)) { + gfx::PNGCodec::Decode((*item)->data()->front(), + (*item)->data()->size(), + &icon_bitmap)) { std::wstring icon_path; if (CreateIconFile(icon_bitmap, icon_dir_, &icon_path)) (*item)->SetIcon(icon_path, 0, true); @@ -510,7 +512,9 @@ void JumpListUpdateTask::Run() { item != recently_closed_pages_.end(); ++item) { SkBitmap icon_bitmap; if ((*item)->data().get() && - gfx::PNGCodec::Decode(&(*item)->data()->data, &icon_bitmap)) { + gfx::PNGCodec::Decode((*item)->data()->front(), + (*item)->data()->size(), + &icon_bitmap)) { std::wstring icon_path; if (CreateIconFile(icon_bitmap, icon_dir_, &icon_path)) (*item)->SetIcon(icon_path, 0, true); diff --git a/chrome/browser/possible_url_model.cc b/chrome/browser/possible_url_model.cc index 5960ada..2f73ed9 100644 --- a/chrome/browser/possible_url_model.cc +++ b/chrome/browser/possible_url_model.cc @@ -176,7 +176,8 @@ void PossibleURLModel::OnFavIconAvailable( size_t index = consumer_.GetClientData(favicon_service, h); if (fav_icon_available) { // The decoder will leave our bitmap empty on error. - gfx::PNGCodec::Decode(&data->data, &(fav_icon_map_[index])); + gfx::PNGCodec::Decode(data->front(), data->size(), + &(fav_icon_map_[index])); // Notify the observer. if (!fav_icon_map_[index].isNull() && observer_) diff --git a/chrome/browser/search_engines/template_url_table_model.cc b/chrome/browser/search_engines/template_url_table_model.cc index 3b1aaca..4b9663f 100644 --- a/chrome/browser/search_engines/template_url_table_model.cc +++ b/chrome/browser/search_engines/template_url_table_model.cc @@ -100,7 +100,7 @@ class ModelEntry { GURL icon_url) { load_state_ = LOADED; if (know_favicon && data.get() && - gfx::PNGCodec::Decode(&data->data, &fav_icon_)) { + gfx::PNGCodec::Decode(data->front(), data->size(), &fav_icon_)) { model_->FavIconAvailable(this); } } @@ -313,7 +313,7 @@ int TemplateURLTableModel::IndexOfTemplateURL( int TemplateURLTableModel::MoveToMainGroup(int index) { if (index < last_search_engine_index_) - return index; // Already in the main group. + return index; // Already in the main group. ModelEntry* current_entry = entries_[index]; entries_.erase(index + entries_.begin()); diff --git a/chrome/browser/webdata/web_database.cc b/chrome/browser/webdata/web_database.cc index f611a93..e163f56 100644 --- a/chrome/browser/webdata/web_database.cc +++ b/chrome/browser/webdata/web_database.cc @@ -211,12 +211,11 @@ bool WebDatabase::GetWebAppImages(const GURL& url, s.BindString(0, history::HistoryDatabase::GURLToDatabaseURL(url)); while (s.Step()) { SkBitmap image; - std::vector<unsigned char> image_data; int col_bytes = s.ColumnByteLength(0); if (col_bytes > 0) { - image_data.resize(col_bytes); - memcpy(&image_data[0], s.ColumnBlob(0), col_bytes); - if (gfx::PNGCodec::Decode(&image_data, &image)) { + if (gfx::PNGCodec::Decode( + reinterpret_cast<const unsigned char*>(s.ColumnBlob(0)), + col_bytes, &image)) { images->push_back(image); } else { // Should only have valid image data in the db. diff --git a/chrome/browser/webdata/web_database_unittest.cc b/chrome/browser/webdata/web_database_unittest.cc index 32001e5..f6ac53b 100644 --- a/chrome/browser/webdata/web_database_unittest.cc +++ b/chrome/browser/webdata/web_database_unittest.cc @@ -665,7 +665,7 @@ TEST_F(WebDatabaseTest, WebAppImages) { // Set some random pixels so that we can identify the image. We don't use // transparent images because of pre-multiplication rounding errors. SkColor test_pixel_1 = 0xffccbbaa; - SkColor test_pixel_2 = 0x00aabbaa; + SkColor test_pixel_2 = 0xffaabbaa; SkColor test_pixel_3 = 0xff339966; image.getAddr32(0, 1)[0] = test_pixel_1; image.getAddr32(0, 1)[1] = test_pixel_2; |