2 * Copyright (c) 2021 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.
19 #include <dali-toolkit/devel-api/utility/npatch-utilities.h>
22 #include <dali/integration-api/debug.h>
28 namespace NPatchUtility
32 Uint16Pair ParseRange(uint32_t& index, uint32_t width, uint8_t*& pixel, uint32_t pixelStride, int32_t testByte, int32_t testBits, int32_t testValue)
34 unsigned int start = 0xFFFF;
35 for(; index < width; ++index, pixel += pixelStride)
37 if((pixel[testByte] & testBits) == testValue)
46 unsigned int end = width;
47 for(; index < width; ++index, pixel += pixelStride)
49 if((pixel[testByte] & testBits) != testValue)
58 return Uint16Pair(start, end);
61 } // unnamed namespace
63 void GetRedOffsetAndMask(Dali::Pixel::Format pixelFormat, int32_t& byteOffset, int32_t& bitMask)
69 case Dali::Pixel::LA88:
75 case Dali::Pixel::RGB888:
76 case Dali::Pixel::RGB8888:
77 case Dali::Pixel::RGBA8888:
83 case Dali::Pixel::BGR8888:
84 case Dali::Pixel::BGRA8888:
90 case Dali::Pixel::RGB565:
96 case Dali::Pixel::BGR565:
102 case Dali::Pixel::RGBA4444:
108 case Dali::Pixel::BGRA4444:
114 case Dali::Pixel::RGBA5551:
120 case Dali::Pixel::BGRA5551:
126 case Dali::Pixel::INVALID:
127 case Dali::Pixel::COMPRESSED_R11_EAC:
128 case Dali::Pixel::COMPRESSED_SIGNED_R11_EAC:
129 case Dali::Pixel::COMPRESSED_RG11_EAC:
130 case Dali::Pixel::COMPRESSED_SIGNED_RG11_EAC:
131 case Dali::Pixel::COMPRESSED_RGB8_ETC2:
132 case Dali::Pixel::COMPRESSED_SRGB8_ETC2:
133 case Dali::Pixel::COMPRESSED_RGB8_ETC1:
134 case Dali::Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
135 case Dali::Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
136 case Dali::Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
137 case Dali::Pixel::COMPRESSED_RGBA8_ETC2_EAC:
138 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
139 case Dali::Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
140 case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
141 case Dali::Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
142 case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
143 case Dali::Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
144 case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
145 case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
146 case Dali::Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
147 case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
148 case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
149 case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
150 case Dali::Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
151 case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
152 case Dali::Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
153 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
154 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
155 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
156 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
157 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
158 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
159 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
160 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
161 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
162 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
163 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
164 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
165 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
166 case Dali::Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
168 DALI_LOG_ERROR("Pixel formats for compressed images are not compatible with simple masking-out of per-pixel alpha.\n");
173 case Dali::Pixel::RGB16F:
174 case Dali::Pixel::RGB32F:
175 case Dali::Pixel::DEPTH_UNSIGNED_INT:
176 case Dali::Pixel::DEPTH_FLOAT:
177 case Dali::Pixel::DEPTH_STENCIL:
178 case Dali::Pixel::R11G11B10F:
180 DALI_LOG_ERROR("Pixel format not compatible.\n");
188 void ParseBorders(Devel::PixelBuffer& pixelBuffer, StretchRanges& stretchPixelsX, StretchRanges& stretchPixelsY)
190 stretchPixelsX.Clear();
191 stretchPixelsY.Clear();
193 Pixel::Format pixelFormat = pixelBuffer.GetPixelFormat();
195 int32_t alphaByte = 0;
196 int32_t alphaBits = 0;
197 Pixel::GetAlphaOffsetAndMask(pixelFormat, alphaByte, alphaBits);
199 int32_t testByte = alphaByte;
200 int32_t testBits = alphaBits;
201 int32_t testValue = alphaBits; // Opaque == stretch
204 GetRedOffsetAndMask(pixelFormat, testByte, testBits);
205 testValue = 0; // Black == stretch
208 uint32_t bytesPerPixel = Pixel::GetBytesPerPixel(pixelFormat);
209 uint32_t width = pixelBuffer.GetWidth();
210 uint32_t height = pixelBuffer.GetHeight();
211 uint8_t* srcPixels = pixelBuffer.GetBuffer();
212 uint32_t srcStride = width * bytesPerPixel;
215 uint8_t* top = srcPixels + bytesPerPixel;
218 for(; index < width - 2;)
220 Uint16Pair range = ParseRange(index, width - 2, top, bytesPerPixel, testByte, testBits, testValue);
221 if(range.GetX() != 0xFFFF)
223 stretchPixelsX.PushBack(range);
228 uint8_t* left = srcPixels + srcStride;
230 for(; index < height - 2;)
232 Uint16Pair range = ParseRange(index, height - 2, left, srcStride, testByte, testBits, testValue);
233 if(range.GetX() != 0xFFFF)
235 stretchPixelsY.PushBack(range);
239 // If there are no stretch pixels then make the entire image stretchable
240 if(stretchPixelsX.Size() == 0)
242 stretchPixelsX.PushBack(Uint16Pair(0, width - 2));
244 if(stretchPixelsY.Size() == 0)
246 stretchPixelsY.PushBack(Uint16Pair(0, height - 2));
250 bool IsNinePatchUrl(const std::string& url)
254 std::string::const_reverse_iterator iter = url.rbegin();
262 while(iter < url.rend())
272 else if(!isalnum(*iter))
280 if(*iter == '#' || *iter == '9')
296 state = DONE; // Stop testing characters
316 } // namespace NPatchUtility
318 } // namespace Toolkit