ThievingSix
asked on
C++ To Delphi Translation Help
Alright, I have some file format conversion code in C++ and gave it my best shot in translating myself. Inflate causes a nice a/v and it's probably because I declared things wrong.
First post will have the C++ code, second post will be my attempt.
Any ideas on where I messed up =)?
First post will have the C++ code, second post will be my attempt.
Any ideas on where I messed up =)?
int decomp_ciso(void)
{
unsigned long long file_size;
unsigned int index , index2;
unsigned long long read_pos , read_size;
int total_sectors;
int index_size;
int block;
unsigned char buf4[4];
int cmp_size;
int status;
int percent_period;
int percent_cnt;
int plain;
// read header
if( fread(&ciso, 1, sizeof(ciso), fin) != sizeof(ciso) )
{
printf("file read error\n");
return 1;
}
// check header
if(
ciso.magic[0] != 'C' ||
ciso.magic[1] != 'I' ||
ciso.magic[2] != 'S' ||
ciso.magic[3] != 'O' ||
ciso.block_size ==0 ||
ciso.total_bytes == 0
)
{
printf("ciso file format error\n");
return 1;
}
//
ciso_total_block = ciso.total_bytes / ciso.block_size;
// allocate index block
index_size = (ciso_total_block + 1 ) * sizeof(unsigned long);
index_buf = malloc(index_size);
block_buf1 = malloc(ciso.block_size);
block_buf2 = malloc(ciso.block_size*2);
if( !index_buf || !block_buf1 || !block_buf2 )
{
printf("Can't allocate memory\n");
return 1;
}
memset(index_buf,0,index_size);
// read index block
if( fread(index_buf, 1, index_size, fin) != index_size )
{
printf("file read error\n");
return 1;
}
// show info
printf("Decompress '%s' to '%s'\n",fname_in,fname_out);
printf("Total File Size %ld bytes\n",ciso.total_bytes);
printf("block size %d bytes\n",ciso.block_size);
printf("total blocks %d blocks\n",ciso_total_block);
printf("index align %d\n",1<<ciso.align);
// init zlib
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
// decompress data
percent_period = ciso_total_block/100;
percent_cnt = 0;
for(block = 0;block < ciso_total_block ; block++)
{
if(--percent_cnt<=0)
{
percent_cnt = percent_period;
printf("decompress %d%%\r",block / percent_period);
}
if (inflateInit2(&z,-15) != Z_OK)
{
printf("deflateInit : %s\n", (z.msg) ? z.msg : "???");
return 1;
}
// check index
index = index_buf[block];
plain = index & 0x80000000;
index &= 0x7fffffff;
read_pos = index << (ciso.align);
if(plain)
{
read_size = ciso.block_size;
}
else
{
index2 = index_buf[block+1] & 0x7fffffff;
read_size = (index2-index) << (ciso.align);
}
fseek(fin,read_pos,SEEK_SET);
z.avail_in = fread(block_buf2, 1, read_size , fin);
if(z.avail_in != read_size)
{
printf("block=%d : read error\n",block);
return 1;
}
if(plain)
{
memcpy(block_buf1,block_buf2,read_size);
cmp_size = read_size;
}
else
{
z.next_out = block_buf1;
z.avail_out = ciso.block_size;
z.next_in = block_buf2;
status = inflate(&z, Z_FULL_FLUSH);
if (status != Z_STREAM_END)
//if (status != Z_OK)
{
printf("block %d:inflate : %s[%d]\n", block,(z.msg) ? z.msg : "error",status);
return 1;
}
cmp_size = ciso.block_size - z.avail_out;
if(cmp_size != ciso.block_size)
{
printf("block %d : block size error %d != %d\n",block,cmp_size , ciso.block_size);
return 1;
}
}
// write decompressed block
if(fwrite(block_buf1, 1,cmp_size , fout) != cmp_size)
{
printf("block %d : Write error\n",block);
return 1;
}
// term zlib
if (inflateEnd(&z) != Z_OK)
{
printf("inflateEnd : %s\n", (z.msg) ? z.msg : "error");
return 1;
}
}
printf("ciso decompress completed\n");
return 0;
}
Please show the declaration for the CISO and BlockBuffer2 variables.
I suspect this:
ZStream.avail_in := FileIn.Read(BlockBuffer2,R eadSize);
should be changed to this:
ZStream.avail_in := FileIn.Read(BlockBuffer2[0 ], ReadSize);
At which line are you receiving the error?
I suspect this:
ZStream.avail_in := FileIn.Read(BlockBuffer2,R
should be changed to this:
ZStream.avail_in := FileIn.Read(BlockBuffer2[0
At which line are you receiving the error?
ASKER
Below are the declarations to which you requested.
Everything seems to go fine until this:
If Plain Then
begin
ReadSize := CISO.BlockSize;
end
Else
begin
Index2 := IndexBuffer[Block + 1] And $7FFFFFFF;
ReadSize := (Index2 - Index) SHL CISO.Align;
end;
Since Plain is false Readsize goes down to 17 bytes instead of a much bigger number. The error comes from the Inflate call. I'll try your suggestion.
Everything seems to go fine until this:
If Plain Then
begin
ReadSize := CISO.BlockSize;
end
Else
begin
Index2 := IndexBuffer[Block + 1] And $7FFFFFFF;
ReadSize := (Index2 - Index) SHL CISO.Align;
end;
Since Plain is false Readsize goes down to 17 bytes instead of a much bigger number. The error comes from the Inflate call. I'll try your suggestion.
type
PCISOHeader = ^TCISOHeader;
TCISOHeader = packed record
Magic : Array[0..3] Of Char; // +00 : 'C','I','S','O'
HeaderSize : Cardinal; // +04 : Header Size(18 Bytes)
TotalBytes : Int64; // +08 : Uncompressed Size
BlockSize : Integer; // +16 : Size Of Compression Blocks
Version : Byte; // +20 : File Format Version($01)
Align : Byte; // +21 : Index Align Value
Reserved : Array[0..1] Of Char; // +22 : Reserved
end;
var
ZStream : TZStreamRec;
IndexBuffer : Array Of Cardinal;
CRCBuffer : PDWORD = nil;
BlockBuffer1 : PChar = nil;
BlockBuffer2 : PChar = nil;
CISO : TCISOHeader;
CISOTotalBlocks : Integer;
ASKER
Declarations in the C++ code below. I'm getting a data error from zlib now. Probably because of the block buffers declaration.
unsigned int *index_buf = NULL;
unsigned int *crc_buf = NULL;
unsigned char *block_buf1 = NULL;
unsigned char *block_buf2 = NULL;
typedef struct ciso_header
{
unsigned char magic[4]; /* +00 : 'C','I','S','O' */
unsigned long header_size; /* +04 : header size (==0x18) */
unsigned long long total_bytes; /* +08 : number of original data size */
unsigned long block_size; /* +10 : number of compressed block size */
unsigned char ver; /* +14 : version 01 */
unsigned char align; /* +15 : align of index value */
unsigned char rsv_06[2]; /* +16 : reserved */
#if 0
// INDEX BLOCK
unsigned int index[0]; /* +18 : block[0] index */
unsigned int index[1]; /* +1C : block[1] index */
:
:
unsigned int index[last]; /* +?? : block[last] */
unsigned int index[last+1]; /* +?? : end of last data point */
// DATA BLOCK
unsigned char data[]; /* +?? : compressed or plain sector data */
#endif
}CISO_H;
can you make a sample input file available for download for me to work with?
ASKER
Well, I just wrote up a sample and it worked fine for some reason...But when I use an actual file(Which is technically illegal for me to upload, if you need one grab a PSP game thats already in cso format) I get a data error for some reason.
ASKER
---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class Exception with message 'Block 65 - Inflate : invalid distance too far back[-3]'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------
sorry. I tried finding a small cso file to test with but no luck.
ASKER
Let me see if I can get one that is legal to upload.
ASKER
http://filebeam.com/bbdd8f793836d97aaf99d192f33fde84
The cso file is in the zip file. Hope this helps.
The cso file is in the zip file. Hope this helps.
downloading...
will look at it tomorrow.
will look at it tomorrow.
Which version of ZLib are you using?
ASKER
ZlibEx.pas, which internalizes zlib source 1.2.3.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Same error I got, yet with the c++ code I don't get it. Weird. I'll try debugging both at the same time and see what exactly happens.
It seems to happen when read_size = 2048
Can you give me the C++ code you are testing with pls, so I can also have a look
ASKER
/*
Compressed ISO9660 conveter by BOOSTER
*/
#include <stdio.h>
#include <stdlib.h>
#include <zlib.h> /* /usr(/local)/include/zlib.h */
#include "stdafx.h"
#include "ciso.h"
const char *fname_in,*fname_out;
FILE *fin,*fout;
z_stream z;
unsigned int *index_buf = NULL;
unsigned int *crc_buf = NULL;
unsigned char *block_buf1 = NULL;
unsigned char *block_buf2 = NULL;
/****************************************************************************
compress ISO to CSO
****************************************************************************/
CISO_H ciso;
int ciso_total_block;
unsigned long long check_file_size(FILE *fp)
{
unsigned long long pos;
if( fseek(fp,0,SEEK_END) < 0)
return -1;
pos = ftell(fp);
if(pos==-1) return pos;
// init ciso header
memset(&ciso,0,sizeof(ciso));
ciso.magic[0] = 'C';
ciso.magic[1] = 'I';
ciso.magic[2] = 'S';
ciso.magic[3] = 'O';
ciso.ver = 0x01;
ciso.block_size = 0x800; /* ISO9660 one of sector */
ciso.total_bytes = pos;
#if 0
/* align >0 has bug */
for(ciso.align = 0 ; (ciso.total_bytes >> ciso.align) >0x80000000LL ; ciso.align++);
#endif
ciso_total_block = pos / ciso.block_size ;
fseek(fp,0,SEEK_SET);
return pos;
}
/****************************************************************************
decompress CSO to ISO
****************************************************************************/
int decomp_ciso(void)
{
unsigned long long file_size;
unsigned int index , index2;
unsigned long long read_pos , read_size;
int total_sectors;
int index_size;
int block;
unsigned char buf4[4];
int cmp_size;
int status;
int percent_period;
int percent_cnt;
int plain;
// read header
if( fread(&ciso, 1, sizeof(ciso), fin) != sizeof(ciso) )
{
printf("file read error\n");
return 1;
}
// check header
if(
ciso.magic[0] != 'C' ||
ciso.magic[1] != 'I' ||
ciso.magic[2] != 'S' ||
ciso.magic[3] != 'O' ||
ciso.block_size ==0 ||
ciso.total_bytes == 0
)
{
printf("ciso file format error\n");
return 1;
}
//
ciso_total_block = ciso.total_bytes / ciso.block_size;
// allocate index block
index_size = (ciso_total_block + 1 ) * sizeof(unsigned long);
index_buf = malloc(index_size);
block_buf1 = malloc(ciso.block_size);
block_buf2 = malloc(ciso.block_size*2);
if( !index_buf || !block_buf1 || !block_buf2 )
{
printf("Can't allocate memory\n");
return 1;
}
memset(index_buf,0,index_size);
// read index block
if( fread(index_buf, 1, index_size, fin) != index_size )
{
printf("file read error\n");
return 1;
}
// show info
printf("Decompress '%s' to '%s'\n",fname_in,fname_out);
printf("Total File Size %ld bytes\n",ciso.total_bytes);
printf("block size %d bytes\n",ciso.block_size);
printf("total blocks %d blocks\n",ciso_total_block);
printf("index align %d\n",1<<ciso.align);
// init zlib
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
// decompress data
percent_period = ciso_total_block/100;
percent_cnt = 0;
for(block = 0;block < ciso_total_block ; block++)
{
if(--percent_cnt<=0)
{
percent_cnt = percent_period;
printf("decompress %d%%\r",block / percent_period);
}
if (inflateInit2(&z,-15) != Z_OK)
{
printf("deflateInit : %s\n", (z.msg) ? z.msg : "???");
return 1;
}
// check index
index = index_buf[block];
plain = index & 0x80000000;
index &= 0x7fffffff;
read_pos = index << (ciso.align);
if(plain)
{
read_size = ciso.block_size;
}
else
{
index2 = index_buf[block+1] & 0x7fffffff;
read_size = (index2-index) << (ciso.align);
}
fseek(fin,read_pos,SEEK_SET);
z.avail_in = fread(block_buf2, 1, read_size , fin);
if(z.avail_in != read_size)
{
printf("block=%d : read error\n",block);
return 1;
}
if(plain)
{
memcpy(block_buf1,block_buf2,read_size);
cmp_size = read_size;
}
else
{
z.next_out = block_buf1;
z.avail_out = ciso.block_size;
z.next_in = block_buf2;
status = inflate(&z, Z_FULL_FLUSH);
if (status != Z_STREAM_END)
//if (status != Z_OK)
{
printf("block %d:inflate : %s[%d]\n", block,(z.msg) ? z.msg : "error",status);
return 1;
}
cmp_size = ciso.block_size - z.avail_out;
if(cmp_size != ciso.block_size)
{
printf("block %d : block size error %d != %d\n",block,cmp_size , ciso.block_size);
return 1;
}
}
// write decompressed block
if(fwrite(block_buf1, 1,cmp_size , fout) != cmp_size)
{
printf("block %d : Write error\n",block);
return 1;
}
// term zlib
if (inflateEnd(&z) != Z_OK)
{
printf("inflateEnd : %s\n", (z.msg) ? z.msg : "error");
return 1;
}
}
printf("ciso decompress completed\n");
return 0;
}
/****************************************************************************
compress ISO
****************************************************************************/
int comp_ciso(int level)
{
unsigned long long file_size;
unsigned long long write_pos;
int total_sectors;
int index_size;
int block;
unsigned char buf4[64];
int cmp_size;
int status;
int percent_period;
int percent_cnt;
int align,align_b,align_m;
file_size = check_file_size(fin);
if(file_size<0)
{
printf("Can't get file size\n");
return 1;
}
// allocate index block
index_size = (ciso_total_block + 1 ) * sizeof(unsigned long);
index_buf = malloc(index_size);
crc_buf = malloc(index_size);
block_buf1 = malloc(ciso.block_size);
block_buf2 = malloc(ciso.block_size*2);
if( !index_buf || !crc_buf || !block_buf1 || !block_buf2 )
{
printf("Can't allocate memory\n");
return 1;
}
memset(index_buf,0,index_size);
memset(crc_buf,0,index_size);
memset(buf4,0,sizeof(buf4));
// init zlib
z.zalloc = Z_NULL;
z.zfree = Z_NULL;
z.opaque = Z_NULL;
// show info
printf("Compress '%s' to '%s'\n",fname_in,fname_out);
printf("Total File Size %ld bytes\n",ciso.total_bytes);
printf("block size %d bytes\n",ciso.block_size);
printf("index align %d\n",1<<ciso.align);
printf("compress level %d\n",level);
// write header block
fwrite(&ciso,1,sizeof(ciso),fout);
// dummy write index block
fwrite(index_buf,1,index_size,fout);
write_pos = sizeof(ciso) + index_size;
// compress data
percent_period = ciso_total_block/100;
percent_cnt = ciso_total_block/100;
align_b = 1<<(ciso.align);
align_m = align_b -1;
for(block = 0;block < ciso_total_block ; block++)
{
if(--percent_cnt<=0)
{
percent_cnt = percent_period;
printf("compress %3d%% avarage rate %3d%%\r"
,block / percent_period
,block==0 ? 0 : (int)(write_pos*1.0)/(block*0x800)*100);
}
if (deflateInit2(&z, level , Z_DEFLATED, -15,8,Z_DEFAULT_STRATEGY) != Z_OK)
{
printf("deflateInit : %s\n", (z.msg) ? z.msg : "???");
return 1;
}
// write align
align = (int)write_pos & align_m;
if(align)
{
align = align_b - align;
if(fwrite(buf4,1,align, fout) != align)
{
printf("block %d : Write error\n",block);
return 1;
}
write_pos += align;
}
// mark offset index
index_buf[block] = write_pos>>(ciso.align);
// read buffer
z.next_out = block_buf2;
z.avail_out = ciso.block_size*2;
z.next_in = block_buf1;
z.avail_in = fread(block_buf1, 1, ciso.block_size , fin);
if(z.avail_in != ciso.block_size)
{
printf("block=%d : read error\n",block);
return 1;
}
// compress block
// status = deflate(&z, Z_FULL_FLUSH);
status = deflate(&z, Z_FINISH);
if (status != Z_STREAM_END)
// if (status != Z_OK)
{
printf("block %d:deflate : %s[%d]\n", block,(z.msg) ? z.msg : "error",status);
return 1;
}
cmp_size = ciso.block_size*2 - z.avail_out;
// choise plain / compress
if(cmp_size >= ciso.block_size)
{
cmp_size = ciso.block_size;
memcpy(block_buf2,block_buf1,cmp_size);
// plain block mark
index_buf[block] |= 0x80000000;
}
// write compressed block
if(fwrite(block_buf2, 1,cmp_size , fout) != cmp_size)
{
printf("block %d : Write error\n",block);
return 1;
}
// mark next index
write_pos += cmp_size;
// term zlib
if (deflateEnd(&z) != Z_OK)
{
printf("deflateEnd : %s\n", (z.msg) ? z.msg : "error");
return 1;
}
}
// last position (total size)
index_buf[block] = write_pos>>(ciso.align);
// write header & index block
fseek(fout,sizeof(ciso),SEEK_SET);
fwrite(index_buf,1,index_size,fout);
printf("ciso compress completed , total size = %8d bytes , rate %d%%\n"
,(int)write_pos,(int)(write_pos*100/ciso.total_bytes));
return 0;
}
/****************************************************************************
main
****************************************************************************/
int main(int argc, char *argv[])
{
int level;
int result;
fprintf(stderr, "Compressed ISO9660 converter Ver.1.01 by BOOSTER\n");
if (argc != 4)
{
printf("Usage: ciso level infile outfile\n");
printf(" level: 1-9 compress ISO to CSO (1=fast/large - 9=small/slow\n");
printf(" 0 decompress CSO to ISO\n");
return 0;
}
level = argv[1][0] - '0';
if(level < 0 || level > 9)
{
printf("Unknown mode: %c\n", argv[1][0]);
return 1;
}
fname_in = argv[2];
fname_out = argv[3];
if ((fin = fopen(fname_in, "rb")) == NULL)
{
printf("Can't open %s\n", fname_in);
return 1;
}
if ((fout = fopen(fname_out, "wb")) == NULL)
{
printf("Can't create %s\n", fname_out);
return 1;
}
if(level==0)
result = decomp_ciso();
else
result = comp_ciso(level);
// free memory
if(index_buf) free(index_buf);
if(crc_buf) free(crc_buf);
if(block_buf1) free(block_buf1);
if(block_buf2) free(block_buf2);
// close files
fclose(fin);
fclose(fout);
return result;
}
#ifndef __CISO_H__
#define __CISO_H__
/*
compressed ISO(9660) header format
*/
typedef struct ciso_header
{
unsigned char magic[4]; /* +00 : 'C','I','S','O' */
unsigned long header_size; /* +04 : header size (==0x18) */
unsigned long long total_bytes; /* +08 : number of original data size */
unsigned long block_size; /* +10 : number of compressed block size */
unsigned char ver; /* +14 : version 01 */
unsigned char align; /* +15 : align of index value */
unsigned char rsv_06[2]; /* +16 : reserved */
#if 0
// INDEX BLOCK
unsigned int index[0]; /* +18 : block[0] index */
unsigned int index[1]; /* +1C : block[1] index */
:
:
unsigned int index[last]; /* +?? : block[last] */
unsigned int index[last+1]; /* +?? : end of last data point */
// DATA BLOCK
unsigned char data[]; /* +?? : compressed or plain sector data */
#endif
}CISO_H;
/*
note:
file_pos_sector[n] = (index[n]&0x7fffffff) << CISO_H.align
file_size_sector[n] = ( (index[n+1]&0x7fffffff) << CISO_H.align) - file_pos_sector[n]
if(index[n]&0x80000000)
// read 0x800 without compress
else
// read file_size_sector[n] bytes and decompress data
*/
#endif
I'm a delphi programmer just learning C++. I can't get your e.g. to run. You sound proficient in C++, maybe you can steer me in the right direction? I use CodeBlocks and get the following errors:
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int decomp_ciso()':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|106|err or: invalid conversion from `void*' to `unsigned int*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|107|err or: invalid conversion from `void*' to `unsigned char*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|108|err or: invalid conversion from `void*' to `unsigned char*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|118|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|war ning: long int format, different type arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|war ning: int format, long unsigned int arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|war ning: int format, long unsigned int arg (arg 4)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warn ing: unused variable 'file_size'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warn ing: unused variable 'total_sectors'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warn ing: unused variable 'buf4'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int main(int, char**)':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|426|err or: `comp_ciso' undeclared (first use this function)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|426|err or: (Each undeclared identifier is reported only once for each function it appears in.)|
||=== Build finished: 5 errors, 9 warnings ===|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int decomp_ciso()':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|106|err
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|107|err
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|108|err
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|118|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warn
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warn
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warn
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int main(int, char**)':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|426|err
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|426|err
||=== Build finished: 5 errors, 9 warnings ===|
The following typecasting got rid of some errors:
index_buf = (unsigned int*) malloc(index_size);
block_buf1 = (unsigned char*)malloc(ciso.block_si ze);
block_buf2 = (unsigned char*)malloc(ciso.block_si ze*2);
index_buf = (unsigned int*) malloc(index_size);
block_buf1 = (unsigned char*)malloc(ciso.block_si
block_buf2 = (unsigned char*)malloc(ciso.block_si
almost have it working. Only have to sort out these now:
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int decomp_ciso()':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|118|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|war ning: long int format, different type arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|war ning: int format, long unsigned int arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|war ning: int format, long unsigned int arg (arg 4)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|war ning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warn ing: unused variable 'file_size'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warn ing: unused variable 'total_sectors'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warn ing: unused variable 'buf4'|
obj\Debug\main.o(.text+0x2 d3)||In function `Z11decomp_cisov':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|148|und efined reference to `inflateInit2_'|
obj\Debug\main.o(.text+0x4 79):C:\Del phi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|187|und efined reference to `inflate'|
obj\Debug\main.o(.text+0x5 64):C:\Del phi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|210|und efined reference to `inflateEnd'|
||=== Build finished: 3 errors, 9 warnings ===|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp||In function `int decomp_ciso()':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|118|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|war
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warn
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warn
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warn
obj\Debug\main.o(.text+0x2
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|148|und
obj\Debug\main.o(.text+0x4
obj\Debug\main.o(.text+0x5
||=== Build finished: 3 errors, 9 warnings ===|
ASKER
A file has been uploaded to EE-Stuff.com
Uploaded by : ThievingSix
Filename : CISO.zip
Size : 959,708 bytes
Comment : Here is my c++ version. Just ran and tested with ciso.
You can download this file from https://filedb.experts-exchange.com/incoming/ee-stuff/7326-CISO.zip
If other files are available for this question, then they can be accessed from https://filedb.experts-exchange.com/incoming/ee-stuff/7326-CISO.zip
Uploaded by : ThievingSix
Filename : CISO.zip
Size : 959,708 bytes
Comment : Here is my c++ version. Just ran and tested with ciso.
You can download this file from https://filedb.experts-exchange.com/incoming/ee-stuff/7326-CISO.zip
If other files are available for this question, then they can be accessed from https://filedb.experts-exchange.com/incoming/ee-stuff/7326-CISO.zip
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Alright, just for good purpose if anyone comes to stumble upon this subject(Which I highly doubt) here is my finished code. Good for compressing and decompressing cso >> iso and vise-versa.
unit uCISO;
interface
uses
Windows,
Math,
ZLibEx,
SysUtils,
Classes;
type
PCISOHeader = ^TCISOHeader;
TCISOHeader = packed record
Magic : Array[0..3] Of Char; // +00 : 'C','I','S','O'
HeaderSize : Cardinal; // +04 : Header Size(18 Bytes)
TotalBytes : Int64; // +08 : Uncompressed Size
BlockSize : Integer; // +16 : Size Of Compression Blocks
Version : Byte; // +20 : File Format Version($01)
Align : Byte; // +21 : Index Align Value
Reserved : Array[0..1] Of Char; // +22 : Reserved
end;
function DecompressCISO(FileIn, FileOut: TFileStream): Boolean;
function CompressCISO(FileIn, FileOut: TFileStream; Level: Integer = 1): Boolean;
const
INVALID_FILE = $1000;
INVALID_HEADER = $1001;
NOT_ENOUGH_MEMORY = $1002;
INFLATEINIT_ERROR = $1003;
INVALID_BLOCK_READ = $1004;
INFLATE_ERROR = $1005;
INVALID_BLOCK_SIZE = $1006;
INFLATE_END_ERROR = $1007;
DEFLATEINIT_ERROR = $1008;
DEFLATE_ERROR = $1009;
DEFLATE_END_ERROR = $100A;
var
iBlockSize : Integer = 2048;
implementation
function InitializeHeader(Input: TFileStream; var CISOTotalBlocks: Integer): TCISOHeader;
var
Position : Int64;
begin
FillChar(Result,SizeOf(Result),0);
Position := Input.Size;
If Position < 0 Then
begin
Exit;
end;
With Result Do
begin
Magic[0] := 'C';
Magic[1] := 'I';
Magic[2] := 'S';
Magic[3] := 'O';
Version := $01;
BlockSize := iBlockSize;
TotalBytes := Position;
end;
CISOTotalBlocks := Ceil(Position / Result.BlockSize);
Input.Position := 0;
end;
function VerifyHeader(CISO: TCISOHeader): Boolean;
begin
Result := True;
If (CISO.Magic[0] <> 'C') Or
(CISO.Magic[1] <> 'I') Or
(CISO.Magic[2] <> 'S') Or
(CISO.Magic[3] <> 'O') Or
(CISO.BlockSize = 0) Or
(CISO.TotalBytes = 0) Then
begin
Result := False;
end;
end;
function DecompressCISO(FileIn, FileOut: TFileStream): Boolean;
var
Index,
Index2 : Cardinal;
ReadPosition,
ReadSize : Int64;
IndexSize : Integer;
Block : Integer;
CmpSize : Integer;
Status : Integer;
Plain : Integer;
CISO : TCISOHeader;
BlockBuffer1 : PChar;
BlockBuffer2 : PChar;
CISOTotalBlocks : Integer;
ZStream : TZStreamRec;
IndexBuffer : Array Of Cardinal;
begin
Result := False;
FileIn.Position := 0;
If FileIn.Read(CISO,SizeOf(CISO)) <> SizeOf(CISO) Then
begin
Raise Exception.CreateFmt('%d',[INVALID_FILE]);
Exit;
end;
If Not(VerifyHeader(CISO)) Then
begin
Raise Exception.CreateFmt('%d',[INVALID_HEADER]);
Exit;
end;
CISOTotalBlocks := Ceil(CISO.TotalBytes / CISO.BlockSize);
IndexSize := (CISOTotalBlocks + 1) * SizeOf(Cardinal);
SetLength(IndexBuffer,CISOTotalBlocks + 1);
BlockBuffer1 := AllocMem(CISO.BlockSize);
BlockBuffer2 := AllocMem(CISO.BlockSize * 2);
If (IndexBuffer = nil) Or (BlockBuffer1 = nil) Or (BlockBuffer2 = nil) Then
begin
Raise Exception.CreateFmt('%d',[NOT_ENOUGH_MEMORY]);
Exit;
end;
If FileIn.Read(IndexBuffer[0],IndexSize) <> IndexSize Then
begin
Raise Exception.CreateFmt('%d',[INVALID_FILE]);
Exit;
end;
ZStream.zalloc := nil;
ZStream.zfree := nil;
ZStream.opaque := nil;
For Block := 0 To CISOTotalBlocks - 1 Do
begin
If InflateInit2(ZStream,-15) <> Z_OK Then
begin
Raise Exception.CreateFmt('%d:%s',[INFLATEINIT_ERROR,ZStream.msg]);
Exit;
end;
Index := IndexBuffer[Block];
Plain := Index And $80000000;
Index := Index And $7FFFFFFF;
ReadPosition := Index SHL CISO.Align;
If Plain <> 0 Then
begin
ReadSize := CISO.BlockSize;
end
Else
begin
Index2 := IndexBuffer[Block + 1] And $7FFFFFFF;
ReadSize := (Index2 - Index) SHL CISO.Align;
end;
FileIn.Position := ReadPosition;
ZStream.avail_in := FileIn.Read(BlockBuffer2[0],ReadSize);
If ZStream.avail_in <> ReadSize Then
begin
Raise Exception.CreateFmt('%d:%d',[INVALID_BLOCK_READ,Block]);
Exit;
end;
If Plain <> 0 Then
begin
CopyMemory(BlockBuffer1,BlockBuffer2,ReadSize);
CmpSize := ReadSize;
end
Else
begin
ZStream.next_out := BlockBuffer1;
ZStream.avail_out := CISO.BlockSize;
ZStream.next_in := BlockBuffer2;
Status := Inflate(ZStream,Z_FULL_FLUSH);
If Status <> Z_STREAM_END Then
begin
Raise Exception.CreateFmt('%d:%d:%s',[INFLATE_ERROR,Block,ZStream.msg]);
Exit;
end;
CmpSize := CISO.BlockSize - ZStream.avail_out;
If CmpSize <> CISO.BlockSize Then
begin
Raise Exception.CreateFmt('%d:%d:%d:%d',[INVALID_BLOCK_SIZE,Block,CmpSize,CISO.BlockSize]);
Exit;
end;
end;
If FileOut.Write(BlockBuffer1[0],CmpSize) <> CmpSize Then
begin
Raise Exception.CreateFmt('%d:%d',[INVALID_FILE,Block]);
Exit;
end;
If InflateEnd(ZStream) <> Z_OK Then
begin
Raise Exception.CreateFmt('%d:%s',[INFLATE_END_ERROR,ZStream.msg]);
Exit;
end;
end;
Result := True;
end;
function CompressCISO(FileIn, FileOut: TFileStream; Level: Integer = 1): Boolean;
var
CISO : TCISOHeader;
FileSize : Int64;
WritePos : Int64;
TotalSectors : Integer;
IndexSize : Integer;
Block : Integer;
Buffer : Array[0..63] Of Char;
CmpSize : Integer;
Status : Integer;
CISOTotalBlocks : Integer;
IndexBuffer : Array Of Cardinal;
CRCBuffer : Array Of Cardinal;
BlockBuffer1 : PChar;
BlockBuffer2 : PChar;
ZStream : TZStreamRec;
Align,
AlignB,
AlignM : Integer;
begin
Result := False;
CISO := InitializeHeader(FileIn,CISOTotalBlocks);
FileSize := CISO.TotalBytes;
If FileSize < 0 Then
begin
Raise Exception.CreateFmt('%d',[INVALID_FILE]);
Exit;
end;
IndexSize := (CISOTotalBlocks + 1) * SizeOf(Cardinal);
SetLength(IndexBuffer,IndexSize);
SetLength(CRCBuffer,IndexSize);
BlockBuffer1 := AllocMem(CISO.BlockSize);
BlockBuffer2 := AllocMem(CISO.BlockSize * 2);
If (IndexBuffer = nil) Or (CRCBuffer = nil) Or(BlockBuffer1 = nil) Or (BlockBuffer2 = nil) Then
begin
Raise Exception.CreateFmt('%d',[NOT_ENOUGH_MEMORY]);
Exit;
end;
FillChar(Buffer,SizeOf(Buffer),0);
ZStream.zalloc := nil;
ZStream.zfree := nil;
ZStream.opaque := nil;
FileOut.Write(CISO,SizeOf(CISO));
FileOut.Write(IndexBuffer[0],IndexSize);
WritePos := SizeOf(CISO) + IndexSize;
AlignB := 1 SHL CISO.Align;
AlignM := AlignB - 1;
For Block := 0 To CISOTotalBlocks - 1 Do
begin
If DeflateInit2(ZStream,Level,Z_DEFLATED,-15,8,Z_DEFAULT_STRATEGY) <> Z_OK Then
begin
Raise Exception.CreateFmt('%d:%s',[DEFLATEINIT_ERROR,ZStream.msg]);
Exit;
end;
Align := WritePos And AlignM;
If Align <> 0 Then
begin
Align := AlignB - Align;
If FileOut.Write(Buffer[0],Align) <> Align Then
begin
Raise Exception.CreateFmt('%d',[INVALID_FILE]);
Exit;
end;
Inc(WritePos,Align);
end;
IndexBuffer[Block] := WritePos SHR CISO.Align;
ZStream.next_out := BlockBuffer2;
ZStream.avail_out := CISO.BlockSize * 2;
ZStream.next_in := BlockBuffer1;
ZStream.avail_in := FileIn.Read(BlockBuffer1[0],CISO.BlockSize);
If ZStream.avail_in <> CISO.BlockSize Then
begin
Raise Exception.CreateFmt('%d:%d',[INVALID_FILE,Block]);
Exit;
end;
Status := Deflate(ZStream,Z_FINISH);
If Status <> Z_STREAM_END Then
begin
Raise Exception.CreateFmt('%d:%d:%s',[DEFLATE_ERROR,Block,ZStream.msg]);
Exit;
end;
CmpSize := (CISO.BlockSize * 2) - ZStream.avail_out;
If CmpSize >= CISO.BlockSize Then
begin
CmpSize := CISO.BlockSize;
CopyMemory(BlockBuffer2,BlockBuffer1,CmpSize);
IndexBuffer[Block] := IndexBuffer[Block] Or $80000000;
end;
If FileOut.Write(BlockBuffer2[0],CmpSize) <> CmpSize Then
begin
Raise Exception.CreateFmt('%d:%d',[INVALID_FILE,Block]);
Exit;
end;
Inc(WritePos,CmpSize);
If DeflateEnd(ZStream) <> Z_OK Then
begin
Raise Exception.CreateFmt('%d:%s',[DEFLATE_END_ERROR,ZStream.msg]);
Exit;
end;
end;
IndexBuffer[Block] := WritePos SHR CISO.Align;
FileOut.Position := SizeOf(CISO);
FileOut.Write(IndexBuffer[0],IndexSize);
Result := True;
end;
end.
Yip, that fixed it. Thanks for
ASKER
Open in new window