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"
34 typedef struct SGIRLEContext
{
38 static av_cold
int sgirle_decode_init(AVCodecContext
*avctx
)
40 SGIRLEContext
*s
= avctx
->priv_data
;
41 avctx
->pix_fmt
= AV_PIX_FMT_BGR8
;
42 s
->frame
= av_frame_alloc();
44 return AVERROR(ENOMEM
);
49 * Convert SGI RBG323 pixel into AV_PIX_FMT_BGR8
50 * SGI RGB data is packed as 8bpp, (msb)3R 2B 3G(lsb)
52 #define RBG323_TO_BGR8(x) ((((x) << 3) & 0xC0) | \
53 (((x) << 3) & 0x38) | \
55 static av_always_inline
56 void rbg323_to_bgr8(uint8_t *dst
, const uint8_t *src
, int size
)
59 for (i
= 0; i
< size
; i
++)
60 dst
[i
] = RBG323_TO_BGR8(src
[i
]);
64 * @param[out] dst Destination buffer
65 * @param[in] src Source buffer
66 * @param src_size Source buffer size (bytes)
67 * @param width Width of destination buffer (pixels)
68 * @param height Height of destination buffer (pixels)
69 * @param linesize Line size of destination buffer (bytes)
73 static int decode_sgirle8(AVCodecContext
*avctx
, uint8_t *dst
,
74 const uint8_t *src
, int src_size
,
75 int width
, int height
, ptrdiff_t linesize
)
77 const uint8_t *src_end
= src
+ src_size
;
89 while (src_end
- src
>= 2) {
91 if (v
> 0 && v
< 0xC0) {
93 int length
= FFMIN(v
, width
- x
);
96 memset(dst
+ y
* linesize
+ x
, RBG323_TO_BGR8(*src
), length
);
101 } else if (v
>= 0xC1) {
104 int length
= FFMIN3(v
, width
- x
, src_end
- src
);
105 if (src_end
- src
< length
|| length
<= 0)
107 rbg323_to_bgr8(dst
+ y
* linesize
+ x
, src
, length
);
113 avpriv_request_sample(avctx
, "opcode %d", v
);
114 return AVERROR_PATCHWELCOME
;
120 static int sgirle_decode_frame(AVCodecContext
*avctx
, void *data
,
121 int *got_frame
, AVPacket
*avpkt
)
123 SGIRLEContext
*s
= avctx
->priv_data
;
126 if ((ret
= ff_reget_buffer(avctx
, s
->frame
)) < 0)
129 ret
= decode_sgirle8(avctx
, s
->frame
->data
[0], avpkt
->data
, avpkt
->size
,
130 avctx
->width
, avctx
->height
, s
->frame
->linesize
[0]);
135 if ((ret
= av_frame_ref(data
, s
->frame
)) < 0)
141 static av_cold
int sgirle_decode_end(AVCodecContext
*avctx
)
143 SGIRLEContext
*s
= avctx
->priv_data
;
145 av_frame_free(&s
->frame
);
150 AVCodec ff_sgirle_decoder
= {
152 .long_name
= NULL_IF_CONFIG_SMALL("Silicon Graphics RLE 8-bit video"),
153 .type
= AVMEDIA_TYPE_VIDEO
,
154 .id
= AV_CODEC_ID_SGIRLE
,
155 .priv_data_size
= sizeof(SGIRLEContext
),
156 .init
= sgirle_decode_init
,
157 .close
= sgirle_decode_end
,
158 .decode
= sgirle_decode_frame
,
159 .capabilities
= CODEC_CAP_DR1
,