|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 #include "pagedcompress.h" |
|
18 |
|
19 // User includes |
|
20 #include "h_utl.h" |
|
21 #include "byte_pair.h" |
|
22 #include "e32defwrap.h" |
|
23 #include "e32errwrap.h" |
|
24 |
|
25 // Constants and defines |
|
26 const TInt MaxBlockSize = 0x1000; |
|
27 #define PAGE_SIZE 4096 |
|
28 |
|
29 |
|
30 typedef struct IndexTableItemTag |
|
31 { |
|
32 TUint16 iSizeOfCompressedPageData; // pointer to an array TUint16[NumberOfPages] |
|
33 TUint8 *iCompressedPageData; // pointer to an array TUint8*. Each elemet of |
|
34 // this array point a compressed Page data |
|
35 }IndexTableItem; |
|
36 |
|
37 |
|
38 typedef struct IndexTableHeaderTag |
|
39 { |
|
40 TInt iSizeOfData; // Includes the index and compressed pages |
|
41 TInt iDecompressedSize; |
|
42 TUint16 iNumberOfPages; |
|
43 } IndexTableHeader; |
|
44 |
|
45 |
|
46 class CBytePairCompressedImage |
|
47 { |
|
48 public: |
|
49 static CBytePairCompressedImage* NewLC(TUint16 aNumberOfPages, TInt aSize); |
|
50 |
|
51 ~CBytePairCompressedImage(); |
|
52 |
|
53 int GetPage(TUint16 aPageNum, TUint8 * aPageData); |
|
54 int ReadInTable(std::istream &is, TUint & aNumberOfPages); |
|
55 |
|
56 private: |
|
57 TInt ConstructL( TUint16 aNumberOfPages, TInt aSize); |
|
58 CBytePairCompressedImage(); |
|
59 |
|
60 private: |
|
61 IndexTableHeader iHeader; |
|
62 IndexTableItem* iPages; |
|
63 TUint8* iOutBuffer; |
|
64 |
|
65 }; |
|
66 |
|
67 |
|
68 CBytePairCompressedImage::CBytePairCompressedImage() |
|
69 { |
|
70 |
|
71 } |
|
72 |
|
73 |
|
74 CBytePairCompressedImage* CBytePairCompressedImage::NewLC(TUint16 aNumberOfPages, TInt aSize) |
|
75 { |
|
76 CBytePairCompressedImage* self = new CBytePairCompressedImage; |
|
77 if( NULL == self) |
|
78 { |
|
79 return self; |
|
80 } |
|
81 |
|
82 if( KErrNone == self->ConstructL(aNumberOfPages, aSize)) |
|
83 { |
|
84 return self; |
|
85 } |
|
86 return NULL; |
|
87 } |
|
88 |
|
89 |
|
90 TInt CBytePairCompressedImage::ConstructL(TUint16 aNumberOfPages, TInt aSize) |
|
91 { |
|
92 //Print(EWarning,"Start ofCBytePairCompressedImage::ConstructL(%d, %d)\n", aNumberOfPages, aSize ); |
|
93 iHeader.iNumberOfPages = aNumberOfPages; |
|
94 iHeader.iDecompressedSize = aSize; |
|
95 |
|
96 if( 0 != aNumberOfPages) |
|
97 { |
|
98 iPages = (IndexTableItem *) calloc(aNumberOfPages, sizeof(IndexTableItem)); |
|
99 |
|
100 if( NULL == iPages ) |
|
101 { |
|
102 return KErrNoMemory; |
|
103 } |
|
104 } |
|
105 |
|
106 iHeader.iSizeOfData = sizeof(iHeader.iSizeOfData) + |
|
107 sizeof(iHeader.iDecompressedSize) + |
|
108 sizeof(iHeader.iNumberOfPages) + |
|
109 aNumberOfPages * sizeof(TUint16); |
|
110 |
|
111 iOutBuffer = (TUint8 *) calloc(4 * PAGE_SIZE, sizeof(TUint8) ); |
|
112 |
|
113 if ( NULL == iOutBuffer) |
|
114 { |
|
115 return KErrNoMemory; |
|
116 } |
|
117 return KErrNone; |
|
118 } // End of ConstructL() |
|
119 |
|
120 CBytePairCompressedImage::~CBytePairCompressedImage() |
|
121 { |
|
122 |
|
123 for( int i = 0; i < iHeader.iNumberOfPages; i++) |
|
124 { |
|
125 free(iPages[i].iCompressedPageData); |
|
126 iPages[i].iCompressedPageData = NULL; |
|
127 } |
|
128 |
|
129 free( iPages ); |
|
130 iPages = NULL; |
|
131 |
|
132 free( iOutBuffer ); |
|
133 iOutBuffer = NULL; |
|
134 } |
|
135 |
|
136 |
|
137 int CBytePairCompressedImage::ReadInTable(std::istream &is, TUint & aNumberOfPages) |
|
138 { |
|
139 // Read page index table header |
|
140 int count = (sizeof(iHeader.iSizeOfData)+sizeof(iHeader.iDecompressedSize)+sizeof(iHeader.iNumberOfPages)); |
|
141 is.read((char *)&iHeader, count); |
|
142 |
|
143 // Allocatin place to Page index table entries |
|
144 iPages = (IndexTableItem *) calloc(iHeader.iNumberOfPages, sizeof(IndexTableItem)); |
|
145 |
|
146 if( NULL == iPages ) |
|
147 { |
|
148 return KErrNoMemory; |
|
149 } |
|
150 |
|
151 // Read whole Page index table |
|
152 for(TInt i = 0; i < iHeader.iNumberOfPages; i++) |
|
153 { |
|
154 is.read((char *) &(iPages[i].iSizeOfCompressedPageData), sizeof(TUint16)); |
|
155 } |
|
156 |
|
157 // Read compressed data pages page by page, decompress and store them |
|
158 for(TInt i = 0; i < iHeader.iNumberOfPages; i++) |
|
159 { |
|
160 |
|
161 iPages[i].iCompressedPageData = (TUint8 *) calloc(iPages[i].iSizeOfCompressedPageData, sizeof(TUint8) ); |
|
162 |
|
163 if( NULL == iPages[i].iCompressedPageData ) |
|
164 { |
|
165 return KErrNoMemory; |
|
166 } |
|
167 |
|
168 is.read((char *)iPages[i].iCompressedPageData, iPages[i].iSizeOfCompressedPageData); |
|
169 } |
|
170 |
|
171 aNumberOfPages = iHeader.iNumberOfPages; |
|
172 |
|
173 return KErrNone; |
|
174 } |
|
175 |
|
176 int CBytePairCompressedImage::GetPage(TUint16 aPageNum, TUint8 * aPageData) |
|
177 { |
|
178 TUint8* pakEnd; |
|
179 |
|
180 |
|
181 TUint16 uncompressedSize = (TUint16) UnpackBytePair( aPageData, |
|
182 MaxBlockSize, |
|
183 iPages[aPageNum].iCompressedPageData, |
|
184 iPages[aPageNum].iSizeOfCompressedPageData, |
|
185 pakEnd ); |
|
186 |
|
187 return uncompressedSize; |
|
188 |
|
189 |
|
190 } |
|
191 |
|
192 |
|
193 |
|
194 int DecompressPages(TUint8 * bytes, std::istream& is) |
|
195 { |
|
196 TUint decompressedSize = 0; |
|
197 CBytePairCompressedImage *comprImage = CBytePairCompressedImage::NewLC(0, 0); |
|
198 if( NULL == comprImage) |
|
199 { |
|
200 return KErrNoMemory; |
|
201 } |
|
202 |
|
203 TUint numberOfPages = 0; |
|
204 comprImage->ReadInTable(is, numberOfPages); |
|
205 |
|
206 |
|
207 TUint8* iPageStart; |
|
208 TUint16 iPage = 0; |
|
209 |
|
210 while(iPage < numberOfPages ) |
|
211 { |
|
212 iPageStart = &bytes[iPage * PAGE_SIZE]; |
|
213 |
|
214 decompressedSize += comprImage->GetPage(iPage, iPageStart); |
|
215 |
|
216 ++iPage; |
|
217 } |
|
218 |
|
219 delete comprImage; |
|
220 return decompressedSize; |
|
221 |
|
222 } |
|
223 |
|
224 TInt UnpackBytePairE32Image( TUint8* aSource, TInt aSourceSize, TUint8* aDest, TInt aDestSize, TInt& aInputBytesRead ) |
|
225 { |
|
226 istrstream stream( (const char*) aSource, aSourceSize ); |
|
227 const streampos startPos = stream.tellg(); |
|
228 const TInt ret = DecompressPages( aDest, stream ); |
|
229 const streampos endPos = stream.tellg(); |
|
230 aInputBytesRead = endPos - startPos; |
|
231 return ret; |
|
232 } |