sceJpeg decoding problem...

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ardatan
Posts: 44
Joined: Sat Jan 12, 2008 8:47 am

sceJpeg decoding problem...

Post by ardatan »

This is the small part of my app. It doesn't decode JPEG to RGB... I think there is a problem on reading the image...
It loads avcodec.prx and inits JPEG library but doesn't decode...
Could you please help me?

Code: Select all


int StartJpegPsp() 
{
  printf("Loading 'flash0:/kd/avcodec.prx'...");
  if (LoadStartModule("flash0:/kd/avcodec.prx") == 0) {
    printf("ok\n");
  }
  else {
    printf("failed\n");
    return -1;
  }

  printf("init Jpeg decompression...");
  if (sceJpegInitMJpeg() == 0) {
    if (sceJpegCreateMJpeg(480, 272) == 0) {
      fprintf(stderr, "ok\n");
      return 0;
    }
  }

  printf("failed\n");
  return -1;
}

void free_img(my_bmp_type *img)
{
  if (img)
  {
    free(img->data);
	free(img);
  }
}

#include <pspiofilemgr.h> // Include for Sony IO Functions
#include <stdio.h> // Include for Seek Constants
#include <string.h> // Include for NULL Macro

SceOff fileSize&#40;SceUID file&#41;
&#123;
  // File Length
  SceOff length = 0;
 
  // Sanity Check for Valid File Handler
  if&#40;file >= 0&#41;
  &#123;
    // Save Position in File
    SceOff pos = sceIoLseek&#40;file, 0, SEEK_CUR&#41;;
   
    // Move to EOF & Grab Location &#40;Size&#41;
    length = sceIoLseek&#40;file, 0, SEEK_END&#41;;
   
    // Restore Position in File
    sceIoLseek&#40;file, pos, SEEK_SET&#41;;
  &#125;
 
  // Return File Length
  return length;
&#125;

typedef struct
&#123;
  short w;
  short h;
  short frame;
  short current_frame;
  u32 *data;
&#125; my_bmp_type;

my_bmp_type* read_jpeg_file&#40;const char * from&#41;
&#123;
  my_bmp_type *img = &#40;my_bmp_type *&#41;malloc&#40;&#40;480 * 65536&#41; + 272&#41;;

  // Sanity Check to avoid NULL Pointers
  if&#40;from&#41;
  &#123;
    // Open Input File
    SceUID infile = sceIoOpen&#40;from, PSP_O_RDONLY, 0777&#41;;
   
    // Opened Input File
    if&#40;infile >= 0&#41;
    &#123;
      // Get Filesize
      SceOff insize = fileSize&#40;infile&#41;;
     img->data = &#40;u32 *&#41;malloc&#40;480 * 272 * 4&#41;;
	    // Transfer Buffer
        unsigned char buffer&#91;480 * 272 * 4&#93;;
       
        // Copy Buffer Blocks
        int copied = 0;
        while&#40;copied < insize&#41;
        &#123;
          // Read Block from Input File
          int read = sceIoRead&#40;infile, buffer, 480 * 272 * 4&#41;;
         
          // Written Bytes
			sceJpegDecodeMJpeg&#40;buffer, 480 * 272 * 4, img->data, 0&#41;;    
			if&#40;read < 1&#41;
			break;
        &#125;
      
    &#125;
	 sceIoClose&#40;infile&#41;;
  &#125;

  // Return Result
  return img;
&#125;
I'm sorry for my bad English.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Probably allocating too much memory. malloc((480 * 65536) + 272) allocates over 30 MB alone. Unless you have a Slim with large memory activated, you won't get more than maybe 23 MB, depending on all the other allocations you've done. Remember, the PSP has next to no memory. You can't just toss memory at a problem like on a PC.
ardatan
Posts: 44
Joined: Sat Jan 12, 2008 8:47 am

Post by ardatan »

I can't copy the image into the buffer... How can I do it?
MS light blinks very long... and PSP powers off...
I'm sorry for my bad English.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

If your images are too big to fit in memory, you either need to scale them before putting them on the PSP, or you need to load them a piece at a time (say, one line at a time) and scale them on the fly.
ardatan
Posts: 44
Joined: Sat Jan 12, 2008 8:47 am

Post by ardatan »

No, it isn't very big...
It is only 480x272....
I'm sorry for my bad English.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Have you adjusted the size of your buffers to be smaller yet? I did point out the one that was too big. Post an updated listing of the code.
ardatan
Posts: 44
Joined: Sat Jan 12, 2008 8:47 am

Post by ardatan »

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pspdisplay.h>
#include <pspnet_inet.h>
#include <pspnet_apctl.h>
#include <pspnet_resolver.h>
#include <psputility.h>
#include <netinet/in.h>
#include <kubridge.h>
#include <sys/select.h>
#include <pspctrl.h>
#include <errno.h>
#include <math.h>
#include <psputility.h>
#include <pspgu.h>
#include <pspgum.h>
#include <pspjpeg.h>

PSP_MODULE_INFO&#40;"JpegSample", PSP_MODULE_USER, 1, 1&#41;;
PSP_HEAP_SIZE_MAX&#40;&#41;;

#define BUF_WIDTH &#40;512&#41;
#define SCR_WIDTH &#40;480&#41;
#define SCR_HEIGHT &#40;272&#41;
#define PIXEL_SIZE &#40;4&#41;
#define FRAME_SIZE &#40;BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE&#41;
#define ZBUF_SIZE &#40;BUF_WIDTH SCR_HEIGHT * 2&#41;
#define printf pspDebugScreenPrintf
#define PTR2HND&#40;PTR&#41;	&#40;&#40;PTR&#41; - 1&#41;
#define HND2PTR&#40;HND&#41;	&#40;HND + 1&#41;

static unsigned int __attribute__&#40;&#40;aligned&#40;16&#41;&#41;&#41; list&#91;262144&#93;;

/* Exit callback */
int exit_callback&#40;int arg1, int arg2, void *common&#41;
&#123;

	sceKernelExitGame&#40;&#41;;

	return 0;
&#125;

/* Callback thread */
int CallbackThread&#40;SceSize args, void *argp&#41;
&#123;
	int cbid;

	cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
	sceKernelRegisterExitCallback&#40;cbid&#41;;

	sceKernelSleepThreadCB&#40;&#41;;

	return 0;
&#125;

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks&#40;void&#41;
&#123;
	int thid = 0;

	thid = sceKernelCreateThread&#40;"update_thread", CallbackThread, 0x11, 0xFA0, 0, 0&#41;;
	if&#40;thid >= 0&#41;
	&#123;
		sceKernelStartThread&#40;thid, 0, 0&#41;;
	&#125;

	return thid;
&#125;


int FileRead_open&#40;const char* FileName&#41;
&#123;
	return PTR2HND&#40;sceIoOpen&#40;FileName,PSP_O_RDWR,0777&#41;&#41;;
//	return PTR2HND&#40;fopen&#40;FileName,"rb"&#41;&#41;;
&#125;
int FileRead_close&#40;int FileHandle&#41;
&#123;
	if&#40;FileHandle == -1&#41;return -1;
	sceIoClose&#40;HND2PTR&#40;FileHandle&#41;&#41;;
//	fclose&#40;HND2PTR&#40;FileHandle&#41;&#41;;
	return 0;
&#125;
int FileRead_size&#40;const char *FileName&#41;
&#123;
	SceIoStat stat;
	if&#40;sceIoGetstat&#40;FileName,&stat&#41; < 0&#41; return -1;
	if&#40;stat.st_size > 0x00000000ffffffff&#41;return 0xffffffff;
	return stat.st_size;
&#125;

int FileRead_read&#40;void * Buffer,int Size,int FileHandle&#41;
&#123;
	if&#40;FileHandle == -1&#41;return -1;
	return sceIoRead&#40;HND2PTR&#40;FileHandle&#41;,Buffer,Size&#41;;
&#125;

u8* convertjpeg&#40;const char *FileName&#41;
&#123;
		printf&#40;"ConvertStarts\n"&#41;;
	int size = FileRead_size&#40;FileName&#41;;
	u8* rgbabuf = &#40;u8*&#41;malloc&#40;4*480*272&#41;;
	u8* databuf = &#40;u8*&#41;malloc&#40;size&#41;;
	if&#40;databuf == NULL || rgbabuf == NULL&#41;
	&#123;
		printf&#40;"Malloc Error!\n"&#41;;
		free&#40;databuf&#41;;
		free&#40;rgbabuf&#41;;
		sceJpegDeleteMJpeg&#40;&#41;;
		sceJpegFinishMJpeg&#40;&#41;;
		return NULL;
	&#125;
	int fh = FileRead_open&#40;FileName&#41;;
	if&#40;fh == -1&#41;
	&#123;
		printf&#40;"File couldn't open!\n"&#41;;
		free&#40;databuf&#41;;
		free&#40;rgbabuf&#41;;
		sceJpegDeleteMJpeg&#40;&#41;;
		sceJpegFinishMJpeg&#40;&#41;;
		return NULL;
	&#125;
	FileRead_read&#40;databuf,size,fh&#41;;
	FileRead_close&#40;fh&#41;;
	int res = sceJpegDecodeMJpeg&#40;databuf,size,rgbabuf,0&#41;;
	free&#40;databuf&#41;;
	sceJpegDeleteMJpeg&#40;&#41;;
	sceJpegFinishMJpeg&#40;&#41;;
	if&#40;res < 0&#41;
	&#123;
		printf&#40;"Decode Error!\n"&#41;;
		free&#40;rgbabuf&#41;;
		return NULL;
	&#125;
	printf&#40;"Convert is completed!\n"&#41;;
	return rgbabuf;
&#125;

void initGraphics&#40;&#41;
&#123;
	sceGuInit&#40;&#41;;
	sceDisplayWaitVblankStart&#40;&#41;;
	sceGuDisplay&#40;1&#41;;
	sceGuStart&#40;GU_DIRECT, list&#41;;
&#125;

void drawFrame&#40;unsigned char* textureData&#41;
&#123;
sceGuStart&#40;GU_DIRECT, list&#41;;
//sceGuDispBuffer&#40;SCR_WIDTH,SCR_HEIGHT, 0,BUF_WIDTH&#41;;
	void* framebuffer = 0;

  sceGuCopyImage&#40;GU_PSM_8888, 0, 0, 480, 272, 480, textureData, 0, 0, 512, &#40;void*&#41;&#40;&#40;&#40;unsigned int&#41;framebuffer&#41; + 0x4000000&#41;&#41;;

  sceGuFinish&#40;&#41;;
  sceGuSync&#40;0,0&#41;;

  sceDisplayWaitVblankStart&#40;&#41;;
  sceGuSwapBuffers&#40;&#41;;
&#125;

int LoadStartModule&#40;char *path&#41; 
&#123; 
  u32 loadResult; 
  u32 startResult; 
  int status; 

  loadResult = kuKernelLoadModule&#40;path, 0, NULL&#41;; 
  if &#40;loadResult & 0x80000000&#41; &#123;
    return -1; 
  &#125; 
  else &#123; 
    startResult = sceKernelStartModule&#40;loadResult, 0, NULL, &status, NULL&#41;; 
  &#125; 

  if &#40;loadResult != startResult&#41; &#123;
    return -2; 
  &#125; 
  return 0; 
&#125;

int StartJpegPsp&#40;&#41; 
&#123;
  printf&#40;"Loading 'flash0&#58;/kd/avcodec.prx'..."&#41;;
  if &#40;LoadStartModule&#40;"flash0&#58;/kd/avcodec.prx"&#41; == 0&#41; &#123;
    printf&#40;"ok\n"&#41;;
  &#125;
  else &#123;
    printf&#40;"failed\n"&#41;;
    return -1;
  &#125;

  printf&#40;"init Jpeg decompression..."&#41;;
  if &#40;sceJpegInitMJpeg&#40;&#41; == 0&#41; &#123;
    if &#40;sceJpegCreateMJpeg&#40;480, 272&#41; == 0&#41; &#123;
      printf&#40;"ok\n"&#41;;
      return 0;
    &#125;
  &#125;

  printf&#40;"failed\n"&#41;;
  return -1;
&#125;


int main&#40;void&#41;
&#123;
SetupCallbacks&#40;&#41;;
pspDebugScreenInit&#40;&#41;;
StartJpegPsp&#40;&#41;;
u8* bitmap = convertjpeg&#40;"background.jpg"&#41;;
initGraphics&#40;&#41;;
drawFrame&#40;bitmap&#41;;
sceKernelSleepThread&#40;&#41;;
return 0;
&#125;
When I try to run this. It gaves Decode error....
What should I do?
I'm sorry for my bad English.
ardatan
Posts: 44
Joined: Sat Jan 12, 2008 8:47 am

Post by ardatan »

Oh Sorry... I solved it... A bad image caused this error...
Now I fixed the problem... :D Thanks J.F
I'm sorry for my bad English.
Post Reply