FFmpeg
lcldec.c
Go to the documentation of this file.
1 /*
2  * LCL (LossLess Codec Library) Codec
3  * Copyright (c) 2002-2004 Roberto Togni
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * LCL (LossLess Codec Library) Video Codec
25  * Decoder for MSZH and ZLIB codecs
26  * Experimental encoder for ZLIB RGB24
27  *
28  * Fourcc: MSZH, ZLIB
29  *
30  * Original Win32 dll:
31  * Ver2.23 By Kenji Oshima 2000.09.20
32  * avimszh.dll, avizlib.dll
33  *
34  * A description of the decoding algorithm can be found here:
35  * http://www.pcisys.net/~melanson/codecs
36  *
37  * Supports: BGR24 (RGB 24bpp)
38  */
39 
40 #include "config_components.h"
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 
45 #include "libavutil/mem.h"
46 #include "libavutil/pixdesc.h"
47 #include "avcodec.h"
48 #include "bytestream.h"
49 #include "codec_internal.h"
50 #include "lcl.h"
51 #include "thread.h"
52 
53 #if CONFIG_ZLIB_DECODER
54 #include "zlib_wrapper.h"
55 #include <zlib.h>
56 #endif
57 
58 typedef struct LclDecContext {
59  // Image type
60  int imgtype;
61  // Compression type
63  // Flags
64  int flags;
65  // Decompressed data size
66  unsigned int decomp_size;
67  // Decompression buffer
68  unsigned char* decomp_buf;
69 #if CONFIG_ZLIB_DECODER
70  FFZStream zstream;
71 #endif
73 
74 
75 /**
76  * @param srcptr compressed source buffer, must be padded with at least 5 extra bytes
77  * @param destptr must be padded sufficiently for av_memcpy_backptr
78  */
79 static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
80 {
81  unsigned char *destptr_bak = destptr;
82  unsigned char *destptr_end = destptr + destsize;
83  const unsigned char *srcptr_end = srcptr + srclen;
84  unsigned mask = *srcptr++;
85  unsigned maskbit = 0x80;
86 
87  while (srcptr < srcptr_end && destptr < destptr_end) {
88  if (!(mask & maskbit)) {
89  memcpy(destptr, srcptr, 4);
90  destptr += 4;
91  srcptr += 4;
92  } else {
93  unsigned ofs = bytestream_get_le16(&srcptr);
94  unsigned cnt = (ofs >> 11) + 1;
95  ofs &= 0x7ff;
96  ofs = FFMIN(ofs, destptr - destptr_bak);
97  cnt *= 4;
98  cnt = FFMIN(cnt, destptr_end - destptr);
99  if (ofs) {
100  av_memcpy_backptr(destptr, ofs, cnt);
101  } else {
102  // Not known what the correct behaviour is, but
103  // this at least avoids uninitialized data.
104  memset(destptr, 0, cnt);
105  }
106  destptr += cnt;
107  }
108  maskbit >>= 1;
109  if (!maskbit) {
110  mask = *srcptr++;
111  while (!mask) {
112  if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break;
113  memcpy(destptr, srcptr, 32);
114  destptr += 32;
115  srcptr += 32;
116  mask = *srcptr++;
117  }
118  maskbit = 0x80;
119  }
120  }
121 
122  return destptr - destptr_bak;
123 }
124 
125 
126 #if CONFIG_ZLIB_DECODER
127 /**
128  * @brief decompress a zlib-compressed data block into decomp_buf
129  * @param src compressed input buffer
130  * @param src_len data length in input buffer
131  * @param offset offset in decomp_buf
132  * @param expected expected decompressed length
133  */
134 static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected)
135 {
136  LclDecContext *c = avctx->priv_data;
137  z_stream *const zstream = &c->zstream.zstream;
138  int zret = inflateReset(zstream);
139  if (zret != Z_OK) {
140  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
141  return AVERROR_UNKNOWN;
142  }
143  zstream->next_in = src;
144  zstream->avail_in = src_len;
145  zstream->next_out = c->decomp_buf + offset;
146  zstream->avail_out = c->decomp_size - offset;
147  zret = inflate(zstream, Z_FINISH);
148  if (zret != Z_OK && zret != Z_STREAM_END) {
149  av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
150  return AVERROR_UNKNOWN;
151  }
152  if (expected != (unsigned int)zstream->total_out) {
153  av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
154  expected, zstream->total_out);
155  return AVERROR_UNKNOWN;
156  }
157  return zstream->total_out;
158 }
159 #endif
160 
161 
163  int *got_frame, AVPacket *avpkt)
164 {
165  const uint8_t *buf = avpkt->data;
166  int buf_size = avpkt->size;
167  LclDecContext * const c = avctx->priv_data;
168  unsigned int pixel_ptr;
169  int row, col;
170  unsigned char *encoded = avpkt->data, *outptr;
171  uint8_t *y_out, *u_out, *v_out;
172  unsigned int width = avctx->width; // Real image width
173  unsigned int height = avctx->height; // Real image height
174  unsigned int mszh_dlen;
175  unsigned char yq, y1q, uq, vq;
176  int uqvq, ret;
177  unsigned int mthread_inlen, mthread_outlen;
178  unsigned int len = buf_size;
179  int linesize, offset;
180 
181  if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
182  return ret;
183 
184  outptr = frame->data[0]; // Output image pointer
185 
186  /* Decompress frame */
187  switch (avctx->codec_id) {
188  case AV_CODEC_ID_MSZH:
189  switch (c->compression) {
190  case COMP_MSZH:
191  if (c->imgtype == IMGTYPE_RGB24 && len == FFALIGN(width * 3, 4) * height ||
192  c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) {
193  ;
194  } else if (c->flags & FLAG_MULTITHREAD) {
195  mthread_inlen = AV_RL32(buf);
196  if (len < 8 || len - 8 < mthread_inlen) {
197  av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
198  return AVERROR_INVALIDDATA;
199  }
200  mthread_outlen = AV_RL32(buf + 4);
201  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
202  mszh_dlen = mszh_decomp(buf + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
203  if (mthread_outlen != mszh_dlen) {
204  av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
205  mthread_outlen, mszh_dlen);
206  return AVERROR_INVALIDDATA;
207  }
208  mszh_dlen = mszh_decomp(buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
209  c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
210  if (mthread_outlen != mszh_dlen) {
211  av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
212  mthread_outlen, mszh_dlen);
213  return AVERROR_INVALIDDATA;
214  }
215  encoded = c->decomp_buf;
216  len = c->decomp_size;
217  } else {
218  mszh_dlen = mszh_decomp(buf, len, c->decomp_buf, c->decomp_size);
219  if (c->decomp_size != mszh_dlen) {
220  av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
221  c->decomp_size, mszh_dlen);
222  return AVERROR_INVALIDDATA;
223  }
224  encoded = c->decomp_buf;
225  len = mszh_dlen;
226  }
227  break;
228  case COMP_MSZH_NOCOMP: {
229  int bppx2;
230  switch (c->imgtype) {
231  case IMGTYPE_YUV111:
232  case IMGTYPE_RGB24:
233  bppx2 = 6;
234  break;
235  case IMGTYPE_YUV422:
236  case IMGTYPE_YUV211:
237  bppx2 = 4;
238  break;
239  case IMGTYPE_YUV411:
240  case IMGTYPE_YUV420:
241  bppx2 = 3;
242  break;
243  default:
244  bppx2 = 0; // will error out below
245  break;
246  }
247  if (len < ((width * height * bppx2) >> 1))
248  return AVERROR_INVALIDDATA;
249  break;
250  }
251  default:
252  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
253  return AVERROR_INVALIDDATA;
254  }
255  break;
256 #if CONFIG_ZLIB_DECODER
257  case AV_CODEC_ID_ZLIB:
258  /* Using the original dll with normal compression (-1) and RGB format
259  * gives a file with ZLIB fourcc, but frame is really uncompressed.
260  * To be sure that's true check also frame size */
261  if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 &&
262  len == width * height * 3) {
263  if (c->flags & FLAG_PNGFILTER) {
264  memcpy(c->decomp_buf, buf, len);
265  encoded = c->decomp_buf;
266  } else {
267  break;
268  }
269  } else if (c->flags & FLAG_MULTITHREAD) {
270  mthread_inlen = AV_RL32(buf);
271  mthread_inlen = FFMIN(mthread_inlen, len - 8);
272  mthread_outlen = AV_RL32(buf + 4);
273  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
274  ret = zlib_decomp(avctx, buf + 8, mthread_inlen, 0, mthread_outlen);
275  if (ret < 0) return ret;
276  ret = zlib_decomp(avctx, buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
277  mthread_outlen, mthread_outlen);
278  if (ret < 0) return ret;
279  } else {
280  int ret = zlib_decomp(avctx, buf, len, 0, c->decomp_size);
281  if (ret < 0) return ret;
282  }
283  encoded = c->decomp_buf;
284  len = c->decomp_size;
285  break;
286 #endif
287  default:
288  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
289  return AVERROR_INVALIDDATA;
290  }
291 
292 
293  /* Apply PNG filter */
294  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) {
295  switch (c->imgtype) {
296  case IMGTYPE_YUV111:
297  case IMGTYPE_RGB24:
298  for (row = 0; row < height; row++) {
299  pixel_ptr = row * width * 3;
300  yq = encoded[pixel_ptr++];
301  uqvq = AV_RL16(encoded+pixel_ptr);
302  pixel_ptr += 2;
303  for (col = 1; col < width; col++) {
304  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
305  uqvq -= AV_RL16(encoded+pixel_ptr+1);
306  AV_WL16(encoded+pixel_ptr+1, uqvq);
307  pixel_ptr += 3;
308  }
309  }
310  break;
311  case IMGTYPE_YUV422:
312  for (row = 0; row < height; row++) {
313  pixel_ptr = row * width * 2;
314  yq = uq = vq =0;
315  for (col = 0; col < width/4; col++) {
316  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
317  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
318  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
319  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
320  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
321  encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5];
322  encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6];
323  encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7];
324  pixel_ptr += 8;
325  }
326  }
327  break;
328  case IMGTYPE_YUV411:
329  for (row = 0; row < height; row++) {
330  pixel_ptr = row * width / 2 * 3;
331  yq = uq = vq =0;
332  for (col = 0; col < width/4; col++) {
333  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
334  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
335  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
336  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
337  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
338  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
339  pixel_ptr += 6;
340  }
341  }
342  break;
343  case IMGTYPE_YUV211:
344  for (row = 0; row < height; row++) {
345  pixel_ptr = row * width * 2;
346  yq = uq = vq =0;
347  for (col = 0; col < width/2; col++) {
348  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
349  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
350  encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2];
351  encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3];
352  pixel_ptr += 4;
353  }
354  }
355  break;
356  case IMGTYPE_YUV420:
357  for (row = 0; row < height/2; row++) {
358  pixel_ptr = row * width * 3;
359  yq = y1q = uq = vq =0;
360  for (col = 0; col < width/2; col++) {
361  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
362  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
363  encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2];
364  encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3];
365  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
366  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
367  pixel_ptr += 6;
368  }
369  }
370  break;
371  default:
372  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
373  return AVERROR_INVALIDDATA;
374  }
375  }
376 
377  /* Convert colorspace */
378  y_out = frame->data[0] + (height - 1) * frame->linesize[0];
379  offset = (height - 1) * frame->linesize[1];
380  u_out = FF_PTR_ADD(frame->data[1], offset);
381  offset = (height - 1) * frame->linesize[2];
382  v_out = FF_PTR_ADD(frame->data[2], offset);
383  switch (c->imgtype) {
384  case IMGTYPE_YUV111:
385  for (row = 0; row < height; row++) {
386  for (col = 0; col < width; col++) {
387  y_out[col] = *encoded++;
388  u_out[col] = *encoded++ + 128;
389  v_out[col] = *encoded++ + 128;
390  }
391  y_out -= frame->linesize[0];
392  u_out -= frame->linesize[1];
393  v_out -= frame->linesize[2];
394  }
395  break;
396  case IMGTYPE_YUV422:
397  for (row = 0; row < height; row++) {
398  for (col = 0; col < width - 3; col += 4) {
399  memcpy(y_out + col, encoded, 4);
400  encoded += 4;
401  u_out[ col >> 1 ] = *encoded++ + 128;
402  u_out[(col >> 1) + 1] = *encoded++ + 128;
403  v_out[ col >> 1 ] = *encoded++ + 128;
404  v_out[(col >> 1) + 1] = *encoded++ + 128;
405  }
406  y_out -= frame->linesize[0];
407  u_out -= frame->linesize[1];
408  v_out -= frame->linesize[2];
409  }
410  break;
411  case IMGTYPE_RGB24:
412  linesize = len < FFALIGN(3 * width, 4) * height ? 3 * width : FFALIGN(3 * width, 4);
413  for (row = height - 1; row >= 0; row--) {
414  pixel_ptr = row * frame->linesize[0];
415  memcpy(outptr + pixel_ptr, encoded, 3 * width);
416  encoded += linesize;
417  }
418  break;
419  case IMGTYPE_YUV411:
420  for (row = 0; row < height; row++) {
421  for (col = 0; col < width - 3; col += 4) {
422  memcpy(y_out + col, encoded, 4);
423  encoded += 4;
424  u_out[col >> 2] = *encoded++ + 128;
425  v_out[col >> 2] = *encoded++ + 128;
426  }
427  y_out -= frame->linesize[0];
428  u_out -= frame->linesize[1];
429  v_out -= frame->linesize[2];
430  }
431  break;
432  case IMGTYPE_YUV211:
433  for (row = 0; row < height; row++) {
434  for (col = 0; col < width - 1; col += 2) {
435  memcpy(y_out + col, encoded, 2);
436  encoded += 2;
437  u_out[col >> 1] = *encoded++ + 128;
438  v_out[col >> 1] = *encoded++ + 128;
439  }
440  y_out -= frame->linesize[0];
441  u_out -= frame->linesize[1];
442  v_out -= frame->linesize[2];
443  }
444  break;
445  case IMGTYPE_YUV420:
446  u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
447  v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
448  for (row = 0; row < height - 1; row += 2) {
449  for (col = 0; col < width - 1; col += 2) {
450  memcpy(y_out + col, encoded, 2);
451  encoded += 2;
452  memcpy(y_out + col - frame->linesize[0], encoded, 2);
453  encoded += 2;
454  u_out[col >> 1] = *encoded++ + 128;
455  v_out[col >> 1] = *encoded++ + 128;
456  }
457  y_out -= frame->linesize[0] << 1;
458  u_out -= frame->linesize[1];
459  v_out -= frame->linesize[2];
460  }
461  break;
462  default:
463  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
464  return AVERROR_INVALIDDATA;
465  }
466 
467  frame->key_frame = 1;
468  frame->pict_type = AV_PICTURE_TYPE_I;
469 
470  *got_frame = 1;
471 
472  /* always report that the buffer was completely consumed */
473  return buf_size;
474 }
475 
477 {
478  LclDecContext * const c = avctx->priv_data;
479  unsigned int basesize = avctx->width * avctx->height;
480  unsigned int max_basesize = FFALIGN(avctx->width, 4) *
481  FFALIGN(avctx->height, 4);
482  unsigned int max_decomp_size;
483  int subsample_h, subsample_v;
484 
485  if (avctx->extradata_size < 8) {
486  av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
487  return AVERROR_INVALIDDATA;
488  }
489 
490  /* Check codec type */
491  if ((avctx->codec_id == AV_CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) ||
492  (avctx->codec_id == AV_CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) {
493  av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
494  }
495 
496  /* Detect image type */
497  switch (c->imgtype = avctx->extradata[4]) {
498  case IMGTYPE_YUV111:
499  c->decomp_size = basesize * 3;
500  max_decomp_size = max_basesize * 3;
501  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
502  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n");
503  break;
504  case IMGTYPE_YUV422:
505  c->decomp_size = basesize * 2;
506  max_decomp_size = max_basesize * 2;
507  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
508  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
509  if (avctx->width % 4) {
510  avpriv_request_sample(avctx, "Unsupported dimensions");
511  return AVERROR_INVALIDDATA;
512  }
513  break;
514  case IMGTYPE_RGB24:
515  c->decomp_size = basesize * 3;
516  max_decomp_size = max_basesize * 3;
517  avctx->pix_fmt = AV_PIX_FMT_BGR24;
518  av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n");
519  break;
520  case IMGTYPE_YUV411:
521  c->decomp_size = basesize / 2 * 3;
522  max_decomp_size = max_basesize / 2 * 3;
523  avctx->pix_fmt = AV_PIX_FMT_YUV411P;
524  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n");
525  break;
526  case IMGTYPE_YUV211:
527  c->decomp_size = basesize * 2;
528  max_decomp_size = max_basesize * 2;
529  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
530  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n");
531  break;
532  case IMGTYPE_YUV420:
533  c->decomp_size = basesize / 2 * 3;
534  max_decomp_size = max_basesize / 2 * 3;
535  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
536  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n");
537  break;
538  default:
539  av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
540  return AVERROR_INVALIDDATA;
541  }
542 
543  av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v);
544  if (avctx->width % (1<<subsample_h) || avctx->height % (1<<subsample_v)) {
545  avpriv_request_sample(avctx, "Unsupported dimensions");
546  return AVERROR_INVALIDDATA;
547  }
548 
549  /* Detect compression method */
550  c->compression = (int8_t)avctx->extradata[5];
551  switch (avctx->codec_id) {
552  case AV_CODEC_ID_MSZH:
553  switch (c->compression) {
554  case COMP_MSZH:
555  av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n");
556  break;
557  case COMP_MSZH_NOCOMP:
558  c->decomp_size = 0;
559  av_log(avctx, AV_LOG_DEBUG, "No compression.\n");
560  break;
561  default:
562  av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
563  return AVERROR_INVALIDDATA;
564  }
565  break;
566 #if CONFIG_ZLIB_DECODER
567  case AV_CODEC_ID_ZLIB:
568  switch (c->compression) {
569  case COMP_ZLIB_HISPEED:
570  av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n");
571  break;
572  case COMP_ZLIB_HICOMP:
573  av_log(avctx, AV_LOG_DEBUG, "High compression.\n");
574  break;
575  case COMP_ZLIB_NORMAL:
576  av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n");
577  break;
578  default:
579  if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
580  av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
581  return AVERROR_INVALIDDATA;
582  }
583  av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
584  }
585  break;
586 #endif
587  default:
588  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
589  return AVERROR_INVALIDDATA;
590  }
591 
592  /* Allocate decompression buffer */
593  if (c->decomp_size) {
594  if (!(c->decomp_buf = av_malloc(max_decomp_size))) {
595  av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
596  return AVERROR(ENOMEM);
597  }
598  }
599 
600  /* Detect flags */
601  c->flags = avctx->extradata[6];
602  if (c->flags & FLAG_MULTITHREAD)
603  av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n");
604  if (c->flags & FLAG_NULLFRAME)
605  av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n");
606  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER))
607  av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n");
608  if (c->flags & FLAGMASK_UNUSED)
609  av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
610 
611  /* If needed init zlib */
612 #if CONFIG_ZLIB_DECODER
613  if (avctx->codec_id == AV_CODEC_ID_ZLIB)
614  return ff_inflate_init(&c->zstream, avctx);
615 #endif
616 
617  return 0;
618 }
619 
621 {
622  LclDecContext * const c = avctx->priv_data;
623 
624  av_freep(&c->decomp_buf);
625 #if CONFIG_ZLIB_DECODER
626  ff_inflate_end(&c->zstream);
627 #endif
628 
629  return 0;
630 }
631 
632 #if CONFIG_MSZH_DECODER
633 const FFCodec ff_mszh_decoder = {
634  .p.name = "mszh",
635  .p.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
636  .p.type = AVMEDIA_TYPE_VIDEO,
637  .p.id = AV_CODEC_ID_MSZH,
638  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
639  .priv_data_size = sizeof(LclDecContext),
640  .init = decode_init,
641  .close = decode_end,
644 };
645 #endif
646 
647 #if CONFIG_ZLIB_DECODER
648 const FFCodec ff_zlib_decoder = {
649  .p.name = "zlib",
650  .p.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
651  .p.type = AVMEDIA_TYPE_VIDEO,
652  .p.id = AV_CODEC_ID_ZLIB,
653  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
654  .priv_data_size = sizeof(LclDecContext),
655  .init = decode_init,
656  .close = decode_end,
659 };
660 #endif
LclDecContext::decomp_size
unsigned int decomp_size
Definition: lcldec.c:66
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:39
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
IMGTYPE_YUV420
#define IMGTYPE_YUV420
Definition: lcl.h:33
CODEC_ZLIB
#define CODEC_ZLIB
Definition: lcl.h:47
mszh_decomp
static unsigned int mszh_decomp(const unsigned char *srcptr, int srclen, unsigned char *destptr, unsigned int destsize)
Definition: lcldec.c:79
IMGTYPE_YUV211
#define IMGTYPE_YUV211
Definition: lcl.h:32
COMP_MSZH_NOCOMP
#define COMP_MSZH_NOCOMP
Definition: lcl.h:36
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
pixdesc.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
ff_zlib_decoder
const FFCodec ff_zlib_decoder
FLAG_MULTITHREAD
#define FLAG_MULTITHREAD
Definition: lcl.h:41
FFCodec
Definition: codec_internal.h:112
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
ff_mszh_decoder
const FFCodec ff_mszh_decoder
thread.h
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
lcl.h
init
static int init
Definition: av_tx.c:47
LclDecContext::flags
int flags
Definition: lcldec.c:64
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:116
inflate
static void inflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord, int maxc)
Definition: vf_neighbor.c:195
AV_CODEC_ID_MSZH
@ AV_CODEC_ID_MSZH
Definition: codec_id.h:103
ff_thread_get_buffer
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames. The frames must then be freed with ff_thread_release_buffer(). Otherwise decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
av_pix_fmt_get_chroma_sub_sample
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:2690
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
zlib_wrapper.h
av_cold
#define av_cold
Definition: attributes.h:90
mask
static const uint16_t mask[17]
Definition: lzw.c:38
COMP_ZLIB_NORMAL
#define COMP_ZLIB_NORMAL
Definition: lcl.h:39
av_memcpy_backptr
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition: mem.c:455
LclDecContext::imgtype
int imgtype
Definition: lcldec.c:60
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:491
width
#define width
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:254
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: lcldec.c:476
LclDecContext::decomp_buf
unsigned char * decomp_buf
Definition: lcldec.c:68
IMGTYPE_RGB24
#define IMGTYPE_RGB24
Definition: lcl.h:30
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
IMGTYPE_YUV422
#define IMGTYPE_YUV422
Definition: lcl.h:29
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:399
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:113
FLAG_NULLFRAME
#define FLAG_NULLFRAME
Definition: lcl.h:42
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
AV_CODEC_ID_ZLIB
@ AV_CODEC_ID_ZLIB
Definition: codec_id.h:104
FF_PTR_ADD
#define FF_PTR_ADD(ptr, off)
Definition: internal.h:100
COMP_MSZH
#define COMP_MSZH
Definition: lcl.h:35
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
decode_end
static av_cold int decode_end(AVCodecContext *avctx)
Definition: lcldec.c:620
CODEC_MSZH
#define CODEC_MSZH
Definition: lcl.h:46
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:375
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
codec_internal.h
IMGTYPE_YUV411
#define IMGTYPE_YUV411
Definition: lcl.h:31
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:412
height
#define height
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
IMGTYPE_YUV111
#define IMGTYPE_YUV111
Definition: lcl.h:28
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:490
LclDecContext::compression
int compression
Definition: lcldec.c:62
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: codec_internal.h:31
COMP_ZLIB_HICOMP
#define COMP_ZLIB_HICOMP
Definition: lcl.h:38
COMP_ZLIB_HISPEED
#define COMP_ZLIB_HISPEED
Definition: lcl.h:37
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
len
int len
Definition: vorbis_enc_data.h:426
ff_inflate_end
void ff_inflate_end(FFZStream *zstream)
Wrapper around inflateEnd().
decode_frame
static int decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)
Definition: lcldec.c:162
LclDecContext
Definition: lcldec.c:58
AVCodecContext::height
int height
Definition: avcodec.h:562
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:599
avcodec.h
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVCodecContext
main external API structure.
Definition: avcodec.h:389
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
FFZStream
Definition: zlib_wrapper.h:27
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
mem.h
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
FLAG_PNGFILTER
#define FLAG_PNGFILTER
Definition: lcl.h:43
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
ff_inflate_init
int ff_inflate_init(FFZStream *zstream, void *logctx)
Wrapper around inflateInit().
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:562
bytestream.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
FLAGMASK_UNUSED
#define FLAGMASK_UNUSED
Definition: lcl.h:44
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61