WebP API ドキュメント

このセクションでは、WebP ライブラリに含まれるエンコーダとデコーダ用の API について説明します。この API の説明は、バージョン 1.3.2 に関連しています。

ヘッダーとライブラリ

libwebpインストールすると、webp/ というディレクトリがプラットフォームの一般的な場所にインストールされます。たとえば、Unix プラットフォームでは、次のヘッダー ファイルは /usr/local/include/webp/ にコピーされます。

decode.h
encode.h
types.h

ライブラリは通常のライブラリ ディレクトリにあります。静的ライブラリと動的ライブラリは、Unix プラットフォームでは /usr/local/lib/ にあります。

シンプルなデコード API

デコード API の使用を開始するには、上記の説明に沿ってライブラリとヘッダー ファイルがインストールされていることを確認する必要があります。

次のように、C/C++ コードにデコード API ヘッダーを含めます。

#include "webp/decode.h"
int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height);

この関数は、WebP 画像ヘッダーを検証し、画像の幅と高さを取得します。ポインタの *width*height は、関連性がないと判断した場合は NULL を渡すことができます。

入力属性

data
WebP 画像データへのポインタ
data_size
これは、画像データを含む data がポイントするメモリブロックのサイズです。

戻り値

false
(a)フォーマット エラーの場合に返されるエラーコード。
true
成功時。*width*height は、正常に返された場合にのみ有効です。
width
整数値。範囲は 1 ~ 16383 に制限されます。
height
整数値。範囲は 1 ~ 16383 に制限されます。
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 構造体は、ビットストリームから収集された情報で満たされます。

入力属性

data
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 は、BGR 画像サンプルを [b0, g0, r0, b1, g1, r1, ...] の順序で返します。

これらの関数を呼び出すコードは、WebPFree() でこれらの関数から返されたデータバッファ (uint8_t*) を削除する必要があります。

入力属性

data
WebP 画像データへのポインタ
data_size
これは、画像データを含む data が指すメモリブロックのサイズです。
width
整数値。範囲は現在 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_sizeoutput_stride * picture - height 以上であることが想定されます。

入力属性

data
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 にあります)。画像の保存、表示、処理を行うことができます。その後、構成のオブジェクトに割り当てられたメモリを再利用する必要があります。メモリが外部にあり、WebPDecode() によって割り当てられていなくても、この関数を安全に呼び出すことができます。

WebPFreeDecBuffer(&config.output);

この API を使用すると、MODE_YUVMODE_YUVA をそれぞれ使用して、画像を YUV 形式と YUVA 形式にデコードすることもできます。この形式は Y'CbCr とも呼ばれます。

シンプル エンコード 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);

非可逆バージョンと同様に、これらの関数はライブラリのデフォルト設定を使用します。可逆圧縮の場合、「exact」は無効になります。透明領域の RGB 値は、圧縮率を高めるために変更されます。これを回避するには、WebPEncode() を使用して、WebPConfig::exact1 に設定します。

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 は、あまり使用されていないパラメータを見つけるのに役立ちます。