|
1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <barsc.h> |
|
17 #include <barsread.h> |
|
18 #include <bautils.h> |
|
19 #include <imageconversion.h> |
|
20 #include "ImageClientMain.h" |
|
21 #include "ImageUtils.h" |
|
22 #include <101F45C0_extra.rsg> |
|
23 #include "icl/ICL_UIDS.hrh" |
|
24 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
25 #include <icl/icl_uids_const.hrh> |
|
26 #include <icl/icl_uids_def.hrh> |
|
27 #include <icl/imagecodecdef.h> |
|
28 #endif |
|
29 #include "TIFFCodec.h" |
|
30 |
|
31 _LIT(KTIFFPanicCategory, "TIFFConvertPlugin"); |
|
32 |
|
33 // Global panic function |
|
34 GLDEF_C void Panic(TIclPanic aError) |
|
35 { |
|
36 User::Panic(KTIFFPanicCategory, aError); |
|
37 } |
|
38 |
|
39 // TTiffValueReader. |
|
40 TUint32 TTiffValueReader::ReadUint32(const TUint8* aPtr) const |
|
41 { |
|
42 TUint value; |
|
43 if (iEndianness == ETiffLittleEndian) |
|
44 { |
|
45 value = aPtr[0]; |
|
46 value |= aPtr[1] << 8; |
|
47 value |= aPtr[2] << 16; |
|
48 value |= aPtr[3] << 24; |
|
49 } |
|
50 else |
|
51 { |
|
52 value = aPtr[0] << 24; |
|
53 value |= aPtr[1] << 16; |
|
54 value |= aPtr[2] << 8; |
|
55 value |= aPtr[3]; |
|
56 } |
|
57 return TUint32(value); |
|
58 } |
|
59 |
|
60 TUint16 TTiffValueReader::ReadUint16(const TUint8* aPtr) const |
|
61 { |
|
62 TUint value; |
|
63 if (iEndianness == ETiffLittleEndian) |
|
64 { |
|
65 value = aPtr[0]; |
|
66 value |= aPtr[1] << 8; |
|
67 } |
|
68 else |
|
69 { |
|
70 value = aPtr[0] << 8; |
|
71 value |= aPtr[1]; |
|
72 } |
|
73 return TUint16(value); |
|
74 } |
|
75 |
|
76 |
|
77 // Tiff decoder. |
|
78 CTiffDecoder* CTiffDecoder::NewL() |
|
79 { |
|
80 return new(ELeave) CTiffDecoder(ETiffUnknownSubType); |
|
81 } |
|
82 |
|
83 CTiffDecoder* CTiffDecoder::NewLittleEndianL() |
|
84 { |
|
85 return new(ELeave) CTiffDecoder(ETiffLittleEndianSubType); |
|
86 } |
|
87 |
|
88 CTiffDecoder* CTiffDecoder::NewBigEndianL() |
|
89 { |
|
90 return new(ELeave) CTiffDecoder(ETiffBigEndianSubType); |
|
91 } |
|
92 |
|
93 CTiffDecoder::CTiffDecoder(TTiffSubType aTiffSubType) |
|
94 { |
|
95 iTiffSubType = aTiffSubType; |
|
96 } |
|
97 |
|
98 CTiffDecoder::~CTiffDecoder() |
|
99 { |
|
100 Cleanup(); |
|
101 } |
|
102 |
|
103 void CTiffDecoder::Cleanup() |
|
104 { |
|
105 // Delete any objects we should get rid of |
|
106 |
|
107 // Base class included |
|
108 CImageDecoderPlugin::Cleanup(); |
|
109 } |
|
110 |
|
111 void CTiffDecoder::ImageType(TInt aFrameNumber, TUid& aImageType, TUid& aImageSubType) const |
|
112 { |
|
113 __ASSERT_ALWAYS((aFrameNumber >= 0) && (aFrameNumber < NumberOfFrames()), Panic(EFrameNumberOutOfRange)); |
|
114 aImageType = KImageTypeTIFFUid; |
|
115 if (iTiffSubType == ETiffLittleEndianSubType) |
|
116 aImageSubType = KImageTypeTIFFSubTypeLittleEndianUid; |
|
117 else |
|
118 aImageSubType = KImageTypeTIFFSubTypeBigEndianUid; |
|
119 } |
|
120 |
|
121 // Scan header. |
|
122 void CTiffDecoder::ScanDataL() |
|
123 { |
|
124 ReadFormatL(); |
|
125 |
|
126 ASSERT(ImageReadCodec() == NULL); |
|
127 |
|
128 CTiffReadCodec* imageReadCodec; |
|
129 |
|
130 imageReadCodec = CTiffReadCodec::NewL(iFormatInfo, *this); |
|
131 |
|
132 SetImageReadCodec(imageReadCodec); |
|
133 |
|
134 ReadFrameHeadersL(); |
|
135 } |
|
136 |
|
137 #define KTiffHeaderLittleEndianDefine { 0x49, 0x49, 0x2A, 0x00 } |
|
138 #define KTiffHeaderBigEndianDefine { 0x4D, 0x4D, 0x00, 0x2A } |
|
139 LOCAL_D const TUint8 TiffLittleEndianSignature[KTiffSignatureLength] = KTiffHeaderLittleEndianDefine; |
|
140 LOCAL_D const TUint8 TiffBigEndianSignature[KTiffSignatureLength] = KTiffHeaderBigEndianDefine; |
|
141 void CTiffDecoder::ReadFormatL() |
|
142 { |
|
143 TPtrC8 bufferDes; |
|
144 |
|
145 ReadDataL(0, bufferDes, KTiffHeaderSize); |
|
146 |
|
147 // Validate the header. |
|
148 if (bufferDes.Length() < KTiffHeaderSize) |
|
149 User::Leave(KErrUnderflow); |
|
150 |
|
151 iFormatInfo.iSignature = PtrReadUtil::ReadUint32(CONST_CAST(TUint8*, bufferDes.Ptr())); |
|
152 |
|
153 switch (iTiffSubType) |
|
154 { |
|
155 case ETiffUnknownSubType: |
|
156 if (iFormatInfo.iSignature == *REINTERPRET_CAST(const TUint32*,TiffLittleEndianSignature)) |
|
157 iFormatInfo.iEndianness = ETiffLittleEndian; |
|
158 else if (iFormatInfo.iSignature == *REINTERPRET_CAST(const TUint32*,TiffBigEndianSignature)) |
|
159 iFormatInfo.iEndianness = ETiffBigEndian; |
|
160 else |
|
161 User::Leave(KErrCorrupt); |
|
162 break; |
|
163 |
|
164 case ETiffLittleEndianSubType: |
|
165 if (iFormatInfo.iSignature != *REINTERPRET_CAST(const TUint32*,TiffLittleEndianSignature)) |
|
166 User::Leave(KErrCorrupt); |
|
167 |
|
168 iFormatInfo.iEndianness = ETiffLittleEndian; |
|
169 break; |
|
170 |
|
171 case ETiffBigEndianSubType: |
|
172 if (iFormatInfo.iSignature != *REINTERPRET_CAST(const TUint32*,TiffBigEndianSignature)) |
|
173 User::Leave(KErrCorrupt); |
|
174 |
|
175 iFormatInfo.iEndianness = ETiffBigEndian; |
|
176 break; |
|
177 } |
|
178 |
|
179 TTiffValueReader valueReader = TTiffValueReader(iFormatInfo.iEndianness); |
|
180 |
|
181 const TUint8* ifdPtr = &bufferDes[KTiffSignatureLength]; |
|
182 iFormatInfo.iFirstIfd = valueReader.ReadUint32(ifdPtr); |
|
183 |
|
184 //Ifd (offset in file) should always be pointing to bytes after header. |
|
185 if (iFormatInfo.iFirstIfd < KTiffSignatureLength) |
|
186 { |
|
187 User::Leave(KErrCorrupt); |
|
188 } |
|
189 |
|
190 SetStartPosition(iFormatInfo.iFirstIfd); |
|
191 |
|
192 // Set max data length, since header does not contain this information. |
|
193 SetDataLength(KMaxTInt); |
|
194 } |
|
195 |
|
196 CFrameInfoStrings* CTiffDecoder::FrameInfoStringsL(RFs& aFs, TInt aFrameNumber) |
|
197 { |
|
198 |
|
199 const TUid KTiffCodecDllUid = {KTIFFCodecDllUidValue}; |
|
200 |
|
201 RResourceFile resourceFile; |
|
202 OpenExtraResourceFileLC(aFs,KTiffCodecDllUid,resourceFile); |
|
203 |
|
204 HBufC8* resourceInfo = resourceFile.AllocReadLC(THEDECODERINFO); |
|
205 TResourceReader resourceReader; |
|
206 resourceReader.SetBuffer(resourceInfo); |
|
207 |
|
208 TBuf<KCodecResourceStringMax> info; |
|
209 TBuf<KCodecResourceStringMax> templte; |
|
210 |
|
211 const TFrameInfo& frameInfo = FrameInfo(aFrameNumber); |
|
212 const CFrameImageData& frameData = FrameData(aFrameNumber); |
|
213 const TTiffImageData* tiffImageData = STATIC_CAST(const TTiffImageData*, frameData.GetFrameData(0)); |
|
214 |
|
215 CFrameInfoStrings* frameInfoStrings = CFrameInfoStrings::NewLC(); |
|
216 |
|
217 info = resourceReader.ReadTPtrC(); |
|
218 frameInfoStrings->SetDecoderL(info); |
|
219 |
|
220 CDesCArrayFlat* resourceArray = resourceReader.ReadDesCArrayL(); |
|
221 CleanupStack::PushL(resourceArray); |
|
222 TUint formatIndex; |
|
223 switch (tiffImageData->iCompression) |
|
224 { |
|
225 case TTiffIfdEntry::EGroup3FaxCompression: |
|
226 if (tiffImageData->iT4Options & TTiffIfdEntry::ET4TwoDimentionalCoding) |
|
227 formatIndex = EFormatGroup3Fax2D; |
|
228 else |
|
229 formatIndex = EFormatGroup3Fax1D; |
|
230 break; |
|
231 |
|
232 case TTiffIfdEntry::EGroup4FaxCompression: |
|
233 formatIndex = EFormatGroup4Fax; |
|
234 break; |
|
235 |
|
236 default: |
|
237 formatIndex = EFormatUnknown; |
|
238 break; |
|
239 } |
|
240 info = (*resourceArray)[formatIndex]; |
|
241 CleanupStack::PopAndDestroy(resourceArray); |
|
242 frameInfoStrings->SetFormatL(info); |
|
243 |
|
244 TInt width = frameInfo.iOverallSizeInPixels.iWidth; |
|
245 TInt height = frameInfo.iOverallSizeInPixels.iHeight; |
|
246 TInt depth = frameInfo.iBitsPerPixel; |
|
247 |
|
248 templte = resourceReader.ReadTPtrC(); |
|
249 info.Format(templte, width, height); |
|
250 frameInfoStrings->SetDimensionsL(info); |
|
251 |
|
252 resourceArray = resourceReader.ReadDesCArrayL(); |
|
253 CleanupStack::PushL(resourceArray); |
|
254 formatIndex = (frameInfo.iFlags & TFrameInfo::EColor) ? 1 : 0; |
|
255 templte = (*resourceArray)[formatIndex]; |
|
256 CleanupStack::PopAndDestroy(resourceArray); |
|
257 info.Format(templte, depth); |
|
258 frameInfoStrings->SetDepthL(info); |
|
259 |
|
260 // leave details blank |
|
261 |
|
262 CleanupStack::Pop(frameInfoStrings); |
|
263 CleanupStack::PopAndDestroy(2); // resourceInfo + resourceFile |
|
264 return frameInfoStrings; |
|
265 } |
|
266 |
|
267 TInt CTiffDecoder::CurrentFilePosition() |
|
268 { |
|
269 return StartPosition() + Position(); |
|
270 } |
|
271 |