v6: Rebased on top of master as of this patch date
v5: Redundant newline removed.
Signed-off-by: Aaryaman Vasishta <jem456.vasishta@gmail.com>
---
������dlls/d3drm/d3drm_private.h |������ ������1 +
������dlls/d3drm/tests/d3drm.c������ ������|������ 79 ++++++++-
������dlls/d3drm/texture.c������ ������ ������ ������| 325 ++++++++++++++++++++++++++++++++++++-
������3 files changed, 393 insertions(+), 12 deletions(-)
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h
index 858911f350..333b809896 100644
--- a/dlls/d3drm/d3drm_private.h
+++ b/dlls/d3drm/d3drm_private.h
@@ -26,6 +26,7 @@
������#define COBJMACROS
������#include <assert.h>
������#include <math.h>
+#include <limits.h>
������#include "dxfile.h"
������#include "d3drmwin.h"
������#include "rmxfguid.h"
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index f78e098fec..4ed90ca682 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -5572,6 +5572,7 @@ static void test_load_texture(void)
������ ������ ������char *filename;
������ ������ ������HRESULT hr;
������ ������ ������BOOL ret;
+������ ������ ULONG ref1, ref2;
������ ������ ������int i;
������ ������ ������static const struct
@@ -5595,6 +5596,7 @@ static void test_load_texture(void)
������ ������ ������ok(SUCCEEDED(hr), "Failed to get IDirect3DRM2 interface, hr %#x.\n", hr);
������ ������ ������hr = IDirect3DRM_QueryInterface(d3drm1, &IID_IDirect3DRM3, (void **)&d3drm3);
������ ������ ������ok(SUCCEEDED(hr), "Failed to get IDirect3DRM3 interface, hr %#x.\n", hr);
+������ ������ ref1 = get_refcount((IUnknown *)d3drm1);
������ ������ ������for (i = 0; i < ARRAY_SIZE(tests); ++i)
������ ������ ������{
@@ -5602,24 +5604,74 @@ static void test_load_texture(void)
������ ������ ������ ������ ������hr = IDirect3DRM_LoadTexture(d3drm1, filename, &texture1);
������ ������ ������ ������ ������ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ todo_wine ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+
+������ ������ ������ ������ hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
+������ ������ ������ ������ todo_wine ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ /* InitFromFile seems to AddRef IDirect3DRM even if it fails. */
+������ ������ ������ ������ if (FAILED(hr))
+������ ������ ������ ������ ������ ������ IDirect3DRM_Release(d3drm1);
������ ������ ������ ������ ������d3drm_img = IDirect3DRMTexture_GetImage(texture1);
-������ ������ ������ ������ todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
������ ������ ������ ������ ������if (d3drm_img)
-������ ������ ������ ������ ������ ������ test_bitmap_data(i * 4, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
+������ ������ ������ ������ ������ ������ test_bitmap_data(i * 7, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
+������ ������ ������ ������ IDirect3DRMTexture_Release(texture1);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+������ ������ ������ ������ hr = IDirect3DRM_CreateObject(d3drm1, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture, (void **)&texture1);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture_InitFromFile(texture1, NULL);
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture_InitFromFile(texture1, "");
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture_InitFromFile(texture1, filename);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to initialize texture from file, hr %#x.\n", i, hr);
+������ ������ ������ ������ d3drm_img = IDirect3DRMTexture_GetImage(texture1);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ test_bitmap_data(i * 7 + 1, d3drm_img, FALSE, tests[i].w, tests[i].h, tests[i].palettized);
������ ������ ������ ������ ������IDirect3DRMTexture_Release(texture1);
������ ������ ������ ������ ������hr = IDirect3DRM2_LoadTexture(d3drm2, filename, &texture2);
������ ������ ������ ������ ������ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ todo_wine ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+
+������ ������ ������ ������ hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
+������ ������ ������ ������ todo_wine ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ if (FAILED(hr))
+������ ������ ������ ������ ������ ������ IDirect3DRM_Release(d3drm1);
������ ������ ������ ������ ������d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
-������ ������ ������ ������ todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
������ ������ ������ ������ ������if (d3drm_img)
-������ ������ ������ ������ ������ ������ test_bitmap_data(i * 4 + 1, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
+������ ������ ������ ������ ������ ������ test_bitmap_data(i * 7 + 2, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
+������ ������ ������ ������ IDirect3DRMTexture2_Release(texture2);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+������ ������ ������ ������ hr = IDirect3DRM2_CreateObject(d3drm2, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture2, (void **)&texture2);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture2_InitFromFile(texture2, NULL);
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture2_InitFromFile(texture2, "");
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture2_InitFromFile(texture2, filename);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to initialize texture from file, hr %#x.\n", i, hr);
+������ ������ ������ ������ d3drm_img = IDirect3DRMTexture2_GetImage(texture2);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ test_bitmap_data(i * 7 + 3, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
������ ������ ������ ������ ������IDirect3DRMTexture2_Release(texture2);
������ ������ ������ ������ ������hr = IDirect3DRM3_LoadTexture(d3drm3, filename, &texture3);
������ ������ ������ ������ ������ok(SUCCEEDED(hr), "Test %u: Failed to load texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ todo_wine ok(ref2 > ref1, "Test %u: expected ref2 > ref1, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+
+������ ������ ������ ������ hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
+������ ������ ������ ������ todo_wine ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ if (FAILED(hr))
+������ ������ ������ ������ ������ ������ IDirect3DRM_Release(d3drm1);
������ ������ ������ ������ ������d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
-������ ������ ������ ������ todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
������ ������ ������ ������ ������if (d3drm_img)
������ ������ ������ ������ ������ ������ ������test_bitmap_data(i * 4 + 2, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
������ ������ ������ ������ ������/* Test whether querying a version 1 texture from version 3 causes a
@@ -5627,11 +5679,26 @@ static void test_load_texture(void)
������ ������ ������ ������ ������hr = IDirect3DRMTexture3_QueryInterface(texture3, &IID_IDirect3DRMTexture, (void **)&texture1);
������ ������ ������ ������ ������ok(SUCCEEDED(hr), "Failed to get IDirect3DRMTexture interface, hr %#x.\n", hr);
������ ������ ������ ������ ������d3drm_img = IDirect3DRMTexture_GetImage(texture1);
-������ ������ ������ ������ todo_wine ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
������ ������ ������ ������ ������if (d3drm_img)
������ ������ ������ ������ ������ ������ ������test_bitmap_data(i * 4 + 3, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
������ ������ ������ ������ ������IDirect3DRMTexture_Release(texture1);
������ ������ ������ ������ ������IDirect3DRMTexture3_Release(texture3);
+������ ������ ������ ������ ref2 = get_refcount((IUnknown *)d3drm1);
+������ ������ ������ ������ ok(ref1 == ref2, "Test %u: expected ref1 == ref2, got ref1 = %u, ref2 = %u.\n", i, ref1, ref2);
+
+������ ������ ������ ������ hr = IDirect3DRM3_CreateObject(d3drm3, &CLSID_CDirect3DRMTexture, NULL, &IID_IDirect3DRMTexture3, (void **)&texture3);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to create texture, hr %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture3_InitFromFile(texture3, NULL);
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture3_InitFromFile(texture3, "");
+������ ������ ������ ������ ok(hr == D3DRMERR_BADOBJECT, "Test %u: Expected hr == D3DRMERR_BADOBJECT, got %#x.\n", i, hr);
+������ ������ ������ ������ hr = IDirect3DRMTexture3_InitFromFile(texture3, filename);
+������ ������ ������ ������ ok(SUCCEEDED(hr), "Test %u: Failed to initialize texture from file, hr %#x.\n", i, hr);
+������ ������ ������ ������ d3drm_img = IDirect3DRMTexture3_GetImage(texture3);
+������ ������ ������ ������ ok(!!d3drm_img, "Test %u: Failed to get image.\n", i);
+������ ������ ������ ������ test_bitmap_data(i * 7 + 6, d3drm_img, TRUE, tests[i].w, tests[i].h, tests[i].palettized);
+������ ������ ������ ������ IDirect3DRMTexture3_Release(texture3);
������ ������ ������ ������ ������ret = DeleteFileA(filename);
������ ������ ������ ������ ������ok(ret, "Test %u: Failed to delete bitmap \"%s\".\n", i, filename);
diff --git a/dlls/d3drm/texture.c b/dlls/d3drm/texture.c
index fd56e76ff9..4c81c788bf 100644
--- a/dlls/d3drm/texture.c
+++ b/dlls/d3drm/texture.c
@@ -2,6 +2,7 @@
������ * Implementation of IDirect3DRMTextureX interfaces
������ *
������ * Copyright 2012 Christian Costa
+ * Copyright 2016 Aaryaman Vasishta
������ *
������ * This library is free software; you can redistribute it and/or
������ * modify it under the terms of the GNU Lesser General Public
@@ -67,6 +68,294 @@ static BOOL d3drm_validate_image(D3DRMIMAGE *image)
������ ������ ������return TRUE;
������}
+static void CDECL destroy_image_callback(IDirect3DRMObject *obj, void *arg)
+{
+������ ������ D3DRMIMAGE *image = arg;
+
+������ ������ TRACE("image %p texture object %p.\n", arg, obj);
+
+������ ������ HeapFree(GetProcessHeap(), 0, image->buffer1);
+������ ������ HeapFree(GetProcessHeap(), 0, image);
+}
+
+HRESULT d3drm_texture_load(struct d3drm_texture *texture, const char *path, BOOL load_upside_down, D3DRMIMAGE **image_out)
+{
+������ ������ BITMAPINFO *info;
+������ ������ BITMAPFILEHEADER *bmp_header;
+������ ������ unsigned char *buffer;
+������ ������ DWORD size;
+������ ������ HANDLE hfile, hmapping;
+������ ������ HRESULT hr = D3DRM_OK;
+������ ������ D3DRMPALETTEENTRY *colors = NULL;
+������ ������ D3DRMIMAGE *image = NULL;
+������ ������ BOOL black_used = FALSE, palette_used;
+������ ������ LONG w;
+������ ������ LONG h;
+������ ������ UINT i, j, k;
+������ ������ UINT idx, buffer1_idx;
+������ ������ unsigned char *buffer1;
+������ ������ UINT bpp;
+������ ������ UINT bpl;
+������ ������ UINT num_colors = 0;
+������ ������ struct colors_24bpp
+������ ������ {
+������ ������ ������ ������ BYTE red;
+������ ������ ������ ������ BYTE green;
+������ ������ ������ ������ BYTE blue;
+������ ������ } *color = NULL;
+
+������ ������ /* Load the bitmap data */
+������ ������ hfile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
+������ ������ if (hfile == INVALID_HANDLE_VALUE)
+������ ������ ������ ������ return D3DRMERR_BADOBJECT;
+
+������ ������ size = GetFileSize(hfile, NULL);
+������ ������ if (size == INVALID_FILE_SIZE)
+������ ������ {
+������ ������ ������ ������ CloseHandle(hfile);
+������ ������ ������ ������ return D3DRMERR_BADVALUE;
+������ ������ }
+������ ������ if (!(hmapping = CreateFileMappingA(hfile, NULL, PAGE_READONLY, 0, 0, NULL)))
+������ ������ {
+������ ������ ������ ������ CloseHandle(hfile);
+������ ������ ������ ������ return D3DRMERR_BADVALUE;
+������ ������ }
+������ ������ if (!(buffer = MapViewOfFile(hmapping, FILE_MAP_READ, 0, 0, 0)))
+������ ������ {
+������ ������ ������ ������ CloseHandle(hmapping);
+������ ������ ������ ������ CloseHandle(hfile);
+������ ������ ������ ������ return D3DRMERR_BADVALUE;
+������ ������ }
+
+������ ������ bmp_header = (BITMAPFILEHEADER *)buffer;
+������ ������ if (bmp_header->bfType != 0x4d42) /* BM */
+������ ������ {
+������ ������ ������ ������ hr = D3DRMERR_BADFILE;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ info = (BITMAPINFO *)(bmp_header + 1);
+������ ������ /* Only allow version 1 DIB's (BITMAPINFOHEADER) to be loaded������ */
+������ ������ if (info->bmiHeader.biSize != sizeof(info->bmiHeader))
+������ ������ {
+������ ������ ������ ������ hr = D3DRMERR_BADFILE;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ bpp = info->bmiHeader.biBitCount == 24 ? 32 : info->bmiHeader.biBitCount;
+������ ������ w = info->bmiHeader.biWidth;
+������ ������ h = abs(info->bmiHeader.biHeight);
+
+������ ������ if (bpp == 8)
+������ ������ {
+������ ������ ������ ������ buffer += sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + 256 * sizeof(RGBQUAD);
+������ ������ ������ ������ palette_used = TRUE;
+������ ������ }
+������ ������ else if (bpp == 32)
+������ ������ {
+������ ������ ������ ������ buffer += sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
+������ ������ ������ ������ palette_used = FALSE;
+������ ������ }
+������ ������ else
+������ ������ {
+������ ������ ������ ������ hr = D3DRMERR_BADFILE;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ /* Create and initialize the image struct. */
+������ ������ color = (struct colors_24bpp *)buffer;
+
+������ ������ if (palette_used)
+������ ������ ������ ������ bpl = w;
+������ ������ else if ((bpl = ((w + 3) & ~3)) > UINT_MAX / (bpp / 8))
+������ ������ {
+������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ bpl = bpl * bpp / 8;
+
+������ ������ if (bpl > UINT_MAX / h)
+������ ������ {
+������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ if (!(colors = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 256 * sizeof(*colors))))
+������ ������ {
+������ ������ ������ ������ WARN("Not enough memory to allocate palette, returning NULL.\n");
+������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ if (!(image = HeapAlloc(GetProcessHeap(), 0, sizeof(*image))))
+������ ������ {
+������ ������ ������ ������ WARN("Not enough memory to allocate image struct, returning NULL.\n");
+������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+������ ������ image->buffer1 = NULL;
+
+������ ������ if (!(image->buffer1 = HeapAlloc(GetProcessHeap(), 0, bpl * h)))
+������ ������ {
+������ ������ ������ ������ WARN("Not enough memory to allocate image buffer, returning NULL.\n");
+������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ goto cleanup;
+������ ������ }
+
+������ ������ buffer1 = image->buffer1;
+������ ������ memset(buffer1, 0xff, bpl * h);
+������ ������ if (!palette_used)
+������ ������ {
+������ ������ ������ ������ for (i = 0; i < h; i++)
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ for (j = 0; j < w; j++)
+������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ buffer1_idx = ((w + 3) & ~3) * i + j;
+������ ������ ������ ������ ������ ������ ������ ������ idx = load_upside_down ? (h - 1 - i) * w + j : i * w + j;
+������ ������ ������ ������ ������ ������ ������ ������ for (k = 0; k < 256; k++)
+������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ if (color[idx].blue == colors[k].blue������ ������&&
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ color[idx].green == colors[k].green &&
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ color[idx].red == colors[k].red)
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ if (color[idx].blue == 0 &&
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ color[idx].green == 0 &&
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ color[idx].red == 0 &&
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ !black_used)
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ black_used = TRUE;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ colors[num_colors++].flags = D3DRMPALETTE_READONLY;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ buffer1[buffer1_idx] = k;
+
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ break;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ ������ ������ if (k == 256)
+������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ if (num_colors == 256)
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ num_colors++;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ i = h;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ������ break;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ buffer1[buffer1_idx] = num_colors;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ colors[num_colors].red = color[idx].red;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ colors[num_colors].green = color[idx].green;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ colors[num_colors].blue = color[idx].blue;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ colors[num_colors++].flags = D3DRMPALETTE_READONLY;
+������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ }
+
+������ ������ ������ ������ if (num_colors <= 256)
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ if (!(image->palette = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(*image->palette))))
+������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ WARN("Not enough memory to allocate image palette, returning NULL.\n");
+������ ������ ������ ������ ������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ ������ ������ ������ ������ goto cleanup;
+������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ image->red_mask = 0xff;
+������ ������ ������ ������ ������ ������ image->green_mask = 0xff;
+������ ������ ������ ������ ������ ������ image->blue_mask = 0xff;
+������ ������ ������ ������ ������ ������ image->rgb = 0;
+������ ������ ������ ������ ������ ������ bpl = bpl / (bpp / 8);
+������ ������ ������ ������ ������ ������ memcpy(image->palette, colors, num_colors * sizeof(D3DRMPALETTEENTRY));
+������ ������ ������ ������ ������ ������ image->palette_size = num_colors;
+������ ������ ������ ������ ������ ������ palette_used = TRUE;
+������ ������ ������ ������ }
+������ ������ ������ ������ else
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ bpl = w * 4;
+������ ������ ������ ������ ������ ������ image->rgb = 1;
+������ ������ ������ ������ ������ ������ image->palette = NULL;
+������ ������ ������ ������ ������ ������ image->palette_size = 0;
+������ ������ ������ ������ ������ ������ for (i = 0; i < h; ++i)
+������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ for (j = 0; j < w; ++j)
+������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ unsigned char *ptr = &buffer1[i * bpl + j * 4];
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ idx = load_upside_down ? (h - 1 - i) * w * 3 + j * 3 : i * w * 3 + j * 3;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ptr[0] = buffer[idx];
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ptr[1] = buffer[idx + 1];
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ptr[2] = buffer[idx + 2];
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ ptr[3] = 0xff;
+������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ }
+
+������ ������ ������ ������ ������ ������ image->red_mask = 0xff0000;
+������ ������ ������ ������ ������ ������ image->green_mask = 0x00ff00;
+������ ������ ������ ������ ������ ������ image->blue_mask = 0x0000ff;
+������ ������ ������ ������ }
+������ ������ }
+������ ������ else
+������ ������ {
+������ ������ ������ ������ if (!(image->palette = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(*image->palette))))
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ WARN("Not enough memory to allocate image palette, returning NULL.\n");
+������ ������ ������ ������ ������ ������ hr = D3DRMERR_BADALLOC;
+������ ������ ������ ������ ������ ������ goto cleanup;
+������ ������ ������ ������ }
+
+������ ������ ������ ������ memcpy(image->palette, info->bmiColors, 256 * sizeof(D3DRMPALETTEENTRY));
+������ ������ ������ ������ for (i = 0; i < 256; i++)
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ image->palette[i].flags = D3DRMPALETTE_READONLY;
+������ ������ ������ ������ }
+������ ������ ������ ������ if (load_upside_down)
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ for (i = 0; i < h; i++)
+������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ for (j = 0; j < w; j++)
+������ ������ ������ ������ ������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ idx = (h - 1 - i) * bpl + j;
+������ ������ ������ ������ ������ ������ ������ ������ ������ ������ buffer1[i * bpl + j] = buffer[idx];
+������ ������ ������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ ������ ������ }
+������ ������ ������ ������ }
+������ ������ ������ ������ else
+������ ������ ������ ������ {
+������ ������ ������ ������ ������ ������ memcpy(buffer1, buffer, bpl * h);
+������ ������ ������ ������ }
+������ ������ ������ ������ image->palette_size = 256;
+������ ������ ������ ������ image->red_mask = 0xff;
+������ ������ ������ ������ image->green_mask = 0xff;
+������ ������ ������ ������ image->blue_mask = 0xff;
+������ ������ ������ ������ image->rgb = 0;
+������ ������ }
+������ ������ image->width = w;
+������ ������ image->height = h;
+������ ������ image->aspectx = 1;
+������ ������ image->aspecty = 1;
+������ ������ image->alpha_mask = 0;
+������ ������ image->depth = palette_used ? 8 : bpp;
+������ ������ image->bytes_per_line = bpl;
+������ ������ image->buffer2 = NULL;
+
+������ ������ /* Use an internal destroy callback to destroy image struct */
+������ ������ hr = IDirect3DRMObject_AddDestroyCallback(&texture->IDirect3DRMTexture3_iface, destroy_image_callback, image);
+
+������ ������ *image_out = image;
+
+cleanup:
+������ ������ UnmapViewOfFile(buffer);
+������ ������ CloseHandle(hmapping);
+������ ������ CloseHandle(hfile);
+
+������ ������ HeapFree(GetProcessHeap(), 0, colors);
+
+������ ������ if (FAILED(hr))
+������ ������ {
+������ ������ ������ ������ if (image)
+������ ������ ������ ������ ������ ������ HeapFree(GetProcessHeap(), 0, image->buffer1);
+������ ������ ������ ������ HeapFree(GetProcessHeap(), 0, image);
+������ ������ }
+
+������ ������ return hr;
+}
+
������static HRESULT WINAPI d3drm_texture1_QueryInterface(IDirect3DRMTexture *iface, REFIID riid, void **out)
������{
������ ������ ������struct d3drm_texture *texture = impl_from_IDirect3DRMTexture(iface);
@@ -171,9 +460,18 @@ static HRESULT WINAPI d3drm_texture1_GetClassName(IDirect3DRMTexture *iface, DWO
������static HRESULT WINAPI d3drm_texture1_InitFromFile(IDirect3DRMTexture *iface, const char *filename)
������{
-������ ������ FIXME("iface %p, filename %s stub!\n", iface, debugstr_a(filename));
+������ ������ struct d3drm_texture *texture = impl_from_IDirect3DRMTexture(iface);
+������ ������ D3DRMIMAGE *image;
+������ ������ HRESULT hr;
-������ ������ return E_NOTIMPL;
+������ ������ TRACE("iface %p, filename %s.\n", iface, debugstr_a(filename));
+
+������ ������ if (FAILED(hr = d3drm_texture_load(texture, filename, FALSE, &image)))
+������ ������ ������ ������ return hr;
+
+������ ������ hr = IDirect3DRMTexture3_InitFromImage(&texture->IDirect3DRMTexture3_iface, image);
+
+������ ������ return hr;
������}
������static HRESULT WINAPI d3drm_texture1_InitFromSurface(IDirect3DRMTexture *iface,
@@ -473,9 +771,15 @@ static HRESULT WINAPI d3drm_texture2_GetClassName(IDirect3DRMTexture2 *iface, DW
������static HRESULT WINAPI d3drm_texture2_InitFromFile(IDirect3DRMTexture2 *iface, const char *filename)
������{
-������ ������ FIXME("iface %p, filename %s stub!\n", iface, debugstr_a(filename));
+������ ������ struct d3drm_texture *object = impl_from_IDirect3DRMTexture2(iface);
+������ ������ HRESULT hr;
-������ ������ return E_NOTIMPL;
+������ ������ TRACE("iface %p, filename %s.\n", iface, debugstr_a(filename));
+
+������ ������ if (FAILED(hr = IDirect3DRMTexture3_InitFromFile(&object->IDirect3DRMTexture3_iface, filename)))
+������ ������ ������ ������ return hr;
+
+������ ������ return D3DRM_OK;
������}
������static HRESULT WINAPI d3drm_texture2_InitFromSurface(IDirect3DRMTexture2 *iface,
@@ -833,9 +1137,18 @@ static HRESULT WINAPI d3drm_texture3_GetClassName(IDirect3DRMTexture3 *iface, DW
������static HRESULT WINAPI d3drm_texture3_InitFromFile(IDirect3DRMTexture3 *iface, const char *filename)
������{
-������ ������ FIXME("iface %p, filename %s stub!\n", iface, debugstr_a(filename));
+������ ������ struct d3drm_texture *texture = impl_from_IDirect3DRMTexture3(iface);
+������ ������ D3DRMIMAGE *image;
+������ ������ HRESULT hr;
-������ ������ return E_NOTIMPL;
+������ ������ TRACE("iface %p, filename %s.\n", iface, debugstr_a(filename));
+
+������ ������ if (FAILED(hr = d3drm_texture_load(texture, filename, TRUE, &image)))
+������ ������ ������ ������ return hr;
+
+������ ������ hr = IDirect3DRMTexture3_InitFromImage(iface, image);
+
+������ ������ return hr;
������}
������static HRESULT WINAPI d3drm_texture3_InitFromSurface(IDirect3DRMTexture3 *iface,
--
2.17.1