2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include <mv_barcode.h>
19 #include <image_helper.h>
20 #include <mv_private.h>
27 #include <libswscale/swscale.h>
28 #include <libavcodec/avcodec.h>
29 #include <libavutil/pixfmt.h>
32 mv_barcode_type_e type;
33 mv_barcode_qr_ecc_e ecc;
34 mv_barcode_qr_mode_e mode;
38 mv_barcode_image_format_e out_image_format;
39 mv_colorspace_e colorspace;
43 unsigned char *out_buffer_ptr;
47 MV_TS_GENERATE_TO_IMAGE_FCN,
48 MV_TS_GENERATE_TO_SOURCE_FCN
51 int convert_rgb_to(unsigned char *src_buffer, unsigned char **dst_buffer,
52 image_data_s image_data, mv_colorspace_e dst_colorspace,
53 unsigned long *cvt_buffer_size)
55 enum PixelFormat pixel_format = PIX_FMT_NONE;
57 MEDIA_VISION_FUNCTION_ENTER();
59 switch (dst_colorspace) {
60 case MEDIA_VISION_COLORSPACE_Y800:
61 pixel_format = PIX_FMT_GRAY8;
63 case MEDIA_VISION_COLORSPACE_I420:
64 pixel_format = PIX_FMT_YUV420P;
66 case MEDIA_VISION_COLORSPACE_NV12:
67 pixel_format = PIX_FMT_NV12;
69 case MEDIA_VISION_COLORSPACE_YV12:
70 /* the same as I420 with inversed U and V */
71 pixel_format = PIX_FMT_YUV420P;
73 case MEDIA_VISION_COLORSPACE_NV21:
74 pixel_format = PIX_FMT_NV21;
76 case MEDIA_VISION_COLORSPACE_YUYV:
77 pixel_format = PIX_FMT_YUYV422;
79 case MEDIA_VISION_COLORSPACE_UYVY:
80 pixel_format = PIX_FMT_UYVY422;
82 case MEDIA_VISION_COLORSPACE_422P:
83 pixel_format = PIX_FMT_YUV422P;
85 case MEDIA_VISION_COLORSPACE_RGB565:
86 pixel_format = PIX_FMT_RGB565BE;
88 case MEDIA_VISION_COLORSPACE_RGBA:
89 pixel_format = PIX_FMT_RGBA;
91 case MEDIA_VISION_COLORSPACE_RGB888:
92 *cvt_buffer_size = image_data.image_width * image_data.image_height * 3;
93 (*dst_buffer) = (unsigned char*)malloc(*cvt_buffer_size);
94 memcpy(*dst_buffer, src_buffer, *cvt_buffer_size);
96 MEDIA_VISION_FUNCTION_LEAVE();
97 return MEDIA_VISION_ERROR_NONE;
99 MEDIA_VISION_FUNCTION_LEAVE();
100 return MEDIA_VISION_ERROR_NOT_SUPPORTED;
103 AVPicture src_picture;
104 AVPicture dst_picture;
106 avpicture_fill(&src_picture, (uint8_t*)src_buffer, PIX_FMT_RGB24,
107 image_data.image_width, image_data.image_height);
109 avpicture_alloc(&dst_picture, pixel_format,
110 image_data.image_width, image_data.image_height);
112 struct SwsContext *context = sws_getContext(
113 image_data.image_width, image_data.image_height, PIX_FMT_RGB24,
114 image_data.image_width, image_data.image_height, pixel_format,
115 SWS_FAST_BILINEAR, 0, 0, 0);
117 sws_scale(context, (const uint8_t * const *)src_picture.data,
118 src_picture.linesize, 0, image_data.image_height,
119 dst_picture.data, dst_picture.linesize);
121 *cvt_buffer_size = avpicture_get_size(pixel_format,
122 image_data.image_width, image_data.image_height);
123 if(*cvt_buffer_size < 0) {
124 avpicture_free(&dst_picture);
125 MEDIA_VISION_FUNCTION_LEAVE();
126 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
129 (*dst_buffer) = (unsigned char*)malloc(*cvt_buffer_size);
130 memcpy(*dst_buffer, dst_picture.data[0], *cvt_buffer_size);
132 avpicture_free(&dst_picture);
134 MEDIA_VISION_FUNCTION_LEAVE();
136 return MEDIA_VISION_ERROR_NONE;
139 int find_min_x(const mv_quadrangle_s *quadrangle, int *minX)
141 MEDIA_VISION_FUNCTION_ENTER();
143 if (NULL == quadrangle) {
144 MEDIA_VISION_FUNCTION_LEAVE();
145 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
148 *minX = quadrangle->points[0].x;
149 *minX = quadrangle->points[1].x < *minX ? quadrangle->points[1].x : *minX;
150 *minX = quadrangle->points[2].x < *minX ? quadrangle->points[2].x : *minX;
151 *minX = quadrangle->points[3].x < *minX ? quadrangle->points[3].x : *minX;
153 MEDIA_VISION_FUNCTION_LEAVE();
155 return MEDIA_VISION_ERROR_NONE;
158 int find_min_y(const mv_quadrangle_s *quadrangle, int *minY)
160 MEDIA_VISION_FUNCTION_ENTER();
162 if (NULL == quadrangle) {
163 MEDIA_VISION_FUNCTION_LEAVE();
164 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
167 *minY = quadrangle->points[0].y;
168 *minY = quadrangle->points[1].y < *minY ? quadrangle->points[1].y : *minY;
169 *minY = quadrangle->points[2].y < *minY ? quadrangle->points[2].y : *minY;
170 *minY = quadrangle->points[3].y < *minY ? quadrangle->points[3].y : *minY;
172 MEDIA_VISION_FUNCTION_LEAVE();
174 return MEDIA_VISION_ERROR_NONE;
177 int find_max_x(const mv_quadrangle_s *quadrangle, int *maxX)
179 MEDIA_VISION_FUNCTION_ENTER();
181 if (NULL == quadrangle) {
182 MEDIA_VISION_FUNCTION_LEAVE();
183 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
186 *maxX = quadrangle->points[0].x;
187 *maxX = quadrangle->points[1].x > *maxX ? quadrangle->points[1].x : *maxX;
188 *maxX = quadrangle->points[2].x > *maxX ? quadrangle->points[2].x : *maxX;
189 *maxX = quadrangle->points[3].x > *maxX ? quadrangle->points[3].x : *maxX;
191 MEDIA_VISION_FUNCTION_LEAVE();
193 return MEDIA_VISION_ERROR_NONE;
196 int find_max_y(const mv_quadrangle_s *quadrangle, int *maxY)
198 MEDIA_VISION_FUNCTION_ENTER();
200 if (NULL == quadrangle) {
201 MEDIA_VISION_FUNCTION_LEAVE();
202 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
205 *maxY = quadrangle->points[0].y;
206 *maxY = quadrangle->points[1].y > *maxY ? quadrangle->points[1].y : *maxY;
207 *maxY = quadrangle->points[2].y > *maxY ? quadrangle->points[2].y : *maxY;
208 *maxY = quadrangle->points[3].y > *maxY ? quadrangle->points[3].y : *maxY;
210 MEDIA_VISION_FUNCTION_LEAVE();
212 return MEDIA_VISION_ERROR_NONE;
215 bool _mv_engine_config_supported_attribute(mv_config_attribute_type_e attribute_type,
216 const char *attribute_name, void *user_data)
218 printf("Callback call for engine configuration attribute\n");
220 if (user_data == NULL)
223 mv_engine_config_h mv_engine_config = (mv_engine_config_h *)user_data;
226 double double_value = 0.0;
227 bool bool_value = false;
228 char str_value[1024];
229 switch (attribute_type) {
230 case MV_ENGINE_CONFIG_ATTR_TYPE_DOUBLE:
231 if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
232 mv_engine_config_get_double_attribute(
233 mv_engine_config, attribute_name, &double_value)) {
234 printf("Default double attribute %s wasn't set in engine\n",
238 printf("Default double attribute %s was set to %f in engine\n",
239 attribute_name, double_value);
241 case MV_ENGINE_CONFIG_ATTR_TYPE_INTEGER:
242 if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
243 mv_engine_config_get_int_attribute(
244 mv_engine_config, attribute_name, &int_value)) {
245 printf("Default integer attribute %s wasn't set in engine\n",
249 printf("Default interget attribute %s was set to %d in engine\n",
250 attribute_name, int_value);
252 case MV_ENGINE_CONFIG_ATTR_TYPE_BOOLEAN:
253 if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
254 mv_engine_config_get_bool_attribute(
255 mv_engine_config, attribute_name, &bool_value)) {
256 printf("Default bool attribute %s wasn't set in engine\n",
260 printf("Default bool attribute %s was set to %s in engine\n",
261 attribute_name, bool_value ? "TRUE" : "FALSE");
263 case MV_ENGINE_CONFIG_ATTR_TYPE_STRING:
264 if (MEDIA_VISION_ERROR_KEY_NOT_AVAILABLE ==
265 mv_engine_config_get_string_attribute(
266 mv_engine_config, attribute_name, &str_value)) {
267 printf("Default string ttribute %s wasn't set in engine\n",
271 printf("Default string attribute %s was set to %s in engine\n",
272 attribute_name, str_value);
275 printf("Not supported attribute type\n");
282 void barcode_detected_cb(
284 mv_engine_config_h engine_cfg,
285 const mv_quadrangle_s *barcodes_locations,
286 const char *messages[],
287 const mv_barcode_type_e *types,
288 int number_of_barcodes,
291 MEDIA_VISION_FUNCTION_ENTER();
293 printf("%i barcodes were detected on the image.\n", number_of_barcodes);
294 if (number_of_barcodes > 0) {
295 int is_source_data_loaded = 0;
297 char *file_name = NULL;
298 unsigned char *out_buffer = NULL;
299 unsigned char *draw_buffer = NULL;
300 unsigned int buf_size = 0;
301 image_data_s image_data = { 0, 0, MEDIA_VISION_COLORSPACE_INVALID };
302 /* Check Media Vision source: */
303 if (MEDIA_VISION_ERROR_NONE != mv_source_get_buffer(source, &out_buffer, &buf_size) ||
304 MEDIA_VISION_ERROR_NONE != mv_source_get_width(source, &(image_data.image_width)) ||
305 MEDIA_VISION_ERROR_NONE != mv_source_get_height(source, &(image_data.image_height)) ||
306 MEDIA_VISION_ERROR_NONE != mv_source_get_colorspace(source, &(image_data.image_colorspace)) ||
308 printf("ERROR: Creating out image is impossible.\n");
310 file_name = ((barcode_model_s *)user_data)->out_file_name;
311 draw_buffer = ((barcode_model_s *)user_data)->out_buffer_ptr;
312 image_data.image_colorspace = MEDIA_VISION_COLORSPACE_RGB888;
313 is_source_data_loaded = 1;
317 for (i = 0; i < number_of_barcodes; ++i) {
318 const char *cur_message = messages[i];
319 mv_barcode_type_e cur_type = types[i];
320 const char *str_type = NULL;
325 case MV_BARCODE_UPC_A:
328 case MV_BARCODE_UPC_E:
331 case MV_BARCODE_EAN_8:
332 case MV_BARCODE_EAN_13:
333 str_type = "EAN-8/13";
335 case MV_BARCODE_CODE128:
336 str_type = "CODE128";
338 case MV_BARCODE_CODE39:
341 case MV_BARCODE_I2_5:
345 str_type = "Undetected";
348 printf("\tBarcode %i : type is %s\n", i, str_type);
349 if (cur_message != NULL)
350 printf("\t message is %s\n", cur_message);
352 printf("\t message wasn't detected\n");
354 if (is_source_data_loaded == 1) {
359 if (MEDIA_VISION_ERROR_NONE != find_min_x(&barcodes_locations[i], &minX) ||
360 MEDIA_VISION_ERROR_NONE != find_min_y(&barcodes_locations[i], &minY) ||
361 MEDIA_VISION_ERROR_NONE != find_max_x(&barcodes_locations[i], &maxX) ||
362 MEDIA_VISION_ERROR_NONE != find_max_y(&barcodes_locations[i], &maxY)) {
366 const int drawing_color[] = {255, 0, 0};
368 if (MEDIA_VISION_ERROR_NONE != draw_rectangle_on_buffer(
382 if (file_name != NULL &&
383 MEDIA_VISION_ERROR_NONE == save_image_from_buffer(file_name, draw_buffer, &image_data, 100)) {
384 printf("Image was generated as %s\n", file_name);
386 printf("ERROR: Failed to generate output file. Check file name and permissions. \n");
392 MEDIA_VISION_FUNCTION_LEAVE();
395 int generate_barcode_to_image(barcode_model_s model)
397 MEDIA_VISION_FUNCTION_ENTER();
399 if (model.message == NULL ||
400 model.file_name == NULL) {
401 MEDIA_VISION_FUNCTION_LEAVE();
402 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
405 LOGI("Call the mv_barcode_generate_image() function");
407 const int err = mv_barcode_generate_image(
417 model.out_image_format);
419 MEDIA_VISION_FUNCTION_LEAVE();
424 int generate_barcode_to_source(barcode_model_s model)
426 MEDIA_VISION_FUNCTION_ENTER();
428 if (model.message == NULL ||
429 model.file_name == NULL) {
430 MEDIA_VISION_FUNCTION_LEAVE();
432 return MEDIA_VISION_ERROR_INVALID_PARAMETER;
435 LOGI("mv_source_h creation started");
437 mv_source_h source = NULL;
438 int err = mv_create_source(&source);
439 if (MEDIA_VISION_ERROR_NONE != err) {
440 printf("ERROR: Error occurred when trying to create Media Vision "
441 "source. Error code: %i\n", err);
443 MEDIA_VISION_FUNCTION_LEAVE();
448 LOGI("mv_source_h creation finished");
450 LOGI("Call the mv_barcode_generate_source() function");
452 mv_engine_config_h mv_engine_config;
453 err = mv_create_engine_config(&mv_engine_config);
454 if (MEDIA_VISION_ERROR_NONE != err) {
455 printf("ERROR: Errors were occurred during creating the media engine "
456 "config: %i\n", err);
459 err = mv_barcode_generate_source(
468 if (MEDIA_VISION_ERROR_NONE != err) {
469 printf("ERROR: Error occurred during generation barcode to the "
470 "Media Vision source. Error code: %i\n", err);
472 const int err2 = mv_destroy_source(source);
473 if (MEDIA_VISION_ERROR_NONE != err2) {
474 printf("ERROR: Error occurred when try to destroy Media Vision source."
475 "Error code: %i\n", err2);
478 const int err3 = mv_destroy_engine_config(mv_engine_config);
479 if (MEDIA_VISION_ERROR_NONE != err3) {
480 printf("ERROR: Errors were occurred during destroying the media engine "
481 "config: %i\n", err3);
484 MEDIA_VISION_FUNCTION_LEAVE();
489 unsigned char *data_buffer = NULL;
490 unsigned int buffer_size = 0;
491 unsigned int image_width = 0;
492 unsigned int image_height = 0;
493 mv_colorspace_e image_colorspace = MEDIA_VISION_COLORSPACE_INVALID;
495 bool is_source_corrupted = false;
496 err = mv_source_get_buffer(source, &data_buffer, &buffer_size);
497 if (MEDIA_VISION_ERROR_NONE != err) {
498 printf("ERROR: Error occurred when trying to get buffer from "
499 "Media Vision source. Error code: %i\n", err);
500 is_source_corrupted = true;
503 err = mv_source_get_width(source, &image_width);
504 if (MEDIA_VISION_ERROR_NONE != err) {
505 printf("ERROR: Error occurred when trying to get width of "
506 "Media Vision source. Error code: %i\n", err);
507 is_source_corrupted = true;
510 err = mv_source_get_height(source, &image_height);
511 if (MEDIA_VISION_ERROR_NONE != err) {
512 printf("ERROR: Error occurred when trying to get height of "
513 "Media Vision source. Error code: %i\n", err);
514 is_source_corrupted = true;
517 err = mv_source_get_colorspace(source, &image_colorspace);
518 if (MEDIA_VISION_ERROR_NONE != err) {
519 printf("ERROR: Error occurred when trying to get colorspace of "
520 "Media Vision source. Error code: %i\n", err);
521 is_source_corrupted = true;
524 if (is_source_corrupted) {
525 err = mv_destroy_source(source);
526 if (MEDIA_VISION_ERROR_NONE != err) {
527 printf("ERROR: Error occurred when trying to destroy Media Vision "
528 "source. Error code: %i\n", err);
531 err = mv_destroy_engine_config(mv_engine_config);
532 if (MEDIA_VISION_ERROR_NONE != err) {
533 printf("ERROR: Errors were occurred during destroying the media engine "
534 "config: %i\n", err);
537 MEDIA_VISION_FUNCTION_LEAVE();
539 return MEDIA_VISION_ERROR_INTERNAL;
542 const image_data_s image_data = { image_width, image_height, image_colorspace };
544 char *jpeg_file_name = "";
545 if (0 == strcmp(model.file_name + strlen(model.file_name) - 4, ".jpg") ||
546 0 == strcmp(model.file_name + strlen(model.file_name) - 5, ".jpeg")) {
547 jpeg_file_name = (char*)malloc(strlen(model.file_name) + 1);
548 if (jpeg_file_name == NULL) {
549 mv_destroy_source(source);
550 mv_destroy_engine_config(mv_engine_config);
551 MEDIA_VISION_FUNCTION_LEAVE();
552 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
555 strncpy(jpeg_file_name, model.file_name, strlen(model.file_name) + 1);
556 jpeg_file_name[strlen(model.file_name)] = '\0';
558 jpeg_file_name = (char*)malloc(strlen(model.file_name) + 5);
559 if (jpeg_file_name == NULL) {
560 mv_destroy_source(source);
561 mv_destroy_engine_config(mv_engine_config);
562 MEDIA_VISION_FUNCTION_LEAVE();
563 return MEDIA_VISION_ERROR_OUT_OF_MEMORY;
566 strncpy(jpeg_file_name, model.file_name, strlen(model.file_name) + 5);
567 strncpy(jpeg_file_name + strlen(model.file_name), ".jpg", 5);
568 jpeg_file_name[strlen(model.file_name) + 4] = '\0';
571 save_image_from_buffer(jpeg_file_name, data_buffer, &image_data, 100);
573 free(jpeg_file_name);
575 const int err2 = mv_destroy_source(source);
576 if (MEDIA_VISION_ERROR_NONE != err2) {
577 printf("ERROR: Error occurred when try to destroy Media Vision source."
578 "Error code: %i\n", err2);
581 const int err3 = mv_destroy_engine_config(mv_engine_config);
582 if (MEDIA_VISION_ERROR_NONE != err3) {
583 printf("ERROR: Errors were occurred during destroying the media engine "
584 "config: %i\n", err);
587 MEDIA_VISION_FUNCTION_LEAVE();
592 int detect_barcode(barcode_model_s model, mv_rectangle_s roi)
594 MEDIA_VISION_FUNCTION_ENTER();
596 unsigned char *data_buffer = NULL;
597 unsigned long buffer_size = 0;
598 image_data_s image_data;
600 int err = load_image_to_buffer(
601 model.file_name, &data_buffer, &buffer_size, &image_data);
602 if (MEDIA_VISION_ERROR_NONE != err) {
603 printf("ERROR: Errors were occurred during opening the file!!! code: %i\n", err);
605 MEDIA_VISION_FUNCTION_LEAVE();
610 unsigned char *converted_buffer = NULL;
611 unsigned long converted_buffer_size = 0;
612 err = convert_rgb_to(data_buffer, &converted_buffer, image_data, model.colorspace, &converted_buffer_size);
613 if (MEDIA_VISION_ERROR_NONE != err) {
614 printf("ERROR: Can't convert to the selected colorspace!!! code: %i\n", err);
616 MEDIA_VISION_FUNCTION_LEAVE();
621 model.out_buffer_ptr = data_buffer;
623 mv_engine_config_h mv_engine_config;
624 err = mv_create_engine_config(&mv_engine_config);
625 if (MEDIA_VISION_ERROR_NONE != err)
626 printf("ERROR: Errors were occurred during creating the media engine config: %i\n", err);
628 mv_engine_config_foreach_supported_attribute(_mv_engine_config_supported_attribute, mv_engine_config);
630 mv_engine_config_set_int_attribute(mv_engine_config, MV_BARCODE_DETECT_ATTR_TARGET, MV_BARCODE_DETECT_ATTR_TARGET_2D_BARCODE);
633 err = mv_create_source(&source);
634 if (MEDIA_VISION_ERROR_NONE != err) {
635 printf("ERROR: Errors were occurred during creating the source!!! code: %i\n", err);
637 MEDIA_VISION_FUNCTION_LEAVE();
642 err = mv_source_fill_by_buffer(source, converted_buffer, converted_buffer_size,
643 image_data.image_width, image_data.image_height, model.colorspace);
644 if (MEDIA_VISION_ERROR_NONE != err) {
645 printf("ERROR: Errors were occurred during filling the source!!! code: %i\n", err);
647 MEDIA_VISION_FUNCTION_LEAVE();
652 if (converted_buffer != NULL)
653 free(converted_buffer);
655 err = mv_barcode_detect(source, mv_engine_config, roi, barcode_detected_cb, &model);
657 if (data_buffer != NULL)
658 destroy_loaded_buffer(data_buffer);
660 if (MEDIA_VISION_ERROR_NONE != err) {
661 printf("ERROR: Errors were occurred during barcode detection!!! code: %i\n", err);
663 MEDIA_VISION_FUNCTION_LEAVE();
668 err = mv_destroy_source(source);
669 if (MEDIA_VISION_ERROR_NONE != err)
670 printf("ERROR: Errors were occurred during destroying the source!!! code: %i\n", err);
672 err = mv_destroy_engine_config(mv_engine_config);
673 if (MEDIA_VISION_ERROR_NONE != err)
674 printf("ERROR: Error were occurred during destroying the source!!! code: %i\n", err);
676 MEDIA_VISION_FUNCTION_LEAVE();
681 int input_string(const char *prompt, size_t max_len, char **string)
683 MEDIA_VISION_FUNCTION_ENTER();
686 printf("%s ", prompt);
688 if (scanf("\n") != 0) {
689 MEDIA_VISION_FUNCTION_LEAVE();
693 char buffer[max_len];
695 buffer[last_char] = '\0';
696 buffer[sizeof(buffer) - 1] = ~'\0';
697 if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
698 MEDIA_VISION_FUNCTION_LEAVE();
701 size_t real_string_len = strlen(buffer);
702 buffer[real_string_len - 1] = '\0';
703 *string = (char*)malloc(real_string_len * sizeof(char));
704 if (*string == NULL) {
705 MEDIA_VISION_FUNCTION_LEAVE();
709 strncpy(*string, buffer, real_string_len);
711 size_t str_len = strlen(*string);
713 MEDIA_VISION_FUNCTION_LEAVE();
718 int input_size(const char *prompt, size_t max_size, size_t *size)
720 MEDIA_VISION_FUNCTION_ENTER();
723 printf("%s ", prompt);
725 if (scanf("%20zu", size) == 0) {
726 if (scanf("%*[^\n]%*c") != 0) {
727 printf("ERROR: Reading the input line error.\n");
728 MEDIA_VISION_FUNCTION_LEAVE();
731 printf("ERROR: Incorrect input.\n");
732 MEDIA_VISION_FUNCTION_LEAVE();
736 int ret = (*size > max_size ? -1 : 0);
738 MEDIA_VISION_FUNCTION_LEAVE();
743 int input_int(const char *prompt, int min_value, int max_value, int *value)
745 MEDIA_VISION_FUNCTION_ENTER();
748 printf("%s ", prompt);
750 if (scanf("%20i", value) == 0) {
751 if (scanf("%*[^\n]%*c") != 0) {
752 printf("ERROR: Reading the input line error.\n");
753 MEDIA_VISION_FUNCTION_LEAVE();
756 printf("ERROR: Incorrect input.\n");
757 MEDIA_VISION_FUNCTION_LEAVE();
761 int ret = (*value < min_value || *value > max_value ? -1 : 0);
763 MEDIA_VISION_FUNCTION_LEAVE();
768 int show_menu(const char *title, const int *options, const char **names, int cnt)
770 MEDIA_VISION_FUNCTION_ENTER();
772 printf("***************************\n");
773 printf("* %23s *\n", title);
774 printf("*-------------------------*\n");
776 for (i = 0; i < cnt; ++i)
777 printf("* %2i. %19s *\n", options[i], names[i]);
779 printf("***************************\n\n");
781 printf("Your choise: ");
782 if (scanf("%20i", &selection) == 0) {
783 if (scanf("%*[^\n]%*c") != 0) {
784 printf("ERROR: Reading the input line error.\n");
785 MEDIA_VISION_FUNCTION_LEAVE();
788 printf("ERROR: Incorrect input.\n");
791 MEDIA_VISION_FUNCTION_LEAVE();
796 mv_barcode_type_e select_type(void)
798 mv_barcode_type_e selected_type = MV_BARCODE_UNDEFINED;
800 const int options[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
801 const char *names[8] = { "qr", "upca", "upce", "ean8", "ean13", "code39", "code128", "interleave25" };
803 MEDIA_VISION_FUNCTION_ENTER();
805 while (sel_opt == 0) {
806 sel_opt = show_menu("Select barcode type:", options, names, 8);
810 selected_type = MV_BARCODE_QR;
813 selected_type = MV_BARCODE_UPC_A;
816 selected_type = MV_BARCODE_UPC_E;
819 selected_type = MV_BARCODE_EAN_8;
822 selected_type = MV_BARCODE_EAN_13;
825 selected_type = MV_BARCODE_CODE39;
828 selected_type = MV_BARCODE_CODE128;
831 selected_type = MV_BARCODE_I2_5;
839 MEDIA_VISION_FUNCTION_LEAVE();
841 return selected_type;
844 mv_barcode_qr_mode_e select_mode(void)
846 mv_barcode_qr_mode_e selected_mode = MV_BARCODE_QR_MODE_UNAVAILABLE;
848 const int options[4] = { 1, 2, 3, 4 };
849 const char *names[4] = { "numeric", "alphanumeric", "byte", "utf8" };
851 MEDIA_VISION_FUNCTION_ENTER();
853 while (sel_opt == 0) {
854 sel_opt = show_menu("Select encoding mode:", options, names, 4);
857 selected_mode = MV_BARCODE_QR_MODE_NUMERIC;
860 selected_mode = MV_BARCODE_QR_MODE_ALPHANUMERIC;
863 selected_mode = MV_BARCODE_QR_MODE_BYTE;
866 selected_mode = MV_BARCODE_QR_MODE_UTF8;
874 MEDIA_VISION_FUNCTION_LEAVE();
876 return selected_mode;
879 mv_barcode_qr_ecc_e select_ecc(void)
881 mv_barcode_qr_ecc_e selected_ecc = MV_BARCODE_QR_ECC_UNAVAILABLE;
883 const int options[4] = { 1, 2, 3, 4 };
884 const char *names[4] = { "low", "medium", "quartile", "high" };
886 MEDIA_VISION_FUNCTION_ENTER();
888 while (sel_opt == 0) {
889 sel_opt = show_menu("Select ECC level:", options, names, 4);
892 selected_ecc = MV_BARCODE_QR_ECC_LOW;
895 selected_ecc = MV_BARCODE_QR_ECC_MEDIUM;
898 selected_ecc = MV_BARCODE_QR_ECC_QUARTILE;
901 selected_ecc = MV_BARCODE_QR_ECC_HIGH;
909 MEDIA_VISION_FUNCTION_LEAVE();
914 int select_version(void)
916 MEDIA_VISION_FUNCTION_ENTER();
919 while (sel_opt == 0) {
920 const int options[2] = {1, 40};
921 const char *names[2] = { "1..", "..40" };
922 sel_opt = show_menu("Select QR version:", options, names, 2);
923 if (sel_opt < 1 || sel_opt > 40)
927 MEDIA_VISION_FUNCTION_LEAVE();
932 generation_fcn_e select_gen_function(void)
934 generation_fcn_e ret_fcn_type = MV_TS_GENERATE_TO_IMAGE_FCN;
936 const int options[2] = { 1, 2 };
937 const char *names[2] = { "Generate to file", "Generate to source" };
939 MEDIA_VISION_FUNCTION_ENTER();
941 while (sel_opt == 0) {
942 sel_opt = show_menu("Select API function:", options, names, 2);
945 ret_fcn_type = MV_TS_GENERATE_TO_IMAGE_FCN;
948 ret_fcn_type = MV_TS_GENERATE_TO_SOURCE_FCN;
956 MEDIA_VISION_FUNCTION_LEAVE();
961 mv_barcode_image_format_e select_file_format(void)
963 mv_barcode_image_format_e image_format = MV_BARCODE_IMAGE_FORMAT_JPG;
965 const int options[3] = { 1, 2, 3 };
966 const char *names[3] = { "BMP", "JPG", "PNG" };
968 MEDIA_VISION_FUNCTION_ENTER();
970 while (sel_opt == 0) {
971 sel_opt = show_menu("Select file format:", options, names, 3);
974 image_format = MV_BARCODE_IMAGE_FORMAT_BMP;
977 image_format = MV_BARCODE_IMAGE_FORMAT_JPG;
980 image_format = MV_BARCODE_IMAGE_FORMAT_PNG;
988 MEDIA_VISION_FUNCTION_LEAVE();
995 MEDIA_VISION_FUNCTION_ENTER();
997 barcode_model_s detect_model = {
998 MV_BARCODE_UNDEFINED,
999 MV_BARCODE_QR_ECC_UNAVAILABLE,
1000 MV_BARCODE_QR_MODE_UNAVAILABLE,
1002 MV_BARCODE_IMAGE_FORMAT_PNG,
1003 MEDIA_VISION_COLORSPACE_INVALID,
1004 NULL, NULL, NULL, NULL };
1006 while (input_string("Input file name to be analyzed:", 1024, &(detect_model.file_name)) == -1)
1007 printf("Incorrect input! Try again.\n");
1009 LOGI("Barcode input image has been specified");
1011 mv_rectangle_s roi = { {0, 0}, 0, 0 };
1013 while (input_int("Input x coordinate for ROI top left vertex:", 0, 10000, &(roi.point.x)) == -1)
1014 printf("Incorrect input! Try again.\n");
1016 while (input_int("Input y coordinate for ROI top left vertex:", 0, 10000, &(roi.point.y)) == -1)
1017 printf("Incorrect input! Try again.\n");
1019 while (input_int("Input ROI width:", 0, 10000, &(roi.width)) == -1)
1020 printf("Incorrect input! Try again.\n");
1022 while (input_int("Input ROI height:", 0, 10000, &(roi.height)) == -1)
1023 printf("Incorrect input! Try again.\n");
1025 LOGI("Region of interest (ROI) to detect barcode into has been specified");
1027 while (input_string("Input file name to be generated:", 1024, &(detect_model.out_file_name)) == -1)
1028 printf("Incorrect input! Try again.\n");
1030 LOGI("Barcode output image has been specified");
1032 const int options[11] = { MEDIA_VISION_COLORSPACE_Y800,
1033 MEDIA_VISION_COLORSPACE_I420,
1034 MEDIA_VISION_COLORSPACE_NV12,
1035 MEDIA_VISION_COLORSPACE_YV12,
1036 MEDIA_VISION_COLORSPACE_NV21,
1037 MEDIA_VISION_COLORSPACE_YUYV,
1038 MEDIA_VISION_COLORSPACE_UYVY,
1039 MEDIA_VISION_COLORSPACE_422P,
1040 MEDIA_VISION_COLORSPACE_RGB565,
1041 MEDIA_VISION_COLORSPACE_RGB888,
1042 MEDIA_VISION_COLORSPACE_RGBA };
1043 const char *names[11] = { "Y800", "I420", "NV12", "YV12", "NV21",
1044 "YUYV", "UYVY", "422P", "RGB565",
1048 int sel_opt = show_menu("Select colorspace to test detector on:", options, names, 11);
1049 if (sel_opt < MEDIA_VISION_COLORSPACE_Y800 ||
1050 sel_opt > MEDIA_VISION_COLORSPACE_RGBA) {
1053 detect_model.colorspace = (mv_colorspace_e)sel_opt;
1054 LOGI("User selection is %i", sel_opt);
1058 int err = detect_barcode(detect_model, roi);
1060 if (detect_model.file_name != NULL)
1061 free(detect_model.file_name);
1063 if (detect_model.out_file_name != NULL)
1064 free(detect_model.out_file_name);
1066 if (err != MEDIA_VISION_ERROR_NONE)
1067 LOGE("Barcode detection failed with error code (0x%08x)", err);
1069 MEDIA_VISION_FUNCTION_LEAVE();
1074 int perform_generate(void)
1076 MEDIA_VISION_FUNCTION_ENTER();
1078 barcode_model_s generate_model = {
1079 MV_BARCODE_UNDEFINED,
1080 MV_BARCODE_QR_ECC_UNAVAILABLE,
1081 MV_BARCODE_QR_MODE_UNAVAILABLE,
1083 MV_BARCODE_IMAGE_FORMAT_PNG,
1084 MEDIA_VISION_COLORSPACE_INVALID,
1085 NULL, NULL, NULL, NULL };
1087 generation_fcn_e gen_fcn = select_gen_function();
1088 generate_model.type = select_type();
1089 LOGI("Barcode type has been selected");
1091 if (generate_model.type == MV_BARCODE_QR) {
1092 generate_model.mode = select_mode();
1093 LOGI("Barcode encoding mode has been selected");
1094 generate_model.ecc = select_ecc();
1095 LOGI("Barcode ecc level has been selected");
1096 generate_model.version = select_version();
1097 LOGI("Barcode version has been selected");
1100 if (gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN) {
1101 generate_model.out_image_format = select_file_format();
1102 LOGI("Barcode output image format has been selected");
1105 while (input_string("Input message:", 7089, &generate_model.message) == -1)
1106 printf("Incorrect input! Try again.\n");
1108 LOGI("Barcode message has been specified");
1110 while (input_string("Input file name:", 1024, &generate_model.file_name) == -1)
1111 printf("Incorrect input! Try again.\n");
1113 LOGI("Barcode output file name has been specified");
1115 if (gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN) {
1116 while (input_size("Input image width:", 10000, &generate_model.width) == -1)
1117 printf("Incorrect input! Try again.\n");
1119 LOGI("Barcode output file width has been specified");
1121 while (input_size("Input image height:", 10000, &generate_model.height) == -1)
1122 printf("Incorrect input! Try again.\n");
1124 LOGI("Barcode output file height has been specified");
1128 gen_fcn == MV_TS_GENERATE_TO_IMAGE_FCN ?
1129 generate_barcode_to_image(generate_model) :
1130 generate_barcode_to_source(generate_model);
1132 if (generate_model.message != NULL)
1133 free(generate_model.message);
1135 if (generate_model.file_name != NULL)
1136 free(generate_model.file_name);
1138 if (err != MEDIA_VISION_ERROR_NONE) {
1139 LOGE("Barcode generation failed with error code (0x%08x)", err);
1140 printf("ERROR: Errors were occurred during barcode generation!!!\n");
1141 MEDIA_VISION_FUNCTION_LEAVE();
1145 LOGI("Barcode output file has been generated");
1146 printf("\nBarcode image was successfully generated.\n");
1148 MEDIA_VISION_FUNCTION_LEAVE();
1155 LOGI("Media Vision Testsuite is launched.");
1157 int err = MEDIA_VISION_ERROR_NONE;
1160 const int options[2] = { 1, 2 };
1161 const char *names[2] = { "Generate", "Detect" };
1163 while (sel_opt == 0) {
1164 sel_opt = show_menu("Select action:", options, names, 2);
1167 LOGI("Start the barcode generation flow");
1168 err = perform_generate();
1171 LOGI("Start the barcode detection flow");
1172 err = perform_detect();
1181 if (err != MEDIA_VISION_ERROR_NONE)
1182 printf("ERROR: Action is finished with error code: %i\n", err);
1185 const int options_last[2] = { 1, 2 };
1186 const char *names_last[2] = { "YES", "NO" };
1188 while (sel_opt == 0) {
1189 sel_opt = show_menu("Perform another action?", options_last, names_last, 2);
1202 LOGI("User selection is %i", sel_opt);
1204 sel_opt = (do_another == 1 ? 0 : sel_opt);
1207 LOGI("Media Vision Testsuite is closed.");