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  if (expected > (unsigned int)zstream->total_out)
156  return (unsigned int)zstream->total_out;
157  return AVERROR_UNKNOWN;
158  }
159  return zstream->total_out;
160 }
161 #endif
162 
163 
165  int *got_frame, AVPacket *avpkt)
166 {
167  const uint8_t *buf = avpkt->data;
168  int buf_size = avpkt->size;
169  LclDecContext * const c = avctx->priv_data;
170  ptrdiff_t pixel_ptr;
171  int row, col;
172  unsigned char *encoded = avpkt->data, *outptr;
173  uint8_t *y_out, *u_out, *v_out;
174  int width = avctx->width; // Real image width
175  int height = avctx->height; // Real image height
176  unsigned int mszh_dlen;
177  unsigned char yq, y1q, uq, vq;
178  int uqvq, ret;
179  unsigned int mthread_inlen, mthread_outlen;
180  unsigned int len = buf_size;
181  int linesize, offset;
182 
183  if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
184  return ret;
185 
186  outptr = frame->data[0]; // Output image pointer
187 
188  /* Decompress frame */
189  switch (avctx->codec_id) {
190  case AV_CODEC_ID_MSZH:
191  switch (c->compression) {
192  case COMP_MSZH:
193  if (c->imgtype == IMGTYPE_RGB24 && len == FFALIGN(width * 3, 4) * height ||
194  c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) {
195  ;
196  } else if (c->flags & FLAG_MULTITHREAD) {
197  mthread_inlen = AV_RL32(buf);
198  if (len < 8 || len - 8 < mthread_inlen) {
199  av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
200  return AVERROR_INVALIDDATA;
201  }
202  mthread_outlen = AV_RL32(buf + 4);
203  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
204  mszh_dlen = mszh_decomp(buf + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
205  if (mthread_outlen != mszh_dlen) {
206  av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
207  mthread_outlen, mszh_dlen);
208  return AVERROR_INVALIDDATA;
209  }
210  mszh_dlen = mszh_decomp(buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
211  c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
212  if (mthread_outlen != mszh_dlen) {
213  av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
214  mthread_outlen, mszh_dlen);
215  return AVERROR_INVALIDDATA;
216  }
217  encoded = c->decomp_buf;
218  len = c->decomp_size;
219  } else {
220  mszh_dlen = mszh_decomp(buf, len, c->decomp_buf, c->decomp_size);
221  if (c->decomp_size != mszh_dlen) {
222  av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
223  c->decomp_size, mszh_dlen);
224  if (c->decomp_size != mszh_dlen &&
225  c->decomp_size != mszh_dlen + 2) // YUV420 306x306 is missing 2 bytes
226  return AVERROR_INVALIDDATA;
227  }
228  encoded = c->decomp_buf;
229  len = mszh_dlen;
230  }
231  break;
232  case COMP_MSZH_NOCOMP: {
233  int bppx2;
234  switch (c->imgtype) {
235  case IMGTYPE_YUV111:
236  case IMGTYPE_RGB24:
237  bppx2 = 6;
238  break;
239  case IMGTYPE_YUV422:
240  case IMGTYPE_YUV211:
241  bppx2 = 4;
242  break;
243  case IMGTYPE_YUV411:
244  case IMGTYPE_YUV420:
245  bppx2 = 3;
246  break;
247  default:
248  bppx2 = 0; // will error out below
249  break;
250  }
251  if (len < ((width * height * bppx2) >> 1))
252  return AVERROR_INVALIDDATA;
253  break;
254  }
255  default:
256  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
257  return AVERROR_INVALIDDATA;
258  }
259  break;
260 #if CONFIG_ZLIB_DECODER
261  case AV_CODEC_ID_ZLIB:
262  /* Using the original dll with normal compression (-1) and RGB format
263  * gives a file with ZLIB fourcc, but frame is really uncompressed.
264  * To be sure that's true check also frame size */
265  if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 &&
266  len == width * height * 3) {
267  if (c->flags & FLAG_PNGFILTER) {
268  memcpy(c->decomp_buf, buf, len);
269  encoded = c->decomp_buf;
270  } else {
271  break;
272  }
273  } else if (c->flags & FLAG_MULTITHREAD) {
274  mthread_inlen = AV_RL32(buf);
275  mthread_inlen = FFMIN(mthread_inlen, len - 8);
276  mthread_outlen = AV_RL32(buf + 4);
277  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
278  ret = zlib_decomp(avctx, buf + 8, mthread_inlen, 0, mthread_outlen);
279  if (ret < 0) return ret;
280  ret = zlib_decomp(avctx, buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
281  mthread_outlen, mthread_outlen);
282  if (ret < 0) return ret;
283  len = c->decomp_size;
284  } else {
285  int ret = zlib_decomp(avctx, buf, len, 0, c->decomp_size);
286  if (ret < 0) return ret;
287  len = ret;
288  }
289  encoded = c->decomp_buf;
290  break;
291 #endif
292  default:
293  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
294  return AVERROR_INVALIDDATA;
295  }
296 
297 
298  /* Apply PNG filter */
299  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) {
300  switch (c->imgtype) {
301  case IMGTYPE_YUV111:
302  case IMGTYPE_RGB24:
303  for (row = 0; row < height; row++) {
304  pixel_ptr = row * width * 3;
305  yq = encoded[pixel_ptr++];
306  uqvq = AV_RL16(encoded+pixel_ptr);
307  pixel_ptr += 2;
308  for (col = 1; col < width; col++) {
309  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
310  uqvq -= AV_RL16(encoded+pixel_ptr+1);
311  AV_WL16(encoded+pixel_ptr+1, uqvq);
312  pixel_ptr += 3;
313  }
314  }
315  break;
316  case IMGTYPE_YUV422:
317  for (row = 0; row < height; row++) {
318  pixel_ptr = row * width * 2;
319  yq = uq = vq =0;
320  for (col = 0; col < width/4; col++) {
321  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
322  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
323  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
324  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
325  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
326  encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5];
327  encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6];
328  encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7];
329  pixel_ptr += 8;
330  }
331  }
332  break;
333  case IMGTYPE_YUV411:
334  for (row = 0; row < height; row++) {
335  pixel_ptr = row * width / 2 * 3;
336  yq = uq = vq =0;
337  for (col = 0; col < width/4; col++) {
338  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
339  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
340  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
341  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
342  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
343  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
344  pixel_ptr += 6;
345  }
346  }
347  break;
348  case IMGTYPE_YUV211:
349  for (row = 0; row < height; row++) {
350  pixel_ptr = row * width * 2;
351  yq = uq = vq =0;
352  for (col = 0; col < width/2; col++) {
353  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
354  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
355  encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2];
356  encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3];
357  pixel_ptr += 4;
358  }
359  }
360  break;
361  case IMGTYPE_YUV420:
362  for (row = 0; row < height/2; row++) {
363  pixel_ptr = row * width * 3;
364  yq = y1q = uq = vq =0;
365  for (col = 0; col < width/2; col++) {
366  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
367  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
368  encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2];
369  encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3];
370  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
371  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
372  pixel_ptr += 6;
373  }
374  }
375  break;
376  default:
377  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
378  return AVERROR_INVALIDDATA;
379  }
380  }
381 
382  /* Convert colorspace */
383  y_out = frame->data[0] + (height - 1) * frame->linesize[0];
384  offset = (height - 1) * frame->linesize[1];
385  u_out = FF_PTR_ADD(frame->data[1], offset);
386  offset = (height - 1) * frame->linesize[2];
387  v_out = FF_PTR_ADD(frame->data[2], offset);
388  switch (c->imgtype) {
389  case IMGTYPE_YUV111:
390  for (row = 0; row < height; row++) {
391  for (col = 0; col < width; col++) {
392  y_out[col] = *encoded++;
393  u_out[col] = *encoded++ + 128;
394  v_out[col] = *encoded++ + 128;
395  }
396  y_out -= frame->linesize[0];
397  u_out -= frame->linesize[1];
398  v_out -= frame->linesize[2];
399  }
400  break;
401  case IMGTYPE_YUV422:
402  for (row = 0; row < height; row++) {
403  for (col = 0; col < width - 3; col += 4) {
404  memcpy(y_out + col, encoded, 4);
405  encoded += 4;
406  u_out[ col >> 1 ] = *encoded++ + 128;
407  u_out[(col >> 1) + 1] = *encoded++ + 128;
408  v_out[ col >> 1 ] = *encoded++ + 128;
409  v_out[(col >> 1) + 1] = *encoded++ + 128;
410  }
411  if (col && col < width) {
412  u_out[ col >> 1 ] = u_out[(col>>1) - 1];
413  v_out[ col >> 1 ] = v_out[(col>>1) - 1];
414  }
415 
416  y_out -= frame->linesize[0];
417  u_out -= frame->linesize[1];
418  v_out -= frame->linesize[2];
419  }
420  break;
421  case IMGTYPE_RGB24:
422  linesize = len < FFALIGN(3 * width, 4) * height ? 3 * width : FFALIGN(3 * width, 4);
423  for (row = height - 1; row >= 0; row--) {
424  pixel_ptr = row * frame->linesize[0];
425  memcpy(outptr + pixel_ptr, encoded, 3 * width);
426  encoded += linesize;
427  }
428  break;
429  case IMGTYPE_YUV411:
430  for (row = 0; row < height; row++) {
431  for (col = 0; col < width - 3; col += 4) {
432  memcpy(y_out + col, encoded, 4);
433  encoded += 4;
434  u_out[col >> 2] = *encoded++ + 128;
435  v_out[col >> 2] = *encoded++ + 128;
436  }
437  if (col && col < width) {
438  u_out[col >> 2] = u_out[(col>>2) - 1];
439  v_out[col >> 2] = v_out[(col>>2) - 1];
440  }
441  y_out -= frame->linesize[0];
442  u_out -= frame->linesize[1];
443  v_out -= frame->linesize[2];
444  }
445  break;
446  case IMGTYPE_YUV211:
447  for (row = 0; row < height; row++) {
448  for (col = 0; col < width - 1; col += 2) {
449  memcpy(y_out + col, encoded, 2);
450  encoded += 2;
451  u_out[col >> 1] = *encoded++ + 128;
452  v_out[col >> 1] = *encoded++ + 128;
453  }
454  y_out -= frame->linesize[0];
455  u_out -= frame->linesize[1];
456  v_out -= frame->linesize[2];
457  }
458  break;
459  case IMGTYPE_YUV420:
460  u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
461  v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
462  for (row = 0; row < height - 1; row += 2) {
463  for (col = 0; col < width - 1; col += 2) {
464  memcpy(y_out + col, encoded, 2);
465  encoded += 2;
466  memcpy(y_out + col - frame->linesize[0], encoded, 2);
467  encoded += 2;
468  u_out[col >> 1] = *encoded++ + 128;
469  v_out[col >> 1] = *encoded++ + 128;
470  }
471  y_out -= frame->linesize[0] << 1;
472  u_out -= frame->linesize[1];
473  v_out -= frame->linesize[2];
474  }
475  break;
476  default:
477  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
478  return AVERROR_INVALIDDATA;
479  }
480 
481  frame->flags |= AV_FRAME_FLAG_KEY;
482  frame->pict_type = AV_PICTURE_TYPE_I;
483 
484  *got_frame = 1;
485 
486  /* always report that the buffer was completely consumed */
487  return buf_size;
488 }
489 
491 {
492  LclDecContext * const c = avctx->priv_data;
493  unsigned int basesize = avctx->width * avctx->height;
494  unsigned int max_basesize = FFALIGN(avctx->width, 4) *
495  FFALIGN(avctx->height, 4);
496  unsigned int max_decomp_size;
497  int subsample_h, subsample_v;
498  int partial_h_supported = 0;
499 
500  if (avctx->extradata_size < 8) {
501  av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
502  return AVERROR_INVALIDDATA;
503  }
504 
505  /* Check codec type */
506  if ((avctx->codec_id == AV_CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) ||
507  (avctx->codec_id == AV_CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) {
508  av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
509  }
510 
511  /* Detect image type */
512  switch (c->imgtype = avctx->extradata[4]) {
513  case IMGTYPE_YUV111:
514  c->decomp_size = basesize * 3;
515  max_decomp_size = max_basesize * 3;
516  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
517  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n");
518  break;
519  case IMGTYPE_YUV422:
520  c->decomp_size = (avctx->width & ~3) * avctx->height * 2;
521  max_decomp_size = max_basesize * 2;
522  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
523  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
524  partial_h_supported = 1;
525  break;
526  case IMGTYPE_RGB24:
527  c->decomp_size = FFALIGN(avctx->width*3, 4) * avctx->height;
528  max_decomp_size = max_basesize * 3;
529  avctx->pix_fmt = AV_PIX_FMT_BGR24;
530  av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n");
531  break;
532  case IMGTYPE_YUV411:
533  c->decomp_size = (avctx->width & ~3) * avctx->height / 2 * 3;
534  max_decomp_size = max_basesize / 2 * 3;
535  avctx->pix_fmt = AV_PIX_FMT_YUV411P;
536  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n");
537  partial_h_supported = 1;
538  break;
539  case IMGTYPE_YUV211:
540  c->decomp_size = basesize * 2;
541  max_decomp_size = max_basesize * 2;
542  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
543  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n");
544  break;
545  case IMGTYPE_YUV420:
546  c->decomp_size = basesize / 2 * 3;
547  max_decomp_size = max_basesize / 2 * 3;
548  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
549  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n");
550  break;
551  default:
552  av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
553  return AVERROR_INVALIDDATA;
554  }
555 
556  av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v);
557  if ((avctx->width % (1<<subsample_h) && !partial_h_supported) || avctx->height % (1<<subsample_v)) {
558  avpriv_request_sample(avctx, "Unsupported dimensions");
559  return AVERROR_INVALIDDATA;
560  }
561 
562  /* Detect compression method */
563  c->compression = (int8_t)avctx->extradata[5];
564  switch (avctx->codec_id) {
565  case AV_CODEC_ID_MSZH:
566  switch (c->compression) {
567  case COMP_MSZH:
568  av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n");
569  break;
570  case COMP_MSZH_NOCOMP:
571  c->decomp_size = 0;
572  av_log(avctx, AV_LOG_DEBUG, "No compression.\n");
573  break;
574  default:
575  av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
576  return AVERROR_INVALIDDATA;
577  }
578  break;
579 #if CONFIG_ZLIB_DECODER
580  case AV_CODEC_ID_ZLIB:
581  switch (c->compression) {
582  case COMP_ZLIB_HISPEED:
583  av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n");
584  break;
585  case COMP_ZLIB_HICOMP:
586  av_log(avctx, AV_LOG_DEBUG, "High compression.\n");
587  break;
588  case COMP_ZLIB_NORMAL:
589  av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n");
590  break;
591  default:
592  if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
593  av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
594  return AVERROR_INVALIDDATA;
595  }
596  av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
597  }
598  break;
599 #endif
600  default:
601  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
602  return AVERROR_INVALIDDATA;
603  }
604 
605  /* Allocate decompression buffer */
606  if (c->decomp_size) {
607  if (!(c->decomp_buf = av_malloc(max_decomp_size))) {
608  av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
609  return AVERROR(ENOMEM);
610  }
611  }
612 
613  /* Detect flags */
614  c->flags = avctx->extradata[6];
615  if (c->flags & FLAG_MULTITHREAD)
616  av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n");
617  if (c->flags & FLAG_NULLFRAME)
618  av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n");
619  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER))
620  av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n");
621  if (c->flags & FLAGMASK_UNUSED)
622  av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
623 
624  /* If needed init zlib */
625 #if CONFIG_ZLIB_DECODER
626  if (avctx->codec_id == AV_CODEC_ID_ZLIB)
627  return ff_inflate_init(&c->zstream, avctx);
628 #endif
629 
630  return 0;
631 }
632 
634 {
635  LclDecContext * const c = avctx->priv_data;
636 
637  av_freep(&c->decomp_buf);
638 #if CONFIG_ZLIB_DECODER
639  ff_inflate_end(&c->zstream);
640 #endif
641 
642  return 0;
643 }
644 
645 #if CONFIG_MSZH_DECODER
646 const FFCodec ff_mszh_decoder = {
647  .p.name = "mszh",
648  CODEC_LONG_NAME("LCL (LossLess Codec Library) MSZH"),
649  .p.type = AVMEDIA_TYPE_VIDEO,
650  .p.id = AV_CODEC_ID_MSZH,
651  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
652  .priv_data_size = sizeof(LclDecContext),
653  .init = decode_init,
654  .close = decode_end,
656  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
657 };
658 #endif
659 
660 #if CONFIG_ZLIB_DECODER
661 const FFCodec ff_zlib_decoder = {
662  .p.name = "zlib",
663  CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"),
664  .p.type = AVMEDIA_TYPE_VIDEO,
665  .p.id = AV_CODEC_ID_ZLIB,
666  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
667  .priv_data_size = sizeof(LclDecContext),
668  .init = decode_init,
669  .close = decode_end,
671  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
672 };
673 #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:42
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:340
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:127
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
LclDecContext::flags
int flags
Definition: lcldec.c:64
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
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:194
AV_CODEC_ID_MSZH
@ AV_CODEC_ID_MSZH
Definition: codec_id.h:105
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:2964
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
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:628
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:445
LclDecContext::imgtype
int imgtype
Definition: lcldec.c:60
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:539
width
#define width
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: lcldec.c:490
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
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
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:447
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:110
FLAG_NULLFRAME
#define FLAG_NULLFRAME
Definition: lcl.h:42
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
AV_CODEC_ID_ZLIB
@ AV_CODEC_ID_ZLIB
Definition: codec_id.h:106
FF_PTR_ADD
#define FF_PTR_ADD(ptr, off)
Definition: internal.h:90
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:633
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
codec_internal.h
IMGTYPE_YUV411
#define IMGTYPE_YUV411
Definition: lcl.h:31
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:410
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:538
LclDecContext::compression
int compression
Definition: lcldec.c:62
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:194
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:164
LclDecContext
Definition: lcldec.c:58
AVCodecContext::height
int height
Definition: avcodec.h:617
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:654
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:437
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:464
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:617
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