FFmpeg
pixlet.c
Go to the documentation of this file.
1 /*
2  * Apple Pixlet decoder
3  * Copyright (c) 2016 Paul B Mahol
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 #include <stdint.h>
23 
24 #include "libavutil/imgutils.h"
25 #include "libavutil/intmath.h"
26 #include "libavutil/opt.h"
27 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "get_bits.h"
31 #include "internal.h"
32 #include "thread.h"
33 #include "unary.h"
34 
35 #define NB_LEVELS 4
36 
37 #define PIXLET_MAGIC 0xDEADBEEF
38 
39 #define H 0
40 #define V 1
41 
42 typedef struct SubBand {
43  unsigned width, height;
44  unsigned size;
45  unsigned x, y;
46 } SubBand;
47 
48 typedef struct PixletContext {
49  AVClass *class;
50 
53 
54  int levels;
55  int depth;
56  int w, h;
57 
58  int16_t *filter[2];
59  int16_t *prediction;
60  int64_t scaling[4][2][NB_LEVELS];
61  SubBand band[4][NB_LEVELS * 3 + 1];
63 
65 {
68  return 0;
69 }
70 
71 static void free_buffers(AVCodecContext *avctx)
72 {
73  PixletContext *ctx = avctx->priv_data;
74 
75  av_freep(&ctx->filter[0]);
76  av_freep(&ctx->filter[1]);
77  av_freep(&ctx->prediction);
78 }
79 
81 {
82  PixletContext *ctx = avctx->priv_data;
83  free_buffers(avctx);
84  ctx->w = 0;
85  ctx->h = 0;
86  return 0;
87 }
88 
89 static int init_decoder(AVCodecContext *avctx)
90 {
91  PixletContext *ctx = avctx->priv_data;
92  int i, plane;
93 
94  ctx->filter[0] = av_malloc_array(ctx->h, sizeof(int16_t));
95  ctx->filter[1] = av_malloc_array(FFMAX(ctx->h, ctx->w) + 16, sizeof(int16_t));
96  ctx->prediction = av_malloc_array((ctx->w >> NB_LEVELS), sizeof(int16_t));
97  if (!ctx->filter[0] || !ctx->filter[1] || !ctx->prediction)
98  return AVERROR(ENOMEM);
99 
100  for (plane = 0; plane < 3; plane++) {
101  unsigned shift = plane > 0;
102  unsigned w = ctx->w >> shift;
103  unsigned h = ctx->h >> shift;
104 
105  ctx->band[plane][0].width = w >> NB_LEVELS;
106  ctx->band[plane][0].height = h >> NB_LEVELS;
107  ctx->band[plane][0].size = (w >> NB_LEVELS) * (h >> NB_LEVELS);
108 
109  for (i = 0; i < NB_LEVELS * 3; i++) {
110  unsigned scale = ctx->levels - (i / 3);
111 
112  ctx->band[plane][i + 1].width = w >> scale;
113  ctx->band[plane][i + 1].height = h >> scale;
114  ctx->band[plane][i + 1].size = (w >> scale) * (h >> scale);
115 
116  ctx->band[plane][i + 1].x = (w >> scale) * (((i + 1) % 3) != 2);
117  ctx->band[plane][i + 1].y = (h >> scale) * (((i + 1) % 3) != 1);
118  }
119  }
120 
121  return 0;
122 }
123 
124 static int read_low_coeffs(AVCodecContext *avctx, int16_t *dst, int size,
125  int width, ptrdiff_t stride)
126 {
127  PixletContext *ctx = avctx->priv_data;
128  GetBitContext *bc = &ctx->bc;
129  unsigned cnt1, nbits, k, j = 0, i = 0;
130  int64_t value, state = 3;
131  int rlen, escape, flag = 0;
132 
133  while (i < size) {
134  nbits = FFMIN(ff_clz((state >> 8) + 3) ^ 0x1F, 14);
135 
136  cnt1 = get_unary(bc, 0, 8);
137  if (cnt1 < 8) {
138  value = show_bits(bc, nbits);
139  if (value <= 1) {
140  skip_bits(bc, nbits - 1);
141  escape = ((1 << nbits) - 1) * cnt1;
142  } else {
143  skip_bits(bc, nbits);
144  escape = value + ((1 << nbits) - 1) * cnt1 - 1;
145  }
146  } else {
147  escape = get_bits(bc, 16);
148  }
149 
150  value = -((escape + flag) & 1) | 1;
151  dst[j++] = value * ((escape + flag + 1) >> 1);
152  i++;
153  if (j == width) {
154  j = 0;
155  dst += stride;
156  }
157  state = 120 * (escape + flag) + state - (120 * state >> 8);
158  flag = 0;
159 
160  if (state * 4ULL > 0xFF || i >= size)
161  continue;
162 
163  nbits = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24;
164  escape = av_mod_uintp2(16383, nbits);
165  cnt1 = get_unary(bc, 0, 8);
166  if (cnt1 > 7) {
167  rlen = get_bits(bc, 16);
168  } else {
169  value = show_bits(bc, nbits);
170  if (value > 1) {
171  skip_bits(bc, nbits);
172  rlen = value + escape * cnt1 - 1;
173  } else {
174  skip_bits(bc, nbits - 1);
175  rlen = escape * cnt1;
176  }
177  }
178 
179  if (rlen > size - i)
180  return AVERROR_INVALIDDATA;
181  i += rlen;
182 
183  for (k = 0; k < rlen; k++) {
184  dst[j++] = 0;
185  if (j == width) {
186  j = 0;
187  dst += stride;
188  }
189  }
190 
191  state = 0;
192  flag = rlen < 0xFFFF ? 1 : 0;
193  }
194 
195  align_get_bits(bc);
196  return get_bits_count(bc) >> 3;
197 }
198 
199 static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst,
200  int size, int c, int a, int d,
201  int width, ptrdiff_t stride)
202 {
203  PixletContext *ctx = avctx->priv_data;
204  GetBitContext *bc = &ctx->bc;
205  unsigned cnt1, shbits, rlen, nbits, length, i = 0, j = 0, k;
206  int ret, escape, pfx, value, yflag, xflag, flag = 0;
207  int64_t state = 3, tmp;
208 
209  ret = init_get_bits8(bc, src, bytestream2_get_bytes_left(&ctx->gb));
210  if (ret < 0)
211  return ret;
212 
213  if (a ^ (a >> 31)) {
214  nbits = 33 - ff_clz(a ^ (a >> 31));
215  if (nbits > 16)
216  return AVERROR_INVALIDDATA;
217  } else {
218  nbits = 1;
219  }
220 
221  length = 25 - nbits;
222 
223  while (i < size) {
224  if (state >> 8 != -3)
225  value = ff_clz((state >> 8) + 3) ^ 0x1F;
226  else
227  value = -1;
228 
229  cnt1 = get_unary(bc, 0, length);
230  if (cnt1 >= length) {
231  cnt1 = get_bits(bc, nbits);
232  } else {
233  pfx = 14 + ((((uint64_t)(value - 14)) >> 32) & (value - 14));
234  if (pfx < 1 || pfx > 25)
235  return AVERROR_INVALIDDATA;
236  cnt1 *= (1 << pfx) - 1;
237  shbits = show_bits(bc, pfx);
238  if (shbits <= 1) {
239  skip_bits(bc, pfx - 1);
240  } else {
241  skip_bits(bc, pfx);
242  cnt1 += shbits - 1;
243  }
244  }
245 
246  xflag = flag + cnt1;
247  yflag = xflag;
248 
249  if (flag + cnt1 == 0) {
250  value = 0;
251  } else {
252  xflag &= 1u;
253  tmp = (int64_t)c * ((yflag + 1) >> 1) + (c >> 1);
254  value = xflag + (tmp ^ -xflag);
255  }
256 
257  i++;
258  dst[j++] = value;
259  if (j == width) {
260  j = 0;
261  dst += stride;
262  }
263  state += (int64_t)d * (uint64_t)yflag - ((int64_t)(d * (uint64_t)state) >> 8);
264 
265  flag = 0;
266 
267  if ((uint64_t)state > 0xFF / 4 || i >= size)
268  continue;
269 
270  pfx = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24;
271  escape = av_mod_uintp2(16383, pfx);
272  cnt1 = get_unary(bc, 0, 8);
273  if (cnt1 < 8) {
274  if (pfx < 1 || pfx > 25)
275  return AVERROR_INVALIDDATA;
276 
277  value = show_bits(bc, pfx);
278  if (value > 1) {
279  skip_bits(bc, pfx);
280  rlen = value + escape * cnt1 - 1;
281  } else {
282  skip_bits(bc, pfx - 1);
283  rlen = escape * cnt1;
284  }
285  } else {
286  if (get_bits1(bc))
287  value = get_bits(bc, 16);
288  else
289  value = get_bits(bc, 8);
290 
291  rlen = value + 8 * escape;
292  }
293 
294  if (rlen > 0xFFFF || i + rlen > size)
295  return AVERROR_INVALIDDATA;
296  i += rlen;
297 
298  for (k = 0; k < rlen; k++) {
299  dst[j++] = 0;
300  if (j == width) {
301  j = 0;
302  dst += stride;
303  }
304  }
305 
306  state = 0;
307  flag = rlen < 0xFFFF ? 1 : 0;
308  }
309 
310  align_get_bits(bc);
311  return get_bits_count(bc) >> 3;
312 }
313 
314 static int read_highpass(AVCodecContext *avctx, uint8_t *ptr,
315  int plane, AVFrame *frame)
316 {
317  PixletContext *ctx = avctx->priv_data;
318  ptrdiff_t stride = frame->linesize[plane] / 2;
319  int i, ret;
320 
321  for (i = 0; i < ctx->levels * 3; i++) {
322  int32_t a = bytestream2_get_be32(&ctx->gb);
323  int32_t b = bytestream2_get_be32(&ctx->gb);
324  int32_t c = bytestream2_get_be32(&ctx->gb);
325  int32_t d = bytestream2_get_be32(&ctx->gb);
326  int16_t *dest = (int16_t *)frame->data[plane] +
327  ctx->band[plane][i + 1].x +
328  ctx->band[plane][i + 1].y * stride;
329  unsigned size = ctx->band[plane][i + 1].size;
330  uint32_t magic = bytestream2_get_be32(&ctx->gb);
331 
332  if (magic != PIXLET_MAGIC) {
333  av_log(avctx, AV_LOG_ERROR,
334  "wrong magic number: 0x%08"PRIX32" for plane %d, band %d\n",
335  magic, plane, i);
336  return AVERROR_INVALIDDATA;
337  }
338 
339  if (a == INT32_MIN)
340  return AVERROR_INVALIDDATA;
341 
342  ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size,
343  c, (b >= FFABS(a)) ? b : a, d,
344  ctx->band[plane][i + 1].width, stride);
345  if (ret < 0) {
346  av_log(avctx, AV_LOG_ERROR,
347  "error in highpass coefficients for plane %d, band %d\n",
348  plane, i);
349  return ret;
350  }
351  bytestream2_skip(&ctx->gb, ret);
352  }
353 
354  return 0;
355 }
356 
357 static void lowpass_prediction(int16_t *dst, int16_t *pred,
358  int width, int height, ptrdiff_t stride)
359 {
360  int16_t val;
361  int i, j;
362 
363  memset(pred, 0, width * sizeof(*pred));
364 
365  for (i = 0; i < height; i++) {
366  val = pred[0] + dst[0];
367  dst[0] = pred[0] = val;
368  for (j = 1; j < width; j++) {
369  val = pred[j] + dst[j];
370  dst[j] = pred[j] = val;
371  dst[j] += dst[j-1];
372  }
373  dst += stride;
374  }
375 }
376 
377 static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale)
378 {
379  int16_t *low, *high, *ll, *lh, *hl, *hh;
380  int hsize, i, j;
381  int64_t value;
382 
383  hsize = size >> 1;
384  low = tmp + 4;
385  high = &low[hsize + 8];
386 
387  memcpy(low, dest, size);
388  memcpy(high, dest + hsize, size);
389 
390  ll = &low[hsize];
391  lh = &low[hsize];
392  hl = &high[hsize];
393  hh = hl;
394  for (i = 4, j = 2; i; i--, j++, ll--, hh++, lh++, hl--) {
395  low[i - 5] = low[j - 1];
396  lh[0] = ll[-1];
397  high[i - 5] = high[j - 2];
398  hh[0] = hl[-2];
399  }
400 
401  for (i = 0; i < hsize; i++) {
402  value = (int64_t) low [i + 1] * -INT64_C(325392907) +
403  (int64_t) low [i + 0] * INT64_C(3687786320) +
404  (int64_t) low [i - 1] * -INT64_C(325392907) +
405  (int64_t) high[i + 0] * INT64_C(1518500249) +
406  (int64_t) high[i - 1] * INT64_C(1518500249);
407  dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32);
408  }
409 
410  for (i = 0; i < hsize; i++) {
411  value = (int64_t) low [i + 2] * -INT64_C(65078576) +
412  (int64_t) low [i + 1] * INT64_C(1583578880) +
413  (int64_t) low [i + 0] * INT64_C(1583578880) +
414  (int64_t) low [i - 1] * -INT64_C(65078576) +
415  (int64_t) high[i + 1] * INT64_C(303700064) +
416  (int64_t) high[i + 0] * -INT64_C(3644400640) +
417  (int64_t) high[i - 1] * INT64_C(303700064);
418  dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32);
419  }
420 }
421 
422 static void reconstruction(AVCodecContext *avctx, int16_t *dest,
423  unsigned width, unsigned height, ptrdiff_t stride,
424  int64_t *scaling_h, int64_t *scaling_v)
425 {
426  PixletContext *ctx = avctx->priv_data;
427  unsigned scaled_width, scaled_height;
428  int16_t *ptr, *tmp;
429  int i, j, k;
430 
431  scaled_width = width >> NB_LEVELS;
432  scaled_height = height >> NB_LEVELS;
433  tmp = ctx->filter[0];
434 
435  for (i = 0; i < NB_LEVELS; i++) {
436  int64_t scale_v = scaling_v[i];
437  int64_t scale_h = scaling_h[i];
438  scaled_width <<= 1;
439  scaled_height <<= 1;
440 
441  ptr = dest;
442  for (j = 0; j < scaled_height; j++) {
443  filterfn(ptr, ctx->filter[1], scaled_width, scale_v);
444  ptr += stride;
445  }
446 
447  for (j = 0; j < scaled_width; j++) {
448  ptr = dest + j;
449  for (k = 0; k < scaled_height; k++) {
450  tmp[k] = *ptr;
451  ptr += stride;
452  }
453 
454  filterfn(tmp, ctx->filter[1], scaled_height, scale_h);
455 
456  ptr = dest + j;
457  for (k = 0; k < scaled_height; k++) {
458  *ptr = tmp[k];
459  ptr += stride;
460  }
461  }
462  }
463 }
464 
465 static void postprocess_luma(AVFrame *frame, int w, int h, int depth)
466 {
467  uint16_t *dsty = (uint16_t *)frame->data[0];
468  int16_t *srcy = (int16_t *)frame->data[0];
469  ptrdiff_t stridey = frame->linesize[0] / 2;
470  int i, j;
471 
472  for (j = 0; j < h; j++) {
473  for (i = 0; i < w; i++) {
474  if (srcy[i] <= 0)
475  dsty[i] = 0;
476  else if (srcy[i] > ((1 << depth) - 1))
477  dsty[i] = 65535;
478  else
479  dsty[i] = ((int64_t) srcy[i] * srcy[i] * 65535) /
480  ((1 << depth) - 1) / ((1 << depth) - 1);
481  }
482  dsty += stridey;
483  srcy += stridey;
484  }
485 }
486 
487 static void postprocess_chroma(AVFrame *frame, int w, int h, int depth)
488 {
489  uint16_t *dstu = (uint16_t *)frame->data[1];
490  uint16_t *dstv = (uint16_t *)frame->data[2];
491  int16_t *srcu = (int16_t *)frame->data[1];
492  int16_t *srcv = (int16_t *)frame->data[2];
493  ptrdiff_t strideu = frame->linesize[1] / 2;
494  ptrdiff_t stridev = frame->linesize[2] / 2;
495  const unsigned add = 1 << (depth - 1);
496  const unsigned shift = 16 - depth;
497  int i, j;
498 
499  for (j = 0; j < h; j++) {
500  for (i = 0; i < w; i++) {
501  dstu[i] = av_clip_uintp2_c(add + srcu[i], depth) << shift;
502  dstv[i] = av_clip_uintp2_c(add + srcv[i], depth) << shift;
503  }
504  dstu += strideu;
505  dstv += stridev;
506  srcu += strideu;
507  srcv += stridev;
508  }
509 }
510 
511 static int decode_plane(AVCodecContext *avctx, int plane,
512  AVPacket *avpkt, AVFrame *frame)
513 {
514  PixletContext *ctx = avctx->priv_data;
515  ptrdiff_t stride = frame->linesize[plane] / 2;
516  unsigned shift = plane > 0;
517  int16_t *dst;
518  int i, ret;
519 
520  for (i = ctx->levels - 1; i >= 0; i--) {
521  int32_t h = sign_extend(bytestream2_get_be32(&ctx->gb), 32);
522  int32_t v = sign_extend(bytestream2_get_be32(&ctx->gb), 32);
523 
524  if (!h || !v)
525  return AVERROR_INVALIDDATA;
526 
527  ctx->scaling[plane][H][i] = (1000000ULL << 32) / h;
528  ctx->scaling[plane][V][i] = (1000000ULL << 32) / v;
529  }
530 
531  bytestream2_skip(&ctx->gb, 4);
532 
533  dst = (int16_t *)frame->data[plane];
534  dst[0] = sign_extend(bytestream2_get_be16(&ctx->gb), 16);
535 
536  ret = init_get_bits8(&ctx->bc, avpkt->data + bytestream2_tell(&ctx->gb),
538  if (ret < 0)
539  return ret;
540 
541  ret = read_low_coeffs(avctx, dst + 1, ctx->band[plane][0].width - 1,
542  ctx->band[plane][0].width - 1, 0);
543  if (ret < 0) {
544  av_log(avctx, AV_LOG_ERROR,
545  "error in lowpass coefficients for plane %d, top row\n", plane);
546  return ret;
547  }
548 
549  ret = read_low_coeffs(avctx, dst + stride,
550  ctx->band[plane][0].height - 1, 1, stride);
551  if (ret < 0) {
552  av_log(avctx, AV_LOG_ERROR,
553  "error in lowpass coefficients for plane %d, left column\n",
554  plane);
555  return ret;
556  }
557 
558  ret = read_low_coeffs(avctx, dst + stride + 1,
559  (ctx->band[plane][0].width - 1) * (ctx->band[plane][0].height - 1),
560  ctx->band[plane][0].width - 1, stride);
561  if (ret < 0) {
562  av_log(avctx, AV_LOG_ERROR,
563  "error in lowpass coefficients for plane %d, rest\n", plane);
564  return ret;
565  }
566 
567  bytestream2_skip(&ctx->gb, ret);
568  if (bytestream2_get_bytes_left(&ctx->gb) <= 0) {
569  av_log(avctx, AV_LOG_ERROR, "no bytes left\n");
570  return AVERROR_INVALIDDATA;
571  }
572 
573  ret = read_highpass(avctx, avpkt->data, plane, frame);
574  if (ret < 0)
575  return ret;
576 
577  lowpass_prediction(dst, ctx->prediction, ctx->band[plane][0].width,
578  ctx->band[plane][0].height, stride);
579 
580  reconstruction(avctx, (int16_t *)frame->data[plane], ctx->w >> shift,
581  ctx->h >> shift, stride, ctx->scaling[plane][H],
582  ctx->scaling[plane][V]);
583 
584  return 0;
585 }
586 
587 static int pixlet_decode_frame(AVCodecContext *avctx, void *data,
588  int *got_frame, AVPacket *avpkt)
589 {
590  PixletContext *ctx = avctx->priv_data;
591  int i, w, h, width, height, ret, version;
592  AVFrame *p = data;
593  ThreadFrame frame = { .f = data };
594  uint32_t pktsize;
595 
596  bytestream2_init(&ctx->gb, avpkt->data, avpkt->size);
597 
598  pktsize = bytestream2_get_be32(&ctx->gb);
599  if (pktsize <= 44 || pktsize - 4 > bytestream2_get_bytes_left(&ctx->gb)) {
600  av_log(avctx, AV_LOG_ERROR, "Invalid packet size %"PRIu32"\n", pktsize);
601  return AVERROR_INVALIDDATA;
602  }
603 
604  version = bytestream2_get_le32(&ctx->gb);
605  if (version != 1)
606  avpriv_request_sample(avctx, "Version %d", version);
607 
608  bytestream2_skip(&ctx->gb, 4);
609  if (bytestream2_get_be32(&ctx->gb) != 1)
610  return AVERROR_INVALIDDATA;
611  bytestream2_skip(&ctx->gb, 4);
612 
613  width = bytestream2_get_be32(&ctx->gb);
614  height = bytestream2_get_be32(&ctx->gb);
615 
616  if ( width > INT_MAX - (1U << (NB_LEVELS + 1))
617  || height > INT_MAX - (1U << (NB_LEVELS + 1)))
618  return AVERROR_INVALIDDATA;
619 
620  w = FFALIGN(width, 1 << (NB_LEVELS + 1));
621  h = FFALIGN(height, 1 << (NB_LEVELS + 1));
622 
623  ctx->levels = bytestream2_get_be32(&ctx->gb);
624  if (ctx->levels != NB_LEVELS)
625  return AVERROR_INVALIDDATA;
626  ctx->depth = bytestream2_get_be32(&ctx->gb);
627  if (ctx->depth < 8 || ctx->depth > 15) {
628  avpriv_request_sample(avctx, "Depth %d", ctx->depth);
629  return AVERROR_INVALIDDATA;
630  }
631 
632  ret = ff_set_dimensions(avctx, w, h);
633  if (ret < 0)
634  return ret;
635  avctx->width = width;
636  avctx->height = height;
637 
638  if (ctx->w != w || ctx->h != h) {
639  free_buffers(avctx);
640  ctx->w = w;
641  ctx->h = h;
642 
643  ret = init_decoder(avctx);
644  if (ret < 0) {
645  free_buffers(avctx);
646  ctx->w = 0;
647  ctx->h = 0;
648  return ret;
649  }
650  }
651 
652  bytestream2_skip(&ctx->gb, 8);
653 
655  p->key_frame = 1;
657 
658  ret = ff_thread_get_buffer(avctx, &frame, 0);
659  if (ret < 0)
660  return ret;
661 
662  for (i = 0; i < 3; i++) {
663  ret = decode_plane(avctx, i, avpkt, frame.f);
664  if (ret < 0)
665  return ret;
666  if (avctx->flags & AV_CODEC_FLAG_GRAY)
667  break;
668  }
669 
670  postprocess_luma(frame.f, ctx->w, ctx->h, ctx->depth);
671  postprocess_chroma(frame.f, ctx->w >> 1, ctx->h >> 1, ctx->depth);
672 
673  *got_frame = 1;
674 
675  return pktsize;
676 }
677 
678 #if HAVE_THREADS
679 static int pixlet_init_thread_copy(AVCodecContext *avctx)
680 {
681  PixletContext *ctx = avctx->priv_data;
682 
683  ctx->filter[0] = NULL;
684  ctx->filter[1] = NULL;
685  ctx->prediction = NULL;
686  ctx->w = 0;
687  ctx->h = 0;
688 
689  return 0;
690 }
691 #endif /* HAVE_THREADS */
692 
694  .name = "pixlet",
695  .long_name = NULL_IF_CONFIG_SMALL("Apple Pixlet"),
696  .type = AVMEDIA_TYPE_VIDEO,
697  .id = AV_CODEC_ID_PIXLET,
698  .init = pixlet_init,
699  .init_thread_copy = ONLY_IF_THREADS_ENABLED(pixlet_init_thread_copy),
700  .close = pixlet_close,
701  .decode = pixlet_decode_frame,
702  .priv_data_size = sizeof(PixletContext),
703  .capabilities = AV_CODEC_CAP_DR1 |
705  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
707 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
int plane
Definition: avisynth_c.h:384
SubBand band[4][NB_LEVELS *3+1]
Definition: pixlet.c:61
#define NULL
Definition: coverity.c:32
const char const char void * val
Definition: avisynth_c.h:863
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int16_t * filter[2]
Definition: pixlet.c:58
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
misc image utilities
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
AVFrame * f
Definition: thread.h:35
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:104
#define avpriv_request_sample(...)
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:2200
int size
Definition: avcodec.h:1478
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
int version
Definition: avisynth_c.h:858
static int read_low_coeffs(AVCodecContext *avctx, int16_t *dst, int size, int width, ptrdiff_t stride)
Definition: pixlet.c:124
ptrdiff_t stride
Definition: cfhd.h:47
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3481
int width
Definition: cfhd.h:49
#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 av_cold
Definition: attributes.h:82
AVOptions.
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.
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
static void free_buffers(AVCodecContext *avctx)
Definition: pixlet.c:71
uint8_t * data
Definition: avcodec.h:1477
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
bitstream reader API header.
static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale)
Definition: pixlet.c:377
ptrdiff_t size
Definition: opengl_enc.c:100
#define AV_CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition: avcodec.h:883
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
unsigned x
Definition: pixlet.c:45
Definition: cfhd.h:44
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
unsigned length
Definition: diracdec.c:102
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
static int decode_plane(AVCodecContext *avctx, int plane, AVPacket *avpkt, AVFrame *frame)
Definition: pixlet.c:511
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
GetBitContext bc
Definition: pixlet.c:52
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: frame.h:539
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1645
static void postprocess_luma(AVFrame *frame, int w, int h, int depth)
Definition: pixlet.c:465
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
int levels
Definition: pixlet.c:54
#define FFMAX(a, b)
Definition: common.h:94
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: avcodec.h:1037
#define ONLY_IF_THREADS_ENABLED(x)
Define a function with only the non-default version specified.
Definition: internal.h:225
static int read_highpass(AVCodecContext *avctx, uint8_t *ptr, int plane, AVFrame *frame)
Definition: pixlet.c:314
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
#define FFMIN(a, b)
Definition: common.h:96
#define ff_clz
Definition: intmath.h:142
int width
picture width / height.
Definition: avcodec.h:1738
uint8_t w
Definition: llviddspenc.c:38
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
static unsigned int show_bits(GetBitContext *s, int n)
Show 1-25 bits.
Definition: get_bits.h:446
int depth
Definition: pixlet.c:55
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
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
static int init_decoder(AVCodecContext *avctx)
Definition: pixlet.c:89
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:522
static const float pred[4]
Definition: siprdata.h:259
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:398
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int64_t scaling[4][2][NB_LEVELS]
Definition: pixlet.c:60
static av_cold int pixlet_init(AVCodecContext *avctx)
Definition: pixlet.c:64
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
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 NB_LEVELS
Definition: pixlet.c:35
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
Describe the class of an AVClass context structure.
Definition: log.h:67
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
static void postprocess_chroma(AVFrame *frame, int w, int h, int depth)
Definition: pixlet.c:487
GetByteContext gb
Definition: pixlet.c:51
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:130
static int pixlet_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: pixlet.c:587
static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst, int size, int c, int a, int d, int width, ptrdiff_t stride)
Definition: pixlet.c:199
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
unsigned y
Definition: pixlet.c:45
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
common internal api header.
static int get_unary(GetBitContext *gb, int stop, int len)
Get unary code of limited length.
Definition: unary.h:46
#define flag(name)
Definition: cbs_av1.c:553
unsigned size
Definition: pixlet.c:44
uint8_t state[7+512][32]
Definition: snow.h:96
unsigned width
Definition: pixlet.c:43
void * priv_data
Definition: avcodec.h:1592
#define V
Definition: pixlet.c:40
#define H
Definition: pixlet.c:39
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
int height
Definition: cfhd.h:51
int16_t * prediction
Definition: pixlet.c:59
static const uint8_t * align_get_bits(GetBitContext *s)
Definition: get_bits.h:693
static void reconstruction(AVCodecContext *avctx, int16_t *dest, unsigned width, unsigned height, ptrdiff_t stride, int64_t *scaling_h, int64_t *scaling_v)
Definition: pixlet.c:422
#define av_freep(p)
#define PIXLET_MAGIC
Definition: pixlet.c:37
#define av_malloc_array(a, b)
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
static void lowpass_prediction(int16_t *dst, int16_t *pred, int width, int height, ptrdiff_t stride)
Definition: pixlet.c:357
static av_cold int pixlet_close(AVCodecContext *avctx)
Definition: pixlet.c:80
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodec ff_pixlet_decoder
Definition: pixlet.c:693
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
Clip a signed integer to an unsigned power of two range.
Definition: common.h:229
static uint8_t tmp[11]
Definition: aes_ctr.c:26