Skip to content

Commit

Permalink
compoview: better image loading, mipmaps
Browse files Browse the repository at this point in the history
  • Loading branch information
kebby committed Jun 27, 2013
1 parent a789908 commit 4d826f6
Show file tree
Hide file tree
Showing 4 changed files with 338 additions and 2 deletions.
1 change: 1 addition & 0 deletions altona_wz4/altona/tools/compoview/compoview.mp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ depend "altona/main/base";
depend "altona/main/util";

file "main.?pp";
file "image_win.?pp";
file "compoview.mp.txt";
file "readme.txt";
298 changes: 298 additions & 0 deletions altona_wz4/altona/tools/compoview/image_win.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
/*+**************************************************************************/
/*** ***/
/*** Copyright (C) 2005-2006 by Dierk Ohlerich ***/
/*** all rights reserved ***/
/*** ***/
/*** To license this software, please contact the copyright holder. ***/
/*** ***/
/**************************************************************************+*/

#include "image_win.hpp"

#if sPLATFORM==sPLAT_WINDOWS

#undef new
#include <olectl.h>
#include <Gdiplus.h>
#pragma comment (lib, "gdiplus.lib")
#define new sDEFINE_NEW

#include "base/system.hpp"
#include "util/image.hpp"

/****************************************************************************/
/*** ***/
/*** Wrapper class from sFile to Win32 IStream ***/
/*** ***/
/****************************************************************************/

class sIStreamWrapper : public IStream
{
protected:
sFile *File;
sU32 RefCount;

public:
sIStreamWrapper(sFile *f) : File(f), RefCount(1) {}
virtual ~sIStreamWrapper() {}

// IUnknown

virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void ** ppvObject)
{
if (!ppvObject) return E_INVALIDARG;
if (iid==IID_IUnknown || iid==IID_IStream || iid==IID_ISequentialStream)
{
RefCount++;
*ppvObject=this;
return S_OK;
}
return E_NOINTERFACE;
}

virtual ULONG STDMETHODCALLTYPE AddRef()
{
return ++RefCount;
}

virtual ULONG STDMETHODCALLTYPE Release()
{
sVERIFY(RefCount>1); // must never reach zero
return --RefCount;
}

// ISequentialStream

virtual HRESULT STDMETHODCALLTYPE Read(void *buf, ULONG count, ULONG *cntout)
{
if (!buf) return STG_E_INVALIDPOINTER;
count = sMin<ULONG>(count,File->GetSize()-File->GetOffset());
if (!count || File->Read(buf,count))
{
if (cntout) *cntout=count;
return S_OK;
}
if (cntout) *cntout=0;
return STG_E_READFAULT;
}

virtual HRESULT STDMETHODCALLTYPE Write(const void *buf, ULONG count, ULONG *cntout)
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

// IStream

virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
sS64 offs;
switch (dwOrigin)
{
case STREAM_SEEK_SET: offs=0; break;
case STREAM_SEEK_CUR: offs=File->GetOffset(); break;
case STREAM_SEEK_END: offs=File->GetSize(); break;
default: return STG_E_INVALIDFUNCTION;
}
File->SetOffset(offs+dlibMove.QuadPart);

if (plibNewPosition) plibNewPosition->QuadPart=File->GetOffset();
return S_OK;
}

virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize)
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
{
return S_OK;
}

virtual HRESULT STDMETHODCALLTYPE Revert()
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD dwLockType)
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD dwLockType)
{
sVERIFYFALSE;
return STG_E_INVALIDFUNCTION;
}

virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag)
{
if (!(grfStatFlag&1))
{
sVERIFYFALSE;
return STG_E_ACCESSDENIED;
}
sSetMem(pstatstg,0,sizeof(*pstatstg));
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = File->GetSize();
return S_OK;
}

virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)
{
sVERIFYFALSE;
return STG_E_INSUFFICIENTMEMORY;
}
};

/****************************************************************************/
/****************************************************************************/

sBool sLoadImageWin32(sFile *file, sImage &img)
{
Gdiplus::Status st;
Gdiplus::Color background(0,0,0,0);
Gdiplus::Bitmap *gdibitmap = Gdiplus::Bitmap::FromStream(&sIStreamWrapper(file),TRUE);

HBITMAP hbmp=0;
st = gdibitmap->GetHBITMAP(background,&hbmp);

sBool ok = sFALSE;

if (!st)
{
BITMAP bmp;
GetObject(hbmp,sizeof(bmp),&bmp);
sVERIFY(bmp.bmType==0 && bmp.bmPlanes==1);

if (bmp.bmType==0 && bmp.bmPlanes==1)
{

sBool topdown=sFALSE;
if (bmp.bmHeight<0)
{
bmp.bmHeight*=-1;
topdown=sTRUE;
}

img.Init(bmp.bmWidth,bmp.bmHeight);

sU8 *s = (sU8*)bmp.bmBits;
switch(bmp.bmBitsPixel)
{
case 24:
for(sInt y=0;y<img.SizeY;y++)
{
sU32 *d;
if (topdown)
d = img.Data + y*img.SizeX;
else
d = img.Data + (img.SizeY-1-y)*img.SizeX;

for(sInt x=0;x<img.SizeX;x++,s+=3)
*d++ = 0xff000000|(s[0])|(s[1]<<8)|(s[2]<<16);
}
ok = sTRUE;
break;

case 32:
for(sInt y=0;y<img.SizeY;y++)
{
sU32 *d;
if (topdown)
d = img.Data + y*img.SizeX;
else
d = img.Data + (img.SizeY-1-y)*img.SizeX;

for(sInt x=0;x<img.SizeX;x++,s+=4)
*d++ = *(sU32*)s;
}
ok = sTRUE;
break;

default:
sLogF(L"ERROR",L"can't load bmp with %d bits per pixel\n",bmp.bmBitsPixel);
return false;
}
}

DeleteObject(hbmp);
}

delete gdibitmap;
return ok;
}

sImage *sLoadImageWin32(sFile *file)
{
sImage *img = new sImage;
if (!sLoadImageWin32(file, *img))
sDelete(img);
return img;
}

sBool sLoadImageWin32(const sChar *name, sImage &img)
{
sFile *file = sCreateFile(name,sFA_READRANDOM);
sBool ok = sFALSE;
if (file)
ok = sLoadImageWin32(file, img);
delete file;
return ok;
}

sImage *sLoadImageWin32(const sChar *name)
{
sImage *img=0;
sFile *file = sCreateFile(name,sFA_READRANDOM);
if (file)
img = sLoadImageWin32(file);
delete file;
return img;
}

/****************************************************************************/

static ULONG_PTR sGdiToken=0;

static void sInitGdiPlus()
{
Gdiplus::GdiplusStartupInput gsin;
sClear(gsin);
gsin.GdiplusVersion=1;
GdiplusStartup(&sGdiToken,&gsin,NULL);
}

static void sExitGdiPlus()
{
Gdiplus::GdiplusShutdown(sGdiToken);
}

sADDSUBSYSTEM(GdiPlus, 0x78, sInitGdiPlus, sExitGdiPlus);

/****************************************************************************/

#else

sImage *sLoadImageWin32(sFile *file)
{
return null;
}

sImage *sLoadImageWin32(const sChar *name)
{
return null;
}


#endif
28 changes: 28 additions & 0 deletions altona_wz4/altona/tools/compoview/image_win.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*+**************************************************************************/
/*** ***/
/*** Copyright (C) 2005-2006 by Dierk Ohlerich ***/
/*** all rights reserved ***/
/*** ***/
/*** To license this software, please contact the copyright holder. ***/
/*** ***/
/**************************************************************************+*/

#ifndef FILE_CUBE_IMAGE_WIN_HPP
#define FILE_CUBE_IMAGE_WIN_HPP

#include "base/types.hpp"

/****************************************************************************/

class sImage;
class sFile;

sImage *sLoadImageWin32(sFile *file);
sImage *sLoadImageWin32(const sChar *name);
sBool sLoadImageWin32(sFile *file, sImage &image);
sBool sLoadImageWin32(const sChar *name, sImage &image);

/****************************************************************************/

#endif // FILE_CUBE_IMAGE_WIN_HPP

13 changes: 11 additions & 2 deletions altona_wz4/altona/tools/compoview/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "base/windows.hpp"
#include "util/image.hpp"
#include "util/shaders.hpp"
#include "image_win.hpp"

#define VERSION 1
#define REVISION 2
Expand Down Expand Up @@ -459,7 +460,12 @@ void MyApp::GoImage(sInt id)
ImageId = id;
sDelete(TexOld);
TexOld = Tex;
Tex = sLoadTexture2D(&Entries[ImageId]->Image,sTEX_2D|sTEX_ARGB8888|sTEX_NOMIPMAPS);
sU32 flags = sTEX_2D|sTEX_ARGB8888;
sInt sx, sy;
sGetScreenSize(sx,sy);
sImage *img = &Entries[ImageId]->Image;
if (img->SizeX <= sx && img->SizeY <= sy) flags |= sTEX_NOMIPMAPS;
Tex = sLoadTexture2D(img,flags);
GeoPosOld = GeoPos;

ImageX = (sF32)(Tex->SizeX);
Expand Down Expand Up @@ -496,7 +502,10 @@ void MyApp::LoadOne()
ent = new Entry;
sDPrintF(L"load %q\n",de->Name);
if(!ent->Image.Load(de->Name))
sFatal(L"failed to load %q.\ntry to convert this image to a PNG with standard settings",de->Name);
{
if (!sLoadImageWin32(de->Name, ent->Image))
sFatal(L"failed to load %q.\ntry to convert this image to a PNG with standard settings",de->Name);
}
ent->Name = de->Name;
ent->Texture = 0;
Entries.AddTail(ent);
Expand Down

0 comments on commit 4d826f6

Please sign in to comment.