|
1 // Copyright (c) 2006-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 <fbs.h> |
|
17 #include "JpegConsts.h" |
|
18 |
|
19 #include "rgbbufferptr.h" |
|
20 |
|
21 |
|
22 /*static*/ |
|
23 CRgbBufferPtr* CRgbBufferPtr::NewL(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels) |
|
24 { |
|
25 CRgbBufferPtr* self = new (ELeave) CRgbBufferPtr(aBitmap, aMCUSizeinPixels); |
|
26 CleanupStack::PushL(self); |
|
27 self->ConstructL(); |
|
28 CleanupStack::Pop(self); |
|
29 return self; |
|
30 } |
|
31 |
|
32 CRgbBufferPtr::CRgbBufferPtr(CFbsBitmap& aBitmap, const TSize& aMCUSizeinPixels): |
|
33 iBitmapSize( aBitmap.SizeInPixels() ), |
|
34 iMCUSizeinPixels( aMCUSizeinPixels ), |
|
35 iBufferPos(-1,-1), |
|
36 iBitmap( &aBitmap ) |
|
37 { |
|
38 } |
|
39 |
|
40 void CRgbBufferPtr::ConstructL() |
|
41 { |
|
42 if ((iBitmapSize.iWidth <= 0) || (iBitmapSize.iHeight <= 0)) |
|
43 { |
|
44 User::Leave(KErrArgument); |
|
45 } |
|
46 |
|
47 iBitmapData = iBitmap->DataAddress(); |
|
48 iBitmapScanlineLength = iBitmap->ScanLineLength(iBitmapSize.iWidth, iBitmap->DisplayMode()); |
|
49 |
|
50 if (iBitmap->DisplayMode() == EColor16M) |
|
51 { |
|
52 iBufferSizeInPixels.SetSize( iMCUSizeinPixels.iWidth, iMCUSizeinPixels.iHeight); |
|
53 iBitmapDirectAccess = ETrue; |
|
54 } |
|
55 else |
|
56 { |
|
57 // we reduce number of bitmap round-robins using horizontally-widened buffer ONLY! |
|
58 TInt width = Max(iMCUSizeinPixels.iWidth, Min(iMCUSizeinPixels.iWidth<<2, iBitmapSize.iWidth)); |
|
59 if (width == iBitmapSize.iWidth ) |
|
60 { |
|
61 TInt oddPixels = width % iMCUSizeinPixels.iWidth; |
|
62 if (oddPixels) |
|
63 { |
|
64 width += iMCUSizeinPixels.iWidth - oddPixels; |
|
65 } |
|
66 } |
|
67 iBufferSizeInPixels.SetSize( width, iMCUSizeinPixels.iHeight); |
|
68 iBitmapDirectAccess = EFalse; |
|
69 } |
|
70 |
|
71 iOriginalRgbBuffer = reinterpret_cast<TRgbBufferPtr>(User::AllocL(Coord2Size(iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight) + sizeof(TUint32))); |
|
72 iRgbBuffer = Align4(iOriginalRgbBuffer); |
|
73 |
|
74 iBufferScanlineLength = iBufferSizeInPixels.iWidth * KRgbBufferPixelSize; |
|
75 } |
|
76 |
|
77 CRgbBufferPtr::~CRgbBufferPtr() |
|
78 { |
|
79 User::Free( iOriginalRgbBuffer); |
|
80 iOriginalRgbBuffer = NULL; |
|
81 iRgbBuffer = NULL; |
|
82 } |
|
83 |
|
84 |
|
85 CRgbBufferPtr::TConstRgbBufferPtr CRgbBufferPtr::LockBuffer(const TPoint& aTopLeft) |
|
86 { |
|
87 ASSERT( aTopLeft.iX < iBitmapSize.iWidth ); |
|
88 ASSERT( aTopLeft.iY < iBitmapSize.iHeight ); |
|
89 |
|
90 //const TBool KDirectAccess = ( iBitmap->DisplayMode() == EColor16M ); |
|
91 const TBool KInplaceAccess= iBitmapDirectAccess; |
|
92 |
|
93 if ( !KInplaceAccess && |
|
94 aTopLeft.iY >= iBufferPos.iY && aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBufferPos.iY + iBufferSizeInPixels.iHeight && |
|
95 aTopLeft.iX >= iBufferPos.iX && aTopLeft.iX + iMCUSizeinPixels.iWidth <= iBufferPos.iX + iBufferSizeInPixels.iWidth |
|
96 ) |
|
97 { |
|
98 iLockedPtr = ShiftPtr(iRgbBuffer, aTopLeft.iX - iBufferPos.iX); |
|
99 return iLockedPtr; |
|
100 } |
|
101 |
|
102 iLockedPtr = reinterpret_cast<TRgbBufferPtr>(iBitmapData) + iBitmapScanlineLength * aTopLeft.iY + KRgbBufferPixelSize * aTopLeft.iX; |
|
103 |
|
104 if (aTopLeft.iX + iMCUSizeinPixels.iWidth <= iBitmapSize.iWidth && |
|
105 aTopLeft.iY + iMCUSizeinPixels.iHeight <= iBitmapSize.iHeight && |
|
106 KInplaceAccess) |
|
107 { |
|
108 //ASSERT( iBitmapScanlineLength % KRgbBufferPixelSize == 0 ); |
|
109 iNextLineOffset = iBitmapScanlineLength; |
|
110 iBufferPos.iX = -1; |
|
111 } |
|
112 else |
|
113 { |
|
114 const TInt KLineLen = KRgbBufferPixelSize * Min(iBufferSizeInPixels.iWidth, iBitmapSize.iWidth - aTopLeft.iX); |
|
115 const TInt KNumLines = Min(iBufferSizeInPixels.iHeight, iBitmapSize.iHeight - aTopLeft.iY); |
|
116 |
|
117 const TInt KBufferLineLen = iBufferScanlineLength; |
|
118 |
|
119 TRgbBufferPtr pixelBufferPtr = iRgbBuffer; |
|
120 if (KInplaceAccess) |
|
121 { |
|
122 for (TInt y = KNumLines; y--; ) |
|
123 { |
|
124 Mem::Copy(pixelBufferPtr, iLockedPtr, KLineLen); |
|
125 iLockedPtr += iBitmapScanlineLength; |
|
126 |
|
127 // now fill out hor trail using grey |
|
128 const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel |
|
129 for (TInt f = KLineLen; f < KBufferLineLen; ++f) |
|
130 { |
|
131 pixelBufferPtr[ f ] = green; |
|
132 } |
|
133 pixelBufferPtr = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth ); |
|
134 } |
|
135 } |
|
136 else |
|
137 { |
|
138 for (TInt y = aTopLeft.iY; y < aTopLeft.iY + KNumLines; y++ ) |
|
139 { |
|
140 TPtr8 pixelDes(reinterpret_cast<TUint8*>(pixelBufferPtr), KLineLen, KLineLen ); |
|
141 // GetScanLine() is extremely slow, so if support for bitmap modes other than EColor16M is require |
|
142 // it shouldn't be used |
|
143 iBitmap->GetScanLine(pixelDes, TPoint(aTopLeft.iX, y), iBufferSizeInPixels.iWidth, EColor16M); |
|
144 |
|
145 // now fill out hor trail using grey |
|
146 const TInt green = pixelBufferPtr[ KLineLen - KRgbBufferPixelSize + 1 ]; // green of the last pixel |
|
147 for (TInt f = KLineLen; f < KBufferLineLen; ++f) |
|
148 { |
|
149 pixelBufferPtr[ f ] = green; |
|
150 } |
|
151 pixelBufferPtr = ShiftPtr(pixelBufferPtr, iBufferSizeInPixels.iWidth ); |
|
152 } |
|
153 } |
|
154 // fill out vertical trail |
|
155 if ( KNumLines < iMCUSizeinPixels.iHeight ) |
|
156 { |
|
157 TUint32* fillBufferPtr = reinterpret_cast<TUint32*>( pixelBufferPtr ); |
|
158 // we're filling the whole buffer with mid-gray, so to reduce |
|
159 // color entropy of padded block |
|
160 pixelBufferPtr = ShiftPtr(pixelBufferPtr, -iBufferSizeInPixels.iWidth ); // go to the previous line |
|
161 // make a grey using green component |
|
162 TUint32 fillValue = (pixelBufferPtr[1] | pixelBufferPtr[1]<<8); |
|
163 fillValue |= fillValue << 16; |
|
164 TInt i = Coord2Size( iBufferSizeInPixels.iWidth, iBufferSizeInPixels.iHeight - KNumLines) >> 3; // /8 |
|
165 do |
|
166 { |
|
167 *fillBufferPtr++ = fillValue; |
|
168 *fillBufferPtr++ = fillValue; |
|
169 } while (--i); |
|
170 } |
|
171 iLockedPtr = iRgbBuffer; |
|
172 iNextLineOffset = iBufferScanlineLength; |
|
173 iBufferPos = aTopLeft; |
|
174 } |
|
175 |
|
176 return iLockedPtr; |
|
177 } |
|
178 |
|
179 void CRgbBufferPtr::UnlockBuffer() |
|
180 { |
|
181 ASSERT( iLockedPtr != NULL ); |
|
182 iLockedPtr = NULL; |
|
183 } |
|
184 |