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