| @@ -21,6 +21,7 @@ | |||
| #include "avcodec.h" | |||
| #include "bytestream.h" | |||
| #include "internal.h" | |||
| #include "sgi.h" | |||
| #include "rle.h" | |||
| @@ -41,17 +42,17 @@ static av_cold int encode_init(AVCodecContext *avctx) | |||
| return 0; | |||
| } | |||
| static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |||
| int buf_size, void *data) | |||
| static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |||
| const AVFrame *frame, int *got_packet) | |||
| { | |||
| SgiContext *s = avctx->priv_data; | |||
| AVFrame * const p = &s->picture; | |||
| uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf; | |||
| int x, y, z, length, tablesize; | |||
| uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf; | |||
| int x, y, z, length, tablesize, ret; | |||
| unsigned int width, height, depth, dimension; | |||
| unsigned char *orig_buf = buf, *end_buf = buf + buf_size; | |||
| unsigned char *end_buf; | |||
| *p = *(AVFrame*)data; | |||
| *p = *frame; | |||
| p->pict_type = AV_PICTURE_TYPE_I; | |||
| p->key_frame = 1; | |||
| @@ -76,12 +77,18 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |||
| } | |||
| tablesize = depth * height * 4; | |||
| length = tablesize * 2 + SGI_HEADER_SIZE; | |||
| if (buf_size < length) { | |||
| av_log(avctx, AV_LOG_ERROR, "buf_size too small(need %d, got %d)\n", length, buf_size); | |||
| return -1; | |||
| length = SGI_HEADER_SIZE; | |||
| if (avctx->coder_type == FF_CODER_TYPE_RAW) | |||
| length += depth * height * width; | |||
| else // assume ff_rl_encode() produces at most 2x size of input | |||
| length += tablesize * 2 + depth * height * (2 * width + 1); | |||
| if ((ret = ff_alloc_packet(pkt, length)) < 0) { | |||
| av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n", length); | |||
| return ret; | |||
| } | |||
| buf = pkt->data; | |||
| end_buf = pkt->data + pkt->size; | |||
| /* Encode header. */ | |||
| bytestream_put_be16(&buf, SGI_MAGIC); | |||
| @@ -124,7 +131,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |||
| in_buf = p->data[0] + p->linesize[0] * (height - 1) + z; | |||
| for (y = 0; y < height; y++) { | |||
| bytestream_put_be32(&offsettab, buf - orig_buf); | |||
| bytestream_put_be32(&offsettab, buf - pkt->data); | |||
| for (x = 0; x < width; x++) | |||
| encode_buf[x] = in_buf[depth * x]; | |||
| @@ -156,7 +163,11 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, | |||
| } | |||
| /* total length */ | |||
| return buf - orig_buf; | |||
| pkt->size = buf - pkt->data; | |||
| pkt->flags |= AV_PKT_FLAG_KEY; | |||
| *got_packet = 1; | |||
| return 0; | |||
| } | |||
| AVCodec ff_sgi_encoder = { | |||
| @@ -165,7 +176,7 @@ AVCodec ff_sgi_encoder = { | |||
| .id = CODEC_ID_SGI, | |||
| .priv_data_size = sizeof(SgiContext), | |||
| .init = encode_init, | |||
| .encode = encode_frame, | |||
| .encode2 = encode_frame, | |||
| .pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_GRAY8, PIX_FMT_NONE}, | |||
| .long_name= NULL_IF_CONFIG_SMALL("SGI image"), | |||
| }; | |||