Vincent Povirk : windowscodecs: Implement Initialize for the TGA decoder.
Alexandre Julliard
julliard at winehq.org
Thu Oct 21 10:50:44 CDT 2010
Module: wine
Branch: master
Commit: 6d20f775171546f3905c6e307f5dfe3b3a22ae04
URL: http://source.winehq.org/git/wine.git/?a=commit;h=6d20f775171546f3905c6e307f5dfe3b3a22ae04
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Jun 7 16:14:59 2010 -0500
windowscodecs: Implement Initialize for the TGA decoder.
---
dlls/windowscodecs/tgaformat.c | 121 +++++++++++++++++++++++++++++++++++++++-
1 files changed, 119 insertions(+), 2 deletions(-)
diff --git a/dlls/windowscodecs/tgaformat.c b/dlls/windowscodecs/tgaformat.c
index b2fd32c..65d9d3e 100644
--- a/dlls/windowscodecs/tgaformat.c
+++ b/dlls/windowscodecs/tgaformat.c
@@ -35,10 +35,44 @@
WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);
+#include "pshpack1.h"
+
+typedef struct {
+ BYTE id_length;
+ BYTE colormap_type;
+ BYTE image_type;
+ /* Colormap Specification */
+ WORD colormap_firstentry;
+ WORD colormap_length;
+ BYTE colormap_entrysize;
+ /* Image Specification */
+ WORD xorigin;
+ WORD yorigin;
+ WORD width;
+ WORD height;
+ BYTE depth;
+ BYTE image_descriptor;
+} tga_header;
+
+#define IMAGETYPE_COLORMAPPED 1
+#define IMAGETYPE_TRUECOLOR 2
+#define IMAGETYPE_GRAYSCALE 3
+#define IMAGETYPE_RLE 8
+
+#define IMAGE_ATTRIBUTE_BITCOUNT_MASK 0xf
+#define IMAGE_RIGHTTOLEFT 0x10
+#define IMAGE_TOPTOBOTTOM 0x20
+
+#include "poppack.h"
+
typedef struct {
const IWICBitmapDecoderVtbl *lpVtbl;
const IWICBitmapFrameDecodeVtbl *lpFrameVtbl;
LONG ref;
+ BOOL initialized;
+ IStream *stream;
+ tga_header header;
+ CRITICAL_SECTION lock;
} TgaDecoder;
static inline TgaDecoder *decoder_from_frame(IWICBitmapFrameDecode *iface)
@@ -87,6 +121,10 @@ static ULONG WINAPI TgaDecoder_Release(IWICBitmapDecoder *iface)
if (ref == 0)
{
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
+ if (This->stream)
+ IStream_Release(This->stream);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -103,8 +141,83 @@ static HRESULT WINAPI TgaDecoder_QueryCapability(IWICBitmapDecoder *iface, IStre
static HRESULT WINAPI TgaDecoder_Initialize(IWICBitmapDecoder *iface, IStream *pIStream,
WICDecodeOptions cacheOptions)
{
- FIXME("(%p,%p,%u): stub\n", iface, pIStream, cacheOptions);
- return E_NOTIMPL;
+ TgaDecoder *This = (TgaDecoder*)iface;
+ HRESULT hr=S_OK;
+ DWORD bytesread;
+ LARGE_INTEGER seek;
+
+ TRACE("(%p,%p,%u)\n", iface, pIStream, cacheOptions);
+
+ EnterCriticalSection(&This->lock);
+
+ if (This->initialized)
+ {
+ hr = WINCODEC_ERR_WRONGSTATE;
+ goto end;
+ }
+
+ seek.QuadPart = 0;
+ hr = IStream_Seek(pIStream, seek, STREAM_SEEK_SET, NULL);
+ if (FAILED(hr)) goto end;
+
+ hr = IStream_Read(pIStream, &This->header, sizeof(tga_header), &bytesread);
+ if (SUCCEEDED(hr) && bytesread != sizeof(tga_header))
+ {
+ TRACE("got only %u bytes\n", bytesread);
+ hr = E_FAIL;
+ }
+ if (FAILED(hr)) goto end;
+
+ TRACE("imagetype=%u, colormap type=%u, depth=%u, image descriptor=0x%x\n",
+ This->header.image_type, This->header.colormap_type,
+ This->header.depth, This->header.image_descriptor);
+
+ /* Sanity checking. Since TGA has no clear identifying markers, we need
+ * to be careful to not load a non-TGA image. */
+ switch (This->header.image_type)
+ {
+ case IMAGETYPE_COLORMAPPED:
+ case IMAGETYPE_COLORMAPPED|IMAGETYPE_RLE:
+ if (This->header.colormap_type != 1)
+ hr = E_FAIL;
+ break;
+ case IMAGETYPE_TRUECOLOR:
+ case IMAGETYPE_TRUECOLOR|IMAGETYPE_RLE:
+ if (This->header.colormap_type != 0 && This->header.colormap_type != 1)
+ hr = E_FAIL;
+ break;
+ case IMAGETYPE_GRAYSCALE:
+ case IMAGETYPE_GRAYSCALE|IMAGETYPE_RLE:
+ if (This->header.colormap_type != 0)
+ hr = E_FAIL;
+ break;
+ default:
+ hr = E_FAIL;
+ }
+
+ if (This->header.depth != 8 && This->header.depth != 16 &&
+ This->header.depth != 24 && This->header.depth != 32)
+ hr = E_FAIL;
+
+ if ((This->header.image_descriptor & IMAGE_ATTRIBUTE_BITCOUNT_MASK) > 8 ||
+ (This->header.image_descriptor & 0xc0) != 0)
+ hr = E_FAIL;
+
+ if (FAILED(hr))
+ {
+ WARN("bad tga header\n");
+ goto end;
+ }
+
+ /* FIXME: Read footer if there is one. */
+
+ IStream_AddRef(pIStream);
+ This->stream = pIStream;
+ This->initialized = TRUE;
+
+end:
+ LeaveCriticalSection(&This->lock);
+ return hr;
}
static HRESULT WINAPI TgaDecoder_GetContainerFormat(IWICBitmapDecoder *iface,
@@ -309,6 +422,10 @@ HRESULT TgaDecoder_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
This->lpVtbl = &TgaDecoder_Vtbl;
This->lpFrameVtbl = &TgaDecoder_Frame_Vtbl;
This->ref = 1;
+ This->initialized = FALSE;
+ This->stream = NULL;
+ InitializeCriticalSection(&This->lock);
+ This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": TgaDecoder.lock");
ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
IUnknown_Release((IUnknown*)This);
More information about the wine-cvs
mailing list