Last active
March 19, 2025 20:38
-
-
Save usagi/10aaba329af481095923 to your computer and use it in GitHub Desktop.
CMake プロジェクトの C++ アプリで webp 形式の読み書きに libwebp で対応することはじめ ref: http://qiita.com/usagi/items/38589f87a7a88ad1ddcb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required( VERSION 3.2 ) | |
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include) | |
link_directories(${CMAKE_CURRENT_BINARY_DIR}/lib) | |
include( ExternalProject ) | |
ExternalProject_Add( external_libwebp | |
# https://github.com/webmproject/libwebp | |
# http://www.webmproject.org/ | |
GIT_REPOSITORY [email protected]:webmproject/libwebp.git | |
# v0.5.0 タグなどには cmake が無くて少し手間が増えるのでとりあえず master | |
GIT_TAG master | |
# WEBP 系のオプションは webp リポジトリーの CMakeLists.txt 冒頭にわかりやすく整理されているよ | |
# おまけツールの cwebp, dwebp コマンドのビルドを on にする場合は libjpeg が必要になるのでとりあえず off にしておくよ | |
CMAKE_ARGS -DWEBP_BUILD_CWEBP=off | |
-DWEBP_BUILD_DWEBP=off | |
-DWEBP_EXPERIMENTAL_FEATURES=on | |
-DWEBP_FORCE_ALIGNED=on | |
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} | |
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} | |
-DCMAKE_COMPILER_IS_GNUCXX=${CMAKE_COMPILER_IS_GNUCXX} | |
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} | |
-DCMAKE_C_FLAGS=${GL_BINDING_C_FLAGS} | |
# cmake -> ninja -> install ターゲットなどしたいところだけどカスタムプリフィックスの挙動がおかしいようなので install だけごりごり書いておく | |
INSTALL_COMMAND | |
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/external/libwebp/src/external_libwebp/src/webp ${CMAKE_CURRENT_BINARY_DIR}/include/webp | |
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/external/libwebp/src/external_libwebp-build/include ${CMAKE_CURRENT_BINARY_DIR}/include | |
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/external/libwebp/src/external_libwebp-build/libwebp.a ${CMAKE_CURRENT_BINARY_DIR}/lib/libwebp.a | |
# cwebp, dwebp もビルドする時は付ける | |
#COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/external/libwebp/src/external_libwebp-build/cwebp.exe ${CMAKE_CURRENT_BINARY_DIR}/bin/cwebp.exe | |
#COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_BINARY_DIR}/external/libwebp/src/external_libwebp-build/dwebp.exe ${CMAKE_CURRENT_BINARY_DIR}/bin/dwebp.exe | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <webp/decode.h> | |
#include <webp/encode.h> | |
#include <webp/types.h> | |
#include <cstdint> | |
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
auto main() -> int | |
{ | |
// メモリーに 256 pixels * 256 pixels * 4 elements な変換元の入力画像データを適当に作るよ | |
constexpr auto in_width = 256; | |
constexpr auto in_height = 256; | |
constexpr auto in_elements = 4; | |
std::vector< std::uint8_t > in( in_width * in_height * in_elements ); | |
for ( int y = 0 ; y < in_height; ++y ) | |
for ( int x = 0 ; x < in_width; ++x ) | |
{ | |
in[ y * in_width * in_elements + x * in_elements + 0] = x; | |
in[ y * in_width * in_elements + x * in_elements + 1] = 0; | |
in[ y * in_width * in_elements + x * in_elements + 2] = y; | |
in[ y * in_width * in_elements + x * in_elements + 3] = 255; | |
} | |
// webp 形式に変換した結果をこれに入れるよ | |
std::uint8_t* out_data = nullptr; | |
auto out_size = 0ull; | |
constexpr auto in_stride = in_width * in_elements; | |
const auto write_file = [&]( const auto& filename ) | |
{ | |
std::ofstream o( filename, std::ios::binary ); | |
o.write( reinterpret_cast< const char* >( out_data ), out_size ); | |
if ( o.bad() ) | |
return EXIT_FAILURE; | |
}; | |
#ifndef LOSSLESS | |
// ロッシーで最高品質の webp に変換してファイルを出力してみる | |
{ | |
constexpr auto out_quality_factor = 100.0f; | |
out_size = WebPEncodeRGBA | |
( in.data(), in_width, in_height, in_stride | |
, out_quality_factor | |
, &out_data | |
); | |
write_file( "lossy-100.webp" ); | |
} | |
#else | |
// ロスレスで最高品質の webp に変換してファイルを出力してみる | |
{ | |
out_size = WebPEncodeLosslessRGBA | |
( in.data(), in_width, in_height, in_stride | |
, &out_data | |
); | |
write_file( "lossless.webp" ); | |
} | |
#endif | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <webp/decode.h> | |
#include <webp/encode.h> | |
#include <webp/types.h> | |
#include <cstdint> | |
#include <iostream> | |
#include <fstream> | |
#include <vector> | |
auto main() -> int | |
{ | |
std::ifstream i( "hoge.lossless.webp", std::ios::binary ); | |
std::vector< std::uint8_t > in | |
( ( std::istreambuf_iterator< char >( i ) ) | |
, ( std::istreambuf_iterator< char >( ) ) | |
); | |
// 対象のバイナリーデータが webp 形式か確認(†1) | |
if ( WebPGetInfo( in.data(), in.size(), nullptr, nullptr ) == 0 ) | |
return EXIT_FAILURE; | |
int width = 0; | |
int height = 0; | |
const auto deleter = []( auto* p ){ free( p ); }; | |
const std::unique_ptr< std::uint8_t, decltype( deleter ) > decoded_data | |
( WebPDecodeRGBA( in.data(), in.size(), &width, &height ) | |
, deleter | |
); | |
); | |
/* 読みだした画像でお好みの処理をどうぞ */ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment