baidu_34962854 2016-05-24 11:30 采纳率: 0%
浏览 1267
已结题

ndk用libpng加载图片问题,求助!

  (请高手看一下啊,采纳答案可以再提高悬赏分) 
        能够获取到图片长度以及png头。但执行到png_set_read_fn(png_ptr, &imageInfo, readFileCallback );回调里的参数length一直为8,这个长度应该是像素*高度*宽度(大概是这么个意思,可能不准确),图片总长度是6位数,所以length肯定不应该是8。请问这个length是怎么计算的?我对libpng的机制不太熟。现状是由于回调中数据源数据缺失,执行到png_read_info出错。我认为是因为length计算的不对,求帮助!

代码如下

jni

 extern "C" JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_readFromAssets(
        JNIEnv* env,jclass obj,jobject assetManager)
{
   LOGI("ReadAssets");
   AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
   if(mgr==NULL)
   {
      LOGI("AAssetManager==NULL");
      return ;
   }
   LOGI("AAssetManager111");
   string filename = "car.png";
   AAsset* asset = AAssetManager_open(mgr, filename.c_str(), AASSET_MODE_UNKNOWN);
   LOGI("AAssetManager222");
   if(asset==NULL)
   {
      LOGI(" %s","asset==NULL");
      return ;
   }
   off_t bufferSize = AAsset_getLength(asset);
    LOGI("file size         : %ld\n",bufferSize);

   char *tmpInfo = new char [bufferSize+1];
   tmpInfo[bufferSize] = 0;

   int numBytesRead = AAsset_read(asset, tmpInfo, bufferSize);

   //LOGI("tmpInfo is %s", tmpInfo);
   LOGI("AAssetManager333");

   bufferInfo = (unsigned char*)CPNGHandler::LoadFromStream(tmpInfo, (int)bufferSize);
   LOGI("AAssetManager444");
   /*获取文件大小*/
   if(NULL == bufferInfo)
   {
       LOGI("bufferInfo is NULL");
   }
  // int numBytesRead = AAsset_read(asset, bufferInfo, bufferSize);
  // LOGI("bufferInfo        : %s\n",bufferInfo+54);
   //LOGI("buffer: %s",buffer);
    /*关闭文件*/
   AAsset_close(asset);
}
/////


void CPNGHandler::readFileCallback(png_structp png_ptr, png_bytep destination, png_size_t length )
{
    LOGI("readFileCallback length is %d ", length);
    ImageInfo* info = (ImageInfo*)png_get_io_ptr(png_ptr);
    memcpy(destination, info->data, length);
}

char* CPNGHandler::LoadFromStream(char* pngDatastring, int size)
{
    LOGI("LoadFromStream111 ");
    const int PNG_SIG_BYTES = 8;
    char pngSignature[PNG_SIG_BYTES];
   // pngDataStream.read(pngSignature, PNG_SIG_BYTES); // sizeof(char)
    memcpy((unsigned char*)pngSignature, pngDatastring, PNG_SIG_BYTES);
    if(!png_check_sig( (png_bytep)pngSignature, PNG_SIG_BYTES))
    {
        return NULL;
    }

    imageInfo.data = (unsigned char*)(pngDatastring + 8);
    imageInfo.size = size;
    LOGI("LoadFromStream222 ");


    png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (png_ptr == NULL)
    {
        return NULL;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (info_ptr == NULL)
    {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        return NULL;
    }
    LOGI("LoadFromStream333 ");

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        return NULL;
    }
    LOGI("LoadFromStream333 ");

    png_set_read_fn(png_ptr, &imageInfo, readFileCallback );

    //png_set_sig_bytes( png_ptr, 8);
    LOGI("LoadFromStream345 ");
    png_read_info( png_ptr, info_ptr);

    LOGI("LoadFromStream444 ");
    int _width, _height, _depth;
    bool _hasAlpha;
    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 );
    LOGI("LoadFromStream555 ");
    switch(color_type)
    {
        case PNG_COLOR_TYPE_RGB:
            _hasAlpha = false;
            break;
        case PNG_COLOR_TYPE_RGBA:
            _hasAlpha = true;
            break;
        default:
            return NULL;
            break;
    }

    png_size_t cols = png_get_rowbytes(png_ptr, info_ptr);

    png_bytepp row_pp = new png_bytep[_height];
    char * bitmapData = new char[ cols * _height ];
    bitmapData = (char*)png_get_rows(png_ptr, info_ptr);

    for( int i = 0; i < _height; ++i )
    {
        row_pp[_height - i - 1] = (png_bytep)&((char *)bitmapData)[ 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 );
    LOGI("LoadFromStream666 ");
    delete [] row_pp;

   // GLuint _textureID = LoadFromPixels32(_width, _height, _hasAlpha, (GLuint *)bitmapData);

  //  delete [] bitmapData;
    LOGI("LoadFromStream data is%s ", bitmapData);
    return bitmapData;
    //return _textureID;
}
  • 写回答

1条回答 默认 最新

  • jian_cheng_90 2016-05-24 16:56
    关注

    问题呢?图片说明

    评论

报告相同问题?

悬赏问题

  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了
  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类