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)); }
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; }
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; }
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; }
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; }
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; }