WORK-IN-PROGRESS commit: threads working in symbian s60
[spandex:spandex.git] / sct / common / modules / openvg / sct_openvgutils.c
1 /*
2  * Spandex benchmark and test framework.
3  *
4  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
5  *
6  * Contact: Kari J. Kangas <kari.j.kangas@nokia.com>
7  *
8  *   This framework is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation, version 2.1 of the License.
11  *
12  *   This framework is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  *   You should have received a copy of the GNU Lesser General Public License
18  * along with this framework; if not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include "sct_utils.h"
23 #include "sct_openvgutils.h"
24 #include "sct_sicommon.h"
25
26 #include <string.h>
27
28 #pragma warning(disable: 4310)
29
30 /*!
31  *
32  *
33  */
34 static SCTBoolean           sctiGetImageDataSizeAndStride( VGImageFormat format, int width, int height, int* datasize, int* stride );
35 static int                  sctiGetPathDatatypeSize( VGPathDatatype type );
36 static int                  sctiGetBitsPerPixel( VGImageFormat format );
37 static void                 sctiAssignImageColor( VGImageFormat format, void* dest, const float* color, unsigned int shift );
38
39 /*!
40  *
41  *
42  */
43 SCTOpenVGImageData* sctOpenVGCreateImageData( VGImageFormat format, int width, int height )
44 {
45     SCTOpenVGImageData* imageData;
46     int                 datasize    = 0;
47     int                 stride      = 0;
48
49     if( sctiGetImageDataSizeAndStride( format, width, height, &datasize, &stride ) == SCT_FALSE )
50     {
51         return NULL;
52     }
53     
54     imageData = ( SCTOpenVGImageData* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGImageData ) ) );
55     if( imageData == NULL )
56     {
57         return NULL;
58     }
59     memset( imageData, 0, sizeof( SCTOpenVGImageData ) );
60
61     imageData->data = siCommonMemoryAlloc( NULL, datasize );
62     if( imageData->data == NULL )
63     {
64         sctOpenVGDestroyImageData( imageData );
65         return NULL;
66     }
67     memset( imageData->data, 0, datasize );
68     
69     imageData->stride     = stride;
70     imageData->format     = format;
71     imageData->width      = ( VGint )( width );
72     imageData->height     = ( VGint )( height );
73     imageData->dataLength = datasize;
74
75     return imageData;
76 }
77
78 /*!
79  *
80  */
81 SCTOpenVGImageData* sctOpenVGCreateSolidImageData( VGImageFormat format, int width, int height, const float color[ 4 ] )
82 {
83     SCTOpenVGImageData* imageData;
84     unsigned char*      buf;
85     unsigned int        bitShifter;
86     int                 x, y;
87     int                 sizeInBits;
88     
89     imageData = sctOpenVGCreateImageData( format, width, height );
90     if( imageData == NULL )
91     {
92         return NULL;
93     }
94
95     sizeInBits = sctiGetBitsPerPixel( format );
96     SCT_ASSERT( sizeInBits == 1  ||
97                 sizeInBits == 4  ||
98                 sizeInBits == 8  ||
99                 sizeInBits == 16 ||
100                 sizeInBits == 32 );
101
102     bitShifter = 0;   
103     /* Fill in the texture data */
104     for( y = 0; y < height; ++y )
105     {
106         buf = ( unsigned char* )( imageData->data ) + imageData->stride * y; 
107         for( x = 0; x < width; ++x )
108         {
109             sctiAssignImageColor( format,
110                                   buf,
111                                   color,
112                                   bitShifter );
113             bitShifter += sizeInBits;
114             buf += ( bitShifter / 8 );
115             bitShifter %= 8;
116         }
117     }
118     
119     return imageData;
120 }
121
122 /*!
123  *
124  */
125 SCTOpenVGImageData* sctOpenVGCreateBarImageData( VGImageFormat format, int width, int height, const float color1[ 4 ], const float color2[ 4 ], int bars )
126 {
127     SCTOpenVGImageData* imageData;
128     unsigned char*      buf;
129     unsigned int        bitShifter;
130     int                 x, y;
131     int                 sizeInBits;
132     int                 d;
133     
134     SCT_ASSERT( width > 0 && height > 0 );
135     SCT_ASSERT( color1 != NULL );
136     SCT_ASSERT( color2 != NULL );
137     SCT_ASSERT( bars > 0 );
138
139     /* Calculate the bar width in pixels. Make sure bar width is at least 1 */
140     d = width / bars;
141     d = d ? d : 1;
142
143     imageData = sctOpenVGCreateImageData( format, width, height );
144     if( imageData == NULL )
145     {
146         return NULL;
147     }
148
149     sizeInBits = sctiGetBitsPerPixel( format );
150     SCT_ASSERT( sizeInBits == 1  ||
151                 sizeInBits == 4  ||
152                 sizeInBits == 8  ||
153                 sizeInBits == 16 ||
154                 sizeInBits == 32 );
155
156     bitShifter = 0;   
157     /* Fill in the texture data */
158     for( y = 0; y < height; ++y )
159     {
160         buf = ( unsigned char* )( imageData->data ) + imageData->stride * y; 
161         for( x = 0; x < width; ++x )
162         {
163             sctiAssignImageColor( format,
164                                   buf,
165                                   ( ( x / d ) % 2 ) ? color1 : color2,
166                                   bitShifter );
167             bitShifter += sizeInBits;
168             buf += ( bitShifter / 8 );
169             bitShifter %= 8;
170         }
171     }
172     
173     return imageData;
174 }
175
176 /*!
177  *
178  */
179 SCTOpenVGImageData* sctOpenVGCreateCheckerImageData( VGImageFormat format, int width, int height, const float color1[ 4 ], const float color2[ 4 ], int checkersX, int checkersY )
180 {
181     SCTOpenVGImageData* imageData;
182     unsigned char*      buf;
183     unsigned int        bitShifter;
184     int                 x, y;
185     int                 sizeInBits;
186     int                 dx, dy;
187     const float*        color;
188     
189     SCT_ASSERT( width > 0 && height > 0 );
190     SCT_ASSERT( color1 != NULL );
191     SCT_ASSERT( color2 != NULL );
192     SCT_ASSERT( checkersX > 0 );
193     SCT_ASSERT( checkersY > 0 );
194
195     dx = width / checkersX;
196     dx = dx ? dx : 1;
197     dy = height / checkersY;
198     dy = dy ? dy : 1;
199
200     imageData = sctOpenVGCreateImageData( format, width, height );
201     if( imageData == NULL )
202     {
203         return NULL;
204     }
205
206     sizeInBits = sctiGetBitsPerPixel( format );
207     SCT_ASSERT( sizeInBits == 1  ||
208                 sizeInBits == 4  ||
209                 sizeInBits == 8  ||
210                 sizeInBits == 16 ||
211                 sizeInBits == 32 );
212
213     bitShifter = 0;   
214     /* Fill in the texture data */
215     for( y = 0; y < height; ++y )
216     {
217         buf = ( unsigned char* )( imageData->data ) + imageData->stride * y; 
218         for( x = 0; x < width; ++x )
219         {
220             if( ( x / dx ) % 2 )
221             {
222                 if( ( y / dy ) % 2 )
223                 {
224                     color = color1;
225                 }
226                 else
227                 {
228                     color = color2;
229                 }
230             }
231             else
232             {
233                 if( ( y / dy ) % 2 )
234                 {
235                     color = color2;
236                 }
237                 else
238                 {
239                     color = color1;
240                 }
241             }
242             
243             sctiAssignImageColor( format,
244                                   buf,
245                                   color,
246                                   bitShifter );
247             bitShifter += sizeInBits;
248             buf += ( bitShifter / 8 );
249             bitShifter %= 8;
250         }
251     }
252     
253     return imageData;
254 }
255 /*!
256  *
257  */
258 SCTOpenVGImageData* sctOpenVGCreateGradientImageData( VGImageFormat format, int width, int height, const float color1[ 4 ], const float color2[ 4 ], SCTOpenVGGradient gradient )
259 {
260     SCTOpenVGImageData* imageData;
261     unsigned char*      buf;
262     unsigned int        bitShifter;
263     int                 x, y;
264     int                 sizeInBits;
265     float               d           = 0.0;
266     float               r;
267     float               color[ 4 ];
268
269     SCT_ASSERT( width > 0 && height > 0 );
270     SCT_ASSERT( color1 != NULL );
271     SCT_ASSERT( color2 != NULL );
272
273     imageData = sctOpenVGCreateImageData( format, width, height );
274     if( imageData == NULL )
275     {
276         return NULL;
277     }
278
279     sizeInBits = sctiGetBitsPerPixel( format );
280     SCT_ASSERT( sizeInBits == 1  ||
281                 sizeInBits == 4  ||
282                 sizeInBits == 8  ||
283                 sizeInBits == 16 ||
284                 sizeInBits == 32 );
285
286     bitShifter = 0;   
287     
288     if( gradient == OPENVG_GRADIENT_HORIZONTAL )
289     {
290         if( width > 1 )
291         {
292             d = 1.0f / ( float )( width - 1 );
293         }
294         for( y = 0; y < height; ++y )
295         {
296             buf = ( unsigned char* )( imageData->data ) + imageData->stride * y;             
297             r = 0;
298             for( x = 0; x < width; ++x )
299             {
300                 color[ 0 ] = color1[ 0 ] * ( 1 - r ) + color2[ 0 ] * ( r );
301                 color[ 1 ] = color1[ 1 ] * ( 1 - r ) + color2[ 1 ] * ( r );
302                 color[ 2 ] = color1[ 2 ] * ( 1 - r ) + color2[ 2 ] * ( r );
303                 color[ 3 ] = color1[ 3 ] * ( 1 - r ) + color2[ 3 ] * ( r );
304
305                 sctiAssignImageColor( format,
306                                       buf,
307                                       color,
308                                       bitShifter );
309                 bitShifter += sizeInBits;
310                 buf += ( bitShifter / 8 );
311                 bitShifter %= 8;
312                 r += d;
313             }
314         }
315     }
316     else if( gradient == OPENVG_GRADIENT_VERTICAL )
317     {
318         if( height > 1 )
319         {
320             d = 1.0f / ( float )( height - 1 );
321         }
322
323         r = 0;
324         for( y = 0; y < height; ++y )
325         {
326             buf = ( unsigned char* )( imageData->data ) + imageData->stride * y;         
327             
328             color[ 0 ] = color1[ 0 ] * ( 1 - r ) + color2[ 0 ] * ( r );
329             color[ 1 ] = color1[ 1 ] * ( 1 - r ) + color2[ 1 ] * ( r );
330             color[ 2 ] = color1[ 2 ] * ( 1 - r ) + color2[ 2 ] * ( r );
331             color[ 3 ] = color1[ 3 ] * ( 1 - r ) + color2[ 3 ] * ( r );
332             
333             for( x = 0; x < width; ++x )
334             {
335                 sctiAssignImageColor( format,
336                                       buf,
337                                       color,
338                                       bitShifter );
339                 bitShifter += sizeInBits;
340                 buf += ( bitShifter / 8 );
341                 bitShifter %= 8;                
342             }
343             r += d;
344         }
345     }
346     else
347     {
348         d = 1.0f / ( float )( width * height - 1 );
349         r = 0;
350         
351         for( y = 0; y < height; ++y )
352         {
353             buf = ( unsigned char* )( imageData->data ) + imageData->stride * y;
354             
355             for( x = 0; x < width; ++x )
356             {
357                 r = y * x * d;
358                 
359                 color[ 0 ] = color1[ 0 ] * ( 1 - r ) + color2[ 0 ] * ( r );
360                 color[ 1 ] = color1[ 1 ] * ( 1 - r ) + color2[ 1 ] * ( r );
361                 color[ 2 ] = color1[ 2 ] * ( 1 - r ) + color2[ 2 ] * ( r );
362                 color[ 3 ] = color1[ 3 ] * ( 1 - r ) + color2[ 3 ] * ( r );
363
364                 sctiAssignImageColor( format,
365                                       buf,
366                                       color,
367                                       bitShifter );
368                 bitShifter += sizeInBits;
369                 buf += ( bitShifter / 8 );
370                 bitShifter %= 8;                
371             }
372         }
373     }
374     
375     return imageData;
376 }
377
378 /*!
379  *
380  *
381  */
382 void sctOpenVGDestroyImageData( SCTOpenVGImageData* data )
383 {
384     if( data == NULL )
385     {
386         return;
387     }
388
389     if( data->data != NULL )
390     {
391         siCommonMemoryFree( NULL, data->data );
392     }
393     siCommonMemoryFree( NULL, data );
394 }
395
396 /*!
397  *
398  *
399  */
400 static SCTBoolean sctiGetImageDataSizeAndStride( VGImageFormat format, int width, int height, int* datasize, int* stride )
401 {
402     int bitsPerPixel = 0;
403     int bitsPerLine  = 0;
404     int s;
405
406     bitsPerPixel = sctiGetBitsPerPixel( format );
407
408     if( bitsPerPixel == 0 )
409     {
410         SCT_ASSERT( 0 );
411         return SCT_FALSE;
412     }
413     
414     /* Calculate the number of bytes per image line. */
415     bitsPerLine = ( width * bitsPerPixel );
416     s = bitsPerLine / 8;
417
418     if( format == VG_BW_1 && ( bitsPerLine % 8 ) != 0 )
419     {
420         /* We add padding bits to line when the number of pixels in
421          line is not multiple of 8. */
422         s += 1;
423     }
424     
425     *datasize = s * height;
426     *stride   = s;
427
428     return SCT_TRUE;
429 }
430
431 /*!
432  *
433  */
434 static int sctiGetBitsPerPixel( VGImageFormat format )
435 {   
436     switch( format )
437     {
438     default:
439         return 0;
440     case VG_BW_1:
441     case VG_A_1:
442         return 1;
443     case VG_A_4:
444         return 4;
445     case VG_sL_8:
446     case VG_lL_8:
447     case VG_A_8:
448         return 8;
449     case VG_sRGB_565:
450     case VG_sBGR_565:
451     case VG_sRGBA_5551:
452     case VG_sRGBA_4444:
453     case VG_sARGB_1555:
454     case VG_sARGB_4444:
455     case VG_sBGRA_5551:
456     case VG_sBGRA_4444:
457     case VG_sABGR_1555:
458     case VG_sABGR_4444:
459         return 16;
460     case VG_sRGBX_8888:
461     case VG_sRGBA_8888:
462     case VG_sRGBA_8888_PRE:
463     case VG_lRGBX_8888:
464     case VG_lRGBA_8888:
465     case VG_lRGBA_8888_PRE:
466     case VG_sXRGB_8888:
467     case VG_sARGB_8888:
468     case VG_sARGB_8888_PRE:
469     case VG_lXRGB_8888:
470     case VG_lARGB_8888:
471     case VG_lARGB_8888_PRE:
472     case VG_sBGRX_8888:
473     case VG_sBGRA_8888:
474     case VG_sBGRA_8888_PRE:
475     case VG_lBGRX_8888:
476     case VG_lBGRA_8888:
477     case VG_lBGRA_8888_PRE:
478     case VG_sXBGR_8888:
479     case VG_sABGR_8888:
480     case VG_sABGR_8888_PRE:
481     case VG_lXBGR_8888:
482     case VG_lABGR_8888:
483     case VG_lABGR_8888_PRE:
484         return 32;
485     }
486 }
487
488 /*!
489  *
490  */
491 void sctiAssignImageColor( VGImageFormat format, void* dest, const float* color, unsigned int shift )
492 {
493     unsigned char*  cp = ( unsigned char* )( dest );
494     unsigned short* sp = ( unsigned short* )( dest );
495     unsigned int*   ip = ( unsigned int* )( dest );
496     unsigned char   c;
497     unsigned short  s;
498     unsigned int    i;
499
500     SCT_ASSERT( dest != NULL );
501     SCT_ASSERT( color != NULL );
502
503     switch( format )
504     {
505     default:
506         SCT_ASSERT_ALWAYS( 0 );
507         break;
508     case VG_BW_1:
509         c = ( unsigned char )( ( ( ( unsigned int )( color[ 0 ] + 0.5f ) << shift ) & ( 0x0001 << shift ) ) );
510         *cp |= c;
511         break;
512     case VG_A_1:
513         c = ( unsigned char )( ( ( ( unsigned int )( color[ 3 ] + 0.5f ) << shift ) & ( 0x0001 << shift ) ) );
514         *cp |= c;
515         break;
516     case VG_A_4:
517         c = ( unsigned char )( ( ( ( unsigned int )( color[ 3 ] * 0xF ) << shift ) & ( 0x000F << shift ) ) );
518         *cp |= c;
519         break;
520     case VG_sL_8:
521     case VG_lL_8:
522         *cp = ( unsigned char )( color[ 0 ] * 255 );        
523         break;
524     case VG_A_8:
525         *cp = ( unsigned char )( color[ 3 ] * 255 );        
526         break;        
527     case VG_sRGB_565:
528         s = ( unsigned short )(
529             ( ( ( unsigned int )( color[ 0 ] * 0x1F ) << 11 ) & 0xF800 ) |
530             ( ( ( unsigned int )( color[ 1 ] * 0x3F ) << 5 )  & 0x07E0 ) |
531             (   ( unsigned int )( color[ 2 ] * 0x1F )         & 0x001F ) );
532         *sp = s;
533         break;        
534     case VG_sBGR_565:
535         s = ( unsigned short )(
536             ( ( ( unsigned int )( color[ 2 ] * 0x1F ) << 11 ) & 0xF800 ) |
537             ( ( ( unsigned int )( color[ 1 ] * 0x3F ) << 5 )  & 0x07E0 ) |
538             (   ( unsigned int )( color[ 0 ] * 0x1F )         & 0x001F ) );
539         *sp = s;
540         break;
541     case VG_sRGBA_4444:
542         s = ( unsigned short )(
543             ( ( ( unsigned int )( color[ 0 ] * 0xF ) << 12 ) & 0xF000 ) |
544             ( ( ( unsigned int )( color[ 1 ] * 0xF ) << 8 )  & 0x0F00 ) |
545             ( ( ( unsigned int )( color[ 2 ] * 0xF ) << 4 )  & 0x00F0 ) |
546               ( ( unsigned int )( color[ 3 ] * 0xF )         & 0x000F ) );
547         *sp = s;
548         break;       
549     case VG_sBGRA_4444:
550         s = ( unsigned short )(
551             ( ( ( unsigned int )( color[ 2 ] * 0xF ) << 12 ) & 0xF000 ) |
552             ( ( ( unsigned int )( color[ 1 ] * 0xF ) << 8 )  & 0x0F00 ) |
553             ( ( ( unsigned int )( color[ 0 ] * 0xF ) << 4 )  & 0x00F0 ) |
554               ( ( unsigned int )( color[ 3 ] * 0xF )         & 0x000F ) );
555         *sp = s;
556         break;       
557     case VG_sABGR_4444:
558         s = ( unsigned short )(
559             ( ( ( unsigned int )( color[ 3 ] * 0xF ) << 12 ) & 0xF000 ) |
560             ( ( ( unsigned int )( color[ 2 ] * 0xF ) << 8 )  & 0x0F00 ) |
561             ( ( ( unsigned int )( color[ 1 ] * 0xF ) << 4 )  & 0x00F0 ) |
562               ( ( unsigned int )( color[ 0 ] * 0xF )         & 0x000F ) );
563         *sp = s;
564         break;       
565     case VG_sARGB_4444:
566         s = ( unsigned short )(
567             ( ( ( unsigned int )( color[ 3 ] * 0xF ) << 12 ) & 0xF000 ) |
568             ( ( ( unsigned int )( color[ 0 ] * 0xF ) << 8 )  & 0x0F00 ) |
569             ( ( ( unsigned int )( color[ 1 ] * 0xF ) << 4 )  & 0x00F0 ) |
570               ( ( unsigned int )( color[ 2 ] * 0xF )         & 0x000F ) );
571         *sp = s;
572         break;       
573     case VG_sRGBA_5551:
574         s = ( unsigned short )(
575             ( ( ( unsigned int )( color[ 0 ] * 0x1F ) << 11 ) & 0xF800 ) |
576             ( ( ( unsigned int )( color[ 1 ] * 0x1F ) << 6 )  & 0x07C0 ) |
577             ( ( ( unsigned int )( color[ 2 ] * 0x1F ) << 1 )  & 0x003E ) |
578               ( ( unsigned int )( color[ 3 ] + 0.5f )         & 0x0001 ) );
579         *sp = s;
580         break;       
581     case VG_sBGRA_5551:
582         s = ( unsigned short )(
583             ( ( ( unsigned int )( color[ 2 ] * 0x1F ) << 11 ) & 0xF800 ) |
584             ( ( ( unsigned int )( color[ 1 ] * 0x1F ) << 6 )  & 0x07C0 ) |
585             ( ( ( unsigned int )( color[ 0 ] * 0x1F ) << 1 )  & 0x003E ) |
586               ( ( unsigned int )( color[ 3 ] + 0.5f )         & 0x0001 ) );
587         *sp = s;
588         break;       
589     case VG_sARGB_1555:
590         s = ( unsigned short )(
591             ( ( ( unsigned int )( color[ 3 ] + 0.5f ) << 15 ) & 0x8000 ) |
592             ( ( ( unsigned int )( color[ 0 ] * 0x1F ) << 10 ) & 0x7C00 ) |
593             ( ( ( unsigned int )( color[ 1 ] * 0x1F ) << 5 )  & 0x03E0 ) |
594               ( ( unsigned int )( color[ 2 ] * 0x1F )         & 0x001F ) );
595         *sp = s;
596         break;       
597     case VG_sABGR_1555:
598         s = ( unsigned short )(
599             ( ( ( unsigned int )( color[ 3 ] + 0.5f ) << 15 ) & 0x8000 ) |
600             ( ( ( unsigned int )( color[ 2 ] * 0x1F ) << 10 ) & 0x7C00 ) |
601             ( ( ( unsigned int )( color[ 1 ] * 0x1F ) << 5 )  & 0x03E0 ) |
602               ( ( unsigned int )( color[ 0 ] * 0x1F )         & 0x001F ) );
603         *sp = s;
604         break;       
605     case VG_sRGBX_8888:        
606     case VG_lRGBX_8888:
607         i = ( unsigned int )(
608             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
609             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
610             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
611               ( ( unsigned int )( 0 )                         & 0x000000FF ) );
612         *ip = i;
613         break;
614     case VG_sXRGB_8888:
615     case VG_lXRGB_8888:
616         i = ( unsigned int )(
617             ( ( ( unsigned int )( 0 )                 << 24 ) & 0xFF000000 ) |
618             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
619             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
620               ( ( unsigned int )( color[ 2 ] * 0xFF )         & 0x000000FF ) );
621         *ip = i;
622         break;
623     case VG_sBGRX_8888:
624     case VG_lBGRX_8888:
625         i = ( unsigned int )(
626             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
627             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
628             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
629               ( ( unsigned int )( 0 )                         & 0x000000FF ) );
630         *ip = i;
631         break;
632     case VG_sXBGR_8888:
633     case VG_lXBGR_8888:
634         i = ( unsigned int )(
635             ( ( ( unsigned int )( 0 )                 << 24 ) & 0xFF000000 ) |
636             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
637             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
638               ( ( unsigned int )( color[ 0 ] * 0xFF )         & 0x000000FF ) );
639         *ip = i;
640         break;
641     case VG_sRGBA_8888:
642     case VG_sRGBA_8888_PRE:
643     case VG_lRGBA_8888:
644     case VG_lRGBA_8888_PRE:
645         i = ( unsigned int )(
646             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
647             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
648             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
649               ( ( unsigned int )( color[ 3 ] * 0xFF )         & 0x000000FF ) );
650         *ip = i;
651         break;
652     case VG_sARGB_8888:
653     case VG_sARGB_8888_PRE:
654     case VG_lARGB_8888:
655     case VG_lARGB_8888_PRE:
656         i = ( unsigned int )(
657             ( ( ( unsigned int )( color[ 3 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
658             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
659             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
660               ( ( unsigned int )( color[ 2 ] * 0xFF )         & 0x000000FF ) );
661         *ip = i;
662         break;
663     case VG_sBGRA_8888:
664     case VG_sBGRA_8888_PRE:
665     case VG_lBGRA_8888:
666     case VG_lBGRA_8888_PRE:
667         i = ( unsigned int )(
668             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
669             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
670             ( ( ( unsigned int )( color[ 0 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
671               ( ( unsigned int )( color[ 3 ] * 0xFF )         & 0x000000FF ) );
672         *ip = i;
673         break;        
674     case VG_sABGR_8888:
675     case VG_sABGR_8888_PRE:
676     case VG_lABGR_8888:
677     case VG_lABGR_8888_PRE:
678         i = ( unsigned int )(
679             ( ( ( unsigned int )( color[ 3 ] * 0xFF ) << 24 ) & 0xFF000000 ) |
680             ( ( ( unsigned int )( color[ 2 ] * 0xFF ) << 16 ) & 0x00FF0000 ) |
681             ( ( ( unsigned int )( color[ 1 ] * 0xFF ) << 8 )  & 0x0000FF00 ) |
682               ( ( unsigned int )( color[ 0 ] * 0xFF )         & 0x000000FF ) );
683         *ip = i;
684         break;
685     }   
686 }
687
688 /*!
689  *
690  */
691 static int sctiGetPathDatatypeSize( VGPathDatatype type )
692 {
693     switch( type )
694     {
695     case VG_PATH_DATATYPE_S_8:
696         return sizeof( VGbyte );
697
698     case VG_PATH_DATATYPE_S_16:
699         return sizeof( VGshort );
700
701     case VG_PATH_DATATYPE_S_32:
702         return sizeof( VGint );
703
704     case VG_PATH_DATATYPE_F:
705         return sizeof( VGfloat );
706
707     default:
708         return -1;
709     }
710 }
711
712 /*!
713  *
714  */
715 SCTOpenVGPath* sctOpenVGCreatePath( VGPath path, VGPathDatatype type )
716 {
717     SCTOpenVGPath* p;
718     
719     p = ( SCTOpenVGPath* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGPath ) ) );
720     if( p != NULL )
721     {
722         p->path = path;
723         p->type = type;
724     }
725     return p;
726 }
727
728 /*!
729  *
730  */
731 void sctOpenVGDestroyPath( SCTOpenVGPath* path )
732 {
733     if( path != NULL )
734     {
735         siCommonMemoryFree( NULL, path );
736     }
737 }
738
739 /*!
740  *
741  */
742 SCTOpenVGImage* sctOpenVGCreateImage( VGImage image, int width, int height  )
743 {
744     SCTOpenVGImage* i;
745
746     i = ( SCTOpenVGImage* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGImage ) ) );
747     if( i != NULL )
748     {
749         i->image  = image;
750         i->width  = ( VGint )( width );
751         i->height = ( VGint )( height );
752     }
753     return i;
754 }
755
756 /*!
757  *
758  */
759 void sctOpenVGDestroyImage( SCTOpenVGImage* image )
760 {
761     if( image != NULL )
762     {
763         siCommonMemoryFree( NULL, image );
764     }
765 }
766
767 /*!
768  *
769  */
770 SCTOpenVGPaint* sctOpenVGCreatePaint( VGPaint paint )
771 {
772     SCTOpenVGPaint* p;
773     
774     p = ( SCTOpenVGPaint* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGPaint ) ) );
775     if( p != NULL )
776     {
777         p->paint = paint;
778     }
779     return p;
780 }
781
782 /*!
783  *
784  */
785 void sctOpenVGDestroyPaint( SCTOpenVGPaint* paint )
786 {
787     if( paint != NULL )
788     {
789         siCommonMemoryFree( NULL, paint );
790     }
791 }
792
793 #if defined( OPENVG_VERSION_1_1 )
794
795 /*!
796  *
797  */
798 SCTOpenVGFont* sctOpenVGCreateFont( VGFont font )
799 {
800     SCTOpenVGFont* f;
801     
802     f = ( SCTOpenVGFont* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGFont ) ) );
803     if( f != NULL )
804     {
805         f->font = font;
806     }
807     return f;
808 }
809
810 /*!
811  *
812  */
813 void sctOpenVGDestroyFont( SCTOpenVGFont* font )
814 {
815     if( font != NULL )
816     {
817         siCommonMemoryFree( NULL, font );
818     }
819 }
820
821 /*!
822  *
823  */
824 SCTOpenVGMaskLayer* sctOpenVGCreateMaskLayer( VGMaskLayer maskLayer )
825 {
826     SCTOpenVGMaskLayer* ml;
827     
828     ml = ( SCTOpenVGMaskLayer* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGMaskLayer ) ) );
829     if( ml != NULL )
830     {
831         ml->maskLayer = maskLayer;
832     }
833     return ml;
834 }
835
836 /*!
837  *
838  */
839 void sctOpenVGDestroyMaskLayer( SCTOpenVGMaskLayer* maskLayer )
840 {
841     if( maskLayer != NULL )
842     {
843         siCommonMemoryFree( NULL, maskLayer );
844     }
845 }
846
847 #endif /* defined( OPENVG_VERSION_1_1 ) */
848
849 /*!
850  *
851  *
852  */
853 SCTOpenVGPathData* sctOpenVGCreatePathData( VGPathDatatype type, int initialSegments, int initialData )
854 {
855     SCTOpenVGPathData*  data;
856     int                 segmentsSize;
857     int                 dataSize;
858
859     dataSize = sctiGetPathDatatypeSize( type ) * initialData;
860     segmentsSize = initialSegments * sizeof( VGubyte );
861     if( segmentsSize <= 0 || dataSize <= 0 )
862     {
863         return NULL;
864     }
865
866     data = ( SCTOpenVGPathData* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGPathData ) ) );
867     if( data == NULL )
868     {
869         return NULL;
870     }
871     memset( data, 0, sizeof( SCTOpenVGPathData ) );
872
873     data->type           = type;
874     data->numSegments    = 0;
875     data->maxNumSegments = initialSegments;
876     data->dataLength     = 0;
877     data->maxDataLength  = initialData;
878
879     data->segments = ( VGubyte* )( siCommonMemoryAlloc( NULL, segmentsSize ) );
880     data->data     = siCommonMemoryAlloc( NULL, dataSize );
881
882     if( data->segments == NULL || data->data == NULL )
883     {
884         sctOpenVGDestroyPathData( data );
885         return NULL;
886     }
887
888     memset( data->segments, 0, segmentsSize );
889     memset( data->data, 0, dataSize );
890     
891     return data;
892 }
893
894 /*!
895  *
896  *
897  */
898 void sctOpenVGClearPathData( SCTOpenVGPathData* pathData )
899 {
900     SCT_ASSERT( pathData != NULL );
901
902     pathData->numSegments = 0;
903     pathData->dataLength  = 0;
904 }
905
906 /*!
907  *
908  *
909  */
910 SCTBoolean sctOpenVGAddPathData( SCTOpenVGPathData* pathData, const VGubyte* segments, int numSegments, void* data, int dataLength, VGPathDatatype dataType )
911 {
912     int dataTypeSize = 0;
913
914     SCT_ASSERT( pathData != NULL );
915     SCT_ASSERT( segments != NULL );
916     SCT_ASSERT( numSegments > 0 );
917
918     if( ( int )( dataType ) < 0 && dataLength > 0 )
919     {
920         return SCT_FALSE;
921     }
922
923     if( ( int )( dataType ) >= 0 && pathData->type != dataType )
924     {
925         return SCT_FALSE;
926     }
927
928     if( dataLength > 0 )
929     {
930         dataTypeSize = sctiGetPathDatatypeSize( dataType );
931         SCT_ASSERT( dataTypeSize > 0 );
932     }
933
934     if( pathData->numSegments + numSegments > pathData->maxNumSegments )
935     {
936         VGubyte*    newSegments;
937         int         newMaxNumSegments;
938
939         newMaxNumSegments = ( pathData->numSegments + numSegments ) * 2;
940         newSegments = ( VGubyte* )( siCommonMemoryAlloc( NULL, sizeof( VGubyte ) * newMaxNumSegments ) );
941         if( newSegments == NULL )
942         {
943             return SCT_FALSE;
944         }
945
946         memcpy( newSegments, pathData->segments, sizeof( VGubyte ) * pathData->numSegments );
947         siCommonMemoryFree( NULL, pathData->segments );
948
949         pathData->segments = newSegments;
950         pathData->maxNumSegments = newMaxNumSegments;
951     }
952
953     if( pathData->dataLength + dataLength > pathData->maxDataLength )
954     {
955         void*   newData;
956         int     newMaxDataLength;
957
958         newMaxDataLength = ( pathData->dataLength + dataLength ) * 2;
959         newData = siCommonMemoryAlloc( NULL, dataTypeSize * newMaxDataLength );
960         if( newData == NULL )
961         {
962             return SCT_FALSE;
963         }
964
965         memcpy( newData, pathData->data, dataTypeSize * pathData->dataLength );
966         siCommonMemoryFree( NULL, pathData->data );
967
968         pathData->data = newData;
969         pathData->maxDataLength = newMaxDataLength;
970     }
971
972     SCT_ASSERT( pathData->numSegments + numSegments <= pathData->maxNumSegments );
973     memcpy( pathData->segments + pathData->numSegments, segments, sizeof( VGubyte ) * numSegments );
974     pathData->numSegments += numSegments;
975
976     if( dataLength > 0 )
977     {
978         SCT_ASSERT( pathData->dataLength + dataLength <= pathData->maxDataLength );
979         memcpy( ( ( char* )( pathData->data ) ) + ( pathData->dataLength * dataTypeSize ), data, dataLength * dataTypeSize );
980         pathData->dataLength += dataLength;
981     }
982     
983     return SCT_TRUE;
984 }
985
986 /*!
987  *
988  *
989  */
990 void sctOpenVGDestroyPathData( SCTOpenVGPathData* pathData )
991 {
992     if( pathData != NULL )
993     {
994         if( pathData->segments != NULL )
995         {
996             siCommonMemoryFree( NULL, pathData->segments );
997             pathData->segments = NULL;
998         }
999         if( pathData->data != NULL )
1000         {
1001             siCommonMemoryFree( NULL, pathData->data );
1002             pathData->data = NULL;
1003         }
1004
1005         siCommonMemoryFree( NULL, pathData );
1006     }
1007 }
1008
1009
1010 /*!
1011  *
1012  *
1013  */
1014 void sctOpenVGAssignTypeArray( void* destination, VGPathDatatype type, const VGfloat* source, VGint length )
1015 {
1016     int         i;     
1017     VGbyte*     cp  = ( VGbyte* )( destination );
1018     VGshort*    sp  = ( VGshort* )( destination );
1019     VGint*      ip  = ( VGint* )( destination );
1020     VGfloat*    fp  = ( VGfloat* )( destination );
1021
1022     SCT_ASSERT_ALWAYS( destination != NULL );
1023     SCT_ASSERT_ALWAYS( type == VG_PATH_DATATYPE_S_8  || 
1024                        type != VG_PATH_DATATYPE_S_16 || 
1025                        type != VG_PATH_DATATYPE_S_32 || 
1026                        type != VG_PATH_DATATYPE_F );
1027     SCT_ASSERT_ALWAYS( source != NULL );
1028     SCT_ASSERT_ALWAYS( length > 0 );
1029
1030     for( i = 0; i < length; ++i )
1031     {
1032         switch( type )
1033         {
1034         case VG_PATH_DATATYPE_S_8:
1035             *cp++ = ( VGbyte )( *source++ );
1036             break;
1037
1038         case VG_PATH_DATATYPE_S_16:
1039             SCT_ASSERT_ALWAYS( ( int )sp % sizeof( VGshort ) == 0 ); /* Check alignment */
1040             *sp++ = ( VGshort )( *source++ );
1041             break;
1042
1043         case VG_PATH_DATATYPE_S_32:
1044             SCT_ASSERT_ALWAYS( ( int )ip % sizeof( VGint ) == 0 ); /* Check alignment */
1045             *ip++ = ( VGint )( *source++ );
1046             break;
1047
1048         default:
1049         case VG_PATH_DATATYPE_F:
1050             SCT_ASSERT_ALWAYS( (int )fp % sizeof( VGfloat ) == 0 );
1051             *fp++ = *source++;
1052             break;
1053         }
1054     }
1055 }
1056
1057 /*!
1058  *
1059  *
1060  */
1061 void sctOpenVGRescaleToDatatypeRange( VGfloat* src, VGfloat* dst, int length, VGPathDatatype datatype, VGfloat* scale, VGfloat* bias )
1062 {
1063     int     i;
1064     VGfloat maxValue;
1065     VGfloat min, max;
1066     VGfloat div;
1067     VGfloat average;
1068
1069     SCT_ASSERT_ALWAYS( src != NULL );
1070     SCT_ASSERT_ALWAYS( dst != NULL );
1071     SCT_ASSERT_ALWAYS( length > 0 );
1072     SCT_ASSERT_ALWAYS( scale != NULL );
1073     SCT_ASSERT_ALWAYS( bias != NULL );
1074
1075     /* We do not need to do anything with float. */
1076     if( datatype == VG_PATH_DATATYPE_F )
1077     {
1078         for( i = 0; i < length; ++i )
1079         {
1080             dst[ i ] = src[ i ];
1081         }
1082         *scale = 1;
1083         *bias  = 0;
1084         return;
1085     }
1086
1087     switch( datatype )
1088     {
1089     case VG_PATH_DATATYPE_S_8:
1090         maxValue = ( VGfloat )( 0xFF / 2.0f );
1091         break;
1092
1093     case VG_PATH_DATATYPE_S_16:
1094         /* There seems to be an error in OpenVG 1.0 headers for VG_MAXSHORT and
1095          * VG_MAXINT definitions. They result to value -1. Patch it here. */
1096         maxValue = (VGfloat) (( 1 << 15 ) - 1 );
1097         break;
1098
1099     case VG_PATH_DATATYPE_S_32:
1100         /* There seems to be an error in OpenVG 1.0 headers for VG_MAXSHORT and
1101          * VG_MAXINT definitions. They result to value -1. Patch it here. */
1102         maxValue = (VGfloat) ( ( unsigned )( 1 << 31 ) - 1 );
1103         break;
1104
1105     default:
1106         SCT_ASSERT_ALWAYS( 0 );
1107         return;
1108     }
1109
1110     max = src[ 0 ];
1111     min = src[ 0 ];
1112     
1113     /* Find minimum and maximum values in the array. */
1114     for( i = 0; i < length; ++i )
1115     {
1116         if( src[ i ] > max )
1117         {
1118             max = src[ i ];
1119         }
1120         if( src[ i ] < min )
1121         {
1122             min = src[ i ];
1123         }
1124     }
1125
1126     /*
1127         |
1128         |____________________________ max
1129         |
1130      div|
1131         |____________________________ average
1132         |
1133      div|
1134         |____________________________ min
1135         |
1136         |
1137         |______________________________
1138
1139     */
1140
1141     if( min == max )
1142     {
1143         maxValue = sctMaxf( maxValue, sctMaxf( -min, max ) );
1144
1145         for( i = 0; i < length; ++i )
1146         {
1147             dst[ i ] = src[ i ] / maxValue;
1148         }
1149         *scale = maxValue;
1150         *bias = 0;
1151         return;
1152     }
1153
1154     average = ( max + min ) / 2;
1155     div = average - min;
1156     div = sctMaxf( -div, div );
1157
1158     for( i = 0; i < length; ++i )
1159     {
1160         dst[ i ] = ( src[ i ] - average ) / div;
1161         dst[ i ] *= maxValue;
1162     }
1163
1164     *bias  = average;
1165     *scale = div / maxValue;
1166 }
1167
1168 /*!
1169  *
1170  *
1171  */
1172 SCTBoolean sctOpenVGConvertTypeArray( void* dst, VGPathDatatype dstType, void* src, VGPathDatatype srcType, int length )
1173 {
1174     int         i;
1175     VGfloat*    tmpBuf;
1176     VGfloat*    p;
1177     SCTBoolean  ok      = SCT_TRUE;
1178
1179     VGbyte*     csrc    = ( VGbyte* )( src );
1180     VGshort*    ssrc    = ( VGshort* )( src );
1181     VGint*      isrc    = ( VGint* )( src );
1182     VGfloat*    fsrc    = ( VGfloat* )( src );
1183
1184     SCT_ASSERT_ALWAYS( src != NULL );
1185     SCT_ASSERT_ALWAYS( srcType == VG_PATH_DATATYPE_S_8  || 
1186                        srcType != VG_PATH_DATATYPE_S_16 || 
1187                        srcType != VG_PATH_DATATYPE_S_32 || 
1188                        srcType != VG_PATH_DATATYPE_F );
1189     SCT_ASSERT_ALWAYS( dst != NULL );
1190     SCT_ASSERT_ALWAYS( dstType == VG_PATH_DATATYPE_S_8  || 
1191                        dstType != VG_PATH_DATATYPE_S_16 || 
1192                        dstType != VG_PATH_DATATYPE_S_32 || 
1193                        dstType != VG_PATH_DATATYPE_F );
1194     SCT_ASSERT_ALWAYS( length > 0 );
1195
1196     tmpBuf = ( VGfloat* )( siCommonMemoryAlloc( NULL, length * sizeof( VGfloat ) ) );
1197     if( tmpBuf == NULL )
1198     {
1199         return SCT_FALSE;
1200     }
1201
1202     p = tmpBuf;
1203
1204     /* First, convert src to float, perform range check. */
1205     for( i = 0; i < length && ok == SCT_TRUE; ++i )
1206     {
1207         /* Conversion to float. */
1208         switch( srcType )
1209         {
1210         case VG_PATH_DATATYPE_S_8:
1211             *p = *csrc++;
1212             break;
1213
1214         case VG_PATH_DATATYPE_S_16:
1215             *p = *ssrc++;
1216             break;
1217
1218         case VG_PATH_DATATYPE_S_32:
1219             *p = ( float )( *isrc++ );
1220             break;
1221
1222         default:
1223         case VG_PATH_DATATYPE_F:
1224             *p = *fsrc++;
1225             break;
1226         }
1227
1228         /* range check. */
1229         switch( dstType )
1230         {
1231         case VG_PATH_DATATYPE_S_8:
1232             if( ( *p > ( 0xFF / 2 ) ) || ( *p < ( -0xFF / 2 ) ) )
1233             {
1234                 ok = SCT_FALSE;
1235             }
1236             break;
1237
1238         case VG_PATH_DATATYPE_S_16:
1239             if( ( *p > ( SCT_MAX_SHORT ) ) || ( *p < ( SCT_MIN_SHORT ) ) )
1240             {
1241                 ok = SCT_FALSE;
1242             }
1243             break;
1244
1245         default:
1246         case VG_PATH_DATATYPE_S_32:
1247         case VG_PATH_DATATYPE_F:
1248             break;
1249         }
1250
1251         p++;
1252     }
1253
1254     if( ok == SCT_TRUE )
1255     {
1256         sctOpenVGAssignTypeArray( dst, dstType, tmpBuf, length );
1257     }
1258
1259     siCommonMemoryFree( NULL, tmpBuf );
1260
1261     return ok;
1262 }
1263
1264 /*!
1265  *
1266  *
1267  */
1268 SCTBoolean sctOpenVGConvertDoubleArray( void* dst, VGPathDatatype dstType, double* src, int length )
1269 {
1270     int         i;
1271     SCTBoolean  ok      = SCT_TRUE;
1272
1273     VGbyte*     cdst    = ( VGbyte* )( dst );
1274     VGshort*    sdst    = ( VGshort* )( dst );
1275     VGint*      idst    = ( VGint* )( dst );
1276     VGfloat*    fdst    = ( VGfloat* )( dst );
1277
1278     SCT_ASSERT_ALWAYS( dst != NULL );
1279     SCT_ASSERT_ALWAYS( dstType == VG_PATH_DATATYPE_S_8  || 
1280                        dstType != VG_PATH_DATATYPE_S_16 || 
1281                        dstType != VG_PATH_DATATYPE_S_32 || 
1282                        dstType != VG_PATH_DATATYPE_F );
1283     SCT_ASSERT_ALWAYS( src != NULL );
1284     SCT_ASSERT_ALWAYS( length > 0 );
1285
1286     for( i = 0; i < length && ok == SCT_TRUE; ++i )
1287     {
1288         switch( dstType )
1289         {
1290         case VG_PATH_DATATYPE_S_8:
1291             if( *src < -0x7F || *src > 0x7F )
1292             {
1293                 ok = SCT_FALSE;
1294             }
1295             else
1296             {
1297                 *cdst++ = ( VGbyte )( *src++ );
1298             }
1299             break;
1300
1301         case VG_PATH_DATATYPE_S_16:
1302             if( *src < -0x7FFF || *src > 0x7FFF )
1303             {
1304                 ok = SCT_FALSE;
1305             }
1306             else
1307             {
1308                 *sdst++ = ( VGshort )( *src++ );
1309             }
1310             break;
1311
1312         case VG_PATH_DATATYPE_S_32:
1313             if( *src < -0x7FFFFFFF || *src > 0x7FFFFFFF )
1314             {
1315                 ok = SCT_FALSE;
1316             }
1317             else
1318             {
1319                 *idst++ = ( VGint )( *src++ );
1320             }
1321             break;
1322
1323         default:
1324         case VG_PATH_DATATYPE_F:
1325             *fdst++ = ( VGfloat )( *src++ );
1326             break;
1327         }
1328     }
1329
1330     return ok;
1331 }
1332
1333 /*!
1334  *
1335  *
1336  */
1337 SCTOpenVGData* sctOpenVGCreateData( void* data, int length, SCTBoolean copy )
1338 {
1339     SCTOpenVGData*  d;
1340
1341     SCT_ASSERT( data != NULL );
1342     SCT_ASSERT( length > 0 );
1343
1344     d = ( SCTOpenVGData* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGData ) ) );
1345     if( d == NULL )
1346     {
1347         return NULL;
1348     }
1349     
1350     if( copy == SCT_TRUE )
1351     {
1352         d->data = siCommonMemoryAlloc( NULL, length );
1353         if( d->data == NULL )
1354         {
1355             siCommonMemoryFree( NULL, d );
1356             return NULL;
1357         }
1358         memcpy( d->data, data, length );
1359     }
1360     else
1361     {
1362         d->data = data;
1363     }
1364    
1365     d->length = length;
1366
1367     return d;
1368 }
1369
1370 /*!
1371  *
1372  *
1373  */
1374 void sctOpenVGDestroyData( SCTOpenVGData* data )
1375 {
1376     if( data != NULL )
1377     {
1378         if( data->data != NULL )
1379         {
1380             siCommonMemoryFree( NULL, data->data );
1381             data->data = NULL;
1382         }
1383         siCommonMemoryFree( NULL, data );
1384     }
1385 }
1386
1387 /*!
1388  *
1389  *
1390  */
1391 void sctOpenVGInitializeLUT8( VGubyte* lut, int length, float start, float end )
1392 {
1393     int     i, len;
1394     float   r;
1395     
1396     SCT_ASSERT_ALWAYS( lut != NULL );
1397     SCT_ASSERT_ALWAYS( length > 0 );
1398
1399     if( length == 1 )
1400     {
1401         lut[ 0 ] = ( VGubyte )( ( start + end ) / 2 * 0xFF );
1402         return;
1403     }
1404
1405     len = length - 1;
1406     /* Linear interpolation between start and end. */
1407     for( i = 0; i <= len; ++i )
1408     {
1409         r = ( len - i ) / ( VGfloat )( len );
1410         
1411         lut[ i ] = ( VGubyte )( ( start * r + end * ( 1.0f - r ) ) * 0xFF );
1412     }
1413 }
1414
1415 /*!
1416  *
1417  *
1418  */
1419 void sctOpenVGInitializeLUT32( VGuint* lut, int length, float start[ 4 ], float end[ 4 ] )
1420 {
1421     int     i, len;
1422     float   r;
1423     
1424     SCT_ASSERT_ALWAYS( lut != NULL );
1425     SCT_ASSERT_ALWAYS( length > 0 );
1426
1427     if( length == 1 )
1428     {
1429         lut[ 0 ] = ( VGubyte )( ( start[ 0 ] + end[ 0 ] ) / 2 * 0xFF ) << 24 |
1430             ( VGubyte )( ( start[ 1 ] + end[ 1 ] ) / 2 * 0xFF ) << 16 |
1431             ( VGubyte )( ( start[ 2 ] + end[ 2 ] ) / 2 * 0xFF ) << 8 |
1432             ( VGubyte )( ( start[ 3 ] + end[ 3 ] ) / 2 * 0xFF );
1433         return;
1434     }
1435
1436     len = length - 1;
1437     /* Linear interpolation between start and end. */
1438     for( i = 0; i <= len; ++i )
1439     {
1440         r = ( len - i ) / ( VGfloat )( len );
1441         
1442         lut[ i ] = ( VGubyte )( ( start[ 0 ] * r + end[ 0 ] * ( 1.0f - r ) ) * 0xFF ) << 24 |
1443             ( VGubyte )( ( start[ 1 ] * r + end[ 1 ] * ( 1.0f - r ) ) * 0xFF ) << 16 |
1444             ( VGubyte )( ( start[ 2 ] * r + end[ 2 ] * ( 1.0f - r ) ) * 0xFF ) << 8 |
1445             ( VGubyte )( ( start[ 3 ] * r + end[ 3 ] * ( 1.0f - r ) ) * 0xFF );
1446     }
1447 }
1448
1449 /*!
1450  *
1451  *
1452  */
1453 SCTBoolean sctOpenVGFloatsEqual( VGfloat a, VGfloat b, VGfloat delta )
1454 {
1455     VGfloat dif = a - b;
1456     dif = sctMaxf( dif, -dif );
1457     if( dif > delta  )
1458     {
1459         return SCT_FALSE;
1460     }
1461     return SCT_TRUE;
1462 }
1463
1464 /*!
1465  *
1466  *
1467  */
1468 SCTOpenVGLookupTable* sctOpenVGCreateLookupTable( SCTOpenVGLUTType type )
1469 {
1470     SCTOpenVGLookupTable*   lut;
1471     size_t                  typeSize;
1472
1473     SCT_ASSERT( type == SCT_OPENVG_LUT_UBYTE8 ||
1474                 type == SCT_OPENVG_LUT_UINT32 );
1475
1476     lut = ( SCTOpenVGLookupTable* )( siCommonMemoryAlloc( NULL, sizeof( SCTOpenVGLookupTable ) ) );
1477     if( lut == NULL )
1478     {
1479         return NULL;
1480     }
1481     lut->lookupTable = NULL;
1482     lut->type        = type;
1483
1484     typeSize = type == SCT_OPENVG_LUT_UBYTE8 ? sizeof( VGubyte ) : sizeof( VGuint );
1485     
1486     lut->lookupTable = siCommonMemoryAlloc( NULL, typeSize * 256 );
1487     if( lut->lookupTable == NULL )
1488     {
1489         sctOpenVGDestroyLookupTable( lut );
1490         return NULL;
1491     }
1492     memset( lut->lookupTable, 0, typeSize * 256 );
1493
1494     return lut;
1495 }
1496
1497 /*!
1498  *
1499  *
1500  */
1501 SCTBoolean sctOpenVGSetLookupTableData( SCTOpenVGLookupTable* lut, VGuint values[ 256 ] )
1502 {
1503     int i;
1504
1505     SCT_ASSERT_ALWAYS( lut != NULL );
1506
1507     for( i = 0; i < 256; ++i )
1508     {
1509         if( lut->type == SCT_OPENVG_LUT_UBYTE8 )
1510         {
1511             if( values[ i ] > 0xFF )
1512             {
1513                 return SCT_FALSE;
1514             }
1515             ( ( VGubyte* )( lut->lookupTable ) )[ i ] = ( VGubyte )( values[ i ] );
1516         }
1517         else
1518         {
1519             ( ( VGuint* )( lut->lookupTable ) )[ i ] = ( VGuint )( values[ i ] );
1520         }
1521     }
1522
1523     return SCT_TRUE;
1524 }
1525
1526 /*!
1527  *
1528  *
1529  */
1530 void sctOpenVGDestroyLookupTable( SCTOpenVGLookupTable* lookupTable )
1531 {
1532     if( lookupTable != NULL )
1533     {
1534         if( lookupTable->lookupTable != NULL )
1535         {
1536             siCommonMemoryFree( NULL, lookupTable->lookupTable );
1537             lookupTable->lookupTable = NULL;
1538         }
1539         siCommonMemoryFree( NULL, lookupTable );
1540     }
1541 }