Phần này mô tả API cho bộ mã hoá và bộ giải mã đi kèm trong thư viện WebP. Nội dung mô tả API này liên quan đến phiên bản 1.4.0.
Tiêu đề và thư viện
Khi bạn cài đặt libwebp
, một thư mục có tên là webp/
sẽ được cài đặt tại vị trí thông thường dành cho nền tảng của bạn. Ví dụ: bật
nền tảng Unix, tệp tiêu đề sau đây sẽ được sao chép vào
/usr/local/include/webp/
.
decode.h
encode.h
types.h
Các thư viện này nằm trong các thư mục thư viện thông thường. Phương thức tĩnh và
thư viện động nằm trong /usr/local/lib/
trên các nền tảng Unix.
API giải mã đơn giản
Để bắt đầu sử dụng API giải mã, bạn phải đảm bảo rằng bạn có các tệp thư viện và tiêu đề được cài đặt như được mô tả ở trên.
Đưa tiêu đề API giải mã vào mã C/C++ của bạn như sau:
#include "webp/decode.h"
int WebPGetInfo(const uint8_t* data, size_t data_size, int* width, int* height);
Hàm này sẽ xác thực tiêu đề hình ảnh WebP và truy xuất chiều rộng của hình ảnh
và chiều cao. Con trỏ *width
và *height
có thể được truyền NULL
nếu được coi là
không liên quan.
Thuộc tính phương thức nhập
- dữ liệu
- Con trỏ sang dữ liệu hình ảnh WebP
- kích_ thước_dữ_liệu
- Đây là kích thước của khối bộ nhớ mà
data
trỏ đến có chứa dữ liệu hình ảnh.
Giá trị trả về
- false
- Mã lỗi được trả về trong trường hợp (a) lỗi định dạng.
- đúng
- Khi thành công.
*width
và*height
chỉ hợp lệ khi trả về thành công. - chiều rộng
- Giá trị số nguyên. Phạm vi được giới hạn từ 1 đến 16383.
- độ cao
- Giá trị số nguyên. Phạm vi được giới hạn từ 1 đến 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);
Hàm này sẽ truy xuất các đối tượng từ luồng bit. *features
cấu trúc chứa thông tin thu thập được từ luồng bit:
Thuộc tính phương thức nhập
- dữ liệu
- Con trỏ sang dữ liệu hình ảnh WebP
- kích_ thước_dữ_liệu
- Đây là kích thước của khối bộ nhớ mà
data
trỏ đến có chứa dữ liệu hình ảnh.
Giá trị trả về
VP8_STATUS_OK
- Trường hợp các tính năng được truy xuất thành công.
VP8_STATUS_NOT_ENOUGH_DATA
- Khi cần thêm dữ liệu để truy xuất các tính năng từ tiêu đề.
Các giá trị lỗi VP8StatusCode
bổ sung trong các trường hợp khác.
- tính năng
- Con trỏ đến cấu trúc 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);
Các hàm này giải mã hình ảnh WebP được trỏ đến bằng data
.
WebPDecodeRGBA
trả về các mẫu hình ảnh RGBA theo thứ tự[r0, g0, b0, a0, r1, g1, b1, a1, ...]
.WebPDecodeARGB
trả về các mẫu hình ảnh ARGB theo thứ tự[a0, r0, g0, b0, a1, r1, g1, b1, ...]
.WebPDecodeBGRA
trả về các mẫu hình ảnh BGRA theo thứ tự[b0, g0, r0, a0, b1, g1, r1, a1, ...]
.WebPDecodeRGB
trả về các mẫu hình ảnh RGB theo thứ tự[r0, g0, b0, r1, g1, b1, ...]
.WebPDecodeBGR
trả về các mẫu hình ảnh BGR theo thứ tự[b0, g0, r0, b1, g1, r1, ...]
.
Mã gọi bất kỳ hàm nào trong số này phải xoá vùng đệm dữ liệu
(uint8_t*)
được các hàm này trả về bằng WebPFree()
.
Thuộc tính phương thức nhập
- dữ liệu
- Con trỏ sang dữ liệu hình ảnh WebP
- kích_ thước_dữ_liệu
- Đây là kích thước của khối bộ nhớ mà
data
trỏ đến có chứa dữ liệu hình ảnh - chiều rộng
- Giá trị số nguyên. Phạm vi hiện được giới hạn từ 1 đến 16383.
- độ cao
- Giá trị số nguyên. Phạm vi hiện bị giới hạn từ 1 đến 16383.
Giá trị trả về
- uint8_t*
- Con trỏ để giải mã các mẫu hình ảnh WebP ở định dạng RGBA/ARGB/BGRA/RGB/BGR tuyến tính đơn đặt hàng tương ứng.
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);
Các hàm này là biến thể của các hàm trên và giải mã hình ảnh trực tiếp
vào vùng đệm phân bổ trước output_buffer
. Dung lượng lưu trữ tối đa có sẵn trong
vùng đệm này được biểu thị bằng output_buffer_size
. Nếu bộ nhớ này chưa
đủ (hoặc đã xảy ra lỗi), NULL
được trả về. Nếu không,
output_buffer
được trả về để thuận tiện.
Tham số output_stride
chỉ định khoảng cách (tính bằng byte) giữa
đường quét. Do đó, output_buffer_size
dự kiến sẽ có giá trị tối thiểu
output_stride * picture - height
Thuộc tính phương thức nhập
- dữ liệu
- Con trỏ sang dữ liệu hình ảnh WebP
- kích_ thước_dữ_liệu
- Đây là kích thước của khối bộ nhớ mà
data
trỏ đến có chứa dữ liệu hình ảnh - output_buffer_size
- Giá trị số nguyên. Kích thước của vùng đệm phân bổ
- output_stride
- Giá trị số nguyên. Chỉ định khoảng cách giữa các dòng quét.
Giá trị trả về
- output_buffer
- Con trỏ để giải mã hình ảnh WebP.
- uint8_t*
output_buffer
nếu hàm thành công;NULL
.
API Giải mã nâng cao
Giải mã WebP hỗ trợ một API nâng cao để mang lại khả năng truy cập dữ liệu một cách nhanh chóng cắt và thay đổi kích thước, một tính năng rất hữu ích khi bị giới hạn về bộ nhớ như điện thoại di động. Về cơ bản, mức sử dụng bộ nhớ sẽ tăng với kích thước của đầu ra chứ không phải của đầu vào khi người dùng chỉ cần xem trước nhanh hoặc phóng to một phần của hình ảnh quá lớn. Có thể tiết kiệm được một số CPU vô tình.
Giải mã WebP có hai biến thể, đó là giải mã hình ảnh đầy đủ và giải mã gia tăng giải mã qua các vùng đệm đầu vào nhỏ. Người dùng có thể tuỳ ý cung cấp vùng đệm bộ nhớ để giải mã hình ảnh. Mã mẫu sau đây sẽ giúp bạn tìm hiểu các bước sử dụng API giải mã nâng cao.
Trước tiên, chúng ta cần khởi chạy một đối tượng cấu hình:
#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.
Các tuỳ chọn giải mã được tập hợp trong WebPDecoderConfig
cấu trúc:
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]
};
Nếu muốn, bạn có thể đọc các tính năng luồng bit vào config.input
,
phòng khi chúng tôi cần biết trước. Chẳng hạn như việc biết được thông tin này có thể giúp ích cho bạn
liệu bức ảnh có chút trong suốt nào không. Xin lưu ý rằng việc này sẽ
cũng phân tích cú pháp tiêu đề của luồng bit và do đó, là một cách hay để biết
nếu luồng bit có vẻ giống WebP hợp lệ.
CHECK(WebPGetFeatures(data, data_size, &config.input) == VP8_STATUS_OK);
Sau đó, chúng ta cần thiết lập vùng đệm bộ nhớ giải mã trong trường hợp muốn cung cấp vùng đệm đó thay vì dựa vào bộ giải mã để phân bổ. Chúng tôi chỉ cần cung cấp con trỏ cho bộ nhớ cũng như tổng dung lượng của vùng đệm và sải chân của dòng (khoảng cách tính bằng byte giữa các đường quét).
// 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;
Hình ảnh đã sẵn sàng để được giải mã. Có thể có hai biến thể để giải mã hình ảnh. Chúng tôi có thể giải mã hình ảnh một lần bằng cách sử dụng:
CHECK(WebPDecode(data, data_size, &config) == VP8_STATUS_OK);
Ngoài ra, chúng ta có thể sử dụng phương thức gia tăng để giải mã dần dần hình ảnh khi các byte mới trở nên khả dụng:
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.
Hình ảnh đã giải mã hiện nằm trong config.output (hoặc đúng hơn là trong config.output.u.RGBA trong trường hợp này, vì hệ màu đầu ra được yêu cầu là MODE_BGRA). Hình ảnh có thể được lưu, hiển thị hoặc xử lý theo cách khác. Sau đó, chúng ta chỉ cần lấy lại bộ nhớ được phân bổ trong đối tượng của cấu hình. An toàn khi gọi hàm này ngay cả khi bộ nhớ nằm ngoài và không được phân bổ theo WebPDecode():
WebPFreeDecBuffer(&config.output);
Sử dụng API này, hình ảnh cũng có thể được giải mã thành các định dạng YUV và YUVA bằng cách sử dụng
MODE_YUV
và MODE_YUVA
tương ứng. Định dạng này còn được gọi là
Y'CbCr.
API mã hoá đơn giản
Một số hàm rất đơn giản được cung cấp để mã hoá các mảng của mẫu RGBA
trong hầu hết các bố cục phổ biến. Các lớp này được khai báo trong webp/encode.h
tiêu đề dưới dạng:
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);
Hệ số chất lượng quality_factor
nằm trong khoảng từ 0 đến 100 và
kiểm soát tổn thất và chất lượng trong quá trình nén. Giá trị 0 tương ứng với giá trị thấp
có chất lượng và kích thước đầu ra nhỏ, trong khi 100 là mức chất lượng cao nhất và lớn nhất
kích thước đầu ra.
Sau khi thành công, các byte được nén sẽ được đặt vào *output
con trỏ và kích thước tính bằng byte được trả về (nếu không thì trả về 0 trong trường hợp
không thành công). Phương thức gọi phải gọi WebPFree()
trên *output
con trỏ để lấy lại bộ nhớ.
Mảng đầu vào phải là một mảng byte đóng gói (một mảng cho mỗi kênh, như
được mong đợi từ tên hàm). stride
tương ứng với
số byte cần thiết để chuyển từ hàng này sang hàng tiếp theo. Ví dụ:
Bố cục BGRA là:
Có các hàm tương đương để mã hoá không tổn hao, với các chữ ký:
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);
Lưu ý rằng các hàm này (chẳng hạn như các phiên bản có tổn hao) hãy dùng chế độ mặc định của thư viện
phần cài đặt. Đối với định dạng không tổn hao, giá trị này có nghĩa là "chính xác" đã bị tắt. Các giá trị RGB trong
những vùng trong suốt sẽ được sửa đổi để cải thiện độ nén. Để tránh điều này, hãy sử dụng
WebPEncode()
rồi đặt WebPConfig::exact
thành 1
.
API mã hoá nâng cao
nâng cao, bộ mã hoá đi kèm với nhiều tham số mã hoá nâng cao.
Chúng có thể hữu ích để cân bằng tốt hơn sự đánh đổi giữa nén
hiệu quả và thời gian xử lý.
Các tham số này được thu thập trong cấu trúc WebPConfig
.
Các trường được sử dụng nhiều nhất của cấu trúc này là:
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
};
Lưu ý rằng bạn có thể truy cập hầu hết các tham số này để thử nghiệm
bằng công cụ dòng lệnh cwebp
.
Các mẫu đầu vào phải được gói vào cấu trúc WebPPicture
.
Cấu trúc này có thể lưu trữ các mẫu đầu vào ở định dạng RGBA hoặc YUVA, tuỳ thuộc vào
dựa trên giá trị của cờ use_argb
.
Cấu trúc này được sắp xếp như sau:
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;
};
Cấu trúc này cũng có chức năng phát các byte nén khi chúng
được cung cấp. Hãy xem ví dụ dưới đây về một người viết trong bộ nhớ.
Những người viết khác có thể trực tiếp lưu trữ dữ liệu vào một tệp (xem
examples/cwebp.c
cho ví dụ như vậy).
Quy trình mã hoá chung để mã hoá bằng API nâng cao có dạng như sau:
Trước tiên, chúng ta cần thiết lập một cấu hình mã hoá chứa tham số nén. Lưu ý rằng bạn có thể sử dụng cùng một cấu hình để nén một số hình ảnh sau đó.
#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)
Sau đó, các mẫu đầu vào cần được tham chiếu vào WebPPicture
bằng cách tham khảo hoặc sao chép. Sau đây là ví dụ về việc phân bổ vùng đệm để lưu giữ
các mẫu. Nhưng người dùng có thể dễ dàng thiết lập một "chế độ xem" cho một mục tiêu đã phân bổ
mảng mẫu. Hãy xem hàm 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.
Để chuyển phát các byte được nén, một hook sẽ được gọi mỗi khi các byte mới được
sẵn có. Sau đây là một ví dụ đơn giản, trong đó tác giả của bộ nhớ được khai báo trong
webp/encode.h
. Khởi chạy này có thể cần cho
từng ảnh cần nén:
// Set up a byte-writing method (write-to-memory, in this case):
WebPMemoryWriter writer;
WebPMemoryWriterInit(&writer);
pic.writer = WebPMemoryWrite;
pic.custom_ptr = &writer;
Chúng ta hiện đã sẵn sàng nén các mẫu đầu vào (và giải phóng bộ nhớ sau đó):
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);
}
Để sử dụng API và cấu trúc nâng cao hơn, bạn nên xem
tại tài liệu có trong tiêu đề webp/encode.h
.
Việc đọc mã ví dụ examples/cwebp.c
có thể hữu ích
để khám phá các tham số ít được sử dụng hơn.