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