2 * Silicon Graphics RLE 8-bit video decoder
3 * Copyright (c) 2012 Peter Ross
5 * This file is part of FFmpeg.
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.
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.
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
24 * Silicon Graphics RLE 8-bit video decoder
25 * @note Data is packed in rbg323 with rle, contained in mv or mov.
26 * The algorithm and pixfmt are subtly different from SGI images.
29 #include "libavutil/common.h"
32 #include "codec_internal.h"
35 static av_cold
int sgirle_decode_init(AVCodecContext
*avctx
)
37 avctx
->pix_fmt
= AV_PIX_FMT_BGR8
;
42 * Convert SGI RBG323 pixel into AV_PIX_FMT_BGR8
43 * SGI RGB data is packed as 8bpp, (msb)3R 2B 3G(lsb)
45 #define RBG323_TO_BGR8(x) ((((x) << 3) & 0xC0) | \
46 (((x) << 3) & 0x38) | \
48 static av_always_inline
49 void rbg323_to_bgr8(uint8_t *dst
, const uint8_t *src
, int size
)
52 for (i
= 0; i
< size
; i
++)
53 dst
[i
] = RBG323_TO_BGR8(src
[i
]);
57 * @param[out] dst Destination buffer
58 * @param[in] src Source buffer
59 * @param src_size Source buffer size (bytes)
60 * @param width Width of destination buffer (pixels)
61 * @param height Height of destination buffer (pixels)
62 * @param linesize Line size of destination buffer (bytes)
66 static int decode_sgirle8(AVCodecContext
*avctx
, uint8_t *dst
,
67 const uint8_t *src
, int src_size
,
68 int width
, int height
, ptrdiff_t linesize
)
70 const uint8_t *src_end
= src
+ src_size
;
82 while (src_end
- src
>= 2) {
84 if (v
> 0 && v
< 0xC0) {
86 int length
= FFMIN(v
, width
- x
);
89 memset(dst
+ y
* linesize
+ x
, RBG323_TO_BGR8(*src
), length
);
94 } else if (v
>= 0xC1) {
97 int length
= FFMIN3(v
, width
- x
, src_end
- src
);
98 if (src_end
- src
< length
|| length
<= 0)
100 rbg323_to_bgr8(dst
+ y
* linesize
+ x
, src
, length
);
106 avpriv_request_sample(avctx
, "opcode %d", v
);
107 return AVERROR_PATCHWELCOME
;
113 static int sgirle_decode_frame(AVCodecContext
*avctx
, AVFrame
*frame
,
114 int *got_frame
, AVPacket
*avpkt
)
118 if (avpkt
->size
* 192ll / 2 < avctx
->width
* avctx
->height
)
119 return AVERROR_INVALIDDATA
;
121 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
124 ret
= decode_sgirle8(avctx
, frame
->data
[0], avpkt
->data
, avpkt
->size
,
125 avctx
->width
, avctx
->height
, frame
->linesize
[0]);
134 const FFCodec ff_sgirle_decoder
= {
136 CODEC_LONG_NAME("Silicon Graphics RLE 8-bit video"),
137 .p
.type
= AVMEDIA_TYPE_VIDEO
,
138 .p
.id
= AV_CODEC_ID_SGIRLE
,
139 .init
= sgirle_decode_init
,
140 FF_CODEC_DECODE_CB(sgirle_decode_frame
),
141 .p
.capabilities
= AV_CODEC_CAP_DR1
,