Removed forward declaration of (removed) FrameBufferTexture
[platform/core/uifw/dali-core.git] / dali / internal / event / images / pixel-manipulation.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include <dali/internal/event/images/pixel-manipulation.h>
19
20 // INTERNAL HEADERS
21 #include <dali/public-api/images/pixel.h>
22 #include <dali/integration-api/debug.h>
23
24 namespace Dali
25 {
26
27 namespace Internal
28 {
29
30 namespace Pixel
31 {
32
33 struct Location
34 {
35   unsigned int bitShift;
36   unsigned int bitMask;
37   bool available;
38 };
39
40 struct Locations
41 {
42   Location luminance;
43   Location alpha;
44   Location red;
45   Location green;
46   Location blue;
47 };
48
49
50 bool HasChannel( Dali::Pixel::Format pixelFormat, Channel channel )
51 {
52   switch (pixelFormat)
53   {
54     case Dali::Pixel::A8:
55     {
56       return (channel == ALPHA);
57     }
58     case Dali::Pixel::L8:
59     {
60       return (channel == LUMINANCE);
61     }
62     case Dali::Pixel::LA88:
63     {
64       return ( channel == LUMINANCE || channel == ALPHA );
65     }
66     case Dali::Pixel::RGB565:
67     case Dali::Pixel::BGR565:
68     case Dali::Pixel::RGB888:
69     case Dali::Pixel::RGB8888:
70     case Dali::Pixel::BGR8888:
71     {
72       return ( channel == RED || channel == GREEN || channel == BLUE );
73     }
74
75     case Dali::Pixel::RGBA8888:
76     case Dali::Pixel::BGRA8888:
77     case Dali::Pixel::RGBA4444:
78     case Dali::Pixel::BGRA4444:
79     case Dali::Pixel::RGBA5551:
80     case Dali::Pixel::BGRA5551:
81     {
82       return ( channel == RED || channel == GREEN || channel == BLUE || channel == ALPHA );
83     }
84
85     case Dali::Pixel::INVALID:
86     case Dali::Pixel::COMPRESSED_R11_EAC:
87     case Dali::Pixel::COMPRESSED_SIGNED_R11_EAC:
88     case Dali::Pixel::COMPRESSED_RG11_EAC:
89     case Dali::Pixel::COMPRESSED_SIGNED_RG11_EAC:
90     case Dali::Pixel::COMPRESSED_RGB8_ETC2:
91     case Dali::Pixel::COMPRESSED_SRGB8_ETC2:
92     case Dali::Pixel::COMPRESSED_RGB8_ETC1:
93     case Dali::Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
94     case Dali::Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
95     case Dali::Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
96     case Dali::Pixel::COMPRESSED_RGBA8_ETC2_EAC:
97     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
98     case Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
99     case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
100     case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
101     case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
102     case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
103     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
104     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
105     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
106     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
107     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
108     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
109     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
110     case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
111     case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
112     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
113     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
114     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
115     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
116     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
117     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
118     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
119     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
120     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
121     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
122     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
123     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
124     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
125     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
126     {
127       DALI_LOG_ERROR("Pixel formats for compressed images are not compatible with simple channels.\n");
128       break;
129     }
130   }
131
132   return false;
133 }
134
135 unsigned int ReadChannel( unsigned char* pixelData,
136                           Dali::Pixel::Format pixelFormat,
137                           Channel channel )
138 {
139   switch (pixelFormat)
140   {
141     case Dali::Pixel::A8:
142     {
143       if( channel == ALPHA )
144       {
145         return static_cast<unsigned int>(*pixelData);
146       }
147       else return 0u;
148     }
149     case Dali::Pixel::L8:
150     {
151       if( channel == LUMINANCE )
152       {
153         return static_cast<unsigned int>(*pixelData);
154       }
155       else return 0u;
156     }
157     case Dali::Pixel::LA88:
158     {
159       if( channel == LUMINANCE )
160       {
161         return static_cast<unsigned int>(*pixelData);
162       }
163       else if( channel == ALPHA )
164       {
165         return static_cast<unsigned int>(*(pixelData+1));
166       }
167       else return 0u;
168     }
169     case Dali::Pixel::RGB565:
170     {
171       if( channel == RED )
172       {
173         return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
174       }
175       else if( channel == GREEN )
176       {
177         return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
178           ((static_cast<unsigned int>(*(pixelData+1)) & 0xE0) >> 5);
179       }
180       else if( channel == BLUE )
181       {
182         return static_cast<unsigned int>(*(pixelData+1)) & 0x1F;
183       }
184       else return 0u;
185     }
186
187     case Dali::Pixel::BGR565:
188     {
189       if( channel == BLUE )
190       {
191         return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
192       }
193       else if( channel == GREEN )
194       {
195         return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
196           ((static_cast<unsigned int>(*(pixelData+1)) & 0xE0) >> 5);
197       }
198       else if( channel == RED )
199       {
200         return (static_cast<unsigned int>(*(pixelData+1) & 0x1F) );
201       }
202       else return 0u;
203     }
204
205     case Dali::Pixel::RGB888:
206     case Dali::Pixel::RGB8888:
207     {
208       if( channel == RED )
209       {
210         return static_cast<unsigned int>(*pixelData);
211       }
212       else if( channel == GREEN )
213       {
214         return static_cast<unsigned int>(*(pixelData+1));
215       }
216       else if( channel == BLUE )
217       {
218         return static_cast<unsigned int>(*(pixelData+2));
219       }
220       else return 0u;
221     }
222
223     case Dali::Pixel::BGR8888:
224     {
225       if( channel == BLUE )
226       {
227         return static_cast<unsigned int>(*pixelData);
228       }
229       else if( channel == GREEN )
230       {
231         return static_cast<unsigned int>(*(pixelData+1));
232       }
233       else if( channel == RED )
234       {
235         return static_cast<unsigned int>(*(pixelData+2));
236       }
237       else return 0u;
238     }
239
240     case Dali::Pixel::RGBA8888:
241     {
242       if( channel == RED )
243       {
244         return static_cast<unsigned int>(*pixelData);
245       }
246       else if( channel == GREEN )
247       {
248         return static_cast<unsigned int>(*(pixelData+1));
249       }
250       else if( channel == BLUE )
251       {
252         return static_cast<unsigned int>(*(pixelData+2));
253       }
254       else if( channel == ALPHA )
255       {
256         return static_cast<unsigned int>(*(pixelData+3));
257       }
258       else return 0u;
259     }
260
261     case Dali::Pixel::BGRA8888:
262     {
263       if( channel == BLUE )
264       {
265         return static_cast<unsigned int>(*pixelData);
266       }
267       else if( channel == GREEN )
268       {
269         return static_cast<unsigned int>(*(pixelData+1));
270       }
271       else if( channel == RED )
272       {
273         return static_cast<unsigned int>(*(pixelData+2));
274       }
275       else if( channel == ALPHA )
276       {
277         return static_cast<unsigned int>(*(pixelData+3));
278       }
279       else return 0u;
280     }
281
282     case Dali::Pixel::RGBA4444:
283     {
284       if( channel == RED )
285       {
286         return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
287       }
288       else if( channel == GREEN )
289       {
290         return (static_cast<unsigned int>(*pixelData) & 0x0F);
291       }
292       else if( channel == BLUE )
293       {
294         return (static_cast<unsigned int>(*(pixelData+1)) & 0xF0) >> 4;
295       }
296       else if( channel == ALPHA )
297       {
298         return (static_cast<unsigned int>(*(pixelData+1)) & 0x0F);
299       }
300       else return 0u;
301     }
302
303     case Dali::Pixel::BGRA4444:
304     {
305       if( channel == BLUE )
306       {
307         return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
308       }
309       else if( channel == GREEN )
310       {
311         return (static_cast<unsigned int>(*pixelData) & 0x0F);
312       }
313       else if( channel == RED )
314       {
315         return (static_cast<unsigned int>(*(pixelData+1)) & 0xF0) >> 4;
316       }
317       else if( channel == ALPHA )
318       {
319         return (static_cast<unsigned int>(*(pixelData+1)) & 0x0F);
320       }
321       else return 0u;
322     }
323
324     case Dali::Pixel::RGBA5551:
325     {
326       if( channel == RED )
327       {
328         return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
329       }
330       else if( channel == GREEN )
331       {
332         return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
333           ((static_cast<unsigned int>(*(pixelData+1)) & 0xC0) >> 6);
334       }
335       else if( channel == BLUE )
336       {
337         return (static_cast<unsigned int>(*(pixelData+1)) & 0x3E) >> 1;
338       }
339       else if( channel == ALPHA )
340       {
341         return static_cast<unsigned int>(*(pixelData+1)) & 0x01;
342       }
343
344       else return 0u;
345     }
346
347     case Dali::Pixel::BGRA5551:
348     {
349       if( channel == BLUE )
350       {
351         return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
352       }
353       else if( channel == GREEN )
354       {
355         return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
356           ((static_cast<unsigned int>(*(pixelData+1)) & 0xC0) >> 6);
357       }
358       else if( channel == RED )
359       {
360         return ( static_cast<unsigned int>(*(pixelData+1)) & 0x3E) >> 1;
361       }
362       else if( channel == ALPHA )
363       {
364         return static_cast<unsigned int>(*(pixelData+1)) & 0x01;
365       }
366
367       else return 0u;
368     }
369
370     default:
371     {
372       return 0u;
373     }
374   }
375 }
376
377 void WriteChannel( unsigned char* pixelData,
378                    Dali::Pixel::Format pixelFormat,
379                    Channel channel,
380                    unsigned int channelValue )
381 {
382   switch (pixelFormat)
383   {
384     case Dali::Pixel::A8:
385     {
386       if( channel == ALPHA )
387       {
388         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
389       }
390       break;
391     }
392     case Dali::Pixel::L8:
393     {
394       if( channel == LUMINANCE )
395       {
396         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
397       }
398       break;
399     }
400     case Dali::Pixel::LA88:
401     {
402       if( channel == LUMINANCE )
403       {
404         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
405       }
406       else if( channel == ALPHA )
407       {
408         *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
409       }
410       break;
411     }
412     case Dali::Pixel::RGB565:
413     {
414       if( channel == RED )
415       {
416         *pixelData &= ~0xF8;
417         *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
418       }
419       else if( channel == GREEN )
420       {
421         *pixelData &= ~0x07;
422         *pixelData |= static_cast<unsigned char>( (channelValue >> 3) & 0x07 );
423
424         *(pixelData+1) &= ~0xE0;
425         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 5) & 0xE0 );
426       }
427       else if( channel == BLUE )
428       {
429         *(pixelData+1) &= ~0x1F;
430         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x1F );
431       }
432       break;
433     }
434
435     case Dali::Pixel::BGR565:
436     {
437       if( channel == BLUE )
438       {
439         *pixelData &= ~0xF8;
440         *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
441       }
442       else if( channel == GREEN )
443       {
444         *pixelData &= ~0x07;
445         *pixelData |= static_cast<unsigned char>( (channelValue >> 3) & 0x07 );
446
447         *(pixelData+1) &= ~0xE0;
448         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 5) & 0xE0 );
449       }
450       else if( channel == RED )
451       {
452         *(pixelData+1) &= ~0x1F;
453         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x1F );
454       }
455       break;
456     }
457
458     case Dali::Pixel::RGB888:
459     case Dali::Pixel::RGB8888:
460     {
461       if( channel == RED )
462       {
463         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
464       }
465       else if( channel == GREEN )
466       {
467         *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
468       }
469       else if( channel == BLUE )
470       {
471         *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
472       }
473       break;
474     }
475
476     case Dali::Pixel::BGR8888:
477     {
478       if( channel == BLUE )
479       {
480         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
481       }
482       else if( channel == GREEN )
483       {
484         *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
485       }
486       else if( channel == RED )
487       {
488         *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
489       }
490       break;
491     }
492
493     case Dali::Pixel::RGBA8888:
494     {
495       if( channel == RED )
496       {
497         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
498       }
499       else if( channel == GREEN )
500       {
501         *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
502       }
503       else if( channel == BLUE )
504       {
505         *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
506       }
507       else if( channel == ALPHA )
508       {
509         *(pixelData+3) = static_cast<unsigned char>( channelValue & 0xFF );
510       }
511       break;
512     }
513
514     case Dali::Pixel::BGRA8888:
515     {
516       if( channel == BLUE )
517       {
518         *pixelData = static_cast<unsigned char>( channelValue & 0xFF );
519       }
520       else if( channel == GREEN )
521       {
522         *(pixelData+1) = static_cast<unsigned char>( channelValue & 0xFF );
523       }
524       else if( channel == RED )
525       {
526         *(pixelData+2) = static_cast<unsigned char>( channelValue & 0xFF );
527       }
528       else if( channel == ALPHA )
529       {
530         *(pixelData+3) = static_cast<unsigned char>( channelValue & 0xFF );
531       }
532       break;
533     }
534
535     case Dali::Pixel::RGBA4444:
536     {
537       if( channel == RED )
538       {
539         *pixelData &= ~0xF0;
540         *pixelData |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
541       }
542       else if( channel == GREEN )
543       {
544         *pixelData &= ~0x0F;
545         *pixelData |= static_cast<unsigned char>( channelValue & 0x0F );
546       }
547       else if( channel == BLUE )
548       {
549         *(pixelData+1) &= ~0xF0;
550         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
551       }
552       else if( channel == ALPHA )
553       {
554         *(pixelData+1) &= ~0x0F;
555         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x0F );
556       }
557       break;
558     }
559
560     case Dali::Pixel::BGRA4444:
561     {
562       if( channel == BLUE )
563       {
564         *pixelData &= ~0xF0;
565         *pixelData |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
566       }
567       else if( channel == GREEN )
568       {
569         *pixelData &= ~0x0F;
570         *pixelData |= static_cast<unsigned char>( channelValue & 0x0F );
571       }
572       else if( channel == RED )
573       {
574         *(pixelData+1) &= ~0xF0;
575         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 4) & 0xF0 );
576       }
577       else if( channel == ALPHA )
578       {
579         *(pixelData+1) &= ~0x0F;
580         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x0F );
581       }
582       break;
583     }
584
585     case Dali::Pixel::RGBA5551:
586     {
587       // rrrrrggg ggbbbbba
588       //    F8  7 C0  3E 1
589       if( channel == RED )
590       {
591         *pixelData &= ~0xF8;
592         *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
593       }
594       else if( channel == GREEN )
595       {
596         *pixelData &= ~0x07;
597         *pixelData |= static_cast<unsigned char>( (channelValue >> 2) & 0x07 );
598
599         *(pixelData+1) &= ~0xC0;
600         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 6) & 0xC0 );
601       }
602       else if( channel == BLUE )
603       {
604         *(pixelData+1) &= ~0x3E;
605         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 1) & 0x3E );
606       }
607       else if( channel == ALPHA )
608       {
609         *(pixelData+1) &= ~0x01;
610         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x01 );
611       }
612       break;
613     }
614
615     case Dali::Pixel::BGRA5551:
616     {
617       if( channel == BLUE )
618       {
619         *pixelData &= ~0xF8;
620         *pixelData |= static_cast<unsigned char>( (channelValue << 3) & 0xF8 );
621       }
622       else if( channel == GREEN )
623       {
624         *pixelData &= ~0x07;
625         *pixelData |= static_cast<unsigned char>( (channelValue >> 2) & 0x07 );
626
627         *(pixelData+1) &= ~0xC0;
628         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 6) & 0xC0 );
629       }
630       else if( channel == RED )
631       {
632         *(pixelData+1) &= ~0x3E;
633         *(pixelData+1) |= static_cast<unsigned char>( (channelValue << 1 ) & 0x3E );
634       }
635       else if( channel == ALPHA )
636       {
637         *(pixelData+1) &= ~0x01;
638         *(pixelData+1) |= static_cast<unsigned char>( channelValue & 0x01 );
639       }
640       break;
641     }
642
643     default:
644       break;
645   }
646 }
647
648 void ConvertColorChannelsToRGBA8888(
649   unsigned char* srcPixel,  int srcOffset,  Dali::Pixel::Format srcFormat,
650   unsigned char* destPixel, int destOffset )
651 {
652   int red   = ReadChannel(srcPixel+srcOffset, srcFormat, RED );
653   int green = ReadChannel(srcPixel+srcOffset, srcFormat, GREEN );
654   int blue  = ReadChannel(srcPixel+srcOffset, srcFormat, BLUE );
655   switch( srcFormat )
656   {
657     case Dali::Pixel::RGB565:
658     case Dali::Pixel::BGR565:
659     {
660       red<<=3;
661       green<<=2;
662       blue<<=3;
663       break;
664     }
665     case Dali::Pixel::RGBA4444:
666     case Dali::Pixel::BGRA4444:
667     {
668       red<<=4;
669       green<<=4;
670       blue<<=4;
671       break;
672     }
673     case Dali::Pixel::RGBA5551:
674     case Dali::Pixel::BGRA5551:
675     {
676       red<<=3;
677       green<<=3;
678       blue<<=3;
679       break;
680     }
681     default:
682       break;
683   }
684   WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, RED, red);
685   WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, GREEN, green);
686   WriteChannel(destPixel+destOffset, Dali::Pixel::RGBA8888, BLUE, blue);
687 }
688
689
690
691 } // Pixel
692 } // Internal
693 } // Dali