mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2025-02-15 09:27:47 +00:00
Added PIX_FMT_GRAY8 to the formats supported by the QuickTime RLE encoder
The QuickTime RLE encoder only supports 16, 24, and 32-bit color. This patch adds support for 8-bit grayscale. Signed-off-by: John Horigan <john@glyphic.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
1d14edb724
commit
ce10e858a7
@ -39,6 +39,7 @@ typedef struct QtrleEncContext {
|
||||
int pixel_size;
|
||||
AVPicture previous_frame;
|
||||
unsigned int max_buf_size;
|
||||
int logical_width;
|
||||
/**
|
||||
* This array will contain at ith position the value of the best RLE code
|
||||
* if the line started at pixel i
|
||||
@ -67,8 +68,13 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx)
|
||||
return -1;
|
||||
}
|
||||
s->avctx=avctx;
|
||||
s->logical_width=avctx->width;
|
||||
|
||||
switch (avctx->pix_fmt) {
|
||||
case PIX_FMT_GRAY8:
|
||||
s->logical_width = avctx->width / 4;
|
||||
s->pixel_size = 4;
|
||||
break;
|
||||
case PIX_FMT_RGB555BE:
|
||||
s->pixel_size = 2;
|
||||
break;
|
||||
@ -82,11 +88,11 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx)
|
||||
av_log(avctx, AV_LOG_ERROR, "Unsupported colorspace.\n");
|
||||
break;
|
||||
}
|
||||
avctx->bits_per_coded_sample = s->pixel_size*8;
|
||||
avctx->bits_per_coded_sample = avctx->pix_fmt == PIX_FMT_GRAY8 ? 40 : s->pixel_size*8;
|
||||
|
||||
s->rlecode_table = av_mallocz(s->avctx->width);
|
||||
s->skip_table = av_mallocz(s->avctx->width);
|
||||
s->length_table = av_mallocz((s->avctx->width + 1)*sizeof(int));
|
||||
s->rlecode_table = av_mallocz(s->logical_width);
|
||||
s->skip_table = av_mallocz(s->logical_width);
|
||||
s->length_table = av_mallocz((s->logical_width + 1)*sizeof(int));
|
||||
if (!s->skip_table || !s->length_table || !s->rlecode_table) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error allocating memory.\n");
|
||||
return -1;
|
||||
@ -96,10 +102,10 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx)
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->max_buf_size = s->avctx->width*s->avctx->height*s->pixel_size /* image base material */
|
||||
+ 15 /* header + footer */
|
||||
+ s->avctx->height*2 /* skip code+rle end */
|
||||
+ s->avctx->width/MAX_RLE_BULK + 1 /* rle codes */;
|
||||
s->max_buf_size = s->logical_width*s->avctx->height*s->pixel_size /* image base material */
|
||||
+ 15 /* header + footer */
|
||||
+ s->avctx->height*2 /* skip code+rle end */
|
||||
+ s->logical_width/MAX_RLE_BULK + 1 /* rle codes */;
|
||||
avctx->coded_frame = &s->frame;
|
||||
return 0;
|
||||
}
|
||||
@ -109,7 +115,7 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx)
|
||||
*/
|
||||
static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t **buf)
|
||||
{
|
||||
int width=s->avctx->width;
|
||||
int width=s->logical_width;
|
||||
int i;
|
||||
signed char rlecode;
|
||||
|
||||
@ -224,12 +230,26 @@ static void qtrle_encode_line(QtrleEncContext *s, AVFrame *p, int line, uint8_t
|
||||
}
|
||||
else if (rlecode > 0) {
|
||||
/* bulk copy */
|
||||
bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
|
||||
if (s->avctx->pix_fmt == PIX_FMT_GRAY8) {
|
||||
// QT grayscale colorspace has 0=white and 255=black, we will
|
||||
// ignore the palette that is included in the AVFrame because
|
||||
// PIX_FMT_GRAY8 has defined color mapping
|
||||
for (int j = 0; j < rlecode*s->pixel_size; ++j)
|
||||
bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
|
||||
} else {
|
||||
bytestream_put_buffer(buf, this_line + i*s->pixel_size, rlecode*s->pixel_size);
|
||||
}
|
||||
i += rlecode;
|
||||
}
|
||||
else {
|
||||
/* repeat the bits */
|
||||
bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
|
||||
if (s->avctx->pix_fmt == PIX_FMT_GRAY8) {
|
||||
// QT grayscale colorspace has 0=white and 255=black, ...
|
||||
for (int j = 0; j < s->pixel_size; ++j)
|
||||
bytestream_put_byte(buf, *(this_line + i*s->pixel_size + j) ^ 0xff);
|
||||
} else {
|
||||
bytestream_put_buffer(buf, this_line + i*s->pixel_size, s->pixel_size);
|
||||
}
|
||||
i -= rlecode;
|
||||
}
|
||||
}
|
||||
@ -245,7 +265,7 @@ static int encode_frame(QtrleEncContext *s, AVFrame *p, uint8_t *buf)
|
||||
uint8_t *orig_buf = buf;
|
||||
|
||||
if (!s->frame.key_frame) {
|
||||
unsigned line_size = s->avctx->width * s->pixel_size;
|
||||
unsigned line_size = s->logical_width * s->pixel_size;
|
||||
for (start_line = 0; start_line < s->avctx->height; start_line++)
|
||||
if (memcmp(p->data[0] + start_line*p->linesize[0],
|
||||
s->previous_frame.data[0] + start_line*s->previous_frame.linesize[0],
|
||||
@ -329,6 +349,6 @@ AVCodec ff_qtrle_encoder = {
|
||||
qtrle_encode_init,
|
||||
qtrle_encode_frame,
|
||||
qtrle_encode_end,
|
||||
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_NONE},
|
||||
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB555BE, PIX_FMT_ARGB, PIX_FMT_GRAY8, PIX_FMT_NONE},
|
||||
.long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user