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