changeset 9114:306ea9a02ebe

Quicktime rle 32 bit supported
author rtognimp
date Sun, 26 Jan 2003 22:05:18 +0000
parents ee0fdf5505c4
children fc803aa85058
files libmpcodecs/native/qtrle.c libmpcodecs/vd_qtrle.c
diffstat 2 files changed, 104 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libmpcodecs/native/qtrle.c	Sun Jan 26 21:26:45 2003 +0000
+++ b/libmpcodecs/native/qtrle.c	Sun Jan 26 22:05:18 2003 +0000
@@ -3,6 +3,7 @@
 
     (C) 2001 Mike Melanson
     8 and 16bpp support by Alex Beregszaszi
+    32 bpp support by Roberto Togni
 */
 
 #include "config.h"
@@ -258,6 +259,96 @@
   }
 }
 
+void qt_decode_rle32(
+  unsigned char *encoded,
+  int encoded_size,
+  unsigned char *decoded,
+  int width,
+  int height,
+  int bytes_per_pixel)
+{
+  int stream_ptr;
+  int header;
+  int start_line;
+  int lines_to_change;
+  signed char rle_code;
+  int row_ptr, pixel_ptr;
+  int row_inc = bytes_per_pixel * width;
+  unsigned char r, g, b;
+
+  // check if this frame is even supposed to change
+  if (encoded_size < 8)
+    return;
+
+  // start after the chunk size
+  stream_ptr = 4;
+
+  // fetch the header
+  header = BE_16(&encoded[stream_ptr]);
+  stream_ptr += 2;
+
+  // if a header is present, fetch additional decoding parameters
+  if (header & 0x0008)
+  {
+    start_line = BE_16(&encoded[stream_ptr]);
+    stream_ptr += 4;
+    lines_to_change = BE_16(&encoded[stream_ptr]);
+    stream_ptr += 4;
+  }
+  else
+  {
+    start_line = 0;
+    lines_to_change = height;
+  }
+
+  row_ptr = row_inc * start_line;
+  while (lines_to_change--)
+  {
+    pixel_ptr = row_ptr + ((encoded[stream_ptr++] - 1) * bytes_per_pixel);
+
+    while (stream_ptr < encoded_size &&
+           (rle_code = (signed char)encoded[stream_ptr++]) != -1)
+    {
+      if (rle_code == 0)
+        // there's another skip code in the stream
+        pixel_ptr += ((encoded[stream_ptr++] - 1) * bytes_per_pixel);
+      else if (rle_code < 0)
+      {
+        // decode the run length code
+        rle_code = -rle_code;
+        stream_ptr++; // Ignore alpha channel
+        r = encoded[stream_ptr++];
+        g = encoded[stream_ptr++];
+        b = encoded[stream_ptr++];
+        while (rle_code--)
+        {
+          decoded[pixel_ptr++] = b;
+          decoded[pixel_ptr++] = g;
+          decoded[pixel_ptr++] = r;
+          if (bytes_per_pixel == 4)
+            pixel_ptr++;
+        }
+      }
+      else
+      {
+        // copy pixels directly to output
+        while (rle_code--)
+        {
+          stream_ptr++; // Ignore alpha channel
+          decoded[pixel_ptr++] = encoded[stream_ptr + 2];
+          decoded[pixel_ptr++] = encoded[stream_ptr + 1];
+          decoded[pixel_ptr++] = encoded[stream_ptr + 0];
+          stream_ptr += 3;
+          if (bytes_per_pixel == 4)
+            pixel_ptr++;
+        }
+      }
+    }
+
+    row_ptr += row_inc;
+  }
+}
+
 void qt_decode_rle(
   unsigned char *encoded,
   int encoded_size,
@@ -296,5 +387,14 @@
         height,
         bytes_per_pixel);
       break;
+    case 32:
+      qt_decode_rle32(
+        encoded,
+        encoded_size,
+        decoded,
+        width,
+        height,
+        bytes_per_pixel);
+      break;
   }
 }
--- a/libmpcodecs/vd_qtrle.c	Sun Jan 26 21:26:45 2003 +0000
+++ b/libmpcodecs/vd_qtrle.c	Sun Jan 26 22:05:18 2003 +0000
@@ -32,7 +32,8 @@
 	    
 	    /* qtrle24 supports 32bit output too */
 	    if ((req_format == (IMGFMT_BGR|ctx->depth)) ||
-		((IMGFMT_BGR_DEPTH(req_format) == 32) && (ctx->depth == 24)))
+		((IMGFMT_BGR_DEPTH(req_format) == 32) && (ctx->depth == 24)) ||
+		((IMGFMT_BGR_DEPTH(req_format) == 24) && (ctx->depth == 32)))
 		return(CONTROL_TRUE);
 	    else
 		return(CONTROL_FALSE);
@@ -68,6 +69,8 @@
 	case 16:
 	    ctx->depth--; /* this is the trick ;) */
 	    break;
+  case 32:
+      mp_msg(MSGT_DECVIDEO,MSGL_INFO,"[qtrle] 32 bpp file, alpha channel will be ignored.\n");
 	case 24:
 	    break;
 	default: