On 03/20/2014 09:13 PM, Vittorio Giovara wrote: > --- > Amended as asked by Justin. I only kept the avctx->pix_fmt checks because > they look > more readable to me. > Cheers, > 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 > [...] > diff --git a/libavcodec/aliaspixenc.c b/libavcodec/aliaspixenc.c > new file mode 100644 > index 0000000..22f6aac > --- /dev/null > +++ b/libavcodec/aliaspixenc.c > @@ -0,0 +1,132 @@ > +/* > + * Alias PIX image encoder > + * Copyright (C) 2014 Vittorio Giovara <vittorio.giov...@gmail.com> > + * > + * This file is part of Libav. > + * > + * Libav is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * Libav is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with Libav; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include "libavutil/intreadwrite.h" > + > +#include "avcodec.h" > +#include "bytestream.h" > +#include "internal.h" > + > +#define ALIAS_HEADER_SIZE 10 > + > +static av_cold int encode_init(AVCodecContext *avctx) > +{ > + avctx->coded_frame = av_frame_alloc(); > + if (!avctx->coded_frame) > + return AVERROR(ENOMEM); > + return 0; > +} > + > +static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, > + const AVFrame *frame, int *got_packet) > +{ > + int width, height, bits_pixel, 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 > 65535 || > + width * height >= INT_MAX / 4 - 10LL) { > + av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n", width, > height); > + return AVERROR_INVALIDDATA; > + }
That doesn't need to be 10LL. You can use ALIAS_HEADER_SIZE. > + > + switch (avctx->pix_fmt) { > + case AV_PIX_FMT_GRAY8: > + bits_pixel = 8; > + break; > + case AV_PIX_FMT_BGR24: > + bits_pixel = 24; > + break; > + default: > + return AVERROR_INVALIDDATA; AVERROR(EINVAL) although it won't ever get this far... > + } > + > + 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 */ You don't need the L > + bytestream_put_be16(&buf, bits_pixel); > + > + 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) { > + 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 */ > + av_shrink_packet(pkt, buf - pkt->data); > + pkt->flags |= AV_PKT_FLAG_KEY; > + *got_packet = 1; > + > + return 0; > +} > + > +static av_cold int encode_close(AVCodecContext *avctx) > +{ > + av_frame_free(&avctx->coded_frame); > + return 0; > +} > + > +AVCodec ff_alias_pix_encoder = { > + .name = "alias_pix", > + .long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"), > + .type = AVMEDIA_TYPE_VIDEO, > + .id = AV_CODEC_ID_ALIAS_PIX, > + .init = encode_init, > + .encode2 = encode_frame, > + .close = encode_close, > + .pix_fmts = (const enum AVPixelFormat[]) { > + AV_PIX_FMT_BGR24, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE > + }, > +}; > diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c > index ed6d7ff..8918481 100644 > --- a/libavcodec/allcodecs.c > +++ b/libavcodec/allcodecs.c > @@ -98,6 +98,7 @@ void avcodec_register_all(void) > REGISTER_ENCODER(A64MULTI5, a64multi5); > REGISTER_DECODER(AASC, aasc); > REGISTER_DECODER(AIC, aic); > + REGISTER_ENCDEC (ALIAS_PIX, alias_pix); > REGISTER_DECODER(AMV, amv); > REGISTER_DECODER(ANM, anm); > REGISTER_DECODER(ANSI, ansi); > diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h > index 7beb277..b3eded3 100644 > --- a/libavcodec/avcodec.h > +++ b/libavcodec/avcodec.h > @@ -284,6 +284,7 @@ enum AVCodecID { > AV_CODEC_ID_HNM4_VIDEO, > AV_CODEC_ID_HEVC, > AV_CODEC_ID_FIC, > + AV_CODEC_ID_ALIAS_PIX, > > /* various PCM "codecs" */ > AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the > start of audio codecs > diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c > index 2ad5326..dceffe8 100644 > --- a/libavcodec/codec_desc.c > +++ b/libavcodec/codec_desc.c > @@ -1095,6 +1095,13 @@ static const AVCodecDescriptor codec_descriptors[] = { > > /* image codecs */ > { > + .id = AV_CODEC_ID_ALIAS_PIX, > + .type = AVMEDIA_TYPE_VIDEO, > + .name = "alias_pix", > + .long_name = NULL_IF_CONFIG_SMALL("Alias/Wavefront PIX image"), > + .props = AV_CODEC_PROP_LOSSLESS, AV_CODEC_PROP_INTRA_ONLY > + }, > + { > .id = AV_CODEC_ID_ANSI, > .type = AVMEDIA_TYPE_VIDEO, > .name = "ansi", > diff --git a/libavcodec/version.h b/libavcodec/version.h > index 5ab49d5..d2f80ad 100644 > --- a/libavcodec/version.h > +++ b/libavcodec/version.h > @@ -29,8 +29,8 @@ > #include "libavutil/version.h" > > #define LIBAVCODEC_VERSION_MAJOR 55 > -#define LIBAVCODEC_VERSION_MINOR 34 > -#define LIBAVCODEC_VERSION_MICRO 1 > +#define LIBAVCODEC_VERSION_MINOR 35 > +#define LIBAVCODEC_VERSION_MICRO 0 > > #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ > LIBAVCODEC_VERSION_MINOR, \ > diff --git a/libavformat/img2.c b/libavformat/img2.c > index ed59281..9cec45a 100644 > --- a/libavformat/img2.c > +++ b/libavformat/img2.c > @@ -43,6 +43,7 @@ static const IdStrMap img_tags[] = { > { AV_CODEC_ID_PGMYUV, "pgmyuv" }, > { AV_CODEC_ID_PBM, "pbm" }, > { AV_CODEC_ID_PAM, "pam" }, > + { AV_CODEC_ID_ALIAS_PIX, "pix" }, > { AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" }, > { AV_CODEC_ID_MPEG2VIDEO, "mpg2-img" }, > { AV_CODEC_ID_MPEG4, "mpg4-img" }, > diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c > index f4a80aa..13e6828 100644 > --- a/libavformat/img2enc.c > +++ b/libavformat/img2enc.c > @@ -148,7 +148,7 @@ AVOutputFormat ff_image2_muxer = { > .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"), > .extensions = "bmp,dpx,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png," > "ppm,sgi,tga,tif,tiff,jp2,xwd,sun,ras,rs,im1,im8,im24," > - "sunras,webp,xbm,j2c", > + "sunras,webp,xbm,j2c,pix", > .priv_data_size = sizeof(VideoMuxData), > .video_codec = AV_CODEC_ID_MJPEG, > .write_header = write_header, _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel