예제 #1
0
static Uint32 init_dds_image(el_file_ptr file, DdsHeader *header)
{
	Uint8 magic[4];

	el_read(file, sizeof(magic), magic);

	if (!check_dds(magic))
	{
		LOG_ERROR_OLD("File '%s' is invalid. Wrong magic number for a "
			"valid DDS.", el_file_name(file));
		return 0;
	}

	el_read(file, sizeof(DdsHeader), header);

	header->m_size = SDL_SwapLE32(header->m_size);
	header->m_flags = SDL_SwapLE32(header->m_flags);
	header->m_height = SDL_SwapLE32(header->m_height);
	header->m_width = SDL_SwapLE32(header->m_width);
	header->m_size_or_pitch = SDL_SwapLE32(header->m_size_or_pitch);
	header->m_depth = SDL_SwapLE32(header->m_depth);
	header->m_mipmap_count = SDL_SwapLE32(header->m_mipmap_count);

	header->m_reserved1[0] = SDL_SwapLE32(header->m_reserved1[0]);
	header->m_reserved1[1] = SDL_SwapLE32(header->m_reserved1[1]);
	header->m_reserved1[2] = SDL_SwapLE32(header->m_reserved1[2]);
	header->m_reserved1[3] = SDL_SwapLE32(header->m_reserved1[3]);
	header->m_reserved1[4] = SDL_SwapLE32(header->m_reserved1[4]);
	header->m_reserved1[5] = SDL_SwapLE32(header->m_reserved1[5]);
	header->m_reserved1[6] = SDL_SwapLE32(header->m_reserved1[6]);
	header->m_reserved1[7] = SDL_SwapLE32(header->m_reserved1[7]);
	header->m_reserved1[8] = SDL_SwapLE32(header->m_reserved1[8]);
	header->m_reserved1[9] = SDL_SwapLE32(header->m_reserved1[9]);
	header->m_reserved1[10] = SDL_SwapLE32(header->m_reserved1[10]);

	header->m_pixel_format.m_size = SDL_SwapLE32(header->m_pixel_format.m_size);
	header->m_pixel_format.m_flags = SDL_SwapLE32(header->m_pixel_format.m_flags);
	header->m_pixel_format.m_fourcc = SDL_SwapLE32(header->m_pixel_format.m_fourcc);
	header->m_pixel_format.m_bit_count = SDL_SwapLE32(header->m_pixel_format.m_bit_count);
	header->m_pixel_format.m_red_mask = SDL_SwapLE32(header->m_pixel_format.m_red_mask);
	header->m_pixel_format.m_green_mask = SDL_SwapLE32(header->m_pixel_format.m_green_mask);
	header->m_pixel_format.m_blue_mask = SDL_SwapLE32(header->m_pixel_format.m_blue_mask);
	header->m_pixel_format.m_alpha_mask = SDL_SwapLE32(header->m_pixel_format.m_alpha_mask);

	header->m_caps.m_caps1 = SDL_SwapLE32(header->m_caps.m_caps1);
	header->m_caps.m_caps2 = SDL_SwapLE32(header->m_caps.m_caps2);
	header->m_caps.m_caps3 = SDL_SwapLE32(header->m_caps.m_caps3);
	header->m_caps.m_caps4 = SDL_SwapLE32(header->m_caps.m_caps4);

	header->m_reserved2 = SDL_SwapLE32(header->m_reserved2);

	return validate_header(header, el_file_name(file));
}
예제 #2
0
static Uint32 get_sdl_image_information(el_file_ptr file, image_t* image)
{
	SDL_Surface *image_surface;
	SDL_RWops *buffer;

	if (file == 0)
	{
		LOG_ERROR("Invalid file!");
		return 0;
	}

	buffer = SDL_RWFromMem(el_get_pointer(file), el_get_size(file));

	image_surface = IMG_Load_RW(buffer, 1);

	if (image_surface == 0)
	{
		LOG_ERROR("load_image() error: [%s] [%s]", el_file_name(file),
			IMG_GetError());
		return 0;
	}

	SDL_LockSurface(image_surface);

	memset(image, 0, sizeof(image_t));

	image->width = image_surface->w;
	image->height = image_surface->h;
	image->mipmaps = 1;
	image->format = ift_rgba8;

	if ((image_surface->format->BitsPerPixel == 8) &&
		(image_surface->format->palette != 0))
	{
		image->alpha = 0;
	}
	else
	{
		if (image_surface->format->Amask != 0)
		{
			image->alpha = 1;
		}
		else
		{
			image->alpha = 0;
		}
	}

	SDL_UnlockSurface(image_surface);
	SDL_FreeSurface(image_surface);

	return 1;
}
예제 #3
0
static void* decompress_dds(el_file_ptr file, DdsHeader *header,
	const Uint32 strip_mipmaps, const Uint32 base_level)
{
	Uint32 width, height, size, format, mipmap_count;
	Uint32 x, y, i, w, h;
	Uint32 index;
	Uint8 *dest;

	if ((header->m_height % 4) != 0)
	{
		LOG_ERROR_OLD("Can`t decompressed DDS file %s because height is"
			" %d and not a multiple of four.", el_file_name(file),
			header->m_height);
		return 0;
	}

	if ((header->m_width % 4) != 0)
	{
		LOG_ERROR_OLD("Can`t decompressed DDS file %s because width is"
			" %d and not a multiple of four.", el_file_name(file),
			header->m_width);
		return 0;
	}

	format = header->m_pixel_format.m_fourcc;

	if ((format != DDSFMT_DXT1) && (format != DDSFMT_DXT2) &&
		(format != DDSFMT_DXT3) && (format != DDSFMT_DXT4) &&
		(format != DDSFMT_DXT5) && (format != DDSFMT_ATI1) &&
		(format != DDSFMT_ATI2))
	{
		return 0;
	}

	index = 0;

	size = get_dds_size(header, 1, strip_mipmaps, base_level);
	width = max2u(header->m_width >> base_level, 1);
	height = max2u(header->m_height >> base_level, 1);
	mipmap_count = header->m_mipmap_count;

	if (strip_mipmaps != 0)
	{
		if (mipmap_count > (base_level + 1))
		{
			mipmap_count = base_level + 1;
		}
	}

	dest = malloc_aligned(size, 16);

	el_seek(file, get_dds_offset(header, base_level), SEEK_CUR);

	for (i = base_level; i < mipmap_count; i++)
	{
		w = (width + 3) / 4;
		h = (height + 3) / 4;

		assert(index * 4 <= size);

		// 4x4 blocks in x/y
		for (y = 0; y < h; y++)
		{
			for (x = 0; x < w; x++)
			{
				decompress_block(file, format, x * 4, y * 4,
					width, height, index, dest);
			}
		}

		index += width * height;

		if (width > 1)
		{
			width /= 2;
		}

		if (height > 1)
		{
			height /= 2;
		}
	}

	assert(index * 4 == size);

	return dest;
}
예제 #4
0
Uint32 load_image_data_file(el_file_ptr file, const Uint32 compression,
	const Uint32 unpack, const Uint32 strip_mipmaps,
	const Uint32 base_level, image_t* image)
{
	char buffer[128];
	el_file_ptr alpha_file;
	Uint32 dds, result;

	if (file == 0)
	{
		LOG_ERROR("Invalid file!");

		return 0;
	}

	dds = 0;

	if (el_get_size(file) >= 4)
	{
		if (check_dds(el_get_pointer(file)))
		{
			dds = 1;
		}
	}

	if (dds == 1)
	{
		result = load_dds(file, compression, unpack,
			strip_mipmaps, base_level, image);
	}
	else
	{
		result = load_image_SDL(file, image);
	}

	if ((result == 0) || (image->image == 0))
	{
		LOG_ERROR("Can't load file '%s'!", el_file_name(file));

		el_close(file);

		return 0;
	}

	if ((dds != 1) && (check_alpha_image_name(el_file_name(file),
		sizeof(buffer), buffer) != 0))
	{
		alpha_file = el_open_custom(buffer);

		if (alpha_file == 0)
		{
			LOG_ERROR("Can't load file '%s'!", buffer);

			el_close(file);

			return 0;
		}

		load_image_SDL_alpha(alpha_file, image);

		el_close(alpha_file);
	}

	el_close(file);

	return 1;
}
예제 #5
0
static Uint32 load_image_SDL_alpha(el_file_ptr file, image_t* image)
{
	SDL_Surface *image_surface;
	GLubyte* data;
	int image_width, image_height, idx;
	int pixel, temp, r, g, b, a;
	int bpp, i, j, index, x_padding;

	if (file == 0)
	{
		LOG_ERROR("Invalid file!");

		return 0;
	}

	if (image == 0)
	{
		LOG_ERROR("Invalid image for file '%s'.", el_file_name(file));

		return 0;
	}

	if (image->format != ift_rgba8)
	{
		LOG_ERROR("Alpha map '%s' can't be used for formats other than"
			" RGBA8.", el_file_name(file));

		return 0;
	}

	image_surface = IMG_Load_RW(SDL_RWFromMem(el_get_pointer(file),
		el_get_size(file)), 1);

	if (image_surface == 0)
	{
		LOG_ERROR("load_image() error: [%s] [%s]", el_file_name(file),
			IMG_GetError());
		return 0;
	}

	// at this point, the Surface contains some type of pixel data.
	// SDL requires us to lock the surface before using the pixel data:
	SDL_LockSurface(image_surface);

	image_width = image_surface->w;
	image_height = image_surface->h;

	if (image->width != image_width)
	{
		LOG_ERROR("Alpha map '%s' had wrong width %i, expected width"
			" is %i.", el_file_name(file), image_width,
			image->width);

		return 0;
	}

	if (image->height != image_height)
	{
		LOG_ERROR("Alpha map '%s' had wrong width %i, expected width"
			" is %i.", el_file_name(file), image_height,
			image->height);

		return 0;
	}

	x_padding = image_width % 4;

	if (x_padding)
	{
		x_padding = 4 - x_padding;
	}
	if (image_width <= x_padding)
	{
		x_padding = 0;
	}

	data = image->image;
	image->alpha = 1;

	idx = 0;
	pixel = 0;
	bpp = image_surface->format->BytesPerPixel;

	for (i = 0; i < image_height; i++)
	{
		for (j = 0; j < image_width; j++)
		{
			if ((image_surface->format->BitsPerPixel == 8) &&
				(image_surface->format->palette != 0))
			{
				index = ((Uint8 *)image_surface->pixels)[idx];
				r = image_surface->format->palette->colors[index].r;
				g = image_surface->format->palette->colors[index].g;
				b = image_surface->format->palette->colors[index].b;
				a = (r + g + b) / 3;
			}
			else
			{
				memcpy(&pixel, &((Uint8 *)image_surface->pixels)[idx], bpp);

				/* Get Alpha component */
				temp = pixel & image_surface->format->Amask;  /* Isolate alpha component */
				temp = temp >> image_surface->format->Ashift; /* Shift it down to 8-bit */
				temp = temp << image_surface->format->Aloss;  /* Expand to a full 8-bit number */
				a = (Uint8)temp;
			}

			idx += bpp;

			index = (image_height - i - 1) * image_width + j;

			data[index * 4 + 3] = a;
		}
		idx += bpp * x_padding;
	}

	SDL_UnlockSurface(image_surface);
	SDL_FreeSurface(image_surface);

	return 1;
}
예제 #6
0
static Uint32 load_image_SDL(el_file_ptr file, image_t* image)
{
	SDL_Surface *image_surface;
	SDL_RWops *buffer;
	Uint8* data;
	int image_width, image_height, idx;
	int pixel, temp, r, g, b, a;
	int bpp, i, j, index, x_padding;

	if (file == 0)
	{
		LOG_ERROR("Invalid file!");

		return 0;
	}

	if (image == 0)
	{
		LOG_ERROR("Invalid image for file '%s'!", el_file_name(file));

		return 0;
	}

	buffer = SDL_RWFromMem(el_get_pointer(file), el_get_size(file));

	image_surface = IMG_Load_RW(buffer, 1);

	if (image_surface == 0)
	{
		LOG_ERROR("load_image() error: [%s] [%s]", el_file_name(file),
			IMG_GetError());
		return 0;
	}

	// at this point, the Surface contains some type of pixel data.
	// SDL requires us to lock the surface before using the pixel data:
	SDL_LockSurface(image_surface);

	image_width = image_surface->w;
	image_height = image_surface->h;

	image->width = image_width;
	image->height = image_height;
	image->mipmaps = 1;
	image->format = ift_rgba8;
	image->sizes[0] = image_width * image_height * 4;

	if ((image_surface->format->BitsPerPixel == 8) &&
		(image_surface->format->palette != 0))
	{
		image->alpha = 0;
	}
	else
	{
		if (image_surface->format->Amask != 0)
		{
			image->alpha = 1;
		}
		else
		{
			image->alpha = 0;
		}
	}

	x_padding = image_width % 4;

	if (x_padding)
	{
		x_padding = 4 - x_padding;
	}
	if (image_width <= x_padding)
	{
		x_padding = 0;
	}

	image->image = (GLubyte*)malloc_aligned(image_width * image_height * 4,
		16);
	data = image->image;

	idx = 0;
	pixel = 0;
	bpp = image_surface->format->BytesPerPixel;

	for (i = 0; i < image_height; i++)
	{
		for (j = 0; j < image_width; j++)
		{
			if ((image_surface->format->BitsPerPixel == 8) &&
				(image_surface->format->palette != 0))
			{
				index = ((Uint8 *)image_surface->pixels)[idx];
				r = image_surface->format->palette->colors[index].r;
				g = image_surface->format->palette->colors[index].g;
				b = image_surface->format->palette->colors[index].b;
				a = 255;
			}
			else
			{
				memcpy(&pixel, &((Uint8 *)image_surface->pixels)[idx], bpp);
				/* Get Red component */
				temp = pixel & image_surface->format->Rmask;  /* Isolate red component */
				temp = temp >> image_surface->format->Rshift; /* Shift it down to 8-bit */
				temp = temp << image_surface->format->Rloss;  /* Expand to a full 8-bit number */
				r = (Uint8)temp;

				/* Get Green component */
				temp = pixel & image_surface->format->Gmask;  /* Isolate green component */
				temp = temp >> image_surface->format->Gshift; /* Shift it down to 8-bit */
				temp = temp << image_surface->format->Gloss;  /* Expand to a full 8-bit number */
				g = (Uint8)temp;

				/* Get Blue component */
				temp = pixel & image_surface->format->Bmask;  /* Isolate blue component */
				temp = temp >> image_surface->format->Bshift; /* Shift it down to 8-bit */
				temp = temp << image_surface->format->Bloss;  /* Expand to a full 8-bit number */
				b = (Uint8)temp;

				/* Get Alpha component */
				temp = pixel & image_surface->format->Amask;  /* Isolate alpha component */
				temp = temp >> image_surface->format->Ashift; /* Shift it down to 8-bit */
				temp = temp << image_surface->format->Aloss;  /* Expand to a full 8-bit number */
				a = (Uint8)temp;

				if (image_surface->format->Amask == 0)
				{
					a = 255;
				}
			}
			idx += bpp;

			index = i * image_width + j;
			data[index * 4 + 0] = r;
			data[index * 4 + 1] = g;
			data[index * 4 + 2] = b;
			data[index * 4 + 3] = a;
		}
		idx += bpp * x_padding;
	}

	SDL_UnlockSurface(image_surface);
	SDL_FreeSurface(image_surface);

	return 1;
}