Important information: this site is currently scheduled to go offline indefinitely by end of the year.

Corpse Party PSP image.bin file

The Original Forum. Game archives, full of resources. How to open them? Get help here.
brainfog
ultra-n00b
Posts: 5
Joined: Thu Dec 01, 2011 11:35 am
Location: Russia, Moscow
Has thanked: 2 times

Re: Corpse Party PSP image.bin file

Post by brainfog »

Thank you, good sir! Extractor works nicely.
Wouldn't you mind to share recompression alg code?
Don't have much patience to wait fully functioning tool (:
User avatar
cozy
beginner
Posts: 39
Joined: Mon Dec 07, 2009 10:18 pm
Been thanked: 21 times

Re: Corpse Party PSP image.bin file

Post by cozy »

The contents of this post was deleted because of possible forum rules violation.
SkyBladeCloud
beginner
Posts: 37
Joined: Fri Jun 25, 2010 10:44 pm
Been thanked: 11 times

Re: Corpse Party PSP image.bin file

Post by SkyBladeCloud »

This is the complete code I'm using to decompress and recompress; it is a pretty standard implementation, with a top of 16 byte os compressed strings:

Code: Select all

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace LZSS
{
    unsafe static class LZSS
    {
        const int N = 4096;
        const int F = 16;
        const int THRESHOLD = 2;

        const int NIL = N;

        static int textsize = 0, codesize = 0;

        static byte* text_buf = (byte*)Marshal.AllocHGlobal(N + F - 1);

        static int match_position, match_length;
        static int[] lson = new int[N + 1], rson = new int[N + 257], dad = new int[N + 1];

        static Stream infile, outfile;

        private static void InitTree()
        {
            int i;

            for (i = N + 1; i <= N + 256; i++) rson[i] = NIL;
            for (i = 0; i < N; i++) dad[i] = NIL;
        }

        private static void InsertNode(int r)
        {
            int i, p, cmp;
            byte* key;

            cmp = 1; key = &text_buf[r]; p = N + 1 + key[0];
            rson[r] = lson[r] = NIL; match_length = 0;
            for (; ; )
            {
                if (cmp >= 0)
                {
                    if (rson[p] != NIL) p = rson[p];
                    else { rson[p] = r; dad[r] = p; return; }
                }
                else
                {
                    if (lson[p] != NIL) p = lson[p];
                    else { lson[p] = r; dad[r] = p; return; }
                }
                for (i = 1; i < F; i++)
                    if ((cmp = key[i] - text_buf[p + i]) != 0) break;
                if (i > match_length)
                {
                    match_position = p;
                    if ((match_length = i) >= F) break;
                }
            }
            dad[r] = dad[p]; lson[r] = lson[p]; rson[r] = rson[p];
            dad[lson[p]] = r; dad[rson[p]] = r;
            if (rson[dad[p]] == p) rson[dad[p]] = r;
            else lson[dad[p]] = r;
            dad[p] = NIL;
        }

        private static void DeleteNode(int p)
        {
            int q;

            if (dad[p] == NIL) return;
            if (rson[p] == NIL) q = lson[p];
            else if (lson[p] == NIL) q = rson[p];
            else
            {
                q = lson[p];
                if (rson[q] != NIL)
                {
                    do { q = rson[q]; } while (rson[q] != NIL);
                    rson[dad[q]] = lson[q]; dad[lson[q]] = dad[q];
                    lson[q] = lson[p]; dad[lson[p]] = q;
                }
                rson[q] = rson[p]; dad[rson[p]] = q;
            }
            dad[q] = dad[p];
            if (rson[dad[p]] == p) rson[dad[p]] = q; else lson[dad[p]] = q;
            dad[p] = NIL;
        }

        private static void Encode()
        {
            int i, c, len, r, s, last_match_length, code_buf_ptr;
            byte[] code_buf = new byte[17];
            byte mask;

            InitTree();
            code_buf[0] = 0;
            code_buf_ptr = mask = 1;
            s = 0; r = N - F;
            for (i = s; i < r; i++) text_buf[i] = 0x00;
            for (len = 0; len < F && infile.Position != infile.Length; len++)
            {
                c = infile.ReadByte();
                text_buf[r + len] = (byte)c;
            }
            if ((textsize = len) == 0) return;
            for (i = 1; i <= F; i++) InsertNode(r - i);
            InsertNode(r);
            do
            {
                if (match_length > len) match_length = len;
                if (match_length <= THRESHOLD)
                {
                    match_length = 1;
                    code_buf[0] |= mask;
                    code_buf[code_buf_ptr++] = text_buf[r];
                }
                else
                {
                    code_buf[code_buf_ptr++] = (byte)match_position;
                    code_buf[code_buf_ptr++] = (byte)
                            (((match_position >> 4) & 0xf0)
                      | (match_length - (THRESHOLD + 1)));
                }
                if ((mask <<= 1) == 0)
                {
                    for (i = 0; i < code_buf_ptr; i++)
                        outfile.WriteByte(code_buf[i]);
                    codesize += code_buf_ptr;
                    code_buf[0] = 0; code_buf_ptr = mask = 1;
                }
                last_match_length = match_length;
                for (i = 0; i < last_match_length && infile.Position != infile.Length; i++)
                {
                    c = infile.ReadByte();
                    DeleteNode(s);
                    text_buf[s] = (byte)c;
                    if (s < F - 1) text_buf[s + N] = (byte)c;
                    s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);

                    InsertNode(r);
                }
                while (i++ < last_match_length)
                {
                    DeleteNode(s);
                    s = (s + 1) & (N - 1); r = (r + 1) & (N - 1);
                    if (--len != 0) InsertNode(r);
                }
            } while (len > 0);
            if (code_buf_ptr > 1)
            {
                for (i = 0; i < code_buf_ptr; i++) outfile.WriteByte(code_buf[i]);
                codesize += code_buf_ptr;
            }
        }

        private static void Decode()
        {
            int i, j, k, r, c, flags;

            for (i = 0; i < N - F; i++) text_buf[i] = 0x00;
            r = N - F; flags = 0;
            for (; ; )
            {
                if (((flags >>= 1) & 256) == 0)
                {
                    if (infile.Position == infile.Length) break;
                    c = infile.ReadByte();
                    flags = c | 0xff00;
                }
                if ((flags & 1) != 0)
                {
                    if (infile.Position == infile.Length) break;
                    c = infile.ReadByte();
                    outfile.WriteByte((byte)(c)); text_buf[r++] = (byte)(c); r &= (N - 1);
                }
                else
                {
                    if (infile.Position == infile.Length) break;
                    i = infile.ReadByte();
                    if (infile.Position == infile.Length) break;
                    j = infile.ReadByte();
                    i |= ((j & 0xf0) << 4); j = (j & 0x0f) + THRESHOLD;
                    for (k = 0; k <= j; k++)
                    {
                        c = text_buf[(i + k) & (N - 1)];
                        outfile.WriteByte((byte)(c)); text_buf[r++] = (byte)(c); r &= (N - 1);
                    }
                }
            }
        }

        public static byte[] Decompress(byte[] inBuffer)
        {
            MemoryStream inStream = new MemoryStream(inBuffer);
            BinaryReader reader = new BinaryReader(inStream);
            reader.BaseStream.Seek(0x04, SeekOrigin.Begin);
            int decSize = reader.ReadInt32();
            infile = new MemoryStream(reader.ReadBytes(inBuffer.Length - 0x08));
            outfile = new MemoryStream();
            Decode();
            if (outfile.Length == decSize)
                return (outfile as MemoryStream).ToArray();
            else throw new InvalidDataException("Decompression Error");
        }

        public static byte[] Compress(byte[] inBuffer)
        {
            int decSize = inBuffer.Length;
            infile = new MemoryStream(inBuffer);
            outfile = new MemoryStream();
            Encode();
            MemoryStream outStream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(outStream);
            writer.Write(0x53535a4c);
            writer.Write(decSize);
            writer.Write((outfile as MemoryStream).ToArray());
            return outStream.ToArray();
        }

        public static void Decompress(String inFile, String outFile)
        {
            infile = new FileStream(inFile, FileMode.Open, FileAccess.Read);
            outfile = new FileStream(outFile, FileMode.Create, FileAccess.Write);
            Decode();
        }

        public static void Compress(String inFile, String outFile)
        {
            infile = new FileStream(inFile, FileMode.Open, FileAccess.Read);
            outfile = new FileStream(outFile, FileMode.Create, FileAccess.Write);
            Encode();
        }

        public static void Decompress(Stream inFileStream, Stream outFileStream)
        {
            infile = inFileStream;
            outfile = outFileStream;
            Decode();
        }

        public static void Compress(Stream inFileStream, Stream outFileStream)
        {
            infile = inFileStream;
            outfile = outFileStream;
            Encode();
        }
    }
}
Regards:

~Sky
Image
brainfog
ultra-n00b
Posts: 5
Joined: Thu Dec 01, 2011 11:35 am
Location: Russia, Moscow
Has thanked: 2 times

Re: Corpse Party PSP image.bin file

Post by brainfog »

Thanx again :)
Toren
ultra-n00b
Posts: 5
Joined: Fri Nov 25, 2011 1:37 am

Re: Corpse Party PSP image.bin file

Post by Toren »

This is great. Thank you all for your help.
Demoniiiik
ultra-n00b
Posts: 1
Joined: Thu Dec 08, 2011 8:25 pm

Re: Corpse Party PSP image.bin file

Post by Demoniiiik »

I'm sorry. But you can do the opposite? That is archiving folder IMAGE in image.bin?
I want to replace some of the texture.
magarcan
ultra-n00b
Posts: 4
Joined: Wed Dec 21, 2011 9:06 pm

Re: Corpse Party PSP image.bin file

Post by magarcan »

Thanks for the code and for the app, but I'm having a problem.

I've tested your app with the 10Mb file that other user has uploaded and I get an exception. Can´t a partial file be used?

I'm interested in traslate game into my language, spanish, do aby of you know how can I get string??

Thanks!!
finale00
M-M-M-Monster veteran
M-M-M-Monster veteran
Posts: 2382
Joined: Sat Apr 09, 2011 1:22 am
Has thanked: 170 times
Been thanked: 307 times

Re: Corpse Party PSP image.bin file

Post by finale00 »

The 10 MB sample most likely won't work cause it's trying to decompress or go to some offset that may or may not exist.
magarcan
ultra-n00b
Posts: 4
Joined: Wed Dec 21, 2011 9:06 pm

Re: Corpse Party PSP image.bin file

Post by magarcan »

finale00 wrote:The 10 MB sample most likely won't work cause it's trying to decompress or go to some offset that may or may not exist.
You are right, I've tested it with full file and works O.K.

Any idea about were can I find text's files??
cierpa
n00b
Posts: 10
Joined: Sun Nov 08, 2009 9:26 pm

Re: Corpse Party PSP image.bin file

Post by cierpa »

Any idea about were can I find text's files??
They're stored in SCRIPT folder. Check file SCRIPT_MAP5 (CHAP1) - these one have introduction of chapter 1.
As I checked they're seems compressed and contains bitmaps / voice acting/ avatars.
Post Reply