このセクションでは、WebP ライブラリに含まれるエンコーダとデコーダの API について説明します。この API の説明はバージョン 1.5.0 に関するものです。
ヘッダーとライブラリ
libwebp
をインストールすると、webp/
という名前のディレクトリがプラットフォームの一般的な場所にインストールされます。たとえば、Unix プラットフォームでは、次のヘッダー ファイルが /usr/local/include/webp/
にコピーされます。
decode.h
encode.h
types.h
ライブラリは通常のライブラリ ディレクトリにあります。静的ライブラリと動的ライブラリは、Unix プラットフォームの /usr/local/lib/
にあります。
Simple Decoding API
デコード API の使用を開始するには、上記の説明に従って、ライブラリとヘッダー ファイルがインストールされていることを確認する必要があります。
次のように、デコード API ヘッダーを C/C++ コードに含めます。
#include "webp/decode.h"
int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height);
この関数は、WebP 画像ヘッダーを検証し、画像の幅と高さを取得します。ポインタ *width
と *height
は、関連性がないと判断された場合は NULL
を渡すことができます。
入力属性
- データ
- WebP 画像データへのポインタ
- data_size
- これは、イメージデータを含む
data
が指すメモリブロックのサイズです。
戻り値
- false
- フォーマット エラーの場合に返されるエラーコード。
- true
- 成功した場合。
*width
と*height
は、正常に返された場合にのみ有効です。 - 幅
- 整数値。範囲は 1 ~ 16383 に制限されています。
- height
- 整数値。範囲は 1 ~ 16,383 です。
struct WebPBitstreamFeatures {
int width; // Width in pixels.
int height; // Height in pixels.
int has_alpha; // True if the bitstream contains an alpha channel.
int has_animation; // True if the bitstream is an animation.
int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
}
VP8StatusCode WebPGetFeatures(const uint8_t* data,
size_t data_size,
WebPBitstreamFeatures* features);
この関数は、ビットストリームから特徴を取得します。*features
構造体には、ビットストリームから収集された情報が格納されます。
入力属性
- データ
- WebP 画像データへのポインタ
- data_size
- これは、イメージデータを含む
data
が指すメモリブロックのサイズです。
戻り値
VP8_STATUS_OK
- 特徴が正常に取得されたとき。
VP8_STATUS_NOT_ENOUGH_DATA
- ヘッダーから特徴を取得するために追加のデータが必要な場合。
その他のケースでは、追加の VP8StatusCode
エラー値。
- 機能
- WebPBitstreamFeatures 構造体へのポインタ。
uint8_t* WebPDecodeRGBA(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeARGB(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeBGRA(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeRGB(const uint8_t* data, size_t data_size, int* width, int* height);
uint8_t* WebPDecodeBGR(const uint8_t* data, size_t data_size, int* width, int* height);
これらの関数は、data
によって参照される WebP 画像をデコードします。
WebPDecodeRGBA
は、RGBA 画像サンプルを[r0, g0, b0, a0, r1, g1, b1, a1, ...]
順に返します。WebPDecodeARGB
は、ARGB 画像サンプルを[a0, r0, g0, b0, a1, r1, g1, b1, ...]
順に返します。WebPDecodeBGRA
は、BGRA 画像サンプルを[b0, g0, r0, a0, b1, g1, r1, a1, ...]
順に返します。WebPDecodeRGB
は、RGB 画像サンプルを[r0, g0, b0, r1, g1, b1, ...]
の順序で返します。WebPDecodeBGR
は、[b0, g0, r0, b1, g1, r1, ...]
順に BGR 画像サンプルを返します。
これらの関数のいずれかを呼び出すコードは、これらの関数によって返されたデータバッファ (uint8_t*)
を WebPFree()
で削除する必要があります。
入力属性
- データ
- WebP 画像データへのポインタ
- data_size
- これは、イメージデータを含む
data
が指すメモリブロックのサイズです。 - 幅
- 整数値。範囲は現在 1 ~ 16383 に制限されています。
- height
- 整数値。範囲は現在 1 ~ 16383 に制限されています。
戻り値
- uint8_t*
- デコードされた WebP 画像サンプルへのポインタ(リニア RGBA/ARGB/BGRA/RGB/BGR の順序)。
uint8_t* WebPDecodeRGBAInto(const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeARGBInto(const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRAInto(const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeRGBInto(const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
uint8_t* WebPDecodeBGRInto(const uint8_t* data, size_t data_size,
uint8_t* output_buffer, int output_buffer_size, int output_stride);
これらの関数は上記の関数のバリエーションであり、事前割り当てられたバッファ output_buffer
に画像を直接デコードします。このバッファで使用可能な最大ストレージは output_buffer_size
で示されます。このストレージが不足している場合(またはエラーが発生した場合)は、NULL
が返されます。それ以外の場合は、便宜上 output_buffer
が返されます。
パラメータ output_stride
は、スキャンライン間の距離(バイト単位)を指定します。したがって、output_buffer_size
は output_stride * picture - height
以上である必要があります。
入力属性
- データ
- WebP 画像データへのポインタ
- data_size
- これは、イメージデータを含む
data
が指すメモリブロックのサイズです。 - output_buffer_size
- 整数値。割り振られたバッファのサイズ
- output_stride
- 整数値。走査線間の距離を指定します。
戻り値
- output_buffer
- デコードされた WebP 画像へのポインタ。
- uint8_t*
- 関数が成功した場合は
output_buffer
、それ以外の場合はNULL
。
Advanced Decoding API
WebP デコードは、高度な API をサポートして、オンザフライの切り抜きと再スケーリングを可能にします。これは、スマートフォンなどのメモリ制限のある環境で非常に有用です。基本的に、メモリ使用量は、サイズが大きすぎる画像の簡単なプレビューや拡大部分のみが必要な場合は入力ではなく出力のサイズに応じてスケーリングされます。余分な CPU を節約することもできます。
WebP デコードには、完全な画像デコードと小さな入力バッファでの増分デコードの 2 種類があります。必要に応じて、画像のデコード用に外部メモリバッファを指定できます。次のコードサンプルでは、高度なデコード API を使用する手順について説明します。
まず、構成オブジェクトを初期化する必要があります。
#include "webp/decode.h"
WebPDecoderConfig config;
CHECK(WebPInitDecoderConfig(&config));
// One can adjust some additional decoding options:
config.options.no_fancy_upsampling = 1;
config.options.use_scaling = 1;
config.options.scaled_width = scaledWidth();
config.options.scaled_height = scaledHeight();
// etc.
デコード オプションは WebPDecoderConfig
構造内に収集されます。
struct WebPDecoderOptions {
int bypass_filtering; // if true, skip the in-loop filtering
int no_fancy_upsampling; // if true, use faster pointwise upsampler
int use_cropping; // if true, cropping is applied first
int crop_left, crop_top; // top-left position for cropping.
// Will be snapped to even values.
int crop_width, crop_height; // dimension of the cropping area
int use_scaling; // if true, scaling is applied afterward
int scaled_width, scaled_height; // final resolution
int use_threads; // if true, use multi-threaded decoding
int dithering_strength; // dithering strength (0=Off, 100=full)
int flip; // if true, flip output vertically
int alpha_dithering_strength; // alpha dithering strength in [0..100]
};
必要に応じて、事前に把握しておく必要がある場合は、ビットストリーム機能を config.input
に読み込むことができます。たとえば、画像に透明度があるかどうかを確認できます。なお、これによりビットストリームのヘッダーも解析されるため、ビットストリームが有効な WebP ビットストリームかどうかを確認するのに適しています。
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
次に、デコーダに依存せずに直接提供する場合に備えて、デコード メモリ バッファを設定する必要があります。メモリへのポインタ、バッファの合計サイズ、ライン ストライド(スキャンライン間の距離(バイト単位))を指定するだけです。
// Specify the desired output colorspace:
config.output.colorspace = MODE_BGRA;
// Have config.output point to an external buffer:
config.output.u.RGBA.rgba = (uint8_t*)memory_buffer;
config.output.u.RGBA.stride = scanline_stride;
config.output.u.RGBA.size = total_size_of_the_memory_buffer;
config.output.is_external_memory = 1;
画像をデコードする準備ができました。画像のデコードには、次の 2 つのバリエーションがあります。次のコマンドを使用して、画像を一度にデコードできます。
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
または、増分メソッドを使用して、新しいバイトが利用可能になったときに画像を段階的にデコードすることもできます。
WebPIDecoder* idec = WebPINewDecoder(&config.output);
CHECK(idec != NULL);
while (additional_data_is_available) {
// ... (get additional data in some new_data[] buffer)
VP8StatusCode status = WebPIAppend(idec, new_data, new_data_size);
if (status != VP8_STATUS_OK && status != VP8_STATUS_SUSPENDED) {
break;
}
// The above call decodes the current available buffer.
// Part of the image can now be refreshed by calling
// WebPIDecGetRGB()/WebPIDecGetYUVA() etc.
}
WebPIDelete(idec); // the object doesn't own the image memory, so it can
// now be deleted. config.output memory is preserved.
デコードされた画像は config.output に格納されます(この場合は、リクエストされた出力色空間が MODE_BGRA であるため、config.output.u.RGBA に格納されます)。画像は保存、表示、その他の処理を行うことができます。その後、config のオブジェクトに割り振られたメモリを再利用する必要があります。メモリが外部で、WebPDecode() によって割り当てられていない場合でも、この関数を呼び出すことは安全です。
WebPFreeDecBuffer(&config.output);
この API を使用すると、MODE_YUV
と MODE_YUVA
を使用して、画像を YUV 形式と YUVA 形式にデコードすることもできます。この形式は Y'CbCr とも呼ばれます。
Simple Encoding API
最も一般的なレイアウトで RGBA サンプルの配列をエンコードするために、非常にシンプルな関数が用意されています。これらは webp/encode.h
ヘッダーで次のように宣言されます。
size_t WebPEncodeRGB(const uint8_t* rgb, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGR(const uint8_t* bgr, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeRGBA(const uint8_t* rgba, int width, int height, int stride, float quality_factor, uint8_t** output);
size_t WebPEncodeBGRA(const uint8_t* bgra, int width, int height, int stride, float quality_factor, uint8_t** output);
品質係数 quality_factor
の範囲は 0 ~ 100 で、圧縮時の損失と品質を制御します。値 0 は品質が低く出力サイズが小さいことを示し、100 は品質が最も高く出力サイズが最大であることを示します。成功すると、圧縮されたバイトは *output
ポインタに配置され、サイズ(バイト単位)が返されます(失敗した場合は 0 が返されます)。呼び出し元は、*output
ポインタで WebPFree()
を呼び出してメモリを再利用する必要があります。
入力配列は、バイトの圧縮配列(関数名から想定されるように、チャンネルごとに 1 つ)である必要があります。stride
は、ある行から次の行にジャンプするために必要なバイト数に対応します。たとえば、BGRA レイアウトは次のようになります。
ロスレス エンコードには、次のようなシグネチャを持つ同等の関数があります。
size_t WebPEncodeLosslessRGB(const uint8_t* rgb, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGR(const uint8_t* bgr, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessRGBA(const uint8_t* rgba, int width, int height, int stride, uint8_t** output);
size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output);
これらの関数は、非可逆バージョンと同様に、ライブラリのデフォルト設定を使用します。ロスレスの場合、これは「正確」が無効になることを意味します。透明領域の RGB 値は、圧縮を改善するために変更されます。これを回避するには、WebPEncode()
を使用して WebPConfig::exact
を 1
に設定します。
Advanced Encoding API
エンコーダには、高度なエンコード パラメータが多数用意されています。圧縮効率と処理時間のトレードオフをより適切に調整するために役立ちます。これらのパラメータは WebPConfig
構造内で収集されます。この構造で最も使用されるフィールドは次のとおりです。
struct WebPConfig {
int lossless; // Lossless encoding (0=lossy(default), 1=lossless).
float quality; // between 0 and 100. For lossy, 0 gives the smallest
// size and 100 the largest. For lossless, this
// parameter is the amount of effort put into the
// compression: 0 is the fastest but gives larger
// files compared to the slowest, but best, 100.
int method; // quality/speed trade-off (0=fast, 6=slower-better)
WebPImageHint image_hint; // Hint for image type (lossless only for now).
// Parameters related to lossy compression only:
int target_size; // if non-zero, set the desired target size in bytes.
// Takes precedence over the 'compression' parameter.
float target_PSNR; // if non-zero, specifies the minimal distortion to
// try to achieve. Takes precedence over target_size.
int segments; // maximum number of segments to use, in [1..4]
int sns_strength; // Spatial Noise Shaping. 0=off, 100=maximum.
int filter_strength; // range: [0 = off .. 100 = strongest]
int filter_sharpness; // range: [0 = off .. 7 = least sharp]
int filter_type; // filtering type: 0 = simple, 1 = strong (only used
// if filter_strength > 0 or autofilter > 0)
int autofilter; // Auto adjust filter's strength [0 = off, 1 = on]
int alpha_compression; // Algorithm for encoding the alpha plane (0 = none,
// 1 = compressed with WebP lossless). Default is 1.
int alpha_filtering; // Predictive filtering method for alpha plane.
// 0: none, 1: fast, 2: best. Default if 1.
int alpha_quality; // Between 0 (smallest size) and 100 (lossless).
// Default is 100.
int pass; // number of entropy-analysis passes (in [1..10]).
int show_compressed; // if true, export the compressed picture back.
// In-loop filtering is not applied.
int preprocessing; // preprocessing filter (0=none, 1=segment-smooth)
int partitions; // log2(number of token partitions) in [0..3]
// Default is set to 0 for easier progressive decoding.
int partition_limit; // quality degradation allowed to fit the 512k limit on
// prediction modes coding (0: no degradation,
// 100: maximum possible degradation).
int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion
};
これらのパラメータのほとんどは、cwebp
コマンドライン ツールを使用してテストできます。
入力サンプルは WebPPicture
構造にラップする必要があります。この構造では、use_argb
フラグの値に応じて、入力サンプルを RGBA 形式または YUVA 形式で保存できます。
構造は次のとおりです。
struct WebPPicture {
int use_argb; // To select between ARGB and YUVA input.
// YUV input, recommended for lossy compression.
// Used if use_argb = 0.
WebPEncCSP colorspace; // colorspace: should be YUVA420 or YUV420 for now (=Y'CbCr).
int width, height; // dimensions (less or equal to WEBP_MAX_DIMENSION)
uint8_t *y, *u, *v; // pointers to luma/chroma planes.
int y_stride, uv_stride; // luma/chroma strides.
uint8_t* a; // pointer to the alpha plane
int a_stride; // stride of the alpha plane
// Alternate ARGB input, recommended for lossless compression.
// Used if use_argb = 1.
uint32_t* argb; // Pointer to argb (32 bit) plane.
int argb_stride; // This is stride in pixels units, not bytes.
// Byte-emission hook, to store compressed bytes as they are ready.
WebPWriterFunction writer; // can be NULL
void* custom_ptr; // can be used by the writer.
// Error code for the latest error encountered during encoding
WebPEncodingError error_code;
};
この構造体には、圧縮されたバイトが利用可能になったときに出力する関数もあります。メモリ内書き込みの例については、以下をご覧ください。他の書き込み元は、データをファイルに直接保存できます(例については examples/cwebp.c
をご覧ください)。
高度な API を使用してエンコードする一般的なフローは次のとおりです。
まず、圧縮パラメータを含むエンコード構成を設定する必要があります。同じ構成を、後で複数の異なる画像の圧縮に使用できます。
#include "webp/encode.h"
WebPConfig config;
if (!WebPConfigPreset(&config, WEBP_PRESET_PHOTO, quality_factor)) return 0; // version error
// Add additional tuning:
config.sns_strength = 90;
config.filter_sharpness = 6;
config.alpha_quality = 90;
config_error = WebPValidateConfig(&config); // will verify parameter ranges (always a good habit)
次に、入力サンプルを参照またはコピーして WebPPicture
に参照する必要があります。以下に、サンプルを保持するバッファを割り当てる例を示します。ただし、すでに割り振られているサンプル配列への「ビュー」は簡単に設定できます。WebPPictureView()
関数をご覧ください。
// Setup the input data, allocating a picture of width x height dimension
WebPPicture pic;
if (!WebPPictureInit(&pic)) return 0; // version error
pic.width = width;
pic.height = height;
if (!WebPPictureAlloc(&pic)) return 0; // memory error
// At this point, 'pic' has been initialized as a container, and can receive the YUVA or RGBA samples.
// Alternatively, one could use ready-made import functions like WebPPictureImportRGBA(), which will take
// care of memory allocation. In any case, past this point, one will have to call WebPPictureFree(&pic)
// to reclaim allocated memory.
圧縮されたバイトを出力するために、新しいバイトが利用可能になるたびにフックが呼び出されます。webp/encode.h
でメモリ書き込みツールを宣言した簡単な例を次に示します。この初期化は、各画像を圧縮するために必要になる可能性があります。
// Set up a byte-writing method (write-to-memory, in this case):
WebPMemoryWriter writer;
WebPMemoryWriterInit(&writer);
pic.writer = WebPMemoryWrite;
pic.custom_ptr = &writer;
これで、入力サンプルを圧縮し(その後メモリを解放)ることができます。
int ok = WebPEncode(&config, &pic);
WebPPictureFree(&pic); // Always free the memory associated with the input.
if (!ok) {
printf("Encoding error: %d\n", pic.error_code);
} else {
printf("Output size: %d\n", writer.size);
}
API と構造をより高度に使用するには、webp/encode.h
ヘッダーで利用可能なドキュメントを確認することをおすすめします。サンプルコード examples/cwebp.c
を読むことは、あまり使用されていないパラメータを見つけるのに役立ちます。