WebP API 문서

이 섹션에서는 WebP 라이브러리에 포함된 인코더 및 디코더의 API를 설명합니다. 이 API 설명은 버전 1.6.0에 관한 것입니다.

헤더 및 라이브러리

libwebp설치하면 webp/라는 디렉터리가 플랫폼의 일반적인 위치에 설치됩니다. 예를 들어 Unix 플랫폼에서는 다음 헤더 파일이 /usr/local/include/webp/에 복사됩니다.

decode.h
encode.h
types.h

라이브러리는 일반 라이브러리 디렉터리에 있습니다. 정적 및 동적 라이브러리는 Unix 플랫폼의 /usr/local/lib/에 있습니다.

Simple Decoding 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에 전달될 수 있습니다.

입력 속성

데이터
WebP 이미지 데이터 포인터
data_size
이미지 데이터를 포함하는 data이 가리키는 메모리 블록의 크기입니다.

반환 값

거짓
서식 오류가 있는 경우 반환되는 오류 코드
true
성공 시 *width*height은 반품이 완료된 경우에만 유효합니다.
너비
정수 값입니다. 범위는 1~16383으로 제한됩니다.
높이
정수 값입니다. 범위는 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 구조는 비트 스트림에서 수집한 정보로 채워집니다.

입력 속성

데이터
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[r0, g0, b0, a0, r1, g1, b1, a1, ...] 순서로 RGBA 이미지 샘플을 반환합니다.
  • WebPDecodeARGB[a0, r0, g0, b0, a1, r1, g1, b1, ...] 순서로 ARGB 이미지 샘플을 반환합니다.
  • WebPDecodeBGRA[b0, g0, r0, a0, b1, g1, r1, a1, ...] 순서로 BGRA 이미지 샘플을 반환합니다.
  • WebPDecodeRGB[r0, g0, b0, r1, g1, b1, ...] 순서로 RGB 이미지 샘플을 반환합니다.
  • WebPDecodeBGR은 BGR 이미지 샘플을 [b0, g0, r0, b1, g1, r1, ...] 순서로 반환합니다.

이러한 함수를 호출하는 코드는 WebPFree()를 사용하여 이러한 함수에서 반환된 데이터 버퍼 (uint8_t*)를 삭제해야 합니다.

입력 속성

데이터
WebP 이미지 데이터 포인터
data_size
이미지 데이터를 포함하는 data가 가리키는 메모리 블록의 크기입니다.
너비
정수 값입니다. 현재 범위는 1~16383으로 제한됩니다.
높이
정수 값입니다. 현재 범위는 1~16383으로 제한됩니다.

반환 값

uint8_t*
선형 RGBA/ARGB/BGRA/RGB/BGR 순서로 디코딩된 WebP 이미지 샘플에 대한 포인터입니다.
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 이상이어야 합니다.

입력 속성

데이터
WebP 이미지 데이터 포인터
data_size
이미지 데이터를 포함하는 data가 가리키는 메모리 블록의 크기입니다.
output_buffer_size
정수 값입니다. 할당된 버퍼의 크기
output_stride
정수 값입니다. 스캔선 간의 거리를 지정합니다.

반환 값

output_buffer
디코딩된 WebP 이미지에 대한 포인터입니다.
uint8_t*
함수가 성공하면
output_buffer, 그렇지 않으면 NULL

고급 디코딩 API

WebP 디코딩은 고급 API를 지원하여 즉석 자르기 및 크기 조절 기능을 제공합니다. 이는 휴대전화와 같이 메모리가 제한된 환경에서 매우 유용합니다. 기본적으로 메모리 사용량은 입력 크기가 아닌 출력 크기에 따라 조정됩니다. 빠른 미리보기나 너무 큰 사진의 확대된 부분만 필요한 경우에 유용합니다. CPU도 절약할 수 있습니다.

WebP 디코딩에는 전체 이미지 디코딩과 작은 입력 버퍼를 통한 증분 디코딩의 두 가지 변형이 있습니다. 사용자는 선택적으로 이미지를 디코딩하기 위한 외부 메모리 버퍼를 제공할 수 있습니다. 다음 코드 샘플에서는 고급 디코딩 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;

이미지를 디코딩할 준비가 되었습니다. 이미지를 디코딩하는 데는 두 가지 가능한 변형이 있습니다. 다음 코드를 사용하여 이미지를 한 번에 디코딩할 수 있습니다.

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이라고도 합니다.

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()를 호출하여 메모리를 회수해야 합니다.

입력 배열은 함수의 이름에서 예상되는 대로 채널당 하나인 바이트의 패킹된 배열이어야 합니다. 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);

이러한 함수는 손실 버전과 마찬가지로 라이브러리의 기본 설정을 사용합니다. 무손실의 경우 '정확'이 사용 중지됨을 의미합니다. 완전히 투명한 영역 (즉, 알파 값이 0인 영역)의 RGB 값은 압축을 개선하기 위해 수정됩니다. 이를 방지하려면 WebPEncode()를 사용하고 WebPConfig::exact1로 설정하세요.

고급 인코딩 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에 선언된 memory-writer가 있는 간단한 예입니다. 이 초기화는 압축할 각 사진에 필요할 수 있습니다.

// 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 예시 코드를 읽으면 사용 빈도가 낮은 매개변수를 찾는 데 도움이 될 수 있습니다.