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/string_number_conversions.h"
12 #include "printing/metafile.h"
13 #include "printing/metafile_impl.h"
14 #include "third_party/skia/include/core/SkColor.h"
15 #include "ui/gfx/codec/png_codec.h"
19 Image::Image(const FilePath
& path
)
23 file_util::ReadFileToString(path
, &data
);
25 if (path
.MatchesExtension(FILE_PATH_LITERAL(".png"))) {
26 success
= LoadPng(data
);
27 } else if (path
.MatchesExtension(FILE_PATH_LITERAL(".emf"))) {
28 success
= LoadMetafile(data
);
39 Image::Image(const Metafile
& metafile
)
42 LoadMetafile(metafile
);
45 Image::Image(const Image
& image
)
47 row_length_(image
.row_length_
),
49 ignore_alpha_(image
.ignore_alpha_
) {
54 std::string
Image::checksum() const {
55 base::MD5Digest digest
;
56 base::MD5Sum(&data_
[0], data_
.size(), &digest
);
57 return base::HexEncode(&digest
, sizeof(digest
));
60 bool Image::SaveToPng(const FilePath
& filepath
) const {
61 DCHECK(!data_
.empty());
62 std::vector
<unsigned char> compressed
;
63 bool success
= gfx::PNGCodec::Encode(&*data_
.begin(),
64 gfx::PNGCodec::FORMAT_BGRA
,
68 std::vector
<gfx::PNGCodec::Comment
>(),
70 DCHECK(success
&& compressed
.size());
72 int write_bytes
= file_util::WriteFile(
74 reinterpret_cast<char*>(&*compressed
.begin()), compressed
.size());
75 success
= (write_bytes
== static_cast<int>(compressed
.size()));
81 double Image::PercentageDifferent(const Image
& rhs
) const {
82 if (size_
.width() == 0 || size_
.height() == 0 ||
83 rhs
.size_
.width() == 0 || rhs
.size_
.height() == 0)
86 int width
= std::min(size_
.width(), rhs
.size_
.width());
87 int height
= std::min(size_
.height(), rhs
.size_
.height());
88 // Compute pixels different in the overlap
89 int pixels_different
= 0;
90 for (int y
= 0; y
< height
; ++y
) {
91 for (int x
= 0; x
< width
; ++x
) {
92 uint32 lhs_pixel
= pixel_at(x
, y
);
93 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
94 if (lhs_pixel
!= rhs_pixel
)
98 // Look for extra right lhs pixels. They should be white.
99 for (int x
= width
; x
< size_
.width(); ++x
) {
100 uint32 lhs_pixel
= pixel_at(x
, y
);
101 if (lhs_pixel
!= Color(SK_ColorWHITE
))
105 // Look for extra right rhs pixels. They should be white.
106 for (int x
= width
; x
< rhs
.size_
.width(); ++x
) {
107 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
108 if (rhs_pixel
!= Color(SK_ColorWHITE
))
113 // Look for extra bottom lhs pixels. They should be white.
114 for (int y
= height
; y
< size_
.height(); ++y
) {
115 for (int x
= 0; x
< size_
.width(); ++x
) {
116 uint32 lhs_pixel
= pixel_at(x
, y
);
117 if (lhs_pixel
!= Color(SK_ColorWHITE
))
122 // Look for extra bottom rhs pixels. They should be white.
123 for (int y
= height
; y
< rhs
.size_
.height(); ++y
) {
124 for (int x
= 0; x
< rhs
.size_
.width(); ++x
) {
125 uint32 rhs_pixel
= rhs
.pixel_at(x
, y
);
126 if (rhs_pixel
!= Color(SK_ColorWHITE
))
131 // Like the WebKit ImageDiff tool, we define percentage different in terms
132 // of the size of the 'actual' bitmap.
133 double total_pixels
= static_cast<double>(size_
.width()) *
134 static_cast<double>(height
);
135 return static_cast<double>(pixels_different
) / total_pixels
* 100.;
138 bool Image::LoadPng(const std::string
& compressed
) {
141 bool success
= gfx::PNGCodec::Decode(
142 reinterpret_cast<const unsigned char*>(compressed
.c_str()),
143 compressed
.size(), gfx::PNGCodec::FORMAT_BGRA
, &data_
, &w
, &h
);
145 row_length_
= size_
.width() * sizeof(uint32
);
149 bool Image::LoadMetafile(const std::string
& data
) {
150 DCHECK(!data
.empty());
151 NativeMetafile metafile
;
152 if (!metafile
.InitFromData(data
.data(), data
.size()))
154 return LoadMetafile(metafile
);
157 } // namespace printing