Codebase list mozc / 73a8154
Add a tool to convert PNG file to PBGRA32 BMP Currently the logo image on the candidate window footer is rendered by AlphaBlend GDI API, which implicitly assumes that the specified bitmap is a PBGRA (pre-multiplied alpha) Device Independent Bitmap (DIB) when AC_SRC_ALPHA parameter is specified. This tool is designed for doing such a required conversion in build time as follow. gen_pbgra32_bitmap.exe --src=src.png --dest=dest.bmp Ideally candidate_window.cc should be able to handle PNG file directly, but doing that requires some non-trivial code changes that need to run in end user environment. This CL has no impact on production binaries. Hence no user-visible behavior change is intended. BUG= TEST= REF_BUG=25634278 REF_CL=110514591 Yohei Yukawa 8 years ago
3 changed file(s) with 184 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
00 MAJOR=2
11 MINOR=17
2 BUILD=2403
2 BUILD=2404
33 REVISION=102
44 # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be
55 # downloaded by NaCl Mozc.
362362 ],
363363 },
364364 {
365 'target_name': 'gen_pbgra32_bitmap',
366 'type': 'executable',
367 'sources': [
368 'win32/gen_pbgra32_bitmap.cc',
369 ],
370 'dependencies': [
371 '../base/base.gyp:base_core',
372 '../base/base.gyp:scoped_handle',
373 ],
374 'msvs_settings': {
375 'VCLinkerTool': {
376 'AdditionalDependencies': [
377 'gdiplus.lib', # used in 'gen_pbgra32_bitmap.cc'
378 ],
379 'SubSystem': '1', # 1 == subSystemConsole
380 },
381 },
382 },
383 {
365384 'target_name': 'mozc_renderer',
366385 'product_name': '<(renderer_product_name_win)',
367386 'type': 'executable',
0 // Copyright 2010-2016, Google Inc.
1 // All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 // * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 #include <Windows.h>
30 #include <objbase.h>
31
32 #include <algorithm>
33 #include <memory>
34
35 #include "base/file_stream.h"
36 #include "base/flags.h"
37 #include "base/init_mozc.h"
38 #include "base/logging.h"
39 #include "base/port.h"
40 #include "base/util.h"
41
42 DEFINE_string(src, "", "path to the input PNG file");
43 DEFINE_string(dest, "", "path to the output BMP file");
44
45 using ::std::min;
46 using ::std::max;
47
48 // gdiplus.h must be placed here because it internally depends on
49 // global min/max functions.
50 // TODO(yukawa): Use WIC (Windows Imaging Component) instead of GDI+.
51 #include <gdiplus.h> // NOLINT
52
53 namespace {
54
55 const int kErrorLevelSuccess = 0;
56 const int kErrorLevelFail = 1;
57
58 const uint32 kMaxBitmapWidth = 16384;
59 const uint32 kMaxBitmapHeight = 16384;
60
61 bool ConvertMain() {
62 wstring wide_src;
63 mozc::Util::UTF8ToWide(FLAGS_src, &wide_src);
64 std::unique_ptr<Gdiplus::Bitmap> image(
65 Gdiplus::Bitmap::FromFile(wide_src.c_str()));
66
67 const uint32 width_original = image->GetWidth();
68 if (width_original > kMaxBitmapWidth) {
69 LOG(ERROR) << "Too long width: " << width_original;
70 return false;
71 }
72 const int32 width = static_cast<int32>(width_original);
73
74 const uint32 height_original = image->GetHeight();
75 if (height_original > kMaxBitmapHeight) {
76 LOG(ERROR) << "Too long height: " << height_original;
77 return false;
78 }
79 const int32 height = static_cast<int32>(height_original);
80
81 const uint32 num_pixels = static_cast<uint32>(width * height);
82 const uint32 pixel_data_bytes = num_pixels * 4;
83
84 // Use <pshpack2.h> header to match the actual file BMP file format,
85 // which uses 2 byte packing. Include <poppack.h> to restore the
86 // current packing mode.
87 // c.f. https://msdn.microsoft.com/en-us/library/2e70t5y1.aspx
88 #include <pshpack2.h> // NOLINT
89 struct PBGR32Bitmap {
90 uint16 file_signature;
91 uint32 file_size;
92 uint16 reserved1;
93 uint16 reserved2;
94 uint32 pixel_data_offset;
95 uint32 header_size;
96 int32 width;
97 int32 height;
98 uint16 num_planes;
99 uint16 bit_count;
100 uint32 compression;
101 uint32 pixel_data_size;
102 int32 pixel_per_meter_x;
103 int32 pixel_per_meter_y;
104 uint32 num_pallete;
105 uint32 important_color;
106 };
107 #include <poppack.h> // NOLINT
108
109 PBGR32Bitmap header = {};
110 header.file_signature = 0x4d42; // 'BM'
111 header.file_size = sizeof(header) + pixel_data_bytes;
112 header.pixel_data_offset = sizeof(header);
113 header.header_size = sizeof(header) - offsetof(PBGR32Bitmap, header_size);
114 header.width = width;
115 header.height = height;
116 header.num_planes = 1;
117 header.bit_count = 32;
118 header.pixel_data_size = pixel_data_bytes;
119
120 mozc::OutputFileStream output_file(
121 FLAGS_dest.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
122 if (!output_file.good()) {
123 return false;
124 }
125
126 output_file.write(reinterpret_cast<const char *>(&header), sizeof(header));
127 for (size_t y = 0; y < height; ++y) {
128 for (size_t x = 0; x < width; ++x) {
129 Gdiplus::Color color;
130 image->GetPixel(x, height - y - 1, &color);
131 const size_t index = (y * width + x) * 4;
132 output_file << static_cast<uint8>(color.GetB() / 255.0 * color.GetA());
133 output_file << static_cast<uint8>(color.GetG() / 255.0 * color.GetA());
134 output_file << static_cast<uint8>(color.GetR() / 255.0 * color.GetA());
135 output_file << color.GetA();
136 }
137 }
138 return true;
139 }
140
141 } // namespace
142
143 int main(int argc, char **argv) {
144 mozc::InitMozc(argv[0], &argc, &argv, false);
145
146 if (FLAGS_src.empty()) {
147 std::cout << "Specify --src option";
148 return kErrorLevelFail;
149 }
150 if (FLAGS_dest.empty()) {
151 std::cout << "Specify --dest option";
152 return kErrorLevelFail;
153 }
154
155 ULONG_PTR gdiplus_token;
156 Gdiplus::GdiplusStartupInput input;
157 Gdiplus::GdiplusStartup(&gdiplus_token, &input, nullptr);
158
159 const bool result = ConvertMain();
160
161 Gdiplus::GdiplusShutdown(gdiplus_token);
162 return result ? kErrorLevelSuccess : kErrorLevelFail;
163 }