📄 qrenc.c
字号:
/** * qrencode - QR Code encoder * * QR Code encoding tool * Copyright (C) 2006,2007 Kentaro Fukuchi <fukuchi@megaui.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include <stdio.h>#include <stdlib.h>#include <png.h>#include <getopt.h>#include "qrencode.h"static int casesensitive = 0;static int eightbit = 0;static int kanji = 0;static int version = 0;static int size = 3;static int margin = 4;static QRecLevel level = QR_ECLEVEL_L;enum { O_HELP, O_OUTPUT, O_SIZE, O_VERSION, O_LEVEL, O_MARGIN, O_KANJI, O_CASE, O_8BIT,};static const struct option options[] = { {"h", no_argument , NULL, O_HELP}, {"o", required_argument, NULL, O_OUTPUT}, {"l", required_argument, NULL, O_LEVEL}, {"s", required_argument, NULL, O_SIZE}, {"v", required_argument, NULL, O_VERSION}, {"m", required_argument, NULL, O_MARGIN}, {"k", no_argument , NULL, O_KANJI}, {"c", no_argument , NULL, O_CASE}, {"8", no_argument , NULL, O_8BIT}, {NULL, 0, NULL, 0}};static void usage(void){ fprintf(stderr,"qrencode version %s\n\n""Usage: qrencode [OPTION]... [STRING]\n""Encode input data in a QR Code and save as a PNG image.\n\n"" -h display this message.\n"" -o FILENAME write PNG image to FILENAME. If '-' is specified, the result\n"" will be output to standard output.\n"" -s NUMBER specify the size of dot (pixel). (default=3)\n"" -l {LMQH} specify error collectin level from L (lowest) to H (highest).\n"" (default=L)\n"" -v NUMBER specify the version of the symbol. (default=auto)\n"" -m NUMBER specify the width of margin. (default=4)\n"" -k assume that the input text contains kanji (shift-jis).\n"" -c encode alphabet characters in 8-bit mode. If your application\n"" is case-sensitive, choose this.\n"" -8 encode entire data in 8-bit mode. -c and -k will be ignored.\n"" [STRING] input data. If it is not specified, data will be taken from\n"" standard input.\n", VERSION);}#define MAX_DATA_SIZE 7090 /* from the specification */static char *readStdin(void){ char *buffer; int ret; buffer = (char *)malloc(MAX_DATA_SIZE); ret = fread(buffer, 1, MAX_DATA_SIZE, stdin); if(ret == 0) { fprintf(stderr, "No input data.\n"); exit(1); } if(!feof(stdin)) { fprintf(stderr, "Input data is too large.\n"); exit(1); } buffer[ret] = '\0'; return buffer;}static QRcode *encode(const char *intext){ QRencodeMode hint; QRcode *code; if(kanji) { hint = QR_MODE_KANJI; } else { hint = QR_MODE_8; } if(eightbit) { code = QRcode_encodeString8bit(intext, version, level); } else { code = QRcode_encodeString(intext, version, level, hint, casesensitive); } return code;}static void qrencode(const char *intext, const char *outfile){ FILE *fp; QRcode *qrcode; png_structp png_ptr; png_infop info_ptr; unsigned char *row, *p, *q; int x, y, xx, yy, bit; int realwidth; qrcode = encode(intext); if(qrcode == NULL) { fprintf(stderr, "Failed to encode the input data.\n"); exit(1); } realwidth = (qrcode->width + margin * 2) * size; row = (unsigned char *)malloc((realwidth + 7) / 8); if(outfile[0] == '-' && outfile[1] == '\0') { fp = stdout; } else { fp = fopen(outfile, "w"); if(fp == NULL) { fprintf(stderr, "Failed to create file: %s\n", outfile); perror(NULL); exit(1); } } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(png_ptr == NULL) { fclose(fp); fprintf(stderr, "Failed to initialize PNG writer.\n"); exit(1); } info_ptr = png_create_info_struct(png_ptr); if(info_ptr == NULL) { fclose(fp); fprintf(stderr, "Failed to initialize PNG write.\n"); exit(1); } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); fprintf(stderr, "Failed to write PNG image.\n"); exit(1); } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, realwidth, realwidth, 1, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); /* top margin */ memset(row, 0xff, (realwidth + 7) / 8); for(y=0; y<margin * size; y++) { png_write_row(png_ptr, row); } /* data */ p = qrcode->data; for(y=0; y<qrcode->width; y++) { bit = 7; memset(row, 0xff, (realwidth + 7) / 8); q = row; q += margin * size / 8; bit = 7 - (margin * size % 8); for(x=0; x<qrcode->width; x++) { for(xx=0; xx<size; xx++) { *q ^= (*p & 1) << bit; bit--; if(bit < 0) { q++; bit = 7; } } p++; } for(yy=0; yy<size; yy++) { png_write_row(png_ptr, row); } } /* bottom margin */ memset(row, 0xff, (realwidth + 7) / 8); for(y=0; y<margin * size; y++) { png_write_row(png_ptr, row); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); free(row); QRcode_free(qrcode);}int main(int argc, char **argv){ int opt; char *outfile = NULL; char *intext = NULL; while((opt = getopt_long_only(argc, argv, "", options, NULL)) != -1) { switch(opt) { case O_HELP: usage(); exit(0); break; case O_OUTPUT: outfile = optarg; break; case O_SIZE: size = atoi(optarg); if(size <= 0) { fprintf(stderr, "Invalid size: %d\n", size); exit(1); } break; case O_VERSION: version = atoi(optarg); if(version < 0) { fprintf(stderr, "Invalid version: %d\n", version); exit(1); } break; case O_LEVEL: switch(*optarg) { case 'l': case 'L': level = QR_ECLEVEL_L; break; case 'm': case 'M': level = QR_ECLEVEL_M; break; case 'q': case 'Q': level = QR_ECLEVEL_Q; break; case 'h': case 'H': level = QR_ECLEVEL_H; break; default: fprintf(stderr, "Invalid level: %s\n", optarg); exit(1); break; } break; case O_MARGIN: margin = atoi(optarg); if(margin < 0) { fprintf(stderr, "Invalid margin: %d\n", margin); exit(1); } break; case O_KANJI: kanji = 1; break; case O_CASE: casesensitive = 1; break; case O_8BIT: eightbit = 1; break; default: usage(); exit(1); break; } } if(argc == 1) { usage(); exit(0); } if(outfile == NULL) { fprintf(stderr, "No output filename is given.\n"); exit(1); } if(optind < argc) { intext = argv[optind]; } if(intext == NULL) { intext = readStdin(); } qrencode(intext, outfile); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -