{"id":23395922,"url":"https://github.com/ghindea/qr_code_generator","last_synced_at":"2025-04-08T17:19:44.347Z","repository":{"id":194557386,"uuid":"691093169","full_name":"Ghindea/QR_code_generator","owner":"Ghindea","description":"C program that generates QR Codes","archived":false,"fork":false,"pushed_at":"2023-10-12T15:17:16.000Z","size":1927,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-08T17:19:40.536Z","etag":null,"topics":["jpg","png","ppm","qrcode"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ghindea.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-13T13:39:47.000Z","updated_at":"2023-10-08T17:03:21.000Z","dependencies_parsed_at":"2024-12-22T07:19:31.980Z","dependency_job_id":"722a2e2e-d14e-4fec-968d-e7efc1c1ab6a","html_url":"https://github.com/Ghindea/QR_code_generator","commit_stats":null,"previous_names":["ghindea/qr_code_beta","ghindea/qr_code_generator"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ghindea%2FQR_code_generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ghindea%2FQR_code_generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ghindea%2FQR_code_generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ghindea%2FQR_code_generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ghindea","download_url":"https://codeload.github.com/Ghindea/QR_code_generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247888568,"owners_count":21013002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jpg","png","ppm","qrcode"],"created_at":"2024-12-22T07:19:34.167Z","updated_at":"2025-04-08T17:19:44.323Z","avatar_url":"https://github.com/Ghindea.png","language":"C","readme":"\u003cimg \n    style=\"display: block; \n           margin-left: auto;\n           margin-right: auto;\n           width: 30%;\"\n    src=\"./git_aux/QR.png\" \n    alt=\"https://github.com/Ghindea/QR_code_beta\"\u003e\n\u003c/img\u003e\n# **QR Code Generator**\nby [*Daniel Ghindea*](https://github.com/Ghindea)\n\n The QR Code is generated as a .ppm/.png/.jpg image and its properties (version, color, error_correction and more) are all customizable. Currently the program has been tested on Linux.\n\n## CONTENTS:\n\n- [How it works](#how-it-works)\n- [Configuration parametes](#configuration-parameters)\n- [Contributors](#contributors)\n- [Bibliography](#bibliography)\n- [Licence](#license)\n\n## HOW IT WORKS:\nThe process of generating a QR code consists of 5 steps:\n\n\u003cdetails\u003e\u003csummary\u003e Step 1: apply function patterns               \u003c/summary\u003e\n\n- *Finder Patterns* are unique blocks of 7x7 modules used to orient the QR code in the correct position for decoding.\n- *Separators* are used to distinguish the finder patterns from the rest of the QR code.\n- *Timing Patterns* are used to accurately determine the size of the data grid.\n- *Alignment Patterns* are used to straighten out QR Codes drawn on a curved surface. Depending of the selected QR version more or less alignment patterns can be placed.\n- *Dark Module* is a single module that is always set on 1\n\n\u003cimg style=\"display: block; width: 40%;\"\n    src=\"./git_aux/patterns.png\" \n    alt=\"patterns placement\"\u003e\n\u003c/img\u003e\n\nQR code version 2\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e Step 2: encode data \u0026 place modules in matrix \u003c/summary\u003e\n\u003cbr\u003e\n\n**PART I**\n\nFor the beginning the input string has to be processed into a data string.\nThe first 4 bits of the data string represent the *Mode Indicator*\n\n\u003e| Mode name              | Mode Indicator |\n\u003e|------------------------|:--------------:|\n\u003e| Numeric mode           |  0001          |\n\u003e| Alphanumeric mode      |  0010          |\n\u003e| Byte mode              |  0100          |\n\u003e| Kanji mode             |  1000          |\n\nNext, the *Character Count Indicator* needs to be added in a group of x bits, where x depends on QR code version (check [len_bit_no()](./src/step2.c)). After that, based on the selected mode, the encoded input string needs to be added. In the end, the obtained string has to be broken up into 8-bit Codewords and padded with 0s if necessary (if its length isn't a multiple of 8 more 0s are required and, if it's still too short, it will be filled with 236 and 17 until maximum capacity is reached).\n\n---\n**PART II** \n\nTo ensure that the data is read correctly by the scanner it's required to generate error correction codewords for comparison. This process uses *Reed-Solomon method* for error correction. In a nutshell, it performs a polynomial division between the polynomial with coefficients made of data string elements and the generator polynomial (check Reed-Solomon documentation). The key of this process is finite field arithmetic ( GF(256) ).\n\n\u003cimg style=\"display: block; width: 75%;\"\n    src=\"./git_aux/codewords.png\" \n    alt=\"encoding results\"\u003e\n\u003c/img\u003e\n\nCodewords obtained for \"Hello world!\" input in a version 1 QR code.\n\nTo arrange the codewords correctly into the matrix it's necessary to break the data string into groups and groups into blocks in a suitable manner for the given version of QR code. Then,  an error correction array of codewords will be generated for every block. For more information see [^2].\n\n---\n**PART III**\n\nOnce the data has been encoded and error correction was generated it's time to place the codewords into the matrix. For this part it's required to interleave the blocks.\n\n\u003cimg style=\"display: block; width: 75%;\"\n    src=\"./git_aux/interleaved.png\" \n    alt=\"interleaving results\"\u003e\n\u003c/img\u003e\n\nFinal Message Codewords obtained for \"Hello world!\" input in a version 5-Q QR code.\n\n\u003cimg style=\"display: block; width: 50%;\"\n    src=\"./git_aux/data_placement.png\" \n    alt=\"https://en.wikiversity.org/wiki/File:QR_Code_Unmasked.svg\"\u003e\n\u003c/img\u003e\n\nPlacing final message codewords in a version 1 QR code.\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e Step 3: mask the data section                 \u003c/summary\u003e\n\u003cbr\u003e\nTo avoid the appearance of patterns that may disturb the scanning process is necessary to apply a mask. A mask pattern changes which modules are 1 and which are 0. To automaticaly determine which is the best mask a penalty score is calculated for each variant and the pattern with the lowest score is chosen.\n\n\u003cbr\u003e\n\u003cimg style=\"display: block; width: 60%;\"\n    src=\"./git_aux/mask.png\" \n    alt=\"https://en.wikiversity.org/wiki/File:QR_Code_Masking_Example.svg\"\u003e\n\u003c/img\u003e\n\u003cimg style=\"display: block; width: 60%;\"\n    src=\"./git_aux/mask_patterns.png\" \n    alt=\"https://en.wikiversity.org/wiki/File:QR_Code_Mask_Patterns.svg\"\u003e\n\u003c/img\u003e\n\n[\u003e source](https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#QR_code_structure)\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e Step 4: apply format patterns                 \u003c/summary\u003e\n\u003cbr\u003e\nThe format pattern is used to encode which mask pattern and which error correction level are in use. The first 2 bits in the format string represent the error correction and the next 3 the mask applied.\n\n\u003cbr\u003e\n\n\u003e| EC level  | Bits | Integer Equivalent |\n\u003e|-----------|:----:|:------------------:|\n\u003e| L         |  01  |    1               |\n\u003e| M         |  00  |    0               |\n\u003e| Q         |  11  |    3               |\n\u003e| H         |  10  |    2               |\n\nAfter that, the format string is processed similary to the data string, which results in a string with 15 bits that is placed like this:\n\n\u003cimg style=\"width: 40%;\"\n    src=\"./git_aux/format_pattern.png\" \n    alt=\"format pattern\"/\u003e\n\nFor versions \u003e= 7 a special pattern is required to identify version information.\n\n\u003cimg style=\"width: 57%;\"\n    src=\"./git_aux/format_special_pattern.png\" \n    alt=\"format pattern\" /\u003e\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e Step 5: generate image based on matrix        \u003c/summary\u003e\n\u003cbr\u003e\nCurrently 3 image formats can be generated, the simplest one being .pmm. It is structured as it follows:\n\n\u003e       P6              # magic number \n\u003e       115 115         # image width \u0026 height\n\u003e       255             # maximum color value (ranges between 0-255)\n\u003e       0 0 0     0  0  0     0 1 0  ...        # (width * height) groups of binary data\n\u003e       5 1 8     11 3 12     4 6 11 ...        # that represent the RGB color values \n\u003e       ...       ...         ...               # of each corresponding pixel \n\nSince a QR code only has values of 0s and 1s, the .ppm file will contain only white pixels (255 255 255) and a specific color (0 0 0 - black by default). Because the dimensions of the data matrix depends on the selected version a scale variable was implemented to make images of the same size.\n\n.png and .jpg image formats are more complex and in this program they're implemented using [stb_image_write.h](https://github.com/nothings/stb/blob/master/stb_image_write.h) library.\n\u003c/details\u003e\n\u003cbr\u003e\n\n\nFor detailed explanations on this topic check [bibliography](#bibliography).\n\n### MAKEFILE:\n```bash       \n    make build      # compile\n    make clean      # cleanup\n```\n###  SYNOPSIS:\n        ./qr [OPTION]\n###  DESCRIPTION:\n        --config\n                opens header file \"config.h\" to edit program parameters.\n\n## CONFIGURATION PARAMETERS:\n\nCurrently all versions are implemented. For more information about character capacities see [^1]\n1. `version`: there are fixed configurations of QR code sizes that range from 1 to 40: \n```\n        1: 21 x 21; can encode up to 17 ASCII characters\n        2: 25 x 25; can encode up to 32 ASCII characters\n        3: 29 x 29; can encode up to 53 ASCII characters\n        ...\n        40: 177 x 177; can encode up to 2953 ASCII characters\n```                \n2. `error_correction_level`: there are 4 levels of error correction that helps QR code to stay readable even if some pixels can't be recognised by the scanner:\n```\n        0: level M - up to 15%\n        1: level L - up to 7%\n        2: level H - up to 30%\n        3: level Q - up to 25% \n```\n3. `data_type`: QR code can hold 4 different types of data:\n```\n        1: numeric              /* not implemented */\n        2: alphanumeric         /* not implemented */\n        3: bytes\n        4: kanji                /* not implemented */\n```        \n      \n4. `mask_type`: certain patterns in the QR code matrix can make it difficult for QR code scanners to correctly read the code. to counteract this, the QR code specification defines 8 mask patterns:\n```\n        0: (i + j) % 2 == 0\n        1: i % 2 == 0\n        2: j % 3 == 0\n        3: (i + j) % 3 == 0\n        4: (i/2 + j/3) % 2 == 0\n        5: (i*j) % 2 + (i*j) % 3 == 0\n        6: [(i*j) % 3 + i*j ] % 2 == 0\n        7: [(i*j) % 3 + i + j] % 2 == 0\n```\n5. `RGB` color of the QR code is determined by the given amount of red, green and blue color. their values range between 0 and 255.\n\n6. `file`: string that defines output file's name and format.\n```bash\n        name.ppm  #.ppm file\n        name.png  #.png file\n        name.jpg  #.jpg file\n```\n\n7. `scale`: factor used to determine the final size of the generated image\n\n### Example of configuration \n```c\nconfig.h:\n    // QR properties\n    #define version 7\n    #define error_correction_level 1\n    #define data_type 3\n    #define mask_type 3\n    // color parameters\n    #define red 0\n    #define green 0\n    #define blue 0\n    // file name\n    #define file \"QR.png\"\n    #define scale 10\n\n```\nQR code version 7, ec level L, byte format, mask no. 3, color black, generated as .png file\n## CONTRIBUTORS:\nThanks to [radubig](https://github.com/radubig) for fixing memory leaks and overview.\n\n## BIBLIOGRAPHY:\n- [Thonky QR code tutorial](https://www.thonky.com/qr-code-tutorial/)\n- [Reed-Solomon CFC](https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders)\n- [Reed-Solomon EC](https://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction)\n- [Polynomials](https://en.wikipedia.org/wiki/Polynomial_code)\n- [stb library for image formats](https://github.com/nothings/stb)\n\n## LICENSE:\nContent is published under [MIT Licence](https://en.wikipedia.org/wiki/MIT_License). For more information check [LICENSE.md](https://github.com/Ghindea/QR_code_beta/blob/master/LICENSE.md)\n\n---\n[^1]: [character capacities by version](https://www.thonky.com/qr-code-tutorial/character-capacities)\n[^2]: [error correction table](https://www.thonky.com/qr-code-tutorial/error-correction-table)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghindea%2Fqr_code_generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghindea%2Fqr_code_generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghindea%2Fqr_code_generator/lists"}