Link to home
Start Free TrialLog in
Avatar of ThievingSix
ThievingSixFlag for United States of America

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 =)?
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;
}

Open in new window

Avatar of ThievingSix
ThievingSix
Flag of United States of America image

ASKER

Here's the delphi code. If you need any of the declaration or file structures in either code let me know.
function DecompressCISO(FileIn, FileOut: TFileStream): Boolean;
var
  FileSize : Int64;
  Index,
  Index2 : Cardinal;
  ReadPosition,
  ReadSize : Int64;
  TotalSectors : Integer;
  IndexSize : Integer;
  Block : Integer;
  Buffer : Array[0..3] Of Char;
  CmpSize : Integer;
  Status : Integer;
  Plain : Boolean;
  BytesRead : Cardinal;
begin
  FileIn.Position := 0;
  If FileIn.Read(CISO,SizeOf(CISO)) <> SizeOf(CISO) Then
    begin
    Raise Exception.Create('File could not be read.');
    Result := False;
    Exit;
  end;
  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
    Raise Exception.Create('Invalid Header');
    Result := False;
    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.Create('Not Enough Memory');
    Result := False;
    Exit;
  end;
  If FileIn.Read(IndexBuffer[0],IndexSize) <> IndexSize Then
    begin
    Raise Exception.Create('File Could Not Be Read');
    Result := False;
    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('InflateInit2 : %s',[ZStream.msg]);
      Result := False;
      Exit;
    end;
    Index := IndexBuffer[Block];
    Plain := Boolean(Index And $80000000);
    Index := Index And $7FFFFFFF;
    ReadPosition := Index SHL CISO.Align;
    If Plain 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,ReadSize);
    If ZStream.avail_in <> ReadSize Then
      begin
      Raise Exception.CreateFmt('Could not read block number %d',[Block]);
      Result := False;
      Exit;
    end;
    If Plain 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('Block %d - Inflate : %s[%d]',[Block,ZStream.msg,Status]);
        Result := False;
        Exit;
      end;
      CmpSize := CISO.BlockSize - ZStream.avail_out;
      If CmpSize <> CISO.BlockSize Then
        begin
        Raise Exception.CreateFmt('Block %d - Block Size Error %d != %d',[Block,CmpSize,CISO.BlockSize]);
        Result := False;
        Exit;
      end;
    end;
    If FileOut.Write(BlockBuffer1,CmpSize) <> CmpSize Then
      begin
      Raise Exception.CreateFmt('Block %d - Write Error',[Block]);
      Result := False;
      Exit;
    end;
    If InflateEnd(ZStream) <> Z_OK Then
      begin
      Raise Exception.CreateFmt('InflateEnd - %s',[ZStream.msg]);
      Result := False;
      Exit;
    end;
  end;
  Result := True;
end;

Open in new window

Please show the declaration for the CISO and BlockBuffer2 variables.
 I suspect this:
   ZStream.avail_in := FileIn.Read(BlockBuffer2,ReadSize);
should be changed to this:
   ZStream.avail_in := FileIn.Read(BlockBuffer2[0], ReadSize);
 

At which line are you receiving the error?
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.
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;

Open in new window

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;

Open in new window

can you make a sample input file available for download for me to work with?
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.

---------------------------
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   
---------------------------

Open in new window

sorry. I tried finding a small cso file to test with but no luck.
Let me see if I can get one that is legal to upload.
http://filebeam.com/bbdd8f793836d97aaf99d192f33fde84

The cso file is in the zip file. Hope this helps.
downloading...

will look at it tomorrow.
Which version of ZLib are you using?
ZlibEx.pas, which internalizes zlib source 1.2.3.
SOLUTION
Avatar of Pierre Cornelius
Pierre Cornelius
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

/*
	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

Open in new window

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|error: invalid conversion from `void*' to `unsigned int*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|107|error: invalid conversion from `void*' to `unsigned char*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|108|error: invalid conversion from `void*' to `unsigned char*'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|118|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|warning: long int format, different type arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|warning: int format, long unsigned int arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|warning: int format, long unsigned int arg (arg 4)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warning: unused variable 'file_size'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warning: unused variable 'total_sectors'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warning: 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|error: `comp_ciso' undeclared (first use this function)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|426|error: (Each undeclared identifier is reported only once for each function it appears in.)|
||=== 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_size);
      block_buf2 = (unsigned char*)malloc(ciso.block_size*2);
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|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|126|warning: long int format, different type arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|127|warning: int format, long unsigned int arg (arg 2)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|196|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|198|warning: int format, long unsigned int arg (arg 4)|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|203|warning: comparison between signed and unsigned integer expressions|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|68|warning: unused variable 'file_size'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|71|warning: unused variable 'total_sectors'|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|74|warning: unused variable 'buf4'|
obj\Debug\main.o(.text+0x2d3)||In function `Z11decomp_cisov':|
C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|148|undefined reference to `inflateInit2_'|
obj\Debug\main.o(.text+0x479):C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|187|undefined reference to `inflate'|
obj\Debug\main.o(.text+0x564):C:\Delphi\EE\cso file decompression\cpp\cso to iso converter\main.cpp|210|undefined reference to `inflateEnd'|
||=== Build finished: 3 errors, 9 warnings ===|
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
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.

Open in new window

Yip, that fixed it. Thanks for