Android native libpng problems

Started by
9 comments, last by polyfrag 11 years ago

I load a png okay, then it complains on this line:


  int is_png = !png_sig_cmp(header, 0, 8);
  if (!is_png) 
  {
    LOGE("Not a png file : %s", strFileName);
    return NULL;
  }

And the next one causes a crash.

03-27 17:34:01.060: A/libc(21835): @@@ ABORTING: LIBC: ARGUMENT IS INVALID HEAP ADDRESS IN dlfree addr=0x5b050000

03-27 17:34:01.060: A/libc(21835): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 21849 (engame.pathogen)

Any ideas why?

Advertisement

Which of all those lines? If it's the first, check that header points to valid memory. If it's the fourth, check strFileName instead. Also in the case of header make sure it's long enough (should be 8 bytes).

Sounds dumb but you may have overlooked something.

Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.
I mean I load one png file okay (it seems, I haven't tried viewing it) but then for the second one png_sig_cmp returns non-zero. And yeah it is 8 png_byte's.

The second one is now complaining about setjmp:

03-27 22:01:01.320: E/NDK_MainActivity(23871): Error during setjmp : fonts/msgothic16b.png


  if (setjmp(png_jmpbuf(png_ptr))) 
  {
    LOGE("Error during setjmp : %s", strFileName);
    png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
    return NULL;
  }

I changed the order of the first two files and still got the same result. I saved msgothic16b.png in MS Paint, which got rid of the transparency. It was the first one loading and it loaded fine, but now it was complaining about the header in what was the first file. So changing the data of one file somehow messed up the data of the second. It's either the way I'm reading the file into memory, how it's stored in the APK, or something wrong with the asset manager.

I now switched the first and second one to their original order and it still has an invalid header but it changed. And it's crashing on the second one instead of loading it.

The shader text files are loading fine. They're small. The font text files only load up to 979-980 characters...

If I got the asset manager this way


	g_amgr = state->activity->assetManager;

then it shouldn't change during the course of the program?

Here's how I load files into memory from the APK:


CFile::CFile(const char* filepath)
{
	data = NULL;
	fsize = 0;
	position = 0;

	//zip_file* file = zip_fopen(APKArchive, filepath, 0);
	AAsset* asset_file = AAssetManager_open(g_amgr, filepath, AASSET_MODE_UNKNOWN); 

	//if(!file)
	if(!asset_file)
		return;

	unsigned char buff[256];
	unsigned char* oldbuf = NULL;
	unsigned char* newbuf = NULL;

	int r=0;
	//while((r=zip_fread(file, buff, 256)) > 0)
	while((r = AAsset_read(asset_file, buff, 256)) > 0)
	{
		newbuf = new unsigned char[fsize+r];

		if(oldbuf)
		{
			memcpy(newbuf, oldbuf, fsize);
		}

		memcpy(&newbuf[fsize], buff, r);

		delete [] oldbuf;
		oldbuf = newbuf;

		fsize += r;
	}

	data = newbuf;

	//zip_fclose(file);
	AAsset_close(asset_file);
}

void CFile::seek(int off)
{
	position = off;
}

int CFile::read(void* to, int amt)
{
	int read = amt;

	if(read > fsize-position)
		read = fsize-position;

	memcpy(to, &data[position], read);
	position += read;

	return read;
}

class CFile
{
public:
	unsigned char* data;
	int fsize;
	int position;

	CFile();
	CFile(const char* filepath);
	~CFile();
	void seek(int off);
	void seekend();
	int read(void* to, int amt);
	int tell();
	void close();
};

Is there anything wrong with this?

There's a problem in here somewhere because it does show all chunks (I checked) of the file but at the end it shows only part of it.

Somewhere in the data copying... file size is alright.


	data = NULL;
	fsize = 0;
	position = 0;

	//zip_file* file = zip_fopen(APKArchive, filepath, 0);
	AAsset* asset_file = AAssetManager_open(g_amgr, filepath, AASSET_MODE_UNKNOWN); 

	//if(!file)
	if(!asset_file)
		return;

	unsigned char buff[257];
	unsigned char* oldbuf = NULL;
	unsigned char* newbuf = NULL;

	int r=0;
	//while((r=zip_fread(file, buff, 256)) > 0)
	while((r = AAsset_read(asset_file, buff, 256)) > 0)
	{
		newbuf = new unsigned char[fsize+r];

		//buff[r] = '\0';
		//LOGI("%s", buff);

		LOG("read %d", r);

		//if(oldbuf)
		if(fsize > 0)
		{
			memcpy(newbuf, oldbuf, fsize);
		}

		memcpy(&newbuf[fsize], buff, r);

		//if(oldbuf)
		if(fsize > 0)
		{
			delete [] oldbuf;
		}
		oldbuf = newbuf;

		fsize += r;
	}

	//LOGI("%s size=%d", filepath, fsize);
	data = newbuf;

	//char show[fsize];
	//memcpy(show, data, fsize);
	//LOGI("%s", show);

I'm using AAsset_getLength, AAsset_seek and AAsset_getRemainingLength to read the whole file directly.

http://minigamestudio.googlecode.com/svn-history/r407/trunk/source/render/android/ola_afile.cpp

It was only showing ~1000 characters because that was the logcat limit.

PNG now says:

03-28 00:53:21.293: A/libc(26952): Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 26967 (engame.pathogen)

This topic is closed to new replies.

Advertisement