summaryrefslogtreecommitdiff
path: root/plugins/Clist_modern/src/modern_skinengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Clist_modern/src/modern_skinengine.cpp')
-rw-r--r--plugins/Clist_modern/src/modern_skinengine.cpp169
1 files changed, 166 insertions, 3 deletions
diff --git a/plugins/Clist_modern/src/modern_skinengine.cpp b/plugins/Clist_modern/src/modern_skinengine.cpp
index d24d5c82e2..f0d0cd173e 100644
--- a/plugins/Clist_modern/src/modern_skinengine.cpp
+++ b/plugins/Clist_modern/src/modern_skinengine.cpp
@@ -36,8 +36,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "hdr/modern_skinengine.h"
#include "hdr/modern_commonprototypes.h"
#include "hdr/modern_sync.h"
+
//Implementation
+#pragma pack(push, 1)
+/* tga header */
+struct tga_header_t
+{
+ BYTE id_lenght; /* size of image id */
+ BYTE colormap_type; /* 1 is has a colormap */
+ BYTE image_type; /* compression type */
+
+ short cm_first_entry; /* colormap origin */
+ short cm_length; /* colormap length */
+ BYTE cm_size; /* colormap size */
+
+ short x_origin; /* bottom left x coord origin */
+ short y_origin; /* bottom left y coord origin */
+
+ short width; /* picture width (in pixels) */
+ short height; /* picture height (in pixels) */
+
+ BYTE pixel_depth; /* bits per pixel: 8, 16, 24 or 32 */
+ BYTE image_descriptor; /* 24 bits = 0x00; 32 bits = 0x80 */
+};
+#pragma pack(pop)
+
/* Global variables */
SKINOBJECTSLIST g_SkinObjectList = { 0 };
@@ -1476,19 +1500,158 @@ int ske_GetFullFilename(TCHAR *buf, const TCHAR *file, TCHAR *skinfolder, BOOL m
return 0;
}
+/*
+This function is required to load TGA to dib buffer myself
+Major part of routines is from http://tfcduke.developpez.com/tutoriel/format/tga/fichiers/tga.c
+*/
+
+static BOOL ske_ReadTGAImageData(void * From, DWORD fromSize, BYTE * destBuf, DWORD bufSize, BOOL RLE)
+{
+ BYTE * pos = destBuf;
+ BYTE * from = fromSize ? (BYTE*)From : NULL;
+ FILE * fp = !fromSize ? (FILE*)From : NULL;
+ DWORD destCount = 0;
+ DWORD fromCount = 0;
+ if (!RLE) {
+ while (((from && fromCount < fromSize) || (fp && fromCount < bufSize))
+ && (destCount < bufSize)) {
+ BYTE r = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ BYTE g = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ BYTE b = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ BYTE a = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ pos[destCount++] = r;
+ pos[destCount++] = g;
+ pos[destCount++] = b;
+ pos[destCount++] = a;
+
+ if (destCount > bufSize) break;
+ if (from) if (fromCount < fromSize) break;
+ }
+ }
+ else {
+ BYTE rgba[4];
+ BYTE packet_header;
+ BYTE *ptr = pos;
+ BYTE size;
+ int i;
+ while (ptr < pos + bufSize) {
+ /* read first byte */
+ packet_header = from ? from[fromCount] : (BYTE)fgetc(fp);
+ if (from) from++;
+ size = 1 + (packet_header & 0x7f);
+ if (packet_header & 0x80) {
+ /* run-length packet */
+ if (from) {
+ *((DWORD*)rgba) = *((DWORD*)(from + fromCount));
+ fromCount += 4;
+ }
+ else fread(rgba, sizeof(BYTE), 4, fp);
+ for (i = 0; i < size; ++i, ptr += 4) {
+ ptr[2] = rgba[2];
+ ptr[1] = rgba[1];
+ ptr[0] = rgba[0];
+ ptr[3] = rgba[3];
+ }
+ }
+ else { /* not run-length packet */
+ for (i = 0; i < size; ++i, ptr += 4) {
+ ptr[0] = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ ptr[1] = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ ptr[2] = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ ptr[3] = from ? from[fromCount++] : (BYTE)fgetc(fp);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+
+static HBITMAP ske_LoadGlyphImage_TGA(const TCHAR *szFilename)
+{
+ BYTE *colormap = NULL;
+ int cx = 0, cy = 0;
+ BOOL err = FALSE;
+ tga_header_t header;
+ if (!szFilename) return NULL;
+ if (!wildcmpit(szFilename, _T("*\\*%.tga"))) {
+ //Loading TGA image from file
+ FILE *fp = _tfopen(szFilename, _T("rb"));
+ if (!fp) {
+ TRACEVAR("error: couldn't open \"%s\"!\n", szFilename);
+ return NULL;
+ }
+ /* read header */
+ fread(&header, sizeof(tga_header_t), 1, fp);
+ if ((header.pixel_depth != 32) || ((header.image_type != 10) && (header.image_type != 2))) {
+ fclose(fp);
+ return NULL;
+ }
+
+ /*memory allocation */
+ colormap = (BYTE*)malloc(header.width*header.height * 4);
+ cx = header.width;
+ cy = header.height;
+ fseek(fp, header.id_lenght, SEEK_CUR);
+ fseek(fp, header.cm_length, SEEK_CUR);
+ err = !ske_ReadTGAImageData((void*)fp, 0, colormap, header.width*header.height * 4, header.image_type == 10);
+ fclose(fp);
+ }
+ else {
+ /* reading from resources IDR_TGA_DEFAULT_SKIN */
+ HRSRC hRSrc = FindResourceA(g_hInst, MAKEINTRESOURCEA(IDR_TGA_DEFAULT_SKIN), "TGA");
+ if (!hRSrc) return NULL;
+ HGLOBAL hRes = LoadResource(g_hInst, hRSrc);
+ if (!hRes) return NULL;
+ DWORD size = SizeofResource(g_hInst, hRSrc);
+ BYTE *mem = (BYTE*)LockResource(hRes);
+ if (size > sizeof(header)) {
+ tga_header_t * header = (tga_header_t *)mem;
+ if (header->pixel_depth == 32 && (header->image_type == 2 || header->image_type == 10)) {
+ colormap = (BYTE*)malloc(header->width*header->height * 4);
+ cx = header->width;
+ cy = header->height;
+ ske_ReadTGAImageData((void*)(mem + sizeof(tga_header_t) + header->id_lenght + header->cm_length), size - (sizeof(tga_header_t) + header->id_lenght + header->cm_length), colormap, cx*cy * 4, header->image_type == 10);
+ }
+ }
+ FreeResource(hRes);
+ }
+
+ if (colormap) { //create dib section
+ BYTE * pt;
+ HBITMAP hbmp = ske_CreateDIB32Point(cx, cy, (void**)&pt);
+ if (hbmp)
+ memcpy(pt, colormap, cx*cy * 4);
+ free(colormap);
+ return hbmp;
+ }
+ return NULL;
+}
+
static HBITMAP ske_LoadGlyphImageByDecoders(const TCHAR *tszFileName)
{
if (!_tcschr(tszFileName, '%') && !PathFileExists(tszFileName))
return NULL;
- HBITMAP hBitmap = Bitmap_Load(tszFileName);
- if (hBitmap == NULL)
+ const TCHAR *ext = _tcsrchr(tszFileName, '.');
+ if (ext == NULL)
return NULL;
BITMAP bmpInfo;
+ HBITMAP hBitmap;
+ bool f = false;
+
+ if (!mir_tstrcmpi(ext, _T(".tga"))) {
+ hBitmap = ske_LoadGlyphImage_TGA(tszFileName);
+ f = true;
+ }
+ else hBitmap = Bitmap_Load(tszFileName);
+
+ if (hBitmap == NULL)
+ return NULL;
+
GetObject(hBitmap, sizeof(BITMAP), &bmpInfo);
if (bmpInfo.bmBitsPixel == 32)
- ske_PreMultiplyChannels(hBitmap, 0);
+ ske_PreMultiplyChannels(hBitmap, f);
else {
HDC dc32 = CreateCompatibleDC(NULL);
HDC dc24 = CreateCompatibleDC(NULL);