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 + }