Sigrid Solveig Haflínudóttirport to Plan 9 using npe8d7fffe3 years agoHistory
152 lines · 2.7 KB · C
RawDownload
/* PowerPacker unpack code taken from Heikki Orsila's amigadepack. Seems to have no license,** so I'll assume it fits into BSD 3-Clause. If not, feel free to contact me at my email** address found at the bottom of 16-bits.org.**** Edited by me (8bitbubsy).*/ #include <stdio.h>#include <stdlib.h>#include <stdint.h>#include <stdbool.h> #define READ_BITS(nbits, var) \	bitCnt = (nbits); \	while (bitsLeft < bitCnt) \	{ \		if (bufSrc < src) \			return false; \		bitBuffer |= ((*--bufSrc) << bitsLeft); \		bitsLeft += 8; \	} \	(var) = 0; \	bitsLeft -= bitCnt; \	while (bitCnt--) \	{ \		(var) = ((var) << 1) | (bitBuffer & 1); \		bitBuffer >>= 1; \	} static bool decrunch(uint8_t *src, uint8_t *dst, uint8_t *offsetLens, uint32_t srcLen, uint32_t dstLen, uint8_t skipBits){	uint8_t bitCnt;	uint32_t x, todo, offset; 	if (src == NULL || dst == NULL || offsetLens == NULL)		return false; 	uint8_t bitsLeft = 0;	uint32_t bitBuffer = 0;	uint32_t written = 0;	uint8_t *bufSrc = src + srcLen;	uint8_t *out = dst + dstLen;	uint8_t *dstEnd = out; 	READ_BITS(skipBits, x);	while (written < dstLen)	{		READ_BITS(1, x);		if (x == 0)		{			todo = 1; 			do			{				READ_BITS(2, x);				todo += x;			}			while (x == 3); 			while (todo--)			{				READ_BITS(8, x);				if (out <= dst)					return false; 				*--out = (uint8_t)x;				written++;			} 			if (written == dstLen)				break;		} 		READ_BITS(2, x);		uint32_t offBits = offsetLens[x];		todo = x + 2; 		if (x == 3)		{			READ_BITS(1, x);			if (x == 0) offBits = 7; 			READ_BITS((uint8_t)offBits, offset);			do			{				READ_BITS(3, x);				todo += x;			}			while (x == 7);		}		else		{			READ_BITS((uint8_t)offBits, offset);		} 		if (out+offset >= dstEnd)			return false; 		while (todo--)		{			x = out[offset];			if (out <= dst)				return false; 			*--out = (uint8_t)x;			written++;		}	} 	return true;} uint8_t *unpackPP(FILE *f, uint32_t *filesize){	uint8_t *outBuffer, ppCrunchData[4], *ppBuffer;	uint32_t ppPackLen, ppUnpackLen; 	ppPackLen = *filesize;	if ((ppPackLen & 3) != 0 || ppPackLen <= 12)		return NULL; 	ppBuffer = (uint8_t *)malloc(ppPackLen);	if (ppBuffer == NULL)		return NULL; 	fseek(f, ppPackLen-4, SEEK_SET);	fread(ppCrunchData, 1, 4, f); 	ppUnpackLen = (ppCrunchData[0] << 16) | (ppCrunchData[1] << 8) | ppCrunchData[2]; 	outBuffer = (uint8_t *)malloc(ppUnpackLen);	if (outBuffer == NULL)	{		free(ppBuffer);		return NULL;	} 	rewind(f);	fread(ppBuffer, 1, ppPackLen, f);	fclose(f); 	if (!decrunch(ppBuffer+8, outBuffer, ppBuffer+4, ppPackLen-12, ppUnpackLen, ppCrunchData[3]))	{		free(ppBuffer);		return NULL;	} 	free(ppBuffer);	*filesize = ppUnpackLen; 	return outBuffer;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t