• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "components/ui_image_view.h"
17 #include "common/image.h"
18 #include "common/typed_text.h"
19 #include "draw/draw_image.h"
20 #include "draw/draw_label.h"
21 #include "engines/gfx/gfx_engine_manager.h"
22 #include "gfx_utils/file.h"
23 #include "gfx_utils/image_info.h"
24 #include "gfx_utils/mem_api.h"
25 #include "imgdecode/cache_manager.h"
26 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
27 #include "gif_lib.h"
28 #endif
29 
30 namespace OHOS {
31 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
32 class GifImageAnimator : public Animator, public AnimatorCallback {
33 public:
GifImageAnimator(UIView * view,const char * src)34     GifImageAnimator(UIView* view, const char* src)
35         : Animator(this, view, 0, true),
36           gifFileType_(nullptr),
37           imageIndex_(0),
38           delayTime_(0),
39           lastRunTime_(0),
40           deltaTime_(0),
41           gifDataSize_(0),
42           src_(src)
43     {
44     }
45 
~GifImageAnimator()46     virtual ~GifImageAnimator()
47     {
48         CloseGifFile();
49     }
50 
51     void Callback(UIView* view) override;
52 
SetGifFileType(GifFileType * gifFileType)53     void SetGifFileType(GifFileType* gifFileType)
54     {
55         gifFileType_ = gifFileType;
56     }
57 
58     uint32_t SetGifFrame(GifFileType* gifFileType, int32_t imageIndex, UIImageView* imageView) const;
59     void DealGifImageData(const GifFileType* gifFileType,
60                           const GifImageDesc* gifImageDesc,
61                           const SavedImage* savedImage,
62                           GraphicsControlBlock gcb,
63                           const ColorMapObject* colorMap) const;
64     void OpenGifFile(const char* src);
65     void CloseGifFile();
66 
67 private:
GetGifFileType()68     GifFileType* GetGifFileType()
69     {
70         if (gifFileType_ == nullptr) {
71             OpenGifFile(src_);
72         }
73         return gifFileType_;
74     }
75 
76     GifFileType* gifFileType_;
77     int32_t imageIndex_;
78     uint32_t delayTime_;
79     uint32_t lastRunTime_;
80     uint32_t deltaTime_;
81     uint32_t gifDataSize_;
82     uint8_t* gifImageData_ = nullptr;
83     const char* src_;
84 };
85 
OpenGifFile(const char * src)86 void GifImageAnimator::OpenGifFile(const char* src)
87 {
88     int error = D_GIF_SUCCEEDED;
89     GifFileType* gifFileType = DGifOpenFileName(src, &error);
90     if (error != D_GIF_SUCCEEDED) {
91         return;
92     }
93     DGifSlurp(gifFileType);
94     /* 3 : when change single pixel to byte, the buffer should divided by 8, equal to shift right 3 bits. */
95     uint8_t pixelByteSize = DrawUtils::GetPxSizeByColorMode(ARGB8888) >> 3;
96     gifDataSize_ = gifFileType->SWidth * gifFileType->SHeight * pixelByteSize;
97     gifImageData_ = static_cast<uint8_t*>(UIMalloc(gifDataSize_));
98     if (gifImageData_ == nullptr) {
99         CloseGifFile();
100         return;
101     }
102     SetGifFileType(gifFileType);
103 }
104 
CloseGifFile()105 void GifImageAnimator::CloseGifFile()
106 {
107     GifFileType* gifFileType = GetGifFileType();
108     if (gifFileType != nullptr) {
109         DGifCloseFile(gifFileType, nullptr);
110     }
111     if (gifImageData_ != nullptr) {
112         UIFree(reinterpret_cast<void*>(const_cast<uint8_t*>(gifImageData_)));
113         gifImageData_ = nullptr;
114     }
115 }
116 
Callback(UIView * view)117 void GifImageAnimator::Callback(UIView* view)
118 {
119     if (view == nullptr) {
120         return;
121     }
122     UIImageView* imageView = static_cast<UIImageView*>(view);
123     uint32_t curTime = GetRunTime();
124     if (curTime != 0) {
125         if (curTime + deltaTime_ - lastRunTime_ >= delayTime_) {
126             deltaTime_ = curTime + deltaTime_ - lastRunTime_ - delayTime_;
127             lastRunTime_ = curTime;
128         } else {
129             return;
130         }
131     }
132     GifFileType* gifFileType = GetGifFileType();
133     if (gifFileType != nullptr) {
134         delayTime_ = SetGifFrame(gifFileType, imageIndex_, imageView);
135         imageIndex_ = (imageIndex_ < gifFileType->ImageCount - 1) ? (imageIndex_ + 1) : 0;
136     }
137 }
138 
SetGifFrame(GifFileType * gifFileType,int32_t imageIndex,UIImageView * imageView) const139 uint32_t GifImageAnimator::SetGifFrame(GifFileType* gifFileType, int32_t imageIndex, UIImageView* imageView) const
140 {
141     SavedImage* savedImage = &(gifFileType->SavedImages[imageIndex]);
142     if (savedImage == nullptr) {
143         return 0;
144     }
145     GifImageDesc* gifImageDesc = &(savedImage->ImageDesc);
146     if (gifImageDesc == nullptr) {
147         return 0;
148     }
149     GraphicsControlBlock gcb;
150     int32_t ret = DGifSavedExtensionToGCB(gifFileType, imageIndex, &gcb);
151     if (ret != GIF_OK) {
152         return 0;
153     }
154     ColorMapObject* colorMap = nullptr;
155     if (gifImageDesc->ColorMap != nullptr) {
156         colorMap = gifImageDesc->ColorMap;
157     } else {
158         colorMap = gifFileType->SColorMap;
159     }
160 
161     DealGifImageData(gifFileType, gifImageDesc, savedImage, gcb, colorMap);
162     if (gifImageData_ == nullptr) {
163         return 0;
164     }
165     imageView->gifFrameFlag_ = true;
166     ImageInfo gifFrame;
167     gifFrame.header.width = gifFileType->SWidth;
168     gifFrame.header.height = gifFileType->SHeight;
169     gifFrame.header.colorMode = ARGB8888;
170     gifFrame.dataSize = gifDataSize_;
171     gifFrame.data = gifImageData_;
172     imageView->SetSrc(&gifFrame);
173 
174     if (gcb.DelayTime >= 0) {
175         return static_cast<uint32_t>(gcb.DelayTime) * 10; // 10: change hundredths (1/100) of a second to millisecond
176     } else {
177         return 0;
178     }
179 }
180 
DealGifImageData(const GifFileType * gifFileType,const GifImageDesc * gifImageDesc,const SavedImage * savedImage,GraphicsControlBlock gcb,const ColorMapObject * colorMap) const181 void GifImageAnimator::DealGifImageData(const GifFileType* gifFileType,
182                                         const GifImageDesc* gifImageDesc,
183                                         const SavedImage* savedImage,
184                                         GraphicsControlBlock gcb,
185                                         const ColorMapObject* colorMap) const
186 {
187     if ((gifFileType == nullptr) || (gifImageDesc == nullptr) || (savedImage == nullptr) ||
188         (savedImage->RasterBits == nullptr) || (colorMap == nullptr) || (colorMap->Colors == nullptr)) {
189         return;
190     }
191     uint8_t colorIndex = 0;
192     GifColorType* gifColorType = nullptr;
193     uint32_t index = 0;
194 
195     for (int32_t x = 0; x < gifFileType->SHeight; x++) {
196         for (int32_t y = 0; y < gifFileType->SWidth; y++) {
197             bool transparentColor = true;
198             if ((x >= gifImageDesc->Top) && (x < gifImageDesc->Top + gifImageDesc->Height) &&
199                 (y >= gifImageDesc->Left) && (y < gifImageDesc->Left + gifImageDesc->Width)) {
200                 int32_t loc = (x - gifImageDesc->Top) * gifImageDesc->Width + (y - gifImageDesc->Left);
201                 colorIndex = savedImage->RasterBits[loc];
202 
203                 if ((gcb.DisposalMode != DISPOSE_DO_NOT) || (gcb.TransparentColor == NO_TRANSPARENT_COLOR) ||
204                     (colorIndex != gcb.TransparentColor)) {
205                     transparentColor = false;
206                 }
207             }
208             if (transparentColor) {
209                 index += 4; // 4: skip color index, keep last frame color
210             } else {
211                 gifColorType = &colorMap->Colors[colorIndex];
212                 gifImageData_[index++] = gifColorType->Blue;
213                 gifImageData_[index++] = gifColorType->Green;
214                 gifImageData_[index++] = gifColorType->Red;
215                 gifImageData_[index++] = OPA_OPAQUE;
216             }
217         }
218     }
219 }
220 #endif
221 
UIImageView()222 UIImageView::UIImageView()
223     : imageWidth_(0),
224       imageHeight_(0),
225       autoEnable_(true),
226       needRefresh_(false),
227       colorFormat_(UNKNOWN),
228       blurLevel_(BlurLevel::LEVEL0),
229       algorithm_(TransformAlgorithm::BILINEAR),
230       reserve_(0)
231 {
232     style_ = &(StyleDefault::GetBackgroundTransparentStyle());
233 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
234     gifImageAnimator_ = nullptr;
235     gifFrameFlag_ = false;
236 #endif
237 }
238 
~UIImageView()239 UIImageView::~UIImageView()
240 {
241 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
242     RemoveAndStopGifAnimator();
243 #endif
244     if (drawTransMap_ != nullptr) {
245         delete drawTransMap_;
246         drawTransMap_ = nullptr;
247     }
248     if (contentMatrix_ != nullptr) {
249         delete contentMatrix_;
250         contentMatrix_ = nullptr;
251     }
252 }
253 
SetResizeMode(ImageResizeMode mode)254 void UIImageView::SetResizeMode(ImageResizeMode mode)
255 {
256     // when automatic adaptation is enabled only save the mode, no need to update the DrawtransMap
257     if (autoEnable_) {
258         imageResizeMode_ = mode;
259     } else if (imageResizeMode_ != mode) {
260         needRefresh_ = true;
261         ReMeasure();
262         // must update the mode, before calling UpdateDrawTransMap
263         imageResizeMode_ = mode;
264         UpdateDrawTransMap(true);
265     }
266 }
267 
AdjustScaleAndTranslate(Vector3<float> & scale,Vector3<int16_t> & translate,int16_t widgetWidth,int16_t widgetHeight) const268 void UIImageView::AdjustScaleAndTranslate(Vector3<float>& scale, Vector3<int16_t>& translate,
269     int16_t widgetWidth, int16_t widgetHeight) const
270 {
271     // adjust scale
272     float ratio = 1.0f;
273     switch (imageResizeMode_) {
274         case ImageResizeMode::COVER:
275             ratio = MATH_MAX(scale.x_, scale.y_);
276             break;
277         case ImageResizeMode::CONTAIN:
278             ratio = MATH_MIN(scale.x_, scale.y_);
279             break;
280         case ImageResizeMode::CENTER: // ratio is 1.0f
281             break;
282         case ImageResizeMode::SCALE_DOWN:
283             ratio = MATH_MIN(scale.x_, scale.y_);
284             ratio = MATH_MIN(ratio, 1.0f);
285             break;
286         case ImageResizeMode::FILL: // do nothing
287             return;
288         default:
289             break;
290     }
291     if (scale.x_ != ratio) {
292         scale.x_ = ratio;
293         // 0.5: adjust the x-coordinate of the content to the center of widget
294         translate.x_ += (static_cast<float>(widgetWidth) - static_cast<float>(imageWidth_) * ratio) * 0.5f;
295     }
296     if (scale.y_ != ratio) {
297         scale.y_ = ratio;
298         // 0.5: adjust the y-coordinate of the content to the center of widget
299         translate.y_ += (static_cast<float>(widgetHeight) - static_cast<float>(imageHeight_) * ratio) * 0.5f;
300     }
301 }
302 
UpdateContentMatrix()303 void UIImageView::UpdateContentMatrix()
304 {
305     Rect viewRect = GetOrigRect();
306     if (autoEnable_ || (imageResizeMode_ == ImageResizeMode::NONE) ||
307         (imageWidth_ == viewRect.GetWidth() && imageHeight_ == viewRect.GetHeight()) ||
308         imageWidth_ == 0 || imageHeight_ == 0) {
309         if (contentMatrix_ != nullptr) {
310             delete contentMatrix_;
311             contentMatrix_ = nullptr;
312         }
313         return;
314     }
315     if (contentMatrix_ == nullptr) {
316         contentMatrix_ = new Matrix4<float>();
317         if (contentMatrix_ == nullptr) {
318             GRAPHIC_LOGE("can not new contentMatrix");
319             return;
320         }
321     }
322     int16_t widgetWidth = viewRect.GetWidth() - style_->paddingLeft_ - style_->paddingRight_ -
323         style_->borderWidth_ * 2; // 2: excludes the border-left and border-right
324     int16_t widgetHeight = viewRect.GetHeight() - style_->paddingTop_ - style_->paddingBottom_ -
325         style_->borderWidth_ * 2; // 2: excludes the border-top and border-bottom
326 
327     float scaleX = static_cast<float>(widgetWidth) / static_cast<float>(imageWidth_);
328     float scaleY = static_cast<float>(widgetHeight) / static_cast<float>(imageHeight_);
329     Vector3<float> scale(scaleX, scaleY, 1.0f);
330     Vector3<int16_t> translate(style_->paddingLeft_ + style_->borderWidth_,
331         style_->paddingTop_ + style_->borderWidth_, 0);
332     AdjustScaleAndTranslate(scale, translate, widgetWidth, widgetHeight);
333 
334     auto scaleMatrix = Matrix4<float>::Scale(scale, Vector3<float>(viewRect.GetX(), viewRect.GetY(), 0));
335     auto translateMatrix = Matrix4<float>::Translate(Vector3<float>(translate.x_, translate.y_, 0));
336     *contentMatrix_ = translateMatrix * scaleMatrix;
337 }
338 
UpdateDrawTransMap(bool updateContentMatrix)339 void UIImageView::UpdateDrawTransMap(bool updateContentMatrix)
340 {
341     auto viewRect = GetOrigRect();
342     if (updateContentMatrix || (drawTransMap_ != nullptr &&
343         (drawTransMap_->GetTransMapRect().GetX() != viewRect.GetX() ||
344         drawTransMap_->GetTransMapRect().GetY() != viewRect.GetY()))) {
345         UpdateContentMatrix();
346     }
347     // has no transformation
348     if ((contentMatrix_ == nullptr) && ((transMap_ == nullptr) || transMap_->IsInvalid())) {
349         if (drawTransMap_ != nullptr) {
350             delete drawTransMap_;
351             drawTransMap_ = nullptr;
352         }
353         return;
354     }
355     if (drawTransMap_ == nullptr) {
356         drawTransMap_ = new TransformMap();
357         if (drawTransMap_ == nullptr) {
358             GRAPHIC_LOGE("can not new drawTransMap");
359             return;
360         }
361     }
362     if (contentMatrix_ != nullptr) {
363         drawTransMap_->SetTransMapRect(Rect(viewRect.GetX(), viewRect.GetY(),
364             viewRect.GetX() + imageWidth_ - 1, viewRect.GetY() + imageHeight_ - 1));
365     } else {
366         drawTransMap_->SetTransMapRect(viewRect);
367     }
368     // only contentMatrix
369     if (transMap_ == nullptr || transMap_->IsInvalid()) {
370         if (contentMatrix_ == nullptr) {
371             GRAPHIC_LOGE("Text: UpdateDrawTransMap contentMatrix_ is nullptr");
372             return;
373         }
374         drawTransMap_->SetMatrix(*contentMatrix_);
375         return;
376     }
377     // update the transMap, now the transMap is not nullptr
378     if (!(transMap_->GetTransMapRect() == viewRect)) {
379         transMap_->SetTransMapRect(viewRect);
380     }
381     // only transMap
382     if (contentMatrix_ == nullptr) {
383         *drawTransMap_ = *transMap_;
384         return;
385     }
386     // merge the transMap and content matrix
387     auto rect = transMap_->GetTransMapRect();
388     auto translate = Matrix4<float>::Translate(Vector3<float>(-rect.GetX(), -rect.GetY(), 0));
389     auto matrix = transMap_->GetTransformMatrix() * translate;
390     matrix = matrix * (*contentMatrix_);
391     drawTransMap_->SetMatrix(matrix);
392 }
393 
SetHeight(int16_t height)394 void UIImageView::SetHeight(int16_t height)
395 {
396     if (GetHeight() != height) {
397         UIView::SetHeight(height);
398         UpdateDrawTransMap(true);
399     }
400 }
401 
SetWidth(int16_t width)402 void UIImageView::SetWidth(int16_t width)
403 {
404     if (GetWidth() != width) {
405         UIView::SetWidth(width);
406         UpdateDrawTransMap(true);
407     }
408 }
409 
OnPreDraw(Rect & invalidatedArea) const410 bool UIImageView::OnPreDraw(Rect& invalidatedArea) const
411 {
412     if ((image_.GetSrcType() == IMG_SRC_UNKNOWN)) {
413         return true;
414     }
415 
416     if ((colorFormat_ == RGB565) || (colorFormat_ == RGB888)) {
417         if (GetRect().IsContains(invalidatedArea)) {
418             return true;
419         }
420         invalidatedArea.Intersect(invalidatedArea, GetRect());
421     }
422 
423     return false;
424 }
425 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)426 void UIImageView::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
427 {
428     OpacityType opa = GetMixOpaScale();
429     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetRect(), invalidatedArea, *style_, opa);
430     if ((imageHeight_ == 0) || (imageWidth_ == 0)) {
431         return;
432     }
433     UpdateDrawTransMap();
434     Rect viewRect = GetContentRect();
435     Rect trunc(invalidatedArea);
436     if (trunc.Intersect(trunc, viewRect)) {
437         uint8_t srcType = image_.GetSrcType();
438         if ((srcType == IMG_SRC_FILE) || (srcType == IMG_SRC_VARIABLE)) {
439             Rect cordsTmp;
440             cordsTmp.SetTop(viewRect.GetY());
441             cordsTmp.SetBottom(viewRect.GetY() + imageHeight_ - 1);
442 
443             if ((drawTransMap_ == nullptr) || drawTransMap_->IsInvalid()) {
444                 while (cordsTmp.GetTop() <= viewRect.GetBottom()) {
445                     cordsTmp.SetLeft(viewRect.GetX());
446                     cordsTmp.SetRight(viewRect.GetX() + imageWidth_ - 1);
447                     while (cordsTmp.GetLeft() <= viewRect.GetRight()) {
448                         image_.DrawImage(gfxDstBuffer, cordsTmp, trunc, *style_, opa);
449                         cordsTmp.SetLeft(cordsTmp.GetLeft() + imageWidth_);
450                         cordsTmp.SetRight(cordsTmp.GetRight() + imageWidth_);
451                     }
452                     cordsTmp.SetTop(cordsTmp.GetTop() + imageHeight_);
453                     cordsTmp.SetBottom(cordsTmp.GetBottom() + imageHeight_);
454                 }
455             } else if ((drawTransMap_ != nullptr) && !drawTransMap_->IsInvalid()) {
456                 ImageInfo imgInfo;
457                 if (srcType == IMG_SRC_FILE) {
458                     CacheEntry entry;
459                     RetCode ret = CacheManager::GetInstance().Open(GetPath(), *style_, entry);
460                     if (ret != RetCode::OK) {
461                         return;
462                     }
463                     imgInfo = entry.GetImageInfo();
464                 } else {
465                     imgInfo = *(GetImageInfo());
466                 }
467                 uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(imgInfo.header.colorMode);
468                 TransformDataInfo imageTranDataInfo = {imgInfo.header, imgInfo.data, pxSize,
469                                                        static_cast<BlurLevel>(blurLevel_),
470                                                        static_cast<TransformAlgorithm>(algorithm_)};
471                 OpacityType opaScale = DrawUtils::GetMixOpacity(opa, style_->imageOpa_);
472                 BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, trunc, {0, 0}, Color::Black(),
473                                                             opaScale, *drawTransMap_, imageTranDataInfo);
474             }
475         }
476     }
477 }
478 
SetSrc(const char * src)479 void UIImageView::SetSrc(const char* src)
480 {
481 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
482     if (src == nullptr) {
483         return;
484     }
485     const static uint8_t IMG_BYTES_TO_CHECK = 4; // 4: check 4 bytes of image file
486     char buf[IMG_BYTES_TO_CHECK] = {0};
487     int32_t fd = open(src, O_RDONLY);
488     if (fd < 0) {
489         return;
490     }
491     if (read(fd, buf, IMG_BYTES_TO_CHECK) != IMG_BYTES_TO_CHECK) {
492         close(fd);
493         return;
494     }
495     close(fd);
496     bool updated = false;
497     RemoveAndStopGifAnimator();
498     // 0x47 0x49 0x46: GIF file's header
499     if ((static_cast<uint8_t>(buf[0]) == 0x47) && (static_cast<uint8_t>(buf[1]) == 0x49) &&
500         (static_cast<uint8_t>(buf[2]) == 0x46)) { // 2: array index of GIF file's header
501         if (gifImageAnimator_ == nullptr) {
502             gifImageAnimator_ = new GifImageAnimator(this, src);
503             if (gifImageAnimator_ == nullptr) {
504                 GRAPHIC_LOGE("new GifImageAnimator fail");
505                 return;
506             }
507         }
508         AddAndStartGifAnimator();
509         updated = true;
510     } else {
511         updated = image_.SetSrc(src);
512     }
513 #else
514     bool updated = image_.SetSrc(src);
515 #endif
516     if (!updated) {
517         return;
518     }
519     needRefresh_ = true;
520     if (autoEnable_) {
521         UIImageView::ReMeasure();
522     }
523     Invalidate();
524 }
525 
ReMeasure()526 void UIImageView::ReMeasure()
527 {
528     if (!needRefresh_) {
529         return;
530     }
531     needRefresh_ = false;
532 
533     ImageHeader header = {0};
534     image_.GetHeader(header);
535 
536     imageWidth_ = header.width;
537     imageHeight_ = header.height;
538     colorFormat_ = header.colorMode;
539 
540     if (autoEnable_) {
541         Invalidate();
542         Resize(imageWidth_, imageHeight_);
543         Invalidate();
544     }
545 }
546 
SetSrc(const ImageInfo * src)547 void UIImageView::SetSrc(const ImageInfo* src)
548 {
549 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
550     if (!gifFrameFlag_ && (gifImageAnimator_ != nullptr)) {
551         RemoveAndStopGifAnimator();
552     }
553     gifFrameFlag_ = false;
554 #endif
555     bool updated = image_.SetSrc(src);
556     if (!updated) {
557         return;
558     }
559     needRefresh_ = true;
560     if (autoEnable_) {
561         UIImageView::ReMeasure();
562     }
563     Invalidate();
564 }
565 
566 #if defined(ENABLE_GIF) && (ENABLE_GIF == 1)
AddAndStartGifAnimator()567 void UIImageView::AddAndStartGifAnimator()
568 {
569     if (gifImageAnimator_ != nullptr) {
570         gifImageAnimator_->Start();
571     }
572 }
573 
RemoveAndStopGifAnimator()574 void UIImageView::RemoveAndStopGifAnimator()
575 {
576     if (gifImageAnimator_ != nullptr) {
577         gifImageAnimator_->Stop();
578         delete gifImageAnimator_;
579         gifImageAnimator_ = nullptr;
580     }
581 }
582 #endif
583 } // namespace OHOS
584