This is a mbed Client sample where ZXing is incorporated, and works on GR-PEACH and GR-LYCHEE.
Dependencies: DisplayApp AsciiFont
zxing_main.cpp
00001 00002 #include "mbed.h" 00003 #include "EasyAttach_CameraAndLCD.h" 00004 #include "ImageReaderSource.h" 00005 #include "AsciiFont.h" 00006 00007 /**** User Selection *********/ 00008 /** JPEG out setting **/ 00009 #define JPEG_SEND (1) /* Select 0(JPEG images are not output to PC) or 1(JPEG images are output to PC on USB(CDC) for focusing the camera) */ 00010 #define JPEG_ENCODE_QUALITY (75) /* JPEG encode quality (min:1, max:75 (Considering the size of JpegBuffer, about 75 is the upper limit.)) */ 00011 #define VFIELD_INT_SKIP_CNT (0) /* A guide for GR-LYCHEE. 0:60fps, 1:30fps, 2:20fps, 3:15fps, 4:12fps, 5:10fps */ 00012 /** Decode hints **/ 00013 #define DECODE_HINTS (DecodeHints::ONED_HINT | DecodeHints::QR_CODE_HINT | DecodeHints::DATA_MATRIX_HINT | DecodeHints::AZTEC_HINT) 00014 /*****************************/ 00015 00016 /* Video input and LCD layer 0 output */ 00017 #define VIDEO_FORMAT (DisplayBase::VIDEO_FORMAT_YCBCR422) 00018 #define GRAPHICS_FORMAT (DisplayBase::GRAPHICS_FORMAT_YCBCR422) 00019 //#define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_32_16BIT) 00020 #define WR_RD_WRSWA (DisplayBase::WR_RD_WRSWA_16BIT) 00021 #define DATA_SIZE_PER_PIC (2u) 00022 00023 /*! Frame buffer stride: Frame buffer stride should be set to a multiple of 32 or 128 00024 in accordance with the frame buffer burst transfer mode. */ 00025 #if MBED_CONF_APP_LCD 00026 #define VIDEO_PIXEL_HW LCD_PIXEL_WIDTH /* QVGA */ 00027 #define VIDEO_PIXEL_VW LCD_PIXEL_HEIGHT /* QVGA */ 00028 #else 00029 #define VIDEO_PIXEL_HW (640u) /* VGA */ 00030 #define VIDEO_PIXEL_VW (480u) /* VGA */ 00031 #endif 00032 00033 #define FRAME_BUFFER_STRIDE (((VIDEO_PIXEL_HW * DATA_SIZE_PER_PIC) + 31u) & ~31u) 00034 #define FRAME_BUFFER_HEIGHT (VIDEO_PIXEL_VW) 00035 00036 DisplayBase Display; 00037 // Timer 00038 static Timer decode_timer; 00039 00040 #if defined(__ICCARM__) 00041 #pragma data_alignment=32 00042 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]@ ".mirrorram"; 00043 #else 00044 static uint8_t user_frame_buffer0[FRAME_BUFFER_STRIDE * FRAME_BUFFER_HEIGHT]__attribute((section("NC_BSS"),aligned(32))); 00045 #endif 00046 00047 #if JPEG_SEND 00048 #include "JPEG_Converter.h" 00049 #include "DisplayApp.h" 00050 #include "dcache-control.h" 00051 00052 #if defined(__ICCARM__) 00053 #pragma data_alignment=32 00054 static uint8_t JpegBuffer[2][1024 * 64]; 00055 #else 00056 static uint8_t JpegBuffer[2][1024 * 64]__attribute((aligned(32))); 00057 #endif 00058 static size_t jcu_encode_size[2]; 00059 static JPEG_Converter Jcu; 00060 static int jcu_buf_index_write = 0; 00061 static int jcu_buf_index_write_done = 0; 00062 static int jcu_buf_index_read = 0; 00063 static volatile int jcu_encoding = 0; 00064 static volatile int image_change = 0; 00065 static DisplayApp display_app; 00066 static int Vfield_Int_Cnt = 0; 00067 00068 static int decode_wait_time = 0; 00069 static void (*p_callback_func)(char * addr, int size); 00070 00071 static void JcuEncodeCallBackFunc(JPEG_Converter::jpeg_conv_error_t err_code) { 00072 if (err_code == JPEG_Converter::JPEG_CONV_OK) { 00073 jcu_buf_index_write_done = jcu_buf_index_write; 00074 image_change = 1; 00075 } 00076 jcu_encoding = 0; 00077 } 00078 00079 static void snapshot(void) { 00080 while ((jcu_encoding == 1) || (image_change == 0)) { 00081 Thread::wait(1); 00082 } 00083 jcu_buf_index_read = jcu_buf_index_write_done; 00084 image_change = 0; 00085 display_app.SendJpeg(JpegBuffer[jcu_buf_index_read], (int)jcu_encode_size[jcu_buf_index_read]); 00086 } 00087 00088 static void IntCallbackFunc_Vfield(DisplayBase::int_type_t int_type) { 00089 if (Vfield_Int_Cnt < VFIELD_INT_SKIP_CNT) { 00090 Vfield_Int_Cnt++; 00091 return; 00092 } 00093 Vfield_Int_Cnt = 0; 00094 00095 //Interrupt callback function 00096 if (jcu_encoding == 0) { 00097 JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; 00098 JPEG_Converter::encode_options_t encode_options; 00099 00100 bitmap_buff_info.width = VIDEO_PIXEL_HW; 00101 bitmap_buff_info.height = VIDEO_PIXEL_VW; 00102 bitmap_buff_info.format = JPEG_Converter::WR_RD_YCbCr422; 00103 bitmap_buff_info.buffer_address = (void *)user_frame_buffer0; 00104 00105 encode_options.encode_buff_size = sizeof(JpegBuffer[0]); 00106 encode_options.p_EncodeCallBackFunc = &JcuEncodeCallBackFunc; 00107 // encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; 00108 encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_16_8BIT; 00109 00110 jcu_encoding = 1; 00111 if (jcu_buf_index_read == jcu_buf_index_write) { 00112 jcu_buf_index_write ^= 1; // toggle 00113 } 00114 jcu_encode_size[jcu_buf_index_write] = 0; 00115 dcache_invalid(JpegBuffer[jcu_buf_index_write], sizeof(JpegBuffer[0])); 00116 if (Jcu.encode(&bitmap_buff_info, JpegBuffer[jcu_buf_index_write], 00117 &jcu_encode_size[jcu_buf_index_write], &encode_options) != JPEG_Converter::JPEG_CONV_OK) { 00118 jcu_encode_size[jcu_buf_index_write] = 0; 00119 jcu_encoding = 0; 00120 } 00121 } 00122 } 00123 #endif 00124 00125 static void Start_Video_Camera(void) { 00126 // Video capture setting (progressive form fixed) 00127 Display.Video_Write_Setting( 00128 DisplayBase::VIDEO_INPUT_CHANNEL_0, 00129 DisplayBase::COL_SYS_NTSC_358, 00130 (void *)user_frame_buffer0, 00131 FRAME_BUFFER_STRIDE, 00132 VIDEO_FORMAT, 00133 WR_RD_WRSWA, 00134 VIDEO_PIXEL_VW, 00135 VIDEO_PIXEL_HW 00136 ); 00137 EasyAttach_CameraStart(Display, DisplayBase::VIDEO_INPUT_CHANNEL_0); 00138 } 00139 00140 #if MBED_CONF_APP_LCD 00141 static void Start_LCD_Display(void) { 00142 DisplayBase::rect_t rect; 00143 00144 rect.vs = 0; 00145 rect.vw = LCD_PIXEL_HEIGHT; 00146 rect.hs = 0; 00147 rect.hw = LCD_PIXEL_WIDTH; 00148 Display.Graphics_Read_Setting( 00149 DisplayBase::GRAPHICS_LAYER_0, 00150 (void *)user_frame_buffer0, 00151 FRAME_BUFFER_STRIDE, 00152 GRAPHICS_FORMAT, 00153 WR_RD_WRSWA, 00154 &rect 00155 ); 00156 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_0); 00157 00158 Thread::wait(50); 00159 EasyAttach_LcdBacklight(true); 00160 } 00161 00162 #define VIDEO_PIXEL_HW_STR (VIDEO_PIXEL_HW - 64) 00163 #define VIDEO_PIXEL_VW_STR (VIDEO_PIXEL_VW - 64) 00164 #define FRAME_BUFFER_BYTE_PER_PIXEL_STR (2u) 00165 #define FRAME_BUFFER_STRIDE_STR (((VIDEO_PIXEL_HW_STR * FRAME_BUFFER_BYTE_PER_PIXEL_STR) + 31u) & ~31u) 00166 00167 static uint8_t user_frame_buffer_string[FRAME_BUFFER_STRIDE_STR * VIDEO_PIXEL_VW_STR]__attribute((section("NC_BSS"),aligned(32))); 00168 static AsciiFont ascii_font(user_frame_buffer_string, VIDEO_PIXEL_HW_STR, VIDEO_PIXEL_VW_STR, FRAME_BUFFER_STRIDE_STR, FRAME_BUFFER_BYTE_PER_PIXEL_STR); 00169 static bool string_draw; 00170 static int error_cnt; 00171 00172 static void decode_string_init(void) { 00173 DisplayBase::rect_t rect; 00174 00175 /* The layer by which the touch panel location is drawn */ 00176 ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00177 rect.vs = 32; 00178 rect.vw = VIDEO_PIXEL_VW_STR; 00179 rect.hs = 32; 00180 rect.hw = VIDEO_PIXEL_HW_STR; 00181 Display.Graphics_Read_Setting( 00182 DisplayBase::GRAPHICS_LAYER_2, 00183 (void *)user_frame_buffer_string, 00184 FRAME_BUFFER_STRIDE_STR, 00185 DisplayBase::GRAPHICS_FORMAT_ARGB4444, 00186 DisplayBase::WR_RD_WRSWA_32_16BIT, 00187 &rect 00188 ); 00189 Display.Graphics_Start(DisplayBase::GRAPHICS_LAYER_2); 00190 string_draw = false; 00191 error_cnt = 0; 00192 } 00193 00194 static void decode_string_disp(char ** decode_str) { 00195 if ((decode_str != NULL) && (*decode_str != NULL)) { 00196 /* Drow string */ 00197 ascii_font.Erase(0x00000090); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00198 int rest_size = strlen(*decode_str); 00199 int draw_idx = 0; 00200 int draw_size; 00201 int draw_line = 0; 00202 00203 while (rest_size > 0) { 00204 draw_size = ascii_font.DrawStr(*decode_str + draw_idx, 6, 5 + (18 * draw_line), 0x0000ffff, 2); 00205 if (draw_size <= 0) { 00206 break; 00207 } 00208 rest_size -= draw_size; 00209 draw_idx += draw_size; 00210 draw_line++; 00211 } 00212 string_draw = true; 00213 error_cnt = 0; 00214 } else { 00215 if (string_draw != false) { 00216 error_cnt++; 00217 if (error_cnt > 15) { 00218 /* Clear string */ 00219 ascii_font.Erase(0x00000000); /* rrrrGBAR (r:Reserve G:Green B:Blue A:Alpha R:Red */ 00220 string_draw = false; 00221 } 00222 } 00223 } 00224 } 00225 #endif 00226 00227 00228 /****** zxing_init ******/ 00229 void zxing_init(void (*pfunc)(char * addr, int size)) { 00230 // Initialize the background to black 00231 for (int i = 0; i < (int)sizeof(user_frame_buffer0); i += 2) { 00232 user_frame_buffer0[i + 0] = 0x10; 00233 user_frame_buffer0[i + 1] = 0x80; 00234 } 00235 00236 #if MBED_CONF_APP_LCD 00237 EasyAttach_Init(Display, 640, 360); 00238 #else 00239 EasyAttach_Init(Display); 00240 #endif 00241 #if JPEG_SEND 00242 Jcu.SetQuality(JPEG_ENCODE_QUALITY); 00243 // Interrupt callback function setting (Field end signal for recording function in scaler 0) 00244 Display.Graphics_Irq_Handler_Set(DisplayBase::INT_TYPE_S0_VFIELD, 0, IntCallbackFunc_Vfield); 00245 #endif 00246 Start_Video_Camera(); 00247 #if MBED_CONF_APP_LCD 00248 decode_string_init(); 00249 Start_LCD_Display(); 00250 #endif 00251 00252 p_callback_func = pfunc; 00253 decode_timer.reset(); 00254 decode_timer.start(); 00255 } 00256 00257 /****** zxing_main ******/ 00258 int zxing_loop() { 00259 int decode_result = -1; 00260 vector<Ref<Result> > results; 00261 char ** decode_str = NULL; 00262 00263 /* Decode barcode image */ 00264 if (decode_timer.read_ms() >= decode_wait_time) { 00265 decode_timer.reset(); 00266 DecodeHints hints(DECODE_HINTS); 00267 hints.setTryHarder(false); 00268 decode_result = ex_decode(user_frame_buffer0, (FRAME_BUFFER_STRIDE * VIDEO_PIXEL_VW), VIDEO_PIXEL_HW, VIDEO_PIXEL_VW, &results, hints); 00269 if (decode_result == 0) { 00270 decode_str = (char **)&(results[0]->getText()->getText()); 00271 int size = strlen(*decode_str); 00272 if (p_callback_func != NULL) { 00273 p_callback_func(*decode_str, size); 00274 } 00275 decode_wait_time = 500; 00276 } else { 00277 decode_wait_time = 10; 00278 } 00279 #if MBED_CONF_APP_LCD 00280 decode_string_disp(decode_str); 00281 #endif 00282 } 00283 00284 return decode_result; 00285 } 00286
Generated on Wed Jul 13 2022 20:01:58 by 1.7.2