/*********************************************************/ /* This source code copyright (c) 1991-2001, Aaron Giles */ /* See the Read Me file for licensing information. */ /* Contact email: mac@aarongiles.com */ /*********************************************************/ #if THINK_C #include "THINK.Header" #elif applec #pragma load ":Headers:MPW.Header" #elif __MWERKS__ //#include "MW.Header" #else #include "JPEGView.h" #endif static void compress_decompress(uchar *src_adr, ulong src_len, uchar *dst_adr, ulong *p_dst_len); static void fast_copy(uchar *p_src,uchar *p_dst,ulong len); Handle GetCompResource(OSType theType, short theID) { long srcLen, dstLen; Handle srcHandle; srcHandle = GetResource(theType, theID); if (!srcHandle) return nil; srcLen = GetHandleSize(srcHandle); SetHandleSize(srcHandle, 32768L); if (MemError()) { ReleaseResource(srcHandle); return nil; } HLock(srcHandle); BlockMove(*srcHandle, (uchar *)*srcHandle + 32768L - srcLen, srcLen); compress_decompress((uchar *)*srcHandle + 32768L - srcLen, srcLen, (uchar *)*srcHandle, (ulong *)&dstLen); SetHandleSize(srcHandle, dstLen); HUnlock(srcHandle); return srcHandle; } //------------------------------------------------------------------------------ #define UBYTE unsigned char /* Unsigned byte */ #define UWORD unsigned int /* Unsigned word (2 bytes) */ #define ULONG unsigned long /* Unsigned word (4 bytes) */ #define BOOL unsigned char /* Boolean */ #define REAL double /* USed for floating point stuff. */ #define DONE_PORT /* Don't do all this again. */ #define MALLOC_FAIL NULL /* Failure status from malloc() */ #define LOCAL static /* For non-exported routines. */ #define EXPORT /* Signals exported function. */ #define then /* Useful for aligning ifs. */ #define FLAG_BYTES 4 /* How many bytes does the flag use up? */ #define FLAG_COMPRESS 0 /* Signals that output was result of compression. */ #define FLAG_COPY 1 /* Signals that output was simply copied over. */ #define GROUP_CMP 34 #define GROUP_RAW 288 #define CONTROL_INIT 0xFFFF8000 void fast_copy(UBYTE *p_src,UBYTE *p_dst,ULONG len) /* Fast copy routine. */ {while (len--) *p_dst++=*p_src++;} static void compress_decompress(uchar *p_src_first, ulong src_len, uchar *p_dst_first, ulong *p_dst_len) /* Input : Specify input block using p_src_first and src_len. */ /* Input : Point p_dst_first to the start of the output zone. */ /* Input : Point p_dst_len to a ULONG to receive the output length. */ /* Input : Input block and output zone must not overlap. User knows */ /* Input : upperbound on output block length from earlier compression. */ /* Input : In any case, maximum expansion possible is nine times. */ /* Output : Length of output block written to *p_dst_len. */ /* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */ /* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */ { register UBYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first; UBYTE *p_src_post=p_src_first+src_len; UBYTE *p_src_max16=p_src_first+src_len-(16*2); register ULONG control=1; if (*p_src_first==FLAG_COPY) {fast_copy(p_src_first+FLAG_BYTES,p_dst_first,src_len-FLAG_BYTES); *p_dst_len=src_len-FLAG_BYTES; return;} while (p_src!=p_src_post) {register UWORD unroll; if (control==1) {control=0x10000|*p_src++; control|=(*p_src++)<<8;} unroll= p_src<=p_src_max16 ? 16 : 1; while (unroll--) {if (control&1) {register UWORD lenmt; register UBYTE *p; lenmt=*p_src++; p=p_dst-(((lenmt&0xF0)<<4)|*p_src++); *p_dst++=*p++; *p_dst++=*p++; *p_dst++=*p++; lenmt&=0xF; while (lenmt--) *p_dst++=*p++;} else *p_dst++=*p_src++; control>>=1; } } *p_dst_len=p_dst-p_dst_first; }