native opengl

github:hrydgard/native

https://github.com/hrydgard/native

http://www.henrikrydgard.com/


native、png、opengl (libPng)

#ifndef OPENGL_IMAGE_PARSEPNGFILE_H
#define OPENGL_IMAGE_PARSEPNGFILE_H

#include "common.h"
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>

class ParsePngFile{

public:
    ParsePngFile(AAssetManager *assetManager,const char *filePath);
    bool parse();

    void glPngTexImage2D(int target, int level);
    int getWidth();
    int getHeight();
    bool hasAlpha();

    ~ParsePngFile();

private:
    char * pngData;
    bool _hasAlpha;
    int _width, _height;
    std::string pngDataString;

};

#endif //OPENGL_IMAGE_PARSEPNGFILE_H

#include "ParsePngFile.h"

#include <GLES2/gl2.h>
#include <png.h>

#include <istream>
#include <fstream>
#include <sstream>
#include <vector>

ParsePngFile::ParsePngFile(AAssetManager *assetManager,const char *filePath) {
    std::vector<char> buffer;
    AAsset * asset = AAssetManager_open(assetManager,filePath, AASSET_MODE_UNKNOWN);
    if (asset) {
        int size = AAsset_getLength(asset);
        buffer.resize(size);
        AAsset_read(asset, &buffer[0], size);

        AAsset_close(asset);

        for (int i = 0; i < buffer.size(); i++) {
            pngDataString += buffer[i];
        }

        std::vector<char>().swap(buffer);
    }


}

void readFileCallback(png_structp png_ptr, png_bytep destination, png_size_t bytesToRead)
{
    png_voidp io_ptr = png_get_io_ptr( png_ptr );

    if( io_ptr == 0 )
    {
        return;
    }

    png_voidp a = png_get_io_ptr(png_ptr);
    //Cast the pointer to std::istream* and read 'bytesToRead' bytes into 'destination'
    ((std::istream*)a)->read((char*)destination, bytesToRead);
}

bool ParsePngFile::parse() {

    std::istringstream pngDataStream(pngDataString);

    const int PNG_SIG_BYTES = 8;
    char pngSignature[PNG_SIG_BYTES];
    pngDataStream.read(pngSignature, PNG_SIG_BYTES * sizeof(char));

    if(!png_check_sig( (png_bytep)pngSignature, PNG_SIG_BYTES) )
    {
        return false;
    }

    /**
     * Create and initialize the png_struct
     * with the desired error handler
     * functions.  If you want to use the
     * default stderr and longjump method,
     * you can supply NULL for the last
     * three parameters.  We also supply the
     * the compiler header file version, so
     * that we know if the application
     * was compiled with a compatible version
     * of the library.  REQUIRED
     */
    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL)
    {
        return false;
    }

    /**
     * Allocate/initialize the memory
     * for image information.  REQUIRED. */
    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return false;
    }

    /**
     * Set error handling if you are
     * using the setjmp/longjmp method
     * (this is the normal method of
     * doing things with libpng).
     * REQUIRED unless you  set up
     * your own error handlers in
     * the png_create_read_struct()
     * earlier.
     */
    if (setjmp(png_jmpbuf(png_ptr))) {
        /* Free all of the memory associated
         * with the png_ptr and info_ptr */
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return false;
    }


    /**
     * Set custom input stream READER / handler
     */
    png_set_read_fn( png_ptr, (void*)&pngDataStream, readFileCallback );

    /* If we have already
     * read some of the signature */
    png_set_sig_bytes( png_ptr, 8 );

    png_read_info( png_ptr, info_ptr);

    int  _depth;
    int color_type, interlace_type;

    png_get_IHDR( png_ptr, info_ptr, (png_uint_32*)&_width, (png_uint_32*)&_height, &_depth, &color_type, &interlace_type, NULL, NULL );

    switch(color_type)
    {
        case PNG_COLOR_TYPE_RGB:
            _hasAlpha = false;
            break;
        case PNG_COLOR_TYPE_RGBA:
            _hasAlpha = true;
            break;
        default:
            return false;
    }

    png_size_t cols = png_get_rowbytes(png_ptr, info_ptr);

    png_bytepp row_pp = new png_bytep[_height];
    pngData= new char[ cols * _height ];

    for( int i = 0; i < _height; ++i )
    {
        // note that png is ordered top to
        // bottom, but OpenGL expect it bottom to top
        // so the order or swapped
        row_pp[i] = (png_bytep)&((char *)pngData)[ i * cols ];
    }

    png_read_image( png_ptr, row_pp );
    png_read_end( png_ptr, info_ptr );

    png_destroy_read_struct( &png_ptr, &info_ptr, 0 );

    delete [] row_pp;

    return true;

}


void ParsePngFile::glPngTexImage2D(int target, int level) {

   if(pngData != NULL){
       glTexImage2D(target, level, _hasAlpha ? GL_RGBA : GL_RGB, _width, _height, 0, _hasAlpha ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, pngData);
   }

}
int ParsePngFile::getWidth() { return _width; }

int ParsePngFile::getHeight() { return _height; }

bool ParsePngFile::hasAlpha() { return _hasAlpha; }

ParsePngFile::~ParsePngFile() {
    if(pngData != NULL){
        delete [] pngData;
        pngData = NULL;
    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值