Updated all code to new format
[platform/core/uifw/dali-adaptor.git] / dali / internal / imaging / common / alpha-mask.cpp
1 /*
2  * Copyright (c) 2021 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 #include <dali/internal/imaging/common/alpha-mask.h>
18 #include <dali/internal/imaging/common/image-operations.h>
19 #include <dali/internal/imaging/common/pixel-buffer-impl.h>
20 #include <dali/internal/imaging/common/pixel-manipulation.h>
21 #include <dali/public-api/images/image-operations.h> // For ImageDimensions
22
23 namespace Dali
24 {
25 namespace Internal
26 {
27 namespace Adaptor
28 {
29 void ApplyMaskToAlphaChannel(PixelBuffer& buffer, const PixelBuffer& mask)
30 {
31   int                 srcAlphaByteOffset = 0;
32   int                 srcAlphaMask       = 0;
33   Dali::Pixel::Format srcPixelFormat     = mask.GetPixelFormat();
34
35   if(Pixel::HasAlpha(srcPixelFormat))
36   {
37     Dali::Pixel::GetAlphaOffsetAndMask(srcPixelFormat, srcAlphaByteOffset, srcAlphaMask);
38   }
39   else if(srcPixelFormat == Pixel::L8)
40   {
41     srcAlphaMask = 0xFF;
42   }
43
44   int                 destAlphaByteOffset = 0;
45   int                 destAlphaMask       = 0;
46   Dali::Pixel::Format destPixelFormat     = buffer.GetPixelFormat();
47   Dali::Pixel::GetAlphaOffsetAndMask(destPixelFormat, destAlphaByteOffset, destAlphaMask);
48
49   unsigned int   srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel(srcPixelFormat);
50   unsigned char* srcBuffer        = mask.GetBuffer();
51   unsigned char* destBuffer       = buffer.GetBuffer();
52
53   unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel(buffer.GetPixelFormat());
54
55   int srcOffset  = 0;
56   int destOffset = 0;
57
58   float srcAlphaValue = 1.0f;
59
60   // if image is premultiplied, the other channels of the image need to multiply by alpha.
61   if(buffer.IsAlphaPreMultiplied())
62   {
63     for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
64     {
65       for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
66       {
67         auto srcAlpha      = ReadChannel(srcBuffer + srcOffset, srcPixelFormat, Adaptor::ALPHA);
68         auto destRed       = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::RED);
69         auto destGreen     = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::GREEN);
70         auto destBlue      = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::BLUE);
71         auto destLuminance = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE);
72         auto destAlpha     = ReadChannel(destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA);
73
74         WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::RED, destRed * srcAlpha / 255);
75         WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::GREEN, destGreen * srcAlpha / 255);
76         WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::BLUE, destBlue * srcAlpha / 255);
77         WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::LUMINANCE, destLuminance * srcAlpha / 255);
78         WriteChannel(destBuffer + destOffset, destPixelFormat, Adaptor::ALPHA, destAlpha * srcAlpha / 255);
79
80         srcOffset += srcBytesPerPixel;
81         destOffset += destBytesPerPixel;
82       }
83     }
84   }
85   else
86   {
87     for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
88     {
89       for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
90       {
91         unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
92         srcAlphaValue       = float(alpha) / 255.0f;
93
94         unsigned char destAlpha      = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
95         float         destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
96         destAlpha                    = destAlphaValue;
97         destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
98         destBuffer[destOffset + destAlphaByteOffset] |= (destAlpha & destAlphaMask);
99
100         srcOffset += srcBytesPerPixel;
101         destOffset += destBytesPerPixel;
102       }
103     }
104   }
105 }
106
107 PixelBufferPtr CreateNewMaskedBuffer(const PixelBuffer& buffer, const PixelBuffer& mask)
108 {
109   // Set up source alpha offsets
110   int                 srcAlphaByteOffset = 0;
111   int                 srcAlphaMask       = 0;
112   Dali::Pixel::Format srcPixelFormat     = mask.GetPixelFormat();
113
114   if(Pixel::HasAlpha(srcPixelFormat))
115   {
116     Dali::Pixel::GetAlphaOffsetAndMask(srcPixelFormat, srcAlphaByteOffset, srcAlphaMask);
117   }
118   else if(srcPixelFormat == Pixel::L8)
119   {
120     srcAlphaMask = 0xFF;
121   }
122
123   unsigned int   srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel(srcPixelFormat);
124   unsigned char* srcBuffer        = mask.GetBuffer();
125
126   // Set up source color offsets
127   Dali::Pixel::Format srcColorPixelFormat   = buffer.GetPixelFormat();
128   unsigned int        srcColorBytesPerPixel = Dali::Pixel::GetBytesPerPixel(srcColorPixelFormat);
129
130   // Setup destination offsets
131   Dali::Pixel::Format destPixelFormat     = Dali::Pixel::RGBA8888;
132   unsigned int        destBytesPerPixel   = Dali::Pixel::GetBytesPerPixel(destPixelFormat);
133   int                 destAlphaByteOffset = 0;
134   int                 destAlphaMask       = 0;
135   Dali::Pixel::GetAlphaOffsetAndMask(destPixelFormat, destAlphaByteOffset, destAlphaMask);
136
137   PixelBufferPtr newPixelBuffer = PixelBuffer::New(buffer.GetWidth(), buffer.GetHeight(), destPixelFormat);
138   unsigned char* destBuffer     = newPixelBuffer->GetBuffer();
139   unsigned char* oldBuffer      = buffer.GetBuffer();
140
141   int  srcAlphaOffset = 0;
142   int  srcColorOffset = 0;
143   int  destOffset     = 0;
144   bool hasAlpha       = Dali::Pixel::HasAlpha(buffer.GetPixelFormat());
145
146   float         srcAlphaValue = 1.0f;
147   unsigned char destAlpha     = 0;
148
149   for(unsigned int row = 0; row < buffer.GetHeight(); ++row)
150   {
151     for(unsigned int col = 0; col < buffer.GetWidth(); ++col)
152     {
153       unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
154       srcAlphaValue       = float(alpha) / 255.0f;
155
156       ConvertColorChannelsToRGBA8888(oldBuffer, srcColorOffset, srcColorPixelFormat, destBuffer, destOffset);
157
158       if(hasAlpha)
159       {
160         destAlpha            = ConvertAlphaChannelToA8(oldBuffer, srcColorOffset, srcColorPixelFormat);
161         float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
162         destAlpha            = destAlphaValue;
163       }
164       else
165       {
166         destAlpha = floorf(Clamp(srcAlphaValue * 255.0f, 0.0f, 255.0f));
167       }
168
169       destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
170       destBuffer[destOffset + destAlphaByteOffset] |= (destAlpha & destAlphaMask);
171
172       srcColorOffset += srcColorBytesPerPixel;
173       srcAlphaOffset += srcBytesPerPixel;
174       destOffset += destBytesPerPixel;
175     }
176   }
177
178   return newPixelBuffer;
179 }
180
181 } //namespace Adaptor
182
183 } // namespace Internal
184
185 } // namespace Dali