Support YUV decoding for JPEG
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / common / pixel-manipulation.cpp
1 /*
2  * Copyright (c) 2022 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/imaging/common/pixel-manipulation.h>
19
20 // INTERNAL HEADERS
21 #include <dali/integration-api/debug.h>
22 #include <dali/public-api/images/pixel.h>
23
24 namespace Dali
25 {
26 namespace Internal
27 {
28 namespace Adaptor
29 {
30 namespace
31 {
32 // clang-format off
33 /**
34  * @brief Pre-defined offset tables for each Channel.
35  * If invalid channel, return -1. else, return the offset bytes.
36  */
37 //                                                                           | LUMINANCE | RED | GREEN | BLUE | ALPHA | DEPTH | STENCIL |
38 constexpr std::int8_t ALPHA_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]      = {        -1 ,  -1 ,    -1 ,   -1 ,     0 ,    -1 ,      -1 };
39 constexpr std::int8_t LUMINANCE_ONLY_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]  = {         0 ,  -1 ,    -1 ,   -1 ,    -1 ,    -1 ,      -1 };
40 constexpr std::int8_t LUMINANCE_ALPHA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS] = {         0 ,  -1 ,    -1 ,   -1 ,     1 ,    -1 ,      -1 };
41 constexpr std::int8_t RGB_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]             = {        -1 ,   0 ,     1 ,    2 ,    -1 ,    -1 ,      -1 };
42 constexpr std::int8_t BGR_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]             = {        -1 ,   2 ,     1 ,    0 ,    -1 ,    -1 ,      -1 };
43 constexpr std::int8_t RGBA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]            = {        -1 ,   0 ,     1 ,    2 ,     3 ,    -1 ,      -1 };
44 constexpr std::int8_t BGRA_OFFSET_TABLE[MAX_NUMBER_OF_CHANNELS]            = {        -1 ,   2 ,     1 ,    0 ,     3 ,    -1 ,      -1 };
45 // clang-format on
46
47 /**
48  * @brief Template to Read from a buffer with pixel formats that have one byte per channel.
49  *
50  * @tparam NumberOfChannels The number of channels to check
51  * @param pixelData The pixel data to retrieve the value from
52  * @param channel The channel we're after
53  * @param offsetTable The array of offset bytes for each channels in the pixel format
54  * @return The value of the required channel
55  */
56 unsigned int ReadChannelTable(unsigned char* pixelData, Channel channel, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
57 {
58   auto retVal = 0u;
59   if(offsetTable[channel] >= 0)
60   {
61     retVal = static_cast<unsigned int>(*(pixelData + offsetTable[channel]));
62   }
63   return retVal;
64 }
65
66 /**
67  * @brief Template to Write to a buffer with pixel formats that have one byte per channel.
68  *
69  * @tparam NumberOfChannels The number of channels to check
70  * @param pixelData The pixel data to write the value to
71  * @param channel The channel we're after
72  * @param channelValue The value of the channel to set
73  * @param offsetTable The array of offset bytes for each channels in the pixel format
74  */
75 void WriteChannelTable(unsigned char* pixelData, Channel channel, unsigned int channelValue, const std::int8_t (&offsetTable)[MAX_NUMBER_OF_CHANNELS])
76 {
77   if(offsetTable[channel] >= 0)
78   {
79     *(pixelData + offsetTable[channel]) = static_cast<unsigned char>(channelValue & 0xFF);
80   }
81 }
82
83 /**
84  * @brief Reads from buffers with a pixel format of 565.
85  *
86  * @param pixelData The pixel data to read from
87  * @param channel The channel we're after
88  * @param one The first channel of the pixel format
89  * @param two The second channel of the pixel format
90  * @param three The third channel of the pixel format
91  * @return The value of the required channel
92  */
93 unsigned int ReadChannel565(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three)
94 {
95   if(channel == one)
96   {
97     return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
98   }
99   else if(channel == two)
100   {
101     return ((static_cast<unsigned int>(*pixelData) & 0x07) << 3) |
102            ((static_cast<unsigned int>(*(pixelData + 1)) & 0xE0) >> 5);
103   }
104   else if(channel == three)
105   {
106     return static_cast<unsigned int>(*(pixelData + 1)) & 0x1F;
107   }
108   return 0u;
109 }
110
111 /**
112  * @brief Writes to the buffer with a pixel format of 565.
113  *
114  * @param pixelData The pixel data to write to
115  * @param channel The channel we're after
116  * @param channelValue The value to write
117  * @param one The first channel of the pixel format
118  * @param two The second channel of the pixel format
119  * @param three The third channel of the pixel format
120  */
121 void WriteChannel565(unsigned char* pixelData, Channel channel, unsigned int channelValue, Channel one, Channel two, Channel three)
122 {
123   if(channel == one)
124   {
125     *pixelData &= static_cast<unsigned char>(~0xF8);
126     *pixelData |= static_cast<unsigned char>((channelValue << 3) & 0xF8);
127   }
128   else if(channel == two)
129   {
130     *pixelData &= static_cast<unsigned char>(~0x07);
131     *pixelData |= static_cast<unsigned char>((channelValue >> 3) & 0x07);
132
133     *(pixelData + 1) &= static_cast<unsigned char>(~0xE0);
134     *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 5) & 0xE0);
135   }
136   else if(channel == three)
137   {
138     *(pixelData + 1) &= static_cast<unsigned char>(~0x1F);
139     *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x1F);
140   }
141 }
142
143 /**
144  * @brief Reads from buffers with a pixel format of 4444.
145  *
146  * @param pixelData The pixel data to read from
147  * @param channel The channel we're after
148  * @param one The first channel of the pixel format
149  * @param two The second channel of the pixel format
150  * @param three The third channel of the pixel format
151  * @param four The fourth channel of the pixel format
152  * @return
153  */
154 unsigned int ReadChannel4444(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three, Channel four)
155 {
156   if(channel == one)
157   {
158     return (static_cast<unsigned int>(*pixelData) & 0xF0) >> 4;
159   }
160   else if(channel == two)
161   {
162     return (static_cast<unsigned int>(*pixelData) & 0x0F);
163   }
164   else if(channel == three)
165   {
166     return (static_cast<unsigned int>(*(pixelData + 1)) & 0xF0) >> 4;
167   }
168   else if(channel == four)
169   {
170     return (static_cast<unsigned int>(*(pixelData + 1)) & 0x0F);
171   }
172   return 0u;
173 }
174
175 /**
176  * @brief Writes to the buffer with a pixel format of 565.
177  *
178  * @param pixelData The pixel data to write to
179  * @param channel The channel we're after
180  * @param channelValue The value to write
181  * @param one The first channel of the pixel format
182  * @param two The second channel of the pixel format
183  * @param three The third channel of the pixel format
184  * @param four The fourth channel of the pixel format
185  */
186 void WriteChannel4444(unsigned char* pixelData, Channel channel, unsigned int channelValue, Channel one, Channel two, Channel three, Channel four)
187 {
188   if(channel == one)
189   {
190     *pixelData &= static_cast<unsigned char>(~0xF0);
191     *pixelData |= static_cast<unsigned char>((channelValue << 4) & 0xF0);
192   }
193   else if(channel == two)
194   {
195     *pixelData &= static_cast<unsigned char>(~0x0F);
196     *pixelData |= static_cast<unsigned char>(channelValue & 0x0F);
197   }
198   else if(channel == three)
199   {
200     *(pixelData + 1) &= static_cast<unsigned char>(~0xF0);
201     *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 4) & 0xF0);
202   }
203   else if(channel == four)
204   {
205     *(pixelData + 1) &= static_cast<unsigned char>(~0x0F);
206     *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x0F);
207   }
208 }
209
210 /**
211  * @brief Reads from buffers with a pixel format of 5551.
212  *
213  * @param pixelData The pixel data to read from
214  * @param channel The channel we're after
215  * @param one The first channel of the pixel format
216  * @param two The second channel of the pixel format
217  * @param three The third channel of the pixel format
218  * @param four The fourth channel of the pixel format
219  * @return
220  */
221 unsigned int ReadChannel5551(unsigned char* pixelData, Channel channel, Channel one, Channel two, Channel three, Channel four)
222 {
223   if(channel == one)
224   {
225     return (static_cast<unsigned int>(*pixelData) & 0xF8) >> 3;
226   }
227   else if(channel == two)
228   {
229     return ((static_cast<unsigned int>(*pixelData) & 0x07) << 2) |
230            ((static_cast<unsigned int>(*(pixelData + 1)) & 0xC0) >> 6);
231   }
232   else if(channel == three)
233   {
234     return (static_cast<unsigned int>(*(pixelData + 1)) & 0x3E) >> 1;
235   }
236   else if(channel == four)
237   {
238     return static_cast<unsigned int>(*(pixelData + 1)) & 0x01;
239   }
240   return 0u;
241 }
242
243 /**
244  * @brief Writes to the buffer with a pixel format of 5551.
245  *
246  * @param pixelData The pixel data to write to
247  * @param channel The channel we're after
248  * @param channelValue The value to write
249  * @param one The first channel of the pixel format
250  * @param two The second channel of the pixel format
251  * @param three The third channel of the pixel format
252  * @param four The fourth channel of the pixel format
253  */
254 void WriteChannel5551(unsigned char* pixelData, Channel channel, unsigned int channelValue, Channel one, Channel two, Channel three, Channel four)
255 {
256   // 11111222 22333334
257   //    F8  7 C0  3E 1
258   if(channel == one)
259   {
260     *pixelData &= static_cast<unsigned char>(~0xF8);
261     *pixelData |= static_cast<unsigned char>((channelValue << 3) & 0xF8);
262   }
263   else if(channel == two)
264   {
265     *pixelData &= static_cast<unsigned char>(~0x07);
266     *pixelData |= static_cast<unsigned char>((channelValue >> 2) & 0x07);
267
268     *(pixelData + 1) &= static_cast<unsigned char>(~0xC0);
269     *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 6) & 0xC0);
270   }
271   else if(channel == three)
272   {
273     *(pixelData + 1) &= static_cast<unsigned char>(~0x3E);
274     *(pixelData + 1) |= static_cast<unsigned char>((channelValue << 1) & 0x3E);
275   }
276   else if(channel == four)
277   {
278     *(pixelData + 1) &= static_cast<unsigned char>(~0x01);
279     *(pixelData + 1) |= static_cast<unsigned char>(channelValue & 0x01);
280   }
281 }
282
283 } // unnamed namespace
284
285 struct Location
286 {
287   unsigned int bitShift;
288   unsigned int bitMask;
289   bool         available;
290 };
291
292 struct Locations
293 {
294   Location luminance;
295   Location alpha;
296   Location red;
297   Location green;
298   Location blue;
299 };
300
301 bool HasChannel(Dali::Pixel::Format pixelFormat, Channel channel)
302 {
303   switch(pixelFormat)
304   {
305     case Dali::Pixel::A8:
306     {
307       return (channel == ALPHA);
308     }
309     case Dali::Pixel::L8:
310     {
311       return (channel == LUMINANCE);
312     }
313     case Dali::Pixel::LA88:
314     {
315       return (channel == LUMINANCE || channel == ALPHA);
316     }
317     case Dali::Pixel::RGB565:
318     case Dali::Pixel::BGR565:
319     case Dali::Pixel::RGB888:
320     case Dali::Pixel::RGB8888:
321     case Dali::Pixel::BGR8888:
322     case Dali::Pixel::RGB16F:
323     case Dali::Pixel::RGB32F:
324     case Dali::Pixel::R11G11B10F:
325     {
326       return (channel == RED || channel == GREEN || channel == BLUE);
327     }
328
329     case Dali::Pixel::RGBA8888:
330     case Dali::Pixel::BGRA8888:
331     case Dali::Pixel::RGBA4444:
332     case Dali::Pixel::BGRA4444:
333     case Dali::Pixel::RGBA5551:
334     case Dali::Pixel::BGRA5551:
335     {
336       return (channel == RED || channel == GREEN || channel == BLUE || channel == ALPHA);
337     }
338
339     case Dali::Pixel::DEPTH_UNSIGNED_INT:
340     case Dali::Pixel::DEPTH_FLOAT:
341     {
342       return (channel == DEPTH);
343     }
344
345     case Dali::Pixel::DEPTH_STENCIL:
346     {
347       return (channel == DEPTH || channel == STENCIL);
348     }
349
350     case Dali::Pixel::INVALID:
351     case Dali::Pixel::COMPRESSED_R11_EAC:
352     case Dali::Pixel::COMPRESSED_SIGNED_R11_EAC:
353     case Dali::Pixel::COMPRESSED_RG11_EAC:
354     case Dali::Pixel::COMPRESSED_SIGNED_RG11_EAC:
355     case Dali::Pixel::COMPRESSED_RGB8_ETC2:
356     case Dali::Pixel::COMPRESSED_SRGB8_ETC2:
357     case Dali::Pixel::COMPRESSED_RGB8_ETC1:
358     case Dali::Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
359     case Dali::Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
360     case Dali::Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
361     case Dali::Pixel::COMPRESSED_RGBA8_ETC2_EAC:
362     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
363     case Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
364     case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
365     case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
366     case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
367     case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
368     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
369     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
370     case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
371     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
372     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
373     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
374     case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
375     case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
376     case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
377     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
378     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
379     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
380     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
381     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
382     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
383     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
384     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
385     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
386     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
387     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
388     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
389     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
390     case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
391     {
392       DALI_LOG_ERROR("Pixel formats for compressed images are not compatible with simple channels.\n");
393       break;
394     }
395
396     case Dali::Pixel::CHROMINANCE_U:
397     case Dali::Pixel::CHROMINANCE_V:
398     {
399       DALI_LOG_ERROR("Pixel formats for chrominance are not compatible with simple channels.\n");
400       break;
401     }
402   }
403
404   return false;
405 }
406
407 unsigned int ReadChannel(unsigned char*      pixelData,
408                          Dali::Pixel::Format pixelFormat,
409                          Channel             channel)
410 {
411   switch(pixelFormat)
412   {
413     case Dali::Pixel::A8:
414     {
415       return ReadChannelTable(pixelData, channel, ALPHA_ONLY_OFFSET_TABLE);
416     }
417     case Dali::Pixel::L8:
418     {
419       return ReadChannelTable(pixelData, channel, LUMINANCE_ONLY_OFFSET_TABLE);
420     }
421     case Dali::Pixel::LA88:
422     {
423       return ReadChannelTable(pixelData, channel, LUMINANCE_ALPHA_OFFSET_TABLE);
424     }
425     case Dali::Pixel::RGB565:
426     {
427       return ReadChannel565(pixelData, channel, RED, GREEN, BLUE);
428     }
429
430     case Dali::Pixel::BGR565:
431     {
432       return ReadChannel565(pixelData, channel, BLUE, GREEN, RED);
433     }
434
435     case Dali::Pixel::RGB888:
436     case Dali::Pixel::RGB8888:
437     {
438       return ReadChannelTable(pixelData, channel, RGB_OFFSET_TABLE);
439     }
440
441     case Dali::Pixel::BGR8888:
442     {
443       return ReadChannelTable(pixelData, channel, BGR_OFFSET_TABLE);
444     }
445
446     case Dali::Pixel::RGBA8888:
447     {
448       return ReadChannelTable(pixelData, channel, RGBA_OFFSET_TABLE);
449     }
450
451     case Dali::Pixel::BGRA8888:
452     {
453       return ReadChannelTable(pixelData, channel, BGRA_OFFSET_TABLE);
454     }
455
456     case Dali::Pixel::RGBA4444:
457     {
458       return ReadChannel4444(pixelData, channel, RED, GREEN, BLUE, ALPHA);
459     }
460
461     case Dali::Pixel::BGRA4444:
462     {
463       return ReadChannel4444(pixelData, channel, BLUE, GREEN, RED, ALPHA);
464     }
465
466     case Dali::Pixel::RGBA5551:
467     {
468       return ReadChannel5551(pixelData, channel, RED, GREEN, BLUE, ALPHA);
469     }
470
471     case Dali::Pixel::BGRA5551:
472     {
473       return ReadChannel5551(pixelData, channel, BLUE, GREEN, RED, ALPHA);
474     }
475
476     case Dali::Pixel::DEPTH_UNSIGNED_INT:
477     case Dali::Pixel::DEPTH_FLOAT:
478     case Dali::Pixel::DEPTH_STENCIL:
479     {
480       return 0u;
481     }
482
483     default:
484     {
485       return 0u;
486     }
487   }
488 }
489
490 void WriteChannel(unsigned char*      pixelData,
491                   Dali::Pixel::Format pixelFormat,
492                   Channel             channel,
493                   unsigned int        channelValue)
494 {
495   switch(pixelFormat)
496   {
497     case Dali::Pixel::A8:
498     {
499       WriteChannelTable(pixelData, channel, channelValue, ALPHA_ONLY_OFFSET_TABLE);
500       break;
501     }
502     case Dali::Pixel::L8:
503     {
504       WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ONLY_OFFSET_TABLE);
505       break;
506     }
507     case Dali::Pixel::LA88:
508     {
509       WriteChannelTable(pixelData, channel, channelValue, LUMINANCE_ALPHA_OFFSET_TABLE);
510       break;
511     }
512     case Dali::Pixel::RGB565:
513     {
514       WriteChannel565(pixelData, channel, channelValue, RED, GREEN, BLUE);
515       break;
516     }
517
518     case Dali::Pixel::BGR565:
519     {
520       WriteChannel565(pixelData, channel, channelValue, BLUE, GREEN, RED);
521       break;
522     }
523
524     case Dali::Pixel::RGB888:
525     case Dali::Pixel::RGB8888:
526     {
527       WriteChannelTable(pixelData, channel, channelValue, RGB_OFFSET_TABLE);
528       break;
529     }
530
531     case Dali::Pixel::BGR8888:
532     {
533       WriteChannelTable(pixelData, channel, channelValue, BGR_OFFSET_TABLE);
534       break;
535     }
536
537     case Dali::Pixel::RGBA8888:
538     {
539       WriteChannelTable(pixelData, channel, channelValue, RGBA_OFFSET_TABLE);
540       break;
541     }
542
543     case Dali::Pixel::BGRA8888:
544     {
545       WriteChannelTable(pixelData, channel, channelValue, BGRA_OFFSET_TABLE);
546       break;
547     }
548
549     case Dali::Pixel::RGBA4444:
550     {
551       WriteChannel4444(pixelData, channel, channelValue, RED, GREEN, BLUE, ALPHA);
552       break;
553     }
554
555     case Dali::Pixel::BGRA4444:
556     {
557       WriteChannel4444(pixelData, channel, channelValue, BLUE, GREEN, RED, ALPHA);
558       break;
559     }
560
561     case Dali::Pixel::RGBA5551:
562     {
563       WriteChannel5551(pixelData, channel, channelValue, RED, GREEN, BLUE, ALPHA);
564       break;
565     }
566
567     case Dali::Pixel::BGRA5551:
568     {
569       WriteChannel5551(pixelData, channel, channelValue, BLUE, GREEN, RED, ALPHA);
570       break;
571     }
572
573     case Dali::Pixel::DEPTH_UNSIGNED_INT:
574     case Dali::Pixel::DEPTH_FLOAT:
575     case Dali::Pixel::DEPTH_STENCIL:
576     {
577       break;
578     }
579
580     default:
581       break;
582   }
583 }
584
585 void ConvertColorChannelsToRGBA8888(
586   unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat, unsigned char* destPixel, int destOffset)
587 {
588   int red   = ReadChannel(srcPixel + srcOffset, srcFormat, RED);
589   int green = ReadChannel(srcPixel + srcOffset, srcFormat, GREEN);
590   int blue  = ReadChannel(srcPixel + srcOffset, srcFormat, BLUE);
591   switch(srcFormat)
592   {
593     case Dali::Pixel::RGB565:
594     case Dali::Pixel::BGR565:
595     {
596       red   = (red << 3) | (red & 0x07);
597       green = (green << 2) | (green & 0x03);
598       blue  = (blue << 3) | (blue & 0x07);
599       break;
600     }
601     case Dali::Pixel::RGBA4444:
602     case Dali::Pixel::BGRA4444:
603     {
604       red   = (red << 4) | (red & 0x0F);
605       green = (green << 4) | (green & 0x0F);
606       blue  = (blue << 4) | (blue & 0x0F);
607       break;
608     }
609     case Dali::Pixel::RGBA5551:
610     case Dali::Pixel::BGRA5551:
611     {
612       red   = (red << 3) | (red & 0x07);
613       green = (green << 3) | (green & 0x07);
614       blue  = (blue << 3) | (blue & 0x07);
615       break;
616     }
617     default:
618       break;
619   }
620   WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, RED, red);
621   WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, GREEN, green);
622   WriteChannel(destPixel + destOffset, Dali::Pixel::RGBA8888, BLUE, blue);
623 }
624
625 int ConvertAlphaChannelToA8(unsigned char* srcPixel, int srcOffset, Dali::Pixel::Format srcFormat)
626 {
627   int alpha     = ReadChannel(srcPixel + srcOffset, srcFormat, ALPHA);
628   int destAlpha = alpha;
629   switch(srcFormat)
630   {
631     case Pixel::RGBA5551:
632     case Pixel::BGRA5551:
633     {
634       destAlpha = (alpha == 0) ? 0 : 255;
635       break;
636     }
637     case Pixel::RGBA4444:
638     case Pixel::BGRA4444:
639     {
640       destAlpha = (alpha << 4) | (alpha & 0x0F);
641       break;
642     }
643     default:
644       break;
645   }
646   return destAlpha;
647 }
648
649 } // namespace Adaptor
650 } // namespace Internal
651 } // namespace Dali