Thursday, December 18, 2014

Pure CMake based bin2h implementation

I had been writing CMake build script for a project that requires converting few files into C/C++ headers so that the content of those files can be embedded in the output binary.

I could've done this by executing an external bin2h program to do the conversion. But as it is a cross-platform application I need to depend on platform specific bin2h programs. A widely used approach for this is to include bin2h source in the project code base and compile it on the target platform then use the resultant executable for the bin2h conversion.

I didn't want to include the source bin2h in my project and compile it on-demand. I was thinking there should be a CMake command/function/module to do this in cross-platform way but I couldn't find anything.

So I started writing a pure CMake based bin2h implementation and end up with the following. The following module provides a CMake function "BIN2H" that can be used to convert any files into C/C++ header file. We need to specify the source file, header file and the C/C++ variable name that points to the raw bytes of the source file content. We can also specify the optional parameter 'APPEND' to append to the header file instead of overwriting and the optional parameter 'NULL_TERMINATE'  to terminate the raw bytes array with null byte.


I hope it will be useful to others.

Monday, July 07, 2014

RSA OAEP padding with SHA512 hash algorithm

Recently I wanted to encrypt a message with RSA with OAEP padding. I also wanted to use SHA512 as hashing algorithm and mask generation function(MGF) in the OAEP padding instead of SHA1. But it looks like it is not possible with the OpenSSL/libcrypto as the SHA1 hash algorithm is hard coded in OAEP padding implementation. This is confirmed by this thread in OpenSSL forum. Though the forum thread was written around 2012 but still I couldn't find a way use either SHA256 or SHA512 as my hashing algorithm and MGF in OAEP padding.

As suggested by "Dr Stephen N. Henson"(the core developer of OpenSSL) in the forum thread , I've took the implementation of RSA OAEP padding and modified to use SHA512 instead of SHA1. It is mostly just find EVP_sha1 and replace with EVP_sha512. We also need to update the usage of SHA_DIGEST_LENGTH macro to SHA512_DIGEST_LENGTH to reflect the output length of SHA512 hash. Below is the modified RSA OAEP padding implementation which uses SHA512 algorithm. Hope it helps, cheers.



Wednesday, July 02, 2014

Viewing raw RGB bitmaps with ImageMagick

I've been looking for a tool to view raw RGB/RGBA bitmaps but couldn't locate such one. It will be useful at times when we want to troubleshoot what bitmaps we are feeding to video encoder or what frames are getting produced by video decoder. The RGB bitmaps contains raw image data and doesn't carry any header info like width, height and etc. For example, if the image is 100x100 and it is a 32 bits per-pixel(RGBA) then the RGBA image will be 100 * 100 * 4 = 40,000 bytes. In this image data each pixel is represented by four bytes and the bytes present the color primary values of Red, Green, Blue & Alpha respectively.

Very recently I realized I can use ImageMagick to convert these RGB bitmaps to any viewable image formats like png or jpg and use any standard image viewer to view them. The following command uses ImageMagick's convert utility to convert the raw RGBA image to png image which can be viewed with any image viewer application.
convert.exe -depth 8 -size 2048x858 image.rgba image.png
as you can see we specify the bit depth(how many bits per pixel component) and size, without which the utility doesn't know how to interpret the image data from source image. We can also specify source and destination color space with '-colorspace' option to convert the image from one color space to another. Also the option '-alpha off' can be used if we want to ignore the alpha channel from source image.

Saturday, June 28, 2014

Enabling Direct3D fullscreen mode from non-active window

In this post I am going to tell you how can you enable Direct3D fullscreen mode from non-active window which is used as swap chain's rendering target.

Initially I didn't realize it could be challenging to enable Direct3D fullscreen mode from non-active window. I thought all I need to do is call the SetFullscreenState method of the SwapChain which is also worked fine from test application. But when I tried the same thing from the real WinForm application which was not active/foreground window at the time of enabling fullscreen, it didn't work. I was getting DXGI_ERROR_NOT_CURRENTLY_AVAILABLE error from SetFullscreenState method.

When I checked MSDN page about the SetFullscreenState method I can clearly see why it is failing.
DXGI_ERROR_NOT_CURRENTLY_AVAILABLE if the action failed. There are many reasons why a windowed-mode swap chain cannot switch to full-screen mode. For instance:
  • The application is running over Terminal Server.
  • The output window is occluded.
  • The output window does not have keyboard focus.
  • Another application is already in full-screen mode.
The third point mentioned in the MSDN page is clearly my situation. So I thought I can simply set the keyboard focus to my WinForm application window using SetForegroundWindow Win32 API. But it seems it is not as simple as it sounds, Windows impose many restrictions on SetForegroundWindow API which are explained in detail in the MSDN page. Basically a non-foreground window can't set itself or another window as foreground window. But a foreground window can set another window as foreground window.

Apparently there are ways/hacks in which we can overcome this restriction and they are explained here, here and here. I tried the first solution mentioned in the post here and it worked fine. The solution is wrapped inside the following function, the hwnd is the handle of target window which want it to be foreground/active window.

void ActivateWindow(HWND hwnd)
{
    DWORD foregroundThread = ::GetWindowThreadProcessId(GetForegroundWindow(), NULL);
    DWORD thisThread = ::GetCurrentThreadId();

    if (foregroundThread != thisThread)
    {
        BOOL isAttached = ::AttachThreadInput(foregroundThread, thisThread, TRUE);

        ::BringWindowToTop(hwnd);
        ::ShowWindow(hwnd, SW_SHOW);

        if (isAttached)
        {
            ::AttachThreadInput(foregroundThread, thisThread, FALSE);
        }
    }
}

The hack involves temporarily attaching our thread as the active foreground window's input processing thread and trying to bring the our window to the top most. This works as we fake our window as the active foreground window by hooking its input processing mechanism and Windows thinks we are the active foreground window and wants to change the focus. After bring our application to the top most we revert the input processing mechanism to its original thread as our goal is achieved. Once the window becomes active window then full screen mode enabled without any problem.

I hope the above description of my experience and the code snippet helps you, cheers.