usbloadergx/source/libwiigui/gui_imagedata.cpp
ardi@ist-einmalig.de fc8f4c2c7a * For Themes - added alternate coordinates for widescreen-mode.
- Differ the coordinates between 16:9 and 4:3, 
    can add a setting with a "w" as prefix 
    (e.g. sdcard_coord = 163,395 for 4:3 
     and wsdcard_coord = 170,395 for 16:9).
    Isn't setted "w???._coord", the "normal"-coordinate
    is used for both modes.
* added a new constructor for GuiImageData
  currebtly the constructor is unused, i will use later
2009-10-12 15:39:59 +00:00

312 lines
5.9 KiB
C++

/****************************************************************************
* libwiigui
*
* Tantric 2009
*
* gui_imagedata.cpp
*
* GUI class definitions
***************************************************************************/
#include "gui.h"
/**
* Constructor for the GuiImageData class.
*/
extern int idiotFlag;
extern char idiotChar[50];
GuiImageData::GuiImageData(const u8 * img)
{
data = NULL;
width = 0;
height = 0;
if(img)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(img);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", img);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const char * imgPath, const u8 * buffer)
{
data = NULL;
width = 0;
height = 0;
if(imgPath)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromDevice(imgPath);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(ctx)
{
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", imgPath);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
if (!data) //use buffer data instead
{
width = 0;
height = 0;
if(buffer)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(buffer);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
}
/**
* Constructor for the GuiImageData class.
*/
GuiImageData::GuiImageData(const char *path, const char *file, const u8 *buffer, bool force_widescreen/*=false*/, const u8 *wbuffer/*=NULL*/)
{
data = NULL;
width = 0;
height = 0;
char path_4_3[100];
char path_16_9[100];
char *imgPath;
snprintf(path_4_3, sizeof(path_4_3), "%s%s", path, file);
if(force_widescreen)
{
snprintf(path_16_9, sizeof(path_16_9), "%sw%s", path, file);
imgPath = path_16_9;
if(wbuffer)
buffer = wbuffer;
}
else
imgPath = path_4_3;
for(;;)
{
if(imgPath)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromDevice(imgPath);
//if (((4%imgProp.imgWidth)!=0)||((4%imgProp.imgHeight)!=0))idiotFlag=1;
if(ctx)
{
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
idiotFlag=1;
snprintf(idiotChar, sizeof(idiotChar), "%s", imgPath);
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
if(data || imgPath == path_4_3)
break;
imgPath = path_4_3;
}
if (!data) //use buffer data instead
{
width = 0;
height = 0;
if(buffer)
{
PNGUPROP imgProp;
IMGCTX ctx = PNGU_SelectImageFromBuffer(buffer);
if(!ctx)
return;
int res = PNGU_GetImageProperties(ctx, &imgProp);
if(res == PNGU_OK)
{
int len = imgProp.imgWidth * imgProp.imgHeight * 4;
if(len%32) len += (32-len%32);
data = (u8 *)memalign (32, len);
if(data)
{
res = PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, data, 255);
if(res == PNGU_OK)
{
width = imgProp.imgWidth;
height = imgProp.imgHeight;
DCFlushRange(data, len);
}
else
{
free(data);
data = NULL;
}
}
}
PNGU_ReleaseImageContext (ctx);
}
}
}
/**
* Destructor for the GuiImageData class.
*/
GuiImageData::~GuiImageData()
{
if(data)
{
free(data);
data = NULL;
}
}
u8 * GuiImageData::GetImage()
{
return data;
}
int GuiImageData::GetWidth()
{
return width;
}
int GuiImageData::GetHeight()
{
return height;
}
void GuiImageData::SetGrayscale(void)
{
GXColor color;
u32 offset, gray;
for(int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) {
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
color.r = *(data+offset+1);
color.g = *(data+offset+32);
color.b = *(data+offset+33);
gray = (77*color.r + 150*color.g + 28*color.b)/255;
*(data+offset+1) = gray;
*(data+offset+32) = gray;
*(data+offset+33) = gray;
}
}
}