/// <summary> /// Dump this file data to another file. /// </summary> /// <param name="toFile">The destination file stream.</param> /// <returns>Length copied. (If failed, return -1)</returns> public virtual long DumpData(FileStream toFile) { if (this.file == null || !this.file.CanRead) { return(-1); } return(StreamUtility.CopyBlock(this.file, toFile, this.fileOffset, (int)this.fileSize)); }
/// <summary> /// Dump this file data to another file. /// </summary> /// <param name="toFile">The destination file stream.</param> /// <returns>Length copied.</returns> public override long DumpData(FileStream toFile) { if (this.file == null || !this.file.CanRead) { throw new IOException("Source stream is not accessable!"); } if (this.fileSize < this.extractSize) { // Compressed return(this.DecompressToFile(toFile)); } else { // Not compressed byte[] content = StreamUtility.ReadBytesFromStream(this.file, this.fileOffset, (int)this.extractSize); Debug.WriteLine(String.Format("CRC for file {0} is {1:X4}", this.fileName, Crc32.CalcCrc32(content))); return(StreamUtility.CopyBlock(this.file, toFile, this.fileOffset, (int)this.extractSize)); } }
public long DecompressToFile(FileStream toFile) { long offset = this.fileOffset; // Check identifier ulong identifier = StreamUtility.ReadULongFromStream(this.file, offset); if (identifier != 0 && identifier != 0x4352494c41594c41) { throw new FormatException("File is not compressed by CRILAYLA!"); } int decompSize = StreamUtility.ReadIntFromStream(this.file, offset + 0x8); long decompHeaderOffset = StreamUtility.ReadUIntFromStream(this.file, offset + 0xC) + offset + 0x10; if (decompHeaderOffset + 0x100 != offset + this.fileSize) { throw new FormatException("Size mismatch!"); } // Extract real header StreamUtility.CopyBlock(this.file, toFile, decompHeaderOffset, 0x100); //const long input_end = offset + input_size - 0x100 - 1; //long input_offset = input_end; //const long output_end = 0x100 + uncompressed_size - 1; //uint8_t bit_pool = 0; //int bits_left = 0; //long bytes_output = 0; //while ( bytes_output < uncompressed_size ) //{ // if (GET_NEXT_BITS(1)) // { // long backreference_offset = // output_end-bytes_output+GET_NEXT_BITS(13)+3; // long backreference_length = 3; // // decode variable length coding for length // enum { vle_levels = 4 }; // int vle_lens[vle_levels] = { 2, 3, 5, 8 }; // int vle_level; // for (vle_level = 0; vle_level < vle_levels; vle_level++) // { // int this_level = GET_NEXT_BITS(vle_lens[vle_level]); // backreference_length += this_level; // if (this_level != ((1 << vle_lens[vle_level])-1)) break; // } // if (vle_level == vle_levels) // { // int this_level; // do // { // this_level = GET_NEXT_BITS(8); // backreference_length += this_level; // } while (this_level == 255); // } // //printf("0x%08lx backreference to 0x%lx, length 0x%lx\n", output_end-bytes_output, backreference_offset, backreference_length); // for (int i=0;i<backreference_length;i++) // { // output_buffer[output_end-bytes_output] = output_buffer[backreference_offset--]; // bytes_output++; // } // } // else // { // // verbatim byte // output_buffer[output_end-bytes_output] = GET_NEXT_BITS(8); // //printf("0x%08lx verbatim byte\n", output_end-bytes_output); // bytes_output++; // } //} //put_bytes_seek(0, outfile, output_buffer, 0x100 + uncompressed_size); //free(output_buffer); return(0x100 + decompSize); }