1 /*
2  * Copyright (C) 2023 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 "image_converter.h"
17 
18 #include "drawable_descriptor_log.h"
19 #include "securec.h"
20 #ifndef PREVIEW
21 #include "image_utils.h"
22 #include "platform/image_native/image_type.h"
23 #endif
24 
25 namespace OHOS::Ace::Napi {
26 #ifndef USE_ROSEN_DRAWING
PixelFormatToSkColorType(Media::PixelFormat pixelFormat)27 SkColorType ImageConverter::PixelFormatToSkColorType(Media::PixelFormat pixelFormat)
28 {
29     switch (pixelFormat) {
30         case Media::PixelFormat::BGRA_8888:
31             return SkColorType::kBGRA_8888_SkColorType;
32         case Media::PixelFormat::ARGB_8888:
33         case Media::PixelFormat::ALPHA_8:
34         case Media::PixelFormat::RGBA_8888:
35         case Media::PixelFormat::RGB_565:
36         case Media::PixelFormat::RGB_888:
37         case Media::PixelFormat::RGBA_F16:
38         case Media::PixelFormat::NV21:
39         case Media::PixelFormat::NV12:
40         case Media::PixelFormat::CMYK:
41         case Media::PixelFormat::UNKNOWN:
42         default:
43             return SkColorType::kUnknown_SkColorType;
44     }
45 }
46 
AlphaTypeToSkAlphaType(Media::AlphaType alphaType)47 SkAlphaType ImageConverter::AlphaTypeToSkAlphaType(Media::AlphaType alphaType)
48 {
49     switch (alphaType) {
50         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
51             return SkAlphaType::kOpaque_SkAlphaType;
52         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
53             return SkAlphaType::kPremul_SkAlphaType;
54         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
55             return SkAlphaType::kUnpremul_SkAlphaType;
56         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
57         default:
58             return SkAlphaType::kUnknown_SkAlphaType;
59     }
60 }
61 
PixelMapToBitmap( const std::shared_ptr<Media::PixelMap>& pixelMap)62 std::shared_ptr<SkBitmap> ImageConverter::PixelMapToBitmap(
63     const std::shared_ptr<Media::PixelMap>& pixelMap)
64 {
65     auto data = pixelMap->GetPixels();
66     SkBitmap bitmap;
67     SkColorType colorType = ImageConverter::PixelFormatToSkColorType(pixelMap->GetPixelFormat());
68     SkAlphaType alphaType = ImageConverter::AlphaTypeToSkAlphaType(pixelMap->GetAlphaType());
69     auto imageInfo = SkImageInfo::Make(pixelMap->GetWidth(), pixelMap->GetHeight(), colorType, alphaType);
70     bitmap.setInfo(imageInfo);
71     bitmap.setPixels(const_cast<uint8_t*>(data));
72     return std::make_shared<SkBitmap>(bitmap);
73 }
74 
BitmapToPixelMap( const std::shared_ptr<SkBitmap>& bitMap, Media::InitializationOptions& opts)75 std::shared_ptr<Media::PixelMap> ImageConverter::BitmapToPixelMap(
76     const std::shared_ptr<SkBitmap>& bitMap, Media::InitializationOptions& opts)
77 {
78     auto data = bitMap->getPixels();
79     opts.size.width = static_cast<int32_t>(bitMap->width());
80     opts.size.height = static_cast<int32_t>(bitMap->height());
81     auto pixelMap = Media::PixelMap::Create(reinterpret_cast<uint32_t*>(data),
82         opts.size.width * opts.size.height, opts);
83     return pixelMap;
84 }
85 #else
86 Rosen::Drawing::ColorType ImageConverter::PixelFormatToColorType(Media::PixelFormat pixelFormat)
87 {
88     switch (pixelFormat) {
89         case Media::PixelFormat::BGRA_8888:
90             return Rosen::Drawing::ColorType::COLORTYPE_BGRA_8888;
91         case Media::PixelFormat::ARGB_8888:
92         case Media::PixelFormat::ALPHA_8:
93         case Media::PixelFormat::RGBA_8888:
94         case Media::PixelFormat::RGB_565:
95         case Media::PixelFormat::RGB_888:
96         case Media::PixelFormat::RGBA_F16:
97         case Media::PixelFormat::NV21:
98         case Media::PixelFormat::NV12:
99         case Media::PixelFormat::CMYK:
100         case Media::PixelFormat::UNKNOWN:
101         default:
102             return Rosen::Drawing::ColorType::COLORTYPE_UNKNOWN;
103     }
104 }
105 
106 Rosen::Drawing::AlphaType ImageConverter::AlphaTypeToAlphaType(Media::AlphaType alphaType)
107 {
108     switch (alphaType) {
109         case Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
110             return Rosen::Drawing::AlphaType::ALPHATYPE_OPAQUE;
111         case Media::AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
112             return Rosen::Drawing::AlphaType::ALPHATYPE_PREMUL;
113         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
114             return Rosen::Drawing::AlphaType::ALPHATYPE_UNPREMUL;
115         case Media::AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
116         default:
117             return Rosen::Drawing::AlphaType::ALPHATYPE_UNKNOWN;
118     }
119 }
120 
121 std::shared_ptr<Rosen::Drawing::Bitmap> ImageConverter::PixelMapToBitmap(
122     const std::shared_ptr<Media::PixelMap>& pixelMap)
123 {
124     if (!pixelMap) {
125         return nullptr;
126     }
127     auto data = pixelMap->GetPixels();
128     Rosen::Drawing::Bitmap bitmap;
129     Rosen::Drawing::ColorType colorType = ImageConverter::PixelFormatToColorType(pixelMap->GetPixelFormat());
130     Rosen::Drawing::AlphaType alphaType = ImageConverter::AlphaTypeToAlphaType(pixelMap->GetAlphaType());
131     Rosen::Drawing::ImageInfo imageInfo(pixelMap->GetWidth(), pixelMap->GetHeight(), colorType, alphaType);
132     bitmap.Build(imageInfo);
133     bitmap.SetPixels(const_cast<uint8_t*>(data));
134     return std::make_shared<Rosen::Drawing::Bitmap>(bitmap);
135 }
136 
137 std::shared_ptr<Media::PixelMap> ImageConverter::BitmapToPixelMap(
138     const std::shared_ptr<Rosen::Drawing::Bitmap>& bitMap, Media::InitializationOptions& opts)
139 {
140     auto data = bitMap->GetPixels();
141     opts.size.width = static_cast<int32_t>(bitMap->GetWidth());
142     opts.size.height = static_cast<int32_t>(bitMap->GetHeight());
143     opts.editable = false;
144     auto pixelMap = Media::PixelMap::Create(opts);
145     if (!pixelMap) {
146         HILOGE("PixelMap is null, bitMap's Size = (%{public}d, %{public}d)", bitMap->GetWidth(), bitMap->GetHeight());
147         return pixelMap;
148     }
149     auto dstAddr = pixelMap->GetWritablePixels();
150     if (memcpy_s(dstAddr, pixelMap->GetByteCount(), data, pixelMap->GetByteCount()) != 0) {
151         HILOGE("PixelMap write fail");
152         return nullptr;
153     }
154     return pixelMap;
155 }
156 #endif
157 } // namespace OHOS::Ace::Napi
158