En esta sección, se describe la API para el codificador y el decodificador que se incluyen en la biblioteca WebP. La descripción de esta API corresponde a la versión 1.4.0.
Encabezados y bibliotecas
Cuando instalas libwebp
, un directorio llamado webp/
se instalarán en la ubicación habitual de tu plataforma. Por ejemplo, en
plataformas Unix, los siguientes archivos de encabezado se copiarían en
/usr/local/include/webp/
decode.h
encode.h
types.h
Las bibliotecas se encuentran en los directorios de bibliotecas habituales. La transformación estática y
Las bibliotecas dinámicas están en /usr/local/lib/
en plataformas Unix.
API de Simple Decoding
Para comenzar a usar la API de decodificación, debes asegurarte de tener el archivos de encabezado y biblioteca instalados como se describe más arriba.
Incluye el encabezado de la API de decodificación en tu código C/C++ de la siguiente manera:
#include "webp/decode.h"
int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height);
Esta función validará el encabezado de imagen WebP y recuperará el ancho de la imagen.
y altura. Los punteros *width
y *height
pueden pasarse NULL
si se considera
irrelevantes.
Atributos de entrada
- datos
- Puntero a datos de imágenes WebP
- data_size
- Es el tamaño del bloque de memoria al que apunta
data
que contiene el datos de imágenes.
Muestra
- falso
- Código de error que se muestra en el caso de (a) errores de formato.
- verdadero
- En caso de éxito
*width
y*height
solo son válidos si se devuelven correctamente. - ancho
- Valor de número entero. El rango está limitado de 1 a 16,383.
- alto
- Valor de número entero. El rango está limitado de 1 a 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);
Esta función recuperará atributos del flujo de bits. El *features
La estructura está llena de información recopilada del flujo de bits:
Atributos de entrada
- datos
- Puntero a datos de imágenes WebP
- data_size
- Es el tamaño del bloque de memoria al que apunta
data
que contiene el datos de imágenes.
Muestra
VP8_STATUS_OK
- Cuando los atributos se recuperan de forma correcta.
VP8_STATUS_NOT_ENOUGH_DATA
- Cuando se necesitan más datos para recuperar los atributos de los encabezados.
Valores de error VP8StatusCode
adicionales en otros casos.
- funciones
- Puntero a la estructura 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);
Estas funciones decodifican una imagen WebP a la que apunta data
.
WebPDecodeRGBA
devuelve muestras de imágenes RGBA en el orden de[r0, g0, b0, a0, r1, g1, b1, a1, ...]
.WebPDecodeARGB
muestra muestras de imágenes ARGB en el orden de[a0, r0, g0, b0, a1, r1, g1, b1, ...]
.WebPDecodeBGRA
devuelve muestras de imágenes de BGRA en el pedido de[b0, g0, r0, a0, b1, g1, r1, a1, ...]
.WebPDecodeRGB
devuelve muestras de imágenes RGB en el orden de[r0, g0, b0, r1, g1, b1, ...]
.WebPDecodeBGR
devuelve muestras de imágenes BGR en el pedido[b0, g0, r0, b1, g1, r1, ...]
.
El código que llama a cualquiera de estas funciones debe borrar el búfer de datos
(uint8_t*)
que muestran estas funciones con WebPFree()
.
Atributos de entrada
- datos
- Puntero a datos de imágenes WebP
- data_size
- Es el tamaño del bloque de memoria al que apunta
data
que contiene el datos de imágenes - ancho
- Valor de número entero. Actualmente, el rango es limitado de 1 a 16,383.
- alto
- Valor de número entero. Actualmente, el rango es limitado de 1 a 16,383.
Muestra
- uint8_t*
- Puntero para muestras de imágenes WebP decodificadas en RGBA/ARGB/BGRA/RGB/BGR lineal respectivamente.
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);
Estas funciones son variantes de las anteriores y decodifican la imagen directamente.
en un búfer output_buffer
preasignado. El máximo almacenamiento disponible
este búfer se indica mediante output_buffer_size
. Si este almacenamiento no es
suficiente (o se produjo un error), se muestra NULL
. De lo contrario,
Para tu comodidad, se devuelve output_buffer
.
El parámetro output_stride
especifica la distancia (en bytes) entre
líneas de análisis. Por lo tanto, se espera que output_buffer_size
sea de al menos
output_stride * picture - height
Atributos de entrada
- datos
- Puntero a datos de imágenes WebP
- data_size
- Es el tamaño del bloque de memoria al que apunta
data
que contiene el datos de imágenes - output_buffer_size
- Valor de número entero. Tamaño del búfer asignado
- output_stride
- Valor de número entero. Especifica la distancia entre las líneas de análisis.
Muestra
- output_buffer
- Puntero a imagen WebP decodificada.
- uint8_t*
output_buffer
si la función tiene éxito; De lo contrario,NULL
.
API de decodificación avanzada
La decodificación de WebP es compatible con una API avanzada que brinda la posibilidad de utilizar datos sobre la marcha. recortar y reescalar, lo que es muy útil para los modelos entornos como teléfonos celulares. Básicamente, el uso de memoria escalará con el tamaño del archivo de salida, no el de la entrada, cuando solo se necesita una vista previa rápida ampliada de una imagen que, de lo contrario, sería demasiado grande. Se puede guardar parte de la CPU también, por casualidad.
La decodificación de WebP tiene dos variantes: la decodificación de imágenes completa y la incremental decodificación en búferes de entrada pequeños. De forma opcional, los usuarios pueden proporcionar de memoria para decodificar la imagen. En la siguiente muestra de código, los pasos para usar la API de decodificación avanzada.
Primero, debemos inicializar un objeto de configuración:
#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.
Las opciones de decodificación se recopilan en WebPDecoderConfig
estructura:
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]
};
De manera opcional, las funciones de flujo de bits se pueden leer en config.input
.
en caso de que necesitemos conocerlos con anticipación. Por ejemplo, puede ser útil saber
si la imagen tiene algo de transparencia. Ten en cuenta que esta acción
analizar el encabezado del flujo de bits y, por lo tanto, es una buena manera de
si el flujo de bits parece uno de WebP válido.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
Luego, debemos configurar el búfer de memoria de decodificación en caso de que queramos proporcionarle. directamente, en lugar de depender del decodificador para su asignación. Solo necesitamos proporcionan el puntero a la memoria, además del tamaño total del búfer y el zancada de la línea (distancia en bytes entre las líneas de análisis).
// 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;
La imagen está lista para decodificarse. Existen dos variantes posibles para la decodificación la imagen. Podemos decodificar la imagen de una sola vez usando lo siguiente:
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
Alternativamente, podemos usar el método incremental para decodificar la imagen a medida que estén disponibles bytes nuevos:
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.
La imagen decodificada ahora se encuentra en config.output (o, en su lugar, en config.output.u.RGBA en este caso, dado que el espacio de color de salida solicitado era MODE_BGRA). La imagen puede se guarden, se muestren o se procesen de otro modo. Luego, solo necesitamos reclamar la memoria asignada en el objeto de configuración. Se puede llamar a esta función incluso si la memoria es externa y no está asignado por WebPDecode():
WebPFreeDecBuffer(&config.output);
Con esta API, también se puede decodificar la imagen a los formatos YUV y YUVA, con
MODE_YUV
y MODE_YUVA
respectivamente. Este formato también se denomina
Y'CbCr.
API de Simple Encoding
Se proporcionan algunas funciones muy simples para codificar arrays de muestras RGBA
en los diseños más comunes. Se declaran en el archivo webp/encode.h
.
encabezado como:
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);
El factor de calidad quality_factor
varía entre 0 y 100, y
controla la pérdida
y la calidad durante la compresión. El valor 0 corresponde a
calidad y tamaños de salida pequeños, mientras que 100 es la calidad más alta
el tamaño de la salida.
Si se ejecuta de forma correcta, los bytes comprimidos se colocan en el archivo *output
.
puntero y se devuelve el tamaño en bytes (de lo contrario, se devuelve 0 en caso
de fallas). El llamador debe llamar a WebPFree()
en *output
puntero para recuperar memoria.
El array de entrada debe ser un array empaquetado de bytes (uno por cada canal,
esperado por el nombre de la función). stride
corresponde al
la cantidad de bytes necesarios para saltar de una fila a la siguiente. Por ejemplo:
El diseño de BGRA es:
Existen funciones equivalentes para la codificación sin pérdidas, con firmas:
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);
Ten en cuenta que estas funciones, como las versiones con pérdida, usan el valor predeterminado
configuración. Para los modelos con pérdida,
significa “exacto” está inhabilitada. Valores RGB en
las áreas transparentes
se modificarán para mejorar la compresión. Para evitar esto, usa
WebPEncode()
y establece WebPConfig::exact
en 1
.
API de Advanced Encoding
En niveles más profundos, el codificador cuenta con varios parámetros de codificación avanzados.
Pueden ser útiles para equilibrar mejor el equilibrio entre la compresión
la eficiencia y el tiempo de procesamiento.
Estos parámetros se recopilan dentro de la estructura WebPConfig
.
Los campos más usados de esta estructura son los siguientes:
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
};
Ten en cuenta que se puede acceder a la mayoría de estos parámetros para la experimentación
con la herramienta de línea de comandos de cwebp
Las muestras de entrada deben unirse en una estructura WebPPicture
.
Esta estructura puede almacenar muestras de entrada en formato RGBA o YUVA, según
en el valor de la marca use_argb
La estructura está organizada de la siguiente manera:
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;
};
Esta estructura también tiene una función para emitir los bytes comprimidos a medida que
de datos. Consulta a continuación un ejemplo con un escritor en la memoria.
Otros escritores pueden almacenar datos directamente en un archivo (consulta
examples/cwebp.c
para ese ejemplo).
El flujo general para codificar usando la API avanzada se parece al lo siguiente:
Primero, debemos establecer una configuración de codificación que contenga el parámetros de compresión. Ten en cuenta que puedes usar la misma configuración para comprimir varias imágenes diferentes después.
#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)
Luego, se debe hacer referencia a las muestras de entrada en un WebPPicture
.
por referencia o copia. Aquí hay un ejemplo de asignación del búfer para mantener
las muestras. pero se puede configurar fácilmente una "vista" a una dirección de correo electrónico
array de muestra. Consulta la función 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.
Para emitir los bytes comprimidos, se llama a un hook cada vez que se generan bytes nuevos
disponibles. Aquí hay un ejemplo sencillo con el escritor de memoria declarado en
webp/encode.h
Es probable que esta inicialización sea necesaria para
cada imagen a comprimir:
// Set up a byte-writing method (write-to-memory, in this case):
WebPMemoryWriter writer;
WebPMemoryWriterInit(&writer);
pic.writer = WebPMemoryWrite;
pic.custom_ptr = &writer;
Ahora estamos listos para comprimir las muestras de entrada (y, luego, liberar su memoria):
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);
}
Para un uso más avanzado de la API y la estructura, se recomienda buscar
en la documentación disponible en el encabezado webp/encode.h
.
Leer el código de ejemplo examples/cwebp.c
puede resultar útil
para descubrir parámetros menos usados.