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