WebP API 문서

이 섹션에서는 WebP 라이브러리에 포함된 인코더 및 디코더용 API를 설명합니다. 이 API 설명은 버전 1.4.0과 관련이 있습니다.

헤더 및 라이브러리

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를 전달할 수 있습니다.

입력 속성

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

반환 값

false
(a) 형식 오류 시 반환되는 오류 코드
true
성공 시 *width*height는 성공적인 반환 시에만 유효합니다.
너비
정수 값입니다. 범위는 1에서 16,383까지로 제한됩니다.
정수 값입니다. 범위는 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 오류 값입니다.

기능
WebBitstreamFeatures 구조를 가리키는 포인터입니다.
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*)를 삭제해야 합니다.

입력 속성

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

반환 값

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에 있음)에 있습니다. 이미지를 저장, 표시 또는 기타 방식으로 처리할 수 있습니다. 이후에는 config의 객체에 할당된 메모리만 회수하면 됩니다. 메모리가 외부이고 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()를 호출하여 메모리를 회수해야 합니다.

입력 배열은 패킹된 바이트 배열 (함수 이름으로 예상한 대로 각 채널당 하나씩)이어야 합니다. 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::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에 선언된 메모리 작성기를 사용한 간단한 예입니다. 각 사진을 압축하려면 이 초기화가 필요할 수 있습니다.

// 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를 읽으면 덜 사용되는 매개변수를 찾는 데 유용할 수 있습니다.