[2/3] d3dxof: Factor out duplicated code for parsing X file header.

Dylan Smith dylan.ah.smith at gmail.com
Wed Jun 8 14:38:58 CDT 2011


---
 dlls/d3dxof/d3dxof.c         |  233 +++++-------------------------------------
 dlls/d3dxof/d3dxof_private.h |    1 +
 dlls/d3dxof/parsing.c        |  101 ++++++++++++++++++
 3 files changed, 128 insertions(+), 207 deletions(-)

diff --git a/dlls/d3dxof/d3dxof.c b/dlls/d3dxof/d3dxof.c
index 8392c31..213f3e1 100644
--- a/dlls/d3dxof/d3dxof.c
+++ b/dlls/d3dxof/d3dxof.c
@@ -33,18 +33,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof);
 
-#define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
-#define XOFFILE_FORMAT_MAGIC         MAKEFOUR('x','o','f',' ')
-#define XOFFILE_FORMAT_VERSION_302   MAKEFOUR('0','3','0','2')
-#define XOFFILE_FORMAT_VERSION_303   MAKEFOUR('0','3','0','3')
-#define XOFFILE_FORMAT_BINARY        MAKEFOUR('b','i','n',' ')
-#define XOFFILE_FORMAT_TEXT          MAKEFOUR('t','x','t',' ')
-#define XOFFILE_FORMAT_BINARY_MSZIP  MAKEFOUR('b','z','i','p')
-#define XOFFILE_FORMAT_TEXT_MSZIP    MAKEFOUR('t','z','i','p')
-#define XOFFILE_FORMAT_COMPRESSED    MAKEFOUR('c','m','p',' ')
-#define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
-#define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
-
 static const struct IDirectXFileVtbl IDirectXFile_Vtbl;
 static const struct IDirectXFileBinaryVtbl IDirectXFileBinary_Vtbl;
 static const struct IDirectXFileDataVtbl IDirectXFileData_Vtbl;
@@ -57,15 +45,6 @@ static HRESULT IDirectXFileDataReferenceImpl_Create(IDirectXFileDataReferenceImp
 static HRESULT IDirectXFileEnumObjectImpl_Create(IDirectXFileEnumObjectImpl** ppObj);
 static HRESULT IDirectXFileSaveObjectImpl_Create(IDirectXFileSaveObjectImpl** ppObj);
 
-/* FOURCC to string conversion for debug messages */
-static const char *debugstr_fourcc(DWORD fourcc)
-{
-    if (!fourcc) return "'null'";
-    return wine_dbg_sprintf ("\'%c%c%c%c\'",
-		(char)(fourcc), (char)(fourcc >> 8),
-        (char)(fourcc >> 16), (char)(fourcc >> 24));
-}
-
 HRESULT IDirectXFileImpl_Create(IUnknown* pUnkOuter, LPVOID* ppObj)
 {
     IDirectXFileImpl* object;
@@ -140,10 +119,6 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
   IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
   IDirectXFileEnumObjectImpl* object;
   HRESULT hr;
-  DWORD* header;
-  LPBYTE mapped_memory = NULL;
-  LPBYTE decomp_buffer = NULL;
-  DWORD decomp_size = 0;
   LPBYTE file_buffer;
   DWORD file_size;
 
@@ -155,6 +130,10 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
   /* Only lowest 4 bits are relevant in DXFILELOADOPTIONS */
   dwLoadOptions &= 0xF;
 
+  hr = IDirectXFileEnumObjectImpl_Create(&object);
+  if (FAILED(hr))
+    return hr;
+
   if (dwLoadOptions == DXFILELOAD_FROMFILE)
   {
     HANDLE hFile, file_mapping;
@@ -178,15 +157,15 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
       goto error;
     }
 
-    mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
+    object->mapped_memory = MapViewOfFile(file_mapping, FILE_MAP_READ, 0, 0, 0);
     CloseHandle(file_mapping);
     CloseHandle(hFile);
-    if (!mapped_memory)
+    if (!object->mapped_memory)
     {
       hr = DXFILEERR_BADFILETYPE;
       goto error;
     }
-    file_buffer = mapped_memory;
+    file_buffer = object->mapped_memory;
   }
   else if (dwLoadOptions == DXFILELOAD_FROMRESOURCE)
   {
@@ -235,107 +214,17 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
     goto error;
   }
 
-  header = (DWORD*)file_buffer;
-
-  if (TRACE_ON(d3dxof))
-  {
-    char string[17];
-    memcpy(string, header, 16);
-    string[16] = 0;
-    TRACE("header = '%s'\n", string);
-  }
-
-  if (file_size < 16)
-  {
-    hr = DXFILEERR_BADFILETYPE;
-    goto error;
-  }
-
-  if (header[0] != XOFFILE_FORMAT_MAGIC)
-  {
-    hr = DXFILEERR_BADFILETYPE;
-    goto error;
-  }
-
-  if ((header[1] != XOFFILE_FORMAT_VERSION_302) && (header[1] != XOFFILE_FORMAT_VERSION_303))
-  {
-    hr = DXFILEERR_BADFILEVERSION;
-    goto error;
-  }
-
-  if ((header[2] != XOFFILE_FORMAT_BINARY) && (header[2] != XOFFILE_FORMAT_TEXT) &&
-      (header[2] != XOFFILE_FORMAT_BINARY_MSZIP) && (header[2] != XOFFILE_FORMAT_TEXT_MSZIP))
-  {
-    WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
-    hr = DXFILEERR_BADFILETYPE;
-    goto error;
-  }
-
-  if ((header[2] == XOFFILE_FORMAT_BINARY_MSZIP) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP))
-  {
-    int err;
-    DWORD comp_size;
-
-    /*  0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
-       20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
-       24-xx -> compressed MSZIP data */
-    decomp_size = ((WORD*)file_buffer)[10];
-    comp_size = ((WORD*)file_buffer)[11];
-
-    TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
-        debugstr_fourcc(header[2]), comp_size, decomp_size);
-
-    decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
-    if (!decomp_buffer)
-    {
-        ERR("Out of memory\n");
-        hr = DXFILEERR_BADALLOC;
-        goto error;
-    }
-    err = mszip_decompress(comp_size, decomp_size, (char*)file_buffer + 24, (char*)decomp_buffer);
-    if (err)
-    {
-        WARN("Error while decomrpessing mszip archive %d\n", err);
-        hr = DXFILEERR_BADALLOC;
-        goto error;
-    }
-  }
-
-  if ((header[3] != XOFFILE_FORMAT_FLOAT_BITS_32) && (header[3] != XOFFILE_FORMAT_FLOAT_BITS_64))
-  {
-    hr = DXFILEERR_BADFILEFLOATSIZE;
-    goto error;
-  }
-
-  TRACE("Header is correct\n");
-
-  hr = IDirectXFileEnumObjectImpl_Create(&object);
-  if (FAILED(hr))
-    goto error;
+  TRACE("File size is %d bytes\n", file_size);
 
-  object->mapped_memory = mapped_memory;
-  object->decomp_buffer = decomp_buffer;
   object->pDirectXFile = This;
+
   object->buf.pdxf = This;
-  object->buf.txt = (header[2] == XOFFILE_FORMAT_TEXT) || (header[2] == XOFFILE_FORMAT_TEXT_MSZIP);
   object->buf.token_present = FALSE;
-
-  TRACE("File size is %d bytes\n", file_size);
-
-  if (decomp_size)
-  {
-    /* Use decompressed data */
-    object->buf.buffer = decomp_buffer;
-    object->buf.rem_bytes = decomp_size;
-  }
-  else
-  {
-    /* Go to data after header */
-    object->buf.buffer = file_buffer + 16;
-    object->buf.rem_bytes = file_size - 16;
-  }
-
-  *ppEnumObj = &object->IDirectXFileEnumObject_iface;
+  object->buf.buffer = file_buffer;
+  object->buf.rem_bytes = file_size;
+  hr = parse_header(&object->buf, &object->decomp_buffer);
+  if (FAILED(hr))
+    goto error;
 
   while (object->buf.rem_bytes && is_template_available(&object->buf))
   {
@@ -361,12 +250,12 @@ static HRESULT WINAPI IDirectXFileImpl_CreateEnumObject(IDirectXFile* iface, LPV
       DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
   }
 
+  *ppEnumObj = &object->IDirectXFileEnumObject_iface;
+
   return DXFILE_OK;
 
 error:
-  if (mapped_memory)
-    UnmapViewOfFile(mapped_memory);
-  HeapFree(GetProcessHeap(), 0, decomp_buffer);
+  IDirectXFileEnumObject_Release(&object->IDirectXFileEnumObject_iface);
   *ppEnumObj = NULL;
 
   return hr;
@@ -392,10 +281,9 @@ static HRESULT WINAPI IDirectXFileImpl_CreateSaveObject(IDirectXFile* iface, LPC
 static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LPVOID pvData, DWORD cbSize)
 {
   IDirectXFileImpl *This = impl_from_IDirectXFile(iface);
-  DWORD token_header;
   parse_buffer buf;
+  HRESULT hr;
   LPBYTE decomp_buffer = NULL;
-  DWORD decomp_size = 0;
 
   buf.buffer = pvData;
   buf.rem_bytes = cbSize;
@@ -408,87 +296,17 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
   if (!pvData)
     return DXFILEERR_BADVALUE;
 
-  if (cbSize < 16)
-    return DXFILEERR_BADFILETYPE;
-
-  if (TRACE_ON(d3dxof))
-  {
-    char string[17];
-    memcpy(string, pvData, 16);
-    string[16] = 0;
-    TRACE("header = '%s'\n", string);
-  }
-
-  read_bytes(&buf, &token_header, 4);
-
-  if (token_header != XOFFILE_FORMAT_MAGIC)
-    return DXFILEERR_BADFILETYPE;
-
-  read_bytes(&buf, &token_header, 4);
-
-  if ((token_header != XOFFILE_FORMAT_VERSION_302) && (token_header != XOFFILE_FORMAT_VERSION_303))
-    return DXFILEERR_BADFILEVERSION;
-
-  read_bytes(&buf, &token_header, 4);
-
-  if ((token_header != XOFFILE_FORMAT_BINARY) && (token_header != XOFFILE_FORMAT_TEXT) &&
-      (token_header != XOFFILE_FORMAT_BINARY_MSZIP) && (token_header != XOFFILE_FORMAT_TEXT_MSZIP))
-  {
-    WARN("File type %s unknown\n", debugstr_fourcc(token_header));
-    return DXFILEERR_BADFILETYPE;
-  }
-
-  if ((token_header == XOFFILE_FORMAT_BINARY_MSZIP) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
-  {
-    int err;
-    DWORD comp_size;
-
-    /*  0-15 -> xfile header, 16-17 -> decompressed size w/ header, 18-19 -> null,
-       20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
-       24-xx -> compressed MSZIP data */
-    decomp_size = ((WORD*)pvData)[10];
-    comp_size = ((WORD*)pvData)[11];
-
-    TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
-        debugstr_fourcc(token_header), comp_size, decomp_size);
-
-    decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
-    if (!decomp_buffer)
-    {
-        ERR("Out of memory\n");
-        return DXFILEERR_BADALLOC;
-    }
-    err = mszip_decompress(comp_size, decomp_size, (char*)pvData + 24, (char*)decomp_buffer);
-    if (err)
-    {
-        WARN("Error while decomrpessing mszip archive %d\n", err);
-        HeapFree(GetProcessHeap(), 0, decomp_buffer);
-        return DXFILEERR_BADALLOC;
-    }
-  }
-
-  if ((token_header == XOFFILE_FORMAT_TEXT) || (token_header == XOFFILE_FORMAT_TEXT_MSZIP))
-    buf.txt = TRUE;
-
-  read_bytes(&buf, &token_header, 4);
-
-  if ((token_header != XOFFILE_FORMAT_FLOAT_BITS_32) && (token_header != XOFFILE_FORMAT_FLOAT_BITS_64))
-    return DXFILEERR_BADFILEFLOATSIZE;
-
-  TRACE("Header is correct\n");
-
-  if (decomp_size)
-  {
-    buf.buffer = decomp_buffer;
-    buf.rem_bytes = decomp_size;
-  }
+  hr = parse_header(&buf, &decomp_buffer);
+  if (FAILED(hr))
+    goto cleanup;
 
   while (buf.rem_bytes && is_template_available(&buf))
   {
     if (!parse_template(&buf))
     {
       WARN("Template is not correct\n");
-      return DXFILEERR_BADVALUE;
+      hr = DXFILEERR_BADVALUE;
+      goto cleanup;
     }
     else
     {
@@ -506,9 +324,10 @@ static HRESULT WINAPI IDirectXFileImpl_RegisterTemplates(IDirectXFile* iface, LP
       DPRINTF("%s - %s\n", This->xtemplates[i].name, debugstr_guid(&This->xtemplates[i].class_id));
   }
 
+  hr = DXFILE_OK;
+cleanup:
   HeapFree(GetProcessHeap(), 0, decomp_buffer);
-
-  return DXFILE_OK;
+  return hr;
 }
 
 static const IDirectXFileVtbl IDirectXFile_Vtbl =
diff --git a/dlls/d3dxof/d3dxof_private.h b/dlls/d3dxof/d3dxof_private.h
index 5e61d65..15dca52 100644
--- a/dlls/d3dxof/d3dxof_private.h
+++ b/dlls/d3dxof/d3dxof_private.h
@@ -163,6 +163,7 @@ typedef struct {
 HRESULT IDirectXFileImpl_Create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN;
 
 BOOL read_bytes(parse_buffer * buf, LPVOID data, DWORD size) DECLSPEC_HIDDEN;
+HRESULT parse_header(parse_buffer *buf, BYTE **decomp_buffer_ptr) DECLSPEC_HIDDEN;
 BOOL parse_template(parse_buffer * buf) DECLSPEC_HIDDEN;
 void dump_template(xtemplate* templates_array, xtemplate* ptemplate) DECLSPEC_HIDDEN;
 BOOL is_template_available(parse_buffer * buf) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dxof/parsing.c b/dlls/d3dxof/parsing.c
index 417194b..7682dfe 100644
--- a/dlls/d3dxof/parsing.c
+++ b/dlls/d3dxof/parsing.c
@@ -36,6 +36,18 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(d3dxof_parsing);
 
+#define MAKEFOUR(a,b,c,d) ((DWORD)a + ((DWORD)b << 8) + ((DWORD)c << 16) + ((DWORD)d << 24))
+#define XOFFILE_FORMAT_MAGIC         MAKEFOUR('x','o','f',' ')
+#define XOFFILE_FORMAT_VERSION_302   MAKEFOUR('0','3','0','2')
+#define XOFFILE_FORMAT_VERSION_303   MAKEFOUR('0','3','0','3')
+#define XOFFILE_FORMAT_BINARY        MAKEFOUR('b','i','n',' ')
+#define XOFFILE_FORMAT_TEXT          MAKEFOUR('t','x','t',' ')
+#define XOFFILE_FORMAT_BINARY_MSZIP  MAKEFOUR('b','z','i','p')
+#define XOFFILE_FORMAT_TEXT_MSZIP    MAKEFOUR('t','z','i','p')
+#define XOFFILE_FORMAT_COMPRESSED    MAKEFOUR('c','m','p',' ')
+#define XOFFILE_FORMAT_FLOAT_BITS_32 MAKEFOUR('0','0','3','2')
+#define XOFFILE_FORMAT_FLOAT_BITS_64 MAKEFOUR('0','0','6','4')
+
 #define TOKEN_NAME         1
 #define TOKEN_STRING       2
 #define TOKEN_INTEGER      3
@@ -70,6 +82,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dxof_parsing);
 
 #define CLSIDFMT "<%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X>"
 
+/* FOURCC to string conversion for debug messages */
+static const char *debugstr_fourcc(DWORD fourcc)
+{
+    if (!fourcc) return "'null'";
+    return wine_dbg_sprintf ("\'%c%c%c%c\'",
+        (char)(fourcc), (char)(fourcc >> 8),
+        (char)(fourcc >> 16), (char)(fourcc >> 24));
+}
+
 static const char* get_primitive_string(WORD token)
 {
   switch(token)
@@ -161,6 +182,86 @@ static void rewind_bytes(parse_buffer * buf, DWORD size)
   buf->rem_bytes += size;
 }
 
+HRESULT parse_header(parse_buffer * buf, BYTE ** decomp_buffer_ptr)
+{
+  /* X File common header:
+   *  0-3  -> Magic Number (format identifier)
+   *  4-7  -> Format Version
+   *  8-11 -> Format Type (text or binary, decompressed or compressed)
+   * 12-15 -> Float Size (32 or 64 bits) */
+  DWORD header[4];
+
+  if (!read_bytes(buf, header, sizeof(header)))
+    return DXFILEERR_BADFILETYPE;
+
+  if (TRACE_ON(d3dxof_parsing))
+  {
+    char string[17];
+    memcpy(string, header, 16);
+    string[16] = 0;
+    TRACE("header = '%s'\n", string);
+  }
+
+  if (header[0] != XOFFILE_FORMAT_MAGIC)
+    return DXFILEERR_BADFILETYPE;
+
+  if (header[1] != XOFFILE_FORMAT_VERSION_302 && header[1] != XOFFILE_FORMAT_VERSION_303)
+    return DXFILEERR_BADFILEVERSION;
+
+  if (header[2] != XOFFILE_FORMAT_BINARY && header[2] != XOFFILE_FORMAT_TEXT &&
+      header[2] != XOFFILE_FORMAT_BINARY_MSZIP && header[2] != XOFFILE_FORMAT_TEXT_MSZIP)
+  {
+    WARN("File type %s unknown\n", debugstr_fourcc(header[2]));
+    return DXFILEERR_BADFILETYPE;
+  }
+
+  if (header[3] != XOFFILE_FORMAT_FLOAT_BITS_32 && header[3] != XOFFILE_FORMAT_FLOAT_BITS_64)
+    return DXFILEERR_BADFILEFLOATSIZE;
+
+  buf->txt = header[2] == XOFFILE_FORMAT_TEXT || header[2] == XOFFILE_FORMAT_TEXT_MSZIP;
+
+  if (header[2] == XOFFILE_FORMAT_BINARY_MSZIP || header[2] == XOFFILE_FORMAT_TEXT_MSZIP)
+  {
+    /* Extended header for compressed data:
+     * 16-17 -> decompressed size w/ header,  18-19 -> null,
+     * 20-21 -> decompressed size w/o header, 22-23 -> size of MSZIP compressed data,
+     * 24-xx -> compressed MSZIP data */
+    int err;
+    WORD decomp_size;
+    WORD comp_size;
+    LPBYTE decomp_buffer;
+
+    buf->rem_bytes -= sizeof(WORD) * 2;
+    buf->buffer += sizeof(WORD) * 2;
+    read_bytes(buf, &decomp_size, sizeof(decomp_size));
+    read_bytes(buf, &comp_size, sizeof(comp_size));
+
+    TRACE("Compressed format %s detected: compressed_size = %x, decompressed_size = %x\n",
+        debugstr_fourcc(header[2]), comp_size, decomp_size);
+
+    decomp_buffer = HeapAlloc(GetProcessHeap(), 0, decomp_size);
+    if (!decomp_buffer)
+    {
+        ERR("Out of memory\n");
+        return DXFILEERR_BADALLOC;
+    }
+    err = mszip_decompress(comp_size, decomp_size, (char*)buf->buffer, (char*)decomp_buffer);
+    if (err)
+    {
+        WARN("Error while decompressing mszip archive %d\n", err);
+        HeapFree(GetProcessHeap(), 0, decomp_buffer);
+        return DXFILEERR_BADALLOC;
+    }
+    /* Use decompressed data */
+    buf->buffer = *decomp_buffer_ptr = decomp_buffer;
+    buf->rem_bytes = decomp_size;
+  }
+
+  TRACE("Header is correct\n");
+
+  return S_OK;
+}
+
 static void dump_TOKEN(WORD token)
 {
 #define DUMP_TOKEN(t) case t: TRACE(#t "\n"); break
-- 
1.7.4.1




More information about the wine-patches mailing list