LCOV - code coverage report
Current view: top level - libavcodec - pixlet.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 330 407 81.1 %
Date: 2017-12-14 08:27:08 Functions: 14 15 93.3 %

          Line data    Source code
       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             : 
      51             :     GetByteContext gb;
      52             :     GetBitContext bc;
      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];
      62             : } PixletContext;
      63             : 
      64           2 : static av_cold int pixlet_init(AVCodecContext *avctx)
      65             : {
      66           2 :     avctx->pix_fmt     = AV_PIX_FMT_YUV420P16;
      67           2 :     avctx->color_range = AVCOL_RANGE_JPEG;
      68           2 :     return 0;
      69             : }
      70             : 
      71           3 : static void free_buffers(AVCodecContext *avctx)
      72             : {
      73           3 :     PixletContext *ctx = avctx->priv_data;
      74             : 
      75           3 :     av_freep(&ctx->filter[0]);
      76           3 :     av_freep(&ctx->filter[1]);
      77           3 :     av_freep(&ctx->prediction);
      78           3 : }
      79             : 
      80           2 : static av_cold int pixlet_close(AVCodecContext *avctx)
      81             : {
      82           2 :     PixletContext *ctx = avctx->priv_data;
      83           2 :     free_buffers(avctx);
      84           2 :     ctx->w = 0;
      85           2 :     ctx->h = 0;
      86           2 :     return 0;
      87             : }
      88             : 
      89           1 : static int init_decoder(AVCodecContext *avctx)
      90             : {
      91           1 :     PixletContext *ctx = avctx->priv_data;
      92             :     int i, plane;
      93             : 
      94           1 :     ctx->filter[0]  = av_malloc_array(ctx->h, sizeof(int16_t));
      95           1 :     ctx->filter[1]  = av_malloc_array(FFMAX(ctx->h, ctx->w) + 16, sizeof(int16_t));
      96           1 :     ctx->prediction = av_malloc_array((ctx->w >> NB_LEVELS), sizeof(int16_t));
      97           1 :     if (!ctx->filter[0] || !ctx->filter[1] || !ctx->prediction)
      98           0 :         return AVERROR(ENOMEM);
      99             : 
     100           4 :     for (plane = 0; plane < 3; plane++) {
     101           3 :         unsigned shift = plane > 0;
     102           3 :         unsigned w     = ctx->w >> shift;
     103           3 :         unsigned h     = ctx->h >> shift;
     104             : 
     105           3 :         ctx->band[plane][0].width  =  w >> NB_LEVELS;
     106           3 :         ctx->band[plane][0].height =  h >> NB_LEVELS;
     107           3 :         ctx->band[plane][0].size   = (w >> NB_LEVELS) * (h >> NB_LEVELS);
     108             : 
     109          39 :         for (i = 0; i < NB_LEVELS * 3; i++) {
     110          36 :             unsigned scale = ctx->levels - (i / 3);
     111             : 
     112          36 :             ctx->band[plane][i + 1].width  =  w >> scale;
     113          36 :             ctx->band[plane][i + 1].height =  h >> scale;
     114          36 :             ctx->band[plane][i + 1].size   = (w >> scale) * (h >> scale);
     115             : 
     116          36 :             ctx->band[plane][i + 1].x = (w >> scale) * (((i + 1) % 3) != 2);
     117          36 :             ctx->band[plane][i + 1].y = (h >> scale) * (((i + 1) % 3) != 1);
     118             :         }
     119             :     }
     120             : 
     121           1 :     return 0;
     122             : }
     123             : 
     124           9 : static int read_low_coeffs(AVCodecContext *avctx, int16_t *dst, int size,
     125             :                            int width, ptrdiff_t stride)
     126             : {
     127           9 :     PixletContext *ctx = avctx->priv_data;
     128           9 :     GetBitContext *bc = &ctx->bc;
     129           9 :     unsigned cnt1, nbits, k, j = 0, i = 0;
     130           9 :     int64_t value, state = 3;
     131           9 :     int rlen, escape, flag = 0;
     132             : 
     133          21 :     while (i < size) {
     134           3 :         nbits = FFMIN(ff_clz((state >> 8) + 3) ^ 0x1F, 14);
     135             : 
     136           3 :         cnt1 = get_unary(bc, 0, 8);
     137           3 :         if (cnt1 < 8) {
     138           0 :             value = show_bits(bc, nbits);
     139           0 :             if (value <= 1) {
     140           0 :                 skip_bits(bc, nbits - 1);
     141           0 :                 escape = ((1 << nbits) - 1) * cnt1;
     142             :             } else {
     143           0 :                 skip_bits(bc, nbits);
     144           0 :                 escape = value + ((1 << nbits) - 1) * cnt1 - 1;
     145             :             }
     146             :         } else {
     147           3 :             escape = get_bits(bc, 16);
     148             :         }
     149             : 
     150           3 :         value    = -((escape + flag) & 1) | 1;
     151           3 :         dst[j++] = value * ((escape + flag + 1) >> 1);
     152           3 :         i++;
     153           3 :         if (j == width) {
     154           3 :             j    = 0;
     155           3 :             dst += stride;
     156             :         }
     157           3 :         state = 120 * (escape + flag) + state - (120 * state >> 8);
     158           3 :         flag  = 0;
     159             : 
     160           3 :         if (state * 4ULL > 0xFF || i >= size)
     161           3 :             continue;
     162             : 
     163           0 :         nbits  = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24;
     164           0 :         escape = av_mod_uintp2(16383, nbits);
     165           0 :         cnt1   = get_unary(bc, 0, 8);
     166           0 :         if (cnt1 > 7) {
     167           0 :             rlen = get_bits(bc, 16);
     168             :         } else {
     169           0 :             value = show_bits(bc, nbits);
     170           0 :             if (value > 1) {
     171           0 :                 skip_bits(bc, nbits);
     172           0 :                 rlen = value + escape * cnt1 - 1;
     173             :             } else {
     174           0 :                 skip_bits(bc, nbits - 1);
     175           0 :                 rlen = escape * cnt1;
     176             :             }
     177             :         }
     178             : 
     179           0 :         if (rlen > size - i)
     180           0 :             return AVERROR_INVALIDDATA;
     181           0 :         i += rlen;
     182             : 
     183           0 :         for (k = 0; k < rlen; k++) {
     184           0 :             dst[j++] = 0;
     185           0 :             if (j == width) {
     186           0 :                 j    = 0;
     187           0 :                 dst += stride;
     188             :             }
     189             :         }
     190             : 
     191           0 :         state = 0;
     192           0 :         flag  = rlen < 0xFFFF ? 1 : 0;
     193             :     }
     194             : 
     195           9 :     align_get_bits(bc);
     196           9 :     return get_bits_count(bc) >> 3;
     197             : }
     198             : 
     199          36 : 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          36 :     PixletContext *ctx = avctx->priv_data;
     204          36 :     GetBitContext *bc = &ctx->bc;
     205          36 :     unsigned cnt1, shbits, rlen, nbits, length, i = 0, j = 0, k;
     206          36 :     int ret, escape, pfx, value, yflag, xflag, flag = 0;
     207          36 :     int64_t state = 3, tmp;
     208             : 
     209          36 :     ret = init_get_bits8(bc, src, bytestream2_get_bytes_left(&ctx->gb));
     210          36 :     if (ret < 0)
     211           0 :         return ret;
     212             : 
     213          36 :     if (a ^ (a >> 31)) {
     214          36 :         nbits = 33 - ff_clz(a ^ (a >> 31));
     215          36 :         if (nbits > 16)
     216           0 :             return AVERROR_INVALIDDATA;
     217             :     } else {
     218           0 :         nbits = 1;
     219             :     }
     220             : 
     221          36 :     length = 25 - nbits;
     222             : 
     223         787 :     while (i < size) {
     224         715 :         if (state >> 8 != -3)
     225         715 :             value = ff_clz((state >> 8) + 3) ^ 0x1F;
     226             :         else
     227           0 :             value = -1;
     228             : 
     229         715 :         cnt1 = get_unary(bc, 0, length);
     230         715 :         if (cnt1 >= length) {
     231          46 :             cnt1 = get_bits(bc, nbits);
     232             :         } else {
     233         669 :             pfx = 14 + ((((uint64_t)(value - 14)) >> 32) & (value - 14));
     234         669 :             if (pfx < 1 || pfx > 25)
     235           0 :                 return AVERROR_INVALIDDATA;
     236         669 :             cnt1 *= (1 << pfx) - 1;
     237         669 :             shbits = show_bits(bc, pfx);
     238         669 :             if (shbits <= 1) {
     239         394 :                 skip_bits(bc, pfx - 1);
     240             :             } else {
     241         275 :                 skip_bits(bc, pfx);
     242         275 :                 cnt1 += shbits - 1;
     243             :             }
     244             :         }
     245             : 
     246         715 :         xflag = flag + cnt1;
     247         715 :         yflag = xflag;
     248             : 
     249         715 :         if (flag + cnt1 == 0) {
     250         251 :             value = 0;
     251             :         } else {
     252         464 :             xflag &= 1u;
     253         464 :             tmp    = (int64_t)c * ((yflag + 1) >> 1) + (c >> 1);
     254         464 :             value  = xflag + (tmp ^ -xflag);
     255             :         }
     256             : 
     257         715 :         i++;
     258         715 :         dst[j++] = value;
     259         715 :         if (j == width) {
     260          85 :             j    = 0;
     261          85 :             dst += stride;
     262             :         }
     263         715 :         state += (int64_t)d * (uint64_t)yflag - ((int64_t)(d * (uint64_t)state) >> 8);
     264             : 
     265         715 :         flag = 0;
     266             : 
     267         715 :         if ((uint64_t)state > 0xFF / 4 || i >= size)
     268         651 :             continue;
     269             : 
     270          64 :         pfx    = ((state + 8) >> 5) + (state ? ff_clz(state) : 32) - 24;
     271          64 :         escape = av_mod_uintp2(16383, pfx);
     272          64 :         cnt1   = get_unary(bc, 0, 8);
     273          64 :         if (cnt1 < 8) {
     274          62 :             if (pfx < 1 || pfx > 25)
     275           0 :                 return AVERROR_INVALIDDATA;
     276             : 
     277          62 :             value = show_bits(bc, pfx);
     278          62 :             if (value > 1) {
     279          40 :                 skip_bits(bc, pfx);
     280          40 :                 rlen = value + escape * cnt1 - 1;
     281             :             } else {
     282          22 :                 skip_bits(bc, pfx - 1);
     283          22 :                 rlen = escape * cnt1;
     284             :             }
     285             :         } else {
     286           2 :             if (get_bits1(bc))
     287           0 :                 value = get_bits(bc, 16);
     288             :             else
     289           2 :                 value = get_bits(bc, 8);
     290             : 
     291           2 :             rlen = value + 8 * escape;
     292             :         }
     293             : 
     294          64 :         if (rlen > 0xFFFF || i + rlen > size)
     295           0 :             return AVERROR_INVALIDDATA;
     296          64 :         i += rlen;
     297             : 
     298         879 :         for (k = 0; k < rlen; k++) {
     299         815 :             dst[j++] = 0;
     300         815 :             if (j == width) {
     301          95 :                 j    = 0;
     302          95 :                 dst += stride;
     303             :             }
     304             :         }
     305             : 
     306          64 :         state = 0;
     307          64 :         flag  = rlen < 0xFFFF ? 1 : 0;
     308             :     }
     309             : 
     310          36 :     align_get_bits(bc);
     311          36 :     return get_bits_count(bc) >> 3;
     312             : }
     313             : 
     314           3 : static int read_highpass(AVCodecContext *avctx, uint8_t *ptr,
     315             :                          int plane, AVFrame *frame)
     316             : {
     317           3 :     PixletContext *ctx = avctx->priv_data;
     318           3 :     ptrdiff_t stride = frame->linesize[plane] / 2;
     319             :     int i, ret;
     320             : 
     321          39 :     for (i = 0; i < ctx->levels * 3; i++) {
     322          36 :         int32_t a = bytestream2_get_be32(&ctx->gb);
     323          36 :         int32_t b = bytestream2_get_be32(&ctx->gb);
     324          36 :         int32_t c = bytestream2_get_be32(&ctx->gb);
     325          36 :         int32_t d = bytestream2_get_be32(&ctx->gb);
     326          72 :         int16_t *dest = (int16_t *)frame->data[plane] +
     327          72 :                         ctx->band[plane][i + 1].x +
     328          36 :                         ctx->band[plane][i + 1].y * stride;
     329          36 :         unsigned size = ctx->band[plane][i + 1].size;
     330          36 :         uint32_t magic = bytestream2_get_be32(&ctx->gb);
     331             : 
     332          36 :         if (magic != PIXLET_MAGIC) {
     333           0 :             av_log(avctx, AV_LOG_ERROR,
     334             :                    "wrong magic number: 0x%08"PRIX32" for plane %d, band %d\n",
     335             :                    magic, plane, i);
     336           0 :             return AVERROR_INVALIDDATA;
     337             :         }
     338             : 
     339          36 :         if (a == INT32_MIN)
     340           0 :             return AVERROR_INVALIDDATA;
     341             : 
     342          72 :         ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size,
     343          36 :                                c, (b >= FFABS(a)) ? b : a, d,
     344          36 :                                ctx->band[plane][i + 1].width, stride);
     345          36 :         if (ret < 0) {
     346           0 :             av_log(avctx, AV_LOG_ERROR,
     347             :                    "error in highpass coefficients for plane %d, band %d\n",
     348             :                    plane, i);
     349           0 :             return ret;
     350             :         }
     351          36 :         bytestream2_skip(&ctx->gb, ret);
     352             :     }
     353             : 
     354           3 :     return 0;
     355             : }
     356             : 
     357           3 : 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           3 :     memset(pred, 0, width * sizeof(*pred));
     364             : 
     365           7 :     for (i = 0; i < height; i++) {
     366           4 :         val    = pred[0] + dst[0];
     367           4 :         dst[0] = pred[0] = val;
     368           6 :         for (j = 1; j < width; j++) {
     369           2 :             val     = pred[j] + dst[j];
     370           2 :             dst[j]  = pred[j] = val;
     371           2 :             dst[j] += dst[j-1];
     372             :         }
     373           4 :         dst += stride;
     374             :     }
     375           3 : }
     376             : 
     377         240 : 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         240 :     hsize = size >> 1;
     384         240 :     low   = tmp + 4;
     385         240 :     high  = &low[hsize + 8];
     386             : 
     387         240 :     memcpy(low, dest, size);
     388         240 :     memcpy(high, dest + hsize, size);
     389             : 
     390         240 :     ll = &low[hsize];
     391         240 :     lh = &low[hsize];
     392         240 :     hl = &high[hsize];
     393         240 :     hh = hl;
     394        1200 :     for (i = 4, j = 2; i; i--, j++, ll--, hh++, lh++, hl--) {
     395         960 :         low[i - 5]  = low[j - 1];
     396         960 :         lh[0]       = ll[-1];
     397         960 :         high[i - 5] = high[j - 2];
     398         960 :         hh[0]       = hl[-2];
     399             :     }
     400             : 
     401        2280 :     for (i = 0; i < hsize; i++) {
     402        6120 :         value = (int64_t) low [i + 1] * -INT64_C(325392907)  +
     403        4080 :                 (int64_t) low [i + 0] *  INT64_C(3687786320) +
     404        4080 :                 (int64_t) low [i - 1] * -INT64_C(325392907)  +
     405        2040 :                 (int64_t) high[i + 0] *  INT64_C(1518500249) +
     406        2040 :                 (int64_t) high[i - 1] *  INT64_C(1518500249);
     407        2040 :         dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32);
     408             :     }
     409             : 
     410        2280 :     for (i = 0; i < hsize; i++) {
     411        6120 :         value = (int64_t) low [i + 2] * -INT64_C(65078576)   +
     412        4080 :                 (int64_t) low [i + 1] *  INT64_C(1583578880) +
     413        4080 :                 (int64_t) low [i + 0] *  INT64_C(1583578880) +
     414        4080 :                 (int64_t) low [i - 1] * -INT64_C(65078576)   +
     415        4080 :                 (int64_t) high[i + 1] *  INT64_C(303700064)  +
     416        2040 :                 (int64_t) high[i + 0] * -INT64_C(3644400640) +
     417        2040 :                 (int64_t) high[i - 1] *  INT64_C(303700064);
     418        2040 :         dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32);
     419             :     }
     420         240 : }
     421             : 
     422           3 : 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           3 :     PixletContext *ctx = avctx->priv_data;
     427             :     unsigned scaled_width, scaled_height;
     428             :     int16_t *ptr, *tmp;
     429             :     int i, j, k;
     430             : 
     431           3 :     scaled_width  = width  >> NB_LEVELS;
     432           3 :     scaled_height = height >> NB_LEVELS;
     433           3 :     tmp           = ctx->filter[0];
     434             : 
     435          15 :     for (i = 0; i < NB_LEVELS; i++) {
     436          12 :         int64_t scale_v = scaling_v[i];
     437          12 :         int64_t scale_h = scaling_h[i];
     438          12 :         scaled_width  <<= 1;
     439          12 :         scaled_height <<= 1;
     440             : 
     441          12 :         ptr = dest;
     442         132 :         for (j = 0; j < scaled_height; j++) {
     443         120 :             filterfn(ptr, ctx->filter[1], scaled_width, scale_v);
     444         120 :             ptr += stride;
     445             :         }
     446             : 
     447         132 :         for (j = 0; j < scaled_width; j++) {
     448         120 :             ptr = dest + j;
     449        2160 :             for (k = 0; k < scaled_height; k++) {
     450        2040 :                 tmp[k] = *ptr;
     451        2040 :                 ptr   += stride;
     452             :             }
     453             : 
     454         120 :             filterfn(tmp, ctx->filter[1], scaled_height, scale_h);
     455             : 
     456         120 :             ptr = dest + j;
     457        2160 :             for (k = 0; k < scaled_height; k++) {
     458        2040 :                 *ptr = tmp[k];
     459        2040 :                 ptr += stride;
     460             :             }
     461             :         }
     462             :     }
     463           3 : }
     464             : 
     465           1 : static void postprocess_luma(AVFrame *frame, int w, int h, int depth)
     466             : {
     467           1 :     uint16_t *dsty = (uint16_t *)frame->data[0];
     468           1 :     int16_t *srcy  = (int16_t *)frame->data[0];
     469           1 :     ptrdiff_t stridey = frame->linesize[0] / 2;
     470             :     int i, j;
     471             : 
     472          33 :     for (j = 0; j < h; j++) {
     473        1056 :         for (i = 0; i < w; i++) {
     474        1024 :             if (srcy[i] <= 0)
     475           1 :                 dsty[i] = 0;
     476        1023 :             else if (srcy[i] > ((1 << depth) - 1))
     477           0 :                 dsty[i] = 65535;
     478             :             else
     479        3069 :                 dsty[i] = ((int64_t) srcy[i] * srcy[i] * 65535) /
     480        2046 :                           ((1 << depth) - 1) / ((1 << depth) - 1);
     481             :         }
     482          32 :         dsty += stridey;
     483          32 :         srcy += stridey;
     484             :     }
     485           1 : }
     486             : 
     487           1 : static void postprocess_chroma(AVFrame *frame, int w, int h, int depth)
     488             : {
     489           1 :     uint16_t *dstu = (uint16_t *)frame->data[1];
     490           1 :     uint16_t *dstv = (uint16_t *)frame->data[2];
     491           1 :     int16_t *srcu  = (int16_t *)frame->data[1];
     492           1 :     int16_t *srcv  = (int16_t *)frame->data[2];
     493           1 :     ptrdiff_t strideu = frame->linesize[1] / 2;
     494           1 :     ptrdiff_t stridev = frame->linesize[2] / 2;
     495           1 :     const unsigned add = 1 << (depth - 1);
     496           1 :     const unsigned shift = 16 - depth;
     497             :     int i, j;
     498             : 
     499          17 :     for (j = 0; j < h; j++) {
     500         272 :         for (i = 0; i < w; i++) {
     501         256 :             dstu[i] = av_clip_uintp2_c(add + srcu[i], depth) << shift;
     502         256 :             dstv[i] = av_clip_uintp2_c(add + srcv[i], depth) << shift;
     503             :         }
     504          16 :         dstu += strideu;
     505          16 :         dstv += stridev;
     506          16 :         srcu += strideu;
     507          16 :         srcv += stridev;
     508             :     }
     509           1 : }
     510             : 
     511           3 : static int decode_plane(AVCodecContext *avctx, int plane,
     512             :                         AVPacket *avpkt, AVFrame *frame)
     513             : {
     514           3 :     PixletContext *ctx = avctx->priv_data;
     515           3 :     ptrdiff_t stride   = frame->linesize[plane] / 2;
     516           3 :     unsigned shift     = plane > 0;
     517             :     int16_t *dst;
     518             :     int i, ret;
     519             : 
     520          15 :     for (i = ctx->levels - 1; i >= 0; i--) {
     521          12 :         int32_t h = sign_extend(bytestream2_get_be32(&ctx->gb), 32);
     522          12 :         int32_t v = sign_extend(bytestream2_get_be32(&ctx->gb), 32);
     523             : 
     524          12 :         if (!h || !v)
     525           0 :             return AVERROR_INVALIDDATA;
     526             : 
     527          12 :         ctx->scaling[plane][H][i] = (1000000ULL << 32) / h;
     528          12 :         ctx->scaling[plane][V][i] = (1000000ULL << 32) / v;
     529             :     }
     530             : 
     531           3 :     bytestream2_skip(&ctx->gb, 4);
     532             : 
     533           3 :     dst    = (int16_t *)frame->data[plane];
     534           3 :     dst[0] = sign_extend(bytestream2_get_be16(&ctx->gb), 16);
     535             : 
     536           3 :     ret = init_get_bits8(&ctx->bc, avpkt->data + bytestream2_tell(&ctx->gb),
     537           3 :                          bytestream2_get_bytes_left(&ctx->gb));
     538           3 :     if (ret < 0)
     539           0 :         return ret;
     540             : 
     541           3 :     ret = read_low_coeffs(avctx, dst + 1, ctx->band[plane][0].width - 1,
     542           3 :                           ctx->band[plane][0].width - 1, 0);
     543           3 :     if (ret < 0) {
     544           0 :         av_log(avctx, AV_LOG_ERROR,
     545             :                "error in lowpass coefficients for plane %d, top row\n", plane);
     546           0 :         return ret;
     547             :     }
     548             : 
     549           3 :     ret = read_low_coeffs(avctx, dst + stride,
     550           3 :                           ctx->band[plane][0].height - 1, 1, stride);
     551           3 :     if (ret < 0) {
     552           0 :         av_log(avctx, AV_LOG_ERROR,
     553             :                "error in lowpass coefficients for plane %d, left column\n",
     554             :                plane);
     555           0 :         return ret;
     556             :     }
     557             : 
     558           6 :     ret = read_low_coeffs(avctx, dst + stride + 1,
     559           3 :                           (ctx->band[plane][0].width - 1) * (ctx->band[plane][0].height - 1),
     560           3 :                           ctx->band[plane][0].width - 1, stride);
     561           3 :     if (ret < 0) {
     562           0 :         av_log(avctx, AV_LOG_ERROR,
     563             :                "error in lowpass coefficients for plane %d, rest\n", plane);
     564           0 :         return ret;
     565             :     }
     566             : 
     567           3 :     bytestream2_skip(&ctx->gb, ret);
     568           3 :     if (bytestream2_get_bytes_left(&ctx->gb) <= 0) {
     569           0 :         av_log(avctx, AV_LOG_ERROR, "no bytes left\n");
     570           0 :         return AVERROR_INVALIDDATA;
     571             :     }
     572             : 
     573           3 :     ret = read_highpass(avctx, avpkt->data, plane, frame);
     574           3 :     if (ret < 0)
     575           0 :         return ret;
     576             : 
     577           3 :     lowpass_prediction(dst, ctx->prediction, ctx->band[plane][0].width,
     578           3 :                        ctx->band[plane][0].height, stride);
     579             : 
     580           3 :     reconstruction(avctx, (int16_t *)frame->data[plane], ctx->w >> shift,
     581           3 :                    ctx->h >> shift, stride, ctx->scaling[plane][H],
     582           3 :                    ctx->scaling[plane][V]);
     583             : 
     584           3 :     return 0;
     585             : }
     586             : 
     587           1 : static int pixlet_decode_frame(AVCodecContext *avctx, void *data,
     588             :                                int *got_frame, AVPacket *avpkt)
     589             : {
     590           1 :     PixletContext *ctx = avctx->priv_data;
     591             :     int i, w, h, width, height, ret, version;
     592           1 :     AVFrame *p = data;
     593           1 :     ThreadFrame frame = { .f = data };
     594             :     uint32_t pktsize;
     595             : 
     596           1 :     bytestream2_init(&ctx->gb, avpkt->data, avpkt->size);
     597             : 
     598           1 :     pktsize = bytestream2_get_be32(&ctx->gb);
     599           1 :     if (pktsize <= 44 || pktsize - 4 > bytestream2_get_bytes_left(&ctx->gb)) {
     600           0 :         av_log(avctx, AV_LOG_ERROR, "Invalid packet size %"PRIu32"\n", pktsize);
     601           0 :         return AVERROR_INVALIDDATA;
     602             :     }
     603             : 
     604           1 :     version = bytestream2_get_le32(&ctx->gb);
     605           1 :     if (version != 1)
     606           0 :         avpriv_request_sample(avctx, "Version %d", version);
     607             : 
     608           1 :     bytestream2_skip(&ctx->gb, 4);
     609           1 :     if (bytestream2_get_be32(&ctx->gb) != 1)
     610           0 :         return AVERROR_INVALIDDATA;
     611           1 :     bytestream2_skip(&ctx->gb, 4);
     612             : 
     613           1 :     width  = bytestream2_get_be32(&ctx->gb);
     614           1 :     height = bytestream2_get_be32(&ctx->gb);
     615             : 
     616           1 :     if (    width > INT_MAX - (1U << (NB_LEVELS + 1))
     617           1 :         || height > INT_MAX - (1U << (NB_LEVELS + 1)))
     618           0 :         return AVERROR_INVALIDDATA;
     619             : 
     620           1 :     w = FFALIGN(width,  1 << (NB_LEVELS + 1));
     621           1 :     h = FFALIGN(height, 1 << (NB_LEVELS + 1));
     622             : 
     623           1 :     ctx->levels = bytestream2_get_be32(&ctx->gb);
     624           1 :     if (ctx->levels != NB_LEVELS)
     625           0 :         return AVERROR_INVALIDDATA;
     626           1 :     ctx->depth = bytestream2_get_be32(&ctx->gb);
     627           1 :     if (ctx->depth < 8 || ctx->depth > 15) {
     628           0 :         avpriv_request_sample(avctx, "Depth %d", ctx->depth);
     629           0 :         return AVERROR_INVALIDDATA;
     630             :     }
     631             : 
     632           1 :     ret = ff_set_dimensions(avctx, w, h);
     633           1 :     if (ret < 0)
     634           0 :         return ret;
     635           1 :     avctx->width  = width;
     636           1 :     avctx->height = height;
     637             : 
     638           1 :     if (ctx->w != w || ctx->h != h) {
     639           1 :         free_buffers(avctx);
     640           1 :         ctx->w = w;
     641           1 :         ctx->h = h;
     642             : 
     643           1 :         ret = init_decoder(avctx);
     644           1 :         if (ret < 0) {
     645           0 :             free_buffers(avctx);
     646           0 :             ctx->w = 0;
     647           0 :             ctx->h = 0;
     648           0 :             return ret;
     649             :         }
     650             :     }
     651             : 
     652           1 :     bytestream2_skip(&ctx->gb, 8);
     653             : 
     654           1 :     p->pict_type = AV_PICTURE_TYPE_I;
     655           1 :     p->key_frame = 1;
     656           1 :     p->color_range = AVCOL_RANGE_JPEG;
     657             : 
     658           1 :     ret = ff_thread_get_buffer(avctx, &frame, 0);
     659           1 :     if (ret < 0)
     660           0 :         return ret;
     661             : 
     662           4 :     for (i = 0; i < 3; i++) {
     663           3 :         ret = decode_plane(avctx, i, avpkt, frame.f);
     664           3 :         if (ret < 0)
     665           0 :             return ret;
     666           3 :         if (avctx->flags & AV_CODEC_FLAG_GRAY)
     667           0 :             break;
     668             :     }
     669             : 
     670           1 :     postprocess_luma(frame.f, ctx->w, ctx->h, ctx->depth);
     671           1 :     postprocess_chroma(frame.f, ctx->w >> 1, ctx->h >> 1, ctx->depth);
     672             : 
     673           1 :     *got_frame = 1;
     674             : 
     675           1 :     return pktsize;
     676             : }
     677             : 
     678             : #if HAVE_THREADS
     679           0 : static int pixlet_init_thread_copy(AVCodecContext *avctx)
     680             : {
     681           0 :     PixletContext *ctx = avctx->priv_data;
     682             : 
     683           0 :     ctx->filter[0]  = NULL;
     684           0 :     ctx->filter[1]  = NULL;
     685           0 :     ctx->prediction = NULL;
     686           0 :     ctx->w = 0;
     687           0 :     ctx->h = 0;
     688             : 
     689           0 :     return 0;
     690             : }
     691             : #endif /* HAVE_THREADS */
     692             : 
     693             : AVCodec ff_pixlet_decoder = {
     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 |
     704             :                         AV_CODEC_CAP_FRAME_THREADS,
     705             :     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
     706             :                         FF_CODEC_CAP_INIT_CLEANUP,
     707             : };

Generated by: LCOV version 1.13