Cpper
C/C++高级工程师 Android高级软件工程师 IT集成工程师 音频工程师 熟悉c,c++,java,c#,py,js,asp等多种语言 程序猿
libpng比较另类,解码方式比较奇特,这里记录下
以下代码为使用虚拟IOReader的方式,稍做修改就基于FILE使用
代码很详细,不需额外解释
PNGImage::PNGImage(const std::string& filename):
    ReferenceCountedImage(filename),
    data_(
0)
{
    IOReader
* reader = FileSystem::instance()->readFile(filename);
    
if(reader == 0)
        
return;

    png_structp png_ptr 
= png_create_read_struct(PNG_LIBPNG_VER_STRING, 000);
    
if(png_ptr == 0)
    {
        reader
->close();
        reader
->deleteLater();
    }

    png_infop info_ptr 
= png_create_info_struct(png_ptr);
    
if(info_ptr == 0)
    {
        png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
        reader
->close();
        reader
->deleteLater();
    }

    
if(setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(
&png_ptr,png_infopp(0),png_infopp(0));
        reader
->close();
        reader
->deleteLater();
    }

    png_set_read_fn( png_ptr,reader,(png_rw_ptr)user_read_data);

    png_set_sig_bytes(png_ptr,
0);

    png_read_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,
0);
    
const unsigned int width = png_get_image_width(png_ptr,info_ptr);
    
const unsigned int height = png_get_image_height(png_ptr,info_ptr);
    
const unsigned int bit_depth = png_get_bit_depth(png_ptr,info_ptr);
    
if(bit_depth != 8)
    {
        reader
->close();
        reader
->deleteLater();
        png_destroy_info_struct(png_ptr,png_infopp(
&info_ptr));
        png_destroy_read_struct(
&png_ptr,png_infopp(0), png_infopp(0));
    }

    
const png_byte colorType = png_get_color_type(png_ptr, info_ptr);
    
if((colorType != PNG_COLOR_TYPE_RGB) && (colorType != PNG_COLOR_TYPE_RGB_ALPHA))
    {
        reader
->close();
        reader
->deleteLater();
        png_destroy_info_struct(png_ptr, png_infopp(
&info_ptr));
        png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
    }

    
const int bytesPerPixel = (colorType == PNG_COLOR_TYPE_RGB) ? 3 : 4;
    
const int stride = bytesPerPixel * width;

    unsigned 
char* data = new unsigned char[stride * height];
    png_bytep
* row_pointers = png_get_rows(png_ptr, info_ptr);
    
for(unsigned int i = 0; i < height; ++i)
    {
        
const unsigned int row = height - i - 1;
        memcpy(data 
+ (row * stride), row_pointers[i], stride);
    }

    size_.x_ 
= width;
    size_.y_ 
= height;
    numberOfBitsPerPixel_ 
= bytesPerPixel * 8;
    data_ 
= data;

    reader
->close();
    reader
->deleteLater();
    png_destroy_info_struct(png_ptr, png_infopp(
&info_ptr));
    png_destroy_read_struct(
&png_ptr, png_infopp(0), png_infopp(0));
}
posted on 2015-12-29 11:12 ccsdu2009 阅读(1989) 评论(0)  编辑 收藏 引用 所属分类: Game引擎编程基础

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理