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