[FFmpeg-devel] [HACK] 16 bpp sgi support

Reimar Döffinger Reimar.Doeffinger
Mon Sep 14 11:30:29 CEST 2009


Hello,
attached quite hackish patch add support for some uncompressed sgi
formats with 16 bpp.
In particular, these files:
http://media.xiph.org/svt/2160p50_CgrLevels_Master_SVTdec05_/1_CrowdRun_2160p50_CgrLevels_MASTER_SVTdec05_/
What do you think needs to be done to make this acceptable?
Supporting e.g. 16 bit RLE makes no sense due to lack of sample files
(are there any programs that can create such files?).
-------------- next part --------------
Index: libavcodec/sgidec.c
===================================================================
--- libavcodec/sgidec.c	(revision 19824)
+++ libavcodec/sgidec.c	(working copy)
@@ -28,6 +28,7 @@
     unsigned int width;
     unsigned int height;
     unsigned int depth;
+    unsigned int bytes_per_channel;
     int linesize;
 } SgiState;
 
@@ -125,7 +126,7 @@
 {
     int x, y, z;
     const uint8_t *ptr;
-    unsigned int offset = s->height * s->width;
+    unsigned int offset = s->height * s->width * s->bytes_per_channel;
 
     /* Test buffer size. */
     if (offset * s->depth > in_end - in_buf) {
@@ -135,9 +136,10 @@
     for (y = s->height - 1; y >= 0; y--) {
         out_end = out_buf + (y * s->linesize);
         for (x = s->width; x > 0; x--) {
-            ptr = in_buf++;
+            ptr = in_buf += s->bytes_per_channel;
             for(z = 0; z < s->depth; z ++) {
-                bytestream_put_byte(&out_end, *ptr);
+                memcpy(out_end, ptr, s->bytes_per_channel);
+                out_end += s->bytes_per_channel;
                 ptr += offset;
             }
         }
@@ -155,7 +157,7 @@
     AVFrame *picture = data;
     AVFrame *p = &s->picture;
     const uint8_t *in_end = in_buf + buf_size;
-    unsigned int dimension, bytes_per_channel, rle;
+    unsigned int dimension, rle;
     int ret = 0;
     uint8_t *out_buf, *out_end;
 
@@ -171,13 +173,13 @@
     }
 
     rle = bytestream_get_byte(&in_buf);
-    bytes_per_channel = bytestream_get_byte(&in_buf);
+    s->bytes_per_channel = bytestream_get_byte(&in_buf);
     dimension = bytestream_get_be16(&in_buf);
     s->width  = bytestream_get_be16(&in_buf);
     s->height = bytestream_get_be16(&in_buf);
     s->depth  = bytestream_get_be16(&in_buf);
 
-    if (bytes_per_channel != 1) {
+    if (s->bytes_per_channel != 1 && (s->bytes_per_channel != 2 || rle)) {
         av_log(avctx, AV_LOG_ERROR, "wrong channel number\n");
         return -1;
     }
@@ -189,10 +191,10 @@
     }
 
     if (s->depth == SGI_GRAYSCALE) {
-        avctx->pix_fmt = PIX_FMT_GRAY8;
+        avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_GRAY16BE : PIX_FMT_GRAY8;
     } else if (s->depth == SGI_RGB) {
-        avctx->pix_fmt = PIX_FMT_RGB24;
-    } else if (s->depth == SGI_RGBA) {
+        avctx->pix_fmt = s->bytes_per_channel == 2 ? PIX_FMT_RGB48BE : PIX_FMT_RGB24;
+    } else if (s->depth == SGI_RGBA && s->bytes_per_channel == 1) {
         avctx->pix_fmt = PIX_FMT_RGBA;
     } else {
         av_log(avctx, AV_LOG_ERROR, "wrong picture format\n");



More information about the ffmpeg-devel mailing list