From 45f3a7754850a595bfaeaa3a82f49b1cc69d8be7 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Thu, 6 Jul 2023 02:26:56 +0300 Subject: [PATCH] barcodes --- ReadMe.md | 2 +- applications/external/barcode_gen/LICENSE | 22 + applications/external/barcode_gen/README.md | 88 +++ .../external/barcode_gen/application.fam | 16 + .../external/barcode_gen/barcode_app.c | 348 ++++++++++++ .../external/barcode_gen/barcode_app.h | 91 +++ .../external/barcode_gen/barcode_utils.c | 147 +++++ .../external/barcode_gen/barcode_utils.h | 55 ++ .../external/barcode_gen/barcode_validator.c | 532 ++++++++++++++++++ .../external/barcode_gen/barcode_validator.h | 15 + applications/external/barcode_gen/encodings.c | 52 ++ applications/external/barcode_gen/encodings.h | 6 + .../barcode_gen/images/barcode_10.png | Bin 0 -> 161 bytes .../screenshots/Codabar Data Example.png | Bin 0 -> 1672 bytes .../screenshots/Creating Barcode.png | Bin 0 -> 1681 bytes .../screenshots/Flipper Barcode.png | Bin 0 -> 1207 bytes .../screenshots/Flipper Box Barcode.png | Bin 0 -> 1372 bytes .../external/barcode_gen/views/barcode_view.c | 510 +++++++++++++++++ .../external/barcode_gen/views/barcode_view.h | 23 + .../external/barcode_gen/views/create_view.c | 494 ++++++++++++++++ .../external/barcode_gen/views/create_view.h | 46 ++ .../external/barcode_gen/views/message_view.c | 66 +++ .../external/barcode_gen/views/message_view.h | 22 + .../barcode_generator/application.fam | 17 - .../barcode_generator/barcode_10px.png | Bin 2363 -> 0 bytes .../barcode_generator/barcode_generator.c | 447 --------------- .../barcode_generator/barcode_generator.h | 115 ---- .../barcode_data/codabar_encodings.txt | 22 + .../barcode_data/code128_encodings.txt | 202 +++++++ .../barcode_data/code128c_encodings.txt | 106 ++++ .../barcode_data/code39_encodings.txt | 44 ++ 31 files changed, 2908 insertions(+), 580 deletions(-) create mode 100644 applications/external/barcode_gen/LICENSE create mode 100644 applications/external/barcode_gen/README.md create mode 100644 applications/external/barcode_gen/application.fam create mode 100644 applications/external/barcode_gen/barcode_app.c create mode 100644 applications/external/barcode_gen/barcode_app.h create mode 100644 applications/external/barcode_gen/barcode_utils.c create mode 100644 applications/external/barcode_gen/barcode_utils.h create mode 100644 applications/external/barcode_gen/barcode_validator.c create mode 100644 applications/external/barcode_gen/barcode_validator.h create mode 100644 applications/external/barcode_gen/encodings.c create mode 100644 applications/external/barcode_gen/encodings.h create mode 100644 applications/external/barcode_gen/images/barcode_10.png create mode 100644 applications/external/barcode_gen/screenshots/Codabar Data Example.png create mode 100644 applications/external/barcode_gen/screenshots/Creating Barcode.png create mode 100644 applications/external/barcode_gen/screenshots/Flipper Barcode.png create mode 100644 applications/external/barcode_gen/screenshots/Flipper Box Barcode.png create mode 100644 applications/external/barcode_gen/views/barcode_view.c create mode 100644 applications/external/barcode_gen/views/barcode_view.h create mode 100644 applications/external/barcode_gen/views/create_view.c create mode 100644 applications/external/barcode_gen/views/create_view.h create mode 100644 applications/external/barcode_gen/views/message_view.c create mode 100644 applications/external/barcode_gen/views/message_view.h delete mode 100644 applications/external/barcode_generator/application.fam delete mode 100644 applications/external/barcode_generator/barcode_10px.png delete mode 100644 applications/external/barcode_generator/barcode_generator.c delete mode 100644 applications/external/barcode_generator/barcode_generator.h create mode 100644 assets/resources/apps_data/barcode_data/codabar_encodings.txt create mode 100644 assets/resources/apps_data/barcode_data/code128_encodings.txt create mode 100644 assets/resources/apps_data/barcode_data/code128c_encodings.txt create mode 100644 assets/resources/apps_data/barcode_data/code39_encodings.txt diff --git a/ReadMe.md b/ReadMe.md index 28c580a3c..b589e164e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -145,7 +145,7 @@ You can support us by using links or addresses below: - WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module) - MultiConverter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff) - WAV Player [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) - Fixed and improved by [LTVA1](https://github.com/LTVA1/wav_player) -> Also outputs audio on `PA6` - `3(A6)` pin -- Barcode generator plugin [(original by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) - [EAN-8 and refactoring](https://github.com/DarkFlippers/unleashed-firmware/pull/154) by @msvsergey +- Barcode Generator [(by Kingal1337)](https://github.com/Kingal1337/flipper-barcode-generator) - GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin) - ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-wifi-marauder) - Saving .pcap on flipper microSD [by tcpassos](https://github.com/tcpassos/flipperzero-firmware-with-wifi-marauder-companion) -> Only with custom marauder build (It is necessary to uncomment "#define WRITE_PACKETS_SERIAL" in configs.h (in marauder fw) and compile the firmware for the wifi board.) Or download precompiled build -> [Download esp32_marauder_ver_flipper_sd_serial.bin](https://github.com/justcallmekoko/ESP32Marauder/releases/latest) - NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker) diff --git a/applications/external/barcode_gen/LICENSE b/applications/external/barcode_gen/LICENSE new file mode 100644 index 000000000..4c02d8221 --- /dev/null +++ b/applications/external/barcode_gen/LICENSE @@ -0,0 +1,22 @@ + +MIT License + +Copyright (c) 2023 Alan Tsui + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/applications/external/barcode_gen/README.md b/applications/external/barcode_gen/README.md new file mode 100644 index 000000000..ec944cb26 --- /dev/null +++ b/applications/external/barcode_gen/README.md @@ -0,0 +1,88 @@ +

+

Barcode Generator

+

+ +A barcode generator for the Flipper Zero that supports **UPC-A**, **EAN-8**, **EAN-13**, **Code-39**, **Codabar**, and **Code-128**[1] +

+ +Note: Barcode save locations have been moved from `/barcodes` to `/apps_data/barcodes` + +## Table of Contents +- [Table of Contents](#table-of-contents) +- [Installing](#installing) +- [Building](#building) +- [Usage](#usage) + - [Creating a barcode](#creating-a-barcode) + - [Editing a barcode](#editing-a-barcode) + - [Deleting a barcode](#deleting-a-barcode) + - [Viewing a barcode](#viewing-a-barcode) +- [Screenshots](#screenshots) +- [Credits](#credits) + + +## Installing +1) Download the `.zip` file from the release section +2) Extract/unzip the `.zip` file onto your computer +3) Open qFlipper and go to the file manager +4) Navigate to the `apps` folder +5) Drag & drop the `.fap` file into the `apps` folder +6) Navigate back to the root folder of the SD card and create the folder `apps_data`, if not already there +7) Navigate into `apps_data` and create another folder called `barcode_data` +8) Navigate into `barcode_data` +9) Drag & drop the encoding txts (`code39_encodings.txt`, `code128_encodings.txt` & `codabar_encodings.txt`) into the `barcode_data` folder + +## Building +1) Clone the [flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware) repository or a firmware of your choice +2) Clone this repository and put it in the `applications_user` folder +3) Build this app by using the command `./fbt fap_Barcode_App` +4) Copy the `.fap` from `build\f7-firmware-D\.extapps\Barcode_App.fap` to `apps\Misc` using the qFlipper app +5) While still in the qFlipper app, navigate to the root folder of the SD card and create the folder `apps_data`, if not already there +6) Navigate into `apps_data` and create another folder called `barcode_data` +7) Navigate into `barcode_data` +8) Drag & drop the encoding txts (`code39_encodings.txt`, `code128_encodings.txt` & `codabar_encodings.txt`) from the `encoding_tables` folder in this repository into the `barcode_data` folder + +## Usage + +### Creating a barcode +1) To create a barcode click on `Create Barcode` +2) Next select your type using the left and right arrows +3) Enter your filename and then your barcode data +4) Click save + +**Note**: For Codabar barcodes, you must manually add the start and stop codes to the barcode data +Start/Stop codes can be A, B, C, or D +For example, if you wanted to represent `1234` as a barcode you will need to enter something like `A1234A`. (You can replace the letters A with either A, B, C, or D) + +![Codabar Data Example](screenshots/Codabar%20Data%20Example.png "Codabar Data Example") + +### Editing a barcode +1) To edit a barcode click on `Edit Barcode` +2) Next select the barcode file you want to edit +3) Edit the type, name, or data +4) Click save + +### Deleting a barcode +1) To delete a barcode click on `Edit Barcode` +2) Next select the barcode file you want to delete +3) Scroll all the way to the bottom +4) Click delete + +### Viewing a barcode +1) To view a barcode click on `Load Barcode` +2) Next select the barcode file you want to view + +## Screenshots +![Barcode Create Screen](screenshots/Creating%20Barcode.png "Barcode Create Screen") + +![Flipper Code-128 Barcode](screenshots/Flipper%20Barcode.png "Flipper Code-128 Barcode") + +![Flipper Box EAN-13 Barcode](screenshots/Flipper%20Box%20Barcode.png "Flipper Box EAN-13 Barcode") + +## Credits + +- [Kingal1337](https://github.com/Kingal1337) - Developer +- [Z0wl](https://github.com/Z0wl) - Added Code128-C Support +- [@teeebor](https://github.com/teeebor) - Menu Code Snippet + + +[1] - supports Set B (only the characters from 0-94). Also supports Set C diff --git a/applications/external/barcode_gen/application.fam b/applications/external/barcode_gen/application.fam new file mode 100644 index 000000000..371e52c04 --- /dev/null +++ b/applications/external/barcode_gen/application.fam @@ -0,0 +1,16 @@ +App( + appid="barcode_app", + name="Barcode App", + apptype=FlipperAppType.EXTERNAL, + entry_point="barcode_main", + requires=["gui", "storage"], + stack_size=2 * 1024, + fap_category="Tools", + fap_icon="images/barcode_10.png", + fap_icon_assets="images", + fap_icon_assets_symbol="barcode_app", + fap_author="@Kingal1337", + fap_weburl="https://github.com/Kingal1337/flipper-barcode-generator", + fap_version="1.0", + fap_description="App allows you to display various barcodes on flipper screen", +) diff --git a/applications/external/barcode_gen/barcode_app.c b/applications/external/barcode_gen/barcode_app.c new file mode 100644 index 000000000..99e5769d2 --- /dev/null +++ b/applications/external/barcode_gen/barcode_app.c @@ -0,0 +1,348 @@ +#include "barcode_app.h" + +#include "barcode_app_icons.h" + +/** + * Opens a file browser dialog and returns the filepath of the selected file + * + * @param folder the folder to view when the browser opens + * @param file_path a string pointer for the file_path when a file is selected, + * file_path will be the folder path is nothing is selected + * @returns true if a file is selected +*/ +static bool select_file(const char* folder, FuriString* file_path) { + DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); + DialogsFileBrowserOptions browser_options; + dialog_file_browser_set_basic_options(&browser_options, "", &I_barcode_10); + browser_options.base_path = DEFAULT_USER_BARCODES; + furi_string_set(file_path, folder); + + bool res = dialog_file_browser_show(dialogs, file_path, file_path, &browser_options); + + furi_record_close(RECORD_DIALOGS); + + return res; +} + +/** + * Reads the data from a file and stores them in the FuriStrings raw_type and raw_data +*/ +ErrorCode read_raw_data(FuriString* file_path, FuriString* raw_type, FuriString* raw_data) { + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + ErrorCode reason = OKCode; + + if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(file_path))) { + FURI_LOG_E(TAG, "Could not open file %s", furi_string_get_cstr(file_path)); + reason = FileOpening; + } else { + if(!flipper_format_read_string(ff, "Type", raw_type)) { + FURI_LOG_E(TAG, "Could not read \"Type\" string"); + reason = InvalidFileData; + } + if(!flipper_format_read_string(ff, "Data", raw_data)) { + FURI_LOG_E(TAG, "Could not read \"Data\" string"); + reason = InvalidFileData; + } + } + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + return reason; +} + +/** + * Gets the file name from a file path + * @param file_path the file path + * @param file_name the FuriString to store the file name + * @param remove_extension true if the extension should be removed, otherwise false +*/ +bool get_file_name_from_path(FuriString* file_path, FuriString* file_name, bool remove_extension) { + if(file_path == NULL || file_name == NULL) { + return false; + } + uint32_t slash_index = furi_string_search_rchar(file_path, '/', 0); + if(slash_index == FURI_STRING_FAILURE || slash_index >= (furi_string_size(file_path) - 1)) { + return false; + } + + furi_string_set(file_name, file_path); + furi_string_right(file_name, slash_index + 1); + if(remove_extension) { + uint32_t ext_index = furi_string_search_rchar(file_name, '.', 0); + if(ext_index != FURI_STRING_FAILURE && ext_index < (furi_string_size(file_path))) { + furi_string_left(file_name, ext_index); + } + } + + return true; +} + +/** + * Creates the barcode folder +*/ +void init_folder() { + Storage* storage = furi_record_open(RECORD_STORAGE); + FURI_LOG_I(TAG, "Creating barcodes folder"); + if(storage_simply_mkdir(storage, DEFAULT_USER_BARCODES)) { + FURI_LOG_I(TAG, "Barcodes folder successfully created!"); + } else { + FURI_LOG_I(TAG, "Barcodes folder already exists."); + } + furi_record_close(RECORD_STORAGE); +} + +void select_barcode_item(BarcodeApp* app) { + FuriString* file_path = furi_string_alloc(); + FuriString* raw_type = furi_string_alloc(); + FuriString* raw_data = furi_string_alloc(); + + //this determines if the data was read correctly or if the + bool loaded_success = true; + ErrorCode reason = OKCode; + + bool file_selected = select_file(DEFAULT_USER_BARCODES, file_path); + if(file_selected) { + FURI_LOG_I(TAG, "The file selected is %s", furi_string_get_cstr(file_path)); + Barcode* barcode = app->barcode_view; + + reason = read_raw_data(file_path, raw_type, raw_data); + if(reason != OKCode) { + loaded_success = false; + FURI_LOG_E(TAG, "Could not read data correctly"); + } + + //Free the data from the previous barcode + barcode_free_model(barcode); + + with_view_model( + barcode->view, + BarcodeModel * model, + { + model->file_path = furi_string_alloc_set(file_path); + + model->data = malloc(sizeof(BarcodeData)); + model->data->valid = loaded_success; + + if(loaded_success) { + model->data->raw_data = furi_string_alloc_set(raw_data); + model->data->correct_data = furi_string_alloc(); + + model->data->type_obj = get_type(raw_type); + + barcode_loader(model->data); + } else { + model->data->reason = reason; + } + }, + true); + + view_dispatcher_switch_to_view(app->view_dispatcher, BarcodeView); + } + + furi_string_free(raw_type); + furi_string_free(raw_data); + furi_string_free(file_path); +} + +void edit_barcode_item(BarcodeApp* app) { + FuriString* file_path = furi_string_alloc(); + FuriString* file_name = furi_string_alloc(); + FuriString* raw_type = furi_string_alloc(); + FuriString* raw_data = furi_string_alloc(); + + //this determines if the data was read correctly or if the + ErrorCode reason = OKCode; + + bool file_selected = select_file(DEFAULT_USER_BARCODES, file_path); + if(file_selected) { + FURI_LOG_I(TAG, "The file selected is %s", furi_string_get_cstr(file_path)); + CreateView* create_view_object = app->create_view; + + reason = read_raw_data(file_path, raw_type, raw_data); + if(reason != OKCode) { + FURI_LOG_E(TAG, "Could not read data correctly"); + with_view_model( + app->message_view->view, + MessageViewModel * model, + { model->message = get_error_code_message(reason); }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); + + } else { + BarcodeTypeObj* type_obj = get_type(raw_type); + if(type_obj->type == UNKNOWN) { + type_obj = barcode_type_objs[0]; + } + get_file_name_from_path(file_path, file_name, true); + + create_view_free_model(create_view_object); + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = 0; + model->barcode_type = type_obj; + model->file_path = furi_string_alloc_set(file_path); + model->file_name = furi_string_alloc_set(file_name); + model->barcode_data = furi_string_alloc_set(raw_data); + model->mode = EditMode; + }, + true); + view_dispatcher_switch_to_view(app->view_dispatcher, CreateBarcodeView); + } + } + + furi_string_free(raw_type); + furi_string_free(raw_data); + furi_string_free(file_name); + furi_string_free(file_path); +} + +void create_barcode_item(BarcodeApp* app) { + CreateView* create_view_object = app->create_view; + + create_view_free_model(create_view_object); + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = 0; + model->barcode_type = barcode_type_objs[0]; + model->file_path = furi_string_alloc(); + model->file_name = furi_string_alloc(); + model->barcode_data = furi_string_alloc(); + model->mode = NewMode; + }, + true); + view_dispatcher_switch_to_view(app->view_dispatcher, CreateBarcodeView); +} + +void submenu_callback(void* context, uint32_t index) { + furi_assert(context); + + BarcodeApp* app = context; + + if(index == SelectBarcodeItem) { + select_barcode_item(app); + } else if(index == EditBarcodeItem) { + edit_barcode_item(app); + } else if(index == CreateBarcodeItem) { + create_barcode_item(app); + } +} + +uint32_t create_view_callback(void* context) { + UNUSED(context); + return CreateBarcodeView; +} + +uint32_t main_menu_callback(void* context) { + UNUSED(context); + return MainMenuView; +} + +uint32_t exit_callback(void* context) { + UNUSED(context); + return VIEW_NONE; +} + +void free_app(BarcodeApp* app) { + FURI_LOG_I(TAG, "Freeing Data"); + + init_folder(); + free_types(); + + view_dispatcher_remove_view(app->view_dispatcher, TextInputView); + text_input_free(app->text_input); + + view_dispatcher_remove_view(app->view_dispatcher, MessageErrorView); + message_view_free(app->message_view); + + view_dispatcher_remove_view(app->view_dispatcher, MainMenuView); + submenu_free(app->main_menu); + + view_dispatcher_remove_view(app->view_dispatcher, CreateBarcodeView); + create_view_free(app->create_view); + + view_dispatcher_remove_view(app->view_dispatcher, BarcodeView); + barcode_free(app->barcode_view); + + //free the dispatcher + view_dispatcher_free(app->view_dispatcher); + + furi_message_queue_free(app->event_queue); + + furi_record_close(RECORD_GUI); + app->gui = NULL; + + free(app); +} + +int32_t barcode_main(void* p) { + UNUSED(p); + BarcodeApp* app = malloc(sizeof(BarcodeApp)); + init_types(); + app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); + + // Register view port in GUI + app->gui = furi_record_open(RECORD_GUI); + + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->main_menu = submenu_alloc(); + submenu_add_item(app->main_menu, "Load Barcode", SelectBarcodeItem, submenu_callback, app); + view_set_previous_callback(submenu_get_view(app->main_menu), exit_callback); + view_dispatcher_add_view(app->view_dispatcher, MainMenuView, submenu_get_view(app->main_menu)); + + submenu_add_item(app->main_menu, "Edit Barcode", EditBarcodeItem, submenu_callback, app); + + /***************************** + * Creating Text Input View + ******************************/ + app->text_input = text_input_alloc(); + view_set_previous_callback(text_input_get_view(app->text_input), create_view_callback); + view_dispatcher_add_view( + app->view_dispatcher, TextInputView, text_input_get_view(app->text_input)); + + /***************************** + * Creating Message View + ******************************/ + app->message_view = message_view_allocate(app); + view_dispatcher_add_view( + app->view_dispatcher, MessageErrorView, message_get_view(app->message_view)); + + /***************************** + * Creating Create View + ******************************/ + app->create_view = create_view_allocate(app); + submenu_add_item(app->main_menu, "Create Barcode", CreateBarcodeItem, submenu_callback, app); + view_set_previous_callback(create_get_view(app->create_view), main_menu_callback); + view_dispatcher_add_view( + app->view_dispatcher, CreateBarcodeView, create_get_view(app->create_view)); + + /***************************** + * Creating Barcode View + ******************************/ + app->barcode_view = barcode_view_allocate(app); + view_set_previous_callback(barcode_get_view(app->barcode_view), main_menu_callback); + view_dispatcher_add_view( + app->view_dispatcher, BarcodeView, barcode_get_view(app->barcode_view)); + + //switch view to submenu and run dispatcher + view_dispatcher_switch_to_view(app->view_dispatcher, MainMenuView); + view_dispatcher_run(app->view_dispatcher); + + free_app(app); + + return 0; +} diff --git a/applications/external/barcode_gen/barcode_app.h b/applications/external/barcode_gen/barcode_app.h new file mode 100644 index 000000000..3150bff1f --- /dev/null +++ b/applications/external/barcode_gen/barcode_app.h @@ -0,0 +1,91 @@ +#pragma once +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "barcode_utils.h" + +#define TAG "BARCODE" +#define VERSION "1.1" +#define FILE_VERSION "1" + +#define TEXT_BUFFER_SIZE 128 + +#define BARCODE_HEIGHT 50 +#define BARCODE_Y_START 3 + +//the folder where the encodings are located +#define BARCODE_DATA_FILE_DIR_PATH EXT_PATH("apps_data/barcode_data") + +//the folder where the codabar encoding table is located +#define CODABAR_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/codabar_encodings.txt" + +//the folder where the code 39 encoding table is located +#define CODE39_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code39_encodings.txt" + +//the folder where the code 128 encoding table is located +#define CODE128_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code128_encodings.txt" + +//the folder where the code 128 C encoding table is located +#define CODE128C_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code128c_encodings.txt" + +//the folder where the user stores their barcodes +#define DEFAULT_USER_BARCODES EXT_PATH("apps_data/barcodes") + +//The extension barcode files use +#define BARCODE_EXTENSION ".txt" +#define BARCODE_EXTENSION_LENGTH 4 + +#include "views/barcode_view.h" +#include "views/create_view.h" +#include "views/message_view.h" +#include "barcode_validator.h" + +typedef struct BarcodeApp BarcodeApp; + +struct BarcodeApp { + Submenu* main_menu; + ViewDispatcher* view_dispatcher; + Gui* gui; + + FuriMessageQueue* event_queue; + + CreateView* create_view; + Barcode* barcode_view; + + MessageView* message_view; + TextInput* text_input; +}; + +enum SubmenuItems { + SelectBarcodeItem, + EditBarcodeItem, + + CreateBarcodeItem +}; + +enum Views { + TextInputView, + MessageErrorView, + MainMenuView, + CreateBarcodeView, + + BarcodeView +}; + +void submenu_callback(void* context, uint32_t index); + +uint32_t main_menu_callback(void* context); + +uint32_t exit_callback(void* context); + +int32_t barcode_main(void* p); diff --git a/applications/external/barcode_gen/barcode_utils.c b/applications/external/barcode_gen/barcode_utils.c new file mode 100644 index 000000000..31274c1fe --- /dev/null +++ b/applications/external/barcode_gen/barcode_utils.c @@ -0,0 +1,147 @@ +#include "barcode_utils.h" + +BarcodeTypeObj* barcode_type_objs[NUMBER_OF_BARCODE_TYPES] = {NULL}; + +void init_types() { + BarcodeTypeObj* upc_a = malloc(sizeof(BarcodeTypeObj)); + upc_a->name = "UPC-A"; + upc_a->type = UPCA; + upc_a->min_digits = 11; + upc_a->max_digits = 12; + upc_a->start_pos = 16; + barcode_type_objs[UPCA] = upc_a; + + BarcodeTypeObj* ean_8 = malloc(sizeof(BarcodeTypeObj)); + ean_8->name = "EAN-8"; + ean_8->type = EAN8; + ean_8->min_digits = 7; + ean_8->max_digits = 8; + ean_8->start_pos = 32; + barcode_type_objs[EAN8] = ean_8; + + BarcodeTypeObj* ean_13 = malloc(sizeof(BarcodeTypeObj)); + ean_13->name = "EAN-13"; + ean_13->type = EAN13; + ean_13->min_digits = 12; + ean_13->max_digits = 13; + ean_13->start_pos = 16; + barcode_type_objs[EAN13] = ean_13; + + BarcodeTypeObj* code_39 = malloc(sizeof(BarcodeTypeObj)); + code_39->name = "CODE-39"; + code_39->type = CODE39; + code_39->min_digits = 1; + code_39->max_digits = -1; + code_39->start_pos = 0; + barcode_type_objs[CODE39] = code_39; + + BarcodeTypeObj* code_128 = malloc(sizeof(BarcodeTypeObj)); + code_128->name = "CODE-128"; + code_128->type = CODE128; + code_128->min_digits = 1; + code_128->max_digits = -1; + code_128->start_pos = 0; + barcode_type_objs[CODE128] = code_128; + + BarcodeTypeObj* code_128c = malloc(sizeof(BarcodeTypeObj)); + code_128c->name = "CODE-128C"; + code_128c->type = CODE128C; + code_128c->min_digits = 2; + code_128c->max_digits = -1; + code_128c->start_pos = 0; + barcode_type_objs[CODE128C] = code_128c; + + BarcodeTypeObj* codabar = malloc(sizeof(BarcodeTypeObj)); + codabar->name = "Codabar"; + codabar->type = CODABAR; + codabar->min_digits = 1; + codabar->max_digits = -1; + codabar->start_pos = 0; + barcode_type_objs[CODABAR] = codabar; + + BarcodeTypeObj* unknown = malloc(sizeof(BarcodeTypeObj)); + unknown->name = "Unknown"; + unknown->type = UNKNOWN; + unknown->min_digits = 0; + unknown->max_digits = 0; + unknown->start_pos = 0; + barcode_type_objs[UNKNOWN] = unknown; +} + +void free_types() { + for(int i = 0; i < NUMBER_OF_BARCODE_TYPES; i++) { + free(barcode_type_objs[i]); + } +} + +BarcodeTypeObj* get_type(FuriString* type_string) { + if(furi_string_cmp_str(type_string, "UPC-A") == 0) { + return barcode_type_objs[UPCA]; + } + if(furi_string_cmp_str(type_string, "EAN-8") == 0) { + return barcode_type_objs[EAN8]; + } + if(furi_string_cmp_str(type_string, "EAN-13") == 0) { + return barcode_type_objs[EAN13]; + } + if(furi_string_cmp_str(type_string, "CODE-39") == 0) { + return barcode_type_objs[CODE39]; + } + if(furi_string_cmp_str(type_string, "CODE-128") == 0) { + return barcode_type_objs[CODE128]; + } + if(furi_string_cmp_str(type_string, "CODE-128C") == 0) { + return barcode_type_objs[CODE128C]; + } + if(furi_string_cmp_str(type_string, "Codabar") == 0) { + return barcode_type_objs[CODABAR]; + } + + return barcode_type_objs[UNKNOWN]; +} + +const char* get_error_code_name(ErrorCode error_code) { + switch(error_code) { + case WrongNumberOfDigits: + return "Wrong Number Of Digits"; + case InvalidCharacters: + return "Invalid Characters"; + case UnsupportedType: + return "Unsupported Type"; + case FileOpening: + return "File Opening Error"; + case InvalidFileData: + return "Invalid File Data"; + case MissingEncodingTable: + return "Missing Encoding Table"; + case EncodingTableError: + return "Encoding Table Error"; + case OKCode: + return "OK"; + default: + return "Unknown Code"; + }; +} + +const char* get_error_code_message(ErrorCode error_code) { + switch(error_code) { + case WrongNumberOfDigits: + return "Wrong # of characters"; + case InvalidCharacters: + return "Invalid characters"; + case UnsupportedType: + return "Unsupported barcode type"; + case FileOpening: + return "Could not open file"; + case InvalidFileData: + return "Invalid file data"; + case MissingEncodingTable: + return "Missing encoding table"; + case EncodingTableError: + return "Encoding table error"; + case OKCode: + return "OK"; + default: + return "Could not read barcode data"; + }; +} diff --git a/applications/external/barcode_gen/barcode_utils.h b/applications/external/barcode_gen/barcode_utils.h new file mode 100644 index 000000000..0a27785cf --- /dev/null +++ b/applications/external/barcode_gen/barcode_utils.h @@ -0,0 +1,55 @@ + +#pragma once +#include +#include + +#define NUMBER_OF_BARCODE_TYPES 8 + +typedef enum { + WrongNumberOfDigits, //There is too many or too few digits in the barcode + InvalidCharacters, //The barcode contains invalid characters + UnsupportedType, //the barcode type is not supported + FileOpening, //A problem occurred when opening the barcode data file + InvalidFileData, //One of the key in the file doesn't exist or there is a typo + MissingEncodingTable, //The encoding table txt for the barcode type is missing + EncodingTableError, //Something is wrong with the encoding table, probably missing data or typo + OKCode +} ErrorCode; + +typedef enum { + UPCA, + EAN8, + EAN13, + CODE39, + CODE128, + CODE128C, + CODABAR, + + UNKNOWN +} BarcodeType; + +typedef struct { + char* name; //The name of the barcode type + BarcodeType type; //The barcode type enum + int min_digits; //the minimum number of digits + int max_digits; //the maximum number of digits + int start_pos; //where to start drawing the barcode, set to -1 to dynamically draw barcode +} BarcodeTypeObj; + +typedef struct { + BarcodeTypeObj* type_obj; + int check_digit; //A place to store the check digit + FuriString* raw_data; //the data directly from the file + FuriString* correct_data; //the corrected/processed data + bool valid; //true if the raw data is correctly formatted, such as correct num of digits, valid characters, etc. + ErrorCode reason; //the reason why this barcode is invalid +} BarcodeData; + +//All available barcode types +extern BarcodeTypeObj* barcode_type_objs[NUMBER_OF_BARCODE_TYPES]; + +void init_types(); +void free_types(); +BarcodeTypeObj* get_type(FuriString* type_string); +const char* get_error_code_name(ErrorCode error_code); +const char* get_error_code_message(ErrorCode error_code); diff --git a/applications/external/barcode_gen/barcode_validator.c b/applications/external/barcode_gen/barcode_validator.c new file mode 100644 index 000000000..cb493f3e9 --- /dev/null +++ b/applications/external/barcode_gen/barcode_validator.c @@ -0,0 +1,532 @@ +#include "barcode_validator.h" + +void barcode_loader(BarcodeData* barcode_data) { + switch(barcode_data->type_obj->type) { + case UPCA: + case EAN8: + case EAN13: + ean_upc_loader(barcode_data); + break; + case CODE39: + code_39_loader(barcode_data); + break; + case CODE128: + code_128_loader(barcode_data); + break; + case CODE128C: + code_128c_loader(barcode_data); + break; + case CODABAR: + codabar_loader(barcode_data); + break; + case UNKNOWN: + barcode_data->reason = UnsupportedType; + barcode_data->valid = false; + default: + break; + } +} + +/** + * Calculates the check digit of a barcode if they have one + * @param barcode_data the barcode data + * @returns a check digit or -1 for either an invalid +*/ +int calculate_check_digit(BarcodeData* barcode_data) { + int check_digit = -1; + switch(barcode_data->type_obj->type) { + case UPCA: + case EAN8: + case EAN13: + check_digit = calculate_ean_upc_check_digit(barcode_data); + break; + case CODE39: + case CODE128: + case CODE128C: + case CODABAR: + case UNKNOWN: + default: + break; + } + + return check_digit; +} + +/** + * Calculates the check digit of barcode types UPC-A, EAN-8, & EAN-13 +*/ +int calculate_ean_upc_check_digit(BarcodeData* barcode_data) { + int check_digit = 0; + int odd = 0; + int even = 0; + + int length = barcode_data->type_obj->min_digits; + + //Get sum of odd digits + for(int i = 0; i < length; i += 2) { + odd += furi_string_get_char(barcode_data->raw_data, i) - '0'; + } + + //Get sum of even digits + for(int i = 1; i < length; i += 2) { + even += furi_string_get_char(barcode_data->raw_data, i) - '0'; + } + + if(barcode_data->type_obj->type == EAN13) { + check_digit = even * 3 + odd; + } else { + check_digit = odd * 3 + even; + } + + check_digit = check_digit % 10; + + return (10 - check_digit) % 10; +} + +/** + * Loads and validates Barcode Types EAN-8, EAN-13, and UPC-A + * barcode_data and its strings should already be allocated; +*/ +void ean_upc_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + int min_digits = barcode_data->type_obj->min_digits; + int max_digit = barcode_data->type_obj->max_digits; + + //check the length of the barcode + if(barcode_length < min_digits || barcode_length > max_digit) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + //checks if the barcode contains any characters that aren't a number + for(int i = 0; i < barcode_length; i++) { + char character = furi_string_get_char(barcode_data->raw_data, i); + int digit = character - '0'; //convert the number into an int (also the index) + if(digit < 0 || digit > 9) { + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + return; + } + } + + int check_digit = calculate_check_digit(barcode_data); + char check_digit_char = check_digit + '0'; + + barcode_data->check_digit = check_digit; + + //if the barcode length is at max length then we will verify if the check digit is correct + if(barcode_length == max_digit) { + //append the raw_data to the correct data string + furi_string_cat(barcode_data->correct_data, barcode_data->raw_data); + + //append the check digit to the correct data string + furi_string_set_char(barcode_data->correct_data, min_digits, check_digit_char); + } + //if the barcode length is at min length, we will calculate the check digit + if(barcode_length == min_digits) { + //append the raw_data to the correct data string + furi_string_cat(barcode_data->correct_data, barcode_data->raw_data); + + //append the check digit to the correct data string + furi_string_push_back(barcode_data->correct_data, check_digit_char); + } +} + +void code_39_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + int min_digits = barcode_data->type_obj->min_digits; + + //check the length of the barcode, must contain atleast a character, + //this can have as many characters as it wants, it might not fit on the screen + if(barcode_length < min_digits) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + FuriString* barcode_bits = furi_string_alloc(); + FuriString* temp_string = furi_string_alloc(); + + //add starting and ending * + if(!furi_string_start_with(barcode_data->raw_data, "*")) { + furi_string_push_back(temp_string, '*'); + furi_string_cat(temp_string, barcode_data->raw_data); + furi_string_set(barcode_data->raw_data, temp_string); + } + + if(!furi_string_end_with(barcode_data->raw_data, "*")) { + furi_string_push_back(barcode_data->raw_data, '*'); + } + + furi_string_free(temp_string); + barcode_length = furi_string_size(barcode_data->raw_data); + + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + if(!flipper_format_file_open_existing(ff, CODE39_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "Could not open file %s", CODE39_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i++) { + char barcode_char = toupper(furi_string_get_char(barcode_data->raw_data, i)); + + //convert a char into a string so it used in flipper_format_read_string + char current_character[2]; + snprintf(current_character, 2, "%c", barcode_char); + + if(!flipper_format_read_string(ff, current_character, char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + break; + } else { + FURI_LOG_I( + TAG, "\"%c\" string: %s", barcode_char, furi_string_get_cstr(char_bits)); + furi_string_cat(barcode_bits, char_bits); + } + flipper_format_rewind(ff); + } + furi_string_free(char_bits); + } + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} + +/** + * Loads a code 128 barcode + * + * Only supports character set B +*/ +void code_128_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + //the start code for character set B + int start_code_value = 104; + + //The bits for the start code + const char* start_code_bits = "11010010000"; + + //The bits for the stop code + const char* stop_code_bits = "1100011101011"; + + int min_digits = barcode_data->type_obj->min_digits; + + /** + * A sum of all of the characters values + * Ex: + * Barcode Data : ABC + * A has a value of 33 + * B has a value of 34 + * C has a value of 35 + * + * the checksum_adder would be (33 * 1) + (34 * 2) + (35 * 3) + 104 = 310 + * + * Add 104 since we are using set B + */ + int checksum_adder = start_code_value; + /** + * Checksum digits is the number of characters it has read so far + * In the above example the checksum_digits would be 3 + */ + int checksum_digits = 0; + + //the calculated check digit + int final_check_digit = 0; + + //check the length of the barcode, must contain atleast a character, + //this can have as many characters as it wants, it might not fit on the screen + if(barcode_length < min_digits) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + FuriString* barcode_bits = furi_string_alloc(); + + //add the start code + furi_string_cat(barcode_bits, start_code_bits); + + if(!flipper_format_file_open_existing(ff, CODE128_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "Could not open file %s", CODE128_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* value = furi_string_alloc(); + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i++) { + char barcode_char = furi_string_get_char(barcode_data->raw_data, i); + + //convert a char into a string so it used in flipper_format_read_string + char current_character[2]; + snprintf(current_character, 2, "%c", barcode_char); + + //get the value of the character + if(!flipper_format_read_string(ff, current_character, value)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + break; + } + //using the value of the character, get the characters bits + if(!flipper_format_read_string(ff, furi_string_get_cstr(value), char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + break; + } else { + //add the bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + //calculate the checksum + checksum_digits += 1; + checksum_adder += (atoi(furi_string_get_cstr(value)) * checksum_digits); + + FURI_LOG_D( + TAG, + "\"%c\" string: %s : %s : %d : %d : %d", + barcode_char, + furi_string_get_cstr(char_bits), + furi_string_get_cstr(value), + checksum_digits, + (atoi(furi_string_get_cstr(value)) * checksum_digits), + checksum_adder); + } + //bring the file pointer back to the beginning + flipper_format_rewind(ff); + } + + //calculate the check digit and convert it into a c string for lookup in the encoding table + final_check_digit = checksum_adder % 103; + int length = snprintf(NULL, 0, "%d", final_check_digit); + char* final_check_digit_string = malloc(length + 1); + snprintf(final_check_digit_string, length + 1, "%d", final_check_digit); + + //after the checksum has been calculated, add the bits to the full barcode + if(!flipper_format_read_string(ff, final_check_digit_string, char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%s\" string", final_check_digit_string); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + } else { + //add the check digit bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + FURI_LOG_D( + TAG, + "\"%s\" string: %s", + final_check_digit_string, + furi_string_get_cstr(char_bits)); + } + + free(final_check_digit_string); + furi_string_free(value); + furi_string_free(char_bits); + } + + //add the stop code + furi_string_cat(barcode_bits, stop_code_bits); + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} + +/** + * Loads a code 128 C barcode +*/ +void code_128c_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + //the start code for character set C + int start_code_value = 105; + + //The bits for the start code + const char* start_code_bits = "11010011100"; + + //The bits for the stop code + const char* stop_code_bits = "1100011101011"; + + int min_digits = barcode_data->type_obj->min_digits; + + int checksum_adder = start_code_value; + int checksum_digits = 0; + + //the calculated check digit + int final_check_digit = 0; + + // check the length of the barcode, must contain atleast 2 character, + // this can have as many characters as it wants, it might not fit on the screen + // code 128 C: the length must be even + if((barcode_length < min_digits) || (barcode_length & 1)) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + FuriString* barcode_bits = furi_string_alloc(); + + //add the start code + furi_string_cat(barcode_bits, start_code_bits); + + if(!flipper_format_file_open_existing(ff, CODE128C_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "c128c Could not open file %s", CODE128C_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* value = furi_string_alloc(); + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i += 2) { + char barcode_char1 = furi_string_get_char(barcode_data->raw_data, i); + char barcode_char2 = furi_string_get_char(barcode_data->raw_data, i + 1); + FURI_LOG_I(TAG, "c128c bc1='%c' bc2='%c'", barcode_char1, barcode_char2); + + char current_chars[4]; + snprintf(current_chars, 3, "%c%c", barcode_char1, barcode_char2); + FURI_LOG_I(TAG, "c128c current_chars='%s'", current_chars); + + //using the value of the characters, get the characters bits + if(!flipper_format_read_string(ff, current_chars, char_bits)) { + FURI_LOG_E(TAG, "c128c Could not read \"%s\" string", current_chars); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + break; + } else { + //add the bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + // calculate the checksum + checksum_digits += 1; + checksum_adder += (atoi(current_chars) * checksum_digits); + + FURI_LOG_I( + TAG, + "c128c \"%s\" string: %s : %s : %d : %d : %d", + current_chars, + furi_string_get_cstr(char_bits), + furi_string_get_cstr(value), + checksum_digits, + (atoi(furi_string_get_cstr(value)) * checksum_digits), + checksum_adder); + } + //bring the file pointer back to the begining + flipper_format_rewind(ff); + } + //calculate the check digit and convert it into a c string for lookup in the encoding table + final_check_digit = checksum_adder % 103; + FURI_LOG_I(TAG, "c128c finale_check_digit=%d", final_check_digit); + + int length = snprintf(NULL, 0, "%d", final_check_digit); + if(final_check_digit < 100) length = 2; + char* final_check_digit_string = malloc(length + 1); + snprintf(final_check_digit_string, length + 1, "%02d", final_check_digit); + + //after the checksum has been calculated, add the bits to the full barcode + if(!flipper_format_read_string(ff, final_check_digit_string, char_bits)) { + FURI_LOG_E(TAG, "c128c cksum Could not read \"%s\" string", final_check_digit_string); + barcode_data->reason = EncodingTableError; + barcode_data->valid = false; + } else { + //add the check digit bits to the full barcode + furi_string_cat(barcode_bits, char_bits); + + FURI_LOG_I( + TAG, + "check digit \"%s\" string: %s", + final_check_digit_string, + furi_string_get_cstr(char_bits)); + } + + free(final_check_digit_string); + furi_string_free(value); + furi_string_free(char_bits); + } + + //add the stop code + furi_string_cat(barcode_bits, stop_code_bits); + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + FURI_LOG_I(TAG, "c128c %s", furi_string_get_cstr(barcode_bits)); + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} + +void codabar_loader(BarcodeData* barcode_data) { + int barcode_length = furi_string_size(barcode_data->raw_data); + + int min_digits = barcode_data->type_obj->min_digits; + + //check the length of the barcode, must contain atleast a character, + //this can have as many characters as it wants, it might not fit on the screen + if(barcode_length < min_digits) { + barcode_data->reason = WrongNumberOfDigits; + barcode_data->valid = false; + return; + } + + FuriString* barcode_bits = furi_string_alloc(); + + barcode_length = furi_string_size(barcode_data->raw_data); + + //Open Storage + Storage* storage = furi_record_open(RECORD_STORAGE); + FlipperFormat* ff = flipper_format_file_alloc(storage); + + if(!flipper_format_file_open_existing(ff, CODABAR_DICT_FILE_PATH)) { + FURI_LOG_E(TAG, "Could not open file %s", CODABAR_DICT_FILE_PATH); + barcode_data->reason = MissingEncodingTable; + barcode_data->valid = false; + } else { + FuriString* char_bits = furi_string_alloc(); + for(int i = 0; i < barcode_length; i++) { + char barcode_char = toupper(furi_string_get_char(barcode_data->raw_data, i)); + + //convert a char into a string so it used in flipper_format_read_string + char current_character[2]; + snprintf(current_character, 2, "%c", barcode_char); + + if(!flipper_format_read_string(ff, current_character, char_bits)) { + FURI_LOG_E(TAG, "Could not read \"%c\" string", barcode_char); + barcode_data->reason = InvalidCharacters; + barcode_data->valid = false; + break; + } else { + FURI_LOG_I( + TAG, "\"%c\" string: %s", barcode_char, furi_string_get_cstr(char_bits)); + furi_string_cat(barcode_bits, char_bits); + } + flipper_format_rewind(ff); + } + furi_string_free(char_bits); + } + + //Close Storage + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + furi_string_cat(barcode_data->correct_data, barcode_bits); + furi_string_free(barcode_bits); +} diff --git a/applications/external/barcode_gen/barcode_validator.h b/applications/external/barcode_gen/barcode_validator.h new file mode 100644 index 000000000..2138124dd --- /dev/null +++ b/applications/external/barcode_gen/barcode_validator.h @@ -0,0 +1,15 @@ +#pragma once + +#include "barcode_app.h" + +int calculate_check_digit(BarcodeData* barcode_data); +int calculate_ean_upc_check_digit(BarcodeData* barcode_data); +void ean_upc_loader(BarcodeData* barcode_data); +void upc_a_loader(BarcodeData* barcode_data); +void ean_8_loader(BarcodeData* barcode_data); +void ean_13_loader(BarcodeData* barcode_data); +void code_39_loader(BarcodeData* barcode_data); +void code_128_loader(BarcodeData* barcode_data); +void code_128c_loader(BarcodeData* barcode_data); +void codabar_loader(BarcodeData* barcode_data); +void barcode_loader(BarcodeData* barcode_data); diff --git a/applications/external/barcode_gen/encodings.c b/applications/external/barcode_gen/encodings.c new file mode 100644 index 000000000..764fde796 --- /dev/null +++ b/applications/external/barcode_gen/encodings.c @@ -0,0 +1,52 @@ +#include "encodings.h" + +const char EAN_13_STRUCTURE_CODES[10][6] = { + "LLLLLL", + "LLGLGG", + "LLGGLG", + "LLGGGL", + "LGLLGG", + "LGGLLG", + "LGGGLL", + "LGLGLG", + "LGLGGL", + "LGGLGL"}; + +const char UPC_EAN_L_CODES[10][8] = { + "0001101", // 0 + "0011001", // 1 + "0010011", // 2 + "0111101", // 3 + "0100011", // 4 + "0110001", // 5 + "0101111", // 6 + "0111011", // 7 + "0110111", // 8 + "0001011" // 9 +}; + +const char EAN_G_CODES[10][8] = { + "0100111", // 0 + "0110011", // 1 + "0011011", // 2 + "0100001", // 3 + "0011101", // 4 + "0111001", // 5 + "0000101", // 6 + "0010001", // 7 + "0001001", // 8 + "0010111" // 9 +}; + +const char UPC_EAN_R_CODES[10][8] = { + "1110010", // 0 + "1100110", // 1 + "1101100", // 2 + "1000010", // 3 + "1011100", // 4 + "1001110", // 5 + "1010000", // 6 + "1000100", // 7 + "1001000", // 8 + "1110100" // 9 +}; \ No newline at end of file diff --git a/applications/external/barcode_gen/encodings.h b/applications/external/barcode_gen/encodings.h new file mode 100644 index 000000000..c5b8d61ff --- /dev/null +++ b/applications/external/barcode_gen/encodings.h @@ -0,0 +1,6 @@ +#pragma once + +extern const char EAN_13_STRUCTURE_CODES[10][6]; +extern const char UPC_EAN_L_CODES[10][8]; +extern const char EAN_G_CODES[10][8]; +extern const char UPC_EAN_R_CODES[10][8]; \ No newline at end of file diff --git a/applications/external/barcode_gen/images/barcode_10.png b/applications/external/barcode_gen/images/barcode_10.png new file mode 100644 index 0000000000000000000000000000000000000000..32d4971ad355874ef62be4cf9eb9586fdef48ad7 GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2ZGmxy8xzq=w7>k44ofy`glX(f`u%tWsIx;Y9 z?C1WI$O`1M1^9%x0_p$%|1Z5c|1OZlS>O>_%)r2R2!t6$HM|;tf-0Uajv*44lM@6) zL{btGSSB$ks7+8-IB?=bM{COorw}H~CLRWdH%zMMw$JzmRL|h)>gTe~DWM4f+!!l! literal 0 HcmV?d00001 diff --git a/applications/external/barcode_gen/screenshots/Codabar Data Example.png b/applications/external/barcode_gen/screenshots/Codabar Data Example.png new file mode 100644 index 0000000000000000000000000000000000000000..907dfd901317f06d5cc034e9a30866959506edb1 GIT binary patch literal 1672 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 zS$VoRhE&XXdpA1owgrR3Mb8OOQ)(k!u1){S^4Yu~-EC!r*R{vHGyFV8zV!95JQ6o(bS6V7uj|0R#)|!eqY|!WcvJK z;PcauZ)}q~EO-8-jWOJ$6%TD2mVUL)u9@-J}Ub`mpevDPx>g*NM z=N+$lZ5va|Tl@a|hcoF_Y3B~^J-+Ao`>x$a%y8#fc9roUOT4sYczx)5+1I}f+I=&# z4N=YhGViXp+k4%8&q~*Bzjt2ppa1q<{(sL@S3KKe{n_&Ld?eLXmQ@V)Gk4lsI2=3^ zw@i}3VG09-3nzoa70q|7PpWDfo*N^X{Pj5l!;hOUYM0jil)0*>%=F+33xk3e1H&SG z)V*tW+?g7FBiTuO992oz9sowLeSO^LSf<6toew^)-1ub0=hXh5!gyk9%(48rxx zzA;R@c5BT1#QU)vdMklb2HR2TjU?yO6+^IS?$ePgqBwu-m}h`Pw-oyG#BUuWxQMjwp`H`C51H@tzqsZzs${3X8;Q2IJRX7hhM)-)hcKZE?6d z|C!X!i+kH`*B!S%eEvfhQtbJCv}Dk@{n*YjJ7=rd{_pp0&w6h8D!rleoxn_v?+Hxubln;c{&>;BLef|*QB|8 z5AKQWum0I_kfFea=wgQW0*MHfE4D9YXZZi^*T=87llR%*pKlkPQ5z`%M)B0Xno zJ;V7FgwIp?8!qqswYTBhjpPQ~8HfnK$^1a%+@59juUOt^pBD2MV(V9UHJH8P33ft*|iGXh-O*l}B63G!RV) z9eV&(9?|{*i)$Mo4uloD;#QrdKS;1$8Mf=t7I}=&biPDPzIDq@n?2NZR zsA^yO?QZj76MjjE4Vjx~+7d0_p2XD!b)V+(^UFMylS;wCDy7&f;A zEUR_H!bX^B#`7@fj)E@&pbool=wVMDy10ZFN;)k!HS?QiqUrp4&TJ#GJ2QfWyw2_u zn;5j?0J$#kVvHTe$UxV6EvFXWr{PWODK%!EB#PFaDR@iP&odL)g&Nzt(YxV$G)Z;b zMUHJ6#~LWpTGcOUQ#k`-%tFhrGF|M`XCvdcvN50fCeUM`<>l=VwCONW?ghCYqgzvJ zeuPKj^sh`)rFe;Yy`zCcJ@TMn0p*lTYq4uvuXrX(Qm9eQ4}Vqd*F|W>_jXoJRk%x6 z@BqXU0N);fgRw&Q5~4wsNAx?r#Na>a(U;fjS@qOJmtC%Ej?Aay)(g1wMgt!5HWv|H z=WL^DpjIA9z~xnS0{;mricDER@%wu8X6^l-fkN1~h&ys`YZ=F!n$_e)rrEf) z$^j-htx^#j*tkuEBdrDn)Y(WEnp9>2QgUEhReMrN-@8+$@ITR?-cSwctF^0Kb!iCm zHB6bdFx-M>6N|ZmVH!rUu@H*-n*zs!-{YaAi`jj;RUEaMD~YlUKm5EtH*=iF9+68) z2Bkt4q}U*b?46Ie9Xv5-xs!jXd(>N(O3qP|43(;DT~4`muF;{g&<{J~EfsE|Z8G}W zH7C|T9QC}jmU=gr-ZWMqGopw2f_r;Z&-0RXZYTSoqH3MT%DPm3Sv>pCUu1 zl4@I?uVBV}0Rm?u)^1kThW>X4o}#iiN`ogj@(2Nx@;s=NDieIGGv$w{a z_#U6Zh=k?V+Og0>uA(h_mF;-`e+7b!fHHLJ1eI`N1y=o(R9m`zegAW5 z2HWqO{TUjHIT#$KFfh1q;-PH&><;|>`}z3w>E{)q_NBkQ>7x8z(z1QxM&;*wzD7hp zmznwe#p?}bWtr>G7rwqB7;fJ_v(oL&*Lw3}U$k^IdiTD4yxi_P^-<@H zKUo=^=VDOsVqjRr!k}uGMS-v2W>+w^asLAucWW)t~#lw{dgg;Bx3M%^>bP0l+XkK2Z=AV literal 0 HcmV?d00001 diff --git a/applications/external/barcode_gen/screenshots/Flipper Box Barcode.png b/applications/external/barcode_gen/screenshots/Flipper Box Barcode.png new file mode 100644 index 0000000000000000000000000000000000000000..8dbd7d2a9c1b0564a1a2188e6de48fe9370ad426 GIT binary patch literal 1372 zcmeAS@N?(olHy`uVBq!ia0y~yU;;8388|?c*QZDWAjMhW5n0T@z;^_M8K-LVNi#68 z@_D*AhE&XXd)M3VwE=^}MfN1iHT|v|?5;K6<0%!=419F!rEPl4Dzo{=UTEdb-t)Jv z{vY##=e6J17!2AO7+g3R9H!u*t{i{EYw`N;>*w#^AAc>CYrF63E%)kq`=3jBRd379 z-s`?S_e)jy?Ka!>dtZHATWTxy@t&OQ;c(gGf{#D1`af6j{LRmQ7N6e9ozB1z$iyI^ zI!cWO!H`M?`TOtB-@N_dl<({3@82)~J@s|rtRCTSD|&^IQndW$us;^dx21lGx!qB@ zclEdI^F?m@|6f!WO;4S-@zV^;UF#x`Kk7^V9cszU&>_Uopuxz{QS~aF!Tq^>`q}OC zBA<2qon`ue_w%3Sk$~yq>ajDi76?7FzF9ZuDnE;s&yBsGoVxYB z>H2N@L_AKW^J5uTZKKS~}5{XBJZ&y8os_ov?b{P*>0yYPxoyXX8zo#$ z{h9gt{2Bvsn@6?Mg@5O)j2BYgfF$?abI_=KPCw;X0F^`vvZs1y6c9o=N(pl*O@i*eBpG%&FQh5>$Y!9k4^tp tzSVHE5mM-0wqs^U&_fcySC0H=oN}tJOPWI=6Ifg_c)I$ztaD0e0suzQQWgLJ literal 0 HcmV?d00001 diff --git a/applications/external/barcode_gen/views/barcode_view.c b/applications/external/barcode_gen/views/barcode_view.c new file mode 100644 index 000000000..55ab52046 --- /dev/null +++ b/applications/external/barcode_gen/views/barcode_view.c @@ -0,0 +1,510 @@ +#include "../barcode_app.h" +#include "barcode_view.h" +#include "../encodings.h" + +/** + * @brief Draws a single bit from a barcode at a specified location + * @param canvas + * @param bit a 1 or a 0 to signify a bit of data + * @param x the top left x coordinate + * @param y the top left y coordinate + * @param width the width of the bit + * @param height the height of the bit + */ +static void draw_bit(Canvas* canvas, int bit, int x, int y, int width, int height) { + if(bit == 1) { + canvas_set_color(canvas, ColorBlack); + } else { + canvas_set_color(canvas, ColorWhite); + } + canvas_draw_box(canvas, x, y, width, height); +} + +/** + * +*/ +static void draw_error_str(Canvas* canvas, const char* error) { + canvas_clear(canvas); + canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); +} + +/** + * @param bits a string of 1's and 0's + * @returns the x coordinate after the bits have been drawn, useful for drawing the next section of bits +*/ +static int draw_bits(Canvas* canvas, const char* bits, int x, int y, int width, int height) { + int bits_length = strlen(bits); + for(int i = 0; i < bits_length; i++) { + char c = bits[i]; + int num = c - '0'; + + draw_bit(canvas, num, x, y, width, height); + + x += width; + } + return x; +} + +/** + * Draws an EAN-8 type barcode, does not check if the barcode is valid + * @param canvas the canvas + * @param barcode_digits the digits in the barcode, must be 8 characters long +*/ +static void draw_ean_8(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + const char* end_bits = "101"; + const char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + + //the actual number and the index of the bits + int index = current_digit - '0'; + //use the L-codes for the first 4 digits and the R-Codes for the last 4 digits + if(i <= 3) { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 3, that means 4 digits have been drawn and now draw the center guard pattern + if(i == 3) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +static void draw_ean_13(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + const char* end_bits = "101"; + const char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* left_structure = furi_string_alloc(); + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + int index = current_digit - '0'; + + if(i == 0) { + furi_string_set_str(left_structure, EAN_13_STRUCTURE_CODES[index]); + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x - 10, y + height + 8, current_digit_string); + + continue; + } else { + //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits + if(i <= 6) { + //get the encoding type at the current barcode bit position + char encoding_type = furi_string_get_char(left_structure, i - 1); + if(encoding_type == 'L') { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, EAN_G_CODES[index]); + } + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern + if(i == 6) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + } + + furi_string_free(left_structure); + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +/** + * Draw a UPC-A barcode +*/ +static void draw_upc_a(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* barcode_digits = barcode_data->correct_data; + BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + + int x = type_obj->start_pos; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + //the guard patterns for the beginning, center, ending + char* end_bits = "101"; + char* center_bits = "01010"; + + //draw the starting guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); + + FuriString* code_part = furi_string_alloc(); + + //loop through each digit, find the encoding, and draw it + for(int i = 0; i < barcode_length; i++) { + char current_digit = furi_string_get_char(barcode_digits, i); + int index = current_digit - '0'; //convert the number into an int (also the index) + + //use the L-codes for the first 6 digits and the R-Codes for the last 6 digits + if(i <= 5) { + furi_string_set_str(code_part, UPC_EAN_L_CODES[index]); + } else { + furi_string_set_str(code_part, UPC_EAN_R_CODES[index]); + } + + //convert the current_digit char into a string so it can be printed + char current_digit_string[2]; + snprintf(current_digit_string, 2, "%c", current_digit); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, x + 1, y + height + 8, current_digit_string); + + //draw the bits of the barcode + x = draw_bits(canvas, furi_string_get_cstr(code_part), x, y, width, height); + + //if the index has reached 6, that means 6 digits have been drawn and we now draw the center guard pattern + if(i == 5) { + x = draw_bits(canvas, center_bits, x, y, width, height + 5); + } + } + + furi_string_free(code_part); + + //draw the ending guard pattern + x = draw_bits(canvas, end_bits, x, y, width, height + 5); +} + +static void draw_code_39(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* raw_data = barcode_data->raw_data; + FuriString* barcode_digits = barcode_data->correct_data; + //BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + int total_pixels = 0; + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(wn_digit == 1) { + total_pixels += 3; + } else { + total_pixels += 1; + } + if((i + 1) % 9 == 0) { + total_pixels += 1; + } + } + + int x = (128 - total_pixels) / 2; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + bool filled_in = true; + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); + canvas_draw_str_aligned( + canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data)); + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(filled_in) { + if(wn_digit == 1) { + x = draw_bits(canvas, "111", x, y, width, height); + } else { + x = draw_bits(canvas, "1", x, y, width, height); + } + filled_in = false; + } else { + if(wn_digit == 1) { + x = draw_bits(canvas, "000", x, y, width, height); + } else { + x = draw_bits(canvas, "0", x, y, width, height); + } + filled_in = true; + } + if((i + 1) % 9 == 0) { + x = draw_bits(canvas, "0", x, y, width, height); + filled_in = true; + } + } +} + +static void draw_code_128(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* raw_data = barcode_data->raw_data; + FuriString* barcode_digits = barcode_data->correct_data; + + int barcode_length = furi_string_size(barcode_digits); + + int x = (128 - barcode_length) / 2; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + + x = draw_bits(canvas, furi_string_get_cstr(barcode_digits), x, y, width, height); + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); + canvas_draw_str_aligned( + canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data)); +} + +static void draw_codabar(Canvas* canvas, BarcodeData* barcode_data) { + FuriString* raw_data = barcode_data->raw_data; + FuriString* barcode_digits = barcode_data->correct_data; + //BarcodeTypeObj* type_obj = barcode_data->type_obj; + + int barcode_length = furi_string_size(barcode_digits); + int total_pixels = 0; + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(wn_digit == 1) { + total_pixels += 3; + } else { + total_pixels += 1; + } + if((i + 1) % 7 == 0) { + total_pixels += 1; + } + } + + int x = (128 - total_pixels) / 2; + int y = BARCODE_Y_START; + int width = 1; + int height = BARCODE_HEIGHT; + bool filled_in = true; + + //set the canvas color to black to print the digit + canvas_set_color(canvas, ColorBlack); + // canvas_draw_str_aligned(canvas, 62, 30, AlignCenter, AlignCenter, error); + canvas_draw_str_aligned( + canvas, 62, y + height + 8, AlignCenter, AlignBottom, furi_string_get_cstr(raw_data)); + + for(int i = 0; i < barcode_length; i++) { + //1 for wide, 0 for narrow + char wide_or_narrow = furi_string_get_char(barcode_digits, i); + int wn_digit = wide_or_narrow - '0'; //wide(1) or narrow(0) digit + + if(filled_in) { + if(wn_digit == 1) { + x = draw_bits(canvas, "111", x, y, width, height); + } else { + x = draw_bits(canvas, "1", x, y, width, height); + } + filled_in = false; + } else { + if(wn_digit == 1) { + x = draw_bits(canvas, "000", x, y, width, height); + } else { + x = draw_bits(canvas, "0", x, y, width, height); + } + filled_in = true; + } + if((i + 1) % 7 == 0) { + x = draw_bits(canvas, "0", x, y, width, height); + filled_in = true; + } + } +} + +static void barcode_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + BarcodeModel* barcode_model = ctx; + BarcodeData* data = barcode_model->data; + // const char* barcode_digits =; + + canvas_clear(canvas); + if(data->valid) { + switch(data->type_obj->type) { + case UPCA: + draw_upc_a(canvas, data); + break; + case EAN8: + draw_ean_8(canvas, data); + break; + case EAN13: + draw_ean_13(canvas, data); + break; + case CODE39: + draw_code_39(canvas, data); + break; + case CODE128: + case CODE128C: + draw_code_128(canvas, data); + break; + case CODABAR: + draw_codabar(canvas, data); + break; + case UNKNOWN: + default: + break; + } + } else { + switch(data->reason) { + case WrongNumberOfDigits: + draw_error_str(canvas, "Wrong # of characters"); + break; + case InvalidCharacters: + draw_error_str(canvas, "Invalid characters"); + break; + case UnsupportedType: + draw_error_str(canvas, "Unsupported barcode type"); + break; + case FileOpening: + draw_error_str(canvas, "Could not open file"); + break; + case InvalidFileData: + draw_error_str(canvas, "Invalid file data"); + break; + case MissingEncodingTable: + draw_error_str(canvas, "Missing encoding table"); + break; + case EncodingTableError: + draw_error_str(canvas, "Encoding table error"); + break; + default: + draw_error_str(canvas, "Could not read barcode data"); + break; + } + } +} + +bool barcode_input_callback(InputEvent* input_event, void* ctx) { + UNUSED(ctx); + //furi_assert(ctx); + + //Barcode* test_view_object = ctx; + + if(input_event->key == InputKeyBack) { + return false; + } else { + return true; + } +} + +Barcode* barcode_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + Barcode* barcode = malloc(sizeof(Barcode)); + + barcode->view = view_alloc(); + barcode->barcode_app = barcode_app; + + view_set_context(barcode->view, barcode); + view_allocate_model(barcode->view, ViewModelTypeLocking, sizeof(BarcodeModel)); + view_set_draw_callback(barcode->view, barcode_draw_callback); + view_set_input_callback(barcode->view, barcode_input_callback); + + return barcode; +} + +void barcode_free_model(Barcode* barcode) { + with_view_model( + barcode->view, + BarcodeModel * model, + { + if(model->file_path != NULL) { + furi_string_free(model->file_path); + } + if(model->data != NULL) { + if(model->data->raw_data != NULL) { + furi_string_free(model->data->raw_data); + } + if(model->data->correct_data != NULL) { + furi_string_free(model->data->correct_data); + } + free(model->data); + } + }, + false); +} + +void barcode_free(Barcode* barcode) { + furi_assert(barcode); + + barcode_free_model(barcode); + view_free(barcode->view); + free(barcode); +} + +View* barcode_get_view(Barcode* barcode) { + furi_assert(barcode); + return barcode->view; +} diff --git a/applications/external/barcode_gen/views/barcode_view.h b/applications/external/barcode_gen/views/barcode_view.h new file mode 100644 index 000000000..828428c08 --- /dev/null +++ b/applications/external/barcode_gen/views/barcode_view.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef struct { + View* view; + BarcodeApp* barcode_app; +} Barcode; + +typedef struct { + FuriString* file_path; + BarcodeData* data; +} BarcodeModel; + +Barcode* barcode_view_allocate(BarcodeApp* barcode_app); + +void barcode_free_model(Barcode* barcode); + +void barcode_free(Barcode* barcode); + +View* barcode_get_view(Barcode* barcode); diff --git a/applications/external/barcode_gen/views/create_view.c b/applications/external/barcode_gen/views/create_view.c new file mode 100644 index 000000000..e4e489113 --- /dev/null +++ b/applications/external/barcode_gen/views/create_view.c @@ -0,0 +1,494 @@ +#include "../barcode_app.h" +#include "create_view.h" +#include + +#define LINE_HEIGHT 16 +#define TEXT_PADDING 4 +#define TOTAL_MENU_ITEMS 5 + +typedef enum { + TypeMenuItem, + FileNameMenuItem, + BarcodeDataMenuItem, + SaveMenuButton, + DeleteMenuButton +} MenuItems; + +/** + * Took this function from blackjack + * @author @teeebor +*/ +void draw_menu_item( + Canvas* const canvas, + const char* text, + const char* value, + int y, + bool left_caret, + bool right_caret, + bool selected) { + UNUSED(selected); + if(y < 0 || y >= 64) { + return; + } + + if(selected) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT); + canvas_set_color(canvas, ColorWhite); + } + + canvas_draw_str_aligned(canvas, 4, y + TEXT_PADDING, AlignLeft, AlignTop, text); + if(left_caret) { + canvas_draw_str_aligned(canvas, 60, y + TEXT_PADDING, AlignLeft, AlignTop, "<"); + } + + canvas_draw_str_aligned(canvas, 90, y + TEXT_PADDING, AlignCenter, AlignTop, value); + if(right_caret) { + canvas_draw_str_aligned(canvas, 120, y + TEXT_PADDING, AlignRight, AlignTop, ">"); + } + + canvas_set_color(canvas, ColorBlack); +} + +void draw_button(Canvas* const canvas, const char* text, int y, bool selected) { + if(selected) { + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 0, y, 123, LINE_HEIGHT); + canvas_set_color(canvas, ColorWhite); + } + + canvas_draw_str_aligned(canvas, 64, y + TEXT_PADDING, AlignCenter, AlignTop, text); + + canvas_set_color(canvas, ColorBlack); +} + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + + CreateViewModel* create_view_model = ctx; + + BarcodeTypeObj* type_obj = create_view_model->barcode_type; + if(create_view_model->barcode_type == NULL) { + return; + } + BarcodeType selected_type = type_obj->type; + + int selected_menu_item = create_view_model->selected_menu_item; + + int total_menu_items = create_view_model->mode == EditMode ? TOTAL_MENU_ITEMS : + TOTAL_MENU_ITEMS - 1; + + int startY = 0; + + //the menu items index that is/would be in view + //int current_last_menu_item = selected_menu_item + 3; + if(selected_menu_item > 1) { + int offset = 2; + if(selected_menu_item + offset > total_menu_items) { + offset = 3; + } + startY -= (LINE_HEIGHT * (selected_menu_item - offset)); + } + + //ensure that the scroll height is atleast 1 + int scrollHeight = ceil(64.0 / total_menu_items); + int scrollPos = scrollHeight * selected_menu_item; + + canvas_set_color(canvas, ColorBlack); + //draw the scroll bar box + canvas_draw_box(canvas, 125, scrollPos, 3, scrollHeight); + //draw the scroll bar track + canvas_draw_box(canvas, 126, 0, 1, 64); + + draw_menu_item( + canvas, + "Type", + type_obj->name, + TypeMenuItem * LINE_HEIGHT + startY, + selected_type > 0, + selected_type < NUMBER_OF_BARCODE_TYPES - 2, + selected_menu_item == TypeMenuItem); + + draw_menu_item( + canvas, + "Name", + furi_string_empty(create_view_model->file_name) ? + "--" : + furi_string_get_cstr(create_view_model->file_name), + FileNameMenuItem * LINE_HEIGHT + startY, + false, + false, + selected_menu_item == FileNameMenuItem); + + draw_menu_item( + canvas, + "Data", + furi_string_empty(create_view_model->barcode_data) ? + "--" : + furi_string_get_cstr(create_view_model->barcode_data), + BarcodeDataMenuItem * LINE_HEIGHT + startY, + false, + false, + selected_menu_item == BarcodeDataMenuItem); + + draw_button( + canvas, + "Save", + SaveMenuButton * LINE_HEIGHT + startY, + selected_menu_item == SaveMenuButton); + + if(create_view_model->mode == EditMode) { + draw_button( + canvas, + "Delete", + DeleteMenuButton * LINE_HEIGHT + startY, + selected_menu_item == DeleteMenuButton); + } +} + +void text_input_callback(void* ctx) { + CreateView* create_view_object = ctx; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + if(create_view_object->setter == FileNameSetter) { + furi_string_set_str(model->file_name, create_view_object->input); + } + if(create_view_object->setter == BarcodeDataSetter) { + furi_string_set_str(model->barcode_data, create_view_object->input); + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, CreateBarcodeView); +} + +static bool app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + if(input_event->key == InputKeyBack) { + return false; + } + + CreateView* create_view_object = ctx; + + //get the currently selected menu item from the model + int selected_menu_item = 0; + BarcodeTypeObj* barcode_type = NULL; + FuriString* file_name; + FuriString* barcode_data; + CreateMode mode; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + selected_menu_item = model->selected_menu_item; + barcode_type = model->barcode_type; + file_name = model->file_name; + barcode_data = model->barcode_data; + mode = model->mode; + }, + true); + + int total_menu_items = mode == EditMode ? TOTAL_MENU_ITEMS : TOTAL_MENU_ITEMS - 1; + + if(input_event->type == InputTypePress) { + if(input_event->key == InputKeyUp && selected_menu_item > 0) { + selected_menu_item--; + } else if(input_event->key == InputKeyDown && selected_menu_item < total_menu_items - 1) { + selected_menu_item++; + } else if(input_event->key == InputKeyLeft) { + if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type + if(barcode_type->type > 0) { + barcode_type = barcode_type_objs[barcode_type->type - 1]; + } + } + } else if(input_event->key == InputKeyRight) { + if(selected_menu_item == TypeMenuItem && barcode_type != NULL) { //Select Barcode Type + if(barcode_type->type < NUMBER_OF_BARCODE_TYPES - 2) { + barcode_type = barcode_type_objs[barcode_type->type + 1]; + } + } + } else if(input_event->key == InputKeyOk) { + if(selected_menu_item == FileNameMenuItem && barcode_type != NULL) { + create_view_object->setter = FileNameSetter; + + snprintf( + create_view_object->input, + sizeof(create_view_object->input), + "%s", + furi_string_get_cstr(file_name)); + + text_input_set_result_callback( + create_view_object->barcode_app->text_input, + text_input_callback, + create_view_object, + create_view_object->input, + TEXT_BUFFER_SIZE - BARCODE_EXTENSION_LENGTH, //remove the barcode length + //clear default text + false); + text_input_set_header_text( + create_view_object->barcode_app->text_input, "File Name"); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, TextInputView); + } + if(selected_menu_item == BarcodeDataMenuItem && barcode_type != NULL) { + create_view_object->setter = BarcodeDataSetter; + + snprintf( + create_view_object->input, + sizeof(create_view_object->input), + "%s", + furi_string_get_cstr(barcode_data)); + + text_input_set_result_callback( + create_view_object->barcode_app->text_input, + text_input_callback, + create_view_object, + create_view_object->input, + TEXT_BUFFER_SIZE, + //clear default text + false); + text_input_set_header_text( + create_view_object->barcode_app->text_input, "Barcode Data"); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, TextInputView); + } + if(selected_menu_item == SaveMenuButton && barcode_type != NULL) { + save_barcode(create_view_object); + } + if(selected_menu_item == DeleteMenuButton && barcode_type != NULL) { + if(mode == EditMode) { + remove_barcode(create_view_object); + } else if(mode == NewMode) { + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MainMenuView); + } + } + } + } + + //change the currently selected menu item + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + model->selected_menu_item = selected_menu_item; + model->barcode_type = barcode_type; + }, + true); + + return true; +} + +CreateView* create_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + CreateView* create_view_object = malloc(sizeof(CreateView)); + + create_view_object->view = view_alloc(); + create_view_object->barcode_app = barcode_app; + + view_set_context(create_view_object->view, create_view_object); + view_allocate_model(create_view_object->view, ViewModelTypeLocking, sizeof(CreateViewModel)); + view_set_draw_callback(create_view_object->view, app_draw_callback); + view_set_input_callback(create_view_object->view, app_input_callback); + + return create_view_object; +} + +void create_view_free_model(CreateView* create_view_object) { + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + if(model->file_path != NULL) { + furi_string_free(model->file_path); + } + if(model->file_name != NULL) { + furi_string_free(model->file_name); + } + if(model->barcode_data != NULL) { + furi_string_free(model->barcode_data); + } + }, + true); +} + +void remove_barcode(CreateView* create_view_object) { + Storage* storage = furi_record_open(RECORD_STORAGE); + + bool success = false; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + FURI_LOG_I(TAG, "Attempting to remove file"); + if(model->file_path != NULL) { + FURI_LOG_I(TAG, "Removing File: %s", furi_string_get_cstr(model->file_path)); + if(storage_simply_remove(storage, furi_string_get_cstr(model->file_path))) { + FURI_LOG_I( + TAG, + "File: \"%s\" was successfully removed", + furi_string_get_cstr(model->file_path)); + success = true; + } else { + FURI_LOG_E(TAG, "Unable to remove file!"); + success = false; + } + } else { + FURI_LOG_E(TAG, "Could not remove barcode file"); + success = false; + } + }, + true); + furi_record_close(RECORD_STORAGE); + + with_view_model( + create_view_object->barcode_app->message_view->view, + MessageViewModel * model, + { + if(success) { + model->message = "File Deleted"; + } else { + model->message = "Could not delete file"; + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); +} + +void save_barcode(CreateView* create_view_object) { + BarcodeTypeObj* barcode_type = NULL; + FuriString* file_path; //this may be empty + FuriString* file_name; + FuriString* barcode_data; + CreateMode mode; + + with_view_model( + create_view_object->view, + CreateViewModel * model, + { + file_path = model->file_path; + file_name = model->file_name; + barcode_data = model->barcode_data; + barcode_type = model->barcode_type; + mode = model->mode; + }, + true); + + if(file_name == NULL || furi_string_empty(file_name)) { + FURI_LOG_E(TAG, "File Name cannot be empty"); + return; + } + if(barcode_data == NULL || furi_string_empty(barcode_data)) { + FURI_LOG_E(TAG, "Barcode Data cannot be empty"); + return; + } + if(barcode_type == NULL) { + FURI_LOG_E(TAG, "Type not defined"); + return; + } + + bool success = false; + + FuriString* full_file_path = furi_string_alloc_set(DEFAULT_USER_BARCODES); + furi_string_push_back(full_file_path, '/'); + furi_string_cat(full_file_path, file_name); + furi_string_cat_str(full_file_path, BARCODE_EXTENSION); + + Storage* storage = furi_record_open(RECORD_STORAGE); + + if(mode == EditMode) { + if(!furi_string_empty(file_path)) { + if(!furi_string_equal(file_path, full_file_path)) { + FS_Error error = storage_common_rename( + storage, + furi_string_get_cstr(file_path), + furi_string_get_cstr(full_file_path)); + if(error != FSE_OK) { + FURI_LOG_E(TAG, "Rename error: %s", storage_error_get_desc(error)); + } else { + FURI_LOG_I(TAG, "Rename Success"); + } + } + } + } + + FlipperFormat* ff = flipper_format_file_alloc(storage); + + FURI_LOG_I(TAG, "Saving Barcode to: %s", furi_string_get_cstr(full_file_path)); + + bool file_opened_status = false; + if(mode == NewMode) { + file_opened_status = + flipper_format_file_open_new(ff, furi_string_get_cstr(full_file_path)); + } else if(mode == EditMode) { + file_opened_status = + flipper_format_file_open_always(ff, furi_string_get_cstr(full_file_path)); + } + + if(file_opened_status) { + // Filetype: Barcode + // Version: 1 + + // # Types - UPC-A, EAN-8, EAN-13, CODE-39 + // Type: CODE-39 + // Data: AB + flipper_format_write_string_cstr(ff, "Filetype", "Barcode"); + + flipper_format_write_string_cstr(ff, "Version", FILE_VERSION); + + flipper_format_write_comment_cstr( + ff, "Types - UPC-A, EAN-8, EAN-13, CODE-39, CODE-128, Codabar"); + + flipper_format_write_string_cstr(ff, "Type", barcode_type->name); + + flipper_format_write_string_cstr(ff, "Data", furi_string_get_cstr(barcode_data)); + + success = true; + } else { + FURI_LOG_E(TAG, "Save error"); + success = false; + } + furi_string_free(full_file_path); + flipper_format_free(ff); + furi_record_close(RECORD_STORAGE); + + with_view_model( + create_view_object->barcode_app->message_view->view, + MessageViewModel * model, + { + if(success) { + model->message = "File Saved!"; + } else { + model->message = "A saving error has occurred"; + } + }, + true); + + view_dispatcher_switch_to_view( + create_view_object->barcode_app->view_dispatcher, MessageErrorView); +} + +void create_view_free(CreateView* create_view_object) { + furi_assert(create_view_object); + + create_view_free_model(create_view_object); + view_free(create_view_object->view); + free(create_view_object); +} + +View* create_get_view(CreateView* create_view_object) { + furi_assert(create_view_object); + return create_view_object->view; +} \ No newline at end of file diff --git a/applications/external/barcode_gen/views/create_view.h b/applications/external/barcode_gen/views/create_view.h new file mode 100644 index 000000000..6063786d9 --- /dev/null +++ b/applications/external/barcode_gen/views/create_view.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef enum { + FileNameSetter, + BarcodeDataSetter +} InputSetter; //what value to set for the text input view + +typedef enum { + EditMode, + + NewMode +} CreateMode; + +typedef struct { + View* view; + BarcodeApp* barcode_app; + + InputSetter setter; + char input[TEXT_BUFFER_SIZE]; +} CreateView; + +typedef struct { + int selected_menu_item; + + CreateMode mode; + BarcodeTypeObj* barcode_type; + FuriString* file_path; //the current file that is opened + FuriString* file_name; + FuriString* barcode_data; +} CreateViewModel; + +CreateView* create_view_allocate(BarcodeApp* barcode_app); + +void remove_barcode(CreateView* create_view_object); + +void save_barcode(CreateView* create_view_object); + +void create_view_free_model(CreateView* create_view_object); + +void create_view_free(CreateView* create_view_object); + +View* create_get_view(CreateView* create_view_object); diff --git a/applications/external/barcode_gen/views/message_view.c b/applications/external/barcode_gen/views/message_view.c new file mode 100644 index 000000000..3a9aa90b3 --- /dev/null +++ b/applications/external/barcode_gen/views/message_view.c @@ -0,0 +1,66 @@ +#include "../barcode_app.h" +#include "message_view.h" + +static void app_draw_callback(Canvas* canvas, void* ctx) { + furi_assert(ctx); + + MessageViewModel* message_view_model = ctx; + + canvas_clear(canvas); + if(message_view_model->message != NULL) { + canvas_draw_str_aligned( + canvas, 62, 30, AlignCenter, AlignCenter, message_view_model->message); + } + + canvas_set_color(canvas, ColorBlack); + canvas_draw_box(canvas, 100, 52, 28, 12); + canvas_set_color(canvas, ColorWhite); + canvas_draw_str_aligned(canvas, 114, 58, AlignCenter, AlignCenter, "OK"); +} + +static bool app_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + + MessageView* message_view_object = ctx; + + if(input_event->key == InputKeyBack) { + view_dispatcher_switch_to_view( + message_view_object->barcode_app->view_dispatcher, MainMenuView); + } + if(input_event->type == InputTypeShort) { + if(input_event->key == InputKeyOk) { + view_dispatcher_switch_to_view( + message_view_object->barcode_app->view_dispatcher, MainMenuView); + } + } + + return true; +} + +MessageView* message_view_allocate(BarcodeApp* barcode_app) { + furi_assert(barcode_app); + + MessageView* message_view_object = malloc(sizeof(MessageView)); + + message_view_object->view = view_alloc(); + message_view_object->barcode_app = barcode_app; + + view_set_context(message_view_object->view, message_view_object); + view_allocate_model(message_view_object->view, ViewModelTypeLocking, sizeof(MessageViewModel)); + view_set_draw_callback(message_view_object->view, app_draw_callback); + view_set_input_callback(message_view_object->view, app_input_callback); + + return message_view_object; +} + +void message_view_free(MessageView* message_view_object) { + furi_assert(message_view_object); + + view_free(message_view_object->view); + free(message_view_object); +} + +View* message_get_view(MessageView* message_view_object) { + furi_assert(message_view_object); + return message_view_object->view; +} \ No newline at end of file diff --git a/applications/external/barcode_gen/views/message_view.h b/applications/external/barcode_gen/views/message_view.h new file mode 100644 index 000000000..33acc3d0c --- /dev/null +++ b/applications/external/barcode_gen/views/message_view.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +typedef struct BarcodeApp BarcodeApp; + +typedef struct { + View* view; + BarcodeApp* barcode_app; +} MessageView; + +typedef struct { + const char* message; +} MessageViewModel; + +MessageView* message_view_allocate(BarcodeApp* barcode_app); + +void message_view_free_model(MessageView* message_view_object); + +void message_view_free(MessageView* message_view_object); + +View* message_get_view(MessageView* message_view_object); diff --git a/applications/external/barcode_generator/application.fam b/applications/external/barcode_generator/application.fam deleted file mode 100644 index 9bb44915c..000000000 --- a/applications/external/barcode_generator/application.fam +++ /dev/null @@ -1,17 +0,0 @@ -App( - appid="barcode_generator", - name="Barcode Generator", - apptype=FlipperAppType.EXTERNAL, - entry_point="barcode_generator_app", - requires=[ - "gui", - "dialogs", - ], - stack_size=1 * 1024, - order=50, - fap_icon="barcode_10px.png", - fap_category="Tools", - fap_author="@xMasterX & @msvsergey & @McAzzaMan", - fap_version="1.0", - fap_description="App displays Barcode on flipper screen and allows to edit it", -) diff --git a/applications/external/barcode_generator/barcode_10px.png b/applications/external/barcode_generator/barcode_10px.png deleted file mode 100644 index 7c19c665687e0e6f81a805511af4d8ed409b54bc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2363 zcmcIleQeZZ81FWfF+QB4FvMlG7#NXWKkwSN?ikzM?JL~4Z6|D~fnNLeR(IEyYq#AN z%oaruB@i%+Xe3Ao#)CCTV+^Ork;KJQyBnW;32#3Z*#BN*U?_IKaeUzS z(mh7`Q{OyWxU&9K%`bDe6`dY_KCpfM-7jDH?cf#g@cDuxu}cScwCuRreyr!qeaC+| zcX^3+pm4DHz|o##-B{_$tsj?NnJ6B-6doDp&s-m1E8c1?Xn7AZ;Hz?we2wykvY;APuiu^WudPi-z(SN?R@;HLcx zzv`HXo_hy&To_+b^XT3=ukAU{ovhfot7*~2FItwIohaJER3wD*lN;WD_rq%gfBEmb zbQKzh>WkN|_AlwENgwtMJW=-eD?i6Rv6e2Jko%+Rh+v&4n0F%d!KN2}U0k(r02@2A z{?Dsz)n`#A=UNRNHipexmF-j2N>s1GtI`r8NJ2-()5(Nk zOKCrm;g!(Zy-g8#2I6%2iEKgJ!x21SrXVhO7*e5W8fO@vM+B;mlj+qsOS25cFcd42 zEF;lC;y66_AyB-Os!6TEx?D7Lg|^w9QedbD8qV^3FssvaOuN&(gSN@XwZJ((Pu#-JdnCYAT3h zGMkbHfmhKWPx68YNKWHpB=89W$)F&DLi0Qq6Z35AQ#$G$IWd*hRiz?EFAG&o0D#nF zD3F@KE2QWZASo!K07OLqng|H|X54_8FjHYuMcL&DTva5^OeJOHA3Z6@A!QkH*Ug9> zouWavQR(_}{m}-u=2i(E&zMe<71!&2LUD@>RU&s=pC)^=)0w61?SzPQhT>;owy8P2 zathYOQKtXZT-2S!+j7s$(tTc$<9v#jgtU(%V*<~UKm;rac%W!BOZx;LlRx_ZB0ZN@ zrBgQI5WPAn;=dneb}pW_4*%?{+19~3waK%aZaWO+zAv*5qi#3fP4ng(pa!+3YfU>> z(^@$`S=}|$_ZtmF=mQKSQNQ>|p64|ZXsSxGKn9G)sv>06s*H++ev>QTWdUDpD8SOZ z;HwiECKM1uAW+NlLC#mlhXQr%l${xltRQM;hMI%NYqvc2H!SJ|umAu6 diff --git a/applications/external/barcode_generator/barcode_generator.c b/applications/external/barcode_generator/barcode_generator.c deleted file mode 100644 index 2645bbcea..000000000 --- a/applications/external/barcode_generator/barcode_generator.c +++ /dev/null @@ -1,447 +0,0 @@ -#include "barcode_generator.h" - -static BarcodeType* barcodeTypes[NUMBER_OF_BARCODE_TYPES]; - -void init_types() { - BarcodeType* upcA = malloc(sizeof(BarcodeType)); - upcA->name = "UPC-A"; - upcA->numberOfDigits = 12; - upcA->startPos = 19; - upcA->bartype = BarTypeUPCA; - barcodeTypes[0] = upcA; - - BarcodeType* ean8 = malloc(sizeof(BarcodeType)); - ean8->name = "EAN-8"; - ean8->numberOfDigits = 8; - ean8->startPos = 33; - ean8->bartype = BarTypeEAN8; - barcodeTypes[1] = ean8; - - BarcodeType* ean13 = malloc(sizeof(BarcodeType)); - ean13->name = "EAN-13"; - ean13->numberOfDigits = 13; - ean13->startPos = 19; - ean13->bartype = BarTypeEAN13; - barcodeTypes[2] = ean13; -} - -void draw_digit( - Canvas* canvas, - int digit, - BarEncodingType rightHand, - int startingPosition, - bool drawlines) { - char digitStr[2]; - snprintf(digitStr, 2, "%u", digit); - canvas_set_color(canvas, ColorBlack); - canvas_draw_str( - canvas, startingPosition, BARCODE_Y_START + BARCODE_HEIGHT + BARCODE_TEXT_OFFSET, digitStr); - - if(drawlines) { - switch(rightHand) { - case BarEncodingTypeLeft: - case BarEncodingTypeRight: - canvas_set_color( - canvas, (rightHand == BarEncodingTypeRight) ? ColorBlack : ColorWhite); - //int count = 0; - for(int i = 0; i < 4; i++) { - canvas_draw_box( - canvas, startingPosition, BARCODE_Y_START, DIGITS[digit][i], BARCODE_HEIGHT); - canvas_invert_color(canvas); - startingPosition += DIGITS[digit][i]; - } - break; - case BarEncodingTypeG: - canvas_set_color(canvas, ColorWhite); - //int count = 0; - for(int i = 3; i >= 0; i--) { - canvas_draw_box( - canvas, startingPosition, BARCODE_Y_START, DIGITS[digit][i], BARCODE_HEIGHT); - canvas_invert_color(canvas); - startingPosition += DIGITS[digit][i]; - } - break; - default: - break; - } - } -} - -int get_digit_position(int index, BarcodeType* type) { - int pos = 0; - switch(type->bartype) { - case BarTypeEAN8: - case BarTypeUPCA: - pos = type->startPos + index * 7; - if(index >= type->numberOfDigits / 2) { - pos += 5; - } - break; - case BarTypeEAN13: - if(index == 0) - pos = type->startPos - 10; - else { - pos = type->startPos + (index - 1) * 7; - if((index - 1) >= type->numberOfDigits / 2) { - pos += 5; - } - } - break; - default: - break; - } - return pos; -} - -int get_menu_text_location(int index) { - return 20 + 10 * index; -} - -int get_barcode_max_index(PluginState* plugin_state) { - return plugin_state->barcode_state.doParityCalculation ? - barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]->numberOfDigits - 1 : - barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]->numberOfDigits; -} - -int calculate_check_digit(PluginState* plugin_state, BarcodeType* type) { - int checkDigit = 0; - int checkDigitOdd = 0; - int checkDigitEven = 0; - //add all odd positions. Confusing because 0index - for(int i = 0; i < type->numberOfDigits - 1; i += 2) { - checkDigitOdd += plugin_state->barcode_state.barcodeNumeral[i]; - } - - //add all even positions to above. Confusing because 0index - for(int i = 1; i < type->numberOfDigits - 1; i += 2) { - checkDigitEven += plugin_state->barcode_state.barcodeNumeral[i]; - } - - if(type->bartype == BarTypeEAN13) { - checkDigit = checkDigitEven * 3 + checkDigitOdd; - } else { - checkDigit = checkDigitOdd * 3 + checkDigitEven; - } - - checkDigit = checkDigit % 10; //mod 10 - - //if m = 0 then x12 = 0, otherwise x12 is 10 - m - return (10 - checkDigit) % 10; -} - -static void render_callback(Canvas* const canvas, void* ctx) { - furi_assert(ctx); - PluginState* plugin_state = ctx; - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - if(plugin_state->mode == MenuMode) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_str_aligned(canvas, 64, 6, AlignCenter, AlignCenter, "MENU"); - canvas_draw_frame(canvas, 50, 0, 29, 11); //box around Menu - canvas_draw_str_aligned( - canvas, 64, get_menu_text_location(0), AlignCenter, AlignCenter, "View"); - canvas_draw_str_aligned( - canvas, 64, get_menu_text_location(1), AlignCenter, AlignCenter, "Edit"); - canvas_draw_str_aligned( - canvas, 64, get_menu_text_location(2), AlignCenter, AlignCenter, "Parity?"); - - canvas_draw_frame(canvas, 83, get_menu_text_location(2) - 3, 6, 6); - if(plugin_state->barcode_state.doParityCalculation == true) { - canvas_draw_box(canvas, 85, get_menu_text_location(2) - 1, 2, 2); - } - canvas_draw_str_aligned( - canvas, - 64, - get_menu_text_location(3), - AlignCenter, - AlignCenter, - (barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex])->name); - canvas_draw_disc( - canvas, - 40, - get_menu_text_location(plugin_state->menuIndex) - 1, - 2); //draw menu cursor - } else { - BarcodeType* type = barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]; - - //start saftey - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, type->startPos - 3, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - canvas_draw_box(canvas, (type->startPos - 1), BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - - int startpos = 0; - int endpos = type->numberOfDigits; - if(type->bartype == BarTypeEAN13) { - startpos++; - draw_digit( - canvas, - plugin_state->barcode_state.barcodeNumeral[0], - BarEncodingTypeRight, - get_digit_position(0, barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]), - false); - } - if(plugin_state->barcode_state.doParityCalculation) { //calculate the check digit - plugin_state->barcode_state.barcodeNumeral[type->numberOfDigits - 1] = - calculate_check_digit(plugin_state, type); - } - for(int index = startpos; index < endpos; index++) { - BarEncodingType barEncodingType = BarEncodingTypeLeft; - if(type->bartype == BarTypeEAN13) { - if(index - 1 >= (type->numberOfDigits - 1) / 2) { - barEncodingType = BarEncodingTypeRight; - } else { - barEncodingType = - (FURI_BIT( - EAN13ENCODE[plugin_state->barcode_state.barcodeNumeral[0]], - index - 1)) ? - BarEncodingTypeG : - BarEncodingTypeLeft; - } - } else { - if(index >= type->numberOfDigits / 2) { - barEncodingType = BarEncodingTypeRight; - } - } - - int digitPosition = get_digit_position( - index, barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]); - draw_digit( - canvas, - plugin_state->barcode_state.barcodeNumeral[index], - barEncodingType, - digitPosition, - true); - } - - //central separator - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, 62, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - canvas_draw_box(canvas, 64, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - - if(plugin_state->mode == EditMode) { - canvas_set_color(canvas, ColorBlack); - canvas_draw_box( - canvas, - get_digit_position( - plugin_state->editingIndex, - barcodeTypes[plugin_state->barcode_state.barcodeTypeIndex]) - - 1, - 63, - 7, - 1); //draw editing cursor - } - - //end safety - int endSafetyPosition = get_digit_position(type->numberOfDigits - 1, type) + 7; - canvas_set_color(canvas, ColorBlack); - canvas_draw_box(canvas, endSafetyPosition, BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - canvas_draw_box(canvas, (endSafetyPosition + 2), BARCODE_Y_START, 1, BARCODE_HEIGHT + 2); - } - - furi_mutex_release(plugin_state->mutex); -} - -static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { - furi_assert(event_queue); - - PluginEvent event = {.type = EventTypeKey, .input = *input_event}; - furi_message_queue_put(event_queue, &event, FuriWaitForever); -} - -static void barcode_generator_state_init(PluginState* plugin_state) { - plugin_state->editingIndex = 0; - plugin_state->mode = ViewMode; - plugin_state->menuIndex = MENU_INDEX_VIEW; - if(!LOAD_BARCODE_SETTINGS(&plugin_state->barcode_state)) { - for(int i = 0; i < BARCODE_MAX_LENS; ++i) { - plugin_state->barcode_state.barcodeNumeral[i] = i % 10; - } - plugin_state->barcode_state.doParityCalculation = true; - plugin_state->barcode_state.barcodeTypeIndex = 0; - } -} - -static bool handle_key_press_view(InputKey key, PluginState* plugin_state) { - switch(key) { - case InputKeyOk: - case InputKeyBack: - plugin_state->mode = MenuMode; - break; - - default: - break; - } - - return true; -} - -static bool handle_key_press_edit(InputKey key, PluginState* plugin_state) { - int barcodeMaxIndex = get_barcode_max_index(plugin_state); - - switch(key) { - case InputKeyUp: - plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] = - (plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] + 1) % 10; - break; - - case InputKeyDown: - plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] = - (plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] == 0) ? - 9 : - plugin_state->barcode_state.barcodeNumeral[plugin_state->editingIndex] - 1; - break; - - case InputKeyRight: - plugin_state->editingIndex = (plugin_state->editingIndex + 1) % barcodeMaxIndex; - break; - - case InputKeyLeft: - plugin_state->editingIndex = (plugin_state->editingIndex == 0) ? - barcodeMaxIndex - 1 : - plugin_state->editingIndex - 1; - break; - - case InputKeyOk: - case InputKeyBack: - plugin_state->mode = MenuMode; - break; - - default: - break; - } - - return true; -} - -static bool handle_key_press_menu(InputKey key, PluginState* plugin_state) { - switch(key) { - case InputKeyUp: - plugin_state->menuIndex = (plugin_state->menuIndex == MENU_INDEX_VIEW) ? - MENU_INDEX_TYPE : - plugin_state->menuIndex - 1; - break; - - case InputKeyDown: - plugin_state->menuIndex = (plugin_state->menuIndex + 1) % 4; - break; - - case InputKeyRight: - if(plugin_state->menuIndex == MENU_INDEX_TYPE) { - plugin_state->barcode_state.barcodeTypeIndex = - (plugin_state->barcode_state.barcodeTypeIndex == NUMBER_OF_BARCODE_TYPES - 1) ? - 0 : - plugin_state->barcode_state.barcodeTypeIndex + 1; - } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) { - plugin_state->barcode_state.doParityCalculation = - !plugin_state->barcode_state.doParityCalculation; - } - break; - case InputKeyLeft: - if(plugin_state->menuIndex == MENU_INDEX_TYPE) { - plugin_state->barcode_state.barcodeTypeIndex = - (plugin_state->barcode_state.barcodeTypeIndex == 0) ? - NUMBER_OF_BARCODE_TYPES - 1 : - plugin_state->barcode_state.barcodeTypeIndex - 1; - } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) { - plugin_state->barcode_state.doParityCalculation = - !plugin_state->barcode_state.doParityCalculation; - } - break; - - case InputKeyOk: - if(plugin_state->menuIndex == MENU_INDEX_VIEW) { - plugin_state->mode = ViewMode; - } else if(plugin_state->menuIndex == MENU_INDEX_EDIT) { - plugin_state->mode = EditMode; - } else if(plugin_state->menuIndex == MENU_INDEX_PARITY) { - plugin_state->barcode_state.doParityCalculation = - !plugin_state->barcode_state.doParityCalculation; - } else if(plugin_state->menuIndex == MENU_INDEX_TYPE) { - plugin_state->barcode_state.barcodeTypeIndex = - (plugin_state->barcode_state.barcodeTypeIndex == NUMBER_OF_BARCODE_TYPES - 1) ? - 0 : - plugin_state->barcode_state.barcodeTypeIndex + 1; - } - break; - - case InputKeyBack: - return false; - - default: - break; - } - int barcodeMaxIndex = get_barcode_max_index(plugin_state); - if(plugin_state->editingIndex >= barcodeMaxIndex) - plugin_state->editingIndex = barcodeMaxIndex - 1; - - return true; -} - -int32_t barcode_generator_app(void* p) { - UNUSED(p); - - init_types(); - - FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); - - PluginState* plugin_state = malloc(sizeof(PluginState)); - barcode_generator_state_init(plugin_state); - - plugin_state->mutex = furi_mutex_alloc(FuriMutexTypeNormal); - if(!plugin_state->mutex) { - FURI_LOG_E("barcode_generator", "cannot create mutex\r\n"); - furi_message_queue_free(event_queue); - free(plugin_state); - return 255; - } - - // Set system callbacks - ViewPort* view_port = view_port_alloc(); - view_port_draw_callback_set(view_port, render_callback, plugin_state); - view_port_input_callback_set(view_port, input_callback, event_queue); - - // Open GUI and register view_port - Gui* gui = furi_record_open(RECORD_GUI); - gui_add_view_port(gui, view_port, GuiLayerFullscreen); - - PluginEvent event; - for(bool processing = true; processing;) { - FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); - furi_mutex_acquire(plugin_state->mutex, FuriWaitForever); - - if(event_status == FuriStatusOk) { - // press events - if(event.type == EventTypeKey && - ((event.input.type == InputTypePress) || (event.input.type == InputTypeRepeat))) { - switch(plugin_state->mode) { - case ViewMode: - processing = handle_key_press_view(event.input.key, plugin_state); - break; - case EditMode: - processing = handle_key_press_edit(event.input.key, plugin_state); - break; - case MenuMode: - processing = handle_key_press_menu(event.input.key, plugin_state); - break; - default: - break; - } - } - } - - view_port_update(view_port); - furi_mutex_release(plugin_state->mutex); - } - - view_port_enabled_set(view_port, false); - gui_remove_view_port(gui, view_port); - furi_record_close(RECORD_GUI); - view_port_free(view_port); - furi_message_queue_free(event_queue); - furi_mutex_free(plugin_state->mutex); - // save settings - SAVE_BARCODE_SETTINGS(&plugin_state->barcode_state); - free(plugin_state); - - return 0; -} diff --git a/applications/external/barcode_generator/barcode_generator.h b/applications/external/barcode_generator/barcode_generator.h deleted file mode 100644 index 9f2e10c16..000000000 --- a/applications/external/barcode_generator/barcode_generator.h +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#define BARCODE_SETTINGS_FILE_NAME "apps/Tools/barcodegen.save" - -#define BARCODE_SETTINGS_VER (1) -#define BARCODE_SETTINGS_PATH EXT_PATH(BARCODE_SETTINGS_FILE_NAME) -#define BARCODE_SETTINGS_MAGIC (0xC2) - -#define SAVE_BARCODE_SETTINGS(x) \ - saved_struct_save( \ - BARCODE_SETTINGS_PATH, \ - (x), \ - sizeof(BarcodeState), \ - BARCODE_SETTINGS_MAGIC, \ - BARCODE_SETTINGS_VER) - -#define LOAD_BARCODE_SETTINGS(x) \ - saved_struct_load( \ - BARCODE_SETTINGS_PATH, \ - (x), \ - sizeof(BarcodeState), \ - BARCODE_SETTINGS_MAGIC, \ - BARCODE_SETTINGS_VER) - -#define BARCODE_HEIGHT 50 -#define BARCODE_Y_START 3 -#define BARCODE_TEXT_OFFSET 9 -#define BARCODE_MAX_LENS 13 -#define NUMBER_OF_BARCODE_TYPES 3 -#define MENU_INDEX_VIEW 0 -#define MENU_INDEX_EDIT 1 -#define MENU_INDEX_PARITY 2 -#define MENU_INDEX_TYPE 3 - -typedef enum { - EventTypeTick, - EventTypeKey, -} EventType; - -typedef struct { - EventType type; - InputEvent input; -} PluginEvent; - -typedef enum { - ViewMode, - EditMode, - MenuMode, -} Mode; - -typedef enum { - BarEncodingTypeLeft, - BarEncodingTypeRight, - BarEncodingTypeG, -} BarEncodingType; - -typedef enum { - BarTypeEAN8, - BarTypeUPCA, - BarTypeEAN13, -} BarType; - -typedef struct { - char* name; - int numberOfDigits; - int startPos; - BarType bartype; -} BarcodeType; - -typedef struct { - int barcodeNumeral[BARCODE_MAX_LENS]; //The current barcode number - bool doParityCalculation; //Should do parity check? - int barcodeTypeIndex; -} BarcodeState; - -typedef struct { - FuriMutex* mutex; - BarcodeState barcode_state; - int editingIndex; //The index of the editing symbol - int menuIndex; //The index of the menu cursor - Mode mode; //View, edit or menu -} PluginState; - -static const int DIGITS[10][4] = { - {3, 2, 1, 1}, - {2, 2, 2, 1}, - {2, 1, 2, 2}, - {1, 4, 1, 1}, - {1, 1, 3, 2}, - {1, 2, 3, 1}, - {1, 1, 1, 4}, - {1, 3, 1, 2}, - {1, 2, 1, 3}, - {3, 1, 1, 2}, -}; - -static const uint8_t EAN13ENCODE[10] = { - 0b000000, - 0b110100, - 0b101100, - 0b011100, - 0b110010, - 0b100110, - 0b001110, - 0b101010, - 0b011010, - 0b010110, -}; \ No newline at end of file diff --git a/assets/resources/apps_data/barcode_data/codabar_encodings.txt b/assets/resources/apps_data/barcode_data/codabar_encodings.txt new file mode 100644 index 000000000..5f0684cbd --- /dev/null +++ b/assets/resources/apps_data/barcode_data/codabar_encodings.txt @@ -0,0 +1,22 @@ +# alternates between bars and spaces, always begins with bar +# 0 for narrow, 1 for wide +0: 0000011 +1: 0000110 +2: 0001001 +3: 1100000 +4: 0010010 +5: 1000010 +6: 0100001 +7: 0100100 +8: 0110000 +9: 1001000 +-: 0001100 +$: 0011000 +:: 1000101 +/: 1010001 +.: 1010100 ++: 0010101 +A: 0011010 +B: 0101001 +C: 0001011 +D: 0001110 \ No newline at end of file diff --git a/assets/resources/apps_data/barcode_data/code128_encodings.txt b/assets/resources/apps_data/barcode_data/code128_encodings.txt new file mode 100644 index 000000000..394a34520 --- /dev/null +++ b/assets/resources/apps_data/barcode_data/code128_encodings.txt @@ -0,0 +1,202 @@ + : 00 +!: 01 +": 02 +#: 03 +$: 04 +%: 05 +&: 06 +': 07 +(: 08 +): 09 +*: 10 ++: 11 +,: 12 +-: 13 +.: 14 +/: 15 +0: 16 +1: 17 +2: 18 +3: 19 +4: 20 +5: 21 +6: 22 +7: 23 +8: 24 +9: 25 +:: 26 +;: 27 +<: 28 +=: 29 +>: 30 +?: 31 +@: 32 +A: 33 +B: 34 +C: 35 +D: 36 +E: 37 +F: 38 +G: 39 +H: 40 +I: 41 +J: 42 +K: 43 +L: 44 +M: 45 +N: 46 +O: 47 +P: 48 +Q: 49 +R: 50 +S: 51 +T: 52 +U: 53 +V: 54 +W: 55 +X: 56 +Y: 57 +Z: 58 +[: 59 +\: 60 +]: 61 +^: 62 +_: 63 +`: 64 +a: 65 +b: 66 +c: 67 +d: 68 +e: 69 +f: 70 +g: 71 +h: 72 +i: 73 +j: 74 +k: 75 +l: 76 +m: 77 +n: 78 +o: 79 +p: 80 +q: 81 +r: 82 +s: 83 +t: 84 +u: 85 +v: 86 +w: 87 +x: 88 +y: 89 +z: 90 +{: 91 +|: 92 +}: 93 +~: 94 + +00: 11011001100 +01: 11001101100 +02: 11001100110 +03: 10010011000 +04: 10010001100 +05: 10001001100 +06: 10011001000 +07: 10011000100 +08: 10001100100 +09: 11001001000 +10: 11001000100 +11: 11000100100 +12: 10110011100 +13: 10011011100 +14: 10011001110 +15: 10111001100 +16: 10011101100 +17: 10011100110 +18: 11001110010 +19: 11001011100 +20: 11001001110 +21: 11011100100 +22: 11001110100 +23: 11101101110 +24: 11101001100 +25: 11100101100 +26: 11100100110 +27: 11101100100 +28: 11100110100 +29: 11100110010 +30: 11011011000 +31: 11011000110 +32: 11000110110 +33: 10100011000 +34: 10001011000 +35: 10001000110 +36: 10110001000 +37: 10001101000 +38: 10001100010 +39: 11010001000 +40: 11000101000 +41: 11000100010 +42: 10110111000 +43: 10110001110 +44: 10001101110 +45: 10111011000 +46: 10111000110 +47: 10001110110 +48: 11101110110 +49: 11010001110 +50: 11000101110 +51: 11011101000 +52: 11011100010 +53: 11011101110 +54: 11101011000 +55: 11101000110 +56: 11100010110 +57: 11101101000 +58: 11101100010 +59: 11100011010 +60: 11101111010 +61: 11001000010 +62: 11110001010 +63: 10100110000 +64: 10100001100 +65: 10010110000 +66: 10010000110 +67: 10000101100 +68: 10000100110 +69: 10110010000 +70: 10110000100 +71: 10011010000 +72: 10011000010 +73: 10000110100 +74: 10000110010 +75: 11000010010 +76: 11001010000 +77: 11110111010 +78: 11000010100 +79: 10001111010 +80: 10100111100 +81: 10010111100 +82: 10010011110 +83: 10111100100 +84: 10011110100 +85: 10011110010 +86: 11110100100 +87: 11110010100 +88: 11110010010 +89: 11011011110 +90: 11011110110 +91: 11110110110 +92: 10101111000 +93: 10100011110 +94: 10001011110 +95: 10111101000 +96: 10111100010 +97: 11110101000 +98: 11110100010 +99: 10111011110 +100: 10111101110 +101: 11101011110 +102: 11110101110 +103: 11010000100 +104: 11010010000 +105: 11010011100 \ No newline at end of file diff --git a/assets/resources/apps_data/barcode_data/code128c_encodings.txt b/assets/resources/apps_data/barcode_data/code128c_encodings.txt new file mode 100644 index 000000000..75cc71135 --- /dev/null +++ b/assets/resources/apps_data/barcode_data/code128c_encodings.txt @@ -0,0 +1,106 @@ +00: 11011001100 +01: 11001101100 +02: 11001100110 +03: 10010011000 +04: 10010001100 +05: 10001001100 +06: 10011001000 +07: 10011000100 +08: 10001100100 +09: 11001001000 +10: 11001000100 +11: 11000100100 +12: 10110011100 +13: 10011011100 +14: 10011001110 +15: 10111001100 +16: 10011101100 +17: 10011100110 +18: 11001110010 +19: 11001011100 +20: 11001001110 +21: 11011100100 +22: 11001110100 +23: 11101101110 +24: 11101001100 +25: 11100101100 +26: 11100100110 +27: 11101100100 +28: 11100110100 +29: 11100110010 +30: 11011011000 +31: 11011000110 +32: 11000110110 +33: 10100011000 +34: 10001011000 +35: 10001000110 +36: 10110001000 +37: 10001101000 +38: 10001100010 +39: 11010001000 +40: 11000101000 +41: 11000100010 +42: 10110111000 +43: 10110001110 +44: 10001101110 +45: 10111011000 +46: 10111000110 +47: 10001110110 +48: 11101110110 +49: 11010001110 +50: 11000101110 +51: 11011101000 +52: 11011100010 +53: 11011101110 +54: 11101011000 +55: 11101000110 +56: 11100010110 +57: 11101101000 +58: 11101100010 +59: 11100011010 +60: 11101111010 +61: 11001000010 +62: 11110001010 +63: 10100110000 +64: 10100001100 +65: 10010110000 +66: 10010000110 +67: 10000101100 +68: 10000100110 +69: 10110010000 +70: 10110000100 +71: 10011010000 +72: 10011000010 +73: 10000110100 +74: 10000110010 +75: 11000010010 +76: 11001010000 +77: 11110111010 +78: 11000010100 +79: 10001111010 +80: 10100111100 +81: 10010111100 +82: 10010011110 +83: 10111100100 +84: 10011110100 +85: 10011110010 +86: 11110100100 +87: 11110010100 +88: 11110010010 +89: 11011011110 +90: 11011110110 +91: 11110110110 +92: 10101111000 +93: 10100011110 +94: 10001011110 +95: 10111101000 +96: 10111100010 +97: 11110101000 +98: 11110100010 +99: 10111011110 +100: 10111101110 +101: 11101011110 +102: 11110101110 +103: 11010000100 +104: 11010010000 +105: 11010011100 diff --git a/assets/resources/apps_data/barcode_data/code39_encodings.txt b/assets/resources/apps_data/barcode_data/code39_encodings.txt new file mode 100644 index 000000000..a41ad16e9 --- /dev/null +++ b/assets/resources/apps_data/barcode_data/code39_encodings.txt @@ -0,0 +1,44 @@ +0: 000110100 +1: 100100001 +2: 001100001 +3: 101100000 +4: 000110001 +5: 100110000 +6: 001110000 +7: 000100101 +8: 100100100 +9: 001100100 +A: 100001001 +B: 001001001 +C: 101001000 +D: 000011001 +E: 100011000 +F: 001011000 +G: 000001101 +H: 100001100 +I: 001001100 +J: 000011100 +K: 100000011 +L: 001000011 +M: 101000010 +N: 000010011 +O: 100010010 +P: 001010010 +Q: 000000111 +R: 100000110 +S: 001000110 +T: 000010110 +U: 110000001 +V: 011000001 +W: 111000000 +X: 010010001 +Y: 110010000 +Z: 011010000 +-: 010000101 +.: 110000100 + : 011000100 +*: 010010100 +$: 010101000 +/: 010100010 ++: 010001010 +%: 000101010 \ No newline at end of file