os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_pgcompr.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_pgcompr.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,250 @@
     1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// f32\sfile\sf_pgcompr.cpp
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <f32file.h>
    1.22 +#include "sf_std.h"
    1.23 +#include "sf_ldr.h"
    1.24 +#include <f32image.h>
    1.25 +#include "sf_image.h"
    1.26 +#include <e32uid.h>
    1.27 +#include <e32rom.h>
    1.28 +#include "sf_cache.h"
    1.29 +
    1.30 +#include "sf_pgcompr.h"
    1.31 +
    1.32 +extern TInt BytePairDecompress(TUint8* /*dst*/, TInt /*dstSize*/, TUint8* /*src*/, TInt /*srcSize*/, TUint8*& /*srcNext*/);
    1.33 +
    1.34 +
    1.35 +// CBytePairReader - reading from in-memory buffer
    1.36 +
    1.37 +
    1.38 +CBytePairReader* CBytePairReader::NewLC(TUint8* aBuffer, TUint32 aLength)
    1.39 +	{
    1.40 +	CBytePairReader* reader = new (ELeave) CBytePairReader(aBuffer, aLength);
    1.41 +	CleanupStack::PushL(reader);
    1.42 +	return reader;
    1.43 +	}
    1.44 +
    1.45 +
    1.46 +CBytePairReader::CBytePairReader(TUint8* aBuffer, TUint32 aLength)
    1.47 +	: iNextPage(aBuffer), iBytesLeft(aLength)
    1.48 +	{
    1.49 +	}
    1.50 +
    1.51 +
    1.52 +void CBytePairReader::SeekForwardL(TUint aBytes)
    1.53 +	{
    1.54 +	if (iBytesLeft < aBytes)
    1.55 +		LEAVE_FAILURE(KErrCorrupt);
    1.56 +	iNextPage += aBytes;
    1.57 +	iBytesLeft -= aBytes;
    1.58 +	}
    1.59 +
    1.60 +
    1.61 +void CBytePairReader::ReadInTableL()
    1.62 +	{
    1.63 +	if (KIndexTableHeaderSize > iBytesLeft)
    1.64 +		LEAVE_FAILURE(KErrCorrupt);
    1.65 +	Mem::Copy(&iHeader, iNextPage, KIndexTableHeaderSize);
    1.66 +	iNextPage += KIndexTableHeaderSize;
    1.67 +	iBytesLeft -= KIndexTableHeaderSize;
    1.68 +	
    1.69 +	__IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
    1.70 +	
    1.71 +	TUint size = iHeader.iNumberOfPages * sizeof(TUint16);
    1.72 +	if (size > iBytesLeft)
    1.73 +		LEAVE_FAILURE(KErrCorrupt);
    1.74 +	// coverity[buffer_alloc]
    1.75 +	iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
    1.76 +	Mem::Copy(iIndexTable, iNextPage, size);
    1.77 +	iNextPage += size;
    1.78 +	iBytesLeft -= size;
    1.79 +	} 
    1.80 +
    1.81 +
    1.82 +void CBytePairReader::ReleaseTable()
    1.83 +	{
    1.84 +	delete[] iIndexTable;
    1.85 +	iIndexTable = NULL;
    1.86 +	}
    1.87 +
    1.88 +
    1.89 +TUint CBytePairReader::GetPageL(TUint aPageNum, TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
    1.90 +	{
    1.91 +	if (iIndexTable[aPageNum] > iBytesLeft)
    1.92 +		LEAVE_FAILURE(KErrCorrupt);
    1.93 +	iBytesLeft -= iIndexTable[aPageNum];
    1.94 +	aLength = Min(aLength, KBytePairPageSize);
    1.95 +
    1.96 +	TInt size;
    1.97 +	TUint8* nextPage;
    1.98 +
    1.99 +	if (aMemMoveFn)
   1.100 +		size = BytePairDecompress(iPageBuf, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
   1.101 +	else
   1.102 +		size = BytePairDecompress(aTarget, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
   1.103 +		
   1.104 +	User::LeaveIfError(size);
   1.105 +	if (size != aLength)
   1.106 +		LEAVE_FAILURE(KErrCorrupt);
   1.107 +	if (iNextPage + iIndexTable[aPageNum] != nextPage)
   1.108 +		LEAVE_FAILURE(KErrCorrupt);
   1.109 +
   1.110 +	// If a memmove() was provided, use that to copy the data to its final target
   1.111 +	if (aMemMoveFn)
   1.112 +		aMemMoveFn(aTarget, iPageBuf, size);
   1.113 +
   1.114 +	iNextPage = nextPage;
   1.115 +	return size;
   1.116 +	}
   1.117 +
   1.118 +
   1.119 +TUint CBytePairReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
   1.120 +	{
   1.121 +	TUint decompressedSize = 0;
   1.122 +
   1.123 +	ReadInTableL();
   1.124 +	
   1.125 +	for (TUint curPage = 0; curPage < iHeader.iNumberOfPages; ++curPage)
   1.126 +		{
   1.127 +		TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
   1.128 +		
   1.129 +		decompressedSize += size;
   1.130 +		aTarget += size;
   1.131 +		aLength -= size;
   1.132 +		
   1.133 +		__IF_DEBUG(Printf("decomp page size:%d\n", size ));
   1.134 +		} 
   1.135 +	
   1.136 +	__IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
   1.137 +
   1.138 +	ReleaseTable();
   1.139 +
   1.140 +	return decompressedSize;
   1.141 +	}
   1.142 +
   1.143 +
   1.144 +void CBytePairReader::GetPageOffsetsL(TInt32 aInitialOffset, TInt& aPageCount, TInt32*& aPageOffsets)
   1.145 +	{
   1.146 +	ReadInTableL();
   1.147 +	aPageCount = iHeader.iNumberOfPages;
   1.148 +	aPageOffsets = new (ELeave) TInt32[aPageCount+1];
   1.149 +
   1.150 +	TInt bytes = aInitialOffset + KIndexTableHeaderSize + aPageCount * sizeof(TUint16);
   1.151 +	for (TInt i = 0; i < aPageCount; ++i)
   1.152 +		{
   1.153 +		aPageOffsets[i] = bytes;
   1.154 +		bytes += iIndexTable[i];
   1.155 +		}
   1.156 +	aPageOffsets[aPageCount] = bytes;
   1.157 +
   1.158 +	ReleaseTable();
   1.159 +	}
   1.160 +
   1.161 +
   1.162 +// CBytePairFileReader - reading from file
   1.163 +
   1.164 +
   1.165 +CBytePairFileReader* CBytePairFileReader::NewLC(RFile& aFile)
   1.166 +	{
   1.167 +	CBytePairFileReader* reader = new (ELeave) CBytePairFileReader(aFile);
   1.168 +	CleanupStack::PushL(reader);
   1.169 +	return reader;
   1.170 +	}
   1.171 +
   1.172 +
   1.173 +CBytePairFileReader::CBytePairFileReader(RFile& aFile)
   1.174 +	: CBytePairReader(NULL, 0), iFile(aFile)
   1.175 +	{
   1.176 +	}	
   1.177 +
   1.178 +
   1.179 +CBytePairFileReader::~CBytePairFileReader()
   1.180 +	{
   1.181 +	ReleaseTable();
   1.182 +	}
   1.183 +
   1.184 +
   1.185 +void CBytePairFileReader::SeekForwardL(TUint aBytes)
   1.186 +	{
   1.187 +	TInt bytes = aBytes;
   1.188 +	User::LeaveIfError(iFile.Seek(ESeekCurrent, bytes));
   1.189 +	}
   1.190 +	
   1.191 +
   1.192 +void CBytePairFileReader::ReadInTableL()
   1.193 +	{
   1.194 +	TPtr8 header((TUint8*)&iHeader, KIndexTableHeaderSize);
   1.195 +	User::LeaveIfError(iFile.Read(header, KIndexTableHeaderSize));
   1.196 +	if (header.Length() != (TInt)KIndexTableHeaderSize)
   1.197 +		LEAVE_FAILURE(KErrCorrupt);
   1.198 +	
   1.199 +	__IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
   1.200 +	
   1.201 +	TInt size = iHeader.iNumberOfPages * sizeof(TUint16);
   1.202 +	iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
   1.203 +	TPtr8 indexTable((TUint8*)iIndexTable, size);
   1.204 +	User::LeaveIfError(iFile.Read(indexTable, size));
   1.205 +	if (indexTable.Length() != size)
   1.206 +		LEAVE_FAILURE(KErrCorrupt);
   1.207 +	} 
   1.208 +
   1.209 +
   1.210 +TUint CBytePairFileReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
   1.211 +	{
   1.212 +	TUint decompressedSize = 0;
   1.213 +
   1.214 +	ReadInTableL();
   1.215 +	
   1.216 +	TUint curPage = 0;
   1.217 +	while (curPage < iHeader.iNumberOfPages)
   1.218 +		{
   1.219 +		TUint bytes = 0;
   1.220 +		TUint pages = 0;
   1.221 +		while (curPage + pages < iHeader.iNumberOfPages &&
   1.222 +			   bytes + iIndexTable[curPage+pages] < sizeof(iBuffer))
   1.223 +			{
   1.224 +			bytes += iIndexTable[curPage+pages];
   1.225 +			++pages;
   1.226 +			}
   1.227 +		if(!bytes)
   1.228 +			LEAVE_FAILURE(KErrCorrupt);
   1.229 +		TPtr8 data(iBuffer, bytes);
   1.230 +		User::LeaveIfError(iFile.Read(data, bytes));
   1.231 +		if (data.Length() != (TInt)bytes)
   1.232 +			LEAVE_FAILURE(KErrCorrupt);
   1.233 +		iNextPage = iBuffer;
   1.234 +		iBytesLeft = bytes;
   1.235 +
   1.236 +		for (; pages; ++curPage, --pages)
   1.237 +			{
   1.238 +			TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
   1.239 +		
   1.240 +			decompressedSize += size;
   1.241 +			aTarget += size;
   1.242 +			aLength -= size;
   1.243 +		
   1.244 +			__IF_DEBUG(Printf("decomp page size:%d\n", size ));
   1.245 +			}
   1.246 +		} 
   1.247 +	
   1.248 +	__IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
   1.249 +
   1.250 +	ReleaseTable();
   1.251 +
   1.252 +	return decompressedSize;
   1.253 +	}