В этом разделе описывается API кодера и декодера, входящих в библиотеку WebP. Описание API относится к версии 1.6.0.
Заголовки и библиотеки
 При установке libwebp каталог webp/ будет создан в типичном для вашей платформы месте. Например, на платформах Unix следующие заголовочные файлы будут скопированы в /usr/local/include/webp/ .
decode.h
encode.h
types.h
 Библиотеки расположены в обычных каталогах. Статические и динамические библиотеки находятся в /usr/local/lib/ на платформах Unix.
Простое 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, содержащие данные изображения.
Возврат
- ЛОЖЬ
- Код ошибки возвращается в случае ошибки(ок) форматирования.
- истинный
-  В случае успеха *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, содержащие данные изображения.
Возврат
-  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);
 Эти функции декодируют изображение WebP, на которое указывает data .
-  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, ...].
 Код, вызывающий любую из этих функций, должен удалить буфер данных (uint8_t*) возвращаемый этими функциями с помощью WebPFree() .
Входные атрибуты
- данные
- Указатель на данные изображения WebP
- размер_данных
-  Это размер блока памяти, на который указывают data, содержащие данные изображения.
- ширина
- Целое число. Диапазон в настоящее время ограничен от 1 до 16383.
- высота
- Целое число. Диапазон в настоящее время ограничен от 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, содержащие данные изображения.
- размер_выводного_буфера
- Целое значение. Размер выделенного буфера.
- output_stride
- Целое значение. Указывает расстояние между строками развёртки.
Возврат
- выходной_буфер
- Указатель на декодированное изображение WebP.
- uint8_t*
-  output_buffer, если функция выполнена успешно;NULLв противном случае.
API расширенного декодирования
Декодирование WebP поддерживает расширенный API, позволяющий кадрировать и масштабировать изображение «на лету», что весьма полезно в средах с ограниченной памятью, таких как мобильные телефоны. По сути, использование памяти будет масштабироваться в зависимости от размера выходного файла, а не входного, когда требуется лишь быстрый предварительный просмотр или увеличенный фрагмент слишком большого изображения. Кстати, это также позволяет сэкономить ресурсы процессора.
Декодирование 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 (или, точнее, в config.output.u.RGBA в данном случае, поскольку запрошенное выходное цветовое пространство было MODE_BGRA). Изображение можно сохранить, отобразить или иным образом обработать. После этого нам нужно только освободить память, выделенную в объекте config. Эту функцию можно безопасно вызывать, даже если память внешняя и не была выделена функцией WebPDecode():
WebPFreeDecBuffer(&config.output);
С помощью этого API изображение также можно декодировать в форматы YUV и YUVA, используя MODE_YUV и MODE_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, в случае ошибки). Вызывающий код должен вызвать WebPFree() для указателя *output , чтобы освободить память.
 Входной массив должен представлять собой упакованный массив байтов (по одному на каждый канал, как и следует из названия функции). 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 в полностью прозрачных областях (то есть областях со значениями альфа, равными 0 ) будут изменены для улучшения сжатия. Чтобы избежать этого, используйте WebPEncode() и установите WebPConfig::exact значение 1 .
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 . Эта структура может хранить входные образцы в формате RGBA или YUVA, в зависимости от значения флага use_argb .
Структура организована следующим образом:
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 может оказаться полезным для обнаружения редко используемых параметров.
