Subversion Repositories spk

Rev

Rev 285 | Rev 317 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 285 Rev 308
Line 779... Line 779...
779
	if ( !this->CompressData(compressionType, progress) )
779
	if ( !this->CompressData(compressionType, progress) )
780
		return false;
780
		return false;
781
	return true;
781
	return true;
782
}
782
}
783
 
783
 
784
unsigned char *C_File::CompressToData(int compressionType, unsigned long *outSize, CProgressInfo *progress, int level)
784
unsigned char* C_File::CompressToData(int compressionType, size_t* outSize, CProgressInfo* progress, int level)
785
{
785
{
-
 
786
	if (outSize) *outSize = 0;
786
	unsigned long comprLen = m_lDataSize;
787
	size_t initialLen = m_lDataSize;
787
	if ( comprLen < 100 )		comprLen = 200;
788
	if (initialLen < 100) initialLen = 200;
788
	else if ( comprLen < 1000 )	comprLen *= 2;
789
	else if (initialLen < 1000) initialLen *= 2;
789
	comprLen += 1000;
790
	initialLen += 1000;
790
 
791
 
791
	switch(compressionType)
792
	switch (compressionType)
-
 
793
	{
-
 
794
	case SPKCOMPRESS_ZLIB:
792
	{
795
	{
-
 
796
		unsigned long comprLen = static_cast<unsigned long>(initialLen);
-
 
797
		unsigned char* compr = (unsigned char*)calloc(comprLen, 1);
-
 
798
		if (!compr) return NULL;
-
 
799
 
793
		case SPKCOMPRESS_ZLIB:
800
		int err = Z_NOTENOUGH_BUF;
-
 
801
		while (err == Z_NOTENOUGH_BUF)
-
 
802
		{
-
 
803
			err = compress2(compr, &comprLen, (const unsigned char*)m_sData, m_lDataSize,
-
 
804
				(progress) ? progress->GetDonePointer() : 0, level);
-
 
805
			if (err == Z_NOTENOUGH_BUF)
794
			{
806
			{
795
				unsigned char *compr = (unsigned char *)calloc(comprLen, 1);
807
				unsigned long newLen = comprLen + (CHUNK * 2);
796
				int err = Z_NOTENOUGH_BUF;
808
				unsigned char* newCompr = (unsigned char*)realloc(compr, newLen);
797
				while ( err == Z_NOTENOUGH_BUF )
809
				if (!newCompr) { free(compr); return NULL; }
798
				{
-
 
799
					err = compress2 ( compr, &comprLen, (const unsigned char *)m_sData, m_lDataSize, (progress) ? progress->GetDonePointer() : 0, level );
-
 
800
					if ( err == Z_NOTENOUGH_BUF )
810
				compr = newCompr;
801
					{
-
 
802
						comprLen += (CHUNK * 2);
811
				comprLen = newLen;
803
						compr = (unsigned char *)realloc(compr, comprLen);
-
 
804
					}
812
			}
805
					else
-
 
806
						break;
-
 
807
				}	
813
		}
808
 
814
 
809
				// if its compressed ok, remove old data and use new one
-
 
810
				if ( err == Z_OK )
815
		if (err == Z_OK && comprLen > 0)
811
				{
816
		{
812
					unsigned char *retData = new unsigned char[comprLen];
817
			unsigned char* retData = new (std::nothrow) unsigned char[comprLen];
813
					(*outSize) = comprLen;
818
			if (!retData) { free(compr); return NULL; }
814
					memcpy(retData, compr, comprLen);
819
			memcpy(retData, compr, comprLen);
815
					free(compr);
820
			free(compr);
-
 
821
			if (outSize) *outSize = static_cast<size_t>(comprLen);
816
					return retData;
822
			return retData;
817
				}
823
		}
818
 
824
 
819
				free(compr);
825
		free(compr);
820
				return NULL;
826
		return NULL;
821
			}
827
	}
822
			break;
828
	break;
823
 
829
 
824
		case SPKCOMPRESS_LZMA:
830
	case SPKCOMPRESS_LZMA:
825
			{
831
	{
-
 
832
		size_t comprLen = initialLen;
826
				unsigned char *compr = (unsigned char *)malloc(comprLen);
833
		unsigned char* compr = new (std::nothrow) unsigned char[comprLen];
827
				if (!compr) {
-
 
828
					return NULL;
834
		if (!compr) return NULL;
829
				}
-
 
830
				SRes res = Lzma86_Encode((Byte *)compr, (size_t *)&comprLen, (const Byte *)m_sData, (size_t)m_lDataSize, level, LZMA_DICT, SZ_FILTER_NO, (progress) ? progress->GetDonePointer() : NULL);
-
 
831
 
835
 
832
				if ( res == SZ_OK )
-
 
833
				{
-
 
834
					unsigned char *retData = new unsigned char[comprLen];
836
		SRes res = Lzma86_Encode((Byte*)compr, (size_t*)&comprLen, (const Byte*)m_sData, (size_t)m_lDataSize,
835
					(*outSize) = comprLen;
-
 
836
					memcpy(retData, compr, comprLen);
837
			level, LZMA_DICT, SZ_FILTER_NO, (progress) ? progress->GetDonePointer() : NULL);
837
					free(compr);
-
 
838
					return retData;
-
 
839
				}
-
 
840
 
838
 
-
 
839
		if (res == SZ_OK && comprLen > 0)
-
 
840
		{
-
 
841
			unsigned char* retData = new (std::nothrow) unsigned char[comprLen];
-
 
842
			if (!retData) { delete[] compr; return NULL; }
-
 
843
			memcpy(retData, compr, comprLen);
841
				free(compr);
844
			delete[] compr;
-
 
845
			if (outSize) *outSize = comprLen;
-
 
846
			return retData;
-
 
847
		}
-
 
848
 
-
 
849
		delete[] compr;
842
				return NULL;
850
		return NULL;
843
			}
851
	}
844
			break;
852
	break;
845
	}
853
	}
846
 
854
 
847
	return NULL;
855
	return NULL;
848
}
856
}
849
 
857
 
Line 876... Line 884...
876
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
884
	if ( m_iDataCompression != SPKCOMPRESS_NONE )
877
		return true;
885
		return true;
878
 
886
 
879
	m_lUncomprDataSize = m_lDataSize;
887
	m_lUncomprDataSize = m_lDataSize;
880
 
888
 
881
	unsigned long comprLen = m_lDataSize;
889
	size_t comprLen = static_cast<size_t>(m_lDataSize);
882
	if ( comprLen < 100 )
890
	if ( comprLen < 100 )
883
		comprLen = 200;
891
		comprLen = 200;
884
	else if ( comprLen < 1000 )
892
	else if ( comprLen < 1000 )
885
		comprLen *= 2;
893
		comprLen *= 2;
886
	comprLen += 1000;
894
	comprLen += 1000;
Line 892... Line 900...
892
	// best compression, attempt to compress the file multiple times until we get the best one
900
	// best compression, attempt to compress the file multiple times until we get the best one
893
	if ( compressionType == SPKCOMPRESS_BEST )
901
	if ( compressionType == SPKCOMPRESS_BEST )
894
	{
902
	{
895
		int compress[] = { SPKCOMPRESS_ZLIB, SPKCOMPRESS_LZMA };
903
		int compress[] = { SPKCOMPRESS_ZLIB, SPKCOMPRESS_LZMA };
896
		int bestCompress = -1;
904
		int bestCompress = -1;
897
		unsigned int bestSize = 0;
905
		size_t bestSize = 0;
898
		unsigned char *bestCompr = NULL;
906
		unsigned char *bestCompr = NULL;
899
		for ( int i = 0; i < 2; i++ )
907
		for ( int i = 0; i < 2; i++ )
900
		{
908
		{
901
			unsigned long checkSize = 0;
909
			size_t checkSize = 0;
902
			unsigned char *compr = this->CompressToData(compress[i], &checkSize, progress, level);
910
			unsigned char *compr = this->CompressToData(compress[i], &checkSize, progress, level);
903
			if ( compr )
911
			if ( compr )
904
			{
912
			{
905
				if ( checkSize < bestSize || bestCompress == -1 )
913
				if ( checkSize < bestSize || bestCompress == -1 )
906
				{
914
				{
Line 1492... Line 1500...
1492
	}
1500
	}
1493
 
1501
 
1494
	if ( data )
1502
	if ( data )
1495
	{
1503
	{
1496
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1504
		unsigned char *newdata = UnPCKData ( data, datasize, len, CheckPCK() );
1497
		delete data;
1505
		delete[] data;
1498
		return newdata;
1506
		return newdata;
1499
	}
1507
	}
1500
 
1508
 
1501
	return NULL;
1509
	return NULL;
1502
}
1510
}
Line 1547... Line 1555...
1547
 
1555
 
1548
	return NULL;
1556
	return NULL;
1549
}
1557
}
1550
 
1558
 
1551
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len ) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
1559
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len ) { return UnPCKData(data, datasize, len, IsDataPCK(data, datasize)); }
1552
unsigned char *UnPCKData ( unsigned char *data, size_t datasize, size_t *len, bool nocrypt )
1560
unsigned char* UnPCKData(unsigned char* data, size_t datasize, size_t* len, bool nocrypt)
1553
{
1561
{
1554
	bool isPCK = IsDataPCK(data, datasize);
-
 
1555
 
-
 
1556
	unsigned char *newData = data;
-
 
1557
	unsigned char *tempData = NULL;
-
 
1558
 
-
 
1559
	if ( nocrypt )
-
 
1560
	{
-
 
1561
		tempData = new unsigned char[datasize]; 
-
 
1562
		newData = tempData;
-
 
1563
		memcpy(newData, data, datasize);
-
 
1564
		unsigned char magic = newData[0] ^ 0xC8;
-
 
1565
 
-
 
1566
		for ( size_t i = 1; i < datasize; i++ )
-
 
1567
			newData[i] ^= magic;
-
 
1568
		++newData;
-
 
1569
		--datasize;
-
 
1570
	}
-
 
1571
 
-
 
1572
	// create data buffer
-
 
1573
	size_t *uncomprLenSize = (size_t*)(newData + (datasize - 4));
1562
	if (!data || datasize < 8) { // Minimum size for header + length
1574
	unsigned long uncomprLen = (unsigned long)*uncomprLenSize;
-
 
1575
	if ( uncomprLen > (datasize * 100) )
-
 
1576
	{
-
 
1577
		if ( tempData ) delete []tempData;
-
 
1578
		*len = 0;
1563
		if (len) *len = 0;
1579
		return NULL;
1564
		return nullptr;
1580
	}
1565
	}
1581
	unsigned char *uncompr = new unsigned char[uncomprLen + 1];
-
 
1582
	if ( !uncompr ) {
-
 
1583
		if ( tempData ) delete []tempData;
-
 
1584
		return NULL;
-
 
1585
	}
-
 
1586
	memset ( uncompr, 0, sizeof(uncompr) );
-
 
1587
 
1566
 
-
 
1567
	bool isPCK = IsDataPCK(data, datasize);
-
 
1568
	unsigned char* newData = data;
-
 
1569
	unsigned char* tempData = nullptr;
1588
 
1570
 
1589
	// find header size
1571
	if (nocrypt) {
-
 
1572
		tempData = new (std::nothrow) unsigned char[datasize];
-
 
1573
		if (!tempData) { if (len) *len = 0; return nullptr; }
-
 
1574
		memcpy(tempData, data, datasize);
1590
	unsigned char *buf = newData + PCKHEADERSIZE;
1575
		unsigned char magic = tempData[0] ^ 0xC8;
-
 
1576
		for (size_t i = 1; i < datasize; i++)
-
 
1577
			tempData[i] ^= magic;
-
 
1578
		newData = tempData + 1;
-
 
1579
		datasize -= 1;
-
 
1580
	}
-
 
1581
 
-
 
1582
	if (datasize < 4) { // Not enough data for length
-
 
1583
		if (tempData) delete[] tempData;
-
 
1584
		if (len) *len = 0;
-
 
1585
		return nullptr;
-
 
1586
	}
-
 
1587
 
-
 
1588
	// Read uncompressed length safely
-
 
1589
	size_t lenPos = datasize - 4;
-
 
1590
	unsigned long uncomprLen = 0;
-
 
1591
	memcpy(&uncomprLen, newData + lenPos, 4);
-
 
1592
	if (uncomprLen > datasize * 100 || uncomprLen == 0) {
-
 
1593
		if (tempData) delete[] tempData;
-
 
1594
		if (len) *len = 0;
-
 
1595
		return nullptr;
-
 
1596
	}
-
 
1597
 
-
 
1598
	unsigned char* uncompr = new (std::nothrow) unsigned char[uncomprLen + 1];
-
 
1599
	if (!uncompr) {
-
 
1600
		if (tempData) delete[] tempData;
-
 
1601
		if (len) *len = 0;
-
 
1602
		return nullptr;
-
 
1603
	}
-
 
1604
	memset(uncompr, 0, uncomprLen + 1);
1591
 
1605
 
-
 
1606
	// Parse header
-
 
1607
	size_t bufOffset = PCKHEADERSIZE;
-
 
1608
	if (datasize < bufOffset + 8) { // Not enough data for header and footer
1592
//	buf = data + (6 + sizeof(time_t));
1609
		if (tempData) delete[] tempData;
-
 
1610
		delete[] uncompr;
-
 
1611
		if (len) *len = 0;
-
 
1612
		return nullptr;
-
 
1613
	}
1593
	char flag = newData[3];
1614
	unsigned char flag = newData[3];
-
 
1615
	unsigned char* buf = newData + bufOffset;
1594
 
1616
 
1595
	if ( flag & GZ_FLAG_EXTRA )
1617
	if (flag & GZ_FLAG_EXTRA) {
1596
	{
-
 
-
 
1618
		if (datasize < bufOffset + 2) { if (tempData) delete[] tempData; delete[] uncompr; if (len) *len = 0; return nullptr; }
1597
		size_t xlen = *((short int*)(buf));
1619
		size_t xlen = *((short int*)(buf));
-
 
1620
		buf += 2;
1598
		buf += xlen;
1621
		buf += xlen;
1599
	}
1622
	}
1600
 
-
 
1601
	if ( flag & GZ_FLAG_FILENAME )
1623
	if (flag & GZ_FLAG_FILENAME) {
1602
	{
-
 
1603
		char *origname = (char*)(buf);
1624
		char* origname = (char*)(buf);
1604
		buf += strlen (origname) + 1;
1625
		buf += strlen(origname) + 1;
1605
	}
1626
	}
1606
	if ( flag & GZ_FLAG_COMMENT )
1627
	if (flag & GZ_FLAG_COMMENT) {
1607
	{
-
 
1608
		char *comment = (char*)(buf);
1628
		char* comment = (char*)(buf);
1609
		buf += strlen(comment) + 1;
1629
		buf += strlen(comment) + 1;
1610
	}
1630
	}
1611
	if ( flag & GZ_FLAG_HCRC )
1631
	if (flag & GZ_FLAG_HCRC) {
1612
		buf += 2;
1632
		buf += 2;
1613
	long bufSize = (long)(datasize - (buf-newData) - 8);
-
 
-
 
1633
	}
1614
 
1634
 
1615
	int err = uncompress2 ( uncompr, &uncomprLen, buf, bufSize );
1635
	long bufSize = (long)(datasize - (buf - newData) - 8);
1616
	if ( err != Z_OK )
1636
	if (bufSize <= 0) {
-
 
1637
		if (tempData) delete[] tempData;
-
 
1638
		delete[] uncompr;
-
 
1639
		if (len) *len = 0;
-
 
1640
		return nullptr;
1617
	{
1641
	}
-
 
1642
 
-
 
1643
	int err = uncompress2(uncompr, &uncomprLen, buf, bufSize);
-
 
1644
	if (err != Z_OK) {
1618
		if ( tempData ) delete []tempData;
1645
		if (tempData) delete[] tempData;
1619
		delete uncompr;
1646
		delete[] uncompr;
1620
		*len = 0;
1647
		if (len) *len = 0;
1621
		return NULL;
1648
		return nullptr;
1622
	}
1649
	}
1623
 
1650
 
1624
	*len = uncomprLen;
1651
	if (len) *len = uncomprLen;
1625
	uncompr[uncomprLen] = '\0';
1652
	uncompr[uncomprLen] = '\0';
1626
	if ( tempData ) delete []tempData;
1653
	if (tempData) delete[](tempData - 1); // tempData was offset by +1
1627
	return uncompr;
1654
	return uncompr;
1628
}
1655
}
1629
 
1656
 
1630
bool IsDataPCK ( const unsigned char *data, size_t size )
1657
bool IsDataPCK ( const unsigned char *data, size_t size )
1631
{
1658
{