Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "ui/gfx/icon_util.h" | 5 #include "ui/gfx/icon_util.h" | 
| 6 | 6 | 
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" | 
| 8 #include "base/logging.h" | 8 #include "base/logging.h" | 
| 9 #include "base/md5.h" | |
| 9 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" | 
| 10 #include "base/win/resource_util.h" | 11 #include "base/win/resource_util.h" | 
| 11 #include "base/win/scoped_gdi_object.h" | 12 #include "base/win/scoped_gdi_object.h" | 
| 12 #include "base/win/scoped_handle.h" | 13 #include "base/win/scoped_handle.h" | 
| 13 #include "base/win/scoped_hdc.h" | 14 #include "base/win/scoped_hdc.h" | 
| 14 #include "skia/ext/image_operations.h" | 15 #include "skia/ext/image_operations.h" | 
| 15 #include "third_party/skia/include/core/SkBitmap.h" | 16 #include "third_party/skia/include/core/SkBitmap.h" | 
| 16 #include "ui/gfx/gdi_util.h" | 17 #include "ui/gfx/gdi_util.h" | 
| 17 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" | 
| 18 #include "ui/gfx/image/image_family.h" | 19 #include "ui/gfx/image/image_family.h" | 
| 19 #include "ui/gfx/size.h" | 20 #include "ui/gfx/size.h" | 
| 20 | 21 | 
| 21 namespace { | 22 namespace { | 
| 22 | 23 | 
| 24 const base::FilePath::CharType kIconChecksumFileExt[] = | |
| 25 FILE_PATH_LITERAL(".ico.md5"); | |
| 26 | |
| 23 struct ScopedICONINFO : ICONINFO { | 27 struct ScopedICONINFO : ICONINFO { | 
| 24 ScopedICONINFO() { | 28 ScopedICONINFO() { | 
| 25 hbmColor = NULL; | 29 hbmColor = NULL; | 
| 26 hbmMask = NULL; | 30 hbmMask = NULL; | 
| 27 } | 31 } | 
| 28 | 32 | 
| 29 ~ScopedICONINFO() { | 33 ~ScopedICONINFO() { | 
| 30 if (hbmColor) | 34 if (hbmColor) | 
| 31 ::DeleteObject(hbmColor); | 35 ::DeleteObject(hbmColor); | 
| 32 if (hbmMask) | 36 if (hbmMask) | 
| (...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 700 // Once we compute the size for a singe AND mask scan line, we multiply that | 704 // Once we compute the size for a singe AND mask scan line, we multiply that | 
| 701 // number by the image height in order to get the total number of bytes for | 705 // number by the image height in order to get the total number of bytes for | 
| 702 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 706 // the AND mask. Thus, for a 15X15 image, we need 15 * 4 which is 60 bytes | 
| 703 // for the monochrome bitmap representing the AND mask. | 707 // for the monochrome bitmap representing the AND mask. | 
| 704 size_t and_line_length = (bitmap.width() + 7) >> 3; | 708 size_t and_line_length = (bitmap.width() + 7) >> 3; | 
| 705 and_line_length = (and_line_length + 3) & ~3; | 709 and_line_length = (and_line_length + 3) & ~3; | 
| 706 size_t and_mask_size = and_line_length * bitmap.height(); | 710 size_t and_mask_size = and_line_length * bitmap.height(); | 
| 707 size_t masks_size = *xor_mask_size + and_mask_size; | 711 size_t masks_size = *xor_mask_size + and_mask_size; | 
| 708 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 712 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); | 
| 709 } | 713 } | 
| 714 | |
| 715 void IconUtil::GetImageCheckSum(const gfx::ImageFamily& image, | |
| 716 base::MD5Digest* digest) { | |
| 717 DCHECK(digest); | |
| 718 base::MD5Context md5_context; | |
| 719 base::MD5Init(&md5_context); | |
| 720 | |
| 721 for (gfx::ImageFamily::const_iterator it = image.begin(); it != image.end(); | |
| 722 ++it) { | |
| 723 SkBitmap bitmap = it->AsBitmap(); | |
| 724 | |
| 725 SkAutoLockPixels image_lock(bitmap); | |
| 726 base::StringPiece image_data( | |
| 727 reinterpret_cast<const char*>(bitmap.getPixels()), bitmap.getSize()); | |
| 728 base::MD5Update(&md5_context, image_data); | |
| 729 } | |
| 730 | |
| 731 base::MD5Final(digest, &md5_context); | |
| 732 } | |
| 733 | |
| 734 bool IconUtil::SaveIconWithCheckSum(const base::FilePath& icon_file, | |
| 735 const gfx::ImageFamily& image) { | |
| 736 if (!CreateIconFileFromImageFamily(image, icon_file)) | |
| 737 return false; | |
| 738 | |
| 739 base::MD5Digest digest; | |
| 740 GetImageCheckSum(image, &digest); | |
| 741 | |
| 742 base::FilePath cheksum_file(icon_file.ReplaceExtension(kIconChecksumFileExt)); | |
| 
 
Alexei Svitkine (slow)
2013/05/09 15:34:57
Nit: cheksum -> checksum
 
 | |
| 743 return file_util::WriteFile(cheksum_file, | |
| 744 reinterpret_cast<const char*>(&digest), | |
| 745 sizeof(digest)) == sizeof(digest); | |
| 746 } | |
| 747 | |
| 748 bool IconUtil::ShouldUpdateIcon(const base::FilePath& icon_file, | |
| 749 const gfx::ImageFamily& image) { | |
| 
 
Alexei Svitkine (slow)
2013/05/09 15:34:57
Nit: Align.
 
 | |
| 750 base::FilePath checksum_file( | |
| 751 icon_file.ReplaceExtension(kIconChecksumFileExt)); | |
| 752 | |
| 753 // Returns true if icon_file or checksum file is missing. | |
| 754 if (!file_util::PathExists(icon_file) || | |
| 755 !file_util::PathExists(checksum_file)) | |
| 756 return true; | |
| 757 | |
| 758 base::MD5Digest persisted_image_checksum; | |
| 759 if (sizeof(persisted_image_checksum) != file_util::ReadFile(checksum_file, | |
| 760 reinterpret_cast<char*>(&persisted_image_checksum), | |
| 761 sizeof(persisted_image_checksum))) | |
| 762 return true; | |
| 763 | |
| 764 base::MD5Digest downloaded_image_checksum; | |
| 765 GetImageCheckSum(image, &downloaded_image_checksum); | |
| 766 | |
| 767 // Update icon if checksums are not equal. | |
| 768 return memcmp(&persisted_image_checksum, &downloaded_image_checksum, | |
| 769 sizeof(base::MD5Digest)) != 0; | |
| 770 } | |
| OLD | NEW |