Any ideas how to speed up my program?

I am writing a program that can load sounds, pictures, and video files from zip archives. Basically it searches a zip for files with supported extensions, extracts them to a temp directory, opens them to get information, and then lists the information in a listview control.

The slow part is when I load images because I am trying to generate thumbnail bitmaps from each image to use as icons in the listview. I got the code working but it is quite slow.

Below is the code for generating the thumbnail icon. It runs in a thread separate from the GUI. I know that extracting the files is slow by itself, but without this function it is quite fast so I know this is the problem area. The image has to be scaled down and converted to a BITMAP in order to add it to the listview's imagelist. I looked into ways to scale the original WIC bitmap but got lost in all the COM mumbo jumbo. Any ideas what I can do to make this faster?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
BOOL Images::_getthumb(INT index, IWICBitmapFrameDecode** image)
{
	const INT thumbsize = 128;

	IWICBitmapSource* datasource = NULL;
	HRESULT hr = WICConvertBitmapSource(GUID_WICPixelFormat32bppBGR, (*image), &datasource);
	
	BOOL ret = TRUE;

	if (SUCCEEDED(hr))
	{
		UINT wid = _images[index]->Width;
		UINT hgt = _images[index]->Height;

		BYTE* data = new BYTE[wid * hgt * 4];

		if (data)
		{
			hr = datasource->CopyPixels(0, wid * 4, wid * hgt * 4, data);

			if (SUCCEEDED(hr))
			{
				if (_images[index]->Thumbnail)
				{
					DeleteObject(_images[index]->Thumbnail);
					_images[index]->Thumbnail = NULL;
				}

				HDC screendc = GetDC(NULL);

				HDC fulldc = CreateCompatibleDC(NULL); // for drawing from full-size bitmap
				HDC thumbdc = CreateCompatibleDC(NULL); // for drawing to thumb-size bitmap

				
				HBITMAP fullbitmap = CreateBitmap(wid, hgt, 1, 32, data);
				_images[index]->Thumbnail = CreateCompatibleBitmap(screendc, thumbsize, thumbsize);

				ReleaseDC(NULL, screendc);

				DeleteObject(SelectObject(fulldc, fullbitmap));
				DeleteObject(SelectObject(thumbdc, _images[index]->Thumbnail));

				// get scale rect of full-size bitmap to fit in thumb bitmap
				RECT scalerect = {0, 0, thumbsize, thumbsize};
				
				// scale and copy from full bitmap to thumb bitmap
				FillRect(thumbdc, &scalerect, (HBRUSH)GetStockObject(WHITE_BRUSH));
				
				_getscalerect(index, &scalerect);

				SetStretchBltMode(thumbdc, HALFTONE);
				StretchBlt(thumbdc, scalerect.left, scalerect.top, 
					scalerect.right, scalerect.bottom, fulldc, 0, 0, wid, hgt, SRCCOPY);

				DeleteObject(fullbitmap);
				DeleteDC(fulldc);
				DeleteDC(thumbdc);
			}
			else
				ret = FALSE;

			delete[] data;
			data = NULL;
		}
		else
			ret = FALSE;

		datasource->Release();
		datasource = NULL;
	}
	else
		ret = FALSE;

	return _images[index]->Thumbnail && ret? TRUE: FALSE;
}
What's the size of your source images?

I'm not a GDI crack but you do a lot of creating, copying, filling and releasing memory:
new BYTE[], CopyPixels(), CreateBitmap(), CreateCompatibleBitmap(), FillRect() and StretchBlt().
I think that most of the stuff is done by the CPU, maybe the StretchBlt() function is done by the GPU but I doubt that.
If your source files are maybe 2084x1024 pixels, all that adds up to about 25MB of data that's pumped through the CPU.

I'm not sure how good Microsoft implemented GDI+ but I think it's worth a try. I use it in all my projects now and it's way easier than the old GDI.


What's the size of your source images?


Pretty big(2MB+ ^^).

I don't use gdi+ because WIC supports more file types and I already use it everywhere in my code so it would be a pain to switch now. I also feel like I would end up with essentially the same code but with classes instead of GDI objects.

Anyway I was hoping for a WIC solution and I think I found it: the IWICBitmapScaler interface. Using this I can scale the image down before calling CopyPixels(), CreateBitmap(), etc. It helps alot but I am still open to suggestions.
Topic archived. No new replies allowed.