]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/sunrastenc.c
mpeg12dec: avoid signed overflow in bitrate calculation
[ffmpeg] / libavcodec / sunrastenc.c
index 21d6fc47a02d12f945988f3af030d5e8ff67e14b..3a5f410135e7933f51bd66d3299756163dad7fa6 100644 (file)
  * 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"
 #include "sunrast.h"
 
 typedef struct SUNRASTContext {
-    AVFrame picture;
+    AVClass *class;
+
     PutByteContext p;
     int depth;      ///< depth of pixel
     int length;     ///< length (bytes) of image
@@ -83,15 +86,18 @@ static void sunrast_image_write_image(AVCodecContext *avctx,
      if (s->type == RT_BYTE_ENCODED) {
         uint8_t value, value2;
         int run;
-        const uint8_t *end = pixels + avctx->height * linesize;
+        const uint8_t *start = linesize < 0 ? pixels + (avctx->height - 1) * linesize
+                                            : pixels;
+        const uint8_t *end   = linesize < 0 ? pixels - linesize
+                                            : pixels + avctx->height * linesize;
 
         ptr = pixels;
 
-#define GET_VALUE ptr >= end ? 0 : x >= len ? ptr[len-1] : ptr[x]
+#define GET_VALUE ptr >= end || ptr < start ? 0 : x >= len ? ptr[len-1] : ptr[x]
 
         x = 0;
         value2 = GET_VALUE;
-        while (ptr < end) {
+        while (ptr < end && ptr >= start) {
             run = 1;
             value = value2;
             x++;
@@ -101,7 +107,7 @@ static void sunrast_image_write_image(AVCodecContext *avctx,
             }
 
             value2 = GET_VALUE;
-            while (value2 == value && run < 256 && ptr < end) {
+            while (value2 == value && run < 256 && ptr < end && ptr >= start) {
                 x++;
                 run++;
                 if (x >= alen) {
@@ -139,6 +145,8 @@ static av_cold int sunrast_encode_init(AVCodecContext *avctx)
 {
     SUNRASTContext *s = avctx->priv_data;
 
+#if FF_API_CODER_TYPE
+FF_DISABLE_DEPRECATION_WARNINGS
     switch (avctx->coder_type) {
     case FF_CODER_TYPE_RLE:
         s->type = RT_BYTE_ENCODED;
@@ -150,32 +158,40 @@ static av_cold int sunrast_encode_init(AVCodecContext *avctx)
         av_log(avctx, AV_LOG_ERROR, "invalid coder_type\n");
         return AVERROR(EINVAL);
     }
+FF_ENABLE_DEPRECATION_WARNINGS
+    if (s->type != RT_BYTE_ENCODED && s->type != RT_STANDARD)
+#endif
+    // adjust boolean option to RT equivalent
+    s->type++;
 
-    avctx->coded_frame            = &s->picture;
+#if FF_API_CODED_FRAME
+FF_DISABLE_DEPRECATION_WARNINGS
     avctx->coded_frame->key_frame = 1;
     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
     s->maptype                    = RMT_NONE;
     s->maplength                  = 0;
 
     switch (avctx->pix_fmt) {
-    case PIX_FMT_MONOWHITE:
+    case AV_PIX_FMT_MONOWHITE:
         s->depth = 1;
         break;
-    case PIX_FMT_PAL8 :
+    case AV_PIX_FMT_PAL8 :
         s->maptype   = RMT_EQUAL_RGB;
         s->maplength = 3 * 256;
-    case PIX_FMT_GRAY8:
+        /* fall-through */
+    case AV_PIX_FMT_GRAY8:
         s->depth = 8;
         break;
-    case PIX_FMT_BGR24:
+    case AV_PIX_FMT_BGR24:
         s->depth = 24;
         break;
     default:
         return AVERROR_BUG;
     }
     s->length = avctx->height * (FFALIGN(avctx->width * s->depth, 16) >> 3);
-    s->size   = 32 + s->maplength +
-                s->length * (s->type == RT_BYTE_ENCODED ? 2 : 1);
+    s->size   = 32 + s->maplength + s->length * s->type;
 
     return 0;
 }
@@ -199,27 +215,48 @@ static int sunrast_encode_frame(AVCodecContext *avctx,  AVPacket *avpkt,
         AV_WB32(&avpkt->data[16], s->length);
 
     *got_packet_ptr = 1;
+    avpkt->flags |= AV_PKT_FLAG_KEY;
     avpkt->size = bytestream2_tell_p(&s->p);
     return 0;
 }
 
+#define OFFSET(x) offsetof(SUNRASTContext, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "rle", "Use run-length compression", OFFSET(type), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
+
+    { NULL },
+};
+
+static const AVClass sunrast_class = {
+    .class_name = "sunrast",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
+#if FF_API_CODER_TYPE
 static const AVCodecDefault sunrast_defaults[] = {
      { "coder", "rle" },
      { NULL },
 };
+#endif
 
 AVCodec ff_sunrast_encoder = {
     .name           = "sunrast",
+    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_SUNRAST,
+    .id             = AV_CODEC_ID_SUNRAST,
     .priv_data_size = sizeof(SUNRASTContext),
+    .priv_class     = &sunrast_class,
     .init           = sunrast_encode_init,
     .encode2        = sunrast_encode_frame,
+#if FF_API_CODER_TYPE
     .defaults       = sunrast_defaults,
-    .pix_fmts       = (const enum PixelFormat[]){ PIX_FMT_BGR24,
-                                                  PIX_FMT_PAL8,
-                                                  PIX_FMT_GRAY8,
-                                                  PIX_FMT_MONOWHITE,
-                                                  PIX_FMT_NONE },
-    .long_name      = NULL_IF_CONFIG_SMALL("Sun Rasterfile image"),
+#endif
+    .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24,
+                                                  AV_PIX_FMT_PAL8,
+                                                  AV_PIX_FMT_GRAY8,
+                                                  AV_PIX_FMT_MONOWHITE,
+                                                  AV_PIX_FMT_NONE },
 };