Leptonica  1.82.0
Image processing and image analysis suite
webpanimio.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
38 #ifdef HAVE_CONFIG_H
39 #include <config_auto.h>
40 #endif /* HAVE_CONFIG_H */
41 
42 #include "allheaders.h"
43 
44 /* -----------------------------------------------*/
45 #if HAVE_LIBWEBP_ANIM /* defined in environ.h */
46 /* -----------------------------------------------*/
47 #include "webp/decode.h"
48 #include "webp/encode.h"
49 #include "webp/mux.h"
50 #include "webp/demux.h"
51 
52 /*---------------------------------------------------------------------*
53  * Writing animated WebP *
54  *---------------------------------------------------------------------*/
71 l_ok
72 pixaWriteWebPAnim(const char *filename,
73  PIXA *pixa,
74  l_int32 loopcount,
75  l_int32 duration,
76  l_int32 quality,
77  l_int32 lossless)
78 {
79 l_int32 ret;
80 FILE *fp;
81 
82  PROCNAME("pixaWriteWebPAnim");
83 
84  if (!filename)
85  return ERROR_INT("filename not defined", procName, 1);
86  if (!pixa)
87  return ERROR_INT("pixa not defined", procName, 1);
88 
89  if ((fp = fopenWriteStream(filename, "wb+")) == NULL)
90  return ERROR_INT("stream not opened", procName, 1);
91  ret = pixaWriteStreamWebPAnim(fp, pixa, loopcount, duration,
92  quality, lossless);
93  fclose(fp);
94  if (ret)
95  return ERROR_INT("pixs not compressed to stream", procName, 1);
96  return 0;
97 }
98 
99 
118 l_ok
119 pixaWriteStreamWebPAnim(FILE *fp,
120  PIXA *pixa,
121  l_int32 loopcount,
122  l_int32 duration,
123  l_int32 quality,
124  l_int32 lossless)
125 {
126 l_uint8 *filedata;
127 size_t filebytes, nbytes;
128 
129  PROCNAME("pixaWriteStreamWebpAnim");
130 
131  if (!fp)
132  return ERROR_INT("stream not open", procName, 1);
133  if (!pixa)
134  return ERROR_INT("pixa not defined", procName, 1);
135 
136  filedata = NULL;
137  pixaWriteMemWebPAnim(&filedata, &filebytes, pixa, loopcount,
138  duration, quality, lossless);
139  rewind(fp);
140  if (!filedata)
141  return ERROR_INT("filedata not made", procName, 1);
142  nbytes = fwrite(filedata, 1, filebytes, fp);
143  free(filedata);
144  if (nbytes != filebytes)
145  return ERROR_INT("Write error", procName, 1);
146  return 0;
147 }
148 
149 
167 l_ok
168 pixaWriteMemWebPAnim(l_uint8 **pencdata,
169  size_t *pencsize,
170  PIXA *pixa,
171  l_int32 loopcount,
172  l_int32 duration,
173  l_int32 quality,
174  l_int32 lossless)
175 {
176 l_int32 i, n, same, w, h, wpl, ret;
177 l_uint8 *data;
178 PIX *pix1, *pix2;
179 WebPAnimEncoder *enc;
180 WebPAnimEncoderOptions enc_options;
181 WebPConfig config;
182 WebPData webp_data;
183 WebPMux *mux = NULL;
184 WebPMuxAnimParams newparams;
185 WebPPicture frame;
186 
187  PROCNAME("pixaWriteMemWebPAnim");
188 
189  if (!pencdata)
190  return ERROR_INT("&encdata not defined", procName, 1);
191  *pencdata = NULL;
192  if (!pencsize)
193  return ERROR_INT("&encsize not defined", procName, 1);
194  *pencsize = 0;
195  if (!pixa)
196  return ERROR_INT("&pixa not defined", procName, 1);
197  if ((n = pixaGetCount(pixa)) == 0)
198  return ERROR_INT("no images in pixa", procName, 1);
199  if (loopcount < 0) loopcount = 0;
200  if (lossless == 0 && (quality < 0 || quality > 100))
201  return ERROR_INT("quality not in [0 ... 100]", procName, 1);
202 
203  pixaVerifyDimensions(pixa, &same, &w, &h);
204  if (!same)
205  return ERROR_INT("sizes of all pix are not the same", procName, 1);
206 
207  /* Set up the encoder */
208  WebPAnimEncoderOptionsInit(&enc_options);
209  enc = WebPAnimEncoderNew(w, h, &enc_options);
210 
211  for (i = 0; i < n; i++) {
212  /* Make a frame for each image. Convert the pix to RGBA with
213  * an opaque alpha layer, and put the raster data in the frame. */
214  pix1 = pixaGetPix(pixa, i, L_CLONE);
215  pix2 = pixConvertTo32(pix1);
217  pixEndianByteSwap(pix2);
218  data = (l_uint8 *)pixGetData(pix2);
219  wpl = pixGetWpl(pix2);
220  WebPPictureInit(&frame);
221  frame.width = w;
222  frame.height = h;
223  WebPPictureImportRGBA(&frame, data, 4 * wpl);
224  pixDestroy(&pix1);
225  pixDestroy(&pix2);
226 
227  /* Add the frame data to the encoder, and clear its memory */
228  WebPConfigInit(&config);
229  config.lossless = lossless;
230  config.quality = quality;
231  WebPAnimEncoderAdd(enc, &frame, duration * i, &config);
232  WebPPictureFree(&frame);
233  }
234  WebPAnimEncoderAdd(enc, NULL, duration * i, NULL); /* add a blank frame */
235  WebPAnimEncoderAssemble(enc, &webp_data); /* encode the data */
236  WebPAnimEncoderDelete(enc);
237 
238  /* Set the loopcount if requested. Note that when you make a mux,
239  * it imports the webp_data that was previously made, including
240  * the webp encoded images. Before you re-export that data using
241  * WebPMuxAssemble(), free the heap data in webp_data. There is an
242  * example for setting the loop count in the webp distribution;
243  * see gif2webp.c. */
244  if (loopcount > 0) {
245  mux = WebPMuxCreate(&webp_data, 1);
246  if (!mux) {
247  L_ERROR("could not re-mux to add loop count\n", procName);
248  } else {
249  ret = WebPMuxGetAnimationParams(mux, &newparams);
250  if (ret != WEBP_MUX_OK) {
251  L_ERROR("failed to get loop count\n", procName);
252  } else {
253  newparams.loop_count = loopcount;
254  ret = WebPMuxSetAnimationParams(mux, &newparams);
255  if (ret != WEBP_MUX_OK)
256  L_ERROR("failed to set loop count\n", procName);
257  }
258  WebPDataClear(&webp_data);
259  WebPMuxAssemble(mux, &webp_data);
260  WebPMuxDelete(mux);
261  }
262  }
263 
264  *pencdata = (l_uint8 *)webp_data.bytes;
265  *pencsize = webp_data.size;
266  L_INFO("data size = %zu\n", procName, webp_data.size);
267  return 0;
268 }
269 
270 
271 /* --------------------------------------------*/
272 #endif /* HAVE_LIBWEBP_ANIM */
273 /* --------------------------------------------*/
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
l_ok pixSetComponentArbitrary(PIX *pix, l_int32 comp, l_int32 val)
pixSetComponentArbitrary()
Definition: pix2.c:1068
Definition: pix.h:713
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition: pix2.c:3074
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
Definition: pix.h:455
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
l_ok pixaVerifyDimensions(PIXA *pixa, l_int32 *psame, l_int32 *pmaxw, l_int32 *pmaxh)
pixaVerifyDimensions()
Definition: pixabasic.c:1006
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
Definition: pix.h:138
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650