|
1 /* |
|
2 * Copyright (c) 2005-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 |
|
18 |
|
19 |
|
20 |
|
21 #include "stdafx.h" |
|
22 #include "afxpriv.h" |
|
23 #include "CSTATDataFormatConverter.h" |
|
24 |
|
25 //------------------------------------------------------------------------------- |
|
26 //standard functions for new variant class |
|
27 CSTATDataFormatConverter::CSTATDataFormatConverter(CSTATLogFile *pLog) |
|
28 : bWriteToFile(true) |
|
29 { |
|
30 vt = VT_BLOB; |
|
31 |
|
32 BLOB* pBody = new BLOB; |
|
33 byref = pBody; |
|
34 pBody->pBlobData = m_index = new BYTE [16]; //16 is the default buffer size |
|
35 pBody->cbSize = m_bufsize = 16; |
|
36 |
|
37 // set up logging |
|
38 pLogFile = pLog; |
|
39 |
|
40 // reset bitmap structures |
|
41 memset(&iPbmHeader, 0xff, sizeof(iPbmHeader)); |
|
42 memset(&fileheader, 0xff, sizeof(fileheader)); |
|
43 memset(&bmpHeader, 0xff, sizeof(bmpHeader)); |
|
44 pPbmBits = NULL; |
|
45 bmpBits = NULL; |
|
46 lDataSize = 0; |
|
47 } |
|
48 |
|
49 //------------------------------------------------------------------------------- |
|
50 |
|
51 //Destructor |
|
52 CSTATDataFormatConverter::~CSTATDataFormatConverter() |
|
53 { |
|
54 BLOB* pBody = (BLOB*)byref; |
|
55 if (pBody) |
|
56 { |
|
57 if (pBody->pBlobData) |
|
58 delete [] pBody->pBlobData; |
|
59 |
|
60 delete pBody; |
|
61 } |
|
62 |
|
63 if (pPbmBits) |
|
64 { |
|
65 delete [] pPbmBits; |
|
66 pPbmBits = NULL; |
|
67 } |
|
68 |
|
69 if (bmpBits) |
|
70 { |
|
71 delete [] bmpBits; |
|
72 bmpBits = NULL; |
|
73 } |
|
74 } |
|
75 |
|
76 //---------------------------------------------------------------------------- |
|
77 |
|
78 bool CSTATDataFormatConverter::ConvertStringToUnicode(CString& data) |
|
79 { |
|
80 // clear the existing buffer |
|
81 ((BLOB*)byref)->cbSize = 0; |
|
82 |
|
83 // length IN BYTES of the UNICODE result (not the TCHAR input) |
|
84 UINT len = (data.GetLength() + 1) * 2; |
|
85 |
|
86 // check that the buffer can hold the contents -- otherwise enlarge |
|
87 EnsureBufSize( len ); |
|
88 |
|
89 // convert the input string to unicode |
|
90 USES_CONVERSION; |
|
91 LPWSTR wstr = T2W(data.GetBuffer(0)); |
|
92 |
|
93 // copy data into the buffer and set the size |
|
94 memcpy( m_index, wstr, len); |
|
95 ((BLOB*)byref)->cbSize = len; |
|
96 |
|
97 // done |
|
98 return true; |
|
99 } |
|
100 |
|
101 //---------------------------------------------------------------------------- |
|
102 |
|
103 void CSTATDataFormatConverter::EnsureBufSize(int size) |
|
104 { |
|
105 if (size > m_bufsize) |
|
106 { |
|
107 BLOB* pBody = (BLOB*)byref; |
|
108 BYTE* newbuf = new BYTE [size]; |
|
109 delete[] pBody->pBlobData; |
|
110 m_index = pBody->pBlobData = newbuf; |
|
111 m_bufsize = size; |
|
112 } |
|
113 } |
|
114 |
|
115 //---------------------------------------------------------------------------- |
|
116 //Converts from .mbm to .bmp |
|
117 int |
|
118 CSTATDataFormatConverter::ConvertScreenShot(CString &mbmdirectory, CString &destdir) |
|
119 { |
|
120 CFileFind imagefinder; |
|
121 CString searchpattern = mbmdirectory; |
|
122 if (searchpattern.Right(1) != _T('\\')) |
|
123 searchpattern += _T("\\"); |
|
124 searchpattern += "*.mbm"; |
|
125 |
|
126 // there will only ever be one file to be converted at a time |
|
127 if (imagefinder.FindFile(searchpattern, 0)) |
|
128 { |
|
129 imagefinder.FindNextFile(); |
|
130 |
|
131 // get the source filename (in quotes) |
|
132 CString imagefilename = _T("\""); |
|
133 imagefilename += imagefinder.GetFilePath(); |
|
134 imagefilename += _T("\""); |
|
135 |
|
136 // get the destination folder (in quotes) |
|
137 CString newimagefilename = _T("\""); |
|
138 newimagefilename += destdir; |
|
139 |
|
140 // add a backslash if we need one |
|
141 if (newimagefilename.Right(1) != _T("\\")) |
|
142 newimagefilename += _T("\\"); |
|
143 |
|
144 // add the filename |
|
145 newimagefilename += imagefinder.GetFileName(); |
|
146 newimagefilename.Replace(_T(".mbm"), _T(".bmp")); |
|
147 newimagefilename += _T("\""); |
|
148 imagefinder.Close(); |
|
149 |
|
150 // remove dest file if it already exists |
|
151 if(imagefinder.FindFile(newimagefilename, 0)) |
|
152 { |
|
153 imagefinder.Close(); |
|
154 DeleteFile(newimagefilename); |
|
155 } |
|
156 |
|
157 imagefilename.Remove('\"'); |
|
158 newimagefilename.Remove('\"'); |
|
159 |
|
160 if (bWriteToFile) |
|
161 { |
|
162 pLogFile->Set(CONVERTINGIMAGE, imagefilename.GetBuffer(0)); |
|
163 pLogFile->Set(TO, newimagefilename.GetBuffer(0)); |
|
164 } |
|
165 else |
|
166 pLogFile->Set(READINGIMAGE, imagefilename.GetBuffer(0)); |
|
167 |
|
168 // convert the bitmap |
|
169 int errorcode = LoadBitmap(imagefilename); |
|
170 if (errorcode != ITS_OK) |
|
171 return pLogFile->Set(E_BITMAPLOADFAILED, pLogFile->Text(errorcode)); |
|
172 |
|
173 if ((errorcode = SaveBitmap(newimagefilename)) != ITS_OK) |
|
174 return pLogFile->Set(E_BITMAPSAVEFAILED, pLogFile->Text(errorcode)); |
|
175 |
|
176 DeleteFile(imagefilename); //delete original .mbm image |
|
177 |
|
178 // success |
|
179 mbmdirectory = newimagefilename; |
|
180 |
|
181 // log a message that desktop STAT can use to display bitmap |
|
182 pLogFile->Set(SCREENSHOT_CONVERSION_OK, mbmdirectory, false, true); |
|
183 |
|
184 return ITS_OK; |
|
185 } |
|
186 |
|
187 return pLogFile->Set(E_NOIMAGESTOCONVERT, searchpattern); |
|
188 } |
|
189 |
|
190 //---------------------------------------------------------------------------- |
|
191 int CSTATDataFormatConverter::LoadBitmap(CString &file) |
|
192 { |
|
193 // reset structures |
|
194 memset(&iPbmHeader, 0xff, sizeof(iPbmHeader)); |
|
195 if (pPbmBits) |
|
196 { |
|
197 delete [] pPbmBits; |
|
198 pPbmBits = NULL; |
|
199 } |
|
200 |
|
201 // open file |
|
202 HANDLE infile; |
|
203 if (INVALID_HANDLE_VALUE != (infile = CreateFile(file, |
|
204 GENERIC_READ, |
|
205 FILE_SHARE_READ, |
|
206 NULL, |
|
207 OPEN_EXISTING, |
|
208 FILE_ATTRIBUTE_NORMAL, |
|
209 0))) |
|
210 { |
|
211 long int iBuffer; |
|
212 DWORD dwBytesRead = 0; |
|
213 |
|
214 // read the header to ensure it is a valid file |
|
215 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
216 dwBytesRead != 4 || iBuffer != KWriteOnceFileStoreUid) |
|
217 { |
|
218 CloseHandle(infile); |
|
219 return E_BADFORMAT; |
|
220 } |
|
221 |
|
222 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
223 dwBytesRead != 4 || iBuffer != KMultiBitmapFileImageUid) |
|
224 { |
|
225 CloseHandle(infile); |
|
226 return E_BADFORMAT; |
|
227 } |
|
228 |
|
229 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
230 dwBytesRead != 4 || iBuffer != 0) |
|
231 { |
|
232 CloseHandle(infile); |
|
233 return E_BADFORMAT; |
|
234 } |
|
235 |
|
236 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
237 dwBytesRead != 4 || iBuffer != KMultiBitmapFileImageChecksum) |
|
238 { |
|
239 CloseHandle(infile); |
|
240 return E_BADFORMAT; |
|
241 } |
|
242 |
|
243 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
244 dwBytesRead != 4) |
|
245 { |
|
246 CloseHandle(infile); |
|
247 return E_BADFORMAT; |
|
248 } |
|
249 |
|
250 // go back to offset from the beginning |
|
251 if (SetFilePointer(infile, iBuffer, NULL, FILE_BEGIN) == 0xFFFFFFFF) |
|
252 { |
|
253 CloseHandle(infile); |
|
254 return E_BADFORMAT; |
|
255 } |
|
256 |
|
257 // read the number of sources (in our case it will always be one) |
|
258 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
259 dwBytesRead != 4) |
|
260 { |
|
261 CloseHandle(infile); |
|
262 return E_BADFORMAT; |
|
263 } |
|
264 |
|
265 // read offset from the beginning of this bitmap |
|
266 if (!ReadFile(infile, (LPVOID *)&iBuffer, 4, &dwBytesRead, NULL) || |
|
267 dwBytesRead != 4) |
|
268 { |
|
269 CloseHandle(infile); |
|
270 return E_BADFORMAT; |
|
271 } |
|
272 |
|
273 // go back to offset from the beginning |
|
274 if (SetFilePointer(infile, iBuffer, NULL, FILE_BEGIN) == 0xFFFFFFFF) |
|
275 { |
|
276 CloseHandle(infile); |
|
277 return E_BADFORMAT; |
|
278 } |
|
279 |
|
280 // read in the header |
|
281 DWORD dwSize = sizeof(SEpocBitmapHeader); |
|
282 if (!ReadFile(infile, (LPVOID *)&iPbmHeader, dwSize, &dwBytesRead, NULL) || dwBytesRead != dwSize) |
|
283 { |
|
284 CloseHandle(infile); |
|
285 return E_BADFORMAT; |
|
286 } |
|
287 |
|
288 dwSize = iPbmHeader.iBitmapSize - iPbmHeader.iStructSize; |
|
289 |
|
290 // now read in the bitmap matrix |
|
291 pPbmBits = new char[dwSize]; |
|
292 if (pPbmBits) |
|
293 { |
|
294 memset(pPbmBits, 0xff, dwSize); |
|
295 if (!ReadFile(infile, (LPVOID *)pPbmBits, dwSize, &dwBytesRead, NULL) || dwBytesRead != dwSize) |
|
296 { |
|
297 CloseHandle(infile); |
|
298 return E_BADFORMAT; |
|
299 } |
|
300 |
|
301 if (iPbmHeader.iCompression != ENoBitmapCompression) |
|
302 { |
|
303 int byteWidth = ByteWidth(iPbmHeader.iWidthInPixels, iPbmHeader.iBitsPerPixel); |
|
304 int expandedsize = byteWidth * iPbmHeader.iHeightInPixels; |
|
305 char* newbits = new char[expandedsize]; |
|
306 if (newbits) |
|
307 { |
|
308 memset(newbits,0xff,expandedsize); |
|
309 int ret = ITS_OK; |
|
310 |
|
311 switch (iPbmHeader.iCompression) |
|
312 { |
|
313 case EByteRLECompression: |
|
314 ret = ExpandByteRLEData(newbits,expandedsize,pPbmBits, dwSize); |
|
315 break; |
|
316 case ETwelveBitRLECompression: |
|
317 ret = ExpandTwelveBitRLEData(newbits,expandedsize,pPbmBits, dwSize); |
|
318 break; |
|
319 case ESixteenBitRLECompression: |
|
320 ret = ExpandSixteenBitRLEData(newbits,expandedsize,pPbmBits, dwSize); |
|
321 break; |
|
322 case ETwentyFourBitRLECompression: |
|
323 ret = ExpandTwentyFourBitRLEData(newbits,expandedsize,pPbmBits, dwSize); |
|
324 break; |
|
325 default: |
|
326 delete [] pPbmBits; |
|
327 return E_BADCOMPRESSION; |
|
328 break; |
|
329 } |
|
330 |
|
331 delete [] pPbmBits; |
|
332 pPbmBits = newbits; |
|
333 iPbmHeader.iCompression = ENoBitmapCompression; |
|
334 iPbmHeader.iBitmapSize += expandedsize - dwSize; |
|
335 } |
|
336 else |
|
337 { |
|
338 CloseHandle(infile); |
|
339 return E_OUTOFMEM; |
|
340 } |
|
341 } |
|
342 |
|
343 CloseHandle(infile); |
|
344 } |
|
345 else |
|
346 { |
|
347 CloseHandle(infile); |
|
348 return E_OUTOFMEM; |
|
349 } |
|
350 } |
|
351 else |
|
352 return E_FILE_OPEN_READ_FAILED; |
|
353 |
|
354 return ITS_OK; |
|
355 } |
|
356 |
|
357 bool |
|
358 CSTATDataFormatConverter::ExpandByteRLEData(char* aDest,int aDestSize,char* aSrce,int aSrceSize) |
|
359 { |
|
360 char* srcelimit=aSrce+aSrceSize; |
|
361 char* destlimit=aDest+aDestSize; |
|
362 while(aSrce<srcelimit && aDest<destlimit) |
|
363 { |
|
364 char count=*aSrce++; |
|
365 if (count<0) |
|
366 { |
|
367 int runLength=-count; |
|
368 memcpy(aDest,aSrce,runLength); |
|
369 aSrce+=runLength; |
|
370 aDest+=runLength; |
|
371 } |
|
372 else |
|
373 { |
|
374 char value=*aSrce++; |
|
375 while(count>=0) |
|
376 { |
|
377 *aDest++=value; |
|
378 count--; |
|
379 } |
|
380 } |
|
381 } |
|
382 if (aSrce!=srcelimit || aDest!=destlimit) |
|
383 return false; |
|
384 |
|
385 return true; |
|
386 } |
|
387 |
|
388 bool |
|
389 CSTATDataFormatConverter::ExpandTwelveBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) |
|
390 { |
|
391 unsigned short* srcePtr = (unsigned short*)aSrce; |
|
392 unsigned short* destPtr = (unsigned short*)aDest; |
|
393 unsigned short* srcePtrLimit = srcePtr + (aSrceSizeInBytes / 2); |
|
394 unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); |
|
395 |
|
396 while (srcePtr < srcePtrLimit && destPtr < destPtrLimit) |
|
397 { |
|
398 unsigned short value = *srcePtr++; |
|
399 int runLength = (value >> 12) + 1; |
|
400 value &= 0x0fff; |
|
401 |
|
402 for (;runLength > 0;runLength--) |
|
403 *destPtr++ = value; |
|
404 } |
|
405 |
|
406 if (srcePtr != srcePtrLimit || destPtr != destPtrLimit) |
|
407 return false; |
|
408 |
|
409 return true; |
|
410 } |
|
411 |
|
412 bool |
|
413 CSTATDataFormatConverter::ExpandSixteenBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) |
|
414 { |
|
415 char* srcePtrLimit = aSrce + aSrceSizeInBytes; |
|
416 unsigned short* destPtr = (unsigned short*)aDest; |
|
417 unsigned short* destPtrLimit = destPtr + (aDestSizeInBytes / 2); |
|
418 |
|
419 while (aSrce < srcePtrLimit && destPtr < destPtrLimit) |
|
420 { |
|
421 int runLength = *aSrce++; |
|
422 |
|
423 if (runLength >= 0) |
|
424 { |
|
425 unsigned short value = *((unsigned short*)(aSrce)); |
|
426 aSrce += 2; |
|
427 for (runLength++; runLength > 0; runLength--) |
|
428 *destPtr++ = value; |
|
429 } |
|
430 else |
|
431 { |
|
432 runLength = -runLength; |
|
433 int byteLength = runLength * 2; |
|
434 memcpy(destPtr,aSrce,byteLength); |
|
435 aSrce += byteLength; |
|
436 destPtr += runLength; |
|
437 } |
|
438 } |
|
439 |
|
440 if (aSrce != srcePtrLimit || destPtr != destPtrLimit) |
|
441 return false; |
|
442 |
|
443 return true; |
|
444 } |
|
445 |
|
446 bool |
|
447 CSTATDataFormatConverter::ExpandTwentyFourBitRLEData(char* aDest,int aDestSizeInBytes,char* aSrce,int aSrceSizeInBytes) |
|
448 { |
|
449 char* srcePtrLimit = aSrce + aSrceSizeInBytes; |
|
450 char* destPtrLimit = aDest + aDestSizeInBytes; |
|
451 |
|
452 while (aSrce < srcePtrLimit && aDest < destPtrLimit) |
|
453 { |
|
454 int runLength = *aSrce++; |
|
455 |
|
456 if (runLength >= 0) |
|
457 { |
|
458 char component1 = *aSrce++; |
|
459 char component2 = *aSrce++; |
|
460 char component3 = *aSrce++; |
|
461 for (runLength++; runLength > 0; runLength--) |
|
462 { |
|
463 *aDest++ = component1; |
|
464 *aDest++ = component2; |
|
465 *aDest++ = component3; |
|
466 } |
|
467 } |
|
468 else |
|
469 { |
|
470 runLength = -runLength; |
|
471 int byteLength = runLength * 3; |
|
472 memcpy(aDest,aSrce,byteLength); |
|
473 aSrce += byteLength; |
|
474 aDest += byteLength; |
|
475 } |
|
476 } |
|
477 |
|
478 if (aSrce != srcePtrLimit || aDest != destPtrLimit) |
|
479 return false; |
|
480 |
|
481 return true; |
|
482 } |
|
483 |
|
484 int |
|
485 CSTATDataFormatConverter::SaveBitmap(CString &newfilename) |
|
486 { |
|
487 // reset structures |
|
488 memset(&fileheader, 0xff, sizeof(fileheader)); |
|
489 memset(&bmpHeader, 0xff, sizeof(bmpHeader)); |
|
490 if (bmpBits) |
|
491 { |
|
492 delete [] bmpBits; |
|
493 bmpBits = NULL; |
|
494 } |
|
495 lDataSize = 0; |
|
496 |
|
497 // copy header info into BMP structures |
|
498 bmpHeader.biSize = sizeof(TBitmapInfoHeader); |
|
499 bmpHeader.biWidth = iPbmHeader.iWidthInPixels; |
|
500 bmpHeader.biHeight = iPbmHeader.iHeightInPixels; |
|
501 bmpHeader.biPlanes = 1; |
|
502 bmpHeader.biBitCount = 24; |
|
503 bmpHeader.biCompression = 0; |
|
504 bmpHeader.biSizeImage = 0; |
|
505 bmpHeader.biXPelsPerMeter = 0; |
|
506 bmpHeader.biYPelsPerMeter = 0; |
|
507 bmpHeader.biClrUsed = 0; |
|
508 bmpHeader.biClrImportant = 0; |
|
509 |
|
510 long byteWidth = ((bmpHeader.biWidth * 3) + 3) & ~3; |
|
511 lDataSize = bmpHeader.biHeight * byteWidth; |
|
512 |
|
513 fileheader.bfType = 'B'+('M'<<8); |
|
514 fileheader.bfSize = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader) + lDataSize; |
|
515 fileheader.bfReserved1 = 0; |
|
516 fileheader.bfReserved2 = 0; |
|
517 fileheader.bfOffBits = sizeof(TBitmapFileHeader)+sizeof(TBitmapInfoHeader); |
|
518 |
|
519 // copy BMP data |
|
520 bmpBits = new char[lDataSize]; |
|
521 if (!bmpBits) |
|
522 return E_OUTOFMEM; |
|
523 |
|
524 memset(bmpBits,0xff,lDataSize); |
|
525 |
|
526 for(long y=0;y<bmpHeader.biHeight;y++) |
|
527 { |
|
528 char* dest=&bmpBits[(bmpHeader.biHeight-y-1)*byteWidth]; |
|
529 for(long x=0;x<bmpHeader.biWidth;x++) |
|
530 { |
|
531 TRgb pixel=GetPixel(x,y); |
|
532 *dest++=pixel.iBlue; |
|
533 *dest++=pixel.iGreen; |
|
534 *dest++=pixel.iRed; |
|
535 } |
|
536 } |
|
537 |
|
538 int ret = ITS_OK; |
|
539 if (bWriteToFile) |
|
540 { |
|
541 // write the whole lot out to file |
|
542 HANDLE infile; |
|
543 if (INVALID_HANDLE_VALUE != (infile = CreateFile(newfilename, |
|
544 GENERIC_WRITE, |
|
545 0, |
|
546 NULL, |
|
547 CREATE_ALWAYS, |
|
548 FILE_ATTRIBUTE_NORMAL, |
|
549 0))) |
|
550 { |
|
551 DWORD dwBytesWritten = 0; |
|
552 |
|
553 // read the header to ensure it is a valid file |
|
554 if (WriteFile(infile, (LPVOID *)&fileheader, sizeof(TBitmapFileHeader), &dwBytesWritten, NULL) && |
|
555 dwBytesWritten == sizeof(TBitmapFileHeader)) |
|
556 { |
|
557 // read the header to ensure it is a valid file |
|
558 if (WriteFile(infile, (LPVOID *)&bmpHeader, sizeof(TBitmapInfoHeader), &dwBytesWritten, NULL) && |
|
559 dwBytesWritten == sizeof(TBitmapInfoHeader)) |
|
560 { |
|
561 if (WriteFile(infile, (LPVOID *)bmpBits, lDataSize, &dwBytesWritten, NULL) && |
|
562 dwBytesWritten == lDataSize) |
|
563 { |
|
564 ret = ITS_OK; |
|
565 } |
|
566 else |
|
567 ret = E_BADWRITE; |
|
568 } |
|
569 else |
|
570 ret = E_BADWRITE; |
|
571 } |
|
572 else |
|
573 ret = E_BADWRITE; |
|
574 |
|
575 CloseHandle(infile); |
|
576 } |
|
577 else |
|
578 ret = E_FILE_OPEN_WRITE_FAILED; |
|
579 } |
|
580 |
|
581 return ret; |
|
582 } |
|
583 |
|
584 TRgb |
|
585 CSTATDataFormatConverter::GetPixel(int aXCoord,int aYCoord) |
|
586 { |
|
587 unsigned char col; |
|
588 aXCoord%=iPbmHeader.iWidthInPixels; |
|
589 aYCoord%=iPbmHeader.iHeightInPixels; |
|
590 int byteWidth = ByteWidth(iPbmHeader.iWidthInPixels,iPbmHeader.iBitsPerPixel); |
|
591 int yOffset = aYCoord * byteWidth; |
|
592 |
|
593 switch(iPbmHeader.iBitsPerPixel) |
|
594 { |
|
595 case 1: |
|
596 col = pPbmBits[yOffset + (aXCoord / 8)]; |
|
597 col >>= (aXCoord&7); |
|
598 return TRgb::Gray2(col & 1); |
|
599 case 2: |
|
600 col = pPbmBits[yOffset + (aXCoord / 4)]; |
|
601 col = (unsigned char)(col>>(2*(aXCoord%4))); |
|
602 return TRgb::Gray4(col & 3); |
|
603 case 4: |
|
604 col = pPbmBits[yOffset + (aXCoord / 2)]; |
|
605 if (aXCoord & 1) |
|
606 col >>= 4; |
|
607 col &= 0xf; |
|
608 if (iPbmHeader.iColor==EColorBitmap) |
|
609 return TRgb::Color16(col); |
|
610 else |
|
611 return TRgb::Gray16(col); |
|
612 case 8: |
|
613 col=pPbmBits[yOffset + aXCoord]; |
|
614 if (iPbmHeader.iColor==EColorBitmap) |
|
615 return TRgb::Color256(col); |
|
616 else |
|
617 return TRgb::Gray256(col); |
|
618 case 12: |
|
619 case 16: |
|
620 { |
|
621 unsigned short* shortPtr = (unsigned short*)&pPbmBits[yOffset + (aXCoord * 2)]; |
|
622 if (iPbmHeader.iBitsPerPixel == 12) |
|
623 return TRgb::Color4K(*shortPtr); |
|
624 else |
|
625 return TRgb::Color64K(*shortPtr); |
|
626 } |
|
627 case 24: |
|
628 { |
|
629 char* pixelPtr = pPbmBits + yOffset + (aXCoord * 3); |
|
630 TRgb pixelColor; |
|
631 pixelColor.iBlue = *pixelPtr++; |
|
632 pixelColor.iGreen = *pixelPtr++; |
|
633 pixelColor.iRed = *pixelPtr; |
|
634 return pixelColor; |
|
635 } |
|
636 default: |
|
637 return TRgb(0); |
|
638 } |
|
639 } |
|
640 |
|
641 int |
|
642 CSTATDataFormatConverter::ByteWidth(int aPixelWidth,int aBitsPerPixel) |
|
643 { |
|
644 int wordWidth = 0; |
|
645 |
|
646 switch (aBitsPerPixel) |
|
647 { |
|
648 case 1: |
|
649 wordWidth = (aPixelWidth + 31) / 32; |
|
650 break; |
|
651 case 2: |
|
652 wordWidth = (aPixelWidth + 15) / 16; |
|
653 break; |
|
654 case 4: |
|
655 wordWidth = (aPixelWidth + 7) / 8; |
|
656 break; |
|
657 case 8: |
|
658 wordWidth = (aPixelWidth + 3) / 4; |
|
659 break; |
|
660 case 12: |
|
661 case 16: |
|
662 wordWidth = (aPixelWidth + 1) / 2; |
|
663 break; |
|
664 case 24: |
|
665 wordWidth = (((aPixelWidth * 3) + 11) / 12) * 3; |
|
666 break; |
|
667 default: |
|
668 break; |
|
669 }; |
|
670 |
|
671 return wordWidth * 4; |
|
672 } |
|
673 |