(请高手看一下啊,采纳答案可以再提高悬赏分)
能够获取到图片长度以及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;
}