icon_loader_linux.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/icon_loader.h" 6 7#include <gdk-pixbuf/gdk-pixbuf.h> 8#include <gio/gio.h> 9#include <gtk/gtk.h> 10 11#include "base/file_util.h" 12#include "base/logging.h" 13#include "app/gtk_util.h" 14#include "base/message_loop.h" 15#include "base/mime_util.h" 16#include "base/thread.h" 17#include "base/string_util.h" 18#include "gfx/codec/png_codec.h" 19#include "third_party/skia/include/core/SkBitmap.h" 20 21static int SizeToInt(IconLoader::IconSize size) { 22 int pixels = 48; 23 if (size == IconLoader::NORMAL) 24 pixels = 32; 25 else if (size == IconLoader::SMALL) 26 pixels = 16; 27 28 return pixels; 29} 30 31void IconLoader::ReadIcon() { 32 filename_ = mime_util::GetMimeIcon(group_, SizeToInt(icon_size_)); 33 file_util::ReadFileToString(filename_, &icon_data_); 34 target_message_loop_->PostTask(FROM_HERE, 35 NewRunnableMethod(this, &IconLoader::ParseIcon)); 36} 37 38void IconLoader::ParseIcon() { 39 int size = SizeToInt(icon_size_); 40 41 // It would be more convenient to use gdk_pixbuf_new_from_stream_at_scale 42 // but that is only available after 2.14. 43 GdkPixbufLoader* loader = gdk_pixbuf_loader_new(); 44 gdk_pixbuf_loader_set_size(loader, size, size); 45 gdk_pixbuf_loader_write(loader, 46 reinterpret_cast<const guchar*>(icon_data_.data()), 47 icon_data_.length(), NULL); 48 gdk_pixbuf_loader_close(loader, NULL); 49 // We don't own a reference, we rely on the loader's ref. 50 GdkPixbuf* pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); 51 52 if (pixbuf) { 53 guchar* pixels = gdk_pixbuf_get_pixels(pixbuf); 54 int width = gdk_pixbuf_get_width(pixbuf); 55 int height = gdk_pixbuf_get_height(pixbuf); 56 DCHECK_EQ(width, size); 57 DCHECK_EQ(height, size); 58 int stride = gdk_pixbuf_get_rowstride(pixbuf); 59 60 if (!gdk_pixbuf_get_has_alpha(pixbuf)) { 61 LOG(WARNING) << "Got an image with no alpha channel, aborting load."; 62 } else { 63 uint8_t* BGRA_pixels = 64 gtk_util::BGRAToRGBA(pixels, width, height, stride); 65 std::vector<unsigned char> pixel_vector; 66 pixel_vector.resize(height * stride); 67 memcpy(const_cast<unsigned char*>(pixel_vector.data()), BGRA_pixels, 68 height * stride); 69 bitmap_ = gfx::PNGCodec::CreateSkBitmapFromBGRAFormat(pixel_vector, 70 width, height); 71 free(BGRA_pixels); 72 } 73 } else { 74 LOG(WARNING) << "Unsupported file type or load error: " << 75 filename_.value(); 76 } 77 78 g_object_unref(loader); 79 80 NotifyDelegate(); 81} 82