On 03/20/2014 11:57 AM, Vittorio Giovara wrote:
> ---
> Some more tweaks Justin asked me.
> Vittorio
>
> Changelog | 1 +
> doc/general.texi | 2 +
> libavcodec/Makefile | 2 +
> libavcodec/aliaspixdec.c | 114 ++++++++++++++++++++++++++++++++++++++++
> libavcodec/aliaspixenc.c | 132
> +++++++++++++++++++++++++++++++++++++++++++++++
> libavcodec/allcodecs.c | 1 +
> libavcodec/avcodec.h | 1 +
> libavcodec/codec_desc.c | 7 +++
> libavcodec/version.h | 4 +-
> libavformat/img2.c | 1 +
> libavformat/img2enc.c | 2 +-
> 11 files changed, 264 insertions(+), 3 deletions(-)
> create mode 100644 libavcodec/aliaspixdec.c
> create mode 100644 libavcodec/aliaspixenc.c
[...]
> + bytestream2_init(&gb, avpkt->data, avpkt->size);
> +
> + if (bytestream2_get_bytes_left(&gb) < ALIAS_HEADER_SIZE) {
> + av_log(avctx, AV_LOG_ERROR, "Header too small %d.\n", avpkt->size);
> + return AVERROR_INVALIDDATA;
> + }
> +
> + width = bytestream2_get_be16(&gb);
> + height = bytestream2_get_be16(&gb);
> + bytestream2_skip(&gb, 4); // obsolete X, Y offset
> + format = bytestream2_get_be16(&gb);
since you check the size first, you should use the unchecked bytestream2
functions (i.e. add 'u' to the end of all 4)
also, why not call it 'depth' instead of 'format' to match your encoder?
> +
> + if (format == 24)
> + avctx->pix_fmt = AV_PIX_FMT_BGR24;
> + else if (format == 8)
> + avctx->pix_fmt = AV_PIX_FMT_GRAY8;
> + else {
> + av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
> + return AVERROR_INVALIDDATA;
> + }
> +
> + ret = ff_set_dimensions(avctx, width, height);
> + if (ret < 0)
> + return ret;
> +
> + ret = ff_get_buffer(avctx, f, 0);
> + if (ret < 0)
> + return ret;
> +
> + f->pict_type = AV_PICTURE_TYPE_I;
> + f->key_frame = 1;
> +
> + while (bytestream2_get_bytes_left(&gb) > 0) {
> + int i;
> +
> + /* set buffer at the right position at every new line */
> + if (width == avctx->width) {
> + width = 0;
> + out_buf = f->data[0] + f->linesize[0] * y++;
> + }
> +
> + /* read packet and copy data */
> + count = bytestream2_get_byte(&gb);
same here bytestream2_get_byteu(&gb)
> + if (!count || width + count > avctx->width) {
> + av_log(avctx, AV_LOG_ERROR, "Invalid run length %d.\n", count);
> + return AVERROR_INVALIDDATA;
> + }
> +
> + if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
you could check 'format' instead of avctx->pix_fmt.
[...]
> +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
> + const AVFrame *frame, int *got_packet)
> +{
> + int width, height, depth, i, j, length, ret;
> + uint8_t *in_buf, *buf;
> +
> + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
> + avctx->coded_frame->key_frame = 1;
> +
> + width = avctx->width;
> + height = avctx->height;
> +
> + if (width > 65535 || height > 65536 ||
Looks like a typo for height.
> + width * height >= INT_MAX / 4 - 10LL) {
> + av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n", width,
> height);
> + return AVERROR_INVALIDDATA;
> + }
> +
> + switch (avctx->pix_fmt) {
> + case AV_PIX_FMT_GRAY8:
> + depth = 8;
> + break;
> + case AV_PIX_FMT_BGR24:
> + depth = 24;
> + break;
> + default:
> + return AVERROR_INVALIDDATA;
> + }
> +
> + length = ALIAS_HEADER_SIZE + 4 * width * height; // max possible
> + 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;
> +
> + /* Encode header. */
> + bytestream_put_be16(&buf, width);
> + bytestream_put_be16(&buf, height);
> + bytestream_put_be32(&buf, 0L); /* X, Y offset */
> + bytestream_put_be16(&buf, depth);
> +
> + for (j = 0; j < height; j++) {
> + in_buf = frame->data[0] + frame->linesize[0] * j;
> + for (i = 0; i < width; ) {
> + int count = 0;
> + int pixel;
> +
> + if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
you could check 'depth' instead of avctx->pix_fmt.
> + pixel = *in_buf;
> + while (count < 255 && count + i < width && pixel == *in_buf)
> {
> + count++;
> + in_buf++;
> + }
> + } else { /* AV_PIX_FMT_BGR24 */
> + pixel = AV_RB24(in_buf);
> + while (count < 255 && count + i < width &&
> + pixel == AV_RB24(in_buf)) {
> + count++;
> + in_buf += 3;
> + }
> + }
> + i += count;
> + bytestream_put_byte(&buf, count);
> + bytestream_put_be24(&buf, pixel);
> + }
> + }
> +
> + /* Total length */
> + pkt->size = buf - pkt->data;
av_shrink_packet()
Thanks,
Justin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel