void qrpng_internal (HV * options) { char * text; unsigned text_length; qr_t qr = {0}; qrpng_t qrpng = {0}; SV ** sv_ptr; qrpng_status_t qrpng_status; SV ** size_ptr; /* Get the text. This is assumed to exist. */ HASH_FETCH_PV (options, text); qr.input = text; qr.input_length = text_length; qr.level = 1; sv_ptr = hv_fetch (options, "level", strlen ("level"), 0); if (sv_ptr) { qr.level = SvUV (* sv_ptr); } if (qr.level < 1 || qr.level > 4) { croak ("Bad level %d; this is between 1 and 4", qr.level); } sv_ptr = hv_fetch (options, "version", strlen ("version"), 0); if (sv_ptr) { qr.version = SvUV (* sv_ptr); if (qr.version < 1 || qr.version > 40) { croak ("Bad version %d; this is between 1 and 40", qr.version); } initecc (& qr); } else { initeccsize (& qr); } initframe(& qr); qrencode (& qr); sv_ptr = hv_fetch (options, "quiet", strlen ("quiet"), 0); if (sv_ptr) { SV * quiet_sv; quiet_sv = * sv_ptr; qrpng.quietzone = SvUV (quiet_sv); } else { qrpng.quietzone = QUIETZONE; } sv_ptr = hv_fetch (options, "scale", strlen ("scale"), 0); if (sv_ptr) { SV * scale_sv; scale_sv = * sv_ptr; qrpng.scale = SvUV (scale_sv); } else { qrpng.scale = 3; } qrpng_status = qrpng_make_png (& qr, & qrpng); if (qrpng_status != qrpng_ok) { croak ("bad status %d from qrpng_make_png", qrpng_status); } sv_ptr = hv_fetch (options, "out_sv", strlen ("out_sv"), 0); if (sv_ptr) { /* Write it as a scalar. The code is copied out of Image::PNG::Libpng, but we don't depend on that. */ scalar_as_image_t si = {0}; png_set_write_fn (qrpng.png, & si, perl_png_scalar_write, 0 /* No flush function */); /* Write using our function. */ png_write_png (qrpng.png, qrpng.info, PNG_TRANSFORM_INVERT_MONO, NULL); /* Put the data into %options as $options{png_data}. */ (void) hv_store (options, "png_data", strlen ("png_data"), si.png_image, 0); } else { char * out; unsigned int out_length; HASH_FETCH_PV (options, out); qrpng.filename = out; qrpng_write (& qrpng); } size_ptr = hv_fetch (options, "size", strlen ("size"), 0); if (size_ptr) { // fprintf (stderr, "%s:%d: OK baby.\n", __FILE__, __LINE__); if (SvROK (* size_ptr) && SvTYPE (SvRV (* size_ptr)) < SVt_PVAV) { SV * sv = SvRV (* size_ptr); // fprintf (stderr, "%s:%d: OK baby.\n", __FILE__, __LINE__); sv_setuv (sv, (UV) qrpng.img_size); } } qrfree (& qr); qrpng_free (& qrpng); }
int main(int argc, char *argv[]) { unsigned char x, y, v = 0, l = 1; char *c; unsigned width, height, j, k; int argp = 0; if( argc < 2 ) { printf( "Usage:\n\nqrjpeg [-v VERS_1_40] [-l ECCLVL_1_4] \"text to encode\" >output.jpg\n" ); printf( "version defaults to auto, same as \"-v 0\"\necc level defaults to 1\n" ); return 1; } c = "Test Message"; while( ++argp < argc ) { if( argv[argp][0] == '-' ) { if( argv[argp][1] == 'v' ) v = atoi( argv[++argp]); else if( argv[argp][1] == 'l' ) l = atoi( argv[++argp]); else { printf( "Usage:\n\nqrjpeg [-v VERS_1_40] [-l ECCLVL_1_4] \"text to encode\" >output.jpg\n" ); printf( "version defaults to auto, same as \"-v 0\"\necc level defaults to 1\n" ); return 1; } } else c = argv[argp]; } if( v > 40 ) { fprintf( stderr, "Bad version (size) parameter (should be 0 (auto) to 40)\n" ); return -1; } if( l < 1 || l > 4 ) { fprintf( stderr, "Bad ECC level parameter (should be 1 to 4)\n" ); return -1; } if( v ) k = initecc(l, v); else k = initeccsize( l, strlen(c)); initframe(); strcpy((char *)strinbuf, c ); qrencode(); width = height = WD+8; // set height and width in header jpeg0[0x5e] = width >> 5; jpeg0[0x5f] = width << 3; jpeg0[0x60] = width >> 5; jpeg0[0x61] = width << 3; // write out header fwrite(jpeg0, 1, sizeof(jpeg0), stdout); // put half full scale, 3e for white, 40 for black putchar(0x40); for (j = 0; j < width * 4 + 3; j++) putchar(0x80); for (y = 0; y < WD; y++) { k = 0; for (x = 0; x < WD; x++) { j = QRBIT(x, y); if (k == j) { putchar(0x80); // code for no change continue; } putchar(j ? 0 : 0x7e); // full scale flip k = j; } if (k != 0) putchar(0x7e); else putchar(0x80); for (j = 0; j < 7; j++) putchar(0x80); } for (j = 0; j < width * 4 - 4; j++) putchar(0x80); putchar(0x80); // one last for EOF putchar(0xFF); // end marker putchar(0xd9); return 0; }