PHP Extension Development Notes (10) customizing IO functions in the libpng library to write images to memory

Source: Internet
Author: User
In the development of this generation of QR code extension dcode, the resulting QR code PNG image will be returned to the caller as a string, rather than directly generated files, it is convenient to do not have to manipulate the file, the operation of the file is completely handed over to the user.

Generate pictures using the Libpng library, about libpng documents you can see here in PNG document. I used this library to compile my extensions on Ubuntu14.04 with a small problem png_create_write_struct in Unknown on line 0 on Ubuntu 14, a search on the web is still very common.

Here's a simple list of the code:

/** {{{ dcode_png_writer() * function is custom png_write callback function * Return void */staticvoid dcode_png_writer(png_structp png_ptr, png_bytep data, png_size_t length){    png_mem_encode* p = (png_mem_encode*) png_get_io_ptr(png_ptr);    size_t nsize = p->size + length;    if (p->buffer)        p->buffer = erealloc(p->buffer, nsize);    else        p->buffer = emalloc(nsize);    if (!p->buffer)    {        "PNG allocate memory error");        exit(FAILURE);    }    memcpy(p->buffer + p->size, data, length);    p->size += length;}/* }}} */
/** {{dcode_write_to_png () * Write qrcode struct to memory * Return char* */StaticChar* Dcode_write_to_png (QRCode *qrcode,intSizeintMarginint*pp_len) {PNG_STRUCTP png_ptr; Png_infop info_ptr;unsignedChar*row, *p, *q;intX, y, xx, yy, bit;intRealwidth; Realwidth = (qrcode->width + margin *2) * SIZE;intRow_fill_len = (Realwidth +7) /8; Png_ptr = png_create_write_struct (png_libpng_ver_string, NULL, NULL, NULL);if(png_ptr = = NULL) {Php_error (E_error,"Failed to initialize PNG writer");returnNULL; } info_ptr = Png_create_info_struct (png_ptr);if(info_ptr = = NULL) {Php_error (E_error,"Failed to initialize PNG info");returnNULL; }if(SETJMP (Png_jmpbuf (png_ptr)))        {png_destroy_write_struct (&png_ptr, &info_ptr); Php_error (E_error,"Failed to set PNG jmpbuf");returnNULL; } row = (unsignedChar*) Emalloc (Row_fill_len);if(row = = NULL)        {png_destroy_write_struct (&png_ptr, &info_ptr); Php_error (E_error,"Failed to allocate Memory");returnNULL; } Png_mem_encode state = {NULL,0};    PNG_SET_WRITE_FN (Png_ptr, &state, &dcode_png_writer, NULL); PNG_SET_IHDR (Png_ptr, Info_ptr, Realwidth, Realwidth,1, Png_color_type_gray, Png_interlace_none, Png_compression_type_default,    Png_filter_type_default); Png_write_info (Png_ptr, info_ptr);memset(Row,0xFF, (Realwidth +7) /8); for(y =0; Y < margin * size;    Y + +) {Png_write_row (png_ptr, Row); } p = qrcode->data; for(y =0; Y < qrcode->width; Y + +) {bit =7;memset(Row,0xFF, (Realwidth +7) /8);        Q = row; Q + = margin * Size/8; bit =7-(Margin * size%8); for(x =0; X < qrcode->width; X + +) { for(xx =0; Xx
  
   
     1) << bit;                
 bit--; 
     if  (Bit < 
     0 )                    {q++;                bit = 
     7 ;        }} p++;        
     for  (yy = 
     0 ; yy < size; yy + +) {Png_write_row (png_ptr, Row);    
 }} 
     memset  (row, 
     0xff , (realwidth + 
     7 )/
     8 ); 
     for  (y = 
     0 ; y < margin * size; y + +)    {Png_write_row (png_ptr, Row);    } png_write_end (Png_ptr, info_ptr);    Png_destroy_write_struct (&png_ptr, &info_ptr);    
 Efree (row);    
 
     char  *bin_data = NULL; 
     if         (state.buffer) {bin_data = Estrndup (State.buffer, state.size);        *pp_len = state.size;    Efree (State.buffer);
 } 
     return  bin_data;} 
    /**}}} */

   
  
    1. The first function dcode_png_writer is a custom callback function that writes the PNG data.
    2. The second function dcode_write_to_png is to write qrcode data to a PNG

The main part is to look at this.

png_set_write_fn(png_ptr, &state, &dcode_png_writer, NULL);

This is where the custom write function is called dcode_png_writer and the data is written to the state struct, state as follows

typedefstruct _png_mem_encode {    char *buffer;    size_t size;} png_mem_encode ;

png_set_write_fnThe function sets the custom write function to dcode_png_writer allocate memory dynamically by writing data like state.

On png_set_write_fn the definition, you can refer to the PNG document mentioned above, custom functions can also customize error handling functions, so that you can take over the actual situation rather error handler than let it exit inside. For more relevant code see DCode Extension

The speed of generating qrcode is very fast, if used for ($i = 0; $i < 10000; $i ++) $i as a parameter, 3 seconds can generate 10,000.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

The above describes the PHP extension development Note (10) to customize the IO function in the libpng library, write the picture to memory, including the content of the aspects, I hope that the PHP tutorial interested in a friend helpful.

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.