////////////////////////////////////////////////////////////////////////////// // // This file is part of the Atari Machine Specific Library, // and is Copyright 1992 by Warwick W. Allison. // // You are free to copy and modify these sources, provided you acknoledge // the origin by retaining this notice, and adhere to the conditions // described in the file COPYING. // ////////////////////////////////////////////////////////////////////////////// /**********************************************************\ * * * CrackArt file compressor. * * by Warwick Allison, May 8th 1992. * * * * Reverse engineered from compressor routine: * * * * ; CRACK ART Kompressionsroutine fr Bilddaten (CA?) * * ; Copyright ½ Detlef R”ttger 04.03.1990 * * * * The full file format (in bytes) is: * * 'C', 'A', 1, Rez, Colours x 2, Data * * * * Compressions Codes: * * Esc Esc = One Esc byte * * Esc 2 0 = Delta to end * * Esc 2 Hi Lo = HiLo+1 repeated Deltas (HiLo>255) * * Esc 1 Hi Lo byte = HiLo+1 repeated bytes (HiLo>255) * * Esc 0 Esc byte = Esc+1 repeated byte * * Esc Count byte = Count+1 repeated byte (Count>2) * * Byte = Literal byte * * * \**********************************************************/ #include "ca_pack.h" #include const unsigned char Zero=0; const unsigned char One=1; const unsigned char Two=2; int Compress(unsigned char Esc,unsigned char Delta,short Offset,unsigned char* From,int nel,FILE *f) // f=0 implies dry run. Returns size of output. { int Size=0; int basei=0; int i=basei; int count=nel; while (count) { unsigned char b=From[i]; int newi=i,newbasei=basei; for (int N=0; N=nel) { newbasei++; newi=newbasei; } } if (N==count && b==Delta) { // Dumb, hacky compression special-case in CrackArt if (f) { fwrite(&Esc,sizeof(unsigned char),1,f); fwrite(&Two,sizeof(unsigned char),1,f); fwrite(&Zero,sizeof(unsigned char),1,f); } Size+=3; count=0; } else { if (N>3) { i=newi; basei=newbasei; if (N<=256) { unsigned char n=N-1; if (f) fwrite(&Esc,sizeof(unsigned char),1,f); if (n==Esc) { Size++; if (f) fwrite(&Zero,sizeof(unsigned char),1,f); } if (f) { fwrite(&n,sizeof(unsigned char),1,f); fwrite(&b,sizeof(unsigned char),1,f); } Size+=3; count-=N; } else { if (N>65536) N=65536; unsigned short n=N-1; if (f) fwrite(&Esc,sizeof(unsigned char),1,f); if (n==Delta) { if (f) { fwrite(&Two,sizeof(unsigned char),1,f); fwrite(&n,sizeof(unsigned short),1,f); } } else { if (f) { fwrite(&One,sizeof(unsigned char),1,f); fwrite(&n,sizeof(unsigned short),1,f); fwrite(&b,sizeof(unsigned char),1,f); } Size++; } Size+=4; count-=N; } } else { if (b==Esc) { if (f) fwrite(&Esc,sizeof(unsigned char),1,f); Size++; } if (f) fwrite(&b,sizeof(unsigned char),1,f); Size++; i+=Offset; if (i>=nel) { basei++; i=basei; } count--; } } } return Size; } short GoodOffset[]={160,80,320,8,4,640,2,1,480,0}; // 0 terminated. void SaveCrackArtData(unsigned char* From, int nel, FILE* f, int Compression) { int Freq[256]; unsigned char Esc; unsigned char Delta; int MinF=MAXINT; int MaxF=MININT; int i; for (i=0; i<256; i++) Freq[i]=0; for (i=0; iMaxF) { MaxF=Freq[i]; Delta=i; } } int MinSize=MAXINT; short Offset=GoodOffset[0]; // Only testing one is pointless (might as well just use it). if (Compression) Compression++; for (i=0; i