Vincent Povirk : windowscodecs: Support Run-length encoded TGA images.

Alexandre Julliard julliard at winehq.org
Fri Oct 22 12:30:43 CDT 2010


Module: wine
Branch: master
Commit: a5a7d6c9f0ad400338dffb7714e9536f23765daf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a5a7d6c9f0ad400338dffb7714e9536f23765daf

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Wed Oct 20 15:36:35 2010 -0500

windowscodecs: Support Run-length encoded TGA images.

---

 dlls/windowscodecs/tgaformat.c |   60 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/dlls/windowscodecs/tgaformat.c b/dlls/windowscodecs/tgaformat.c
index e088bbc..2e469bf 100644
--- a/dlls/windowscodecs/tgaformat.c
+++ b/dlls/windowscodecs/tgaformat.c
@@ -577,6 +577,63 @@ static HRESULT WINAPI TgaDecoder_Frame_CopyPalette(IWICBitmapFrameDecode *iface,
     return E_NOTIMPL;
 }
 
+static HRESULT TgaDecoder_ReadRLE(TgaDecoder *This, BYTE *imagebits, int datasize)
+{
+    int i=0, j, bytesperpixel;
+    ULONG bytesread;
+    HRESULT hr=S_OK;
+
+    bytesperpixel = This->header.depth / 8;
+
+    while (i<datasize)
+    {
+        BYTE rc;
+        int count, size;
+        BYTE pixeldata[4];
+
+        hr = IStream_Read(This->stream, &rc, 1, &bytesread);
+        if (bytesread != 1) hr = E_FAIL;
+        if (FAILED(hr)) break;
+
+        count = (rc&0x7f)+1;
+        size = count * bytesperpixel;
+
+        if (size + i > datasize)
+        {
+            WARN("RLE packet too large\n");
+            hr = E_FAIL;
+            break;
+        }
+
+        if (rc&0x80)
+        {
+            /* Run-length packet */
+            hr = IStream_Read(This->stream, pixeldata, bytesperpixel, &bytesread);
+            if (bytesread != bytesperpixel) hr = E_FAIL;
+            if (FAILED(hr)) break;
+
+            if (bytesperpixel == 1)
+                memset(&imagebits[i], pixeldata[0], count);
+            else
+            {
+                for (j=0; j<count; j++)
+                    memcpy(&imagebits[i+j*bytesperpixel], pixeldata, bytesperpixel);
+            }
+        }
+        else
+        {
+            /* Raw packet */
+            hr = IStream_Read(This->stream, &imagebits[i], size, &bytesread);
+            if (bytesread != size) hr = E_FAIL;
+            if (FAILED(hr)) break;
+        }
+
+        i += size;
+    }
+
+    return hr;
+}
+
 static HRESULT TgaDecoder_ReadImage(TgaDecoder *This)
 {
     HRESULT hr=S_OK;
@@ -614,8 +671,7 @@ static HRESULT TgaDecoder_ReadImage(TgaDecoder *This)
         {
             if (This->header.image_type & IMAGETYPE_RLE)
             {
-                FIXME("RLE decoding not implemented\n");
-                hr = E_NOTIMPL;
+                hr = TgaDecoder_ReadRLE(This, This->imagebits, datasize);
             }
             else
             {




More information about the wine-cvs mailing list