]> git.sur5r.net Git - glabels/blob - glabels2/qrencode-3.1.0/tests/create_frame_pattern.c
2009-09-22 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / qrencode-3.1.0 / tests / create_frame_pattern.c
1 /*
2  * This tool creates a frame pattern data for debug purpose used by
3  * test_qrspec. test_qrspec and create_frame_pattern uses the same function
4  * of libqrencode. This means the test is meaningless if test_qrspec is run
5  * with a pattern data created by create_frame_pattern of the same version.
6  * In order to test it correctly, create a pattern data by the tool of the
7  * previous version, or use the frame data attached to the package.
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <png.h>
13 #include "common.h"
14 #include "../qrspec.h"
15
16 void append_pattern(int version, FILE *fp)
17 {
18         int width;
19         unsigned char *frame;
20
21         frame = QRspec_newFrame(version);
22         width = QRspec_getWidth(version);
23         fwrite(frame, 1, width * width, fp);
24         free(frame);
25 }
26
27 static int writePNG(unsigned char *frame, int width, const char *outfile)
28 {
29         static FILE *fp;
30         png_structp png_ptr;
31         png_infop info_ptr;
32         unsigned char *row, *p, *q;
33         int x, y, xx, yy, bit;
34         int realwidth;
35         const int margin = 0;
36         const int size = 1;
37
38         realwidth = (width + margin * 2) * size;
39         row = (unsigned char *)malloc((realwidth + 7) / 8);
40         if(row == NULL) {
41                 fprintf(stderr, "Failed to allocate memory.\n");
42                 exit(EXIT_FAILURE);
43         }
44
45         if(outfile[0] == '-' && outfile[1] == '\0') {
46                 fp = stdout;
47         } else {
48                 fp = fopen(outfile, "wb");
49                 if(fp == NULL) {
50                         fprintf(stderr, "Failed to create file: %s\n", outfile);
51                         perror(NULL);
52                         exit(EXIT_FAILURE);
53                 }
54         }
55
56         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
57         if(png_ptr == NULL) {
58                 fclose(fp);
59                 fprintf(stderr, "Failed to initialize PNG writer.\n");
60                 exit(EXIT_FAILURE);
61         }
62
63         info_ptr = png_create_info_struct(png_ptr);
64         if(info_ptr == NULL) {
65                 fclose(fp);
66                 fprintf(stderr, "Failed to initialize PNG write.\n");
67                 exit(EXIT_FAILURE);
68         }
69
70         if(setjmp(png_jmpbuf(png_ptr))) {
71                 png_destroy_write_struct(&png_ptr, &info_ptr);
72                 fclose(fp);
73                 fprintf(stderr, "Failed to write PNG image.\n");
74                 exit(EXIT_FAILURE);
75         }
76
77         png_init_io(png_ptr, fp);
78         png_set_IHDR(png_ptr, info_ptr,
79                         realwidth, realwidth,
80                         1,
81                         PNG_COLOR_TYPE_GRAY,
82                         PNG_INTERLACE_NONE,
83                         PNG_COMPRESSION_TYPE_DEFAULT,
84                         PNG_FILTER_TYPE_DEFAULT);
85         png_write_info(png_ptr, info_ptr);
86
87         /* top margin */
88         memset(row, 0xff, (realwidth + 7) / 8);
89         for(y=0; y<margin * size; y++) {
90                 png_write_row(png_ptr, row);
91         }
92
93         /* data */
94         p = frame;
95         for(y=0; y<width; y++) {
96                 bit = 7;
97                 memset(row, 0xff, (realwidth + 7) / 8);
98                 q = row;
99                 q += margin * size / 8;
100                 bit = 7 - (margin * size % 8);
101                 for(x=0; x<width; x++) {
102                         for(xx=0; xx<size; xx++) {
103                                 *q ^= (*p & 1) << bit;
104                                 bit--;
105                                 if(bit < 0) {
106                                         q++;
107                                         bit = 7;
108                                 }
109                         }
110                         p++;
111                 }
112                 for(yy=0; yy<size; yy++) {
113                         png_write_row(png_ptr, row);
114                 }
115         }
116         /* bottom margin */
117         memset(row, 0xff, (realwidth + 7) / 8);
118         for(y=0; y<margin * size; y++) {
119                 png_write_row(png_ptr, row);
120         }
121
122         png_write_end(png_ptr, info_ptr);
123         png_destroy_write_struct(&png_ptr, &info_ptr);
124
125         fclose(fp);
126         free(row);
127
128         return 0;
129 }
130
131 void write_pattern_image(int version, const char *filename)
132 {
133         int width;
134         unsigned char *frame;
135         static char str[256];
136
137         frame = QRspec_newFrame(version);
138         width = QRspec_getWidth(version);
139
140         snprintf(str, 256, "%s-%d.png", filename, version);
141         writePNG(frame, width, str);
142         free(frame);
143 }
144
145 void write_pattern(const char *filename)
146 {
147         FILE *fp;
148         int i;
149
150         fp = fopen(filename, "wb");
151         if(fp == NULL) {
152                 perror("Failed to open a file to write:");
153                 abort();
154         }
155         for(i=1; i<=QRSPEC_VERSION_MAX; i++) {
156                 append_pattern(i, fp);
157                 write_pattern_image(i, filename);
158         }
159         fclose(fp);
160 }
161
162 int main(int argc, char **argv)
163 {
164         if(argc < 2) {
165                 printf("Create empty frame patterns.\nUsage: %s FILENAME\n", argv[0]);
166                 exit(0);
167         }
168         write_pattern(argv[1]);
169         return 0;
170 }