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/attributes.h"
46 #include "libavutil/mem.h"
47 #include "libavutil/pixdesc.h"
48 #include "avcodec.h"
49 #include "bytestream.h"
50 #include "codec_internal.h"
51 #include "lcl.h"
52 #include "thread.h"
53 
54 #if CONFIG_ZLIB_DECODER
55 #include "zlib_wrapper.h"
56 #include <zlib.h>
57 #endif
58 
59 typedef struct LclDecContext {
60  // Image type
61  int imgtype;
62  // Compression type
64  // Flags
65  int flags;
66  // Decompressed data size
67  unsigned int decomp_size;
68  // Decompression buffer
69  unsigned char* decomp_buf;
70 #if CONFIG_ZLIB_DECODER
71  FFZStream zstream;
72 #endif
74 
75 
76 /**
77  * @param srcptr compressed source buffer, must be padded with at least 5 extra bytes
78  * @param destptr must be padded sufficiently for av_memcpy_backptr
79  */
80 static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
81 {
82  unsigned char *destptr_bak = destptr;
83  unsigned char *destptr_end = destptr + destsize;
84  const unsigned char *srcptr_end = srcptr + srclen;
85  unsigned mask = *srcptr++;
86  unsigned maskbit = 0x80;
87 
88  while (srcptr < srcptr_end && destptr < destptr_end) {
89  if (!(mask & maskbit)) {
90  memcpy(destptr, srcptr, 4);
91  destptr += 4;
92  srcptr += 4;
93  } else {
94  unsigned ofs = bytestream_get_le16(&srcptr);
95  unsigned cnt = (ofs >> 11) + 1;
96  ofs &= 0x7ff;
97  ofs = FFMIN(ofs, destptr - destptr_bak);
98  cnt *= 4;
99  cnt = FFMIN(cnt, destptr_end - destptr);
100  if (ofs) {
101  av_memcpy_backptr(destptr, ofs, cnt);
102  } else {
103  // Not known what the correct behaviour is, but
104  // this at least avoids uninitialized data.
105  memset(destptr, 0, cnt);
106  }
107  destptr += cnt;
108  }
109  maskbit >>= 1;
110  if (!maskbit) {
111  mask = *srcptr++;
112  while (!mask) {
113  if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break;
114  memcpy(destptr, srcptr, 32);
115  destptr += 32;
116  srcptr += 32;
117  mask = *srcptr++;
118  }
119  maskbit = 0x80;
120  }
121  }
122 
123  return destptr - destptr_bak;
124 }
125 
126 
127 #if CONFIG_ZLIB_DECODER
128 /**
129  * @brief decompress a zlib-compressed data block into decomp_buf
130  * @param src compressed input buffer
131  * @param src_len data length in input buffer
132  * @param offset offset in decomp_buf
133  * @param expected expected decompressed length
134  */
135 static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected)
136 {
137  LclDecContext *c = avctx->priv_data;
138  z_stream *const zstream = &c->zstream.zstream;
139  int zret = inflateReset(zstream);
140  if (zret != Z_OK) {
141  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
142  return AVERROR_UNKNOWN;
143  }
144  zstream->next_in = src;
145  zstream->avail_in = src_len;
146  zstream->next_out = c->decomp_buf + offset;
147  zstream->avail_out = c->decomp_size - offset;
148  zret = inflate(zstream, Z_FINISH);
149  if (zret != Z_OK && zret != Z_STREAM_END) {
150  av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
151  return AVERROR_UNKNOWN;
152  }
153  if (expected != (unsigned int)zstream->total_out) {
154  av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
155  expected, zstream->total_out);
156  if (expected > (unsigned int)zstream->total_out)
157  return (unsigned int)zstream->total_out;
158  return AVERROR_UNKNOWN;
159  }
160  return zstream->total_out;
161 }
162 #endif
163 
164 
166  int *got_frame, AVPacket *avpkt)
167 {
168  const uint8_t *buf = avpkt->data;
169  int buf_size = avpkt->size;
170  LclDecContext * const c = avctx->priv_data;
171  ptrdiff_t pixel_ptr;
172  int row, col;
173  unsigned char *encoded = avpkt->data, *outptr;
174  uint8_t *y_out, *u_out, *v_out;
175  int width = avctx->width; // Real image width
176  int height = avctx->height; // Real image height
177  unsigned int mszh_dlen;
178  unsigned char yq, y1q, uq, vq;
179  int ret;
180  unsigned int mthread_inlen, mthread_outlen;
181  unsigned int len = buf_size;
182  int linesize, offset;
183 
184  if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0)
185  return ret;
186 
187  outptr = frame->data[0]; // Output image pointer
188 
189  /* Decompress frame */
190  switch (avctx->codec_id) {
191  case AV_CODEC_ID_MSZH:
192  switch (c->compression) {
193  case COMP_MSZH:
194  if (c->imgtype == IMGTYPE_RGB24 && len == FFALIGN(width * 3, 4) * height ||
195  c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) {
196  ;
197  } else if (c->flags & FLAG_MULTITHREAD) {
198  mthread_inlen = AV_RL32(buf);
199  if (len < 8 || len - 8 < mthread_inlen) {
200  av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
201  return AVERROR_INVALIDDATA;
202  }
203  mthread_outlen = AV_RL32(buf + 4);
204  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
205  mszh_dlen = mszh_decomp(buf + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
206  if (mthread_outlen != mszh_dlen) {
207  av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
208  mthread_outlen, mszh_dlen);
209  return AVERROR_INVALIDDATA;
210  }
211  mszh_dlen = mszh_decomp(buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
212  c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
213  if (mthread_outlen != mszh_dlen) {
214  av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
215  mthread_outlen, mszh_dlen);
216  return AVERROR_INVALIDDATA;
217  }
218  encoded = c->decomp_buf;
219  len = c->decomp_size;
220  } else {
221  mszh_dlen = mszh_decomp(buf, len, c->decomp_buf, c->decomp_size);
222  if (c->decomp_size != mszh_dlen) {
223  av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
224  c->decomp_size, mszh_dlen);
225  if (c->decomp_size != mszh_dlen &&
226  c->decomp_size != mszh_dlen + 2) // YUV420 306x306 is missing 2 bytes
227  return AVERROR_INVALIDDATA;
228  }
229  encoded = c->decomp_buf;
230  len = mszh_dlen;
231  }
232  break;
233  case COMP_MSZH_NOCOMP: {
234  int bppx2;
235  int aligned_width = width;
236  switch (c->imgtype) {
237  case IMGTYPE_YUV111:
238  case IMGTYPE_RGB24:
239  bppx2 = 6;
240  break;
241  case IMGTYPE_YUV422:
242  aligned_width &= ~3;
244  case IMGTYPE_YUV211:
245  bppx2 = 4;
246  break;
247  case IMGTYPE_YUV411:
248  aligned_width &= ~3;
250  case IMGTYPE_YUV420:
251  bppx2 = 3;
252  break;
253  default:
254  bppx2 = 0; // will error out below
255  break;
256  }
257  if (len < ((aligned_width * height * bppx2) >> 1))
258  return AVERROR_INVALIDDATA;
259  break;
260  }
261  default:
262  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
263  return AVERROR_INVALIDDATA;
264  }
265  break;
266 #if CONFIG_ZLIB_DECODER
267  case AV_CODEC_ID_ZLIB:
268  /* Using the original dll with normal compression (-1) and RGB format
269  * gives a file with ZLIB fourcc, but frame is really uncompressed.
270  * To be sure that's true check also frame size */
271  if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 &&
272  len == width * height * 3) {
273  if (c->flags & FLAG_PNGFILTER) {
274  memcpy(c->decomp_buf, buf, len);
275  encoded = c->decomp_buf;
276  } else {
277  break;
278  }
279  } else if (c->flags & FLAG_MULTITHREAD) {
280  mthread_inlen = AV_RL32(buf);
281  mthread_inlen = FFMIN(mthread_inlen, len - 8);
282  mthread_outlen = AV_RL32(buf + 4);
283  mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
284  ret = zlib_decomp(avctx, buf + 8, mthread_inlen, 0, mthread_outlen);
285  if (ret < 0) return ret;
286  ret = zlib_decomp(avctx, buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
287  mthread_outlen, mthread_outlen);
288  if (ret < 0) return ret;
289  len = c->decomp_size;
290  } else {
291  int ret = zlib_decomp(avctx, buf, len, 0, c->decomp_size);
292  if (ret < 0) return ret;
293  len = ret;
294  }
295  encoded = c->decomp_buf;
296  break;
297 #endif
298  default:
299  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
300  return AVERROR_INVALIDDATA;
301  }
302 
303 
304  /* Apply PNG filter */
305  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) {
306  switch (c->imgtype) {
307  case IMGTYPE_YUV111:
308  case IMGTYPE_RGB24:
309  for (row = 0; row < height; row++) {
310  pixel_ptr = row * width * 3;
311  yq = encoded[pixel_ptr++];
312  unsigned uqvq = AV_RL16(encoded+pixel_ptr);
313  pixel_ptr += 2;
314  for (col = 1; col < width; col++) {
315  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
316  uqvq -= AV_RL16(encoded+pixel_ptr+1);
317  AV_WL16(encoded+pixel_ptr+1, uqvq);
318  pixel_ptr += 3;
319  }
320  }
321  break;
322  case IMGTYPE_YUV422:
323  pixel_ptr = 0;
324  for (row = 0; row < height; row++) {
325  yq = uq = vq =0;
326  for (col = 0; col < width/4; col++) {
327  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
328  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
329  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
330  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
331  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
332  encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5];
333  encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6];
334  encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7];
335  pixel_ptr += 8;
336  }
337  }
338  break;
339  case IMGTYPE_YUV411:
340  pixel_ptr = 0;
341  for (row = 0; row < height; row++) {
342  yq = uq = vq =0;
343  for (col = 0; col < width/4; col++) {
344  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
345  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
346  encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
347  encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
348  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
349  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
350  pixel_ptr += 6;
351  }
352  }
353  break;
354  case IMGTYPE_YUV211:
355  for (row = 0; row < height; row++) {
356  pixel_ptr = row * width * 2;
357  yq = uq = vq =0;
358  for (col = 0; col < width/2; col++) {
359  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
360  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
361  encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2];
362  encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3];
363  pixel_ptr += 4;
364  }
365  }
366  break;
367  case IMGTYPE_YUV420:
368  for (row = 0; row < height/2; row++) {
369  pixel_ptr = row * width * 3;
370  yq = y1q = uq = vq =0;
371  for (col = 0; col < width/2; col++) {
372  encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
373  encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
374  encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2];
375  encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3];
376  encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
377  encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
378  pixel_ptr += 6;
379  }
380  }
381  break;
382  default:
383  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
384  return AVERROR_INVALIDDATA;
385  }
386  }
387 
388  /* Convert colorspace */
389  y_out = frame->data[0] + (height - 1) * frame->linesize[0];
390  offset = (height - 1) * frame->linesize[1];
391  u_out = FF_PTR_ADD(frame->data[1], offset);
392  offset = (height - 1) * frame->linesize[2];
393  v_out = FF_PTR_ADD(frame->data[2], offset);
394  switch (c->imgtype) {
395  case IMGTYPE_YUV111:
396  for (row = 0; row < height; row++) {
397  for (col = 0; col < width; col++) {
398  y_out[col] = *encoded++;
399  u_out[col] = *encoded++ + 128;
400  v_out[col] = *encoded++ + 128;
401  }
402  y_out -= frame->linesize[0];
403  u_out -= frame->linesize[1];
404  v_out -= frame->linesize[2];
405  }
406  break;
407  case IMGTYPE_YUV422:
408  for (row = 0; row < height; row++) {
409  for (col = 0; col < width - 3; col += 4) {
410  memcpy(y_out + col, encoded, 4);
411  encoded += 4;
412  u_out[ col >> 1 ] = *encoded++ + 128;
413  u_out[(col >> 1) + 1] = *encoded++ + 128;
414  v_out[ col >> 1 ] = *encoded++ + 128;
415  v_out[(col >> 1) + 1] = *encoded++ + 128;
416  }
417  if (col && col < width) {
418  u_out[ col >> 1 ] = u_out[(col>>1) - 1];
419  v_out[ col >> 1 ] = v_out[(col>>1) - 1];
420  }
421 
422  y_out -= frame->linesize[0];
423  u_out -= frame->linesize[1];
424  v_out -= frame->linesize[2];
425  }
426  break;
427  case IMGTYPE_RGB24:
428  linesize = len < FFALIGN(3 * width, 4) * height ? 3 * width : FFALIGN(3 * width, 4);
429  for (row = height - 1; row >= 0; row--) {
430  pixel_ptr = row * frame->linesize[0];
431  memcpy(outptr + pixel_ptr, encoded, 3 * width);
432  encoded += linesize;
433  }
434  break;
435  case IMGTYPE_YUV411:
436  for (row = 0; row < height; row++) {
437  for (col = 0; col < width - 3; col += 4) {
438  memcpy(y_out + col, encoded, 4);
439  encoded += 4;
440  u_out[col >> 2] = *encoded++ + 128;
441  v_out[col >> 2] = *encoded++ + 128;
442  }
443  if (col && col < width) {
444  u_out[col >> 2] = u_out[(col>>2) - 1];
445  v_out[col >> 2] = v_out[(col>>2) - 1];
446  }
447  y_out -= frame->linesize[0];
448  u_out -= frame->linesize[1];
449  v_out -= frame->linesize[2];
450  }
451  break;
452  case IMGTYPE_YUV211:
453  for (row = 0; row < height; row++) {
454  for (col = 0; col < width - 1; col += 2) {
455  memcpy(y_out + col, encoded, 2);
456  encoded += 2;
457  u_out[col >> 1] = *encoded++ + 128;
458  v_out[col >> 1] = *encoded++ + 128;
459  }
460  y_out -= frame->linesize[0];
461  u_out -= frame->linesize[1];
462  v_out -= frame->linesize[2];
463  }
464  break;
465  case IMGTYPE_YUV420:
466  u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
467  v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
468  for (row = 0; row < height - 1; row += 2) {
469  for (col = 0; col < width - 1; col += 2) {
470  memcpy(y_out + col, encoded, 2);
471  encoded += 2;
472  memcpy(y_out + col - frame->linesize[0], encoded, 2);
473  encoded += 2;
474  u_out[col >> 1] = *encoded++ + 128;
475  v_out[col >> 1] = *encoded++ + 128;
476  }
477  y_out -= frame->linesize[0] << 1;
478  u_out -= frame->linesize[1];
479  v_out -= frame->linesize[2];
480  }
481  break;
482  default:
483  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
484  return AVERROR_INVALIDDATA;
485  }
486 
487  *got_frame = 1;
488 
489  /* always report that the buffer was completely consumed */
490  return buf_size;
491 }
492 
494 {
495  LclDecContext * const c = avctx->priv_data;
496  unsigned int basesize = avctx->width * avctx->height;
497  unsigned int max_basesize = FFALIGN(avctx->width, 4) *
498  FFALIGN(avctx->height, 4);
499  unsigned int max_decomp_size;
500  int subsample_h, subsample_v;
501  int partial_h_supported = 0;
502 
503  if (avctx->extradata_size < 8) {
504  av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
505  return AVERROR_INVALIDDATA;
506  }
507 
508  /* Check codec type */
509  if ((avctx->codec_id == AV_CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) ||
510  (avctx->codec_id == AV_CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) {
511  av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
512  }
513 
514  /* Detect image type */
515  switch (c->imgtype = avctx->extradata[4]) {
516  case IMGTYPE_YUV111:
517  c->decomp_size = basesize * 3;
518  max_decomp_size = max_basesize * 3;
519  avctx->pix_fmt = AV_PIX_FMT_YUV444P;
520  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n");
521  break;
522  case IMGTYPE_YUV422:
523  c->decomp_size = (avctx->width & ~3) * avctx->height * 2;
524  max_decomp_size = max_basesize * 2;
525  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
526  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
527  partial_h_supported = 1;
528  break;
529  case IMGTYPE_RGB24:
530  c->decomp_size = FFALIGN(avctx->width*3, 4) * avctx->height;
531  max_decomp_size = max_basesize * 3;
532  avctx->pix_fmt = AV_PIX_FMT_BGR24;
533  av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n");
534  break;
535  case IMGTYPE_YUV411:
536  c->decomp_size = (avctx->width & ~3) * avctx->height / 2 * 3;
537  max_decomp_size = max_basesize / 2 * 3;
538  avctx->pix_fmt = AV_PIX_FMT_YUV411P;
539  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n");
540  partial_h_supported = 1;
541  break;
542  case IMGTYPE_YUV211:
543  c->decomp_size = basesize * 2;
544  max_decomp_size = max_basesize * 2;
545  avctx->pix_fmt = AV_PIX_FMT_YUV422P;
546  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n");
547  break;
548  case IMGTYPE_YUV420:
549  c->decomp_size = basesize / 2 * 3;
550  max_decomp_size = max_basesize / 2 * 3;
551  avctx->pix_fmt = AV_PIX_FMT_YUV420P;
552  av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n");
553  break;
554  default:
555  av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
556  return AVERROR_INVALIDDATA;
557  }
558 
559  av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v);
560  if ((avctx->width % (1<<subsample_h) && !partial_h_supported) || avctx->height % (1<<subsample_v)) {
561  avpriv_request_sample(avctx, "Unsupported dimensions");
562  return AVERROR_INVALIDDATA;
563  }
564 
565  /* Detect compression method */
566  c->compression = (int8_t)avctx->extradata[5];
567  switch (avctx->codec_id) {
568  case AV_CODEC_ID_MSZH:
569  switch (c->compression) {
570  case COMP_MSZH:
571  av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n");
572  break;
573  case COMP_MSZH_NOCOMP:
574  c->decomp_size = 0;
575  av_log(avctx, AV_LOG_DEBUG, "No compression.\n");
576  break;
577  default:
578  av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
579  return AVERROR_INVALIDDATA;
580  }
581  break;
582 #if CONFIG_ZLIB_DECODER
583  case AV_CODEC_ID_ZLIB:
584  switch (c->compression) {
585  case COMP_ZLIB_HISPEED:
586  av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n");
587  break;
588  case COMP_ZLIB_HICOMP:
589  av_log(avctx, AV_LOG_DEBUG, "High compression.\n");
590  break;
591  case COMP_ZLIB_NORMAL:
592  av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n");
593  break;
594  default:
595  if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
596  av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
597  return AVERROR_INVALIDDATA;
598  }
599  av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
600  }
601  break;
602 #endif
603  default:
604  av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
605  return AVERROR_INVALIDDATA;
606  }
607 
608  /* Allocate decompression buffer */
609  if (c->decomp_size) {
610  if (!(c->decomp_buf = av_malloc(max_decomp_size))) {
611  av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
612  return AVERROR(ENOMEM);
613  }
614  }
615 
616  /* Detect flags */
617  c->flags = avctx->extradata[6];
618  if (c->flags & FLAG_MULTITHREAD)
619  av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n");
620  if (c->flags & FLAG_NULLFRAME)
621  av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n");
622  if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER))
623  av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n");
624  if (c->flags & FLAGMASK_UNUSED)
625  av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
626 
627  /* If needed init zlib */
628 #if CONFIG_ZLIB_DECODER
629  if (avctx->codec_id == AV_CODEC_ID_ZLIB)
630  return ff_inflate_init(&c->zstream, avctx);
631 #endif
632 
633  return 0;
634 }
635 
637 {
638  LclDecContext * const c = avctx->priv_data;
639 
640  av_freep(&c->decomp_buf);
641 #if CONFIG_ZLIB_DECODER
642  ff_inflate_end(&c->zstream);
643 #endif
644 
645  return 0;
646 }
647 
648 #if CONFIG_MSZH_DECODER
649 const FFCodec ff_mszh_decoder = {
650  .p.name = "mszh",
651  CODEC_LONG_NAME("LCL (LossLess Codec Library) MSZH"),
652  .p.type = AVMEDIA_TYPE_VIDEO,
653  .p.id = AV_CODEC_ID_MSZH,
654  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
655  .priv_data_size = sizeof(LclDecContext),
656  .init = decode_init,
657  .close = decode_end,
659  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
660 };
661 #endif
662 
663 #if CONFIG_ZLIB_DECODER
664 const FFCodec ff_zlib_decoder = {
665  .p.name = "zlib",
666  CODEC_LONG_NAME("LCL (LossLess Codec Library) ZLIB"),
667  .p.type = AVMEDIA_TYPE_VIDEO,
668  .p.id = AV_CODEC_ID_ZLIB,
669  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
670  .priv_data_size = sizeof(LclDecContext),
671  .init = decode_init,
672  .close = decode_end,
674  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
675 };
676 #endif
LclDecContext::decomp_size
unsigned int decomp_size
Definition: lcldec.c:67
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:43
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:80
IMGTYPE_YUV211
#define IMGTYPE_YUV211
Definition: lcl.h:32
mask
int mask
Definition: mediacodecdec_common.c:154
COMP_MSZH_NOCOMP
#define COMP_MSZH_NOCOMP
Definition: lcl.h:36
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:435
pixdesc.h
AVPacket::data
uint8_t * data
Definition: packet.h:595
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:76
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
lcl.h
LclDecContext::flags
int flags
Definition: lcldec.c:65
close
static av_cold void close(AVCodecParserContext *s)
Definition: apv_parser.c:197
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
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:3484
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
zlib_wrapper.h
av_cold
#define av_cold
Definition: attributes.h:119
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:447
LclDecContext::imgtype
int imgtype
Definition: lcldec.c:61
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:523
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:347
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1044
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: lcldec.c:493
LclDecContext::decomp_buf
unsigned char * decomp_buf
Definition: lcldec.c:69
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:231
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:73
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:332
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:449
AV_CODEC_CAP_FRAME_THREADS
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:95
FLAG_NULLFRAME
#define FLAG_NULLFRAME
Definition: lcl.h:42
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:80
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:636
CODEC_MSZH
#define CODEC_MSZH
Definition: lcl.h:46
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:551
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:596
height
#define height
Definition: dsp.h:89
codec_internal.h
IMGTYPE_YUV411
#define IMGTYPE_YUV411
Definition: lcl.h:31
AV_WL16
#define AV_WL16(p, v)
Definition: intreadwrite.h:408
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
attributes.h
IMGTYPE_YUV111
#define IMGTYPE_YUV111
Definition: lcl.h:28
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:522
LclDecContext::compression
int compression
Definition: lcldec.c:63
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:179
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:165
LclDecContext
Definition: lcldec.c:59
AVCodecContext::height
int height
Definition: avcodec.h:600
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:639
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:265
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVCodecContext
main external API structure.
Definition: avcodec.h:439
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:78
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
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:77
mem.h
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:572
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:466
FLAG_PNGFILTER
#define FLAG_PNGFILTER
Definition: lcl.h:43
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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:80
ff_inflate_init
int ff_inflate_init(FFZStream *zstream, void *logctx)
Wrapper around inflateInit().
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:600
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
width
#define width
Definition: dsp.h:89
src
#define src
Definition: vp8dsp.c:248