39#include <config_auto.h>
42#include "allheaders.h"
47#include "webp/encode.h"
70pixaWriteWebPAnim(
const char *filename,
81 return ERROR_INT(
"filename not defined", __func__, 1);
83 return ERROR_INT(
"pixa not defined", __func__, 1);
85 if ((fp = fopenWriteStream(filename,
"wb+")) == NULL)
86 return ERROR_INT_1(
"stream not opened", filename, __func__, 1);
87 ret = pixaWriteStreamWebPAnim(fp, pixa, loopcount, duration,
91 return ERROR_INT_1(
"pixs not compressed to stream",
92 filename, __func__, 1);
116pixaWriteStreamWebPAnim(FILE *fp,
124size_t filebytes, nbytes;
127 return ERROR_INT(
"stream not open", __func__, 1);
129 return ERROR_INT(
"pixa not defined", __func__, 1);
132 pixaWriteMemWebPAnim(&filedata, &filebytes, pixa, loopcount,
133 duration, quality, lossless);
136 return ERROR_INT(
"filedata not made", __func__, 1);
137 nbytes = fwrite(filedata, 1, filebytes, fp);
139 if (nbytes != filebytes)
140 return ERROR_INT(
"Write error", __func__, 1);
163pixaWriteMemWebPAnim(l_uint8 **pencdata,
171l_int32 i, n, same, w, h, wpl, ret, ret_webp;
175WebPAnimEncoderOptions enc_options;
179WebPMuxAnimParams newparams;
183 return ERROR_INT(
"&encdata not defined", __func__, 1);
186 return ERROR_INT(
"&encsize not defined", __func__, 1);
189 return ERROR_INT(
"&pixa not defined", __func__, 1);
190 if ((n = pixaGetCount(pixa)) == 0)
191 return ERROR_INT(
"no images in pixa", __func__, 1);
192 if (loopcount < 0) loopcount = 0;
193 if (lossless == 0 && (quality < 0 || quality > 100))
194 return ERROR_INT(
"quality not in [0 ... 100]", __func__, 1);
196 pixaVerifyDimensions(pixa, &same, &w, &h);
198 return ERROR_INT(
"sizes of all pix are not the same", __func__, 1);
201 if (!WebPAnimEncoderOptionsInit(&enc_options))
202 return ERROR_INT(
"cannot initialize WebP encoder options", __func__, 1);
203 if (!WebPConfigInit(&config))
204 return ERROR_INT(
"cannot initialize WebP config", __func__, 1);
205 config.lossless = lossless;
206 config.quality = quality;
207 if ((enc = WebPAnimEncoderNew(w, h, &enc_options)) == NULL)
208 return ERROR_INT(
"cannot create WebP encoder", __func__, 1);
210 for (i = 0; i < n; i++) {
213 if (!WebPPictureInit(&frame)) {
214 WebPAnimEncoderDelete(enc);
215 return ERROR_INT(
"cannot initialize WebP picture", __func__, 1);
217 pix1 = pixaGetPix(pixa, i,
L_CLONE);
218 pix2 = pixConvertTo32(pix1);
220 pixEndianByteSwap(pix2);
221 data = (l_uint8 *)pixGetData(pix2);
222 wpl = pixGetWpl(pix2);
225 ret_webp = WebPPictureImportRGBA(&frame, data, 4 * wpl);
229 WebPAnimEncoderDelete(enc);
230 return ERROR_INT(
"cannot import RGBA picture", __func__, 1);
234 ret_webp = WebPAnimEncoderAdd(enc, &frame, duration * i, &config);
235 WebPPictureFree(&frame);
237 WebPAnimEncoderDelete(enc);
238 return ERROR_INT(
"cannot add frame to animation", __func__, 1);
242 if (!WebPAnimEncoderAdd(enc, NULL, duration * i, NULL)) {
243 WebPAnimEncoderDelete(enc);
244 return ERROR_INT(
"blank frame not added to animation", __func__, 1);
248 ret_webp = WebPAnimEncoderAssemble(enc, &webp_data);
249 WebPAnimEncoderDelete(enc);
251 return ERROR_INT(
"cannot assemble animation", __func__, 1);
260 mux = WebPMuxCreate(&webp_data, 1);
262 L_ERROR(
"could not re-mux to add loop count\n", __func__);
264 ret = WebPMuxGetAnimationParams(mux, &newparams);
265 if (ret != WEBP_MUX_OK) {
266 L_ERROR(
"failed to get loop count\n", __func__);
268 newparams.loop_count = loopcount;
269 ret = WebPMuxSetAnimationParams(mux, &newparams);
270 if (ret != WEBP_MUX_OK)
271 L_ERROR(
"failed to set loop count\n", __func__);
273 WebPDataClear(&webp_data);
274 if (WebPMuxAssemble(mux, &webp_data) != WEBP_MUX_OK)
275 L_ERROR(
"failed to assemble in the WebP muxer\n", __func__);
280 *pencdata = (l_uint8 *)webp_data.bytes;
281 *pencsize = webp_data.size;
282 L_INFO(
"data size = %zu\n", __func__, webp_data.size);