19
19
/* $Id$ */
20
20
21
21
#include <sys/time.h>
22
+ #include <errno.h>
23
+ #include <png.h>
22
24
23
25
#ifdef HAVE_CONFIG_H
24
26
#include "config.h"
34
36
#include "ext/standard/base64.h"
35
37
#include "ext/standard/php_string.h"
36
38
#include "Zend/zend_strtod.h"
39
+ #include "qrencode/qrencode.h"
37
40
#include "dcode.h"
38
41
39
42
/* If you declare any globals in php_dcode.h uncomment this:
@@ -57,7 +60,6 @@ const zend_function_entry dcode_methods[] = {
57
60
PHP_ME (dcode , encrypt , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
58
61
PHP_ME (dcode , decrypt , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
59
62
PHP_ME (dcode , qrcode , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
60
- PHP_ME (dcode , qrcodex , NULL , ZEND_ACC_PUBLIC | ZEND_ACC_STATIC )
61
63
PHP_FE_END
62
64
};
63
65
/* }}} */
@@ -199,6 +201,143 @@ static long dcode_time()
199
201
}
200
202
/** }}} */
201
203
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
+
202
341
/** {{{ DCode::encrypt($src, $sec_key = "THIS IS SHIT", $sec_rand_key_len = 8, $expire = 0)
203
342
Return False or String */
204
343
PHP_METHOD (dcode , encrypt )
@@ -214,19 +353,19 @@ PHP_METHOD(dcode, encrypt)
214
353
215
354
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s|sll" , & src , & src_len , & key , & key_len , & ck_len , & expire ) == FAILURE )
216
355
{
217
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Invalid arguments ");
356
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid arguments ");
218
357
RETURN_FALSE ;
219
358
}
220
359
221
360
if (ck_len > DCODE_MD5_SIZE || ck_len < 0 )
222
361
{
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" );
224
363
RETURN_FALSE ;
225
364
}
226
365
227
366
if (expire < 0 )
228
367
{
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" );
230
369
RETURN_FALSE ;
231
370
}
232
371
@@ -365,13 +504,13 @@ PHP_METHOD(dcode, decrypt)
365
504
366
505
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "s|sl" , & src , & src_len , & key , & key_len , & ck_len ) == FAILURE )
367
506
{
368
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Invalid arguments ");
507
+ php_error_docref (NULL TSRMLS_CC , E_ERROR , "Invalid arguments ");
369
508
RETURN_FALSE ;
370
509
}
371
510
372
511
if (ck_len > DCODE_MD5_SIZE || ck_len < 0 )
373
512
{
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" );
375
514
RETURN_FALSE ;
376
515
}
377
516
@@ -465,7 +604,8 @@ PHP_METHOD(dcode, decrypt)
465
604
efree (cmp_md5 );
466
605
467
606
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
+ {
469
609
ZVAL_STRING (return_value , cmp_kb_md5 , 1 );
470
610
efree (cmp_kb_md5 );
471
611
efree (cmp_md5_h );
@@ -481,12 +621,51 @@ PHP_METHOD(dcode, decrypt)
481
621
482
622
PHP_METHOD (dcode , qrcode )
483
623
{
624
+ char * str_encode ;
625
+ int str_encode_len ;
484
626
485
- }
627
+ int version = 0 ;
628
+ int level = (int ) QR_ECLEVEL_L ;
629
+ int mode = (int ) QR_MODE_KANJI ;
630
+ int casesensitive = 0 ;
486
631
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
+ }
489
636
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
+ }
490
669
}
491
670
492
671
/*
0 commit comments