HBITMAP ImageDecoder::convertFrameToBitmap(IWICBitmapFrameDecode *frame)
{
	IWICBitmapSource *bitmapSource = frame;
	if (FAILED(WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, frame, &bitmapSource)))
	{
		throw Exception("could not convert bitmap");
	}

	UINT width = 0;
	UINT height = 0;
	if (FAILED(bitmapSource->GetSize(&width, &height)) || width == 0 || height == 0)
	{
		throw Exception("could not get image size");
	}

	std::vector<BYTE> buffer(width * height * 4);
	if (FAILED(bitmapSource->CopyPixels(NULL, width * 4, buffer.size(), &buffer[0])))
	{
		throw Exception("could not get image size");
	}

	bitmapSource->Release();

	return CreateBitmap(width, height, 1, 32, &buffer[0]);
}
Beispiel #2
0
HBITMAP LoadPNGImage(UINT id, OUT VOID **bits)
{
	HBITMAP hbmpSplash = NULL;

	// load the PNG image data into a stream
	IStream * ipImageStream = CreateStreamOnResource(MAKEINTRESOURCE(id), _T("PNG"));

	if (ipImageStream == NULL)
		goto Return;

	// load the bitmap with WIC
	IWICBitmapSource * ipBitmap = LoadBitmapFromStream(ipImageStream);

	if (ipBitmap == NULL)
		goto ReleaseStream;

	// create a HBITMAP containing the image
	hbmpSplash = CreateHBITMAP(ipBitmap, bits);

	ipBitmap->Release();

ReleaseStream:

	ipImageStream->Release();

Return:
	return hbmpSplash;
}
Beispiel #3
0
Image::Buffer * WIC::Api::CreateImage(char * buffer, unsigned bufferLength)
{
	if(!factory) return 0;

	// Create input stream for memory
	IWICStream * stream = 0;
	factory->CreateStream(&stream);
	if(!stream) return 0;

	stream->InitializeFromMemory((unsigned char*)(buffer), static_cast<DWORD>(bufferLength));

	IWICBitmapDecoder * decoder = 0;
	factory->CreateDecoderFromStream(stream, 0, WICDecodeMetadataCacheOnDemand, &decoder);
	if(!decoder) return 0;

	IWICBitmapFrameDecode * bitmapSource = 0;
	decoder->GetFrame(0, &bitmapSource);
	if(!bitmapSource)
	{
		decoder->Release();
		return 0;
	}

	IWICBitmapSource * convertedSource = 0;
	WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmapSource, &convertedSource);
	bitmapSource->Release();
	if(!convertedSource)
	{
		decoder->Release();
		return 0;
	}

	// Create the bitmap from the image frame.
	IWICBitmap * bitmap = 0;
	factory->CreateBitmapFromSource(
		convertedSource,         // Create a bitmap from the image frame
		WICBitmapCacheOnDemand,  // Cache metadata when needed
		&bitmap);                // Pointer to the bitmap

	convertedSource->Release();
	decoder->Release();

	if(!bitmap) return 0;

	unsigned width = 0, height = 0;
	bitmap->GetSize(&width, &height);
	WICRect lockRect = { 0, 0, width, height };

	IWICBitmapLock * lock = 0;
	bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock);
	if(!lock)
	{
		bitmap->Release();
		return 0;
	}

	return new WIC::Buffer(bitmap, lock, width, height);
}
Beispiel #4
0
Image::Buffer * WIC::Api::CreateImage(char * data, unsigned dataSize, unsigned w, unsigned h, Image::Format format)
{
	IWICBitmap * bitmap = 0;

	factory->CreateBitmap(w, h, IMAGE_FORMAT_TO_WIC_GUID[format], WICBitmapCacheOnLoad, &bitmap);
	if(!bitmap) return 0;

	WICRect lockRect = { 0, 0, w, h };

	IWICBitmapLock * lock = 0;
	bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock);
	if(!lock)
	{
		bitmap->Release();
		return 0;
	}
	
	unsigned bufferSize = 0;
	WICInProcPointer dataPointer = 0;
	lock->GetDataPointer(&bufferSize, &dataPointer);

	memcpy(dataPointer, data, dataSize);

	lock->Release();
	lock = 0;

	if(format != Image::Format_4x8intRGBA)
	{
		IWICBitmapSource * convertedSource = 0;
		WICConvertBitmapSource(GUID_WICPixelFormat32bppRGBA, bitmap, &convertedSource);
		bitmap->Release();
		bitmap = 0;
		if(!convertedSource) return 0;

		// Create the bitmap from the image frame.
		factory->CreateBitmapFromSource(
			convertedSource,         // Create a bitmap from the image frame
			WICBitmapCacheOnDemand,  // Cache metadata when needed
			&bitmap);                // Pointer to the bitmap
		convertedSource->Release();
		if(!bitmap) return 0;
	}

	bitmap->Lock(&lockRect, WICBitmapLockWrite, &lock);
	if(!lock)
	{
		bitmap->Release();
		return 0;
	}

	return new WIC::Buffer(bitmap, lock, w, h);
}
//----------------------------------------------------------------------------
Texture2* WICFileIO::Load(std::string const& filename, bool wantMipmaps)
{
    // Start COM and create WIC.
    ComInitializer comInitializer;
    if (!comInitializer.IsInitialized())
    {
        LogError("Unable to initialize COM for WIC.");
        return nullptr;
    }

    // Create a WIC imaging factory.
    ComObject<IWICImagingFactory> wicFactory;
    HRESULT hr = ::CoCreateInstance(CLSID_WICImagingFactory, nullptr,
        CLSCTX_INPROC_SERVER, IID_IWICImagingFactory,
        reinterpret_cast<LPVOID*>(&wicFactory));
    if (FAILED(hr))
    {
        LogError("Unable to create WIC imaging factory.");
        return nullptr;
    }

    // Create a decoder based on the file name.
    std::wstring wfilename = Environment::Convert(filename);
    ComObject<IWICBitmapDecoder> wicDecoder;
    hr = wicFactory->CreateDecoderFromFilename(wfilename.c_str(),
        nullptr, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &wicDecoder);
    if (FAILED(hr))
    {
        LogError("wicFactory->CreateDecoderFromFilename failed (" +
            filename + ").");
        return nullptr;
    }

    // Create a WIC decoder.
    ComObject<IWICBitmapFrameDecode> wicFrameDecode;
    hr = wicDecoder->GetFrame(0, &wicFrameDecode);
    if (FAILED(hr))
    {
        LogError("wicDecoder->GetFrame failed.");
        return nullptr;
    }

    // Get the pixel format of the image.
    WICPixelFormatGUID wicSourceGUID;
    hr = wicFrameDecode->GetPixelFormat(&wicSourceGUID);
    if (FAILED(hr))
    {
        LogError("wicFrameDecode->GetPixelFormat failed.");
        return nullptr;
    }

    // Find the supported WIC input pixel format that matches a Texture2
    // format.  If a matching format is not found, the returned texture
    // is an R8G8B8A8 format with texels converted from the source format.
    WICPixelFormatGUID wicConvertGUID = GUID_WICPixelFormat32bppRGBA;
    DFType gtformat = DF_R8G8B8A8_UNORM;
    for (int i = 0; i < NUM_LOAD_FORMATS; ++i)
    {
        if (IsEqualGUID(wicSourceGUID, *msLoadFormatMap[i].wicInputGUID))
        {
            // Determine whether there is a conversion format.
            if (msLoadFormatMap[i].wicConvertGUID)
            {
                wicConvertGUID = *msLoadFormatMap[i].wicConvertGUID;
            }
            else
            {
                wicConvertGUID = *msLoadFormatMap[i].wicInputGUID;
            }
            gtformat = msLoadFormatMap[i].gtFormat;
            break;
        }
    }

    // The wicFrameDecode value is used for no conversion.  If the decoder
    // does not support the format in the texture, then a conversion is
    // required.
    IWICBitmapSource* wicBitmapSource = wicFrameDecode;
    ComObject<IWICFormatConverter> wicFormatConverter;
    if (!IsEqualGUID(wicSourceGUID, wicConvertGUID))
    {
        // Create a WIC format converter.
        hr = wicFactory->CreateFormatConverter(&wicFormatConverter);
        if (FAILED(hr))
        {
            LogError("wicFactory->CreateFormatConverter failed.");
            return false;
        }

        // Initialize format converter to convert the input texture format
        // to the nearest format supported by the decoder.
        hr = wicFormatConverter->Initialize(wicFrameDecode, wicConvertGUID,
            WICBitmapDitherTypeNone, nullptr, 0.0,
            WICBitmapPaletteTypeCustom);
        if (FAILED(hr))
        {
            LogError("wicFormatConverter->Initialize failed.");
            return false;
        }

        // Use the format converter.
        wicBitmapSource = wicFormatConverter;
    }

    // Get the image dimensions.
    UINT width, height;
    hr = wicBitmapSource->GetSize(&width, &height);
    if (FAILED(hr))
    {
        LogError("wicBitmapSource->GetSize failed.");
        return nullptr;
    }

    // Create the 2D texture and compute the stride and image size.
    std::unique_ptr<Texture2> texture(new Texture2(gtformat, width,
        height, wantMipmaps));
    UINT const stride = width * texture->GetElementSize();
    UINT const imageSize = stride * height;

    // Copy the pixels from the decoder to the texture.
    hr = wicBitmapSource->CopyPixels(nullptr, stride, imageSize,
        texture->Get<BYTE>());
    if (FAILED(hr))
    {
        LogError("wicBitmapSource->CopyPixels failed.");
        return nullptr;
    }

    return texture.release();
}
Beispiel #6
0
	HBITMAP ImageUtil::LoadImage(string path) {
		size_t pathFileExtDot = path.find_last_of('.');
		if (pathFileExtDot == string::npos || pathFileExtDot + 1 >=
			path.length())
			throw INETRException("[imgLoadFailed]");
		string ext = path.substr(pathFileExtDot + 1);

		const GUID *decoderCLSID = nullptr;
		if (ext == "png")
			decoderCLSID = &CLSID_WICPngDecoder;
		else if (ext == "bmp")
			decoderCLSID = &CLSID_WICBmpDecoder;
		else if (ext == "gif")
			decoderCLSID = &CLSID_WICGifDecoder;
		else if (ext == "jpg" || ext == "jpeg")
			decoderCLSID = &CLSID_WICJpegDecoder;

		if (decoderCLSID == nullptr)
			throw INETRException("[unsupportedImg]: " + ext);

		IStream *pngFileStream;
		if (FAILED(SHCreateStreamOnFile(path.c_str(), STGM_READ,
			&pngFileStream)))
			throw INETRException("[imgLoadFailed]:\n" + path);

		IWICBitmapDecoder *bmpDecoder = nullptr;
		if (FAILED(CoCreateInstance(*decoderCLSID, nullptr,
			CLSCTX_INPROC_SERVER, __uuidof(bmpDecoder),
			reinterpret_cast<void**>(&bmpDecoder))))
			throw INETRException("[imgDecFailed]");

		if (FAILED(bmpDecoder->Initialize(pngFileStream,
			WICDecodeMetadataCacheOnLoad))) {

			bmpDecoder->Release();
			throw INETRException("[imgDecFailed]");
		}

		UINT bmpFrameCount = 0;
		if (FAILED(bmpDecoder->GetFrameCount(&bmpFrameCount)) && bmpFrameCount
			!= 1) {

			bmpDecoder->Release();
			throw INETRException("[imgDecFailed]");
		}

		IWICBitmapFrameDecode *bmpFrame = nullptr;
		if (FAILED(bmpDecoder->GetFrame(0, &bmpFrame))) {
			bmpDecoder->Release();
			throw INETRException("[imgDecFailed]");
		}

		IWICBitmapSource *bmpSource = nullptr;
		WICConvertBitmapSource(GUID_WICPixelFormat32bppPBGRA, bmpFrame,
			&bmpSource);

		bmpFrame->Release();
		bmpDecoder->Release();

		UINT width = 0, height = 0;
		if (FAILED(bmpSource->GetSize(&width, &height)) || width == 0 || height
			== 0)
			throw INETRException("[imgDecFailed]");

		BITMAPINFO bmInfo;
		ZeroMemory(&bmInfo, sizeof(bmInfo));
		bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
		bmInfo.bmiHeader.biWidth = width;
		bmInfo.bmiHeader.biHeight = -((LONG)height);
		bmInfo.bmiHeader.biPlanes = 1;
		bmInfo.bmiHeader.biBitCount = 32;
		bmInfo.bmiHeader.biCompression = BI_RGB;

		HBITMAP hbmp = nullptr;

		void *imageBits = nullptr;
		HDC screenDC = GetDC(nullptr);
		hbmp = CreateDIBSection(screenDC, &bmInfo, DIB_RGB_COLORS, &imageBits,
			nullptr, 0);
		ReleaseDC(nullptr, screenDC);
		if (hbmp == nullptr)
			throw INETRException("[imgDecFailed]");

		const UINT bmpStride = width * 4;
		const UINT bmpSize = bmpStride * height;
		if (FAILED(bmpSource->CopyPixels(nullptr, bmpStride, bmpSize,
			static_cast<BYTE*>(imageBits)))) {

			DeleteObject(hbmp);
			hbmp = nullptr;
			throw INETRException("[imgDecFailed]");
		}

		bmpSource->Release();

		return hbmp;
	}