From 983358288de02d3bbf09a007f67d6f7d01bc2eff Mon Sep 17 00:00:00 2001 From: Pixel Date: Wed, 22 May 2002 23:24:36 +0000 Subject: Daily commit. --- FAQ-cd.txt | 203 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ FAQ.cd | 203 ------------------------------------------------------------- generic.h | 3 + lz77.cpp | 81 +++++++++++++++--------- lz77.h | 3 +- 5 files changed, 260 insertions(+), 233 deletions(-) create mode 100644 FAQ-cd.txt delete mode 100644 FAQ.cd diff --git a/FAQ-cd.txt b/FAQ-cd.txt new file mode 100644 index 0000000..4a3a92b --- /dev/null +++ b/FAQ-cd.txt @@ -0,0 +1,203 @@ + + + +Q: What is this tools aimed at anyway? +A: It is designed to handle ISO images you make from CDs. + + +Q: What is an ISO image anyway? +A: You can create an ISO with free tools like cdrdao in raw mode, or others, + like cdrwin, CloneCD, etc... + + +Q: Are all the ISO formats handled? +A: No. Only raw-2532 images files. Always the file format outputted by CloneCD + and cdrwin, and the format outputted by cdrdao with the --read-raw option. + + +Q: Is Nero's file format supported? +A: No. + + +Q: Why? Nero's a spreaded software! +A: It's a commercial tool. Since I don't use any commercial tool, and that no + free-software generates Nero ISO, it won't be suppored. + + +Q: What is this tool/library able to? +A: First, you can read/write sectors from/to an iso file. You can also read + informations about an iso file. You can extract/insert files from/to + an iso file. Depending upon the mode you'll be using, it will compute + the right CRC/ECC code for the given sector. The whole in the following + (eventually mixed) modes: MODE_1, MODE_2, MODE_2_FORM_1, MODE_2_FORM_2. + Additionnaly, it is able to produce patches (.ppf files) instead modifying + the iso file, saving you time when you use the right softwares. + Actually, it is quite "oriented" on the MODE_2* formats, since it's + the PSX's formats. + + +Q: I've heard CDmage or ECCRegen can also correct the sectors for me. +A: Maybe. Since it only runs on Win32 platforms, I've never tried it. + + +Q: So, what is the goal of this software? +A: To modify (patch) ISO images. Nothing else. And of course I want it free, + opensource, and working on my preffered operating system, Linux. If somebody + can make it working for windows (and I think this is easy to do) I will + please me. I can't do it right now since I don't really have the opportunity + to build Win32 binaries (apart of cygwin's ones) + + +Q: Where does the source code for the CRC/ECC comes from? +A: Originally, it has been taken from cdrdao. Yazoo has given some + modifications to it. Then I've cleaned it up and made some minor + modifications on my self. The source code was called 'yazedc'. + + +Q: Do you have the right to do so? +A: The software is GPL'ed. I've got the right to give modified versions + of it, as long as I don't claim the modificated thing it the original, + and as long as I mantion the original authors in it. + + +Q: What a strange name, 'yazedc' ? +A: I've got my own ideas about the name's origin... The easy solution: + "YAZoo EDC", where EDC is the field name of one of the things it will + recompute. But there is a more... complicated solution I won't give. + + +Q: So, I can modify your code too, create a new tool, and diffuse it? +A: Yes, as long as you give the full source code, that the new software + is also GPL'ed, and that you mantion me as the original writer of the + software, you can. Read the GPL carefully, it's very interesting. + + +Q: What is exactly the format of a CD-Rom? +A: Firstly, when you have a raw sector, you have to understand its primary form. + Secondly, the whole CD has an internal format, called the iso9660. The format + of the iso9660 is easy to find on the internet. Here is one first easy link: + http://www.ccs.neu.edu/home/bchafy/cdb/info/iso9660.txt + Then you have two more difficult documents: + http://www.ecma.ch/ecma1/stand/ecma-119.htm + and + http://www.ecma.ch/ecma1/stand/ecma-130.htm + + All those links were taken from the page + http://www.ccs.neu.edu/home/bchafy/cdb/info/info.html + + The sector format is a bit complicated to find on the internet. Here is what + I've found. + + First you have to know that there is many formats that describe the sector's + organisation. Those are called "Books". There is the Red Book, the Yellow + Book, the Blue Book, the Green Book, the Orange Book, and the White Book. + + The Red Book is for Audio CD. The Yellow for common CD-Roms. The Blue book + for Philips's VideoCD. The Green Book for CD-i and CD-XA. The Orange Book + for CD-R cds. And the White Book seems to be a replacement of the Green one. + + This is quite unclear and you have to actually buy the books since they + aren't in public domain. + + So the informations I'll give comes from various source of various free + softwares. Should I mention two: cdrdao http://cdrdao.sourceforge.net + and ECCRegen http://web.tiscali.it/eccregen as the most useful sources. + + Here is the general form of a CD-Rom sector: + + <--------------------------- sector: 2352 bytes ------------------------------> + <- Header: 16 bytes -><---------------- Datas: 2336 bytes --------------------> + + Let's move to the header description: + + <--------------------------- header: 16 bytes ------------------------------> + <-- sync bytes: 12 bytes --><-- localisation: 3 bytes --><-- mode: 1 byte --> + + The sync bytes are easy: it is always 00 FF FF FF FF FF FF FF FF FF FF 00 + + The localisation is the sector "position" described in time. For example, + the sector 200000 of a CD is at the "time" 44:28:50. The first is the number + of minutes, the second is the number of seconds, in the range 0-59 and the + last is the frame number, in the range 0-74. It means there is 75 frames + into a second for a CD player. Please note that the CD "begins" at 00:02:00. + + Ok now that we know all this, you can feel the way the localisation is + stored. But it is not that easy... + + <-------------------- localisation: 3 bytes --------------------> + <-- minute: 1 byte --><-- second: 1 byte --><-- frame: 1 byte --> + + That's seems to be all right *BUT* the fact is that the bytes are stored + in packed BCD format. You may know what the BCD format is if you are "old" + enough for that. I won't enter into the details so if you want a more + description of the BCD format, look into the net. You only have to know that: + +unsigned char from_BCD(unsigned char x) {return ((x & 15) + (x & 240) * 10));} +unsigned char to_BCD(unsigned char x) {return ((x / 10) << 4) | (x % 10));} +int is_valid_BCD(unsigned char x) {return (((x & 15) < 10) && ((x >> 4) < 10));} + + Last thing: when you look at a BCD packed number, you have to read it in + hexadecimal, and then you will see a "decimal" number. So when you count + in BCD, you'll have this: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x10, 0x11, 0x12, etc... You see? You've got a "gap": no 0x0a, + 0x0b, 0x0c, etc... So the BCD is only a trick for an easy reading of hexa + dumps of various informations. + + All right. This was for the localisation part. The last part is the mode + byte. It is really simple actually. It is 0 for an empty sector, 1 for a + sector in MODE1, and 2 for a sector in MODE2. Easy as hell. + + Ok here we are: we know the basic form of a CD's sector, and even know the + MODE of the sector. Now the datas depends upon the sector mode. Here you have + the various kinds: + + <-------------- MODE 1 FORM 1 Sector datas: 2336 bytes ----------------------> + <- datas: 2048 bytes -><- EDC: 4 bytes -><- 0s: 8 bytes -><- ECC: 276 bytes -> + + <---------- MODE 1 FORM 2 and also MODE 2 Sector datas: 2336 bytes ----------> + <----------------------------- datas: 2336 bytes ----------------------------> + + <-------------- MODE 2 FORM 1 Sector datas: 2336 bytes ----------------------> + <- SH: 8 bytes -><- datas: 2048 bytes -><- EDC: 4 bytes -><- ECC: 276 bytes -> + + <-------------- MODE 2 FORM 2 Sector datas: 2336 bytes ----------------------> + <- SH: 8 bytes -><---------- datas: 2324 bytes ----------><- spare: 4 bytes -> + + Well, I *really* don't know how to distinguish the different "FORMS" from + each others for the MODE 1. Have to look further for this. + + The ECC and EDC controls blocks. The yazedc code can compute them, so + don't worry about them. + + The 'SH' (SubHeader) field is the most "complicated" one. Those eight little + bits are the only one I'm really not sure of. All of that because you have to + buy the Books to find the information. This SubHeader is only found into + MODE_2_FORM_1 and MODE_2_FORM_2 sectors. + + Here you have the informations I've been able to gather: + + -) The SubHeader has 8 bytes, but it's twice the same 4 bytes. + -) The 4 bytes are described using the following fields: + o) 1st byte: File Number (FN) + o) 2nd byte: Channel Number (CN) + o) 3rd byte: Sub Mode (SM) + o) 4st byte: Coding Info (CI) + -) I've *never* seen any SubHeader with a FN, CN or CI different from 0, + please inform me if you do. + -) The Sub Mode byte is a bit field which seems to be described like this: + 0: End of Record (EOR) + 1: Video + 2: Audio + 3: Data + 4: Trigger + 5: Form 2 + 6: Real Time (RT) + 7: End of File (EOF) + + Very last things to know: of course, the PSX has the CDs in MODE 2... So the + common files are stored in MODE 2 FORM 1, the STR/XA files are stored in + MODE 2 and I've never seen any file stored in MODE 2 FORM 2. And the MODE 2 + FORM 1 and MODE 2 FORM 2 are also called XA-Mode1 and XA-Mode2 or simplier: + XA-1 and XA-2. + + I hope this will help you as it helped me writing this software. diff --git a/FAQ.cd b/FAQ.cd deleted file mode 100644 index 4a3a92b..0000000 --- a/FAQ.cd +++ /dev/null @@ -1,203 +0,0 @@ - - - -Q: What is this tools aimed at anyway? -A: It is designed to handle ISO images you make from CDs. - - -Q: What is an ISO image anyway? -A: You can create an ISO with free tools like cdrdao in raw mode, or others, - like cdrwin, CloneCD, etc... - - -Q: Are all the ISO formats handled? -A: No. Only raw-2532 images files. Always the file format outputted by CloneCD - and cdrwin, and the format outputted by cdrdao with the --read-raw option. - - -Q: Is Nero's file format supported? -A: No. - - -Q: Why? Nero's a spreaded software! -A: It's a commercial tool. Since I don't use any commercial tool, and that no - free-software generates Nero ISO, it won't be suppored. - - -Q: What is this tool/library able to? -A: First, you can read/write sectors from/to an iso file. You can also read - informations about an iso file. You can extract/insert files from/to - an iso file. Depending upon the mode you'll be using, it will compute - the right CRC/ECC code for the given sector. The whole in the following - (eventually mixed) modes: MODE_1, MODE_2, MODE_2_FORM_1, MODE_2_FORM_2. - Additionnaly, it is able to produce patches (.ppf files) instead modifying - the iso file, saving you time when you use the right softwares. - Actually, it is quite "oriented" on the MODE_2* formats, since it's - the PSX's formats. - - -Q: I've heard CDmage or ECCRegen can also correct the sectors for me. -A: Maybe. Since it only runs on Win32 platforms, I've never tried it. - - -Q: So, what is the goal of this software? -A: To modify (patch) ISO images. Nothing else. And of course I want it free, - opensource, and working on my preffered operating system, Linux. If somebody - can make it working for windows (and I think this is easy to do) I will - please me. I can't do it right now since I don't really have the opportunity - to build Win32 binaries (apart of cygwin's ones) - - -Q: Where does the source code for the CRC/ECC comes from? -A: Originally, it has been taken from cdrdao. Yazoo has given some - modifications to it. Then I've cleaned it up and made some minor - modifications on my self. The source code was called 'yazedc'. - - -Q: Do you have the right to do so? -A: The software is GPL'ed. I've got the right to give modified versions - of it, as long as I don't claim the modificated thing it the original, - and as long as I mantion the original authors in it. - - -Q: What a strange name, 'yazedc' ? -A: I've got my own ideas about the name's origin... The easy solution: - "YAZoo EDC", where EDC is the field name of one of the things it will - recompute. But there is a more... complicated solution I won't give. - - -Q: So, I can modify your code too, create a new tool, and diffuse it? -A: Yes, as long as you give the full source code, that the new software - is also GPL'ed, and that you mantion me as the original writer of the - software, you can. Read the GPL carefully, it's very interesting. - - -Q: What is exactly the format of a CD-Rom? -A: Firstly, when you have a raw sector, you have to understand its primary form. - Secondly, the whole CD has an internal format, called the iso9660. The format - of the iso9660 is easy to find on the internet. Here is one first easy link: - http://www.ccs.neu.edu/home/bchafy/cdb/info/iso9660.txt - Then you have two more difficult documents: - http://www.ecma.ch/ecma1/stand/ecma-119.htm - and - http://www.ecma.ch/ecma1/stand/ecma-130.htm - - All those links were taken from the page - http://www.ccs.neu.edu/home/bchafy/cdb/info/info.html - - The sector format is a bit complicated to find on the internet. Here is what - I've found. - - First you have to know that there is many formats that describe the sector's - organisation. Those are called "Books". There is the Red Book, the Yellow - Book, the Blue Book, the Green Book, the Orange Book, and the White Book. - - The Red Book is for Audio CD. The Yellow for common CD-Roms. The Blue book - for Philips's VideoCD. The Green Book for CD-i and CD-XA. The Orange Book - for CD-R cds. And the White Book seems to be a replacement of the Green one. - - This is quite unclear and you have to actually buy the books since they - aren't in public domain. - - So the informations I'll give comes from various source of various free - softwares. Should I mention two: cdrdao http://cdrdao.sourceforge.net - and ECCRegen http://web.tiscali.it/eccregen as the most useful sources. - - Here is the general form of a CD-Rom sector: - - <--------------------------- sector: 2352 bytes ------------------------------> - <- Header: 16 bytes -><---------------- Datas: 2336 bytes --------------------> - - Let's move to the header description: - - <--------------------------- header: 16 bytes ------------------------------> - <-- sync bytes: 12 bytes --><-- localisation: 3 bytes --><-- mode: 1 byte --> - - The sync bytes are easy: it is always 00 FF FF FF FF FF FF FF FF FF FF 00 - - The localisation is the sector "position" described in time. For example, - the sector 200000 of a CD is at the "time" 44:28:50. The first is the number - of minutes, the second is the number of seconds, in the range 0-59 and the - last is the frame number, in the range 0-74. It means there is 75 frames - into a second for a CD player. Please note that the CD "begins" at 00:02:00. - - Ok now that we know all this, you can feel the way the localisation is - stored. But it is not that easy... - - <-------------------- localisation: 3 bytes --------------------> - <-- minute: 1 byte --><-- second: 1 byte --><-- frame: 1 byte --> - - That's seems to be all right *BUT* the fact is that the bytes are stored - in packed BCD format. You may know what the BCD format is if you are "old" - enough for that. I won't enter into the details so if you want a more - description of the BCD format, look into the net. You only have to know that: - -unsigned char from_BCD(unsigned char x) {return ((x & 15) + (x & 240) * 10));} -unsigned char to_BCD(unsigned char x) {return ((x / 10) << 4) | (x % 10));} -int is_valid_BCD(unsigned char x) {return (((x & 15) < 10) && ((x >> 4) < 10));} - - Last thing: when you look at a BCD packed number, you have to read it in - hexadecimal, and then you will see a "decimal" number. So when you count - in BCD, you'll have this: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x10, 0x11, 0x12, etc... You see? You've got a "gap": no 0x0a, - 0x0b, 0x0c, etc... So the BCD is only a trick for an easy reading of hexa - dumps of various informations. - - All right. This was for the localisation part. The last part is the mode - byte. It is really simple actually. It is 0 for an empty sector, 1 for a - sector in MODE1, and 2 for a sector in MODE2. Easy as hell. - - Ok here we are: we know the basic form of a CD's sector, and even know the - MODE of the sector. Now the datas depends upon the sector mode. Here you have - the various kinds: - - <-------------- MODE 1 FORM 1 Sector datas: 2336 bytes ----------------------> - <- datas: 2048 bytes -><- EDC: 4 bytes -><- 0s: 8 bytes -><- ECC: 276 bytes -> - - <---------- MODE 1 FORM 2 and also MODE 2 Sector datas: 2336 bytes ----------> - <----------------------------- datas: 2336 bytes ----------------------------> - - <-------------- MODE 2 FORM 1 Sector datas: 2336 bytes ----------------------> - <- SH: 8 bytes -><- datas: 2048 bytes -><- EDC: 4 bytes -><- ECC: 276 bytes -> - - <-------------- MODE 2 FORM 2 Sector datas: 2336 bytes ----------------------> - <- SH: 8 bytes -><---------- datas: 2324 bytes ----------><- spare: 4 bytes -> - - Well, I *really* don't know how to distinguish the different "FORMS" from - each others for the MODE 1. Have to look further for this. - - The ECC and EDC controls blocks. The yazedc code can compute them, so - don't worry about them. - - The 'SH' (SubHeader) field is the most "complicated" one. Those eight little - bits are the only one I'm really not sure of. All of that because you have to - buy the Books to find the information. This SubHeader is only found into - MODE_2_FORM_1 and MODE_2_FORM_2 sectors. - - Here you have the informations I've been able to gather: - - -) The SubHeader has 8 bytes, but it's twice the same 4 bytes. - -) The 4 bytes are described using the following fields: - o) 1st byte: File Number (FN) - o) 2nd byte: Channel Number (CN) - o) 3rd byte: Sub Mode (SM) - o) 4st byte: Coding Info (CI) - -) I've *never* seen any SubHeader with a FN, CN or CI different from 0, - please inform me if you do. - -) The Sub Mode byte is a bit field which seems to be described like this: - 0: End of Record (EOR) - 1: Video - 2: Audio - 3: Data - 4: Trigger - 5: Form 2 - 6: Real Time (RT) - 7: End of File (EOF) - - Very last things to know: of course, the PSX has the CDs in MODE 2... So the - common files are stored in MODE 2 FORM 1, the STR/XA files are stored in - MODE 2 and I've never seen any file stored in MODE 2 FORM 2. And the MODE 2 - FORM 1 and MODE 2 FORM 2 are also called XA-Mode1 and XA-Mode2 or simplier: - XA-1 and XA-2. - - I hope this will help you as it helped me writing this software. diff --git a/generic.h b/generic.h index 08fb7eb..2798235 100644 --- a/generic.h +++ b/generic.h @@ -30,6 +30,9 @@ #define bcopy(x,y,z) memcpy((y),(x),(z)) #endif +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)<(b)?(b):(a) + extern char verbosity; void printm(int level, char * fmt, ...); char ** split(char * s, char t); diff --git a/lz77.cpp b/lz77.cpp index 8497868..10423d4 100644 --- a/lz77.cpp +++ b/lz77.cpp @@ -32,18 +32,18 @@ int tolerate = 1; int blockb = 0; scheme_t schemes[] = { -/* Nom 1 I J O N 16 Op F Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 */ - {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Metal Max", 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, - {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0}, - {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0} +/* Nom 1 I J O N 16 P F W Lm1 Ls1 Lm2 Ls2 Jm1 Js1 Jm2 Js2 Fm1 Fs1 Fm2 Fs2 Vm1 Vs1 Vm2 Vs2 */ + {"Xenogears", 1, 0, 0, 1, 0, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"DBZ RPG", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"FF7", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Leen Mean", 1, 1, 1, 1, 0, 0, 0, 0, 0, 0x0f, 0, 0x00, 0, 0xf0, 4, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Metal Max", 0, 0, 0, 1, 0, 0, 2, 0, 0x12, 0x00, 0, 0x0f, 0, 0xff, 0, 0xf0, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Ogre Battle", 0, 0, 0, 1, 0, 0, 1, 0, 0, 0xf8, -3, 0x00, 0, 0x07, 8, 0xff, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Lodoss Wars", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x7f, 0, 0xff, 0, 0x80, 1, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"FF6 PSX", 0, 0, 0, 1, 1, 1, 0, 0, 0, 0x1f, 1, 0x00, 0, 0xe0, -4, 0xff, 4, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Valkyrie-1", 0, 0, 0, 1, 1, 0, 0, 0, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0}, + {"Valkyrie-2", 0, 0, 0, 1, 1, 0, 0, 2, 0, 0x00, 0, 0xf0, -4, 0xff, 0, 0x0f, 8, 0x00, 0, 0x0f, 0, 0xff, 0, 0x00, 0}, + {0 , 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0x00, 0, 0x00, 0, 0x00, 0} }; scheme_t scheme = schemes[0]; @@ -107,7 +107,7 @@ unsigned long lz77_decomp(FILE * f_source, FILE * f_cible, long true_length) int decomp_length; int decomp_fill; int decomp_jump; - int decomp_offset; + int decomp_offset = 0; int loop_length; int whole_count; int i, j; @@ -185,10 +185,16 @@ unsigned long lz77_decomp(FILE * f_source, FILE * f_cible, long true_length) if (blockb) whole_count++; } else { - if (scheme.opposite) { - decomp_offset = r - lz77_maxptr - 1 + decomp_jump; - } else { + switch (scheme.ptrb) { + case 0: decomp_offset = r - decomp_jump; + break; + case 1: + decomp_offset = r - lz77_maxptr - 1 + decomp_jump; + break; + case 2: + decomp_offset = decomp_jump - scheme.window_start; + break; } loop_length = decomp_offset + decomp_length; if ((loop_length >= r) && (!overlap_error)) { @@ -311,6 +317,10 @@ unsigned char * lz77_memcomp(unsigned char * r, long * l, long * delta) { farest = ptr - lz77_maxptr; farest = farest > ((-lz77_maxsize) * scheme.negative_trick) ? farest : -lz77_maxsize * scheme.negative_trick; needle_length = ptr - farest; + if (scheme.ptrb == 2) { + farest = 0; + needle_length = MIN(lz77_maxptr - scheme.window_start, ptr); + } needle = lz77_comp_strstr(&r[ptr], r, &needle_length, farest); if ((needle < 0) && ((-needle) > needle_length)) { needle = -needle_length; @@ -329,7 +339,7 @@ unsigned char * lz77_memcomp(unsigned char * r, long * l, long * delta) { printm(M_INFO, " Found a needle of %i bytes at offset %i (jump = %i = 0x%04x)\n", needle_length, needle, jump, jump); } - if ((needle_length <= (2 + scheme.sixteen_bits)) || (jump > lz77_maxptr) || (!jump)) { + if ((needle_length <= (2 + scheme.sixteen_bits)) || (!jump)) { if (needle_length > 2) { printm(M_ERROR, " ** REJECTED **\n"); } @@ -344,17 +354,24 @@ unsigned char * lz77_memcomp(unsigned char * r, long * l, long * delta) { int j; printm(M_INFO, " Found a needle of %li bytes at %li = 0x%04x\n", needle_length, needle, needle); for (j = 0; j < needle_length; j++) { - printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lz77_rd(r, needle + j), ptr + j, lz77_rd(r, ptr + j)); + printm(M_INFO, "@0x%04x: 0x%02x - @0x%04x: 0x%02x\n", needle + j, lz77_rd(r, needle + j - scheme.window_start), ptr + j, lz77_rd(r, ptr + j)); if (lz77_rd(r, needle + j) != lz77_rd(r, ptr + j)) { printm(M_ERROR, "ERROR!!\n"); } } + jump -= scheme.one_jump; printm(M_INFO, "ptr = %li, needle = %li, jump = %li = 0x%03x\n", ptr, needle, jump, jump); ptr += needle_length; needle_length -= 3; - jump -= scheme.one_jump; - if (scheme.opposite) { + switch (scheme.ptrb) { + case 0: + break; + case 1: jump = lz77_maxptr + 1 - jump; + break; + case 2: + jump = needle + scheme.window_start; + break; } val1 = comp[comp_ptr++] = (shift(jump, -scheme.j_shft_1) & scheme.j_mask_1) | (shift(needle_length, -scheme.l_shft_1) & scheme.l_mask_1); @@ -432,10 +449,11 @@ struct option long_options[] = { {"overlap", 1, &lga, 2 }, {"16bits", 1, &lga, 11 }, {"negative", 1, &lga, 12 }, - {"opposite", 1, &lga, 13 }, + {"ptrb", 1, &lga, 13 }, {"filling", 1, &lga, 14 }, {"inverse", 1, &lga, 23 }, {"onejump", 1, &lga, 24 }, + {"window", 1, &lga, 25 }, {"lmask1", 1, &lga, 3 }, {"lshft1", 1, &lga, 4 }, {"lmask2", 1, &lga, 5 }, @@ -483,7 +501,8 @@ void showhelp(void) { "-b --blocks Switch to blocks decompression behaviour\n" "\n" "Additionnaly you have the scheme manipulation options:\n" -"--1iscomp --overlap --negative --16bits --filling --inverse --onejump\n" +"--1iscomp --overlap --negative --16bits --ptrb\n" +"--filling --inverse --onejump --window\n" "--lmask1 --lshft1 --lmask2 --lshft2 --jmask1 --jshft1 --jmask2 --jshft2\n" "--vmask1 --vshft1 --vmask2 --vshft2 --fmask1 --fshft1 --fmask2 --fshft2\n" "\n" @@ -500,10 +519,11 @@ void showscheme(void) { "--overlap %i\n" "--negative %i\n" "--16bits %i\n" -"--opposite %i\n" +"--ptrb %i\n" "--filling %i\n" "--inverse %i\n" "--onejump %i\n" +"--window %i\n" "--lmask1 0x%02x\n" "--lshft1 %i\n" "--lmask2 0x%02x\n" @@ -521,7 +541,7 @@ void showscheme(void) { "--vmask2 0x%02x\n" "--vshft2 %i\n" "\n", scheme.one_is_compressed, scheme.overlap_trick, scheme.negative_trick, scheme.sixteen_bits, -scheme.opposite, scheme.filling, scheme.bitmap_inversed, scheme.one_jump, +scheme.ptrb, scheme.filling, scheme.bitmap_inversed, scheme.one_jump, scheme.window_start, scheme.l_mask_1, scheme.l_shft_1, scheme.l_mask_2, scheme.l_shft_2, scheme.j_mask_1, scheme.j_shft_1, scheme.j_mask_2, scheme.j_shft_2, scheme.f_mask_1, scheme.f_shft_1, scheme.f_mask_2, scheme.f_shft_2, @@ -560,7 +580,7 @@ LZ77_NAME " compressor/decompressor version " LZ77_VERSION ",\n" "Special thanks to Yazoo, who taught me PSX hacking.\n" "\n"); - while ((c = getopt_long(argc, argv, "Hhs:l:vVScd", long_options, NULL)) != EOF) { + while ((c = getopt_long(argc, argv, "Hhs:l:vVScdb", long_options, NULL)) != EOF) { switch (c) { case 0: switch (lga) { @@ -622,10 +642,10 @@ LZ77_NAME " compressor/decompressor version " LZ77_VERSION ",\n" break; case 13: t = atoi(optarg); - if ((t != 1) && (t != 0)) { - printm(M_ERROR, "Invalid value for boolean: %s\n", optarg); + if ((t != 2) && (t != 1) && (t != 0)) { + printm(M_ERROR, "Invalid value for ter: %s\n", optarg); } else { - scheme.opposite = t; + scheme.ptrb = t; } break; case 14: @@ -676,6 +696,9 @@ LZ77_NAME " compressor/decompressor version " LZ77_VERSION ",\n" scheme.one_jump = t; } break; + case 25: + t = sscanf(optarg, "%i", &scheme.window_start); + break; default: showhelp(); printm(M_ERROR, "Unknow option.\n"); @@ -765,7 +788,7 @@ LZ77_NAME " compressor/decompressor version " LZ77_VERSION ",\n" if (!bitmap_count) bitmap_count = 8; if (compress) - printm(M_STATUS, "Compressed %i = 0x%08x blocs, containing %i = 0x%08x chunks.\n", blk + 1, blk + 1, blk + bitmap_count, blk + bitmap_count); + printm(M_STATUS, "Compressed %i = 0x%08x blocs, containing %i = 0x%08x chunks.\n", blk + 1, blk + 1, blk * 8 + bitmap_count, blk * 8 + bitmap_count); fclose(f1); fclose(f2); diff --git a/lz77.h b/lz77.h index 418578e..34888c5 100644 --- a/lz77.h +++ b/lz77.h @@ -28,7 +28,8 @@ typedef struct { char * name; - int one_is_compressed, bitmap_inversed, one_jump, overlap_trick, negative_trick, sixteen_bits, opposite, filling; + int one_is_compressed, bitmap_inversed, one_jump, overlap_trick, negative_trick, sixteen_bits, ptrb, filling; + int window_start; int l_mask_1, l_shft_1, l_mask_2, l_shft_2; int j_mask_1, j_shft_1, j_mask_2, j_shft_2; int f_mask_1, f_shft_1, f_mask_2, f_shft_2; -- cgit v1.2.3