1 /*
2 * Copyright (c) 2022 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 <cstdio>
16 #include <cmath>
17 #include <unistd.h>
18
19 #include "image_compress.h"
20
21 #include "png.h"
22 #include "jpeglib.h"
23 #include "app_log_wrapper.h"
24 #include "securec.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 constexpr int32_t RGBA_COMPONENTS = 4;
30 constexpr int32_t RGB_COMPONENTS = 3;
31 constexpr int32_t FILE_MAX_SIZE = 10240;
32 constexpr int32_t FILE_COMPRESS_SIZE = 4196;
33 constexpr int32_t BITDEPTH_SIXTHEN = 16;
34 constexpr int32_t BITDEPTH_EIGHT = 8;
35 constexpr int32_t COLOR_CHANNEL_GREEN = 1;
36 constexpr int32_t COLOR_CHANNEL_BLUE = 2;
37 constexpr int32_t COLOR_CHANNEL_ALPHA = 3;
38 constexpr int32_t NUMBER_ONE = 1;
39 constexpr int32_t QUALITY = 30;
40 constexpr double EPSILON = 1e-5;
41 const std::string JPG = "jpg";
42 const std::string PNG = "png";
43 const std::string JPEG = "jpeg";
44 const std::string BUNDLE_PATH = "/data/app/el1/bundle";
45 struct EncodeMemo {
46 ImageRow buffer;
47 uint32_t size;
48 };
49 }
50
ReleasePngPointer(png_bytepp & rowPointers,uint32_t height)51 void ImageCompress::ReleasePngPointer(png_bytepp& rowPointers, uint32_t height)
52 {
53 if (rowPointers != nullptr) {
54 for (uint32_t i = 0; i < height; ++i) {
55 if (rowPointers[i] != nullptr) {
56 free(rowPointers[i]);
57 }
58 }
59 free(rowPointers);
60 }
61 rowPointers = nullptr;
62 }
63
MallocPngPointer(png_bytepp & rowPointers,uint32_t height,uint32_t strides)64 bool ImageCompress::MallocPngPointer(png_bytepp& rowPointers, uint32_t height, uint32_t strides)
65 {
66 if (rowPointers != nullptr || height == 0 || strides == 0) {
67 return false;
68 }
69 rowPointers = (png_bytep*)malloc(sizeof(png_bytep) * height);
70 if (rowPointers == nullptr) {
71 APP_LOGE("ImageCompress: MallocPngPointer malloc buffer failed");
72 return false;
73 }
74 for (uint32_t h = 0; h < height; ++h) {
75 rowPointers[h] = (png_byte*)malloc(strides);
76 if (rowPointers[h] == nullptr) {
77 return false;
78 }
79 }
80 return true;
81 }
82
IsPathValid(std::string & fileName)83 bool ImageCompress::IsPathValid(std::string& fileName)
84 {
85 if (fileName.find(BUNDLE_PATH) != std::string::npos) {
86 return access(fileName.c_str(), F_OK) == 0;
87 } else {
88 return false;
89 }
90 }
91
CalRatio(std::string fileName)92 double ImageCompress::CalRatio(std::string fileName)
93 {
94 if (!IsPathValid(fileName)) {
95 APP_LOGE("%{public}s is unavailable", fileName.c_str());
96 return -1.0;
97 }
98 FILE* file = fopen(fileName.c_str(), "rb");
99 if (!file) {
100 APP_LOGE("ImageCompress: CalRatio %{public}s is unavailable", fileName.c_str());
101 return -1.0;
102 }
103 if (fseek(file, 0L, SEEK_END) != 0) {
104 fclose(file);
105 return -1.0;
106 }
107 int32_t fileSize = ftell(file);
108 if (fileSize < FILE_MAX_SIZE) {
109 APP_LOGE("ImageCompress: CalRatio do not need compress");
110 fclose(file);
111 return -1.0;
112 }
113 if (fclose(file) != 0) {
114 return -1.0;
115 }
116 return sqrt(static_cast<double>(FILE_COMPRESS_SIZE) / fileSize);
117 }
118
NeedCompress(std::string fileName)119 bool ImageCompress::NeedCompress(std::string fileName)
120 {
121 if (!IsPathValid(fileName)) {
122 APP_LOGE("%{public}s is unavailable", fileName.c_str());
123 return false;
124 }
125 FILE* file = fopen(fileName.c_str(), "rb");
126 if (!file) {
127 APP_LOGE("ImageCompress: NeedCompress file %{public}s is unavailable", fileName.c_str());
128 return false;
129 }
130 if (fseek(file, 0L, SEEK_END) != 0) {
131 fclose(file);
132 return false;
133 }
134 int32_t fileSize = ftell(file);
135 if (fileSize < FILE_MAX_SIZE) {
136 APP_LOGE("ImageCompress: CalRatio do not need compress");
137 fclose(file);
138 return false;
139 }
140 if (fclose(file) != 0) {
141 return false;
142 }
143 return true;
144 }
145
PngToBuffer(png_structp png,png_bytep data,png_size_t length)146 void ImageCompress::PngToBuffer(png_structp png, png_bytep data, png_size_t length)
147 {
148 struct EncodeMemo *p = (struct EncodeMemo*)png_get_io_ptr(png);
149 if (memcpy_s(p->buffer + p->size, length, data, length) != EOK) {
150 APP_LOGE("ImageCompress: memcpy_s buffer failed");
151 return;
152 }
153 p->size += length;
154 }
155
DoubleEqual(double left,double right)156 bool ImageCompress::DoubleEqual(double left, double right)
157 {
158 return std::abs(left - right ) <= EPSILON;
159 }
160
InitPngFile(std::shared_ptr<ImageBuffer> & imageBuffer,png_structp & png,png_infop & info)161 bool ImageCompress::InitPngFile(std::shared_ptr<ImageBuffer>& imageBuffer,
162 png_structp& png, png_infop& info)
163 {
164 imageBuffer->SetWidth(png_get_image_width(png, info));
165 imageBuffer->SetHeight(png_get_image_height(png, info));
166 imageBuffer->SetColorType(png_get_color_type(png, info));
167 imageBuffer->SetBitDepth(png_get_bit_depth(png, info));
168 imageBuffer->SetPngComponents(png_get_channels(png, info));
169 if (imageBuffer->GetBitDepth() == BITDEPTH_SIXTHEN) {
170 png_set_strip_16(png);
171 }
172 if (imageBuffer->GetColorType() == PNG_COLOR_TYPE_PALETTE) {
173 png_set_palette_to_rgb(png);
174 }
175 if (png_get_valid(png, info, PNG_INFO_tRNS)) {
176 png_set_tRNS_to_alpha(png);
177 }
178 if (imageBuffer->GetColorType() == PNG_COLOR_TYPE_RGB ||
179 imageBuffer->GetColorType() == PNG_COLOR_TYPE_GRAY ||
180 imageBuffer->GetColorType() == PNG_COLOR_TYPE_PALETTE) {
181 png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
182 }
183 if (imageBuffer->GetColorType() == PNG_COLOR_TYPE_GRAY ||
184 imageBuffer->GetColorType() == PNG_COLOR_TYPE_GRAY_ALPHA) {
185 png_set_gray_to_rgb(png);
186 }
187 png_read_update_info(png, info);
188 if (imageBuffer->GetImageDataPointer()) {
189 png_destroy_read_struct(&png, &info, NULL);
190 return false;
191 }
192
193 imageBuffer->MallocImageMap(RGBA_COMPONENTS);
194 imageBuffer->SetComponents(RGBA_COMPONENTS);
195 uint32_t strides = imageBuffer->GetWidth() * RGBA_COMPONENTS;
196 png_bytepp rowPointers = nullptr;
197 if (!MallocPngPointer(rowPointers, imageBuffer->GetHeight(), strides)) {
198 APP_LOGE("ImageCompress: MallocPngPointer image buffer failed");
199 return false;
200 }
201 png_read_image(png, rowPointers);
202 ImageRow imageRow = imageBuffer->GetImageDataPointer().get();
203 if (rowPointers == nullptr) {
204 return false;
205 }
206 for (uint32_t h = 0; h < imageBuffer->GetHeight(); ++h) {
207 if (memcpy_s(imageRow, strides, rowPointers[h], strides) != EOK) {
208 ReleasePngPointer(rowPointers, imageBuffer->GetHeight());
209 png_destroy_read_struct(&png, &info, NULL);
210 return false;
211 }
212 imageRow += strides;
213 }
214 ReleasePngPointer(rowPointers, imageBuffer->GetHeight());
215 return true;
216 }
217
DecodePngFile(std::string fileName,std::shared_ptr<ImageBuffer> & imageBuffer)218 int ImageCompress::DecodePngFile(std::string fileName, std::shared_ptr<ImageBuffer>& imageBuffer)
219 {
220 if (imageBuffer == nullptr) {
221 APP_LOGE("ImageCompress: DecodePngFile image buffer is unavailable");
222 return -1;
223 }
224 if (!IsPathValid(fileName)) {
225 APP_LOGE("%{public}s is unavailable", fileName.c_str());
226 return -1.0;
227 }
228 double ratio = CalRatio(fileName);
229 if (ratio < 0) {
230 APP_LOGE("ImageCompress: DecodePngFile file %{public}s do not need compress", fileName.c_str());
231 return -1;
232 }
233
234 FILE* inFile = fopen(fileName.c_str(), "rb");
235 if (inFile == nullptr) {
236 APP_LOGE("open file %{private}s failed", fileName.c_str());
237 return -1;
238 }
239 imageBuffer->SetRatio(ratio);
240 png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
241 if (!png) {
242 fclose(inFile);
243 return -1;
244 }
245
246 png_infop info = png_create_info_struct(png);
247 if (!info) {
248 fclose(inFile);
249 return -1;
250 }
251
252 if (setjmp(png_jmpbuf(png))) {
253 fclose(inFile);
254 return -1;
255 }
256
257 png_init_io(png, inFile);
258 png_read_info(png, info);
259
260 if (!InitPngFile(imageBuffer, png, info)) {
261 if (fclose(inFile) != EOK) {
262 APP_LOGE("ImageCompress: fclose file %{public}s error", fileName.c_str());
263 return -1;
264 }
265 png_destroy_read_struct(&png, &info, NULL);
266 return -1;
267 }
268
269 if (fclose(inFile) != EOK) {
270 APP_LOGE("ImageCompress: fclose file %{public}s error", fileName.c_str());
271 return -1;
272 }
273 png_destroy_read_struct(&png, &info, NULL);
274 return 0;
275 }
276
EncodePngFile(std::shared_ptr<ImageBuffer> & imageBuffer)277 int32_t ImageCompress::EncodePngFile(std::shared_ptr<ImageBuffer>& imageBuffer)
278 {
279 if (imageBuffer == nullptr) {
280 APP_LOGE("ImageCompress: Encode none data");
281 return -1;
282 }
283
284 png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
285 if (!png) {
286 return -1;
287 }
288
289 png_infop info = png_create_info_struct(png);
290 if (!info) {
291 return -1;
292 }
293 if (setjmp(png_jmpbuf(png))) {
294 return -1;
295 }
296 png_set_IHDR(
297 png,
298 info,
299 imageBuffer->GetWidth(),
300 imageBuffer->GetHeight(),
301 BITDEPTH_EIGHT,
302 PNG_COLOR_TYPE_RGBA,
303 PNG_INTERLACE_NONE,
304 PNG_COMPRESSION_TYPE_DEFAULT,
305 PNG_FILTER_TYPE_DEFAULT
306 );
307 uint32_t strides = imageBuffer->GetWidth() * RGBA_COMPONENTS;
308 struct EncodeMemo memo;
309 memo.buffer = (ImageRow)malloc(FILE_MAX_SIZE * RGBA_COMPONENTS);
310 if (memo.buffer == nullptr) {
311 return -1;
312 }
313 memo.size = 0;
314 if (!imageBuffer->GetImageDataPointer()) {
315 free(memo.buffer);
316 APP_LOGE("ImageCompress: EncodePngFile should input image buffer");
317 return -1;
318 }
319 ImageRow imageRow = imageBuffer->GetImageDataPointer().get();
320 png_bytep* rowPointers;
321 rowPointers = (png_bytep*)malloc(sizeof(png_bytep) * imageBuffer->GetHeight());
322 if (rowPointers == nullptr) {
323 APP_LOGE("ImageCompress: malloc failed");
324 free(memo.buffer);
325 return -1;
326 }
327 for (uint32_t h = 0; h < imageBuffer->GetHeight(); ++h) {
328 rowPointers[h] = (png_byte*)malloc(strides);
329 }
330 for (uint32_t h = 0; h < imageBuffer->GetHeight(); ++h) {
331 memcpy_s(rowPointers[h], strides, imageRow, strides);
332 imageRow += strides;
333 }
334 png_set_rows(png, info, &rowPointers[0]);
335 png_set_write_fn(png, &memo, PngToBuffer, NULL);
336 png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
337 png_destroy_write_struct(&png, &info);
338 imageBuffer->SetCompressData(memo.buffer, memo.size);
339 imageBuffer->SetCompressSize(memo.size);
340 if (memo.buffer) {
341 free(memo.buffer);
342 }
343 memo.buffer = nullptr;
344 ReleasePngPointer(rowPointers, imageBuffer->GetHeight());
345 return 0;
346 }
347
ResizeRGBAImage(std::shared_ptr<ImageBuffer> & imageBufferIn,std::shared_ptr<ImageBuffer> & imageBufferOut)348 int32_t ImageCompress::ResizeRGBAImage(std::shared_ptr<ImageBuffer>& imageBufferIn,
349 std::shared_ptr<ImageBuffer>& imageBufferOut)
350 {
351 if (imageBufferIn == nullptr || imageBufferOut == nullptr) {
352 APP_LOGE("ImageCompress: ResizePRGBAImage should input image buffer");
353 return -1;
354 }
355 double ratio = imageBufferIn->GetRatio();
356 ratio = ratio * (static_cast<double>(imageBufferIn->GetPngComponents()) / RGBA_COMPONENTS) ;
357 if (DoubleEqual(ratio, 0.0)) {
358 return -1;
359 }
360 imageBufferOut->SetWidth(imageBufferIn->GetWidth() * ratio);
361 imageBufferOut->SetHeight(imageBufferIn->GetHeight() * ratio);
362 imageBufferOut->SetComponents(imageBufferIn->GetComponents());
363 imageBufferOut->SetColorType(imageBufferIn->GetColorType());
364 imageBufferOut->SetBitDepth(imageBufferIn->GetBitDepth());
365 imageBufferOut->MallocImageMap(imageBufferOut->GetComponents());
366 ImageRow imageRowIn = imageBufferIn->GetImageDataPointer().get();
367 ImageRow imageRowOut = imageBufferOut->GetImageDataPointer().get();
368 uint32_t outRowStride = imageBufferOut->GetWidth() * imageBufferOut->GetComponents();
369 uint32_t inRowStride = imageBufferIn->GetWidth() * imageBufferIn->GetComponents();
370 uint32_t components = imageBufferIn->GetComponents();
371 for (uint32_t h = 0; h < imageBufferOut->GetHeight(); ++h) {
372 for (uint32_t w = 0; w < imageBufferOut->GetWidth(); ++w) {
373 uint64_t heightIndex = std::round(h / ratio);
374 uint64_t widthIndex = std::round(w / ratio);
375 if (heightIndex > imageBufferIn->GetHeight()) {
376 heightIndex = imageBufferIn->GetHeight() == 0 ? 0 : imageBufferIn->GetHeight() - 1;
377 }
378 if (widthIndex > imageBufferIn->GetWidth()) {
379 widthIndex = imageBufferIn->GetWidth() == 0 ? 0 : imageBufferIn->GetWidth() - 1;
380 }
381 imageRowOut[h * outRowStride + w * components] =
382 imageRowIn[heightIndex * inRowStride + widthIndex * components];
383 imageRowOut[h * outRowStride + w * components + COLOR_CHANNEL_GREEN] =
384 imageRowIn[heightIndex * inRowStride + widthIndex * components + COLOR_CHANNEL_GREEN];
385 imageRowOut[h * outRowStride + w * components + COLOR_CHANNEL_BLUE] =
386 imageRowIn[heightIndex * inRowStride + widthIndex * components + COLOR_CHANNEL_BLUE];
387 imageRowOut[h * outRowStride + w * components + COLOR_CHANNEL_ALPHA] =
388 imageRowIn[heightIndex * inRowStride + widthIndex * components + COLOR_CHANNEL_ALPHA];
389 }
390 }
391 return 0;
392 }
393
DecodeJPGFile(std::string fileName,std::shared_ptr<ImageBuffer> & imageBuffer)394 int32_t ImageCompress::DecodeJPGFile(std::string fileName, std::shared_ptr<ImageBuffer>& imageBuffer)
395 {
396 if (imageBuffer == nullptr) {
397 APP_LOGE("ImageCompress: DecodeJPGFile imageBuffer is unavailable");
398 return -1;
399 }
400 if (!IsPathValid(fileName)) {
401 APP_LOGE("%{public}s is unavailable", fileName.c_str());
402 return -1.0;
403 }
404 double ratio = CalRatio(fileName);
405 if (ratio < 0) {
406 APP_LOGE("ImageCompress: DecodePngFile file %{public}s do not need compress", fileName.c_str());
407 return -1;
408 }
409 struct jpeg_decompress_struct cinfo;
410 struct jpeg_error_mgr jerr;
411 cinfo.err = jpeg_std_error(&jerr);
412 FILE* inFile = fopen(fileName.c_str(), "rb");
413 if (!inFile) {
414 APP_LOGE("ImageCompress: DecodeJPGFile file %{public}s is unavailable", fileName.c_str());
415 return -1;
416 }
417
418 imageBuffer->SetRatio(ratio);
419 jpeg_create_decompress(&cinfo);
420 jpeg_stdio_src(&cinfo, inFile);
421 jpeg_read_header(&cinfo, TRUE);
422 cinfo.out_color_space = JCS_RGB;
423 jpeg_start_decompress(&cinfo);
424 imageBuffer->SetWidth(cinfo.output_width);
425 imageBuffer->SetHeight(cinfo.output_height);
426 imageBuffer->SetComponents(RGB_COMPONENTS);
427 imageBuffer->MallocImageMap(RGB_COMPONENTS);
428
429 ImageRow imageRow = imageBuffer->GetImageDataPointer().get();
430 uint32_t row_stride = cinfo.output_width * cinfo.output_components;
431 JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, NUMBER_ONE);
432 while (cinfo.output_scanline < cinfo.image_height) {
433 jpeg_read_scanlines(&cinfo, buffer, NUMBER_ONE);
434 if (memcpy_s(imageRow, row_stride, *buffer, row_stride) != EOK) {
435 APP_LOGE("ImageCompress: memcpy_s buffer failed");
436 fclose(inFile);
437 return -1;
438 }
439 imageRow += row_stride;
440 }
441 jpeg_finish_decompress(&cinfo);
442 jpeg_destroy_decompress(&cinfo);
443 if (fclose(inFile) != 0) {
444 return -1;
445 }
446 return 0;
447 }
448
EncodeJPGFile(std::shared_ptr<ImageBuffer> & imageBuffer)449 int32_t ImageCompress::EncodeJPGFile(std::shared_ptr<ImageBuffer>& imageBuffer)
450 {
451
452 if (imageBuffer == nullptr) {
453 APP_LOGE("ImageCompress: EncodeJPGFile should read image buffer first");
454 return -1;
455 }
456
457 struct jpeg_compress_struct cinfo;
458 struct jpeg_error_mgr jerr;
459 cinfo.err = jpeg_std_error(&jerr);
460 jpeg_create_compress(&cinfo);
461 unsigned char* outBuffer = nullptr;
462 int32_t compressSize = 0;
463 jpeg_mem_dest(&cinfo, &outBuffer, reinterpret_cast<size_t *>(&compressSize));
464 cinfo.image_width = imageBuffer->GetWidth();
465 cinfo.image_height = imageBuffer->GetHeight();
466 cinfo.input_components = RGB_COMPONENTS;
467 cinfo.in_color_space = JCS_RGB;
468 jpeg_set_defaults(&cinfo);
469 jpeg_set_quality(&cinfo, QUALITY, TRUE);
470 jpeg_start_compress(&cinfo, TRUE);
471 uint32_t rowStride = imageBuffer->GetWidth() * imageBuffer->GetComponents();
472 ImageRow imageRow = imageBuffer->GetImageDataPointer().get();
473 JSAMPROW rowdata[1];
474 while (cinfo.next_scanline < static_cast<unsigned int>(imageBuffer->GetHeight())) {
475 rowdata[0] = &imageRow[cinfo.next_scanline * rowStride];
476 (void)jpeg_write_scanlines(&cinfo, rowdata, 1);
477 }
478 jpeg_finish_compress(&cinfo);
479 jpeg_destroy_compress(&cinfo);
480 imageBuffer->SetCompressSize(compressSize);
481 imageBuffer->SetCompressData(outBuffer, compressSize);
482 free(outBuffer);
483 outBuffer = nullptr;
484 return 0;
485 }
486
ResizeRGBImage(std::shared_ptr<ImageBuffer> & imageBufferIn,std::shared_ptr<ImageBuffer> & imageBufferOut)487 int32_t ImageCompress::ResizeRGBImage(std::shared_ptr<ImageBuffer>& imageBufferIn,
488 std::shared_ptr<ImageBuffer>& imageBufferOut)
489 {
490 if (imageBufferIn == nullptr || imageBufferOut == nullptr) {
491 APP_LOGE("ImageCompress: ResizePRGBAImage should input image buffer");
492 return -1;
493 }
494 double ratio = imageBufferIn->GetRatio();
495 if (DoubleEqual(ratio, 0.0)) {
496 return -1;
497 }
498 imageBufferOut->SetWidth(imageBufferIn->GetWidth() * ratio);
499 imageBufferOut->SetHeight(imageBufferIn->GetHeight() * ratio);
500 imageBufferOut->SetComponents(imageBufferIn->GetComponents());
501 imageBufferOut->SetColorType(imageBufferIn->GetColorType());
502 imageBufferOut->SetBitDepth(imageBufferIn->GetBitDepth());
503 imageBufferOut->MallocImageMap(imageBufferOut->GetComponents());
504 ImageRow imageRowIn = imageBufferIn->GetImageDataPointer().get();
505 ImageRow imageRowOut = imageBufferOut->GetImageDataPointer().get();
506 uint32_t outRowStride = imageBufferOut->GetWidth() * imageBufferOut->GetComponents();
507 uint32_t inRowStride = imageBufferIn->GetWidth() * imageBufferIn->GetComponents();
508 uint32_t components = imageBufferIn->GetComponents();
509 for (uint32_t h = 0; h < imageBufferOut->GetHeight(); ++h) {
510 for (uint32_t w = 0; w < imageBufferOut->GetWidth(); ++w) {
511 uint64_t heightIndex = std::round(h / ratio);
512 uint64_t widthIndex = std::round(w / ratio);
513 if (heightIndex > imageBufferIn->GetHeight()) {
514 heightIndex = imageBufferIn->GetHeight() == 0 ? 0 : imageBufferIn->GetHeight() - 1;
515 }
516 if (widthIndex > imageBufferIn->GetWidth()) {
517 widthIndex = imageBufferIn->GetWidth() == 0 ? 0 : imageBufferIn->GetWidth() - 1;
518 }
519 imageRowOut[h * outRowStride + w * components] =
520 imageRowIn[heightIndex * inRowStride + widthIndex * components];
521 imageRowOut[h * outRowStride + w * components + COLOR_CHANNEL_GREEN] =
522 imageRowIn[heightIndex * inRowStride + widthIndex * components + COLOR_CHANNEL_GREEN];
523 imageRowOut[h * outRowStride + w * components + COLOR_CHANNEL_BLUE] =
524 imageRowIn[heightIndex * inRowStride + widthIndex * components + COLOR_CHANNEL_BLUE];
525 }
526 }
527 return 0;
528 }
529
CompressImage(std::string inFileName)530 std::shared_ptr<ImageBuffer> ImageCompress::CompressImage(std::string inFileName)
531 {
532 std::string inFileSuffix = inFileName.substr(inFileName.find_last_of('.') + 1);
533 if (inFileSuffix.compare(PNG) != 0 && inFileSuffix.compare(JPG) != 0 && inFileSuffix.compare(JPEG) != 0) {
534 return nullptr;
535 }
536 std::shared_ptr<ImageBuffer> imageBufferIn = std::make_shared<ImageBuffer>();
537 std::shared_ptr<ImageBuffer> imageBufferOut = std::make_shared<ImageBuffer>();
538 if (inFileSuffix.compare("png") == 0 || inFileSuffix.compare("PNG") == 0) {
539 imageBufferIn->SetImageType(PNG);
540 imageBufferOut->SetImageType(PNG);
541 if (DecodePngFile(inFileName, imageBufferIn) != 0) {
542 APP_LOGE("ImageCompress: DecodePngFile decode png file error");
543 return nullptr;
544 }
545 if (ResizeRGBAImage(imageBufferIn, imageBufferOut) != 0) {
546 APP_LOGE("ImageCompress: DecodePngFile resize png file error");
547 return nullptr;
548 }
549 if (EncodePngFile(imageBufferOut) != 0) {
550 return nullptr;
551 }
552 } else if (inFileSuffix.compare(JPG) == 0 || inFileSuffix.compare(JPEG) == 0) {
553 imageBufferIn->SetImageType(JPG);
554 imageBufferOut->SetImageType(JPG);
555 if (DecodeJPGFile(inFileName, imageBufferIn) != 0) {
556 APP_LOGE("ImageCompress: DecodeJPGFile decode jpeg file error");
557 return nullptr;
558 }
559 if (ResizeRGBImage(imageBufferIn, imageBufferOut) != 0) {
560 APP_LOGE("ImageCompress: ResizeRGBImage resize jpeg file error");
561 return nullptr;
562 }
563 if (EncodeJPGFile(imageBufferOut) != 0) {
564 APP_LOGE("ImageCompress: EncodeJPGFile jpeg file error");
565 return nullptr;
566 }
567 } else {
568 APP_LOGE("ImageCompress: input wrong image format");
569 return nullptr;
570 }
571 return imageBufferOut;
572 }
573 }
574 }