os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_pgcompr.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32\sfile\sf_pgcompr.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include <f32file.h>
sl@0
    19
#include "sf_std.h"
sl@0
    20
#include "sf_ldr.h"
sl@0
    21
#include <f32image.h>
sl@0
    22
#include "sf_image.h"
sl@0
    23
#include <e32uid.h>
sl@0
    24
#include <e32rom.h>
sl@0
    25
#include "sf_cache.h"
sl@0
    26
sl@0
    27
#include "sf_pgcompr.h"
sl@0
    28
sl@0
    29
extern TInt BytePairDecompress(TUint8* /*dst*/, TInt /*dstSize*/, TUint8* /*src*/, TInt /*srcSize*/, TUint8*& /*srcNext*/);
sl@0
    30
sl@0
    31
sl@0
    32
// CBytePairReader - reading from in-memory buffer
sl@0
    33
sl@0
    34
sl@0
    35
CBytePairReader* CBytePairReader::NewLC(TUint8* aBuffer, TUint32 aLength)
sl@0
    36
	{
sl@0
    37
	CBytePairReader* reader = new (ELeave) CBytePairReader(aBuffer, aLength);
sl@0
    38
	CleanupStack::PushL(reader);
sl@0
    39
	return reader;
sl@0
    40
	}
sl@0
    41
sl@0
    42
sl@0
    43
CBytePairReader::CBytePairReader(TUint8* aBuffer, TUint32 aLength)
sl@0
    44
	: iNextPage(aBuffer), iBytesLeft(aLength)
sl@0
    45
	{
sl@0
    46
	}
sl@0
    47
sl@0
    48
sl@0
    49
void CBytePairReader::SeekForwardL(TUint aBytes)
sl@0
    50
	{
sl@0
    51
	if (iBytesLeft < aBytes)
sl@0
    52
		LEAVE_FAILURE(KErrCorrupt);
sl@0
    53
	iNextPage += aBytes;
sl@0
    54
	iBytesLeft -= aBytes;
sl@0
    55
	}
sl@0
    56
sl@0
    57
sl@0
    58
void CBytePairReader::ReadInTableL()
sl@0
    59
	{
sl@0
    60
	if (KIndexTableHeaderSize > iBytesLeft)
sl@0
    61
		LEAVE_FAILURE(KErrCorrupt);
sl@0
    62
	Mem::Copy(&iHeader, iNextPage, KIndexTableHeaderSize);
sl@0
    63
	iNextPage += KIndexTableHeaderSize;
sl@0
    64
	iBytesLeft -= KIndexTableHeaderSize;
sl@0
    65
	
sl@0
    66
	__IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
sl@0
    67
	
sl@0
    68
	TUint size = iHeader.iNumberOfPages * sizeof(TUint16);
sl@0
    69
	if (size > iBytesLeft)
sl@0
    70
		LEAVE_FAILURE(KErrCorrupt);
sl@0
    71
	// coverity[buffer_alloc]
sl@0
    72
	iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
sl@0
    73
	Mem::Copy(iIndexTable, iNextPage, size);
sl@0
    74
	iNextPage += size;
sl@0
    75
	iBytesLeft -= size;
sl@0
    76
	} 
sl@0
    77
sl@0
    78
sl@0
    79
void CBytePairReader::ReleaseTable()
sl@0
    80
	{
sl@0
    81
	delete[] iIndexTable;
sl@0
    82
	iIndexTable = NULL;
sl@0
    83
	}
sl@0
    84
sl@0
    85
sl@0
    86
TUint CBytePairReader::GetPageL(TUint aPageNum, TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
sl@0
    87
	{
sl@0
    88
	if (iIndexTable[aPageNum] > iBytesLeft)
sl@0
    89
		LEAVE_FAILURE(KErrCorrupt);
sl@0
    90
	iBytesLeft -= iIndexTable[aPageNum];
sl@0
    91
	aLength = Min(aLength, KBytePairPageSize);
sl@0
    92
sl@0
    93
	TInt size;
sl@0
    94
	TUint8* nextPage;
sl@0
    95
sl@0
    96
	if (aMemMoveFn)
sl@0
    97
		size = BytePairDecompress(iPageBuf, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
sl@0
    98
	else
sl@0
    99
		size = BytePairDecompress(aTarget, aLength, iNextPage, iIndexTable[aPageNum], nextPage);
sl@0
   100
		
sl@0
   101
	User::LeaveIfError(size);
sl@0
   102
	if (size != aLength)
sl@0
   103
		LEAVE_FAILURE(KErrCorrupt);
sl@0
   104
	if (iNextPage + iIndexTable[aPageNum] != nextPage)
sl@0
   105
		LEAVE_FAILURE(KErrCorrupt);
sl@0
   106
sl@0
   107
	// If a memmove() was provided, use that to copy the data to its final target
sl@0
   108
	if (aMemMoveFn)
sl@0
   109
		aMemMoveFn(aTarget, iPageBuf, size);
sl@0
   110
sl@0
   111
	iNextPage = nextPage;
sl@0
   112
	return size;
sl@0
   113
	}
sl@0
   114
sl@0
   115
sl@0
   116
TUint CBytePairReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
sl@0
   117
	{
sl@0
   118
	TUint decompressedSize = 0;
sl@0
   119
sl@0
   120
	ReadInTableL();
sl@0
   121
	
sl@0
   122
	for (TUint curPage = 0; curPage < iHeader.iNumberOfPages; ++curPage)
sl@0
   123
		{
sl@0
   124
		TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
sl@0
   125
		
sl@0
   126
		decompressedSize += size;
sl@0
   127
		aTarget += size;
sl@0
   128
		aLength -= size;
sl@0
   129
		
sl@0
   130
		__IF_DEBUG(Printf("decomp page size:%d\n", size ));
sl@0
   131
		} 
sl@0
   132
	
sl@0
   133
	__IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
sl@0
   134
sl@0
   135
	ReleaseTable();
sl@0
   136
sl@0
   137
	return decompressedSize;
sl@0
   138
	}
sl@0
   139
sl@0
   140
sl@0
   141
void CBytePairReader::GetPageOffsetsL(TInt32 aInitialOffset, TInt& aPageCount, TInt32*& aPageOffsets)
sl@0
   142
	{
sl@0
   143
	ReadInTableL();
sl@0
   144
	aPageCount = iHeader.iNumberOfPages;
sl@0
   145
	aPageOffsets = new (ELeave) TInt32[aPageCount+1];
sl@0
   146
sl@0
   147
	TInt bytes = aInitialOffset + KIndexTableHeaderSize + aPageCount * sizeof(TUint16);
sl@0
   148
	for (TInt i = 0; i < aPageCount; ++i)
sl@0
   149
		{
sl@0
   150
		aPageOffsets[i] = bytes;
sl@0
   151
		bytes += iIndexTable[i];
sl@0
   152
		}
sl@0
   153
	aPageOffsets[aPageCount] = bytes;
sl@0
   154
sl@0
   155
	ReleaseTable();
sl@0
   156
	}
sl@0
   157
sl@0
   158
sl@0
   159
// CBytePairFileReader - reading from file
sl@0
   160
sl@0
   161
sl@0
   162
CBytePairFileReader* CBytePairFileReader::NewLC(RFile& aFile)
sl@0
   163
	{
sl@0
   164
	CBytePairFileReader* reader = new (ELeave) CBytePairFileReader(aFile);
sl@0
   165
	CleanupStack::PushL(reader);
sl@0
   166
	return reader;
sl@0
   167
	}
sl@0
   168
sl@0
   169
sl@0
   170
CBytePairFileReader::CBytePairFileReader(RFile& aFile)
sl@0
   171
	: CBytePairReader(NULL, 0), iFile(aFile)
sl@0
   172
	{
sl@0
   173
	}	
sl@0
   174
sl@0
   175
sl@0
   176
CBytePairFileReader::~CBytePairFileReader()
sl@0
   177
	{
sl@0
   178
	ReleaseTable();
sl@0
   179
	}
sl@0
   180
sl@0
   181
sl@0
   182
void CBytePairFileReader::SeekForwardL(TUint aBytes)
sl@0
   183
	{
sl@0
   184
	TInt bytes = aBytes;
sl@0
   185
	User::LeaveIfError(iFile.Seek(ESeekCurrent, bytes));
sl@0
   186
	}
sl@0
   187
	
sl@0
   188
sl@0
   189
void CBytePairFileReader::ReadInTableL()
sl@0
   190
	{
sl@0
   191
	TPtr8 header((TUint8*)&iHeader, KIndexTableHeaderSize);
sl@0
   192
	User::LeaveIfError(iFile.Read(header, KIndexTableHeaderSize));
sl@0
   193
	if (header.Length() != (TInt)KIndexTableHeaderSize)
sl@0
   194
		LEAVE_FAILURE(KErrCorrupt);
sl@0
   195
	
sl@0
   196
	__IF_DEBUG(Printf("numberOfPages:%d", iHeader.iNumberOfPages));
sl@0
   197
	
sl@0
   198
	TInt size = iHeader.iNumberOfPages * sizeof(TUint16);
sl@0
   199
	iIndexTable = new (ELeave) TUint16[size/sizeof(TUint16)];
sl@0
   200
	TPtr8 indexTable((TUint8*)iIndexTable, size);
sl@0
   201
	User::LeaveIfError(iFile.Read(indexTable, size));
sl@0
   202
	if (indexTable.Length() != size)
sl@0
   203
		LEAVE_FAILURE(KErrCorrupt);
sl@0
   204
	} 
sl@0
   205
sl@0
   206
sl@0
   207
TUint CBytePairFileReader::DecompressPagesL(TUint8* aTarget, TInt aLength, TMemoryMoveFunction aMemMoveFn)
sl@0
   208
	{
sl@0
   209
	TUint decompressedSize = 0;
sl@0
   210
sl@0
   211
	ReadInTableL();
sl@0
   212
	
sl@0
   213
	TUint curPage = 0;
sl@0
   214
	while (curPage < iHeader.iNumberOfPages)
sl@0
   215
		{
sl@0
   216
		TUint bytes = 0;
sl@0
   217
		TUint pages = 0;
sl@0
   218
		while (curPage + pages < iHeader.iNumberOfPages &&
sl@0
   219
			   bytes + iIndexTable[curPage+pages] < sizeof(iBuffer))
sl@0
   220
			{
sl@0
   221
			bytes += iIndexTable[curPage+pages];
sl@0
   222
			++pages;
sl@0
   223
			}
sl@0
   224
		if(!bytes)
sl@0
   225
			LEAVE_FAILURE(KErrCorrupt);
sl@0
   226
		TPtr8 data(iBuffer, bytes);
sl@0
   227
		User::LeaveIfError(iFile.Read(data, bytes));
sl@0
   228
		if (data.Length() != (TInt)bytes)
sl@0
   229
			LEAVE_FAILURE(KErrCorrupt);
sl@0
   230
		iNextPage = iBuffer;
sl@0
   231
		iBytesLeft = bytes;
sl@0
   232
sl@0
   233
		for (; pages; ++curPage, --pages)
sl@0
   234
			{
sl@0
   235
			TUint size = GetPageL(curPage, aTarget, aLength, aMemMoveFn);
sl@0
   236
		
sl@0
   237
			decompressedSize += size;
sl@0
   238
			aTarget += size;
sl@0
   239
			aLength -= size;
sl@0
   240
		
sl@0
   241
			__IF_DEBUG(Printf("decomp page size:%d\n", size ));
sl@0
   242
			}
sl@0
   243
		} 
sl@0
   244
	
sl@0
   245
	__IF_DEBUG(Printf("decompressedSize:%d", decompressedSize));
sl@0
   246
sl@0
   247
	ReleaseTable();
sl@0
   248
sl@0
   249
	return decompressedSize;
sl@0
   250
	}