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