cwebp is a good example to study encoder part of libwebp. Here is a handy class to do the same job.
/*
Copyright (C) 2011, W.L. Chuang
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SimpleWebpEncoder.hh"
SimpleWebpEncoder::SimpleWebpEncoder(unsigned int width, unsigned int height) :
width(width), height(height)
{
WebPPictureInit(&picture);
picture.width = width;
picture.height = height;
WebPConfigInit(&config);
WebPConfigPreset(&config, WEBP_PRESET_PHOTO, 80);
}
SimpleWebpEncoder::~SimpleWebpEncoder()
{
WebPPictureFree(&picture);
}
struct _context
{
unsigned char* buffer;
unsigned int bufferWrote;
unsigned int bufferRemained;
};
static int writeWebP(const uint8_t* data, size_t data_size,
const WebPPicture* const picture);
int SimpleWebpEncoder::compress(void* video, unsigned char* bitstream,
unsigned int max, unsigned int* used)
{
struct _context context;
if (!WebPPictureImportRGB(&picture, (unsigned char*)video, 3 * width)) {
fprintf(stderr, "Failed to convert RGB to YCbCr\n");
return -1;
}
context.buffer = bitstream;
context.bufferWrote = 0;
context.bufferRemained = max;
picture.writer = writeWebP;
picture.custom_ptr = (void*)&context;
if (!WebPEncode(&config, &picture)) {
fprintf(stderr, "Error! Cannot encode picture as WebP\n");
return -1;
}
*used = context.bufferWrote;
return 0;
}
static int writeWebP(const uint8_t* data, size_t data_size,
const WebPPicture* const picture)
{
struct _context* context = (struct _context*)picture->custom_ptr;
if (data_size > context->bufferRemained) {
fprintf(stderr, "Error! Bytestream buffer overflow\n");
return 0;
}
memcpy(&context->buffer[context->bufferWrote], data, data_size);
context->bufferWrote += data_size;
return 1;
}
No comments:
Post a Comment