so I try to load PNG pic (dimansion 3200 x 1200) 3200*1200*4 = 15.34MB
it crash. when I load it.
but when I change to anothor pic (3200 x 640) 3200*640*4= 8.19MB
it work.
you can take a look my load function was call from main()
//***** chkram and load pic to ram ****
fbefor=GetRAMFree();
if ((ImageBG=LoadPng("bg.png",GU_PSM_4444,1,0)) != NULL)png = 1;
fafter=GetRAMFree();
//**********************
Can any one help me please. this is my code.. Thank you very much
PS. all code I learn and grab from this board. Thank you PSPDEV Board.
Code: Select all
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <malloc.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <png.h>
#include <zlib.h>
#include <pspctrl.h>
#include <pspgu.h>
#include <psprtc.h>
PSP_MODULE_INFO("ImageViewer", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
static unsigned int __attribute__((aligned(16))) list[262144];
#define printf pspDebugScreenPrintf
#define BUF_WIDTH (512)
#define SCR_WIDTH (512)
#define SCR_HEIGHT (256)
typedef u32 Color;
#define A(color) ((u8)(color >> 24 & 0xFF))
#define B(color) ((u8)(color >> 16 & 0xFF))
#define G(color) ((u8)(color >> 8 & 0xFF))
#define R(color) ((u8)(color & 0xFF))
typedef struct
{
int textureWidth; // the real width of data, 2^n with n>=0
int textureHeight; // the real height of data, 2^n with n>=0
int imageWidth; // the image width
int imageHeight;
Color * data;
} Image;
static int exitRequest = 0;
static unsigned int staticOffset = 0;
static unsigned int getMemorySize(unsigned int width, unsigned int height, unsigned int psm)
{
switch (psm)
{
case GU_PSM_T4:
return (width * height) >> 1;
case GU_PSM_T8:
return width * height;
case GU_PSM_5650:
case GU_PSM_5551:
case GU_PSM_4444:
case GU_PSM_T16:
return 2 * width * height;
case GU_PSM_8888:
case GU_PSM_T32:
return 4 * width * height;
default:
return 0;
}
}
void* getStaticVramBuffer(unsigned int width, unsigned int height, unsigned int psm)
{
unsigned int memSize = getMemorySize(width,height,psm);
void* result = (void*)staticOffset;
staticOffset += memSize;
return result;
}
int exit_callback(int arg1, int arg2, void *common) {
sceKernelExitGame();
return 0;
}
int CallbackThread(SceSize args, void *argp) {
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
int SetupCallbacks(void) {
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
if(thid >= 0) {
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg)
{
// ignore PNG warnings
}
int PowerOfTwo(int value)
{
int poweroftwo = 1;
while (poweroftwo < value ){
poweroftwo <<= 1;
}
return poweroftwo;
}
unsigned short Color8888To5551(unsigned int Color32)
{
unsigned char Red = (Color32);
unsigned short Red16 = Red>>3;
unsigned char Green = (Color32>>8);
unsigned short Green16 = (Green>>3)<<5;
unsigned char Blue = (Color32>>16);
unsigned short Blue16 = (Blue>>3)<<10;
unsigned char Alpha = (Color32>>24);
unsigned short Alpha16 = (Alpha>>3)<<15;
unsigned short Color16 = Red16 | Green16 | Blue16 | Alpha16;
return Color16;
}
unsigned short Color8888To4444(unsigned int Color32)
{
unsigned char Red = (Color32);
unsigned short Red16 = Red>>4;
unsigned char Green = (Color32>>8);
unsigned short Green16 = (Green>>4)<<4;
unsigned char Blue = (Color32>>16);
unsigned short Blue16 = (Blue>>4)<<8;
unsigned char Alpha = (Color32>>24);
unsigned short Alpha16 = (Alpha>>4)<<12;
unsigned short Color16 = Red16 | Green16 | Blue16 | Alpha16;
return Color16;
}
unsigned short Color8888To5650(unsigned int Color32)
{
unsigned char Red = (Color32);
unsigned short Red16 = Red>>3;
unsigned char Green = (Color32>>8);
unsigned short Green16 = (Green>>2)<<5;
unsigned char Blue = (Color32>>16);
unsigned short Blue16 = (Blue>>3)<<11;
//unsigned char Alpha = (Color32>>24);
unsigned short Color16 = Red16 | Green16 | Blue16;
return Color16;
}
void swizzle_fast(u8* out, const u8* in, unsigned int width, unsigned int height)
{
unsigned int blockx, blocky;
unsigned int j;
unsigned int width_blocks = (width / 16);
unsigned int height_blocks = (height / 8);
unsigned int src_pitch = (width-16)/4;
unsigned int src_row = width * 8;
const u8* ysrc = in;
u32* dst = (u32*)out;
for (blocky = 0; blocky < height_blocks; ++blocky)
{
const u8* xsrc = ysrc;
for (blockx = 0; blockx < width_blocks; ++blockx)
{
const u32* src = (u32*)xsrc;
for (j = 0; j < 8; ++j)
{
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
*(dst++) = *(src++);
src += src_pitch;
}
xsrc += 16;
}
ysrc += src_row;
}
}
Image* LoadPng(const char* filename,int ColorMode,int Swizzle,int Vram)
{
unsigned short *Buffer;
unsigned short *swizzled_pixels = NULL;
Image *Image1;
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type, x, y;
unsigned int* line;
FILE *fp;
int OutBytesPerPixel;
int imageWidth = 0;
int imageHeight = 0;
if(ColorMode == GU_PSM_4444 || ColorMode == GU_PSM_5650 || ColorMode == GU_PSM_5551)OutBytesPerPixel = 2;
else OutBytesPerPixel = 4;
if ((fp = fopen(filename, "rb")) == NULL){
printf("Can't open file %s\n",filename);
return NULL;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(fp);
return NULL;
}
png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
png_set_strip_16(png_ptr);
png_set_packing(png_ptr);
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
line = (unsigned int*) malloc(width * 4);
if (!line) {
fclose(fp);
png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
return NULL;
}
imageWidth = PowerOfTwo(width);
imageHeight = PowerOfTwo(height);
Buffer = memalign(16,imageWidth*imageHeight*OutBytesPerPixel);
for (y = 0; y < height; y++) {
png_read_row(png_ptr, (unsigned char*) line, png_bytep_NULL);
for (x = 0; x < width; x++) {
unsigned int *Buffer32 = (unsigned int*)Buffer;
unsigned int color32 = line[x];
unsigned short color16;
//printf("%d:%d %u ",y,x,color32);
if(ColorMode == GU_PSM_5551){
color16 = Color8888To5551(color32);
Buffer[y*imageWidth+x] = color16;
}
else if(ColorMode == GU_PSM_4444){
color16 = Color8888To4444(color32);
Buffer[y*imageWidth+x] = color16;
}
else if(ColorMode == GU_PSM_5650){
color16 = Color8888To5650(color32);
Buffer[y*imageWidth+x] = color16;
}
else {
Buffer32[y*imageWidth+x] = color32;
}
//printf("%u \n",Buffer[y*width+x]);
//printf("%u \n",color16);
}
}
free(line);
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
Image1 = malloc(sizeof(Image));
Image1->textureWidth = width;
Image1->textureHeight = height;
Image1->imageWidth = imageWidth;
Image1->imageHeight = imageHeight;
swizzled_pixels = memalign(16,Image1->imageHeight*Image1->imageWidth*OutBytesPerPixel);
swizzle_fast((u8*)swizzled_pixels,(const u8*)Buffer,Image1->imageWidth*OutBytesPerPixel,Image1->imageHeight);
// 512*2 because swizzle operates in bytes, and each pixel in a 16-bit texture is 2 bytes
sceKernelDcacheWritebackAll();
Image1->data = swizzled_pixels;
free(Buffer);
//sceGuFinish();
//sceGuSync(0,0);
return Image1;
}
float GetRAMFree(){
float ram;
//a hacky little way to estimate RAM left to use
int ramAdd[320];
int i=0;
for(i=0;i<320;i++){
ramAdd[i] = malloc(100000);
if(ramAdd[i] == 0){//malloc failed
ram = (float)i;
int z=0;
for(z=0;z<i;z++){
free(ramAdd[z]);
}
break;
}
}
return ram/10;
}
int main(int argc, char* argv[])
{
unsigned int i = 0,png = 0;
float fbefor,fafter;
pspDebugScreenInit();
SetupCallbacks();
Image * ImageBG;
sceGuInit();
void* fbp0 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* fbp1 = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_8888);
void* zbp = getStaticVramBuffer(BUF_WIDTH,SCR_HEIGHT,GU_PSM_4444);
sceGuStart(GU_DIRECT,list);
sceGuDrawBuffer(GU_PSM_8888,fbp0,BUF_WIDTH);
sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,fbp1,BUF_WIDTH);
sceGuDepthBuffer(zbp,BUF_WIDTH);
sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2));
sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT);
sceGuDepthRange(0xc350,0x2710);
sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuAlphaFunc(GU_GREATER,0,0xff);
sceGuEnable(GU_ALPHA_TEST);
sceGuDepthFunc(GU_GEQUAL);
sceGuEnable(GU_DEPTH_TEST);
sceGuFrontFace(GU_CW);
sceGuShadeModel(GU_SMOOTH);
sceGuEnable(GU_CULL_FACE);
sceGuEnable(GU_TEXTURE_2D);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(GU_TRUE);
//***** chkram and load pic to ram ****
fbefor=GetRAMFree();
if ((ImageBG=LoadPng("bg.png",GU_PSM_4444,1,0)) != NULL)png = 1;
fafter=GetRAMFree();
//**********************
pspDebugScreenSetOffset((int)fbp0);
pspDebugScreenSetXY(10,10);
pspDebugScreenPrintf("ram befor load = %f\n",fbefor);
pspDebugScreenSetXY(10,100);
pspDebugScreenPrintf("ram after load = %f\n",fafter);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuSwapBuffers();
sceKernelSleepThread();
sceGuTerm();
return 0;
}