int Graph_FillAlpha( LCUI_Graph *graph, uchar_t alpha ) { int x, y; LCUI_Rect rect; LCUI_ARGB *pixel, *pixel_row; Graph_GetValidRect( graph, &rect ); graph = Graph_GetQuote( graph ); if( !Graph_IsValid(graph) ) { return -1; } if( !Graph_HasAlpha(graph) ) { return -2; } pixel_row = graph->argb + rect.y*graph->w + rect.x; for(y=0; y<rect.h; ++y) { pixel = pixel_row; for( x=0; x<rect.w; ++x ) { pixel->alpha = alpha; ++pixel; } pixel_row += graph->w; } return 0; }
int Graph_WritePNG( const char *file_name, const LCUI_Graph *graph ) { #ifdef USE_LIBPNG FILE *fp; LCUI_Rect rect; png_byte color_type; png_structp png_ptr; png_infop info_ptr; png_bytep *row_pointers; int x, y, row_size; if( !Graph_IsValid( graph ) ) { _DEBUG_MSG( "graph is not valid\n" ); return -1; } /* create file */ fp = fopen( file_name, "wb" ); if( !fp ) { _DEBUG_MSG( "file %s could not be opened for writing\n", file_name ); return -1; } /* initialize stuff */ png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if( !png_ptr ) { fclose( fp ); _DEBUG_MSG( "png_create_write_struct failed\n" ); return -1; } info_ptr = png_create_info_struct( png_ptr ); if( !info_ptr ) { fclose( fp ); _DEBUG_MSG( "png_create_info_struct failed\n" ); png_destroy_write_struct( &png_ptr, &info_ptr ); return -1; } if( setjmp( png_jmpbuf( png_ptr ) ) ) { fclose( fp ); _DEBUG_MSG( "error during init_io\n" ); png_destroy_write_struct( &png_ptr, &info_ptr ); return -1; } png_init_io( png_ptr, fp ); if( Graph_HasAlpha( graph ) ) { color_type = PNG_COLOR_TYPE_RGB_ALPHA; } else { color_type = PNG_COLOR_TYPE_RGB; } /* write header */ png_set_IHDR( png_ptr, info_ptr, graph->w, graph->h, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE ); png_write_info( png_ptr, info_ptr ); /* write bytes */ Graph_GetValidRect( graph, &rect ); graph = Graph_GetQuote( graph ); if( graph->color_type == COLOR_TYPE_ARGB ) { LCUI_ARGB *px_ptr, *px_row_ptr; row_size = png_get_rowbytes( png_ptr, info_ptr ); px_row_ptr = graph->argb + rect.top * graph->width + rect.left; row_pointers = (png_bytep*)malloc( rect.height*sizeof( png_bytep ) ); for( y = 0; y < rect.height; ++y ) { row_pointers[y] = png_malloc( png_ptr, row_size ); px_ptr = px_row_ptr; for( x = 0; x < row_size; ++px_ptr ) { row_pointers[y][x++] = px_ptr->red; row_pointers[y][x++] = px_ptr->green; row_pointers[y][x++] = px_ptr->blue; row_pointers[y][x++] = px_ptr->alpha; } px_row_ptr += graph->w; } } else { uchar_t *px_ptr, *px_row_ptr; row_size = png_get_rowbytes( png_ptr, info_ptr ); px_row_ptr = graph->bytes + rect.top * graph->bytes_per_row; px_row_ptr += rect.left * graph->bytes_per_pixel; row_pointers = (png_bytep*)malloc( rect.height*sizeof( png_bytep ) ); for( y = 0; y < rect.height; ++y ) { row_pointers[y] = (png_bytep)malloc( row_size ); px_ptr = px_row_ptr; for( x = 0; x < row_size; x += 3 ) { row_pointers[y][x + 2] = *px_ptr++; // blue row_pointers[y][x + 1] = *px_ptr++; // green row_pointers[y][x] = *px_ptr++; // red } px_row_ptr += graph->bytes_per_row; } } png_write_image( png_ptr, row_pointers ); /* cleanup heap allocation */ for( y = 0; y < rect.height; ++y ) { free( row_pointers[y] ); } free( row_pointers ); /* end write */ png_write_end( png_ptr, NULL ); png_destroy_write_struct( &png_ptr, &info_ptr ); fclose( fp ); return 0; #else printf( "warning: not PNG support!" ); return 0; #endif }