1 // Copyright (c) 2011 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.
5 #include "printing/image.h"
9 #include "base/file_util.h"
11 #include "base/numerics/safe_conversions.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "printing/metafile.h"
14 #include "printing/metafile_impl.h"
15 #include "third_party/skia/include/core/SkColor.h"
16 #include "ui/gfx/codec/png_codec.h"
20 Image::Image(const base::FilePath
& path
)
24 base::ReadFileToString(path
, &data
);
26 if (path
.MatchesExtension(FILE_PATH_LITERAL(".png"))) {
27 success
= LoadPng(data
);
28 } else if (path
.MatchesExtension(FILE_PATH_LITERAL(".emf"))) {
29 success
= LoadMetafile(data
);
40 Image::Image(const Metafile
& metafile
)
43 LoadMetafile(metafile
);
46 Image::Image(const Image
& image
)
48 row_length_(image
.row_length_
),
50 ignore_alpha_(image
.ignore_alpha_
) {
55 std::string
Image::checksum() const {
56 base::MD5Digest digest
;
57 base::MD5Sum(&data_
[0], data_
.size(), &digest
);
58 return base::HexEncode(&digest
, sizeof(digest
));
61 bool Image::SaveToPng(const base::FilePath
& filepath
) const {
62 DCHECK(!data_
.empty());
63 std::vector
<unsigned char> compressed
;
64 bool success
= gfx::PNGCodec::Encode(&*data_
.begin(),
65 gfx::PNGCodec::FORMAT_BGRA
,
69 std::vector
<gfx::PNGCodec::Comment
>(),
71 DCHECK(success
&& compressed
.size());
73 int write_bytes
= base::WriteFile(
75 reinterpret_cast<char*>(&*compressed
.begin()),
76 base::checked_cast
<int>(compressed
.size()));
77 success
= (write_bytes
== static_cast<int>(compressed
.size()));
83 double Image::PercentageDifferent(const Image
& rhs
) const {
84 if (size_
.width() == 0 || size_
.height() == 0 ||
85 rhs
.size_
.width() == 0 || rhs
.size_
.height() == 0)
88 int width
= std::min(size_
.width(), rhs
.size_
.width());
89 int height
= std::min(size_
.height(), rhs
.size_
.height());
90 // Compute pixels different in the overlap
91 int pixels_different
= 0;
92 for (int y
= 0; y
< height
; ++y
) {
93 for (int x
= 0; x
< width
; ++x
) {
94 uint32 lhs_pixel
= pixel_at(x
, y
);
95 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
96 if (lhs_pixel
!= rhs_pixel
)
100 // Look for extra right lhs pixels. They should be white.
101 for (int x
= width
; x
< size_
.width(); ++x
) {
102 uint32 lhs_pixel
= pixel_at(x
, y
);
103 if (lhs_pixel
!= Color(SK_ColorWHITE
))
107 // Look for extra right rhs pixels. They should be white.
108 for (int x
= width
; x
< rhs
.size_
.width(); ++x
) {
109 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
110 if (rhs_pixel
!= Color(SK_ColorWHITE
))
115 // Look for extra bottom lhs pixels. They should be white.
116 for (int y
= height
; y
< size_
.height(); ++y
) {
117 for (int x
= 0; x
< size_
.width(); ++x
) {
118 uint32 lhs_pixel
= pixel_at(x
, y
);
119 if (lhs_pixel
!= Color(SK_ColorWHITE
))
124 // Look for extra bottom rhs pixels. They should be white.
125 for (int y
= height
; y
< rhs
.size_
.height(); ++y
) {
126 for (int x
= 0; x
< rhs
.size_
.width(); ++x
) {
127 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
128 if (rhs_pixel
!= Color(SK_ColorWHITE
))
133 // Like the WebKit ImageDiff tool, we define percentage different in terms
134 // of the size of the 'actual' bitmap.
135 double total_pixels
= static_cast<double>(size_
.width()) *
136 static_cast<double>(height
);
137 return static_cast<double>(pixels_different
) / total_pixels
* 100.;
140 bool Image::LoadPng(const std::string
& compressed
) {
143 bool success
= gfx::PNGCodec::Decode(
144 reinterpret_cast<const unsigned char*>(compressed
.c_str()),
145 compressed
.size(), gfx::PNGCodec::FORMAT_BGRA
, &data_
, &w
, &h
);
147 row_length_
= size_
.width() * sizeof(uint32
);
151 bool Image::LoadMetafile(const std::string
& data
) {
152 DCHECK(!data
.empty());
153 NativeMetafile metafile
;
154 if (!metafile
.InitFromData(data
.data(),
155 base::checked_cast
<uint32
>(data
.size())))
157 return LoadMetafile(metafile
);
160 } // namespace printing