1 /* |
|
2 * Copyright (c) 2004 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: Image Transforms subsystem. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 |
|
21 #include <e32svr.h> |
|
22 #include <fbs.h> |
|
23 |
|
24 #include "CVtImageRotatorImplClockwise.h" |
|
25 #include "cvtimage.h" |
|
26 #include "CVtImageIYUV.h" |
|
27 |
|
28 // MACROS |
|
29 |
|
30 #ifdef _DEBUG |
|
31 # define __IF_DEBUG(t) {RDebug::t;} |
|
32 #else |
|
33 # define __IF_DEBUG(t) |
|
34 #endif |
|
35 |
|
36 // LOCAL CONSTANTS AND MACROS |
|
37 |
|
38 // ============================ MEMBER FUNCTIONS =============================== |
|
39 |
|
40 // ======================= CVtImageRotatorImplClockwise ======================= |
|
41 |
|
42 // ----------------------------------------------------------------------------- |
|
43 // CVtImageRotatorImplClockwise::CVtImageRotatorImplClockwise( |
|
44 // const CVtImageRotator::TRotationAngle& aAngle ) |
|
45 // ----------------------------------------------------------------------------- |
|
46 CVtImageRotatorImplClockwise::CVtImageRotatorImplClockwise( |
|
47 const CVtImageRotator::TRotationAngle& aAngle ) : CVtImageRotatorImpl( aAngle ) |
|
48 { |
|
49 } |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // CVtImageRotatorImplClockwise::Rotate( TBool& aContinue ) |
|
53 // ----------------------------------------------------------------------------- |
|
54 TInt CVtImageRotatorImplClockwise::Rotate( TBool& aContinue ) |
|
55 { |
|
56 __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplClockwise::Rotate() >>" ), RThread().Id().operator TUint() ) ); |
|
57 |
|
58 TInt result( KErrNone ); |
|
59 |
|
60 aContinue = EFalse; |
|
61 |
|
62 DoRotate(); |
|
63 |
|
64 __IF_DEBUG( Print( _L( "ImageRotator [%d]: CVtImageRotatorImplClockwise::Rotate() <<" ), RThread().Id().operator TUint() ) ); |
|
65 |
|
66 return result; |
|
67 } |
|
68 |
|
69 // ----------------------------------------------------------------------------- |
|
70 // CVtImageRotatorImplClockwise::ValidateSourceTargetL( |
|
71 // const CVtImage& aSource, CVtImage& aTarget ) |
|
72 // ----------------------------------------------------------------------------- |
|
73 void CVtImageRotatorImplClockwise::ValidateSourceTargetL( |
|
74 const CVtImage& aSource, |
|
75 CVtImage& aTarget ) |
|
76 { |
|
77 // SourceWidth == TargetHeight && SourceHeight == TargetWidth |
|
78 if( ( aSource.Size().iWidth != aTarget.Size().iHeight ) || |
|
79 ( aSource.Size().iHeight != aTarget.Size().iWidth ) ) |
|
80 { |
|
81 User::Leave( KErrNotSupported ); |
|
82 } |
|
83 |
|
84 // Displaymodes must match |
|
85 if( aSource.DisplayMode() != aTarget.DisplayMode() ) |
|
86 { |
|
87 User::Leave( KErrNotSupported ); |
|
88 } |
|
89 |
|
90 // Check that displaymode is one of the supported |
|
91 switch( aSource.DisplayMode() ) |
|
92 { |
|
93 case CVtImage::EVtColor4K: |
|
94 case CVtImage::EVtColor64K: |
|
95 case CVtImage::EVtColor16M: |
|
96 case CVtImage::EVtColor16MU: |
|
97 case CVtImage::EVtColor16MA: |
|
98 case CVtImage::EVtColorIYUV: |
|
99 break; |
|
100 |
|
101 default: |
|
102 User::Leave( KErrNotSupported ); |
|
103 } |
|
104 } |
|
105 |
|
106 // ----------------------------------------------------------------------------- |
|
107 // CVtImageRotatorImplClockwise::ValidateSourceTargetL( |
|
108 // const CVtImage& aSource, CVtImage& aTarget ) |
|
109 // ----------------------------------------------------------------------------- |
|
110 TBool CVtImageRotatorImplClockwise::SupportsRotationAngle( |
|
111 const CVtImageRotator::TRotationAngle& aAngle ) |
|
112 { |
|
113 TBool result( EFalse ); |
|
114 |
|
115 if( ( aAngle == CVtImageRotator::E90DegreesClockwise ) || |
|
116 ( aAngle == CVtImageRotator::E270DegreesClockwise ) ) |
|
117 { |
|
118 result = ETrue; |
|
119 } |
|
120 |
|
121 return result; |
|
122 } |
|
123 |
|
124 // ----------------------------------------------------------------------------- |
|
125 // void CVtImageRotatorImplClockwise::DoRotate() |
|
126 // ----------------------------------------------------------------------------- |
|
127 void CVtImageRotatorImplClockwise::DoRotate() |
|
128 { |
|
129 TInt bytesPerRow( iSource->BytesPerRow() ); |
|
130 |
|
131 TInt height( iSource->Size().iHeight ); |
|
132 |
|
133 TInt width( iSource->Size().iWidth ); |
|
134 |
|
135 TInt targetWidth( iTarget->Size().iWidth ); |
|
136 |
|
137 TInt targetHeight( iTarget->Size().iHeight ); |
|
138 |
|
139 TInt targetBytesPerRow( iTarget->BytesPerRow() ); |
|
140 |
|
141 switch( iSource->DisplayMode() ) |
|
142 { |
|
143 // DisplayMode: 4K and 64K |
|
144 case CVtImage::EVtColor4K: |
|
145 case CVtImage::EVtColor64K: |
|
146 { |
|
147 const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() ); |
|
148 |
|
149 TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
150 |
|
151 TInt offsetPerRow( -2 ); |
|
152 |
|
153 if( iAngle == CVtImageRotator::E90DegreesClockwise ) |
|
154 { |
|
155 d += targetBytesPerRow - 2; |
|
156 |
|
157 if( targetWidth & 1 ) |
|
158 { |
|
159 d -= 2; |
|
160 } |
|
161 } |
|
162 else |
|
163 { |
|
164 d += targetBytesPerRow * ( targetHeight - 1 ); |
|
165 |
|
166 targetBytesPerRow = -targetBytesPerRow; |
|
167 |
|
168 offsetPerRow = 2; |
|
169 } |
|
170 |
|
171 targetBytesPerRow /= 2; // in loop we need 16-bit precalculated |
|
172 |
|
173 for( TInt y = height - 1; y >= 0; y-- ) |
|
174 { |
|
175 register const TUint16* tempS = reinterpret_cast< const TUint16* >( s ); |
|
176 |
|
177 register TUint16* tempD = reinterpret_cast< TUint16* >( d ); |
|
178 |
|
179 for( register TInt x = width - 1; x >= 0; x-- ) |
|
180 { |
|
181 *tempD = *tempS++; |
|
182 tempD += targetBytesPerRow; |
|
183 } |
|
184 |
|
185 s += bytesPerRow; |
|
186 d += offsetPerRow; |
|
187 } |
|
188 } |
|
189 break; |
|
190 |
|
191 // DisplayMode: 16M |
|
192 case CVtImage::EVtColor16M: |
|
193 { |
|
194 const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() ); |
|
195 |
|
196 TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
197 |
|
198 TInt offsetPerRow( -3 ); |
|
199 |
|
200 if( iAngle == CVtImageRotator::E90DegreesClockwise ) |
|
201 { |
|
202 d += targetWidth * 3 - 3; |
|
203 } |
|
204 else |
|
205 { |
|
206 d += targetBytesPerRow * ( targetHeight - 1 ); |
|
207 |
|
208 targetBytesPerRow = -targetBytesPerRow; |
|
209 |
|
210 offsetPerRow = 3; |
|
211 } |
|
212 |
|
213 for( TInt y = height - 1; y >= 0; y-- ) |
|
214 { |
|
215 register const TUint8* tempS = s; |
|
216 |
|
217 register TUint8* tempD = d; |
|
218 |
|
219 for( register TInt x = width - 1; x >= 0; x-- ) |
|
220 { |
|
221 tempD[ 0 ] = *tempS++; |
|
222 tempD[ 1 ] = *tempS++; |
|
223 tempD[ 2 ] = *tempS++; |
|
224 tempD += targetBytesPerRow; |
|
225 } |
|
226 |
|
227 s += bytesPerRow; |
|
228 d += offsetPerRow; |
|
229 } |
|
230 } |
|
231 break; |
|
232 |
|
233 // DisplayMode: 16MU and 16MA |
|
234 case CVtImage::EVtColor16MU: |
|
235 case CVtImage::EVtColor16MA: |
|
236 { |
|
237 const TUint8* s = reinterpret_cast< const TUint8* >( iSource->DataAddress() ); |
|
238 |
|
239 TUint8* d = reinterpret_cast< TUint8* >( iTarget->DataAddress() ); |
|
240 |
|
241 TInt offsetPerRow( -4 ); |
|
242 |
|
243 if( iAngle == CVtImageRotator::E90DegreesClockwise ) |
|
244 { |
|
245 d += targetBytesPerRow - 4; |
|
246 } |
|
247 else |
|
248 { |
|
249 d += targetBytesPerRow * ( targetHeight - 1 ); |
|
250 |
|
251 targetBytesPerRow = -targetBytesPerRow; |
|
252 |
|
253 offsetPerRow = 4; |
|
254 } |
|
255 |
|
256 targetBytesPerRow /= 4; // in loop we need 32-bit precalculated |
|
257 |
|
258 for( TInt y = height - 1; y >= 0; y-- ) |
|
259 { |
|
260 register const TUint32* tempS = reinterpret_cast< const TUint32* >( s ); |
|
261 |
|
262 register TUint32* tempD = reinterpret_cast< TUint32* >( d ); |
|
263 |
|
264 for( register TInt x = width - 1; x >= 0; x-- ) |
|
265 { |
|
266 *tempD = *tempS++; |
|
267 tempD += targetBytesPerRow; |
|
268 } |
|
269 |
|
270 s += bytesPerRow; |
|
271 d += offsetPerRow; |
|
272 } |
|
273 } |
|
274 break; |
|
275 |
|
276 // DisplayMode: IYUV |
|
277 case CVtImage::EVtColorIYUV: |
|
278 { |
|
279 const CVtImageIYUV* src = reinterpret_cast< const CVtImageIYUV* >( iSource ); |
|
280 CVtImageIYUV* trg = reinterpret_cast< CVtImageIYUV* >( iTarget ); |
|
281 RotatePlane |
|
282 ( |
|
283 src->Y(), |
|
284 trg->Y(), |
|
285 width, |
|
286 height, |
|
287 bytesPerRow, |
|
288 targetHeight, |
|
289 targetBytesPerRow |
|
290 ); |
|
291 |
|
292 RotatePlane |
|
293 ( |
|
294 src->U(), |
|
295 trg->U(), |
|
296 src->UVPlaneWidth(), |
|
297 src->UVPlaneHeight(), |
|
298 src->UVPlaneWidth(), |
|
299 trg->UVPlaneHeight(), |
|
300 trg->UVPlaneWidth() |
|
301 ); |
|
302 |
|
303 RotatePlane |
|
304 ( |
|
305 src->V(), |
|
306 trg->V(), |
|
307 src->UVPlaneWidth(), |
|
308 src->UVPlaneHeight(), |
|
309 src->UVPlaneWidth(), |
|
310 trg->UVPlaneHeight(), |
|
311 trg->UVPlaneWidth() |
|
312 ); |
|
313 |
|
314 } |
|
315 break; |
|
316 |
|
317 default: |
|
318 break; |
|
319 |
|
320 } |
|
321 } |
|
322 |
|
323 // ----------------------------------------------------------------------------- |
|
324 // CVtImageRotatorImplClockwise::RotatePlane( |
|
325 // const TUint8* aSource, |
|
326 // TUint8* aTarget, |
|
327 // TInt aSourceWidth, |
|
328 // TInt aSourceHeight, |
|
329 // TInt aSourceBytesPerRow, |
|
330 // TInt aTargetHeight, |
|
331 // TInt aTargetBytesPerRow ) |
|
332 // ----------------------------------------------------------------------------- |
|
333 void CVtImageRotatorImplClockwise::RotatePlane( |
|
334 const TUint8* aSource, |
|
335 TUint8* aTarget, |
|
336 TInt aSourceWidth, |
|
337 TInt aSourceHeight, |
|
338 TInt aSourceBytesPerRow, |
|
339 TInt aTargetHeight, |
|
340 TInt aTargetBytesPerRow ) |
|
341 { |
|
342 TInt offsetPerRow( -1 ); |
|
343 |
|
344 if( iAngle == CVtImageRotator::E90DegreesClockwise ) |
|
345 { |
|
346 aTarget += aTargetBytesPerRow - 1; |
|
347 } |
|
348 else |
|
349 { |
|
350 aTarget += aTargetBytesPerRow * ( aTargetHeight - 1 ); |
|
351 aTargetBytesPerRow = -aTargetBytesPerRow; |
|
352 offsetPerRow = -offsetPerRow; |
|
353 } |
|
354 |
|
355 for( TInt y = aSourceHeight - 1; y >= 0; y-- ) |
|
356 { |
|
357 register const TUint8* tempS = aSource; |
|
358 register TUint8* tempD = aTarget; |
|
359 for( register TInt x = aSourceWidth - 1; x >= 0; x-- ) |
|
360 { |
|
361 *tempD = *tempS++; |
|
362 tempD += aTargetBytesPerRow; |
|
363 } |
|
364 |
|
365 aSource += aSourceBytesPerRow; |
|
366 aTarget += offsetPerRow; |
|
367 } |
|
368 } |
|
369 |
|
370 // End of File |
|
371 |
|
372 |
|