Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: ui/gfx/icon_util.cc

Issue 14137032: Create profile .ico file on profile creation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: use important_file_handler for icon file creation Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« ui/gfx/icon_util.h ('K') | « ui/gfx/icon_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/files/important_file_writer.h"
8 #include "base/logging.h" 9 #include "base/logging.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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 if (!ConvertImageFamilyToBitmaps(resized_image_family, &bitmaps, &png_bytes)) 467 if (!ConvertImageFamilyToBitmaps(resized_image_family, &bitmaps, &png_bytes))
464 return false; 468 return false;
465 469
466 // Guaranteed true because BuildResizedImageFamily will provide at least one 470 // Guaranteed true because BuildResizedImageFamily will provide at least one
467 // image < 256x256. 471 // image < 256x256.
468 DCHECK(!bitmaps.empty()); 472 DCHECK(!bitmaps.empty());
469 size_t bitmap_count = bitmaps.size(); // Not including PNG image. 473 size_t bitmap_count = bitmaps.size(); // Not including PNG image.
470 // Including PNG image, if any. 474 // Including PNG image, if any.
471 size_t image_count = bitmap_count + (png_bytes.get() ? 1 : 0); 475 size_t image_count = bitmap_count + (png_bytes.get() ? 1 : 0);
472 476
473 // Now that basic checks are done, we can create the file.
474 base::win::ScopedHandle icon_file(::CreateFile(icon_path.value().c_str(),
475 GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL));
476
477 if (!icon_file.IsValid())
478 return false;
479
480 // Computing the total size of the buffer we need in order to store the 477 // Computing the total size of the buffer we need in order to store the
481 // images in the desired icon format. 478 // images in the desired icon format.
482 size_t buffer_size = ComputeIconFileBufferSize(bitmaps); 479 size_t buffer_size = ComputeIconFileBufferSize(bitmaps);
483 // Account for the bytes needed for the PNG entry. 480 // Account for the bytes needed for the PNG entry.
484 if (png_bytes.get()) 481 if (png_bytes.get())
485 buffer_size += sizeof(ICONDIRENTRY) + png_bytes->size(); 482 buffer_size += sizeof(ICONDIRENTRY) + png_bytes->size();
486 483
487 // Setting the information in the structures residing within the buffer. 484 // Setting the information in the structures residing within the buffer.
488 // First, we set the information which doesn't require iterating through the 485 // First, we set the information which doesn't require iterating through the
489 // bitmap set and then we set the bitmap specific structures. In the latter 486 // bitmap set and then we set the bitmap specific structures. In the latter
(...skipping 24 matching lines...) Expand all
514 entry->wPlanes = 1; 511 entry->wPlanes = 1;
515 entry->wBitCount = 32; 512 entry->wBitCount = 32;
516 entry->dwBytesInRes = static_cast<DWORD>(png_bytes->size()); 513 entry->dwBytesInRes = static_cast<DWORD>(png_bytes->size());
517 entry->dwImageOffset = static_cast<DWORD>(offset); 514 entry->dwImageOffset = static_cast<DWORD>(offset);
518 memcpy(&buffer[offset], png_bytes->front(), png_bytes->size()); 515 memcpy(&buffer[offset], png_bytes->front(), png_bytes->size());
519 offset += png_bytes->size(); 516 offset += png_bytes->size();
520 } 517 }
521 518
522 DCHECK_EQ(offset, buffer_size); 519 DCHECK_EQ(offset, buffer_size);
523 520
524 // Finally, write the data to the file. 521 std::string data(buffer.begin(), buffer.end());
525 DWORD bytes_written; 522 return base::ImportantFileWriter::WriteFileAtomically(icon_path, data);
526 bool delete_file = false;
527 if (!WriteFile(icon_file.Get(), &buffer[0], buffer_size, &bytes_written,
528 NULL) ||
529 bytes_written != buffer_size) {
530 delete_file = true;
531 }
532
533 ::CloseHandle(icon_file.Take());
534 if (delete_file) {
535 bool success = file_util::Delete(icon_path, false);
536 DCHECK(success);
537 }
538
539 return !delete_file;
540 } 523 }
541 524
542 bool IconUtil::PixelsHaveAlpha(const uint32* pixels, size_t num_pixels) { 525 bool IconUtil::PixelsHaveAlpha(const uint32* pixels, size_t num_pixels) {
543 for (const uint32* end = pixels + num_pixels; pixels != end; ++pixels) { 526 for (const uint32* end = pixels + num_pixels; pixels != end; ++pixels) {
544 if ((*pixels & 0xff000000) != 0) 527 if ((*pixels & 0xff000000) != 0)
545 return true; 528 return true;
546 } 529 }
547 530
548 return false; 531 return false;
549 } 532 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 // Once we compute the size for a singe AND mask scan line, we multiply that 683 // 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 684 // 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 685 // 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. 686 // for the monochrome bitmap representing the AND mask.
704 size_t and_line_length = (bitmap.width() + 7) >> 3; 687 size_t and_line_length = (bitmap.width() + 7) >> 3;
705 and_line_length = (and_line_length + 3) & ~3; 688 and_line_length = (and_line_length + 3) & ~3;
706 size_t and_mask_size = and_line_length * bitmap.height(); 689 size_t and_mask_size = and_line_length * bitmap.height();
707 size_t masks_size = *xor_mask_size + and_mask_size; 690 size_t masks_size = *xor_mask_size + and_mask_size;
708 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER); 691 *bytes_in_resource = masks_size + sizeof(BITMAPINFOHEADER);
709 } 692 }
693
694 void IconUtil::GetImageCheckSum(const gfx::ImageFamily& image,
695 base::MD5Digest* digest) {
696 DCHECK(digest);
697 base::MD5Context md5_context;
698 base::MD5Init(&md5_context);
699
700 for (gfx::ImageFamily::const_iterator it = image.begin(); it != image.end();
701 ++it) {
702 SkBitmap bitmap = it->AsBitmap();
703
704 SkAutoLockPixels image_lock(bitmap);
705 base::StringPiece image_data(
706 reinterpret_cast<const char*>(bitmap.getPixels()), bitmap.getSize());
707 base::MD5Update(&md5_context, image_data);
708 }
709
710 base::MD5Final(digest, &md5_context);
711 }
712
713 bool IconUtil::SaveIconWithCheckSum(const base::FilePath& icon_file,
714 const gfx::ImageFamily& image) {
715 if (!CreateIconFileFromImageFamily(image, icon_file))
716 return false;
717
718 base::MD5Digest digest;
719 GetImageCheckSum(image, &digest);
720
721 base::FilePath cheksum_file(icon_file.ReplaceExtension(kIconChecksumFileExt));
722 return file_util::WriteFile(cheksum_file,
723 reinterpret_cast<const char*>(&digest),
724 sizeof(digest)) == sizeof(digest);
725 }
726
727 bool IconUtil::ShouldUpdateIcon(const base::FilePath& icon_file,
728 const gfx::ImageFamily& image) {
729 base::FilePath checksum_file(
730 icon_file.ReplaceExtension(kIconChecksumFileExt));
731
732 // Returns true if icon_file or checksum file is missing.
733 if (!file_util::PathExists(icon_file) ||
734 !file_util::PathExists(checksum_file))
735 return true;
736
737 base::MD5Digest persisted_image_checksum;
738 if (sizeof(persisted_image_checksum) != file_util::ReadFile(checksum_file,
739 reinterpret_cast<char*>(&persisted_image_checksum),
740 sizeof(persisted_image_checksum)))
741 return true;
742
743 base::MD5Digest downloaded_image_checksum;
744 GetImageCheckSum(image, &downloaded_image_checksum);
745
746 // Update icon if checksums are not equal.
747 return memcmp(&persisted_image_checksum, &downloaded_image_checksum,
748 sizeof(base::MD5Digest)) != 0;
749 }
OLDNEW
« ui/gfx/icon_util.h ('K') | « ui/gfx/icon_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698