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: Select all
/*
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| | ___| ____| | \ 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;
}
Code: Select all
/*
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| | ___| ____| | \ 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;
}