Skip to content

Commit

Permalink
added new option to decompress frames with transparency onto a checke…
Browse files Browse the repository at this point in the history
…red background

fixed bugs in settings saving/restoring
  • Loading branch information
AndrewRH committed Jan 25, 2015
1 parent 853b0d9 commit 3a6bb73
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 64 deletions.
24 changes: 14 additions & 10 deletions Source/HapCodec/config.rc
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,21 @@ END
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 134, 133
IDD_DIALOG1 DIALOGEX 0, 0, 148, 167
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Configure Hap Codec"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
PUSHBUTTON "OK",IDC_OK,7,103,55,15
PUSHBUTTON "Cancel",IDC_CANCEL,70,103,55,15
CONTROL "Enable Null Frames",IDC_NULLFRAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,73,77,10
LTEXT "Version 1.0.6",IDC_VERSION,83,0,42,10
CONTROL "Use Snappy Compression",IDC_SNAPPY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,61,97,10
LTEXT "DXT Quality",IDC_STATIC3,7,13,41,11
LISTBOX IDC_DXTQUALITY_OPTIONS,7,24,84,30,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "OK",IDC_OK,6,144,66,15
PUSHBUTTON "Cancel",IDC_CANCEL,78,144,61,15
CONTROL "Enable Null Frames",IDC_NULLFRAMES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,84,77,10
CONTROL "Version 1.0.10",IDC_VERSION,"Static",SS_SIMPLE | WS_GROUP,96,0,48,10
CONTROL "Use Snappy Compression",IDC_SNAPPY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,72,97,10
LTEXT "DXT Quality",IDC_STATIC3,12,24,41,11
LISTBOX IDC_DXTQUALITY_OPTIONS,12,36,84,30,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
CONTROL "Generate Transparency Background",IDC_GENTRANSBG,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,120,129,10
CONTROL "Compression",IDC_STATIC4,"Static",SS_SIMPLE | WS_GROUP,6,6,41,11
CONTROL "Decompression",IDC_STATIC5,"Static",SS_SIMPLE | WS_GROUP,6,102,66,11
END

IDD_DIALOG2 DIALOGEX 0, 0, 252, 68
Expand All @@ -88,8 +91,8 @@ BEGIN
IDD_DIALOG1, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 125
BOTTOMMARGIN, 125
RIGHTMARGIN, 139
BOTTOMMARGIN, 159
END

IDD_DIALOG2, DIALOG
Expand Down Expand Up @@ -150,6 +153,7 @@ STRINGTABLE
BEGIN
IDS_TIP_NULLFRAMES "When a frame is identical to the preceding frame, it can be replaced with a nullframe. This indicates that the program reading the video should simply reuse the previous frame. Nullframes can increase compression and speed, but there may be a few editing programs that do no handle them well; disable nullframes if you notice the wrong frame being displayed during still sections of a video."
IDS_TIP_SNAPPY "If this enabled, HAP will use the fast lossless Snappy compression."
IDS_TIP_GENTRANSPBG "For previewing videos with transparency on players that don't support transparency, generates a checkered background and renders the transparent video composited over it."
IDS_TIP_MODE_OPTION "Specifies the mode for encoding. HAP stores frames as 24-bit RGB, HAPA stores frames as 32-bit RGBA, HAP-HQ stores frames as 24-bit RGB but has better quality and larger file size."
END

Expand Down
94 changes: 91 additions & 3 deletions Source/HapCodec/decompression.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CodecInst::DecompressBegin(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut
_width = lpbiIn->biWidth;
_height = lpbiIn->biHeight;

if (lpbiOut->biCompression == 0)
if (lpbiOut->biCompression == BI_RGB)
{
_format = lpbiOut->biBitCount;

Expand Down Expand Up @@ -99,6 +99,80 @@ Convert32bppTo24bpp(int width, int height, bool swapRedBlue, const unsigned char
}
}

inline void AlphaBlend(unsigned char* result, const unsigned char* fg, const unsigned char* bg)
{
unsigned int alpha = fg[3] + 1;
unsigned int inv_alpha = 256 - fg[3];
result[0] = (unsigned char)((alpha * fg[0] + inv_alpha * bg[0]) >> 8);
result[1] = (unsigned char)((alpha * fg[1] + inv_alpha * bg[1]) >> 8);
result[2] = (unsigned char)((alpha * fg[2] + inv_alpha * bg[2]) >> 8);
}

void
Blend32bppTo24bppChecker(int width, int height, bool swapRedBlue, const unsigned char* a, unsigned char* b)
{
unsigned int checkerA = 0xff666666;
unsigned int checkerB = 0xff999999;
int numPixels = width * height;
for (int i = 0; i < numPixels; i++)
{
b[0] = a[0];
b[1] = a[1];
b[2] = a[2];

int x = (i % width) / 64;
int y = i / (64*width);
unsigned int checker = checkerA;
if (((x+y)&1) == 0)
checker = checkerB;

AlphaBlend(b, a, (const unsigned char*)&checker);

if (swapRedBlue)
{
unsigned char temp = b[0];
b[0] = b[2];
b[2] = temp;
}

a += 4;
b += 3;
}
}

void
Blend32bppTo32bppChecker(int width, int height, bool swapRedBlue, const unsigned char* a, unsigned char* b)
{
unsigned int checkerA = 0x00666666;
unsigned int checkerB = 0x00999999;
int numPixels = width * height;
for (int i = 0; i < numPixels; i++)
{
b[0] = a[0];
b[1] = a[1];
b[2] = a[2];
b[3] = a[3];

int x = (i % width) / 64;
int y = i / (64*width);
unsigned int checker = checkerA;
if (((x+y)&1) == 0)
checker = checkerB;

AlphaBlend(b, a, (const unsigned char*)&checker);

if (swapRedBlue)
{
unsigned char temp = b[0];
b[0] = b[2];
b[2] = temp;
}

a += 4;
b += 4;
}
}

// Called to decompress a frame, the actual decompression will be
// handed off to other functions based on the frame type.
DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize)
Expand Down Expand Up @@ -153,7 +227,14 @@ DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize)
squish::DecompressImage(_buffer, _width, _height, _dxtBuffer, _dxtFlags);

// Convert 32-bit to 24-bit and swap red-blue channels
Convert32bppTo24bpp(_width, _height, true, _buffer, _out);
if (_generateTransparencyBackground && outputBufferTextureFormat == HapTextureFormat_RGBA_DXT5)
{
Blend32bppTo24bppChecker(_width, _height, true, _buffer, _out);
}
else
{
Convert32bppTo24bpp(_width, _height, true, _buffer, _out);
}
}

icinfo->lpbiOutput->biSizeImage = _length;
Expand Down Expand Up @@ -182,7 +263,14 @@ DWORD CodecInst::Decompress(ICDECOMPRESS* icinfo, DWORD dwSize)
squish::DecompressImage(_buffer, _width, _height, _dxtBuffer, _dxtFlags);

// Swap red-blue channels
ConvertBGRAtoRGBA(_width, _height, _buffer, _out);
if (_generateTransparencyBackground && outputBufferTextureFormat == HapTextureFormat_RGBA_DXT5)
{
Blend32bppTo32bppChecker(_width, _height, true, _buffer, _out);
}
else
{
ConvertBGRAtoRGBA(_width, _height, _buffer, _out);
}
}

icinfo->lpbiOutput->biSizeImage = _length;
Expand Down
2 changes: 2 additions & 0 deletions Source/HapCodec/hapcodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class CodecInst
bool _useAlpha;
bool _useNullFrames;
bool _useSnappy;
bool _generateTransparencyBackground;

unsigned int compressed_size;

CodecInst(CodecType codecType);
Expand Down
20 changes: 12 additions & 8 deletions Source/HapCodec/interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@

extern BOOL CALLBACK ConfigureDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern BOOL CALLBACK AboutDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
extern void StoreRegistrySettings(bool nullframes, bool useSnappy, int dxtQuality);
extern void LoadRegistrySettings(bool* nullFrames, bool* useSnappy, int* dxtQuality);
extern void StoreRegistrySettings(bool nullframes, bool useSnappy, int dxtQuality, bool generateTransparencyBackground);
extern void LoadRegistrySettings(bool* nullFrames, bool* useSnappy, int* dxtQuality, bool* generateTransparencyBackground);

CodecInst* g_currentUICodec = NULL;
HMODULE hmoduleHap = 0;
Expand Down Expand Up @@ -67,6 +67,7 @@ CodecInst::CodecInst(CodecInst::CodecType codecType)
_useAlpha = false;
_useNullFrames = false;
_useSnappy = true;
_generateTransparencyBackground = false;

_isStarted = 0;
_supportUncompressedOutput = true;
Expand All @@ -80,7 +81,7 @@ BOOL CodecInst::QueryConfigure()
DWORD CodecInst::About(HWND hwnd)
{
g_currentUICodec = this;
DialogBox(hmoduleHap, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)ConfigureDialogProc);
DialogBox(hmoduleHap, MAKEINTRESOURCE(IDD_DIALOG2), hwnd, (DLGPROC)AboutDialogProc);
g_currentUICodec = NULL;
return ICERR_OK;
}
Expand Down Expand Up @@ -193,15 +194,14 @@ DWORD CodecInst::CompressQuery(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpb
}
}


// Make sure width and height is multiple of 4
if ( lpbiIn->biWidth%4 != 0 ||
abs(lpbiIn->biHeight)%4 != 0)
{
return_badformat()
}

LoadRegistrySettings(&_useNullFrames, &_useSnappy, &_dxtQuality);
LoadRegistrySettings(&_useNullFrames, &_useSnappy, &_dxtQuality, &_generateTransparencyBackground);

// See if the output format is acceptable if need be
if ( lpbiOut )
Expand Down Expand Up @@ -246,7 +246,7 @@ DWORD CodecInst::CompressGetFormat(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER
return_badformat()
}

LoadRegistrySettings(&_useNullFrames, &_useSnappy, &_dxtQuality);
LoadRegistrySettings(&_useNullFrames, &_useSnappy, &_dxtQuality, &_generateTransparencyBackground);

if (_codecType == HapAlpha && lpbiIn->biBitCount != 32)
{
Expand Down Expand Up @@ -324,14 +324,14 @@ DWORD CodecInst::GetInfo(ICINFO* icinfo, DWORD dwSize)
// check if the codec can decompress the given format to the desired format
DWORD CodecInst::DecompressQuery(const LPBITMAPINFOHEADER lpbiIn, const LPBITMAPINFOHEADER lpbiOut)
{
#if 1
if (_codecType != Hap &&
_codecType != HapAlpha &&
_codecType != HapQ)
{
return_badformat();
}

// Check input format
if (_codecType == Hap)
{
if (lpbiIn->biCompression != FOURCC_HAP && lpbiIn->biCompression != FOURCC_hap)
Expand Down Expand Up @@ -374,6 +374,7 @@ DWORD CodecInst::DecompressQuery(const LPBITMAPINFOHEADER lpbiIn, const LPBITMAP
return_badformat();
}

// Check output format
if (!lpbiOut)
{
return (DWORD)ICERR_OK;
Expand Down Expand Up @@ -427,7 +428,10 @@ DWORD CodecInst::DecompressQuery(const LPBITMAPINFOHEADER lpbiIn, const LPBITMAP

if ( lpbiIn->biWidth != lpbiOut->biWidth )
return_badformat();
#endif

// Load settings to determine any decompresison overrides
LoadRegistrySettings(&_useNullFrames, &_useSnappy, &_dxtQuality, &_generateTransparencyBackground);

return (DWORD)ICERR_OK;
}

Expand Down
4 changes: 2 additions & 2 deletions Source/HapCodec/interface.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

#pragma once
bool DetectFlags();
void LoadRegistrySettings(bool * nullframes, bool * suggestrgb, bool * multithread, bool * noupsample, int * mode );
//bool DetectFlags();
//void LoadRegistrySettings(bool * nullframes, bool * suggestrgb, bool * multithread, bool * noupsample, int * mode );
4 changes: 4 additions & 0 deletions Source/HapCodec/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//
#define IDS_TIP_NULLFRAMES 1
#define IDS_TIP_SNAPPY 2
#define IDS_TIP_GENTRANSPBG 3
#define IDS_TIP_MODE_OPTION 5
#define IDD_DIALOG1 101
#define IDC_CURSOR1 102
Expand All @@ -15,6 +16,7 @@
#define IDC_CANCEL 1008
#define IDC_RGBA 1009
#define IDC_NULLFRAMES 1010
#define IDC_GENTRANSBG 1011
#define IDC_SNAPPY 1014
#define IDC_BITDEPTH 1015
#define IDC_INTERLACED 1015
Expand All @@ -25,6 +27,8 @@
#define IDC_LIST2 1020
#define IDC_STATIC2 1100
#define IDC_STATIC3 1101
#define IDC_STATIC4 1102
#define IDC_STATIC5 1103

// Next default values for new objects
//
Expand Down
Loading

0 comments on commit 3a6bb73

Please sign in to comment.