├── .gitignore ├── ChangeLog ├── LICENSE ├── Makefile ├── README.md ├── qrencode.c └── test └── test.lua /.gitignore: -------------------------------------------------------------------------------- 1 | qrencode.so 2 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2019-10-23 vinoca 2 | * qrencode.c: 3 | * fix lua 5.3 4 | 5 | 2014-11-03 vinoca 6 | * qrencode.c: 7 | * fixed a bug when initialize value. 8 | [1.0] 9 | - Bumped verstion to 1.0.2 10 | 11 | 2014-10-30 vinoca 12 | * qrencode.c: 13 | * add ansi type. 14 | [1.0] 15 | * add luarocks rockspec. 16 | - Bumped verstion to 1.0.1 17 | 18 | 2014-10-16 vinoca 19 | * Bumped version to 1.0.0. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | qrencode License 2 | ----------- 3 | 4 | qrencode is licensed under the terms of the MIT license reproduced below. 5 | This means that qrencode is free software and can be used for both academic 6 | and commercial purposes at absolutely no cost. 7 | 8 | =============================================================================== 9 | 10 | Copyright (C) 2014-2015 www.vinoca.org, vinoca. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. 29 | 30 | =============================================================================== 31 | 32 | (end of COPYRIGHT) 33 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LIBNAME= qrencode 2 | CFLAGS= -std=gnu99 -pedantic -Wall -Wextra -O2 -shared -fPIC 3 | 4 | all: so 5 | 6 | so: $(LIBNAME).c 7 | $(CC) $(CFLAGS) $(LIBNAME).c -lqrencode -lpng -o $(LIBNAME).so 8 | 9 | clean: 10 | rm -f $(LIBNAME).so 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # qrencode: qrencode is a wrapper of libqrencode with libpng for lua. 2 | 3 | qrencode is a wrapper of [libqrencode](http://fukuchi.org/works/qrencode/) with libpng for lua. 4 | 5 | ## Install 6 | 7 | qrencode is dependent on [libqrencode](http://fukuchi.org/works/qrencode/) 8 | and [libpng](http://www.libpng.org/pub/png/libpng.html), so make sure these are installed 9 | before compile it. 10 | 11 | ### CentOS 12 | 13 | ```shell 14 | yum install -y qrencode-devel libpng-devel 15 | make 16 | ``` 17 | 18 | ## Example usage 19 | 20 | ### simple usage 21 | 22 | ```lua 23 | qr = require "qrencode" 24 | 25 | -- print PNG data stream to stdout. 26 | 27 | print(qr.encode("is ok?")) 28 | print(qr:encode("is ok?")) 29 | print(qr("is ok?")) 30 | print(qr {text = "is ok?", level = "M"}) 31 | 32 | -- or pass a table : 33 | 34 | print(qr { 35 | text="is ok?", 36 | level="L", 37 | kanji=false, 38 | size=4, 39 | margin=2, 40 | symversion=0, 41 | dpi=78, 42 | casesensitive=false, 43 | foreground="48AF6D", 44 | background="3FAF6F" 45 | } 46 | ) 47 | 48 | 49 | ``` 50 | 51 | ### in [nginx lua](https://github.com/openresty/lua-nginx-module) 52 | 53 | ```lua 54 | local qr = require "qrencode" 55 | local args = ngx.req.get_uri_args() 56 | 57 | ngx.header.content_type = 'image/png' 58 | ngx.say( 59 | qr { 60 | text = args.text, 61 | size = args.size or 8, 62 | margin = args.margin or 1, 63 | symversion = 2, 64 | level = 'M', 65 | foreground = args.fg, 66 | background = args.bg 67 | } 68 | ) 69 | ``` 70 | 71 | or nginx config file 72 | 73 | ```nginx 74 | server { 75 | server_name qr.corp.com; 76 | 77 | location /qr { 78 | content_by_lua_block { 79 | local qr = require "qrencode" 80 | local args = ngx.req.get_uri_args() 81 | 82 | ngx.header.content_type = 'image/png' 83 | ngx.say( qr { 84 | text = args.text, 85 | size = args.size or 8, 86 | margin = args.margin or 1, 87 | symversion = 2, 88 | level = 'M', 89 | foreground = args.fg, 90 | background = args.bg 91 | }) 92 | } 93 | } 94 | } 95 | ``` 96 | 97 | and visit `http://qr.corp.com/qr?text=works` to test it. 98 | 99 | when pass a table, "text" is required and other is optional. 100 | 101 | ## Author 102 | 103 | vinoca 104 | 105 | ## Copyright and license 106 | 107 | Code and documentation copyright 2014-2020 vinoca. Code released under the MIT license. 108 | Docs released under Creative commons. 109 | -------------------------------------------------------------------------------- /qrencode.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | 15 | #if LUA_VERSION_NUM < 502 16 | # define luaL_newlib(L,l) (lua_newtable(L), luaL_register(L,NULL,l)) 17 | #endif 18 | 19 | struct memData { 20 | char *buffer; 21 | size_t size; 22 | }; 23 | 24 | #define INCHES_PER_METER (100.0/2.54) 25 | 26 | static int size; 27 | static int margin; 28 | static int dpi; 29 | static unsigned int fg_color[4]; 30 | static unsigned int bg_color[4]; 31 | 32 | 33 | /* png io callback function */ 34 | static void cp_png_data(png_structp png_ptr, png_bytep data, png_size_t length) 35 | { 36 | struct memData* p = (struct memData*)png_get_io_ptr(png_ptr); 37 | 38 | p->buffer = realloc(p->buffer, p->size + length); 39 | if (!p->buffer) 40 | png_error(png_ptr, "Write Error"); 41 | 42 | memcpy(p->buffer + p->size, data, length); 43 | p->size += length; 44 | } 45 | 46 | /* 0:failure/1:true to_png( qrcode: qr data , result: buffer to save result.) {{{ */ 47 | static int to_png(const QRcode *qrcode, struct memData *result) 48 | { 49 | png_structp png_ptr; 50 | png_infop info_ptr; 51 | png_colorp palette; 52 | png_byte alpha_values[2]; 53 | 54 | unsigned char *row, *p, *q; 55 | int x, y, xx, yy, bit; 56 | int realwidth; 57 | 58 | realwidth = (qrcode->width + margin * 2) * size; 59 | row = (unsigned char *)malloc((realwidth + 7) / 8); 60 | if (row == NULL) { 61 | fprintf(stderr, "Failed to allocate memory.\n"); 62 | return 0; 63 | } 64 | 65 | png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 66 | if (png_ptr == NULL) { 67 | fprintf(stderr, "Failed to initialize PNG writer.\n"); 68 | return 0; 69 | } 70 | 71 | info_ptr = png_create_info_struct(png_ptr); 72 | if (info_ptr == NULL) { 73 | fprintf(stderr, "Failed to initialize PNG write.\n"); 74 | return 0; 75 | } 76 | 77 | if (setjmp(png_jmpbuf(png_ptr))) { 78 | png_destroy_write_struct(&png_ptr, &info_ptr); 79 | fprintf(stderr, "Failed to write PNG image.\n"); 80 | return 0; 81 | } 82 | 83 | png_set_write_fn(png_ptr, result, cp_png_data, NULL); 84 | 85 | palette = (png_colorp) malloc(sizeof(png_color) * 2); 86 | if (palette == NULL) { 87 | fprintf(stderr, "Failed to allocate memory.\n"); 88 | return 0; 89 | } 90 | palette[0].red = fg_color[0]; 91 | palette[0].green = fg_color[1]; 92 | palette[0].blue = fg_color[2]; 93 | palette[1].red = bg_color[0]; 94 | palette[1].green = bg_color[1]; 95 | palette[1].blue = bg_color[2]; 96 | alpha_values[0] = fg_color[3]; 97 | alpha_values[1] = bg_color[3]; 98 | png_set_PLTE(png_ptr, info_ptr, palette, 2); 99 | png_set_tRNS(png_ptr, info_ptr, alpha_values, 2, NULL); 100 | 101 | png_set_IHDR(png_ptr, info_ptr, 102 | realwidth, realwidth, 103 | 1, 104 | PNG_COLOR_TYPE_PALETTE, 105 | PNG_INTERLACE_NONE, 106 | PNG_COMPRESSION_TYPE_DEFAULT, 107 | PNG_FILTER_TYPE_DEFAULT); 108 | png_set_pHYs(png_ptr, info_ptr, 109 | dpi * INCHES_PER_METER, 110 | dpi * INCHES_PER_METER, 111 | PNG_RESOLUTION_METER); 112 | png_write_info(png_ptr, info_ptr); 113 | 114 | /* top margin */ 115 | memset(row, 0xff, (realwidth + 7) / 8); 116 | for(y=0; ydata; 122 | for(y=0; ywidth; y++) { 123 | bit = 7; 124 | memset(row, 0xff, (realwidth + 7) / 8); 125 | q = row; 126 | q += margin * size / 8; 127 | bit = 7 - (margin * size % 8); 128 | for(x=0; xwidth; x++) { 129 | for(xx=0; xx