Exemplo n.º 1
0
Arquivo: zip.c Projeto: ccxvii/mio
static unsigned char *read_zip_file(FILE *file, int offset, int *sizep)
{
	int sig, method, csize, usize;
	int namelength, extralength;
	char *cdata, *udata;

	fseek(file, offset, 0);

	sig = getlong(file);
	if (sig != ZIP_LOCAL_FILE_SIG) {
		warn("zip: wrong signature for local file");
		return NULL;
	}

	(void) getshort(file); /* version */
	(void) getshort(file); /* general */
	method = getshort(file);
	(void) getshort(file); /* file time */
	(void) getshort(file); /* file date */
	(void) getlong(file); /* crc-32 */
	csize = getlong(file); /* csize */
	usize = getlong(file); /* usize */
	namelength = getshort(file);
	extralength = getshort(file);

	fseek(file, namelength + extralength, 1);

	if (method == 0 && csize == usize) {
		cdata = malloc(csize);
		fread(cdata, 1, csize, file);
		*sizep = csize;
		return (unsigned char*) cdata;
	}

	if (method == 8) {
		cdata = malloc(csize);
		fread(cdata, 1, csize, file);
		udata = malloc(usize);
		usize = stbi_zlib_decode_noheader_buffer(udata, usize, cdata, csize);
		free(cdata);
		if (usize < 0) {
			warn("zip: %s", stbi_failure_reason());
			return NULL;
		}
		*sizep = usize;
		return (unsigned char*) udata;
	}

	warn("zip: unknown compression method");
	return NULL;
}
Exemplo n.º 2
0
OOBase::SharedPtr<const char> Indigo::detail::ZipFile::load(const OOBase::String& prefix, const char* name)
{
	OOBase::SharedPtr<const char> ret;
	OOBase::String filename(prefix);
	if (!filename.append(name))
		LOG_ERROR_RETURN(("Failed to append string: %s",OOBase::system_error_text()),ret);

	OOBase::Table<OOBase::String,Info>::iterator i=m_mapFiles.find(filename);
	if (!i)
		return ret;

	// Read the local file header
	if (m_file.seek(i->second.m_offset,OOBase::File::seek_begin) == OOBase::uint64_t(-1))
		LOG_ERROR_RETURN(("Failed to get seek in file: %s",OOBase::system_error_text()),ret);

	OOBase::uint8_t header[30];
	if (m_file.read(header,30) != 30)
		LOG_ERROR_RETURN(("Failed to read local file header header in zip"),ret);

	static const OOBase::uint8_t LFR_HEADER[4] = { 0x50, 0x4b, 0x03, 0x04 };
	if (memcmp(header,LFR_HEADER,4) != 0)
		LOG_ERROR_RETURN(("Invalid local file header header in zip"),ret);

	OOBase::uint16_t compression = read_uint16(header,8);
	OOBase::uint32_t compressed_size = read_uint32(header,18);
	size_t offset = 30 + read_uint16(header,26) + read_uint16(header,28);

	OOBase::SharedPtr<const char> mapping = m_file.auto_map<const char>(false,i->second.m_offset + offset,compressed_size);
	if (!mapping)
		LOG_ERROR_RETURN(("Failed to map file content: %s",OOBase::system_error_text()),ret);

	if (compression == 0)
	{
		ret = mapping;
	}
	else if (compression == 8)
	{
		void* p = OOBase::CrtAllocator::allocate(i->second.m_length,1);
		if (!p)
			LOG_ERROR_RETURN(("Failed to allocate: %s",OOBase::system_error_text()),ret);

		if (stbi_zlib_decode_noheader_buffer(static_cast<char*>(p),(int)i->second.m_length,mapping.get(),(int)compressed_size) == -1)
		{
			LOG_ERROR(("Failed to inflate file: %s",stbi_failure_reason()));
			OOBase::CrtAllocator::free(p);
		}
		else
		{
			ret = OOBase::const_pointer_cast<const char>(OOBase::make_shared<char>(static_cast<char*>(p)));
			if (!ret)
			{
				LOG_ERROR(("Failed to allocate: %s",OOBase::system_error_text()));
				OOBase::CrtAllocator::free(p);
			}
		}
	}
	else
		LOG_ERROR(("Unsupported zip compression method: %u",compression));

	return ret;
}