2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "pixel-manipulation.h"
18 #include "alpha-mask.h"
19 #include "pixel-buffer-impl.h"
20 #include <dali/public-api/images/image-operations.h> // For ImageDimensions
21 #include <platform-abstractions/portable/image-operations.h>
30 PixelBufferPtr ResizeMask( const PixelBuffer& inMask, ImageDimensions outDimensions )
34 if( inMask.GetWidth() != outDimensions.GetWidth() || inMask.GetHeight() != outDimensions.GetHeight() )
36 mask = PixelBuffer::New( outDimensions.GetWidth(), outDimensions.GetHeight(), inMask.GetPixelFormat() );
37 ImageDimensions inDimensions( inMask.GetWidth(), inMask.GetHeight() );
39 if( Pixel::GetBytesPerPixel( inMask.GetPixelFormat() ) == 4 )
41 Dali::Internal::Platform::LanczosSample4BPP( inMask.GetBuffer(), inDimensions,
42 mask->GetBuffer(), outDimensions );
44 else if( inMask.GetPixelFormat() == Pixel::L8 )
46 Dali::Internal::Platform::LanczosSample1BPP( inMask.GetBuffer(), inDimensions,
47 mask->GetBuffer(), outDimensions );
52 mask = const_cast<PixelBuffer*>(&inMask);
57 void ApplyMaskToAlphaChannel( PixelBuffer& buffer, const PixelBuffer& inMask )
59 int srcAlphaByteOffset=0;
61 Dali::Pixel::Format srcPixelFormat = inMask.GetPixelFormat();
63 PixelBufferPtr mask = ResizeMask( inMask, ImageDimensions( buffer.GetWidth(), buffer.GetHeight() ) );
65 if( Pixel::HasAlpha(srcPixelFormat) )
67 Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
69 else if( srcPixelFormat == Pixel::L8 )
74 int destAlphaByteOffset=0;
76 Dali::Pixel::GetAlphaOffsetAndMask( buffer.GetPixelFormat(), destAlphaByteOffset, destAlphaMask );
78 unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
79 unsigned char* srcBuffer = mask->GetBuffer();
80 unsigned char* destBuffer = buffer.GetBuffer();
82 unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel( buffer.GetPixelFormat() );
87 float srcAlphaValue = 1.0f;
89 for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
91 for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
93 unsigned char alpha = srcBuffer[srcOffset + srcAlphaByteOffset] & srcAlphaMask;
94 srcAlphaValue = float(alpha)/255.0f;
96 unsigned char destAlpha = destBuffer[destOffset + destAlphaByteOffset] & destAlphaMask;
97 float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
98 destAlpha = destAlphaValue;
99 destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
100 destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
102 srcOffset += srcBytesPerPixel;
103 destOffset += destBytesPerPixel;
108 PixelBufferPtr CreateNewMaskedBuffer( const PixelBuffer& buffer, const PixelBuffer& inMask )
110 // Set up source alpha offsets
111 int srcAlphaByteOffset=0;
113 Dali::Pixel::Format srcPixelFormat = inMask.GetPixelFormat();
115 PixelBufferPtr mask = ResizeMask( inMask, ImageDimensions( buffer.GetWidth(), buffer.GetHeight() ) );
116 if( Pixel::HasAlpha(srcPixelFormat) )
118 Dali::Pixel::GetAlphaOffsetAndMask( srcPixelFormat, srcAlphaByteOffset, srcAlphaMask );
120 else if( srcPixelFormat == Pixel::L8 )
125 unsigned int srcBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcPixelFormat );
126 unsigned char* srcBuffer = mask->GetBuffer();
128 // Set up source color offsets
129 Dali::Pixel::Format srcColorPixelFormat = buffer.GetPixelFormat();
130 unsigned int srcColorBytesPerPixel = Dali::Pixel::GetBytesPerPixel( srcColorPixelFormat );
132 // Setup destination offsets
133 Dali::Pixel::Format destPixelFormat = Dali::Pixel::RGBA8888;
134 unsigned int destBytesPerPixel = Dali::Pixel::GetBytesPerPixel( destPixelFormat );
135 int destAlphaByteOffset=0;
137 Dali::Pixel::GetAlphaOffsetAndMask( destPixelFormat, destAlphaByteOffset, destAlphaMask );
139 PixelBufferPtr newPixelBuffer = PixelBuffer::New( buffer.GetWidth(), buffer.GetHeight(),
141 unsigned char* destBuffer = newPixelBuffer->GetBuffer();
142 unsigned char* oldBuffer = buffer.GetBuffer();
144 int srcAlphaOffset=0;
145 int srcColorOffset=0;
147 bool hasAlpha = Dali::Pixel::HasAlpha(buffer.GetPixelFormat());
149 float srcAlphaValue = 1.0f;
150 unsigned char destAlpha = 0;
152 for( unsigned int row = 0; row < buffer.GetHeight(); ++row )
154 for( unsigned int col = 0; col < buffer.GetWidth(); ++col )
156 unsigned char alpha = srcBuffer[srcAlphaOffset + srcAlphaByteOffset] & srcAlphaMask;
157 srcAlphaValue = float(alpha)/255.0f;
159 ConvertColorChannelsToRGBA8888(oldBuffer, srcColorOffset, srcColorPixelFormat, destBuffer, destOffset );
163 destAlpha = ConvertAlphaChannelToA8( oldBuffer, srcColorOffset, srcColorPixelFormat );
164 float destAlphaValue = Clamp(float(destAlpha) * srcAlphaValue, 0.0f, 255.0f);
165 destAlpha = destAlphaValue;
169 destAlpha = floorf(Clamp(srcAlphaValue * 255.0f, 0.0f, 255.0f));
172 destBuffer[destOffset + destAlphaByteOffset] &= ~destAlphaMask;
173 destBuffer[destOffset + destAlphaByteOffset] |= ( destAlpha & destAlphaMask );
175 srcColorOffset += srcColorBytesPerPixel;
176 srcAlphaOffset += srcBytesPerPixel;
177 destOffset += destBytesPerPixel;
181 return newPixelBuffer;
184 } //namespace Adaptor
186 }// namespace Internal