diff --git a/src/mozc_version_template.txt b/src/mozc_version_template.txt index 14296d930..6f7edfb98 100644 --- a/src/mozc_version_template.txt +++ b/src/mozc_version_template.txt @@ -1,6 +1,6 @@ MAJOR=2 MINOR=17 -BUILD=2403 +BUILD=2404 REVISION=102 # NACL_DICTIONARY_VERSION is the target version of the system dictionary to be # downloaded by NaCl Mozc. diff --git a/src/renderer/renderer.gyp b/src/renderer/renderer.gyp index 5ee1ccba5..3fdaf50e8 100644 --- a/src/renderer/renderer.gyp +++ b/src/renderer/renderer.gyp @@ -362,6 +362,25 @@ 'renderer_style_handler', ], }, + { + 'target_name': 'gen_pbgra32_bitmap', + 'type': 'executable', + 'sources': [ + 'win32/gen_pbgra32_bitmap.cc', + ], + 'dependencies': [ + '../base/base.gyp:base_core', + '../base/base.gyp:scoped_handle', + ], + 'msvs_settings': { + 'VCLinkerTool': { + 'AdditionalDependencies': [ + 'gdiplus.lib', # used in 'gen_pbgra32_bitmap.cc' + ], + 'SubSystem': '1', # 1 == subSystemConsole + }, + }, + }, { 'target_name': 'mozc_renderer', 'product_name': '<(renderer_product_name_win)', diff --git a/src/renderer/win32/gen_pbgra32_bitmap.cc b/src/renderer/win32/gen_pbgra32_bitmap.cc new file mode 100644 index 000000000..77e4b0fba --- /dev/null +++ b/src/renderer/win32/gen_pbgra32_bitmap.cc @@ -0,0 +1,164 @@ +// Copyright 2010-2016, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include +#include + +#include +#include + +#include "base/file_stream.h" +#include "base/flags.h" +#include "base/init_mozc.h" +#include "base/logging.h" +#include "base/port.h" +#include "base/util.h" + +DEFINE_string(src, "", "path to the input PNG file"); +DEFINE_string(dest, "", "path to the output BMP file"); + +using ::std::min; +using ::std::max; + +// gdiplus.h must be placed here because it internally depends on +// global min/max functions. +// TODO(yukawa): Use WIC (Windows Imaging Component) instead of GDI+. +#include // NOLINT + +namespace { + +const int kErrorLevelSuccess = 0; +const int kErrorLevelFail = 1; + +const uint32 kMaxBitmapWidth = 16384; +const uint32 kMaxBitmapHeight = 16384; + +bool ConvertMain() { + wstring wide_src; + mozc::Util::UTF8ToWide(FLAGS_src, &wide_src); + std::unique_ptr image( + Gdiplus::Bitmap::FromFile(wide_src.c_str())); + + const uint32 width_original = image->GetWidth(); + if (width_original > kMaxBitmapWidth) { + LOG(ERROR) << "Too long width: " << width_original; + return false; + } + const int32 width = static_cast(width_original); + + const uint32 height_original = image->GetHeight(); + if (height_original > kMaxBitmapHeight) { + LOG(ERROR) << "Too long height: " << height_original; + return false; + } + const int32 height = static_cast(height_original); + + const uint32 num_pixels = static_cast(width * height); + const uint32 pixel_data_bytes = num_pixels * 4; + + // Use header to match the actual file BMP file format, + // which uses 2 byte packing. Include to restore the + // current packing mode. + // c.f. https://msdn.microsoft.com/en-us/library/2e70t5y1.aspx +#include // NOLINT + struct PBGR32Bitmap { + uint16 file_signature; + uint32 file_size; + uint16 reserved1; + uint16 reserved2; + uint32 pixel_data_offset; + uint32 header_size; + int32 width; + int32 height; + uint16 num_planes; + uint16 bit_count; + uint32 compression; + uint32 pixel_data_size; + int32 pixel_per_meter_x; + int32 pixel_per_meter_y; + uint32 num_pallete; + uint32 important_color; + }; +#include // NOLINT + + PBGR32Bitmap header = {}; + header.file_signature = 0x4d42; // 'BM' + header.file_size = sizeof(header) + pixel_data_bytes; + header.pixel_data_offset = sizeof(header); + header.header_size = sizeof(header) - offsetof(PBGR32Bitmap, header_size); + header.width = width; + header.height = height; + header.num_planes = 1; + header.bit_count = 32; + header.pixel_data_size = pixel_data_bytes; + + mozc::OutputFileStream output_file( + FLAGS_dest.c_str(), std::ios::out | std::ios::binary | std::ios::trunc); + if (!output_file.good()) { + return false; + } + + output_file.write(reinterpret_cast(&header), sizeof(header)); + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x) { + Gdiplus::Color color; + image->GetPixel(x, height - y - 1, &color); + const size_t index = (y * width + x) * 4; + output_file << static_cast(color.GetB() / 255.0 * color.GetA()); + output_file << static_cast(color.GetG() / 255.0 * color.GetA()); + output_file << static_cast(color.GetR() / 255.0 * color.GetA()); + output_file << color.GetA(); + } + } + return true; +} + +} // namespace + +int main(int argc, char **argv) { + mozc::InitMozc(argv[0], &argc, &argv, false); + + if (FLAGS_src.empty()) { + std::cout << "Specify --src option"; + return kErrorLevelFail; + } + if (FLAGS_dest.empty()) { + std::cout << "Specify --dest option"; + return kErrorLevelFail; + } + + ULONG_PTR gdiplus_token; + Gdiplus::GdiplusStartupInput input; + Gdiplus::GdiplusStartup(&gdiplus_token, &input, nullptr); + + const bool result = ConvertMain(); + + Gdiplus::GdiplusShutdown(gdiplus_token); + return result ? kErrorLevelSuccess : kErrorLevelFail; +}