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