예제 #1
0
파일: PFPFile.cpp 프로젝트: pfedick/pplib
/*!\brief Prüfen, ob es sich um ein PFP-File handelt
 *
 * \desc
 * Diese Funktion prüft, ob es sich bei der geöffneten Datei \p ff um eine Datei
 * im \ref PFPFileVersion3 PFP-Format Version 3 handelt. Ist dies der Fall, wird deren
 * ID und Version eingelesen.
 *
 * @param ff Referenz auf eine geöffnete Datei
 * @return Gibt \c true zurück, wenn es sich um eine Datei im PFP-Format handelt. Deren
 * ID kann anschließend mit PFPFile::getID ausgelesen werden, Version mit PFPFile::getVersion bzw.
 * PFPFile::getMainVersion und PFPFile::getSubVersion. Handelt es sich nicht um eine Datei
 * im PFP-Format, gibt die Funktion \c false zurück. Es wird keine Exception geworfen.
 */
bool PFPFile::ident(FileObject &ff)
{
	try {
		const char *p;
		p=ff.map(0,24);
		if (strncmp(p,"PFP-File",8)!=0) return false;
		if (Peek8(p+8)!=3) return false;
		id.set(p+10,4);
		mainversion=Peek8(p+15);
		subversion=Peek8(p+14);
		comp=(Compression::Algorithm)Peek8(p+16);
		return true;
	} catch (...) {
		return false;
	}
	return false;
}
예제 #2
0
int ImageFilter_PNG::ident(FileObject &file, IMAGE &img)
{
#ifdef HAVE_PNG
	try {
		const char *address=file.map(0,256);
		file.seek(0);
		if (address==NULL) return 0;

		if (png_sig_cmp((png_byte*)address, 0, 8)!=0) { // Ist es ein PNG-File?
			return 0;
		}
		png_structp png_ptr = png_create_read_struct
				(PNG_LIBPNG_VER_STRING, NULL ,NULL, NULL);
		if (!png_ptr) return 0;

		png_infop info_ptr = png_create_info_struct(png_ptr);
		if (!info_ptr) {
			png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
			return 0;
		}
		png_infop end_info = png_create_info_struct(png_ptr);
		if (!end_info) {
			png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
			return 0;
		}
		png_set_read_fn(png_ptr,&file, (png_rw_ptr) user_read_data);
		//png_set_write_fn(png_structp write_ptr, voidp write_io_ptr, png_rw_ptr write_data_fn,
		//    png_flush_ptr output_flush_fn);
		png_read_info(png_ptr, info_ptr);
		img.width=png_get_image_width(png_ptr, info_ptr);
		img.height=png_get_image_height(png_ptr, info_ptr);
		img.bitdepth=png_get_bit_depth(png_ptr, info_ptr);
		img.colors=0;
		img.pitch=png_get_rowbytes(png_ptr, info_ptr);
		//img->pfp.header_version=0;
		bool supported=true;
		img.format=RGBFormat::unknown;
		if (img.bitdepth!=8) supported=false;		// Nur 8-Bit/Farbwert wird unterstützt

		switch (png_get_color_type(png_ptr, info_ptr)) {
			case PNG_COLOR_TYPE_GRAY:
				img.bitdepth=8;
				img.colors=256;
				img.format=RGBFormat::GREY8;
				break;
			case PNG_COLOR_TYPE_PALETTE:
				img.bitdepth=8;
				img.colors=256;
				img.format=RGBFormat::Palette;
				//supported=false;
				break;
			case PNG_COLOR_TYPE_RGB:
				img.colors=0xffffff;
				img.bitdepth=24;
				img.format=RGBFormat::X8R8G8B8;
				break;
			case PNG_COLOR_TYPE_RGB_ALPHA:
				img.colors=0xffffff;
				img.bitdepth=32;
				img.format=RGBFormat::A8R8G8B8;
				break;
			case PNG_COLOR_TYPE_GRAY_ALPHA:
				img.colors=256;
				img.bitdepth=32;
				img.format=RGBFormat::GREYALPHA32;
				break;
		};

		if (png_get_interlace_type(png_ptr,info_ptr)!=PNG_INTERLACE_NONE) {	// Interlaced wird nicht unterstützt
			supported=false;
		}

		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
		if (!supported) {
			return 0;
		}
		return 1;
	} catch (...) {
		return 0;
	}
	return 0;
#else
	return 0;
#endif
}
예제 #3
0
파일: PFPFile.cpp 프로젝트: pfedick/pplib
void PFPFile::load(FileObject &ff)
/*!\brief PFP-File laden
 *
 * Mit dieser Funktion wird ein PFP-File in die Klasse geladen. Dabei wird zuerst der Header geladen
 * und überprüft, ob es sich um ein gültiges PFP-File handelt. Dann wird die virtuelle Funktion
 * PFPFile::LoadRequest mit ID, Haupt- und Unterversion als Parameter aufgerufen. Liefert diese
 * nicht true (1) zurück, wird der Ladevorgang abgebrochen. Andernfalls wird fortgeführt
 * und geprüft, ob der
 * Datenbereich komprimiert ist und gegebenenfalls dekomprimiert. Erst danach werden die
 * einzelnen Chunks eingelesen. Kommt es dabei zu Fehlern durch ungültige Chunks, werden diese
 * ignoriert und die Funktion gibt den Fehlercode 434 zurück.
 *
 * \param ff Pointer auf eine CFile-Klasse, mit der die einzulesende Datei geöffnet wurde.
 * \returns Konnte die Datei fehlerfrei eingelesen werden, gibt die Funktion true (1) zurück,
 * im Fehlerfall false (0). Ein entsprechender Fehlercode wird gesetzt.
 *
 * \remarks
 * Vor dem Laden der Datei wird die Funktion PFPFile::Clear aufgerufen, so dass eventuell vorher
 * vorhandene Daten verloren gehen.
 *
 * \since Version 6.1.0
 */
{
	const char *p;
	try {
		p=ff.map(0,24);
	} catch (OverflowException &) {
		throw InvalidFormatException();
	}
	if (strncmp(p,"PFP-File",8)!=0) throw InvalidFormatException();
	if (Peek8(p+8)!=3) throw InvalidFormatException();
	size_t z,fsize;
	// Wir haben ein gültiges PFP-File, aber dürfen wir es auch laden?
	char tmpid[5];
	tmpid[4]=0;
	strncpy(tmpid,p+10,4);
	int t1,t2;
	t1=Peek8(p+15);
	t2=Peek8(p+14);
	if (!loadRequest(tmpid,t1,t2)) {
		throw AccessDeniedByInstanceException();
	}
	clear();
	id.set(p+10,4);
	mainversion=Peek8(p+15);
	subversion=Peek8(p+14);
	comp=(Compression::Algorithm)Peek8(p+16);
	size_t hsize=Peek8(p+9);
	char *u=NULL;
	if (comp) {
		p=(char*)ff.map(hsize,8);
		if (!p) throw ReadException();
		size_t sizeunk=Peek32(p);
		size_t sizecomp=Peek32(p+4);
		p=ff.map(hsize+8,sizecomp);
		if (!p) throw ReadException();
		u=(char*)malloc(sizeunk+1);
		if (!u) throw OutOfMemoryException();
		size_t dstlen=sizeunk;
		Compression c;
		try {
			c.init(comp);
			c.uncompress(u,&dstlen,p,sizecomp);
		} catch (...) {
			free(u);
			clear();
			throw;
		}
		if (dstlen!=sizeunk) {
			free(u);
			clear();
			throw DecompressionFailedException();
		}
		u[dstlen]=0;
		p=u;
		fsize=dstlen;
	} else {
		p=ff.map();
		p+=hsize;
		fsize=ff.size()-hsize;
	}
	// Wir haben nun den ersten Chunk ab Pointer p
	z=0;
	String Chunkname;
	try {
		size_t size=0;
		while ((z+=size)<fsize) {
			size=Peek32(p+z+4);
			if (strncmp(p+z,"ENDF",4)==0) break;
			if (!size) break;
			// Falls z+size über das Ende der Datei geht, stimmt mit diesem Chunk was nicht
			if (z+size>fsize) break;
			PFPChunk *chunk=new PFPChunk;
			if (!chunk) throw OutOfMemoryException();
			Chunkname.set(p+z,4);
			chunk->setName(Chunkname);
			chunk->setData(p+z+8,size-8);
			addChunk(chunk);
		}
	} catch (...) {
		if (u) free(u);
		clear();
		throw;
	}
	if (u) free(u);
}