Tech or Treat! Write an article about your scariest tech disaster to win gadgets!Learn more

x
?
Solved

C++ To Delphi Translation Help

Posted on 2008-10-05
25
Medium Priority
?
744 Views
Last Modified: 2016-08-29
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

0
Comment
Question by:ThievingSix
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 13
  • 12
25 Comments
 
LVL 13

Author Comment

by:ThievingSix
ID: 22647076
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

0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22647561
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?
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22647594
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

0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 13

Author Comment

by:ThievingSix
ID: 22647622
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

0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22648062
can you make a sample input file available for download for me to work with?
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22654424
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.
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22654594

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

0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22657259
sorry. I tried finding a small cso file to test with but no luck.
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22663113
Let me see if I can get one that is legal to upload.
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22663197
http://filebeam.com/bbdd8f793836d97aaf99d192f33fde84

The cso file is in the zip file. Hope this helps.
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22664456
downloading...

will look at it tomorrow.
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22667414
Which version of ZLib are you using?
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22667492
ZlibEx.pas, which internalizes zlib source 1.2.3.
0
 
LVL 14

Assisted Solution

by:Pierre Cornelius
Pierre Cornelius earned 2000 total points
ID: 22668000
cool, same here.

I have converted the code and it seems to work just fine but I get a "invalid stored block length" error. perhaps the sample I downloaded has an error in it??? here it is:

procedure DecompressCSO(InputFile, OutputFile: string);
var
  //unsigned long long file_size;
  index, index2: UINT;
  read_pos, read_size: UInt64;
  //int total_sectors;
  index_size: UINT;
  block: integer;
  //unsigned char buf4[4];
  cmp_size: UINT;
  status: integer;
  percent_period: integer;
  percent_cnt: integer;
  plain: boolean;
  ciso: TCISOHeader;
  z: TZStreamRec;
  fin, fout: TFileStream;
  m_Progress: integer;
  m_CompressionRate: integer;
  index_buf: array of ULONG;
  block_buf1: array of char;
  block_buf2: array of char;
  ciso_total_block: integer;


begin
  if NOT FileExists(InputFile) then
    raise exception.Create('File not found: '+ InputFile);

  if FileExists(OutputFile) then
    if MessageDlg(Format('File exists: %s'#13#13'Overwrite?', [OutputFile]),
                  mtWarning, mbOKCancel, 0)
      <> mrOK then exit;

  fin:= TFileStream.Create(InputFile, fmOpenRead or fmShareDenyWrite);
  fout:= TFileStream.Create(OutputFile, fmCreate);
  try
    m_Progress:= 0;
    m_CompressionRate:= 0;

    // read header
    fin.ReadBuffer(ciso, SizeOf(TCISOHeader));
    // check header
    if(
       (ciso.magic[0] <> 'C') or
       (ciso.magic[1] <> 'I') or
       (ciso.magic[2] <> 'S') or
       (ciso.magic[3] <> 'O') or
       (ciso.block_size = 0)  or
       (ciso.total_bytes = 0)
      )
      then raise exception.Create('ciso file format error');

    ciso_total_block := ciso.total_bytes div ciso.block_size;

    // allocate index block
    index_size:= (ciso_total_block + 1 ) * sizeof(ULONG);
    SetLength(index_buf, index_size);
    FillChar(index_buf[0], 0, SizeOf(UINT));
    SetLength(block_buf1, ciso.block_size);
    SetLength(block_buf2, ciso.block_size*2);

   // read index block
   fin.ReadBuffer(index_buf[0], index_size);

   // init zlib
   z.zalloc := nil;
   z.zfree  := nil;
   //z.opaque := nil; //not in Borland ZLib unit. must be implemented after version 1.0.4

   // decompress data
   percent_period := round(ciso_total_block/100);
   percent_cnt    := 0;

   for block:= 0 to ciso_total_block-1 do
   begin
     if(percent_cnt-1<=0) then
     begin
       percent_cnt := percent_period;
       m_Progress  := round(block / percent_period);
     end;

     if (inflateInit2(z,-15) <> Z_OK) then
       raise exception.Create('inflateInit : ' + z.msg);

     // check index
     index    := index_buf[block];
     plain    := boolean(index AND $80000000);
     index    := index AND $7fffffff;
     read_pos := index SHL ciso.align;
     if plain
       then read_size := ciso.block_size
       else begin
         index2     := index_buf[block+1] AND $7fffffff;
         read_size  := (index2-index) SHL (ciso.align);
       end;

     fin.Seek(read_pos, soFromBeginning);

     z.avail_in:= fin.Read(block_buf2[0], read_size);
     if (z.avail_in <> read_size) then
       raise exception.Create('Block read error at block: ' + IntToStr(block));


     if plain then
     begin
       move(block_buf2, block_buf1, read_size); //memcpy(block_buf1, block_buf2, read_size);
       cmp_size := read_size;
     end
     else begin
       z.next_out  := @block_buf1[0];
       z.avail_out := ciso.block_size;
       z.next_in   := @block_buf2[0];
       status      := inflate(z, Z_FULL_FLUSH);
       if (status <> Z_STREAM_END) then
         raise exception.Create('Block: '+IntToStr(Block)+': '+z.msg);

       cmp_size := ciso.block_size - z.avail_out;
       if(cmp_size <> ciso.block_size) then
         raise exception.Create('Block: '+IntToStr(Block)+': Block size error');
     end;

     // write decompressed block
     fout.WriteBuffer(block_buf1[0], cmp_size);

     // term zlib
     if (inflateEnd(z) <> Z_OK) then
       raise exception.Create('inflateEnd : ' +z.msg);
               
   end;

   m_Progress := 100;

  finally
    fin.Free;
    fout.Free;
  end;
end;
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22668045
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.
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22668177
It seems to happen when read_size = 2048
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22676198
Can you give me the C++ code you are testing with pls, so I can also have a look
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22676208

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

0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22677528
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 ===|
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22677560
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);
0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22677571
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 ===|
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22683542
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
0
 
LVL 13

Accepted Solution

by:
ThievingSix earned 0 total points
ID: 22686506
Well, I just learned how C++ makes no sense.

Seems that

if (plain) {

} else {

}

The condition is only false when plain = 0. My type conversion where I wrapped Boolean() around it screwed it up. If you replace "If plain" to "If Plan <> 0" it works. Which is yay!

I do appreciate all your time though. So I will still give you the points.

Cheers =P
0
 
LVL 13

Author Comment

by:ThievingSix
ID: 22691410
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

0
 
LVL 14

Expert Comment

by:Pierre Cornelius
ID: 22700587
Yip, that fixed it. Thanks for
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
Suggested Courses

648 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question