[coding convention] Fixed coding rule violation
[platform/core/api/mediavision.git] / mv_barcode / barcode_generator / src / mv_barcode_generate_open.cpp
1 /**
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "mv_barcode_generate_open.h"
18
19 #include "mv_common_c.h"
20 #include "BarcodeGenerator.h"
21
22 #include <mv_private.h>
23
24 #include <algorithm>
25 #include <cstring>
26
27 using namespace MediaVision::Barcode;
28
29 namespace {
30 int alphanumToUpper(std::string& strToTransform)
31 {
32         std::string tempString = strToTransform;
33         std::transform(tempString.begin(), tempString.end(),
34                                         tempString.begin(), ::toupper);
35
36         if (std::string::npos != tempString.find_first_not_of("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:")) {
37                 LOGE("Barcode message can't be converted according to support "
38                                 "alphanumeric (0..9, A..Z, space, $, %, *, +, -, ., /, :) "
39                                 "mode: %s", strToTransform.c_str());
40                 return BARCODE_ERROR_INVALID_DATA;
41         }
42
43         LOGI("Barcode message was converted according to support alphanumeric "
44                         "mode: %s -> %s", strToTransform.c_str(), tempString.c_str());
45         strToTransform = tempString;
46         return BARCODE_ERROR_NONE;
47 }
48
49 BarcodeType convertBarcodeType(mv_barcode_type_e type)
50 {
51         BarcodeType barcodeType = BARCODE_QR;
52         switch (type) {
53         case MV_BARCODE_UPC_A:
54                 barcodeType = BARCODE_UPCA;
55                 break;
56         case MV_BARCODE_UPC_E:
57                 barcodeType = BARCODE_UPCE;
58                 break;
59         case MV_BARCODE_EAN_8:
60                 barcodeType = BARCODE_EAN8;
61                 break;
62         case MV_BARCODE_EAN_13:
63                 barcodeType = BARCODE_EAN13;
64                 break;
65         case MV_BARCODE_CODE128:
66                 barcodeType = BARCODE_CODE128;
67                 break;
68         case MV_BARCODE_CODE39:
69                 barcodeType = BARCODE_CODE39;
70                 break;
71         case MV_BARCODE_I2_5:
72                 barcodeType = BARCODE_INTERLEAVE_2_5;
73                 break;
74         default:
75                 break;
76         }
77
78         LOGI("Media vision barcode type has been converted to ZInt barcode type "
79                         "(%i -> %i)", type, barcodeType);
80         return barcodeType;
81 }
82
83 BarcodeQREncodingMode convertEncodingMode(mv_barcode_qr_mode_e mode)
84 {
85         BarcodeQREncodingMode encodingMode = BARCODE_QR_MODE_ALPHANUMERIC;
86
87         switch (mode) {
88         case MV_BARCODE_QR_MODE_NUMERIC:
89                 encodingMode = BARCODE_QR_MODE_NUMERIC;
90                 break;
91         case MV_BARCODE_QR_MODE_BYTE:
92                 encodingMode = BARCODE_QR_MODE_BYTE;
93                 break;
94         case MV_BARCODE_QR_MODE_UTF8:
95                 encodingMode = BARCODE_QR_MODE_UTF8;
96                 break;
97         default:
98                 break;
99         }
100
101         LOGI("Media vision QRCode encoding mode has been converted to "
102                         "ZInt encoding mode (%i -> %i)", mode, encodingMode);
103         return encodingMode;
104 }
105
106 BarcodeQRErrorCorrectionLevel convertECC(mv_barcode_qr_ecc_e ecc)
107 {
108         BarcodeQRErrorCorrectionLevel ecclevel = BARCODE_QR_ECC_LOW;
109
110         switch (ecc) {
111         case MV_BARCODE_QR_ECC_MEDIUM:
112                 ecclevel = BARCODE_QR_ECC_MEDIUM;
113                 break;
114         case MV_BARCODE_QR_ECC_QUARTILE:
115                 ecclevel = BARCODE_QR_ECC_QUARTILE;
116                 break;
117         case MV_BARCODE_QR_ECC_HIGH:
118                 ecclevel = BARCODE_QR_ECC_HIGH;
119                 break;
120         default:
121                 break;
122         }
123
124         LOGI("Media vision ECC level has been converted to "
125                 "ZInt ECC level (%i -> %i)", ecc, ecclevel);
126         return ecclevel;
127 }
128
129 int convertBarcodeError(int barcodeError)
130 {
131         int mvError = MEDIA_VISION_ERROR_NONE;
132
133         switch (barcodeError) {
134         case BARCODE_WARNING_INVALID_OPTION:
135                 mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
136                 break;
137         case BARCODE_ERROR_TOO_LONG:
138                 mvError = MEDIA_VISION_ERROR_MSG_TOO_LONG;
139                 break;
140         case BARCODE_ERROR_INVALID_DATA:
141                 mvError = MEDIA_VISION_ERROR_INVALID_DATA;
142                 break;
143         case BARCODE_ERROR_INVALID_CHECK:
144                 mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
145                 break;
146         case BARCODE_ERROR_INVALID_OPTION:
147                 mvError = MEDIA_VISION_ERROR_INVALID_PARAMETER;
148                 break;
149         case BARCODE_ERROR_ENCODING_PROBLEM:
150                 mvError = MEDIA_VISION_ERROR_INTERNAL;
151                 break;
152         case BARCODE_ERROR_FILE_ACCESS:
153                 mvError = MEDIA_VISION_ERROR_PERMISSION_DENIED;
154                 break;
155         case BARCODE_ERROR_MEMORY:
156                 mvError = MEDIA_VISION_ERROR_OUT_OF_MEMORY;
157                 break;
158         case BARCODE_ERROR_INVALID_PATH:
159                 mvError = MEDIA_VISION_ERROR_INVALID_PATH;
160         default:
161                 break;
162         }
163
164         LOGI("ZInt error code has been converted to the media vision error code "
165                 "(%i -> (0x%08x))", barcodeError, mvError);
166         return mvError;
167 }
168
169 BarcodeImageFormat convertImageFormat(mv_barcode_image_format_e format)
170 {
171         BarcodeImageFormat imageFormat = BARCODE_IMAGE_PNG;
172
173         switch (format) {
174         case MV_BARCODE_IMAGE_FORMAT_JPG:
175                 imageFormat = BARCODE_IMAGE_JPG;
176                 break;
177         case MV_BARCODE_IMAGE_FORMAT_BMP:
178                 imageFormat = BARCODE_IMAGE_BMP;
179                 break;
180         default:
181                 break;
182         }
183
184         LOGI("Media vision image format has been converted to "
185                 "internal image format (%i -> %i)", format, imageFormat);
186         return imageFormat;
187 }
188
189 } /* anonymous namespace */
190
191 int mv_barcode_generate_source_open(
192                 mv_engine_config_h engine_cfg,
193                 const char *message,
194                 mv_barcode_type_e type,
195                 mv_barcode_qr_mode_e qr_enc_mode,
196                 mv_barcode_qr_ecc_e qr_ecc,
197                 int qr_version,
198                 mv_source_h image)
199 {
200         std::string messageStr = std::string(message);
201
202         if (qr_enc_mode == MV_BARCODE_QR_MODE_NUMERIC &&
203                 messageStr.find_first_not_of("0123456789") != std::string::npos) {
204                 LOGE("Barcode message can't be used according to support "
205                         "numeric (0..9) mode: %s", messageStr.c_str());
206                 return MEDIA_VISION_ERROR_INVALID_DATA;
207         }
208
209         int error = BARCODE_ERROR_NONE;
210         if (MV_BARCODE_QR == type &&
211                 MV_BARCODE_QR_MODE_ALPHANUMERIC == qr_enc_mode) {
212                 error = alphanumToUpper(messageStr);
213                 if (BARCODE_ERROR_NONE != error) {
214                         return convertBarcodeError(error);
215                 }
216         }
217
218         unsigned char *imageBuffer = NULL;
219         unsigned int imageWidth = 0u;
220         unsigned int imageHeight = 0u;
221         unsigned int imageChannels = 0u;
222
223         int showText = 0;
224         char value;
225         char *fgcolour = NULL;
226         char *bgcolour = NULL;
227
228         if (engine_cfg != NULL) {
229                 error = mv_engine_config_get_int_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_TEXT", &showText);
230                 if (error != MEDIA_VISION_ERROR_NONE) {
231                         LOGW("mv_engine_config_get_int_attribute failed");
232                         return error;
233                 }
234
235                 if (showText == BARCODE_GEN_TEXT_VISIBLE && type == MV_BARCODE_QR) {
236                         LOGW("QR code generation with visible text is not supported");
237                         return MEDIA_VISION_ERROR_INVALID_OPERATION;
238                 }
239
240                 /* set color value */
241                 error = mv_engine_config_get_string_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_COLOR_FRONT", &fgcolour);
242                 if (error != MEDIA_VISION_ERROR_NONE) {
243                         if (fgcolour) {
244                                 free(fgcolour);
245                                 fgcolour = NULL;
246                         }
247
248                         LOGW("mv_engine_config_get_string_attribute failed");
249                         return error;
250                 }
251
252                 error = mv_engine_config_get_string_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_COLOR_BACK", &bgcolour);
253                 if (error != MEDIA_VISION_ERROR_NONE) {
254                         if (bgcolour) {
255                                 free(bgcolour);
256                                 bgcolour = NULL;
257                         }
258
259                         if (fgcolour) {
260                                 free(fgcolour);
261                                 fgcolour = NULL;
262                         }
263
264                         LOGW("mv_engine_config_get_string_attribute failed");
265                         return error;
266                 }
267
268                 /*
269                 The input colorspace is RGB but the generators' is BGR.
270                 Replace the value of R with that of B
271                 */
272                 value = fgcolour[0];
273                 fgcolour[0] = fgcolour[4];
274                 fgcolour[4] = value;
275
276                 value = fgcolour[1];
277                 fgcolour[1] = fgcolour[5];
278                 fgcolour[5] = value;
279
280                 value = bgcolour[0];
281                 bgcolour[0] = bgcolour[4];
282                 bgcolour[4] = value;
283
284                 value = bgcolour[1];
285                 bgcolour[1] = bgcolour[5];
286                 bgcolour[5] = value;
287         }
288
289         error = BarcodeGenerator::generateBarcodeToBuffer(
290                                         &imageBuffer,
291                                         &imageWidth,
292                                         &imageHeight,
293                                         &imageChannels,
294                                         messageStr,
295                                         convertBarcodeType(type),
296                                         convertEncodingMode(qr_enc_mode),
297                                         convertECC(qr_ecc),
298                                         qr_version,
299                                         showText,
300                                         fgcolour,
301                                         bgcolour);
302
303         if (fgcolour != NULL) {
304                 free(fgcolour);
305                 fgcolour = NULL;
306         }
307
308         if (bgcolour != NULL) {
309                 free(bgcolour);
310                 bgcolour = NULL;
311         }
312
313         if (error != BARCODE_ERROR_NONE) {
314                 LOGE("Barcode generation to the buffer failed");
315                 if (NULL != imageBuffer) {
316                         LOGI("Delete temporal buffer");
317                         delete[] imageBuffer;
318                 }
319                 return convertBarcodeError(error);
320         }
321
322         const unsigned int imageBufferSize = imageWidth * imageHeight * imageChannels;
323
324         LOGI("Barcode has been generated to the buffer: "
325                 "Buffer size = %ui x %ui; Channels = %ui; Message = %s",
326                 imageWidth, imageHeight, imageChannels, messageStr.c_str());
327
328         error = mv_source_fill_by_buffer_c(
329                                         image,
330                                         imageBuffer,
331                                         imageBufferSize,
332                                         imageWidth,
333                                         imageHeight,
334                                         MEDIA_VISION_COLORSPACE_RGB888);
335
336         if (error != MEDIA_VISION_ERROR_NONE) {
337                 LOGE("Meidiavision source fill by generated buffer failed");
338         }
339
340         if (NULL != imageBuffer) {
341                 LOGI("Delete temporal buffer");
342                 delete[] imageBuffer;
343         }
344
345         return error;
346 }
347
348
349 int mv_barcode_generate_image_open(
350                 mv_engine_config_h engine_cfg,
351                 const char *message,
352                 int image_width,
353                 int image_height,
354                 mv_barcode_type_e type,
355                 mv_barcode_qr_mode_e qr_enc_mode,
356                 mv_barcode_qr_ecc_e qr_ecc,
357                 int qr_version,
358                 const char *image_path,
359                 mv_barcode_image_format_e image_format)
360 {
361         std::string messageStr = std::string(message);
362
363         if (qr_enc_mode == MV_BARCODE_QR_MODE_NUMERIC &&
364                 messageStr.find_first_not_of("0123456789") != std::string::npos) {
365                 LOGE("Barcode message can't be used according to support "
366                 "numeric (0..9) mode: %s", messageStr.c_str());
367                 return MEDIA_VISION_ERROR_INVALID_DATA;
368         }
369
370         if (NULL == image_path) {
371                 LOGE("Can't save barcode image to the path[%p]. The path has to be specified", image_path);
372                 return MEDIA_VISION_ERROR_INVALID_PATH;
373         }
374
375         int error = BARCODE_ERROR_NONE;
376         if (MV_BARCODE_QR == type &&
377                 MV_BARCODE_QR_MODE_ALPHANUMERIC == qr_enc_mode) {
378                 error = alphanumToUpper(messageStr);
379                 if (BARCODE_ERROR_NONE != error) {
380                         return convertBarcodeError(error);
381                 }
382         }
383
384         int showText = 0;
385         char value;
386         char *fgcolour = NULL;
387         char *bgcolour = NULL;
388
389         if (engine_cfg != NULL) {
390                 /* set visible text attribute */
391                 error = mv_engine_config_get_int_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_TEXT", &showText);
392                 if (error != MEDIA_VISION_ERROR_NONE) {
393                         LOGW("mv_engine_config_get_int_attribute failed");
394                         return error;
395                 }
396
397                 if (showText == BARCODE_GEN_TEXT_VISIBLE && type == MV_BARCODE_QR) {
398                         LOGW("QR code generation with visible text is not supported");
399                         return MEDIA_VISION_ERROR_INVALID_OPERATION;
400                 }
401
402                 /* set color value */
403                 error = mv_engine_config_get_string_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_COLOR_FRONT", &fgcolour);
404                 if (error != MEDIA_VISION_ERROR_NONE) {
405                         if (fgcolour) {
406                                 free(fgcolour);
407                                 fgcolour = NULL;
408                         }
409
410                         LOGW("mv_engine_config_get_string_attribute failed");
411                         return error;
412                 }
413
414                 error = mv_engine_config_get_string_attribute(engine_cfg, "MV_BARCODE_GENERATE_ATTR_COLOR_BACK", &bgcolour);
415                 if (error != MEDIA_VISION_ERROR_NONE) {
416                         if (bgcolour) {
417                                 free(bgcolour);
418                                 bgcolour = NULL;
419                         }
420
421                         if (fgcolour) {
422                                 free(fgcolour);
423                                 fgcolour = NULL;
424                         }
425
426                         LOGW("mv_engine_config_get_string_attribute failed");
427                         return error;
428                 }
429
430                 /*
431                 The input colorspace is RGB but the generators' is BGR.
432                 Replace the value of R with that of B
433                 */
434                 value = fgcolour[0];
435                 fgcolour[0] = fgcolour[4];
436                 fgcolour[4] = value;
437
438                 value = fgcolour[1];
439                 fgcolour[1] = fgcolour[5];
440                 fgcolour[5] = value;
441
442                 value = bgcolour[0];
443                 bgcolour[0] = bgcolour[4];
444                 bgcolour[4] = value;
445
446                 value = bgcolour[1];
447                 bgcolour[1] = bgcolour[5];
448                 bgcolour[5] = value;
449         }
450
451         error = BarcodeGenerator::generateBarcodeToImage(
452                                                         std::string(image_path),
453                                                         convertImageFormat(image_format),
454                                                         image_width,
455                                                         image_height,
456                                                         messageStr,
457                                                         convertBarcodeType(type),
458                                                         convertEncodingMode(qr_enc_mode),
459                                                         convertECC(qr_ecc),
460                                                         qr_version,
461                                                         showText,
462                                                         fgcolour,
463                                                         bgcolour);
464
465         if (fgcolour != NULL) {
466                 free(fgcolour);
467                 fgcolour = NULL;
468         }
469
470         if (bgcolour != NULL) {
471                 free(bgcolour);
472                 bgcolour = NULL;
473         }
474
475         if (error != BARCODE_ERROR_NONE) {
476                 LOGE("Barcode generation to the image file failed");
477         } else {
478                 LOGI("Barcode has been generated to the image: "
479                         "Image size = %ui x %ui; Message = %s",
480                         image_width, image_height, messageStr.c_str());
481         }
482
483         return convertBarcodeError(error);
484 }