00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "PNGCodec.h"
00020
00021 const TInt KPngScanlineFilterTypeLength = 1;
00022
00023 const TInt KColStart[KPngNumInterlacedPasses] = { 0, 4, 0, 2, 0, 1, 0, 0 };
00024 const TInt KRowStart[KPngNumInterlacedPasses] = { 0, 0, 4, 0, 2, 0, 1, 0 };
00025 const TInt KColIncrement[KPngNumInterlacedPasses] = { 8, 8, 4, 4, 2, 2, 1, 0 };
00026 const TInt KRowIncrement[KPngNumInterlacedPasses] = { 8, 8, 8, 4, 4, 2, 2, 0 };
00027 const TInt KBlockWidth[KPngNumInterlacedPasses] = { 8, 4, 4, 2, 2, 1, 1, 0 };
00028 const TInt KBlockHeight[KPngNumInterlacedPasses] = { 8, 8, 4, 4, 2, 2, 1, 0 };
00029
00030
00031
00032
00033
00034
00035 class CBitDepth1Decoder : public CPngReadSubCodec
00036 {
00037 private:
00038 virtual void DoConstructL();
00039 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00040 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00041 };
00042
00043 class CBitDepth2Decoder : public CPngReadSubCodec
00044 {
00045 private:
00046 virtual void DoConstructL();
00047 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00048 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00049 };
00050
00051 class CBitDepth4Decoder : public CPngReadSubCodec
00052 {
00053 private:
00054 virtual void DoConstructL();
00055 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00056 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00057 };
00058
00059 class CBitDepth8Decoder : public CPngReadSubCodec
00060 {
00061 private:
00062 virtual void DoConstructL();
00063 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00064 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00065 };
00066
00067 class CBitDepth8ColorType2Decoder : public CPngReadSubCodec
00068 {
00069 private:
00070 virtual void DoConstructL();
00071 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00072 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00073 };
00074
00075 class CBitDepth8ColorType4Decoder : public CPngReadSubCodec
00076 {
00077 private:
00078 virtual void DoConstructL();
00079 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00080 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00081 };
00082
00083 class CBitDepth8ColorType6Decoder : public CPngReadSubCodec
00084 {
00085 private:
00086 virtual void DoConstructL();
00087 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00088 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00089 };
00090
00091 class CBitDepth16ColorType0Decoder : public CPngReadSubCodec
00092 {
00093 private:
00094 virtual void DoConstructL();
00095 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00096 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00097 };
00098
00099 class CBitDepth16ColorType2Decoder : public CPngReadSubCodec
00100 {
00101 private:
00102 virtual void DoConstructL();
00103 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00104 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00105 };
00106
00107 class CBitDepth16ColorType4Decoder : public CPngReadSubCodec
00108 {
00109 private:
00110 virtual void DoConstructL();
00111 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00112 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00113 };
00114
00115 class CBitDepth16ColorType6Decoder : public CPngReadSubCodec
00116 {
00117 private:
00118 virtual void DoConstructL();
00119 virtual TInt ScanlineBufferSize(TInt aPixelLength);
00120 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00121 };
00122
00123
00124
00125
00126
00127
00128 CPngReadSubCodec* CPngReadSubCodec::NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo)
00129 {
00130 CPngReadSubCodec* self = NULL;
00131
00132 switch (aInfo.iBitDepth)
00133 {
00134 case 1:
00135 self = new(ELeave) CBitDepth1Decoder;
00136 break;
00137 case 2:
00138 self = new(ELeave) CBitDepth2Decoder;
00139 break;
00140 case 4:
00141 self = new(ELeave) CBitDepth4Decoder;
00142 break;
00143 case 8:
00144 switch (aInfo.iColorType)
00145 {
00146 case TPngImageInformation::EGrayscale:
00147 case TPngImageInformation::EIndexedColor:
00148 self = new(ELeave) CBitDepth8Decoder;
00149 break;
00150 case TPngImageInformation::EDirectColor:
00151 self = new(ELeave) CBitDepth8ColorType2Decoder;
00152 break;
00153 case TPngImageInformation::EAlphaGrayscale:
00154 self = new(ELeave) CBitDepth8ColorType4Decoder;
00155 break;
00156 case TPngImageInformation::EAlphaDirectColor:
00157 self = new(ELeave) CBitDepth8ColorType6Decoder;
00158 break;
00159 default:
00160 User::Leave(KErrNotSupported);
00161 break;
00162 }
00163 break;
00164 case 16:
00165 switch (aInfo.iColorType)
00166 {
00167 case TPngImageInformation::EGrayscale:
00168 self = new(ELeave) CBitDepth16ColorType0Decoder;
00169 break;
00170 case TPngImageInformation::EDirectColor:
00171 self = new(ELeave) CBitDepth16ColorType2Decoder;
00172 break;
00173 case TPngImageInformation::EAlphaGrayscale:
00174 self = new(ELeave) CBitDepth16ColorType4Decoder;
00175 break;
00176 case TPngImageInformation::EAlphaDirectColor:
00177 self = new(ELeave) CBitDepth16ColorType6Decoder;
00178 break;
00179 case TPngImageInformation::EIndexedColor:
00180 default:
00181 User::Leave(KErrNotSupported);
00182 break;
00183 }
00184 break;
00185 default:
00186 User::Leave(KErrNotSupported);
00187 break;
00188 }
00189
00190 CleanupStack::PushL(self);
00191 self->ConstructL(aImageProc,aMaskProc,aInfo);
00192 CleanupStack::Pop();
00193 return self;
00194 }
00195
00196 CPngReadSubCodec::CPngReadSubCodec():
00197 iScanlineDes1(NULL,0),
00198 iScanlineDes2(NULL,0)
00199 {}
00200
00201 CPngReadSubCodec::~CPngReadSubCodec()
00202 {
00203 delete iScanlineBuffer1;
00204 delete iScanlineBuffer2;
00205 }
00206
00207 void CPngReadSubCodec::ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo)
00208 {
00209 iImageProc = aImageProc;
00210 iMaskProc = aMaskProc;
00211 iInfo = aInfo;
00212 iScanlineBufferSize = ScanlineBufferSize(iInfo.iSize.iWidth);
00213
00214 DoConstructL();
00215
00216 iScanlineBuffer1 = HBufC8::NewMaxL(iScanlineBufferSize);
00217 iScanlineBuffer2 = HBufC8::NewMaxL(iScanlineBufferSize);
00218
00219 if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
00220 {
00221 iInterlacedScanlineBufferSize[0] = ScanlineBufferSize((iInfo.iSize.iWidth + 7) >> 3);
00222 iInterlacedScanlineBufferSize[1] = ScanlineBufferSize((iInfo.iSize.iWidth + 3) >> 3);
00223 iInterlacedScanlineBufferSize[2] = ScanlineBufferSize((iInfo.iSize.iWidth + 3) >> 2);
00224 iInterlacedScanlineBufferSize[3] = ScanlineBufferSize((iInfo.iSize.iWidth + 1) >> 2);
00225 iInterlacedScanlineBufferSize[4] = ScanlineBufferSize((iInfo.iSize.iWidth + 1) >> 1);
00226 iInterlacedScanlineBufferSize[5] = ScanlineBufferSize(iInfo.iSize.iWidth >> 1);
00227 iInterlacedScanlineBufferSize[6] = iScanlineBufferSize;
00228 iInterlacedScanlineBufferSize[7] = 0;
00229 iPass = 0;
00230
00231 iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
00232 iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iInterlacedScanlineBufferSize[0],iInterlacedScanlineBufferSize[0]);
00233 }
00234 else
00235 {
00236 iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iScanlineBufferSize,iScanlineBufferSize);
00237 iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iScanlineBufferSize,iScanlineBufferSize);
00238 }
00239 }
00240
00241 TDes8& CPngReadSubCodec::FirstBuffer()
00242 {
00243 iScanlineDes1.FillZ();
00244 iCurrentScanlineBuffer = 2;
00245 return iScanlineDes2;
00246 }
00247
00248 TDes8& CPngReadSubCodec::DecodeL()
00249 {
00250 TUint8* dataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes1[1] : &iScanlineDes2[1];
00251 const TUint8* dataPtrLimit = dataPtr + iScanlineDes1.Length() - 1;
00252
00253 FilterScanlineDataL(dataPtr,dataPtrLimit);
00254 DoDecode(dataPtr,dataPtrLimit);
00255 UpdatePos();
00256
00257 if (iCurrentScanlineBuffer == 1)
00258 {
00259 iCurrentScanlineBuffer = 2;
00260 return iScanlineDes2;
00261 }
00262 else
00263 {
00264 iCurrentScanlineBuffer = 1;
00265 return iScanlineDes1;
00266 }
00267 }
00268
00269 void CPngReadSubCodec::FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00270 {
00271 TInt filterType = (iCurrentScanlineBuffer == 1) ? iScanlineDes1[0] : iScanlineDes2[0];
00272
00273 switch (filterType)
00274 {
00275 case 0:
00276 break;
00277 case 1:
00278 {
00279 aDataPtr += iBytesPerPixel;
00280
00281 while (aDataPtr < aDataPtrLimit)
00282 {
00283 aDataPtr[0] = TUint8(aDataPtr[0] + aDataPtr[-iBytesPerPixel]);
00284 aDataPtr++;
00285 }
00286 }
00287 break;
00288 case 2:
00289 {
00290 TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
00291
00292 while (aDataPtr < aDataPtrLimit)
00293 *aDataPtr++ = TUint8(*aDataPtr + *altDataPtr++);
00294 }
00295 break;
00296 case 3:
00297 {
00298 const TUint8* tempDataPtrLimit = Min<const TUint8*>(aDataPtr + iBytesPerPixel,aDataPtrLimit);
00299 TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
00300
00301 while (aDataPtr < tempDataPtrLimit)
00302 {
00303 aDataPtr[0] = TUint8(aDataPtr[0] + (altDataPtr[0] / 2));
00304 aDataPtr++;
00305 altDataPtr++;
00306 }
00307
00308 while (aDataPtr < aDataPtrLimit)
00309 {
00310 aDataPtr[0] = TUint8(aDataPtr[0] + ((altDataPtr[0] + aDataPtr[-iBytesPerPixel]) / 2));
00311 aDataPtr++;
00312 altDataPtr++;
00313 }
00314 }
00315 break;
00316 case 4:
00317 {
00318 const TUint8* tempDataPtrLimit = Min<const TUint8*>(aDataPtr + iBytesPerPixel,aDataPtrLimit);
00319 TUint8* altDataPtr = (iCurrentScanlineBuffer == 1) ? &iScanlineDes2[1] : &iScanlineDes1[1];
00320
00321 while (aDataPtr < tempDataPtrLimit)
00322 {
00323 aDataPtr[0] = TUint8(aDataPtr[0] + altDataPtr[0]);
00324 aDataPtr++;
00325 altDataPtr++;
00326 }
00327
00328 while (aDataPtr < aDataPtrLimit)
00329 {
00330 aDataPtr[0] = TUint8(aDataPtr[0] + PaethPredictor(aDataPtr[-iBytesPerPixel],altDataPtr[0],altDataPtr[-iBytesPerPixel]));
00331 aDataPtr++;
00332 altDataPtr++;
00333 }
00334 }
00335 break;
00336 default:
00337 User::Leave(KErrCorrupt);
00338 break;
00339 }
00340 }
00341
00342 TInt CPngReadSubCodec::PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft)
00343 {
00344 TInt p = aLeft + aAbove - aAboveLeft;
00345 TInt pa = Abs(p - aLeft);
00346 TInt pb = Abs(p - aAbove);
00347 TInt pc = Abs(p - aAboveLeft);
00348
00349 if (pa <= pb && pa <= pc)
00350 return aLeft;
00351 else if (pb <= pc)
00352 return aAbove;
00353 else
00354 return aAboveLeft;
00355 }
00356
00357 void CPngReadSubCodec::WritePixel(TRgb aPixelColor)
00358 {
00359 if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
00360 {
00361 const TInt width = Min(KBlockWidth[iPass],iInfo.iSize.iWidth - iPos.iX);
00362 const TInt endY = Min(iPos.iY + KBlockHeight[iPass],iInfo.iSize.iHeight);
00363
00364 TPoint pos(iPos);
00365
00366 while (pos.iY < endY)
00367 {
00368 iImageProc->SetPos(pos);
00369
00370 for (TInt col = 0; col < width; col++)
00371 iImageProc->SetPixel(aPixelColor);
00372
00373 pos.iY++;
00374 }
00375
00376 iPos.iX += KColIncrement[iPass];
00377 }
00378 else
00379 iImageProc->SetPixel(aPixelColor);
00380 }
00381
00382 void CPngReadSubCodec::WritePixel(TRgb aPixelColor,TUint8 aAlphaValue)
00383 {
00384 ASSERT(iMaskProc);
00385
00386 TRgb maskColor(TRgb::Gray256(aAlphaValue));
00387
00388 if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
00389 {
00390 iImageProc->SetPos(iPos);
00391 iMaskProc->SetPos(iPos);
00392 iImageProc->SetPixel(aPixelColor);
00393 iMaskProc->SetPixel(maskColor);
00394
00395 iPos.iX += KColIncrement[iPass];
00396 }
00397 else
00398 {
00399 iImageProc->SetPixel(aPixelColor);
00400 iMaskProc->SetPixel(maskColor);
00401 }
00402 }
00403
00404 void CPngReadSubCodec::UpdatePos()
00405 {
00406 if (iInfo.iInterlaceMethod == TPngImageInformation::EAdam7Interlace)
00407 {
00408 ASSERT(iPass <= 7);
00409
00410 iPos.iX = KColStart[iPass];
00411 iPos.iY += KRowIncrement[iPass];
00412
00413 while (iPos.iX >= iInfo.iSize.iWidth || iPos.iY >= iInfo.iSize.iHeight)
00414 {
00415 iPass++;
00416 iPos.iX = KColStart[iPass];
00417 iPos.iY = KRowStart[iPass];
00418 iScanlineDes1.Set(&(iScanlineBuffer1->Des())[0],iInterlacedScanlineBufferSize[iPass],iInterlacedScanlineBufferSize[iPass]);
00419 iScanlineDes2.Set(&(iScanlineBuffer2->Des())[0],iInterlacedScanlineBufferSize[iPass],iInterlacedScanlineBufferSize[iPass]);
00420 iScanlineDes1.FillZ();
00421 iScanlineDes2.FillZ();
00422 }
00423 }
00424 }
00425
00426
00427
00428
00429 void CBitDepth1Decoder::DoConstructL()
00430 {
00431 if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
00432 {
00433 iInfo.iPalette[0] = KRgbBlack;
00434 iInfo.iPalette[1] = KRgbWhite;
00435
00436
00437 if (iInfo.iTransparencyPresent)
00438 {
00439 if (iInfo.iTransparentGray <= 1)
00440 iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
00441 }
00442 }
00443
00444
00445 iInfo.iPalette[2] = iInfo.iPalette[1];
00446 iInfo.iPalette[4] = iInfo.iPalette[1];
00447 iInfo.iPalette[8] = iInfo.iPalette[1];
00448 iInfo.iPalette[16] = iInfo.iPalette[1];
00449 iInfo.iPalette[32] = iInfo.iPalette[1];
00450 iInfo.iPalette[64] = iInfo.iPalette[1];
00451 iInfo.iPalette[128] = iInfo.iPalette[1];
00452
00453 if (iInfo.iTransparencyPresent && iInfo.iTransparencyValue[1] != 255)
00454 {
00455 iInfo.iTransparencyValue[2] = iInfo.iTransparencyValue[1];
00456 iInfo.iTransparencyValue[4] = iInfo.iTransparencyValue[1];
00457 iInfo.iTransparencyValue[8] = iInfo.iTransparencyValue[1];
00458 iInfo.iTransparencyValue[16] = iInfo.iTransparencyValue[1];
00459 iInfo.iTransparencyValue[32] = iInfo.iTransparencyValue[1];
00460 iInfo.iTransparencyValue[64] = iInfo.iTransparencyValue[1];
00461 iInfo.iTransparencyValue[128] = iInfo.iTransparencyValue[1];
00462 }
00463
00464 iBytesPerPixel = 1;
00465 if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
00466 {
00467 TInt pixelPadding = ((iInfo.iSize.iWidth + 7) & ~7) - iInfo.iSize.iWidth;
00468 iImageProc->SetPixelPadding(pixelPadding);
00469 if (iMaskProc)
00470 iMaskProc->SetPixelPadding(pixelPadding);
00471 }
00472 }
00473
00474 TInt CBitDepth1Decoder::ScanlineBufferSize(TInt aPixelLength)
00475 {
00476 return ((aPixelLength + 7) / 8) + KPngScanlineFilterTypeLength;
00477 }
00478
00479 void CBitDepth1Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00480 {
00481 if (iMaskProc && iInfo.iTransparencyPresent)
00482 {
00483 while (aDataPtr < aDataPtrLimit)
00484 {
00485 TInt dataValue = *aDataPtr++;
00486
00487 for (TUint mask=0x80; mask!=0; mask>>=1)
00488 WritePixel(iInfo.iPalette[dataValue & mask],iInfo.iTransparencyValue[dataValue & mask]);
00489 }
00490 }
00491 else
00492 {
00493 while (aDataPtr < aDataPtrLimit)
00494 {
00495 TInt dataValue = *aDataPtr++;
00496
00497 for (TUint mask=0x80; mask!=0; mask>>=1)
00498 WritePixel(iInfo.iPalette[dataValue & mask]);
00499 }
00500 }
00501 }
00502
00503
00504
00505
00506
00507 void CBitDepth2Decoder::DoConstructL()
00508 {
00509 if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
00510 {
00511 iInfo.iPalette[0] = KRgbBlack;
00512 iInfo.iPalette[1] = KRgbDarkGray;
00513 iInfo.iPalette[2] = KRgbGray;
00514 iInfo.iPalette[3] = KRgbWhite;
00515
00516 if (iInfo.iTransparencyPresent)
00517 {
00518 if (iInfo.iTransparentGray <= 3)
00519 iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
00520 }
00521 }
00522
00523
00524 iInfo.iPalette[4] = iInfo.iPalette[1];
00525 iInfo.iPalette[8] = iInfo.iPalette[2];
00526 iInfo.iPalette[12] = iInfo.iPalette[3];
00527
00528 iInfo.iPalette[16] = iInfo.iPalette[1];
00529 iInfo.iPalette[32] = iInfo.iPalette[2];
00530 iInfo.iPalette[48] = iInfo.iPalette[3];
00531
00532 iInfo.iPalette[64] = iInfo.iPalette[1];
00533 iInfo.iPalette[128] = iInfo.iPalette[2];
00534 iInfo.iPalette[192] = iInfo.iPalette[3];
00535
00536 if (iInfo.iTransparencyPresent)
00537 {
00538 iInfo.iTransparencyValue[4] = iInfo.iTransparencyValue[1];
00539 iInfo.iTransparencyValue[8] = iInfo.iTransparencyValue[2];
00540 iInfo.iTransparencyValue[12] = iInfo.iTransparencyValue[3];
00541
00542 iInfo.iTransparencyValue[16] = iInfo.iTransparencyValue[1];
00543 iInfo.iTransparencyValue[32] = iInfo.iTransparencyValue[2];
00544 iInfo.iTransparencyValue[48] = iInfo.iTransparencyValue[3];
00545
00546 iInfo.iTransparencyValue[64] = iInfo.iTransparencyValue[1];
00547 iInfo.iTransparencyValue[128] = iInfo.iTransparencyValue[2];
00548 iInfo.iTransparencyValue[192] = iInfo.iTransparencyValue[3];
00549 }
00550
00551 iBytesPerPixel = 1;
00552 if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
00553 {
00554 TInt pixelPadding = ((iInfo.iSize.iWidth + 3) & ~3) - iInfo.iSize.iWidth;
00555 iImageProc->SetPixelPadding(pixelPadding);
00556 if (iMaskProc)
00557 iMaskProc->SetPixelPadding(pixelPadding);
00558 }
00559 }
00560
00561 TInt CBitDepth2Decoder::ScanlineBufferSize(TInt aPixelLength)
00562 {
00563 return ((aPixelLength + 3) / 4) + KPngScanlineFilterTypeLength;
00564 }
00565
00566 void CBitDepth2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00567 {
00568 if (iMaskProc && iInfo.iTransparencyPresent)
00569 {
00570 while (aDataPtr < aDataPtrLimit)
00571 {
00572 TInt dataValue = *aDataPtr++;
00573
00574 for (TInt mask=0xc0; mask!=0; mask>>=2)
00575 WritePixel(iInfo.iPalette[dataValue & mask],iInfo.iTransparencyValue[dataValue & mask]);
00576 }
00577 }
00578 else
00579 {
00580 while (aDataPtr < aDataPtrLimit)
00581 {
00582 TInt dataValue = *aDataPtr++;
00583
00584 for (TInt mask=0xc0; mask!=0; mask>>=2)
00585 WritePixel(iInfo.iPalette[dataValue & mask]);
00586 }
00587 }
00588 }
00589
00590
00591
00592
00593
00594
00595 void CBitDepth4Decoder::DoConstructL()
00596 {
00597 if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
00598 {
00599 for (TInt index = 0; index < 16; index++)
00600 iInfo.iPalette[index] = TRgb::Gray16(index);
00601
00602 if (iInfo.iTransparencyPresent)
00603 {
00604 if (iInfo.iTransparentGray <= 15)
00605 iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
00606 }
00607 }
00608
00609 iBytesPerPixel = 1;
00610 if (iInfo.iInterlaceMethod == TPngImageInformation::ENoInterlace)
00611 {
00612 TInt pixelPadding = ((iInfo.iSize.iWidth + 1) & ~1) - iInfo.iSize.iWidth;
00613 iImageProc->SetPixelPadding(pixelPadding);
00614 if (iMaskProc)
00615 iMaskProc->SetPixelPadding(pixelPadding);
00616 }
00617 }
00618
00619 TInt CBitDepth4Decoder::ScanlineBufferSize(TInt aPixelLength)
00620 {
00621 return ((aPixelLength + 1) / 2) + KPngScanlineFilterTypeLength;
00622 }
00623
00624 void CBitDepth4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00625 {
00626 if (iMaskProc && iInfo.iTransparencyPresent)
00627 {
00628 while (aDataPtr < aDataPtrLimit)
00629 {
00630 TInt dataValue = *aDataPtr++;
00631
00632 WritePixel(iInfo.iPalette[dataValue >> 4],iInfo.iTransparencyValue[dataValue >> 4]);
00633 WritePixel(iInfo.iPalette[dataValue & 0x0f],iInfo.iTransparencyValue[dataValue & 0x0f]);
00634 }
00635 }
00636 else
00637 {
00638 while (aDataPtr < aDataPtrLimit)
00639 {
00640 TInt dataValue = *aDataPtr++;
00641
00642 WritePixel(iInfo.iPalette[dataValue >> 4]);
00643 WritePixel(iInfo.iPalette[dataValue & 0x0f]);
00644 }
00645 }
00646 }
00647
00648
00649
00650
00651
00652
00653 void CBitDepth8Decoder::DoConstructL()
00654 {
00655 if (!(iInfo.iColorType & TPngImageInformation::EPaletteUsed))
00656 {
00657 for (TInt index = 0; index < 256; index++)
00658 iInfo.iPalette[index] = TRgb::Gray256(index);
00659
00660 if (iInfo.iTransparencyPresent)
00661 {
00662 if (iInfo.iTransparentGray <= 255)
00663 iInfo.iTransparencyValue[iInfo.iTransparentGray] = 0;
00664 }
00665 }
00666
00667 iBytesPerPixel = 1;
00668 }
00669
00670 TInt CBitDepth8Decoder::ScanlineBufferSize(TInt aPixelLength)
00671 {
00672 return aPixelLength + KPngScanlineFilterTypeLength;
00673 }
00674
00675 void CBitDepth8Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00676 {
00677 if (iMaskProc && iInfo.iTransparencyPresent)
00678 {
00679 while (aDataPtr < aDataPtrLimit)
00680 {
00681 WritePixel(iInfo.iPalette[aDataPtr[0]],iInfo.iTransparencyValue[aDataPtr[0]]);
00682 aDataPtr++;
00683 }
00684 }
00685 else
00686 {
00687 while (aDataPtr < aDataPtrLimit)
00688 WritePixel(iInfo.iPalette[*aDataPtr++]);
00689 }
00690 }
00691
00692
00693
00694
00695
00696
00697 void CBitDepth8ColorType2Decoder::DoConstructL()
00698 {
00699 iBytesPerPixel = 3;
00700 }
00701
00702 TInt CBitDepth8ColorType2Decoder::ScanlineBufferSize(TInt aPixelLength)
00703 {
00704 return (aPixelLength * 3) + KPngScanlineFilterTypeLength;
00705 }
00706
00707 void CBitDepth8ColorType2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00708 {
00709 if (iMaskProc && iInfo.iTransparencyPresent)
00710 {
00711 while (aDataPtr < aDataPtrLimit)
00712 {
00713 TInt red = aDataPtr[0];
00714 TInt green = aDataPtr[1];
00715 TInt blue = aDataPtr[2];
00716 TRgb pixelColor(red,green,blue);
00717 if (red == iInfo.iTransparentRed && green == iInfo.iTransparentGreen && blue == iInfo.iTransparentBlue)
00718 WritePixel(pixelColor,0);
00719 else
00720 WritePixel(pixelColor,255);
00721 aDataPtr += 3;
00722 }
00723 }
00724 else
00725 {
00726 while (aDataPtr < aDataPtrLimit)
00727 {
00728 WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]));
00729 aDataPtr += 3;
00730 }
00731 }
00732 }
00733
00734
00735
00736
00737
00738
00739 void CBitDepth8ColorType4Decoder::DoConstructL()
00740 {
00741 iBytesPerPixel = 2;
00742 }
00743
00744 TInt CBitDepth8ColorType4Decoder::ScanlineBufferSize(TInt aPixelLength)
00745 {
00746 return (aPixelLength * 2) + KPngScanlineFilterTypeLength;
00747 }
00748
00749 void CBitDepth8ColorType4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00750 {
00751 if (iMaskProc)
00752 {
00753 while (aDataPtr < aDataPtrLimit)
00754 {
00755 WritePixel(TRgb::Gray256(aDataPtr[0]),aDataPtr[1]);
00756 aDataPtr += 2;
00757 }
00758 }
00759 else
00760 {
00761 while (aDataPtr < aDataPtrLimit)
00762 {
00763 WritePixel(TRgb::Gray256(aDataPtr[0]));
00764 aDataPtr += 2;
00765 }
00766 }
00767 }
00768
00769
00770
00771
00772
00773
00774 void CBitDepth8ColorType6Decoder::DoConstructL()
00775 {
00776 iBytesPerPixel = 4;
00777 }
00778
00779 TInt CBitDepth8ColorType6Decoder::ScanlineBufferSize(TInt aPixelLength)
00780 {
00781 return (aPixelLength * 4) + KPngScanlineFilterTypeLength;
00782 }
00783
00784 void CBitDepth8ColorType6Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00785 {
00786 if (iMaskProc)
00787 {
00788 while (aDataPtr < aDataPtrLimit)
00789 {
00790 WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]),aDataPtr[3]);
00791 aDataPtr += 4;
00792 }
00793 }
00794 else
00795 {
00796 while (aDataPtr < aDataPtrLimit)
00797 {
00798 WritePixel(TRgb(aDataPtr[0],aDataPtr[1],aDataPtr[2]));
00799 aDataPtr += 4;
00800 }
00801 }
00802 }
00803
00804
00805
00806
00807
00808
00809 void CBitDepth16ColorType0Decoder::DoConstructL()
00810 {
00811 iBytesPerPixel = 2;
00812 }
00813
00814 TInt CBitDepth16ColorType0Decoder::ScanlineBufferSize(TInt aPixelLength)
00815 {
00816 return (aPixelLength * 2) + KPngScanlineFilterTypeLength;
00817 }
00818
00819 void CBitDepth16ColorType0Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00820 {
00821 if (iMaskProc && iInfo.iTransparencyPresent)
00822 {
00823 while (aDataPtr < aDataPtrLimit)
00824 {
00825 TInt gray = (aDataPtr[0] << 8) | aDataPtr[1];
00826 TRgb pixelColor(TRgb::Gray256(aDataPtr[0]));
00827 if (gray == iInfo.iTransparentGray)
00828 WritePixel(pixelColor,0);
00829 else
00830 WritePixel(pixelColor,255);
00831 aDataPtr += 2;
00832 }
00833 }
00834 else
00835 {
00836 while (aDataPtr < aDataPtrLimit)
00837 {
00838 WritePixel(TRgb::Gray256(aDataPtr[0]));
00839 aDataPtr += 2;
00840 }
00841 }
00842 }
00843
00844
00845
00846
00847
00848
00849 void CBitDepth16ColorType2Decoder::DoConstructL()
00850 {
00851 iBytesPerPixel = 6;
00852 }
00853
00854 TInt CBitDepth16ColorType2Decoder::ScanlineBufferSize(TInt aPixelLength)
00855 {
00856 return (aPixelLength * 6) + KPngScanlineFilterTypeLength;
00857 }
00858
00859 void CBitDepth16ColorType2Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00860 {
00861 if (iMaskProc && iInfo.iTransparencyPresent)
00862 {
00863 while (aDataPtr < aDataPtrLimit)
00864 {
00865 TInt red = (aDataPtr[0] << 8) | aDataPtr[1];
00866 TInt green = (aDataPtr[2] << 8) | aDataPtr[3];
00867 TInt blue = (aDataPtr[4] << 8) | aDataPtr[5];
00868 TRgb pixelColor(aDataPtr[0],aDataPtr[2],aDataPtr[4]);
00869 if (red == iInfo.iTransparentRed && green == iInfo.iTransparentGreen && blue == iInfo.iTransparentBlue)
00870 WritePixel(pixelColor,0);
00871 else
00872 WritePixel(pixelColor,255);
00873 aDataPtr += 6;
00874 }
00875 }
00876 else
00877 {
00878 while (aDataPtr < aDataPtrLimit)
00879 {
00880 WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]));
00881 aDataPtr += 6;
00882 }
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891 void CBitDepth16ColorType4Decoder::DoConstructL()
00892 {
00893 iBytesPerPixel = 4;
00894 }
00895
00896 TInt CBitDepth16ColorType4Decoder::ScanlineBufferSize(TInt aPixelLength)
00897 {
00898 return (aPixelLength * 4) + KPngScanlineFilterTypeLength;
00899 }
00900
00901 void CBitDepth16ColorType4Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00902 {
00903 if (iMaskProc)
00904 {
00905 while (aDataPtr < aDataPtrLimit)
00906 {
00907 WritePixel(TRgb::Gray256(aDataPtr[0]),aDataPtr[2]);
00908 aDataPtr += 4;
00909 }
00910 }
00911 else
00912 {
00913 while (aDataPtr < aDataPtrLimit)
00914 {
00915 WritePixel(TRgb::Gray256(aDataPtr[0]));
00916 aDataPtr += 4;
00917 }
00918 }
00919 }
00920
00921
00922
00923
00924
00925
00926 void CBitDepth16ColorType6Decoder::DoConstructL()
00927 {
00928 iBytesPerPixel = 8;
00929 }
00930
00931 TInt CBitDepth16ColorType6Decoder::ScanlineBufferSize(TInt aPixelLength)
00932 {
00933 return (aPixelLength * 8) + KPngScanlineFilterTypeLength;
00934 }
00935
00936 void CBitDepth16ColorType6Decoder::DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit)
00937 {
00938 if (iMaskProc)
00939 {
00940 while (aDataPtr < aDataPtrLimit)
00941 {
00942 WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]),aDataPtr[6]);
00943 aDataPtr += 8;
00944 }
00945 }
00946 else
00947 {
00948 while (aDataPtr < aDataPtrLimit)
00949 {
00950 WritePixel(TRgb(aDataPtr[0],aDataPtr[2],aDataPtr[4]));
00951 aDataPtr += 8;
00952 }
00953 }
00954 }
00955