Skip to: Site menu | Main content


Welcome to PSP-Programming.com, a place for developers to get together.

Welcome to the forums. Here you can find other user tutorials as well as homebrew releases and the source code repository. You can also ask for help with your code here and post your own homebrew!

PSP-Programming.com Forums
February 10, 2012, 01:04:24 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

News: Welcome to PSP-Programming.com
Home Help Search Shop Login Register
Digg This!
Pages: [1]
Print
Author Topic: scejpeg sample  (Read 1997 times)
mowglisanu

C/C++ Developer
Hero Member
*

Karma: +36/-11
Offline Offline

Posts: 787
0.00 points

View Inventory
Send Money to mowglisanu


View Profile
« on: August 24, 2009, 09:46:24 PM »

I saw some dude on ps2dev try to submit a sample of how to use scejpeg but got rejected because of the use of libraries not in the official sdk.
I decided to check it out.

and made my own sample
main.c
Code:
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspsdk.h>
#include <stdlib.h>
#include <stdio.h>
#include <pspdisplay.h>
#include <psputility.h>
#include <pspjpeg.h>
#include "graphics.h"
#define printf pspDebugScreenPrintf
PSP_MODULE_INFO("JpegSample", PSP_MODULE_USER, 1, 1);
PSP_HEAP_SIZE_KB(-1024);
//extern int getNextPower2(int width);
int getNextPower2(int width)
{
int b = width;
int n;
for (n = 0; b != 0; n++) b >>= 1;
b = 1 << n;
if (b == 2 * width) b >>= 1;
return b;
}
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{

   sceKernelExitGame();

   return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
   int cbid;

   cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
   sceKernelRegisterExitCallback(cbid);

   sceKernelSleepThreadCB();

   return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
   int thid = 0;

   thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
   if(thid >= 0)
   {
      sceKernelStartThread(thid, 0, 0);
   }

   return thid;
}

int getJpegDimensions(u8* data, int data_size, int *width, int *height){
   int i = 0;
   if (data[i] == 0xFF && data[i+1] == 0xD8 && data[i+2] == 0xFF && data[i+3] == 0xE0) {
      i += 4;
      // Check for valid JPEG header (null terminated JFIF)
      if (data[i+2] == 'J' && data[i+3] == 'F' && data[i+4] == 'I' && data[i+5] == 'F' && data[i+6] == 0x00){
         //Retrieve the block length of the first block since the first block will not contain the size of file
         int block_length = data[i] * 256 + data[i+1];
         while (i < data_size){
               i += block_length;                  //Increase the file index to get to the next block
               if (i >= data_size) return -1;      //Check to protect against segmentation faults
               if (data[i] != 0xFF) return -1;     //Check that we are truly at the start of another block
               if (data[i+1] == 0xC0) {            //0xFFC0 is the "Start of frame" marker which contains the file size
               //The structure of the 0xFFC0 block is quite simple [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
                  *height = data[i+5]*256 + data[i+6];
                  *width = data[i+7]*256 + data[i+8];
                  return 0;
               }
               else{
                  i += 2;                                     //Skip the block marker
                  block_length = data[i] * 256 + data[i+1];   //Go to the next block
               }
         }
         return -1;                //If this point is reached then no size was found
      }
      else
         return -1;                //Not a valid JFIF string
   }
   else
      return -1;                   //Not a valid SOI header
}

int main(int argc, char *argv[]){
    SetupCallbacks();
    pspDebugScreenInit();
    int ret;
    if (sceUtilityLoadAvModule(PSP_AV_MODULE_AVCODEC) < 0) sceKernelExitGame();
    ret = sceJpegInitMJpeg();
    if (ret < 0){
       printf("sceJpegInitMJpeg %d\n", ret);
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    SceUID fd;
    u8 *data;
    int size;
    fd = sceIoOpen("sample.jpg", PSP_O_RDONLY, 0777);
    if (fd < 0){
       printf("sceIoOpen 0x%x\n", fd);
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    size = sceIoLseek32(fd, 0, PSP_SEEK_END);
    if (size < 0){
       printf("sceIoOpen 0x%x\n", ret);
       sceIoClose(fd);
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    sceIoLseek32(fd, 0, PSP_SEEK_SET);
    data = malloc(size);
    if (!data){
       printf("malloc failed\n");
       sceIoClose(fd);
       sceJpegFinishMJpeg();
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    sceIoRead(fd, data, size);
    sceIoClose(fd);
    int width = 480, height = 272;
    if (getJpegDimensions(data, size, &width, &height) < 0){
       printf("Cannot find dimensions defaulting to %dx%d\n", width, height);
    }
    ret = sceJpegCreateMJpeg(width, height);
    if (ret < 0){
       printf("sceJpegCreateMJpeg 0x%x\n", ret);
       free(data);
       sceJpegFinishMJpeg();
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    u32 *imgBuf = (u32*)memalign(64, getNextPower2(width)*getNextPower2(height)*4);
    if (!imgBuf){
       printf("malloc failed\nw = %d\nh = %d\n", width, height);
       free(data);
       sceJpegDeleteMJpeg();
       sceJpegFinishMJpeg();
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    ret = sceJpegDecodeMJpeg(data, size, imgBuf, 0); 
    if (ret < 0){
       printf("sceJpegDecodeMJpeg 0x%x\nw = %d\nh = %d\n", ret, width, height);
       free(data);
       free(imgBuf);
       sceJpegDeleteMJpeg();
       sceJpegFinishMJpeg();
       sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    free(data);
    sceJpegDeleteMJpeg();
    sceJpegFinishMJpeg();
    sceUtilityUnloadAvModule(PSP_AV_MODULE_AVCODEC);
    Image *img = malloc(sizeof(Image));
    if (!img){
       printf("malloc failed\n");
       free(imgBuf);
       sceKernelDelayThread(5000000);
       sceKernelExitGame();
    }
    img->imageHeight = height;
    img->imageWidth = width;
    img->textureHeight = getNextPower2(height);
    img->textureWidth = getNextPower2(width);
    img->data = imgBuf;
    int i, j;
    for (i = height-1; i >= 0 ; i--)
        for (j = width-1; j >= 0; j--)
            imgBuf[i*img->textureWidth+j] = 0xff000000|imgBuf[i*width+j];
    sceKernelDcacheWritebackInvalidateRange(imgBuf, img->textureHeight*img->textureWidth*4);
    initGraphics();
    blitAlphaImageToScreen(0, 0, img->imageWidth, img->imageHeight, img, 0, 0);
    flipScreen();

    sceKernelSleepThread();
    return 0;
}
Makefile
Code:
TARGET = jpeg
OBJS = main.o graphics.o framebuffer.o

BUILD_PRX = 1

CFLAGS = -O2 -G0 -Wall -g
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

INCDIR =
LIBS = -lpspjpeg -lpsputility -lpng -lz -lm -lpspgu
PSP_LARGE_MEMORY = 1

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = JPEG

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
The image data returned is not aligned to the next power of 2 and all the alpha values are 0, so I set it up to work with graphics.c/h
NOTE
note all resolutions are supported
these work(width by height)
176x144, 320x240, 640x480, 272x480, 720x480, 400x192, 144x80, 368x208
This looks like a special case library for decoding camera images of something
Photoshop images fails to load.

error codes
sceJpegDecodeMJpeg
0x80650016 - ?
0x80650020 - ?
0x80650035 - invalid format?(progressive)
Logged

Check out my:
 Audio lib
 Pmf Viewer


AlphaDingDong
Combat Muskrat
All-Around Dev
Hero Member
*

Karma: +32/-3
Offline Offline

Posts: 882
2044.69 points

View Inventory
Send Money to AlphaDingDong
Hey... Are you gonna eat that?


View Profile
« Reply #1 on: August 25, 2009, 07:02:53 AM »

Sweet!  Thanks mowgli!
Logged
Pages: [1]
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.601 seconds with 25 queries.
Sister Sites: Guitar Hero 4   BrokeniTouch.com