]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/sgienc.c
lzf: update pointer p after realloc
[ffmpeg] / libavcodec / sgienc.c
index c5e66cd087411a350e3e182fcd2a135e5661060c..07e224cb35dc8070f9ab08ce49a55033603596b7 100644 (file)
@@ -19,6 +19,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavutil/opt.h"
+
 #include "avcodec.h"
 #include "bytestream.h"
 #include "internal.h"
 #define SGI_SINGLE_CHAN 2
 #define SGI_MULTI_CHAN 3
 
+typedef struct SgiContext {
+    AVClass *class;
+
+    int rle;
+} SgiContext;
+
 static av_cold int encode_init(AVCodecContext *avctx)
 {
     if (avctx->width > 65535 || avctx->height > 65535) {
@@ -83,10 +91,11 @@ static int sgi_rle_encode(PutByteContext *pbc, const uint8_t *src,
 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                         const AVFrame *frame, int *got_packet)
 {
+    SgiContext *s = avctx->priv_data;
     const AVFrame * const p = frame;
     PutByteContext pbc;
     uint8_t *in_buf, *encode_buf;
-    int x, y, z, length, tablesize, ret;
+    int x, y, z, length, tablesize, ret, i;
     unsigned int width, height, depth, dimension;
     unsigned int bytes_per_channel, pixmax, put_be;
 
@@ -95,6 +104,13 @@ FF_DISABLE_DEPRECATION_WARNINGS
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
     avctx->coded_frame->key_frame = 1;
 FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+#if FF_API_CODER_TYPE
+FF_DISABLE_DEPRECATION_WARNINGS
+    if (avctx->coder_type == FF_CODER_TYPE_RAW)
+        s->rle = 0;
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
     width  = avctx->width;
@@ -146,7 +162,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     tablesize = depth * height * 4;
     length = SGI_HEADER_SIZE;
-    if (avctx->coder_type == FF_CODER_TYPE_RAW)
+    if (!s->rle)
         length += depth * height * width;
     else // assume sgi_rle_encode() produces at most 2x size of input
         length += tablesize * 2 + depth * height * (2 * width + 1);
@@ -160,7 +176,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     /* Encode header. */
     bytestream2_put_be16(&pbc, SGI_MAGIC);
-    bytestream2_put_byte(&pbc, avctx->coder_type != FF_CODER_TYPE_RAW); /* RLE 1 - VERBATIM 0 */
+    bytestream2_put_byte(&pbc, s->rle); /* RLE 1 - VERBATIM 0 */
     bytestream2_put_byte(&pbc, bytes_per_channel);
     bytestream2_put_be16(&pbc, dimension);
     bytestream2_put_be16(&pbc, width);
@@ -172,15 +188,17 @@ FF_ENABLE_DEPRECATION_WARNINGS
     bytestream2_put_be32(&pbc, 0L); /* dummy */
 
     /* name */
-    bytestream2_skip_p(&pbc, 80);
+    for (i = 0; i < 80; i++)
+        bytestream2_put_byte(&pbc, 0L);
 
     /* colormap */
     bytestream2_put_be32(&pbc, 0L);
 
     /* The rest of the 512 byte header is unused. */
-    bytestream2_skip_p(&pbc, 404);
+    for (i = 0; i < 404; i++)
+        bytestream2_put_byte(&pbc, 0L);
 
-    if (avctx->coder_type != FF_CODER_TYPE_RAW) {
+    if (s->rle) {
         PutByteContext taboff_pcb, tablen_pcb;
 
         /* Skip RLE offset table. */
@@ -193,7 +211,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
         /* Make an intermediate consecutive buffer. */
         if (!(encode_buf = av_malloc(width * bytes_per_channel)))
-            return -1;
+            return AVERROR(ENOMEM);
 
         for (z = 0; z < depth; z++) {
             in_buf = p->data[0] + p->linesize[0] * (height - 1) + z * bytes_per_channel;
@@ -208,7 +226,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
                                         bytes_per_channel);
                 if (length < 1) {
                     av_free(encode_buf);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
 
                 bytestream2_put_be32(&tablen_pcb, length);
@@ -244,11 +262,28 @@ FF_ENABLE_DEPRECATION_WARNINGS
     return 0;
 }
 
+#define OFFSET(x) offsetof(SgiContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "rle", "Use run-length compression", OFFSET(rle), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
+
+    { NULL },
+};
+
+static const AVClass sgi_class = {
+    .class_name = "sgi",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 AVCodec ff_sgi_encoder = {
     .name      = "sgi",
     .long_name = NULL_IF_CONFIG_SMALL("SGI image"),
     .type      = AVMEDIA_TYPE_VIDEO,
     .id        = AV_CODEC_ID_SGI,
+    .priv_data_size = sizeof(SgiContext),
+    .priv_class = &sgi_class,
     .init      = encode_init,
     .encode2   = encode_frame,
     .pix_fmts  = (const enum AVPixelFormat[]) {