| 94 | } |
| 95 | |
| 96 | static int decode_frame(AVCodecContext *avctx, AVFrame *p, |
| 97 | int *got_frame, AVPacket *avpkt) |
| 98 | { |
| 99 | int ret, width, height, flags; |
| 100 | TextureDSPContext *dsp = avctx->priv_data; |
| 101 | GetByteContext gb; |
| 102 | ptrdiff_t linesize; |
| 103 | uint8_t *dst; |
| 104 | |
| 105 | if (avpkt->size < 22) |
| 106 | return AVERROR_INVALIDDATA; |
| 107 | |
| 108 | bytestream2_init(&gb, avpkt->data, avpkt->size); |
| 109 | |
| 110 | if (bytestream2_get_le32(&gb) != MKTAG('D','X','T','1')) |
| 111 | return AVERROR_INVALIDDATA; |
| 112 | flags = bytestream2_get_le32(&gb); |
| 113 | |
| 114 | width = bytestream2_get_le32(&gb); |
| 115 | height = bytestream2_get_le32(&gb); |
| 116 | if (width > INT_MAX-4U || height > INT_MAX-4U) |
| 117 | return AVERROR_INVALIDDATA; |
| 118 | ret = ff_set_dimensions(avctx, FFALIGN(width, 4), FFALIGN(height, 4)); |
| 119 | if (ret < 0) |
| 120 | return ret; |
| 121 | |
| 122 | avctx->width = width; |
| 123 | avctx->height = height; |
| 124 | |
| 125 | if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0) |
| 126 | return ret; |
| 127 | |
| 128 | dst = p->data[0] + p->linesize[0] * (avctx->coded_height - 1); |
| 129 | linesize = -p->linesize[0]; |
| 130 | |
| 131 | ret = decode_rtv1(&gb, dst, linesize, width, height, flags, dsp->dxt1_block); |
| 132 | if (ret < 0) |
| 133 | return ret; |
| 134 | |
| 135 | *got_frame = 1; |
| 136 | |
| 137 | return avpkt->size; |
| 138 | } |
| 139 | |
| 140 | const FFCodec ff_rtv1_decoder = { |
| 141 | .p.name = "rtv1", |
nothing calls this directly
no test coverage detected