aboutsummaryrefslogtreecommitdiff
path: root/lpg
diff options
context:
space:
mode:
authorLeo Uino <leo@norisys.jp>2013-01-14 23:01:58 +0900
committerLeo Uino <leo@norisys.jp>2013-01-14 23:01:58 +0900
commit7cfac56b2eaec43e507bf31313d5a16ac8133fba (patch)
tree1fb624c8626297fe6b0431e1def2d60b8007543e /lpg
parent082fc1b97f2297fee6b2bba222c0c2e87f931493 (diff)
downloadpdf-simple-sign-7cfac56b2eaec43e507bf31313d5a16ac8133fba.tar.gz
pdf-simple-sign-7cfac56b2eaec43e507bf31313d5a16ac8133fba.tar.xz
pdf-simple-sign-7cfac56b2eaec43e507bf31313d5a16ac8133fba.zip
qrgen: output to PNG
Diffstat (limited to 'lpg')
-rw-r--r--lpg/libqr/Makefile2
-rw-r--r--lpg/libqr/qrgen.c111
2 files changed, 104 insertions, 9 deletions
diff --git a/lpg/libqr/Makefile b/lpg/libqr/Makefile
index fa6cf04..154bcbf 100644
--- a/lpg/libqr/Makefile
+++ b/lpg/libqr/Makefile
@@ -21,7 +21,7 @@ $(OBJECTS) : $(wildcard *.h qr/*.h)
libqr : libqr.a($(OBJECTS))
qrgen : libqr qrgen.c
- $(CC) $(CFLAGS) -o qrgen qrgen.c libqr.a
+ $(CC) $(CFLAGS) -o qrgen qrgen.c libqr.a $(shell pkg-config libpng --cflags --libs)
qrparse : libqr qrparse.c
$(CC) $(CFLAGS) -o qrparse qrparse.c libqr.a
diff --git a/lpg/libqr/qrgen.c b/lpg/libqr/qrgen.c
index 80e8ac2..cf518e5 100644
--- a/lpg/libqr/qrgen.c
+++ b/lpg/libqr/qrgen.c
@@ -2,6 +2,8 @@
#include <ctype.h>
#include <getopt.h>
#include <limits.h>
+#include <png.h>
+#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -16,7 +18,11 @@ struct config {
int version;
enum qr_ec_level ec;
enum qr_data_type dtype;
- int ansi;
+ enum {
+ FORMAT_ANSI,
+ FORMAT_PBM,
+ FORMAT_PNG
+ } format;
const char * file;
const char * outfile;
const char * input;
@@ -120,6 +126,78 @@ void output_ansi(FILE * file, const struct qr_bitmap * bmp)
}
}
+void output_png(FILE * file, const struct qr_bitmap * bmp, const char * comment)
+{
+ const int px_size = 4;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_text text;
+ int x, y, p;
+ unsigned char * row;
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!png_ptr)
+ goto err;
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ goto err;
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ goto err;
+
+ png_init_io(png_ptr, file);
+ png_set_IHDR(png_ptr, info_ptr,
+ (bmp->width + 8) * px_size,
+ (bmp->height + 8) * px_size,
+ 1,
+ PNG_COLOR_TYPE_GRAY,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
+
+ text.compression = PNG_TEXT_COMPRESSION_NONE;
+ text.key = "Software";
+ text.text = (char *) comment;
+ text.text_length = strlen(comment);
+ png_set_text(png_ptr, info_ptr, &text, 1);
+
+ png_write_info(png_ptr, info_ptr);
+ png_set_packing(png_ptr);
+
+ row = malloc((bmp->width + 8) * px_size);
+ memset(row, 1, (bmp->width + 8) * px_size);
+ for (y = 0; y < 4; ++y)
+ for (p = 0; p < px_size; ++p)
+ png_write_row(png_ptr, row);
+
+ for (y = 0; y < bmp->height; ++y) {
+ const unsigned char * bmp_row = bmp->bits + y * bmp->stride;
+ unsigned char * out = row + 4 * px_size;
+ for (x = 0; x < bmp->width; ++x) {
+ int px = bmp_row[x / CHAR_BIT] & (1 << (x % CHAR_BIT));
+ for (p = 0; p < px_size; ++p)
+ *out++ = !px;
+ }
+ for (p = 0; p < px_size; ++p)
+ png_write_row(png_ptr, row);
+ }
+
+ memset(row, 1, (bmp->width + 8) * px_size);
+ for (y = 0; y < 4; ++y)
+ for (p = 0; p < px_size; ++p)
+ png_write_row(png_ptr, row);
+
+ free(row);
+ png_write_end(png_ptr, info_ptr);
+ png_destroy_write_struct(&png_ptr, NULL);
+ return;
+
+err:
+ fprintf(stderr, "error writing PNG\n");
+ exit(2);
+}
+
void show_help() {
fprintf(stderr,
"Usage:\n\t%s [options] <data>\n\n"
@@ -129,6 +207,7 @@ void show_help() {
"\t-e <type> Specify EC type: L, M, Q, H\n"
"\t-a Output as ANSI graphics (default)\n"
"\t-p Output as PBM\n"
+ "\t-g Output as PNG\n"
"\t-o <file> File to write (- for stdout)\n\n",
"qrgen");
}
@@ -138,7 +217,7 @@ void set_default_config(struct config * conf)
conf->version = 0;
conf->ec = QR_EC_LEVEL_M;
conf->dtype = QR_DATA_8BIT;
- conf->ansi = 1;
+ conf->format = FORMAT_ANSI;
conf->file = NULL;
conf->outfile = NULL;
conf->input = NULL;
@@ -149,7 +228,7 @@ void parse_options(int argc, char ** argv, struct config * conf)
int c;
for (;;) {
- c = getopt(argc, argv, ":hf:v:e:t:apo:");
+ c = getopt(argc, argv, ":hf:v:e:t:apgo:");
if (c == -1) /* no more options */
break;
@@ -186,9 +265,11 @@ void parse_options(int argc, char ** argv, struct config * conf)
fprintf(stderr, "XXX: ignored \"type\"\n");
break;
case 'a': /* ansi */
- conf->ansi = 1; break;
+ conf->format = FORMAT_ANSI; break;
case 'p': /* pnm */
- conf->ansi = 0; break;
+ conf->format = FORMAT_PBM; break;
+ case 'g': /* png */
+ conf->format = FORMAT_PNG; break;
case 'o': /* output file */
conf->outfile = optarg; break;
case ':':
@@ -272,7 +353,14 @@ int main(int argc, char ** argv) {
len = strlen(conf.input);
if (!conf.outfile) {
- conf.outfile = conf.ansi ? "-" : "qr.pbm";
+ switch (conf.format) {
+ case FORMAT_ANSI:
+ conf.outfile = "-"; break;
+ case FORMAT_PBM:
+ conf.outfile = "qr.pbm"; break;
+ case FORMAT_PNG:
+ conf.outfile = "qr.png"; break;
+ }
}
if (strcmp(conf.outfile, "-") == 0) {
@@ -294,10 +382,17 @@ int main(int argc, char ** argv) {
if (conf.file)
free(file_data);
- if (conf.ansi)
+ switch (conf.format) {
+ case FORMAT_ANSI:
output_ansi(outfile, code->modules);
- else
+ break;
+ case FORMAT_PBM:
output_pbm(outfile, code->modules, "libqr v" QR_VERSION);
+ break;
+ case FORMAT_PNG:
+ output_png(outfile, code->modules, "libqr v" QR_VERSION);
+ break;
+ }
fclose(outfile);
qr_code_destroy(code);