forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

updated unpack-pbp and pack-pbp

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
flatwhatson



Joined: 29 Dec 2006
Posts: 3
Location: Brisbane, Australia

PostPosted: Sat Dec 30, 2006 10:52 pm    Post subject: updated unpack-pbp and pack-pbp Reply with quote

Hi everyone,

I'm sure many here have been playing with these new PSX eboots for the PSP... I was finding, because they're quite large, that the unpack-pbp and pack-pbp that come with the pspsdk were hogging all my virtual memory, because they don't implement any kind of buffer size limitations.

So I went ahead and rewrote both of them to use a 16mb maximum read/write buffer, plus a couple of other, minor things. It's all at the top of the code...

Hope you guys like my work, let me know.

flatwhatson

unpack-pbp.c
Code:
/*
# _____     ___ ____     ___ ____
#  ____|   |    ____|   |        | |____|
# |     ___|   |     ___|    ____| |    \    PSPDEV Open Source Project.
#-----------------------------------------------------------------------
# (c) 2005 Dan Peori <peori@oopo.net>
# Licenced under Academic Free License version 2.0
# Review pspsdk README & LICENSE files for further details.
#
# 2006-12-26 - Andrew Whatson <whatson@gmail.com>
#   - rewrote for easier reading
#   - gave "correct" names to UNKNOWN.* files
#   - improved memory efficiency with large PBPs
#   - no longer outputs empty files
#
# $Id: unpack-pbp.c 499 2005-07-05 12:43:35Z mc $
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>

#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif

#ifdef WORDS_BIGENDIAN

// Swap the bytes of an int for big-endian machines
static int swap_int(int n)
{
   return ((n >> 24) & 0xff) | ((n >> 8) & 0xff00) | ((n << 8) & 0xff0000) | ((n << 24) & 0xff000000);
}

#endif

// Struct to describe the header of a PBP file
typedef struct {
   char   signature[4];
   int      version;
   int      offset[8];
} HEADER;

// Correct PBP signature
char correct_sig[4] = {
   0x00,
   0x50,   // P
   0x42,   // B
   0x50   // P
};

// Names of files included in a PBP
char *filename[8] = {
   "PARAM.SFO",
   "ICON0.PNG",
   "ICON1.PMF",
   "PIC0.PNG",
   "PIC1.PNG",
   "SND0.AT3",
   "DATA.PSP",
   "DATA.PSAR"
};

// Maximum size of read buffer
int maxbuffer = 16 * 1024 * 1024;

int main(int argc, char *argv[]) {
   FILE *infile;
   FILE *outfile;
   HEADER header;
   int loop0;
   int total_size;
   
   // Check for the correct number of arguments
   if (argc != 2) {
      printf("USAGE: %s <filename>\n", argv[0]);
      return -1;
   }
   
   // Open the specified PBP
   infile = fopen(argv[1], "rb");
   if (infile == NULL) {
      printf("ERROR: Could not open the input file. (%s)\n", argv[1]);
      return -1;
   }
   
   // Get the size of the PBP
   fseek(infile, 0, SEEK_END);
   total_size = ftell(infile);
   fseek(infile, 0, SEEK_SET);
   if (total_size < 0) {
      printf("ERROR: Could not get the input file size.\n");
      return -1;
   }
   
   // Read in the header
   if (fread(&header, sizeof(HEADER), 1, infile) < 0) {
      printf("ERROR: Could not read the input file header.\n");
      return -1;
   }
   
   // Check the signature
   for (loop0 = 0; loop0 < sizeof(correct_sig); loop0++) {
      if (header.signature[loop0] != correct_sig[loop0]) {
         printf("ERROR: Input file is not a PBP file.\n");
         return -1;
      }
   }
   
#ifdef WORDS_BIGENDIAN
   
   // Swap the bytes of the offsets for big-endian machines
   for (loop0 = 0; loop0 < 8; loop0++) {
      header.offset[loop0] = swap_int(header.offset[loop0]);
   }
   
#endif
   
   // For each file in the PBP
   for (loop0 = 0; loop0 < 8; loop0++) {
      void *buffer;
      int size;
      
      // Get the size of this file
      if (loop0 == 7) {
         size = total_size - header.offset[loop0];
      } else {
         size = header.offset[loop0 + 1] - header.offset[loop0];
      }
      
      // Print out the file details
      printf("[%d] %10d bytes | %s\n", loop0, size, filename[loop0]);
      
      // Skip the file if empty
      if (!size) continue;
      
      // Open the output file
      outfile = fopen(filename[loop0], "wb");
      if (outfile == NULL) {
         printf("ERROR: Could not open the output file. (%s)\n", filename[loop0]);
         return -1;
      }
      
      do {
         int readsize;
         
         // Make sure we don't exceed the maximum buffer size
         if (size > maxbuffer) {
            readsize = maxbuffer;
         } else {
            readsize = size;
         }
         size -= readsize;
         
         // Create the read buffer
         buffer = malloc(readsize);
         if (buffer == NULL) {
            printf("ERROR: Could not allocate the section data buffer. (%d)\n", readsize);
            return -1;
         }
         
         // Read in the data from the PBP
         if (fread(buffer, readsize, 1, infile) < 0) {
            printf("ERROR: Could not read in the section data.\n");
            return -1;
         }
         
         // Write the contents of the buffer to the output file
         if (fwrite(buffer, readsize, 1, outfile) < 0) {
            printf("ERROR: Could not write out the section data.\n");
            return -1;
         }
         
         // Clean up the buffer
         free(buffer);
         
         // Repeat if we haven't finished writing the file
      } while (size);
      
      // Close the output file
      if (fclose(outfile) < 0) {
         printf("ERROR: Could not close the output file.\n");
         return -1;
      }
      
   }
   
   // Close the PBP
   if (fclose(infile) < 0) {
      printf("ERROR: Could not close the input file.\n");
      return -1;
   }
   
   // Exit successful
   return 0;
}


pack-pbp.c
Code:
/*
# _____     ___ ____     ___ ____
#  ____|   |    ____|   |        | |____|
# |     ___|   |     ___|    ____| |    \    PSPDEV Open Source Project.
#-----------------------------------------------------------------------
# (c) 2005 Dan Peori <peori@oopo.net>
# Licenced under Academic Free License version 2.0
# Review pspsdk README & LICENSE files for further details.
#
# 2006-12-30 - Andrew Whatson <whatson@gmail.com>
#   - rewrote for easier reading
#   - gave "correct" names to UNKNOWN.* files
#   - improved memory efficiency with large PBPs
#   - output name of each file as it's added
#
# $Id: pack-pbp.c 499 2005-07-05 12:43:35Z mc $
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#ifdef WORDS_BIGENDIAN

// Swap the bytes of an int for big-endian machines
static int swap_int(int n)
{
  return ((n>>24)&0xff)|((n>>8)&0xff00)|((n<<8)&0xff0000)|((n<<24)&0xff000000);
}

#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif

// Struct to describe the header of a PBP file
struct {
   char signature[4];
   char version[4];
   int offset[8];
} header = {
   { 0x00, 0x50, 0x42, 0x50 },
   { 0x00, 0x00, 0x01, 0x00 },
   { 40, 0, 0, 0, 0, 0, 0, 0 }
};

// Maximum size of read buffer
int maxbuffer = 16 * 1024 * 1024;

int main(int argc, char *argv[]) { int loop0, result;
   FILE *infile;
   FILE *outfile;
   int filesize[8];
   
   // Check for the correct number of arguments
   if (argc != 10) {
      printf("USAGE: %s <output.pbp> <param.sfo> <icon0.png> <icon1.pmf> <pic0.png> <pic1.png> <snd0.at3> <data.psp> <data.psar>\n", argv[0]);
      return -1;
   }
   
   // For each file in the PBP
   for (loop0 = 0; loop0 < 8; loop0++) {
      
      // If the specificed filename is NULL or -, skip the file.
      if (strncmp(argv[2 + loop0], "NULL", 4) == 0 || strncmp(argv[2 + loop0], "-", 4) == 0) {
         filesize[loop0] = 0;
      } else {
         
         // Open the file
         infile = fopen(argv[2 + loop0], "rb");
         if (infile == NULL) {
            printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]);
            return -1;
         }
         
         // Read in the file size
         fseek(infile, 0, SEEK_END);
         filesize[loop0] = ftell(infile);
         fseek(infile, 0, SEEK_SET);
         if (filesize[loop0] < 0) {
            printf("ERROR: Could not read in the file size. (%s)\n", argv[2 + loop0]);
            return -1;
         }
         
         // Close the file
         result = fclose(infile);
         if (result < 0) {
            printf("ERROR: Could not close the file. (%s)\n", argv[2 + loop0]);
            return -1;
         }
      }
   }

   // Set the header offset values for each file
   for (loop0 = 1; loop0 < 8; loop0++) {
      header.offset[loop0] = header.offset[loop0 - 1] + filesize[loop0 - 1];
   }
   
#ifdef WORDS_BIGENDIAN
   
   // Swap the bytes of the offsets for big-endian machines
   for (loop0 = 0; loop0 < 8; loop0++) {
      header.offset[loop0] = swap_int(header.offset[loop0]);
   }
   
#endif
   
   // Open the output file
   outfile = fopen(argv[1], "wb");
   if (outfile == NULL) {
      printf("ERROR: Could not open the output file. (%s)\n", argv[1]);
      return -1;
   }
   
   // Write out the header
   result = fwrite(&header, sizeof(header), 1, outfile);
   if (result < 0) {
      printf("ERROR: Could not write out the file header. (%s)\n", argv[1]);
      return -1;
   }
   
   // For each file in the PBP
   for (loop0 = 0; loop0 < 8; loop0++) {
      void *buffer;
      int readsize;
      
      // Print out the file details
      printf("[%d] %10d bytes | %s\n", loop0, filesize[loop0], argv[2 + loop0]);
      
      // If this file is empty, skip it
      if (!filesize[loop0]) continue;
      
      // Open the file
      infile = fopen(argv[2 + loop0], "rb");
      if (infile == NULL) {
         printf("ERROR: Could not open the file. (%s)\n", argv[2 + loop0]);
         return -1;
      }
      
      do {
         // Make sure we don't exceed the maximum buffer size
         if (filesize[loop0] > maxbuffer) {
            readsize = maxbuffer;
         } else {
            readsize = filesize[loop0];
         }
         filesize[loop0] -= readsize;
         
         // Create the read buffer
         buffer = malloc(readsize);
         if (buffer == NULL) {
            printf("ERROR: Could not allocate the file data space. (%s)\n", argv[2 + loop0]);
            return -1;
         }
         
         // Read in the data from the file
         if (fread(buffer, readsize, 1, infile) < 0) {
            printf("ERROR: Could not read in the file data. (%s)\n", argv[2 + loop0]);
            return -1;
         }
         
         // Write the contents of the buffer to the PBP
         if (fwrite(buffer, readsize, 1, outfile) < 0) {
            printf("ERROR: Could not write out the file data. (%s)\n", argv[1]);
            return -1;
         }
         
         // Clean up the buffer
         free(buffer);
         
         // Repeat if we haven't finished writing the file
      } while (filesize[loop0]);
   }
   
   // Close the output file.
   result = fclose(outfile);
   if (result < 0) {
      printf("ERROR: Could not close the output file. (%s)\n", argv[1]);
      return -1;
   }
   
   // Exit successful
   return 0;
}
Back to top
View user's profile Send private message
ooPo
Site Admin


Joined: 17 Jan 2004
Posts: 2032
Location: Canada

PostPosted: Tue May 01, 2007 3:23 pm    Post subject: Reply with quote

Changes added to the repository.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group