• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "picture_utils.h"
17 
18 #include <fstream>
19 #include <iostream>
20 
21 #include "ic_retcode.h"
22 #include "resize_computer.h"
23 #include "securec.h"
24 
25 using namespace std;
26 
27 namespace IC {
WriteJpegFile(const string & filename,int quality,uint8_t * srcBuffer,int srcWidth,int srcHeight)28 int WriteJpegFile(const string &filename, int quality,
29     uint8_t *srcBuffer, int srcWidth, int srcHeight)
30 {
31     struct jpeg_compress_struct cinfo;
32     struct jpeg_error_mgr jerr;
33     JSAMPROW rowPointer[1];
34     int rowStride = 0;
35     cinfo.err = jpeg_std_error(&jerr);
36     jpeg_create_compress(&cinfo);
37     if (srcBuffer == nullptr) {
38         printf("WriteJpegFile: srcBuffer is nullptr\n");
39         return IC_RETCODE_FAILURE;
40     }
41     FILE *outfile;
42     if ((outfile = fopen(filename.c_str(), "wb")) == nullptr) {
43         printf("WriteJpegFile: can't open %s\n", filename.c_str());
44         return IC_RETCODE_FAILURE;
45     }
46     jpeg_stdio_dest(&cinfo, outfile);
47     cinfo.image_width = srcWidth;
48     cinfo.image_height = srcHeight;
49     cinfo.input_components = NUM_CHANNELS;
50     cinfo.in_color_space = JCS_RGB;
51     jpeg_set_defaults(&cinfo);
52     jpeg_set_quality(&cinfo, quality, TRUE);
53     jpeg_start_compress(&cinfo, TRUE);
54     rowStride = srcWidth * NUM_CHANNELS;
55 
56     while (cinfo.next_scanline < cinfo.image_height) {
57         rowPointer[0] = &srcBuffer[cinfo.next_scanline * rowStride];
58         (void)jpeg_write_scanlines(&cinfo, rowPointer, 1);
59     }
60     jpeg_finish_compress(&cinfo);
61 
62     fclose(outfile);
63     jpeg_destroy_compress(&cinfo);
64     return IC_RETCODE_SUCCESS;
65 }
66 
WriteBgrFile(const string & filename,uint8_t * dataBuffer,int bufferSize)67 int WriteBgrFile(const string &filename, uint8_t *dataBuffer, int bufferSize)
68 {
69     if (dataBuffer == nullptr || bufferSize <= 0) {
70         printf("WriteBgrFile: dataBuffer is nullptr.\n");
71         return IC_RETCODE_FAILURE;
72     }
73     ofstream outfile(filename.c_str(), ofstream::out | ofstream::trunc);
74     if (!outfile.is_open()) {
75         printf("WriteBgrFile: Error writing file from BGR dataBuffer\n");
76         return IC_RETCODE_FAILURE;
77     }
78     outfile.write((const char*)dataBuffer, bufferSize);
79     outfile.close();
80     return IC_RETCODE_SUCCESS;
81 }
82 
ConvertToCaffeInput(uint8_t * dataBuffer,int maxSize)83 uint8_t *ConvertToCaffeInput(uint8_t *dataBuffer, int maxSize)
84 {
85     if (dataBuffer == nullptr) {
86         return nullptr;
87     }
88     if (maxSize % NUM_CHANNELS != 0) {
89         return nullptr;
90     }
91     uint8_t *input = new (std::nothrow) uint8_t[maxSize];
92     if (input == nullptr) {
93         return nullptr;
94     }
95     int numPreChannel = maxSize / NUM_CHANNELS;
96     for (int i = 0; i < maxSize; i++) {
97         input[BGR_RED * numPreChannel + i / NUM_CHANNELS] = dataBuffer[i + RGB_RED];
98         input[BGR_BLUE * numPreChannel + i / NUM_CHANNELS] = dataBuffer[i + RGB_BLUE];
99         input[BGR_GREEN * numPreChannel + i / NUM_CHANNELS] = dataBuffer[i + RGB_GREEN];
100     }
101     return input;
102 }
103 
ReadJpegFile(const string & filename,int & srcWidth,int & srcHeight)104 uint8_t *ReadJpegFile(const string &filename, int &srcWidth, int &srcHeight)
105 {
106     struct jpeg_decompress_struct cinfo;
107     struct MyErrorMgr jerr;
108     FILE *infile;
109     if ((infile = fopen(filename.c_str(), "rb")) == nullptr) {
110         printf("ReadJpegFile: can't open %s\n", filename.c_str());
111         return nullptr;
112     }
113 
114     cinfo.err = jpeg_std_error(&jerr.pub);
115     jpeg_create_decompress(&cinfo);
116     jpeg_stdio_src(&cinfo, infile);
117     (void)jpeg_read_header(&cinfo, TRUE);
118     (void)jpeg_start_decompress(&cinfo);
119     srcHeight = cinfo.output_height;
120     srcWidth = cinfo.output_width;
121     int dataSize = srcHeight * srcWidth * cinfo.output_components;
122     uint8_t *buffer = new (std::nothrow) uint8_t[dataSize];
123     if (buffer == nullptr) {
124         printf("ReadJpegFile: error to alloc buffer.\n");
125         (void)jpeg_finish_decompress(&cinfo);
126         jpeg_destroy_decompress(&cinfo);
127         fclose(infile);
128         return nullptr;
129     }
130     uint8_t *rowptr = nullptr;
131     while (cinfo.output_scanline < srcHeight) {
132         rowptr = buffer + cinfo.output_scanline * srcWidth * cinfo.output_components;
133         (void)jpeg_read_scanlines(&cinfo, &rowptr, 1);
134     }
135 
136     (void)jpeg_finish_decompress(&cinfo);
137     jpeg_destroy_decompress(&cinfo);
138     fclose(infile);
139     return buffer;
140 }
141 
Resize(const int widthDest,const int heightDest,uint8_t * src,int widthSrc,int heightSrc)142 uint8_t *Resize(
143     const int widthDest, const int heightDest, uint8_t *src, int widthSrc, int heightSrc)
144 {
145     if (src == nullptr) {
146         printf("Resize: src is nullptr.\n");
147         return nullptr;
148     }
149     if (widthDest <= 0 || heightDest <= 0 || widthSrc <= 0 || heightSrc <= 0) {
150         printf("Resize: dimension below zero.\n");
151         return nullptr;
152     }
153     int bufferSize = widthDest * heightDest * NUM_CHANNELS;
154     uint8_t *pDest = new (std::nothrow) uint8_t[bufferSize];
155     PicInfo picInfo = {
156         .widthSrc = widthSrc,
157         .heightSrc = heightSrc,
158         .widthDest = widthDest,
159         .heightDest = heightDest
160     };
161     ResizeComputer resizer(picInfo);
162     if (pDest == nullptr) {
163         printf("Resize: pDest alloc failed.\n");
164         return nullptr;
165     }
166     if (widthDest == widthSrc && heightDest == heightSrc) {
167         if (memcpy_s(pDest, bufferSize, src, bufferSize) != EOK) {
168             printf("Resize: memcpy_s failed.\n");
169             delete[] pDest;
170             return nullptr;
171         } else {
172             return pDest;
173         }
174     }
175     resizer.Compute(pDest, src, bufferSize, widthSrc * heightSrc * NUM_CHANNELS);
176     return pDest;
177 }
178 }  // namespace IC