void TestFile(SZC strName, int ioffs, Size size2, int cbit, int ccomp, bool littleEndianFile) { int byteCount = size2.cx * size2.cy * ccomp * ((cbit + 7)/8); std::vector<BYTE> rgbyteUncompressed; if (!ReadFile(strName, &rgbyteUncompressed, ioffs, byteCount)) return; if (cbit > 8) { FixEndian(&rgbyteUncompressed, littleEndianFile); } TestRoundTrip(strName, rgbyteUncompressed, size2, cbit, ccomp); }
void TestFile16BitAs12(SZC strName, int ioffs, Size size2, int ccomp, bool littleEndianFile) { std::vector<BYTE> rgbyteUncompressed; if (!ReadFile(strName, &rgbyteUncompressed, ioffs)) return; FixEndian(&rgbyteUncompressed, littleEndianFile); USHORT* pushort = (USHORT*)&rgbyteUncompressed[0]; for (int i = 0; i < (int)rgbyteUncompressed.size()/2; ++i) { pushort[i] = pushort[i] >> 4; } TestRoundTrip(strName, rgbyteUncompressed, size2, 12, ccomp); }
// ============================================================== // Extract License & Notes files // These are stored as 4-bytes length, followed by length-bytes of compressed data int ExtractTextFile(BLOCK_DATA *Blk, ULONG FileType) { ULONG n, m; BYTE *zSrcBuf = (BYTE *) Blk->SrcBuf; BYTE *zDstBuf = (BYTE *) Blk->DstBuf; const char *FileExt; if (FileType == FLAGS_License) FileExt = LicenseExt; else if (FileType == FLAGS_Notes) FileExt = NotesExt; else return 0; // NB:Can't use BioReadBuf... aligment problems? Yet it works for ProcessNextBlock() !!?? // Ok, can use ReadInputFile here cause everythjing is whole no. of bytes... //BioReadBuf((BYTE *)&n, sizeof(n)); // Read length of block from file ReadInputFile((BYTE *)&n, sizeof(n)); // Read length of block from file FixEndian(&n, sizeof(n)); // Fix endian if (n <= 0 || n > ZBUF_SIZE) // Check for valid block length { sprintf(MsgTxt, "ERROR - Invalid length for %s file (apparently %ld bytes) %s", FileExt, n, CorruptedMsg); msg(MsgTxt, MSG_PopUp); GlobalErrorFlag = SFARKLIB_ERR_CORRUPT; return 0; } //BioReadBuf(zSrcBuf, n); // Read the block ReadInputFile((BYTE *)zSrcBuf, n); // Read the block m = UnMemcomp(zSrcBuf, n, zDstBuf, ZBUF_SIZE); // Uncompress Blk->FileCheck = adler32(Blk->FileCheck, zDstBuf, m); // Accumulate checksum if (GlobalErrorFlag || m > ZBUF_SIZE) // Uncompressed ok & size is valid? return 0; // Write file - Use original file name plus specified extension for OutFileName... char OutFileName[MAX_FILENAME]; strncpy(OutFileName, Blk->FileHeader.FileName, sizeof(OutFileName)); // copy output filename ChangeFileExt(OutFileName, FileExt, sizeof(OutFileName)); OpenOutputFile(OutFileName); // Create notes / license file WriteOutputFile(zDstBuf, m); // and write to output file CloseOutputFile(); if (FileType == FLAGS_License) { sprintf(MsgTxt, "Created license file: %s", OutFileName); msg(MsgTxt, 0); if (GetLicenseAgreement((const char *)zDstBuf, OutFileName) == 0) { GlobalErrorFlag = SFARKLIB_ERR_LICENSE; return EndProcess(0); } } else if (FileType == FLAGS_Notes) { sprintf(MsgTxt, "Created notes file: %s", OutFileName); msg(MsgTxt, 0); DisplayNotes((const char *)zDstBuf, OutFileName); } return 1; }
// ============================================================== int ProcessNextBlock(BLOCK_DATA *Blk) { //int TotBytesRead = 0; // Total bytes read in file int NumWords; // uint32_t n, m; // NB: Must be 32-bit integer #define AWBYTES (sizeof(AWORD)) BYTE *zSrcBuf = (BYTE *) Blk->SrcBuf; BYTE *zDstBuf = (BYTE *) Blk->DstBuf; switch (Blk->FileSection) { case AUDIO: { NumWords = Blk->ReadSize; // Number of words we will read in this block n = NumWords * AWBYTES; // ... and number of bytes if (Blk->TotBytesWritten + n >= Blk->FileHeader.PostAudioStart) // Short block? (near end of file) { n = Blk->FileHeader.PostAudioStart - Blk->TotBytesWritten; // Get exact length in bytes NumWords = n / AWBYTES; // ... and words Blk->FileSection = POST_AUDIO; // End of Audio -- PostAudio section is next } //printf("AUDIO, read %ld bytes\n", n); if (Blk->FileHeader.CompMethod == COMPRESSION_v2Turbo) // If using Turbo compression DecompressTurbo(Blk, NumWords); // Decompress else // For all other methods DecompressFast(Blk, NumWords); // Decompress //printf("B4 WriteOutputFile: %ld\n", adler32(0, (const BYTE *) Blk->SrcBuf, n) & 0xffff); /*#ifdef __BIG_ENDIAN__ #define WFIX(I) s = bp[I+0]; bp[I+0] = bp[I+1]; bp[I+1] = s; BYTE *bp = (BYTE *) Blk->SrcBuf; BYTE *ep = bp + n; do { BYTE s; WFIX(0); WFIX(2); WFIX(4); WFIX(6); WFIX(8); WFIX(10); WFIX(12); WFIX(14); bp += 16; } while (bp < ep); #undef WFIX #endif*/ WriteOutputFile((const BYTE *)Blk->SrcBuf, n); // Write to output file Blk->TotBytesWritten += n; // Accumulate total bytes written break; } case PRE_AUDIO: case POST_AUDIO: case NON_AUDIO: { BioReadBuf((BYTE *) &n, sizeof(n)); FixEndian(&n, sizeof(n)); //printf("Reading PRE/POST AUDIO block, compressed %ld bytes\n", n); if (n > ZBUF_SIZE) // Check for valid block length { sprintf(MsgTxt, "ERROR - Invalid length for Non-audio Block (apparently %d bytes) %s", n, CorruptedMsg); msg(MsgTxt, MSG_PopUp); return (GlobalErrorFlag = SFARKLIB_ERR_CORRUPT); } BioReadBuf(zSrcBuf, n); // Read the block m = UnMemcomp(zSrcBuf, n, zDstBuf, ZBUF_SIZE); //printf("PRE/POST AUDIO block, compressed %ld bytes, uncompressed %ld bytes\n", n, m); // Uncompress if (GlobalErrorFlag != SFARKLIB_SUCCESS) return(GlobalErrorFlag); if (m <= ZBUF_SIZE) // Uncompressed ok & size is valid? { //printf("writing uncompressed block %ld bytes\n", m); Blk->FileCheck = adler32(Blk->FileCheck, zDstBuf, m); // Accumulate checksum WriteOutputFile(zDstBuf, m); // and write to output file Blk->TotBytesWritten += m; // Accumulate byte count } else return SFARKLIB_ERR_CORRUPT; #if DB_BLOCKCHECK // If debug mode block check enabled ULONG BlockCheck = BioRead(16); // Read block check bits FixEndian(&BlockCheck, sizeof(Blockcheck)); ULONG CalcBlockCheck = adler32(0, zDstBuf, m) & 0xFFFF; printf("NonAudio Block Checks Read: %ld, Calc %ld Length=%d\n", BlockCheck, CalcBlockCheck, m); if (BlockCheck != CalcBlockCheck) // Compare to calculated cheksum { printf("*** NonAudio Block check FAIL\n"); } else printf("NonAudio Block check Ok\n"); #endif //printf("PRE/POST AUDIO, read %ld bytes, writing %ld bytes...", n, m); if (Blk->TotBytesWritten >= Blk->FileHeader.OriginalSize) // Have we finished the file? Blk->FileSection = FINISHED; else if (Blk->FileSection == PRE_AUDIO && Blk->TotBytesWritten >= Blk->FileHeader.AudioStart) // finished Pre-Audio? Blk->FileSection = AUDIO; // .. then next section is Audio break; } // case } //switch //sprintf(MsgTxt, "BytesWritten: %ld of %ld", Blk->TotBytesWritten, Blk->FileHeader.OriginalSize); //msg(MsgTxt, 0); return SFARKLIB_SUCCESS; }