• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #include "webp_encoder.h"
16 #include "webp/mux.h"
17 #include "hilog/log.h"
18 #include "log_tags.h"
19 #include "media_errors.h"
20 #include "pixel_convert_adapter.h"
21 namespace OHOS {
22 namespace ImagePlugin {
23 using namespace OHOS::HiviewDFX;
24 using namespace MultimediaPlugin;
25 using namespace Media;
26 namespace {
27 constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "WebpEncoder" };
28 constexpr uint32_t WEBP_IMAGE_NUM = 1;
29 constexpr uint32_t COMPONENT_NUM_3 = 3;
30 constexpr uint32_t COMPONENT_NUM_4 = 4;
31 } // namespace
32 
StreamWriter(const uint8_t * data,size_t data_size,const WebPPicture * const picture)33 static int StreamWriter(const uint8_t* data, size_t data_size, const WebPPicture* const picture)
34 {
35     HiLog::Debug(LABEL, "StreamWriter data_size=%{public}zu", data_size);
36 
37     auto webpEncoder = static_cast<WebpEncoder*>(picture->custom_ptr);
38     return webpEncoder->Write(data, data_size) ? 1 : 0;
39 }
40 
WebpEncoder()41 WebpEncoder::WebpEncoder()
42 {
43     HiLog::Debug(LABEL, "create IN");
44 
45     HiLog::Debug(LABEL, "create OUT");
46 }
47 
~WebpEncoder()48 WebpEncoder::~WebpEncoder()
49 {
50     HiLog::Debug(LABEL, "release IN");
51 
52     pixelMaps_.clear();
53 
54     HiLog::Debug(LABEL, "release OUT");
55 }
56 
StartEncode(OutputDataStream & outputStream,PlEncodeOptions & option)57 uint32_t WebpEncoder::StartEncode(OutputDataStream &outputStream, PlEncodeOptions &option)
58 {
59     HiLog::Debug(LABEL, "StartEncode IN, quality=%{public}u, numberHint=%{public}u",
60         option.quality, option.numberHint);
61 
62     pixelMaps_.clear();
63 
64     outputStream_ = &outputStream;
65     encodeOpts_ = option;
66 
67     HiLog::Debug(LABEL, "StartEncode OUT");
68     return SUCCESS;
69 }
70 
AddImage(Media::PixelMap & pixelMap)71 uint32_t WebpEncoder::AddImage(Media::PixelMap &pixelMap)
72 {
73     HiLog::Debug(LABEL, "AddImage IN");
74 
75     if (pixelMaps_.size() >= WEBP_IMAGE_NUM) {
76         HiLog::Error(LABEL, "AddImage, add pixel map out of range=%{public}u.", WEBP_IMAGE_NUM);
77         return ERR_IMAGE_ADD_PIXEL_MAP_FAILED;
78     }
79 
80     pixelMaps_.push_back(&pixelMap);
81 
82     HiLog::Debug(LABEL, "AddImage OUT");
83     return SUCCESS;
84 }
85 
FinalizeEncode()86 uint32_t WebpEncoder::FinalizeEncode()
87 {
88     HiLog::Debug(LABEL, "FinalizeEncode IN");
89 
90     if (pixelMaps_.empty()) {
91         HiLog::Error(LABEL, "FinalizeEncode, no pixel map input.");
92         return ERR_IMAGE_INVALID_PARAMETER;
93     }
94 
95     HiLog::Debug(LABEL, "FinalizeEncode, quality=%{public}u, numberHint=%{public}u",
96         encodeOpts_.quality, encodeOpts_.numberHint);
97 
98     uint32_t errorCode = ERROR;
99 
100     Media::PixelMap &pixelMap = *(pixelMaps_[0]);
101     WebPConfig webpConfig;
102     WebPPicture webpPicture;
103     WebPPictureInit(&webpPicture);
104 
105     errorCode = SetEncodeConfig(pixelMap, webpConfig, webpPicture);
106     HiLog::Debug(LABEL, "FinalizeEncode, config, %{public}u.", errorCode);
107 
108     if (errorCode != SUCCESS) {
109         HiLog::Error(LABEL, "FinalizeEncode, config failed=%{public}u.", errorCode);
110         WebPPictureFree(&webpPicture);
111         return errorCode;
112     }
113 
114     errorCode = DoEncode(pixelMap, webpConfig, webpPicture);
115     HiLog::Debug(LABEL, "FinalizeEncode, encode,%{public}u.", errorCode);
116     WebPPictureFree(&webpPicture);
117 
118     if (errorCode != SUCCESS) {
119         HiLog::Error(LABEL, "FinalizeEncode, encode failed=%{public}u.", errorCode);
120     }
121 
122     HiLog::Debug(LABEL, "FinalizeEncode OUT");
123     return errorCode;
124 }
125 
Write(const uint8_t * data,size_t data_size)126 bool WebpEncoder::Write(const uint8_t* data, size_t data_size)
127 {
128     HiLog::Debug(LABEL, "Write data_size=%{public}zu, iccValid=%{public}d", data_size, iccValid_);
129 
130     if (iccValid_) {
131         return memoryStream_.write(data, data_size);
132     }
133 
134     return outputStream_->Write(data, data_size);
135 }
136 
CheckEncodeFormat(Media::PixelMap & pixelMap)137 bool WebpEncoder::CheckEncodeFormat(Media::PixelMap &pixelMap)
138 {
139     PixelFormat pixelFormat = GetPixelFormat(pixelMap);
140     HiLog::Debug(LABEL, "CheckEncodeFormat, pixelFormat=%{public}u", pixelFormat);
141 
142     switch (pixelFormat) {
143         case PixelFormat::RGBA_8888: {
144             HiLog::Debug(LABEL, "CheckEncodeFormat, RGBA_8888");
145             return true;
146         }
147         case PixelFormat::BGRA_8888: {
148             HiLog::Debug(LABEL, "CheckEncodeFormat, BGRA_8888");
149             return true;
150         }
151         case PixelFormat::RGBA_F16: {
152             HiLog::Debug(LABEL, "CheckEncodeFormat, RGBA_F16");
153             return true;
154         }
155         case PixelFormat::ARGB_8888: {
156             HiLog::Debug(LABEL, "CheckEncodeFormat, ARGB_8888");
157             return true;
158         }
159         case PixelFormat::RGB_888: {
160             HiLog::Debug(LABEL, "CheckEncodeFormat, RGB_888");
161             return true;
162         }
163         case PixelFormat::RGB_565: {
164             bool isOpaque = IsOpaque(pixelMap);
165             HiLog::Debug(LABEL, "CheckEncodeFormat, RGB_565, isOpaque=%{public}d", isOpaque);
166             return isOpaque;
167         }
168         case PixelFormat::ALPHA_8: {
169             HiLog::Debug(LABEL, "CheckEncodeFormat, ALPHA_8");
170             return true;
171         }
172         default: {
173             HiLog::Error(LABEL, "CheckEncodeFormat, pixelFormat=%{public}u", pixelFormat);
174             return false;
175         }
176     }
177 }
178 
DoTransform(Media::PixelMap & pixelMap,char * dst,int componentsNum)179 bool WebpEncoder::DoTransform(Media::PixelMap &pixelMap, char* dst, int componentsNum)
180 {
181     HiLog::Debug(LABEL, "DoTransform IN");
182 
183     PixelFormat pixelFormat = GetPixelFormat(pixelMap);
184     AlphaType alphaType = GetAlphaType(pixelMap);
185     HiLog::Debug(LABEL, "DoTransform, pixelFormat=%{public}u, alphaType=%{public}d, componentsNum=%{public}d",
186         pixelFormat, alphaType, componentsNum);
187 
188     if ((pixelFormat == PixelFormat::RGBA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
189         HiLog::Debug(LABEL, "DoTransform, RGBA_8888, OPAQUE");
190         return DoTransformRGBX(pixelMap, dst, componentsNum);
191     } else if ((pixelFormat == PixelFormat::RGBA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
192         HiLog::Debug(LABEL, "DoTransform, RGBA_8888, UNPREMUL");
193         return DoTransformMemcpy(pixelMap, dst, componentsNum);
194     } else if ((pixelFormat == PixelFormat::RGBA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
195         HiLog::Debug(LABEL, "DoTransform, RGBA_8888, PREMUL");
196         return DoTransformRgbA(pixelMap, dst, componentsNum);
197     } else if ((pixelFormat == PixelFormat::BGRA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
198         HiLog::Debug(LABEL, "DoTransform, BGRA_8888, OPAQUE");
199         return DoTransformBGRX(pixelMap, dst, componentsNum);
200     } else if ((pixelFormat == PixelFormat::BGRA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
201         HiLog::Debug(LABEL, "DoTransform, BGRA_8888, UNPREMUL");
202         return DoTransformBGRA(pixelMap, dst, componentsNum);
203     } else if ((pixelFormat == PixelFormat::BGRA_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
204         HiLog::Debug(LABEL, "DoTransform, BGRA_8888, PREMUL");
205         return DoTransformBgrA(pixelMap, dst, componentsNum);
206     } else if ((pixelFormat == PixelFormat::RGBA_F16) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
207         HiLog::Debug(LABEL, "DoTransform, RGBA_F16, OPAQUE");
208         return DoTransformF16To8888(pixelMap, dst, componentsNum);
209     } else if ((pixelFormat == PixelFormat::RGBA_F16) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
210         HiLog::Debug(LABEL, "DoTransform, RGBA_F16, UNPREMUL");
211         return DoTransformF16To8888(pixelMap, dst, componentsNum);
212     } else if ((pixelFormat == PixelFormat::RGBA_F16) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
213         HiLog::Debug(LABEL, "DoTransform, RGBA_F16, PREMUL");
214         return DoTransformF16pTo8888(pixelMap, dst, componentsNum);
215     } else if ((pixelFormat == PixelFormat::ARGB_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
216         return DoTransformArgbToRgb(pixelMap, dst, componentsNum);
217     } else if ((pixelFormat == PixelFormat::ARGB_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
218         return DoTransformArgbToRgba(pixelMap, dst, componentsNum);
219     } else if ((pixelFormat == PixelFormat::ARGB_8888) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_PREMUL)) {
220         return DoTransformArgbToRgba(pixelMap, dst, componentsNum);
221     } else if (pixelFormat == PixelFormat::RGB_888) {
222         return DoTransformMemcpy(pixelMap, dst, componentsNum);
223     } else if ((pixelFormat == PixelFormat::RGB_565) && IsOpaque(pixelMap)) {
224         HiLog::Debug(LABEL, "DoTransform, RGB_565, Opaque");
225         return DoTransformRGB565(pixelMap, dst, componentsNum);
226     } else if (pixelFormat == PixelFormat::ALPHA_8) {
227         HiLog::Debug(LABEL, "DoTransform, ALPHA_8");
228         return DoTransformGray(pixelMap, dst, componentsNum);
229     }
230 
231     HiLog::Debug(LABEL, "DoTransform OUT");
232     return false;
233 }
234 
SetEncodeConfig(Media::PixelMap & pixelMap,WebPConfig & webpConfig,WebPPicture & webpPicture)235 uint32_t WebpEncoder::SetEncodeConfig(Media::PixelMap &pixelMap, WebPConfig &webpConfig, WebPPicture &webpPicture)
236 {
237     HiLog::Debug(LABEL, "SetEncodeConfig IN");
238 
239     if (pixelMap.GetPixels() == nullptr) {
240         HiLog::Error(LABEL, "SetEncodeConfig, pixels invalid.");
241         return ERROR;
242     }
243 
244     if (!CheckEncodeFormat(pixelMap)) {
245         HiLog::Error(LABEL, "SetEncodeConfig, check invalid.");
246         return ERR_IMAGE_UNKNOWN_FORMAT;
247     }
248 
249     if (GetPixelFormat(pixelMap) == PixelFormat::RGBA_F16) {
250         componentsNum_ = COMPONENT_NUM_4;
251     } else {
252         componentsNum_ = IsOpaque(pixelMap) ? COMPONENT_NUM_3 : COMPONENT_NUM_4;
253     }
254     HiLog::Debug(LABEL, "SetEncodeConfig, componentsNum=%{public}u", componentsNum_);
255 
256     if (!WebPConfigPreset(&webpConfig, WEBP_PRESET_DEFAULT, encodeOpts_.quality)) {
257         HiLog::Error(LABEL, "SetEncodeConfig, config preset issue.");
258         return ERROR;
259     }
260 
261     GetIcc(pixelMap);
262 
263     webpConfig.lossless = 1; // Lossless encoding (0=lossy(default), 1=lossless).
264     webpConfig.method = 0; // quality/speed trade-off (0=fast, 6=slower-better)
265     webpPicture.use_argb = 1; // Main flag for encoder selecting between ARGB or YUV input.
266 
267     webpPicture.width = pixelMap.GetWidth(); // dimensions (less or equal to WEBP_MAX_DIMENSION)
268     webpPicture.height = pixelMap.GetHeight(); // dimensions (less or equal to WEBP_MAX_DIMENSION)
269     webpPicture.writer = StreamWriter;
270     webpPicture.custom_ptr = static_cast<void*>(this);
271 
272     auto colorSpace = GetColorSpace(pixelMap);
273     HiLog::Debug(LABEL, "SetEncodeConfig, "
274         "width=%{public}u, height=%{public}u, colorspace=%{public}d, componentsNum=%{public}d.",
275         webpPicture.width, webpPicture.height, colorSpace, componentsNum_);
276 
277     HiLog::Debug(LABEL, "SetEncodeConfig OUT");
278     return SUCCESS;
279 }
280 
DoEncode(Media::PixelMap & pixelMap,WebPConfig & webpConfig,WebPPicture & webpPicture)281 uint32_t WebpEncoder::DoEncode(Media::PixelMap &pixelMap, WebPConfig &webpConfig, WebPPicture &webpPicture)
282 {
283     HiLog::Debug(LABEL, "DoEncode IN");
284 
285     const int width = pixelMap.GetWidth();
286     const int height = webpPicture.height;
287     const int rgbStride = width * componentsNum_;
288     const int rgbSize = rgbStride * height;
289     HiLog::Debug(LABEL, "DoEncode, width=%{public}d, height=%{public}d, componentsNum=%{public}d,"
290         " rgbStride=%{public}d, rgbSize=%{public}d", width, height, componentsNum_, rgbStride, rgbSize);
291 
292     std::unique_ptr<uint8_t[]> rgb = std::make_unique<uint8_t[]>(rgbSize);
293     if (!DoTransform(pixelMap, reinterpret_cast<char*>(&rgb[0]), componentsNum_)) {
294         HiLog::Error(LABEL, "DoEncode, transform issue.");
295         return ERROR;
296     }
297 
298     auto importProc = WebPPictureImportRGB;
299     if (componentsNum_ != COMPONENT_NUM_3) {
300         importProc = (IsOpaque(pixelMap)) ? WebPPictureImportRGBX : WebPPictureImportRGBA;
301     }
302 
303     HiLog::Debug(LABEL, "DoEncode, importProc");
304     if (!importProc(&webpPicture, &rgb[0], rgbStride)) {
305         HiLog::Error(LABEL, "DoEncode, import issue.");
306         return ERROR;
307     }
308 
309     HiLog::Debug(LABEL, "DoEncode, WebPEncode");
310     if (!WebPEncode(&webpConfig, &webpPicture)) {
311         HiLog::Error(LABEL, "DoEncode, encode issue.");
312         return ERROR;
313     }
314 
315     HiLog::Debug(LABEL, "DoEncode, iccValid=%{public}d", iccValid_);
316     if (iccValid_) {
317         auto res = DoEncodeForICC(pixelMap);
318         if (res != SUCCESS) {
319             HiLog::Error(LABEL, "DoEncode, encode for icc issue.");
320             return res;
321         }
322     }
323 
324     HiLog::Debug(LABEL, "DoEncode OUT");
325     return SUCCESS;
326 }
327 
DoEncodeForICC(Media::PixelMap & pixelMap)328 uint32_t WebpEncoder::DoEncodeForICC(Media::PixelMap &pixelMap)
329 {
330     HiLog::Debug(LABEL, "DoEncodeForICC IN");
331 
332     auto encodedData = memoryStream_.detachAsData();
333     WebPData webpEncode = { encodedData->bytes(), encodedData->size() };
334     WebPData webpIcc = { iccBytes_, iccSize_ };
335 
336     auto mux = WebPMuxNew();
337     if (WebPMuxSetImage(mux, &webpEncode, 0) != WEBP_MUX_OK) {
338         HiLog::Error(LABEL, "DoEncodeForICC, image issue.");
339         WebPMuxDelete(mux);
340         return ERROR;
341     }
342 
343     if (WebPMuxSetChunk(mux, "ICCP", &webpIcc, 0) != WEBP_MUX_OK) {
344         HiLog::Error(LABEL, "DoEncodeForICC, icc issue.");
345         WebPMuxDelete(mux);
346         return ERROR;
347     }
348 
349     WebPData webpAssembled;
350     if (WebPMuxAssemble(mux, &webpAssembled) != WEBP_MUX_OK) {
351         HiLog::Error(LABEL, "DoEncodeForICC, assemble issue.");
352         WebPMuxDelete(mux);
353         return ERROR;
354     }
355 
356     outputStream_->Write(webpAssembled.bytes, webpAssembled.size);
357     WebPDataClear(&webpAssembled);
358     WebPMuxDelete(mux);
359 
360     HiLog::Debug(LABEL, "DoEncodeForICC OUT");
361     return SUCCESS;
362 }
363 
GetColorSpace(Media::PixelMap & pixelMap)364 ColorSpace WebpEncoder::GetColorSpace(Media::PixelMap &pixelMap)
365 {
366     return pixelMap.GetColorSpace();
367 }
368 
GetPixelFormat(Media::PixelMap & pixelMap)369 PixelFormat WebpEncoder::GetPixelFormat(Media::PixelMap &pixelMap)
370 {
371     return pixelMap.GetPixelFormat();
372 }
373 
GetAlphaType(Media::PixelMap & pixelMap)374 AlphaType WebpEncoder::GetAlphaType(Media::PixelMap &pixelMap)
375 {
376     return pixelMap.GetAlphaType();
377 }
378 
GetIcc(Media::PixelMap & pixelMap)379 bool WebpEncoder::GetIcc(Media::PixelMap &pixelMap)
380 {
381     return iccValid_;
382 }
383 
IsOpaque(Media::PixelMap & pixelMap)384 bool WebpEncoder::IsOpaque(Media::PixelMap &pixelMap)
385 {
386     return (GetAlphaType(pixelMap) == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
387 }
388 
DoTransformMemcpy(Media::PixelMap & pixelMap,char * dst,int componentsNum)389 bool WebpEncoder::DoTransformMemcpy(Media::PixelMap &pixelMap, char* dst, int componentsNum)
390 {
391     HiLog::Debug(LABEL, "DoTransformMemcpy IN");
392 
393     auto src = pixelMap.GetPixels();
394     if ((src == nullptr) || (dst == nullptr)) {
395         HiLog::Error(LABEL, "DoTransformMemcpy, address issue.");
396         return false;
397     }
398 
399     const int32_t width = pixelMap.GetWidth();
400     const int32_t height = pixelMap.GetHeight();
401     const uint32_t rowBytes = pixelMap.GetRowBytes();
402     const int stride = pixelMap.GetWidth() * componentsNum;
403 
404     HiLog::Debug(LABEL,
405         "width=%{public}u, height=%{public}u, rowBytes=%{public}u, stride=%{public}d, componentsNum=%{public}d",
406         width, height, rowBytes, stride, componentsNum);
407 
408     for (int32_t h = 0; h < height; h++) {
409         transform_scanline_memcpy(reinterpret_cast<char*>(&dst[h * stride]),
410             reinterpret_cast<const char*>(&src[h * rowBytes]),
411             width, componentsNum);
412     }
413 
414     HiLog::Debug(LABEL, "DoTransformMemcpy OUT");
415     return true;
416 }
417 
DoTransformRGBX(Media::PixelMap & pixelMap,char * dst,int componentsNum)418 bool WebpEncoder::DoTransformRGBX(Media::PixelMap &pixelMap, char* dst, int componentsNum)
419 {
420     HiLog::Debug(LABEL, "DoTransformRGBX IN");
421 
422     const void *srcPixels = pixelMap.GetPixels();
423     uint32_t srcRowBytes = pixelMap.GetRowBytes();
424     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
425         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
426 
427     void *dstPixels = dst;
428     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
429     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
430         PixelFormat::RGB_888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
431 
432     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
433 
434     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
435         HiLog::Error(LABEL, "DoTransformRGBX, address issue.");
436         return false;
437     }
438 
439     const Position dstPos;
440     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
441         dstPixels, dstPos, dstRowBytes, dstInfo)) {
442         HiLog::Error(LABEL, "DoTransformRGBX, pixel convert in adapter failed.");
443         return false;
444     }
445 
446     HiLog::Debug(LABEL, "DoTransformRGBX OUT");
447     return true;
448 }
449 
DoTransformRgbA(Media::PixelMap & pixelMap,char * dst,int componentsNum)450 bool WebpEncoder::DoTransformRgbA(Media::PixelMap &pixelMap, char* dst, int componentsNum)
451 {
452     HiLog::Debug(LABEL, "DoTransformRgbA IN");
453 
454     const void *srcPixels = pixelMap.GetPixels();
455     uint32_t srcRowBytes = pixelMap.GetRowBytes();
456     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
457         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
458 
459     void *dstPixels = dst;
460     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
461     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
462         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
463 
464     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
465 
466     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
467         HiLog::Error(LABEL, "DoTransformRgbA, address issue.");
468         return false;
469     }
470 
471     const Position dstPos;
472     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
473         dstPixels, dstPos, dstRowBytes, dstInfo)) {
474         HiLog::Error(LABEL, "DoTransformRgbA, pixel convert in adapter failed.");
475         return false;
476     }
477 
478     HiLog::Debug(LABEL, "DoTransformRgbA OUT");
479     return true;
480 }
481 
DoTransformBGRX(Media::PixelMap & pixelMap,char * dst,int componentsNum)482 bool WebpEncoder::DoTransformBGRX(Media::PixelMap &pixelMap, char* dst, int componentsNum)
483 {
484     HiLog::Debug(LABEL, "DoTransformBGRX IN");
485 
486     const void *srcPixels = pixelMap.GetPixels();
487     uint32_t srcRowBytes = pixelMap.GetRowBytes();
488     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
489         PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
490 
491     void *dstPixels = dst;
492     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
493     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
494         PixelFormat::RGB_888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
495 
496     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
497 
498     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
499         HiLog::Error(LABEL, "DoTransformBGRX, address issue.");
500         return false;
501     }
502 
503     const Position dstPos;
504     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
505         dstPixels, dstPos, dstRowBytes, dstInfo)) {
506         HiLog::Error(LABEL, "DoTransformBGRX, pixel convert in adapter failed.");
507         return false;
508     }
509 
510     HiLog::Debug(LABEL, "DoTransformBGRX OUT");
511     return true;
512 }
513 
DoTransformBGRA(Media::PixelMap & pixelMap,char * dst,int componentsNum)514 bool WebpEncoder::DoTransformBGRA(Media::PixelMap &pixelMap, char* dst, int componentsNum)
515 {
516     HiLog::Debug(LABEL, "DoTransformBGRA IN");
517 
518     const void *srcPixels = pixelMap.GetPixels();
519     uint32_t srcRowBytes = pixelMap.GetRowBytes();
520     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
521         PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
522 
523     void *dstPixels = dst;
524     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
525     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
526         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
527 
528     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
529 
530     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
531         HiLog::Error(LABEL, "DoTransformBGRA, address issue.");
532         return false;
533     }
534 
535     const Position dstPos;
536     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
537         dstPixels, dstPos, dstRowBytes, dstInfo)) {
538         HiLog::Error(LABEL, "DoTransformBGRA, pixel convert in adapter failed.");
539         return false;
540     }
541 
542     HiLog::Debug(LABEL, "DoTransformBGRA OUT");
543     return true;
544 }
545 
DoTransformBgrA(Media::PixelMap & pixelMap,char * dst,int componentsNum)546 bool WebpEncoder::DoTransformBgrA(Media::PixelMap &pixelMap, char* dst, int componentsNum)
547 {
548     HiLog::Debug(LABEL, "DoTransformBgrA IN");
549 
550     const void *srcPixels = pixelMap.GetPixels();
551     uint32_t srcRowBytes = pixelMap.GetRowBytes();
552     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
553         PixelFormat::BGRA_8888, AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
554 
555     void *dstPixels = dst;
556     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
557     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
558         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
559 
560     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
561 
562     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
563         HiLog::Error(LABEL, "DoTransformBgrA, address issue.");
564         return false;
565     }
566 
567     const Position dstPos;
568     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
569         dstPixels, dstPos, dstRowBytes, dstInfo)) {
570         HiLog::Error(LABEL, "DoTransformBgrA, pixel convert in adapter failed.");
571         return false;
572     }
573 
574     HiLog::Debug(LABEL, "DoTransformBgrA OUT");
575     return true;
576 }
577 
DoTransformF16To8888(Media::PixelMap & pixelMap,char * dst,int componentsNum)578 bool WebpEncoder::DoTransformF16To8888(Media::PixelMap &pixelMap, char* dst, int componentsNum)
579 {
580     HiLog::Debug(LABEL, "DoTransformF16To8888 IN");
581 
582     const void *srcPixels = pixelMap.GetPixels();
583     uint32_t srcRowBytes = pixelMap.GetRowBytes();
584     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
585         PixelFormat::RGBA_F16, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
586 
587     void *dstPixels = dst;
588     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
589     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
590         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
591 
592     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
593 
594     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
595         HiLog::Error(LABEL, "DoTransformF16To8888, address issue.");
596         return false;
597     }
598 
599     const Position dstPos;
600     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
601         dstPixels, dstPos, dstRowBytes, dstInfo)) {
602         HiLog::Error(LABEL, "DoTransformF16To8888, pixel convert in adapter failed.");
603         return false;
604     }
605 
606     HiLog::Debug(LABEL, "DoTransformF16To8888 OUT");
607     return true;
608 }
609 
DoTransformF16pTo8888(Media::PixelMap & pixelMap,char * dst,int componentsNum)610 bool WebpEncoder::DoTransformF16pTo8888(Media::PixelMap &pixelMap, char* dst, int componentsNum)
611 {
612     HiLog::Debug(LABEL, "DoTransformF16pTo8888 IN");
613 
614     const void *srcPixels = pixelMap.GetPixels();
615     uint32_t srcRowBytes = pixelMap.GetRowBytes();
616     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
617         PixelFormat::RGBA_F16, AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
618 
619     void *dstPixels = dst;
620     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
621     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
622         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
623 
624     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
625 
626     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
627         HiLog::Error(LABEL, "DoTransformF16pTo8888, address issue.");
628         return false;
629     }
630 
631     const Position dstPos;
632     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
633         dstPixels, dstPos, dstRowBytes, dstInfo)) {
634         HiLog::Error(LABEL, "DoTransformF16pTo8888, pixel convert in adapter failed.");
635         return false;
636     }
637 
638     HiLog::Debug(LABEL, "DoTransformF16pTo8888 OUT");
639     return true;
640 }
641 
DoTransformArgbToRgb(Media::PixelMap & pixelMap,char * dst,int componentsNum)642 bool WebpEncoder::DoTransformArgbToRgb(Media::PixelMap &pixelMap, char* dst, int componentsNum)
643 {
644     HiLog::Debug(LABEL, "DoTransformArgbToRgb IN");
645 
646     const void *srcPixels = pixelMap.GetPixels();
647     uint32_t srcRowBytes = pixelMap.GetRowBytes();
648     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
649         PixelFormat::ARGB_8888, AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
650 
651     void *dstPixels = dst;
652     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
653     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
654         PixelFormat::RGB_888, AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
655 
656     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
657 
658     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
659         HiLog::Error(LABEL, "DoTransformArgbToRgb, address issue.");
660         return false;
661     }
662 
663     const Position dstPos;
664     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
665         dstPixels, dstPos, dstRowBytes, dstInfo)) {
666         HiLog::Error(LABEL, "DoTransformArgbToRgb, pixel convert in adapter failed.");
667         return false;
668     }
669 
670     HiLog::Debug(LABEL, "DoTransformArgbToRgb OUT");
671     return true;
672 }
673 
DoTransformArgbToRgba(Media::PixelMap & pixelMap,char * dst,int componentsNum)674 bool WebpEncoder::DoTransformArgbToRgba(Media::PixelMap &pixelMap, char* dst, int componentsNum)
675 {
676     HiLog::Debug(LABEL, "DoTransformArgbToRgba IN");
677 
678     const void *srcPixels = pixelMap.GetPixels();
679     uint32_t srcRowBytes = pixelMap.GetRowBytes();
680     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
681         PixelFormat::ARGB_8888, pixelMap.GetAlphaType());
682 
683     void *dstPixels = dst;
684     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
685     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
686         PixelFormat::RGBA_8888, pixelMap.GetAlphaType());
687 
688     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
689 
690     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
691         HiLog::Error(LABEL, "DoTransformArgbToRgba, address issue.");
692         return false;
693     }
694 
695     const Position dstPos;
696     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
697         dstPixels, dstPos, dstRowBytes, dstInfo)) {
698         HiLog::Error(LABEL, "DoTransformArgbToRgba, pixel convert in adapter failed.");
699         return false;
700     }
701 
702     HiLog::Debug(LABEL, "DoTransformArgbToRgba OUT");
703     return true;
704 }
705 
DoTransformRGB565(Media::PixelMap & pixelMap,char * dst,int componentsNum)706 bool WebpEncoder::DoTransformRGB565(Media::PixelMap &pixelMap, char* dst, int componentsNum)
707 {
708     HiLog::Debug(LABEL, "DoTransformRGB565 IN");
709 
710     const void *srcPixels = pixelMap.GetPixels();
711     uint32_t srcRowBytes = pixelMap.GetRowBytes();
712     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
713         PixelFormat::RGB_565, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
714 
715     void *dstPixels = dst;
716     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
717     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
718         PixelFormat::RGB_888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
719 
720     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
721 
722     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
723         HiLog::Error(LABEL, "DoTransformRGB565, address issue.");
724         return false;
725     }
726 
727     const Position dstPos;
728     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
729         dstPixels, dstPos, dstRowBytes, dstInfo)) {
730         HiLog::Error(LABEL, "DoTransformRGB565, pixel convert in adapter failed.");
731         return false;
732     }
733 
734     HiLog::Debug(LABEL, "DoTransformRGB565 OUT");
735     return true;
736 }
737 
DoTransformGray(Media::PixelMap & pixelMap,char * dst,int componentsNum)738 bool WebpEncoder::DoTransformGray(Media::PixelMap &pixelMap, char* dst, int componentsNum)
739 {
740     HiLog::Debug(LABEL, "DoTransformGray IN");
741 
742     const void *srcPixels = pixelMap.GetPixels();
743     uint32_t srcRowBytes = pixelMap.GetRowBytes();
744     const ImageInfo srcInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
745         PixelFormat::ALPHA_8, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
746 
747     void *dstPixels = dst;
748     uint32_t dstRowBytes = pixelMap.GetWidth() * componentsNum;
749     const ImageInfo dstInfo = MakeImageInfo(pixelMap.GetWidth(), pixelMap.GetHeight(),
750         PixelFormat::RGBA_8888, AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
751 
752     ShowTransformParam(srcInfo, srcRowBytes, dstInfo, dstRowBytes, componentsNum);
753 
754     if ((srcPixels == nullptr) || (dstPixels == nullptr)) {
755         HiLog::Error(LABEL, "DoTransformGray, address issue.");
756         return false;
757     }
758 
759     const Position dstPos;
760     if (!PixelConvertAdapter::WritePixelsConvert(srcPixels, srcRowBytes, srcInfo,
761         dstPixels, dstPos, dstRowBytes, dstInfo)) {
762         HiLog::Error(LABEL, "DoTransformGray, pixel convert in adapter failed.");
763         return false;
764     }
765 
766     HiLog::Debug(LABEL, "DoTransformGray OUT");
767     return true;
768 }
769 
MakeImageInfo(int width,int height,PixelFormat pf,AlphaType at,ColorSpace cs)770 ImageInfo WebpEncoder::MakeImageInfo(int width, int height, PixelFormat pf, AlphaType at, ColorSpace cs)
771 {
772     ImageInfo info = {
773         .size = {
774             .width = width,
775             .height = height
776         },
777         .pixelFormat = pf,
778         .colorSpace = cs,
779         .alphaType = at
780     };
781 
782     return info;
783 }
784 
ShowTransformParam(const ImageInfo & srcInfo,const uint32_t & srcRowBytes,const ImageInfo & dstInfo,const uint32_t & dstRowBytes,const int & componentsNum)785 void WebpEncoder::ShowTransformParam(const ImageInfo &srcInfo, const uint32_t &srcRowBytes,
786     const ImageInfo &dstInfo, const uint32_t &dstRowBytes, const int &componentsNum)
787 {
788     HiLog::Debug(LABEL,
789         "src(width=%{public}u, height=%{public}u, rowBytes=%{public}u,"
790         " pixelFormat=%{public}u, colorspace=%{public}d, alphaType=%{public}d, baseDensity=%{public}d), "
791         "dst(width=%{public}u, height=%{public}u, rowBytes=%{public}u,"
792         " pixelFormat=%{public}u, colorspace=%{public}d, alphaType=%{public}d, baseDensity=%{public}d), "
793         "componentsNum=%{public}d",
794         srcInfo.size.width, srcInfo.size.height, srcRowBytes,
795         srcInfo.pixelFormat, srcInfo.colorSpace, srcInfo.alphaType, srcInfo.baseDensity,
796         dstInfo.size.width, dstInfo.size.height, dstRowBytes,
797         dstInfo.pixelFormat, dstInfo.colorSpace, dstInfo.alphaType, dstInfo.baseDensity,
798         componentsNum);
799 }
800 } // namespace ImagePlugin
801 } // namespace OHOS
802