Skip to content

Commit 7146cc0

Browse files
committed
qrcode
1 parent 0680629 commit 7146cc0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+99145
-13
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.DS_Store
2+
13
# Object files
24
*.o
35
*.ko

config.m4

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,5 @@ if test "$PHP_DCODE" != "no"; then
5959
dnl
6060
dnl PHP_SUBST(DCODE_SHARED_LIBADD)
6161

62-
PHP_NEW_EXTENSION(dcode, dcode.c, $ext_shared)
62+
PHP_NEW_EXTENSION(dcode, dcode.c qrencode/bitstream.c qrencode/mask.c qrencode/mmask.c qrencode/mqrspec.c qrencode/qrenc.c qrencode/qrencode.c qrencode/qrinput.c qrencode/qrspec.c qrencode/rscode.c qrencode/split.c, $ext_shared)
6363
fi

dcode.c

+189-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
/* $Id$ */
2020

2121
#include <sys/time.h>
22+
#include <errno.h>
23+
#include <png.h>
2224

2325
#ifdef HAVE_CONFIG_H
2426
#include "config.h"
@@ -34,6 +36,7 @@
3436
#include "ext/standard/base64.h"
3537
#include "ext/standard/php_string.h"
3638
#include "Zend/zend_strtod.h"
39+
#include "qrencode/qrencode.h"
3740
#include "dcode.h"
3841

3942
/* If you declare any globals in php_dcode.h uncomment this:
@@ -57,7 +60,6 @@ const zend_function_entry dcode_methods[] = {
5760
PHP_ME(dcode, encrypt, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
5861
PHP_ME(dcode, decrypt, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
5962
PHP_ME(dcode, qrcode, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
60-
PHP_ME(dcode, qrcodex, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
6163
PHP_FE_END
6264
};
6365
/* }}} */
@@ -199,6 +201,143 @@ static long dcode_time()
199201
}
200202
/** }}} */
201203

204+
static void dcode_png_writer(png_structp png_ptr, png_bytep data, png_size_t length)
205+
{
206+
struct png_mem_encode* p = (struct png_mem_encode*) png_get_io_ptr(png_ptr);
207+
size_t nsize = p->size + length;
208+
if (p->buffer)
209+
{
210+
p->buffer = erealloc(p->buffer, nsize);
211+
}
212+
else {
213+
p->buffer = emalloc(nsize);
214+
}
215+
216+
if (!p->buffer)
217+
{
218+
png_error(png_ptr, "Png image write error");
219+
exit(FAILURE);
220+
}
221+
222+
memcpy(p->buffer + p->size, data, length);
223+
p->size += length;
224+
}
225+
226+
static int dcode_write_to_png(QRcode *qrcode, int size, int margin, char **bin_data)
227+
{
228+
struct png_mem_encode state;
229+
state.buffer = NULL;
230+
state.size = 0;
231+
232+
png_structp png_ptr;
233+
png_infop info_ptr;
234+
235+
unsigned char *row, *p, *q;
236+
int x, y, xx, yy, bit;
237+
int realwidth;
238+
239+
realwidth = (qrcode->width + margin * 2) * size;
240+
241+
int row_fill_len = (realwidth + 7) / 8;
242+
row = (unsigned char *) emalloc(row_fill_len);
243+
244+
if (row == NULL)
245+
{
246+
php_error(E_ERROR, "Failed to allocate memory");
247+
return 0;
248+
}
249+
250+
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
251+
if (png_ptr == NULL)
252+
{
253+
php_error(E_ERROR, "Failed to initialize PNG writer");
254+
return 0;
255+
}
256+
257+
info_ptr = png_create_info_struct(png_ptr);
258+
if (info_ptr == NULL)
259+
{
260+
php_error(E_ERROR, "Failed to initialize PNG writer");
261+
return 0;
262+
}
263+
264+
if (setjmp(png_jmpbuf(png_ptr)))
265+
{
266+
png_destroy_write_struct(&png_ptr, &info_ptr);
267+
php_error(E_ERROR, "Failed to write PNG image");
268+
return 0;
269+
}
270+
//
271+
// fseek(fp, 0, SEEK_SET);
272+
// ftruncate(fileno(fp), 0);
273+
png_set_write_fn(png_ptr, &state, dcode_png_writer, NULL);
274+
275+
// png_init_io(png_ptr, fp);
276+
png_set_IHDR(png_ptr, info_ptr,
277+
realwidth, realwidth,
278+
1,
279+
PNG_COLOR_TYPE_GRAY,
280+
PNG_INTERLACE_NONE,
281+
PNG_COMPRESSION_TYPE_DEFAULT,
282+
PNG_FILTER_TYPE_DEFAULT);
283+
png_write_info(png_ptr, info_ptr);
284+
285+
/* top margin */
286+
memset(row, 0xff, row_fill_len);
287+
for(y = 0; y < margin * size; y ++)
288+
{
289+
png_write_row(png_ptr, row);
290+
}
291+
292+
/* data */
293+
p = qrcode->data;
294+
for(y = 0; y < qrcode->width; y ++)
295+
{
296+
bit = 7;
297+
memset(row, 0xff, row_fill_len);
298+
q = row;
299+
q += margin * size / 8;
300+
bit = 7 - (margin * size % 8);
301+
for(x = 0; x < qrcode->width; x ++)
302+
{
303+
for(xx = 0; xx < size; xx ++)
304+
{
305+
*q ^= (*p & 1) << bit;
306+
bit--;
307+
if(bit < 0)
308+
{
309+
q++;
310+
bit = 7;
311+
}
312+
}
313+
p++;
314+
}
315+
316+
for(yy = 0; yy < size; yy ++)
317+
{
318+
png_write_row(png_ptr, row);
319+
}
320+
}
321+
/* bottom margin */
322+
memset(row, 0xff, row_fill_len);
323+
for(y = 0; y < margin * size; y ++)
324+
{
325+
png_write_row(png_ptr, row);
326+
}
327+
328+
png_write_end(png_ptr, info_ptr);
329+
png_destroy_write_struct(&png_ptr, &info_ptr);
330+
331+
efree(row);
332+
333+
if (state.buffer) {
334+
*bin_data = estrndup(state.buffer, 1);
335+
efree(state.buffer);
336+
return 1;
337+
}
338+
return 0;
339+
}
340+
202341
/** {{{ DCode::encrypt($src, $sec_key = "THIS IS SHIT", $sec_rand_key_len = 8, $expire = 0)
203342
Return False or String */
204343
PHP_METHOD(dcode, encrypt)
@@ -214,19 +353,19 @@ PHP_METHOD(dcode, encrypt)
214353

215354
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sll", &src, &src_len, &key, &key_len, &ck_len, &expire) == FAILURE)
216355
{
217-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
356+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments");
218357
RETURN_FALSE;
219358
}
220359

221360
if (ck_len > DCODE_MD5_SIZE || ck_len < 0)
222361
{
223-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments sec_rand_key_len must 0-32");
362+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments sec_rand_key_len must 0-32");
224363
RETURN_FALSE;
225364
}
226365

227366
if (expire < 0)
228367
{
229-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments expire >= 0");
368+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments expire >= 0");
230369
RETURN_FALSE;
231370
}
232371

@@ -365,13 +504,13 @@ PHP_METHOD(dcode, decrypt)
365504

366505
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sl", &src, &src_len, &key, &key_len, &ck_len) == FAILURE)
367506
{
368-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
507+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments");
369508
RETURN_FALSE;
370509
}
371510

372511
if (ck_len > DCODE_MD5_SIZE || ck_len < 0)
373512
{
374-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments sec_rand_key_len must 0-32");
513+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments sec_rand_key_len must 0-32");
375514
RETURN_FALSE;
376515
}
377516

@@ -465,7 +604,8 @@ PHP_METHOD(dcode, decrypt)
465604
efree(cmp_md5);
466605

467606
if ((expire_time == 0 || (expire_time - dcode_time()) > 0)
468-
&& strcmp(cmp_kb, cmp_md5_h) == 0) {
607+
&& strcmp(cmp_kb, cmp_md5_h) == 0)
608+
{
469609
ZVAL_STRING(return_value, cmp_kb_md5, 1);
470610
efree(cmp_kb_md5);
471611
efree(cmp_md5_h);
@@ -481,12 +621,51 @@ PHP_METHOD(dcode, decrypt)
481621

482622
PHP_METHOD(dcode, qrcode)
483623
{
624+
char *str_encode;
625+
int str_encode_len;
484626

485-
}
627+
int version = 0;
628+
int level = (int) QR_ECLEVEL_L;
629+
int mode = (int) QR_MODE_KANJI;
630+
int casesensitive = 0;
486631

487-
PHP_METHOD(dcode, qrcodex)
488-
{
632+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|llll", &str_encode, &str_encode_len, &version, &level, &mode, &casesensitive) == FAILURE) {
633+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid arguments");
634+
RETURN_FALSE;
635+
}
489636

637+
QRcode *qcode = NULL;
638+
qcode = QRcode_encodeString(str_encode, version, (QRecLevel) level, (QRencodeMode) mode, casesensitive);
639+
if (qcode == NULL)
640+
{
641+
if (errno == EINVAL) {
642+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "DCode::qrcode error, error invalid input object");
643+
}
644+
else if (errno == ENOMEM) {
645+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "DCode::qrcode error, unable to allocate memory for input objects");
646+
}
647+
else if (errno == ERANGE) {
648+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "DCode::qrcode error, input data is too large");
649+
}
650+
else {
651+
php_error_docref(NULL TSRMLS_CC, E_ERROR, "DCode::qrcode error, errno : %d", errno);
652+
}
653+
RETURN_FALSE;
654+
}
655+
656+
char *bin_data = NULL;
657+
int ok = dcode_write_to_png(qcode, 3, 4, &bin_data);
658+
QRcode_free(qcode);
659+
qcode = NULL;
660+
if (ok)
661+
{
662+
ZVAL_STRING(return_value, bin_data, 1);
663+
efree(bin_data);
664+
return;
665+
}
666+
else {
667+
RETURN_FALSE;
668+
}
490669
}
491670

492671
/*

dcode.h

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818

1919
/* $Id$ */
20+
#ifndef DCODE_H
21+
#define DCODE_H
2022

2123
#define DCODE_KEY "THIS IS SHIT"
2224
#define DCODE_CN "DCode"
@@ -25,6 +27,11 @@
2527
#define DCODE_MICROTIME_SIZE 100
2628
#define DCODE_MICRO_IN_SEC 1000000.00
2729

30+
struct png_mem_encode {
31+
char *buffer;
32+
size_t size;
33+
};
34+
#endif
2835
/*
2936
* Local variables:
3037
* tab-width: 4

php_dcode.h

-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ PHP_MINFO_FUNCTION(dcode);
4747
PHP_METHOD(dcode, encrypt);
4848
PHP_METHOD(dcode, decrypt);
4949
PHP_METHOD(dcode, qrcode);
50-
PHP_METHOD(dcode, qrcodex);
5150

5251
/*
5352
Declare any global variables you may need between the BEGIN

0 commit comments

Comments
 (0)