Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 34 additions & 16 deletions drivers/video/fbdev/core/fb_logo.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,8 @@ static bool fb_palette_contains_entry(struct image_palette *palette, int num_exi
return false; // No duplicate found
}

static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
struct fb_image *image, u32 *palette)
static int fb_set_logo_from_file(struct fb_info *info, const char *filepath,
struct fb_image *image, u32 *palette)
{
int current_rows = 0, palette_index = 0, actual_row, skip_x = 0, skip_y = 0, ret;
unsigned char *read_logo = NULL, *header;
Expand All @@ -354,7 +354,7 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
struct image_palette image_palette;
const char *current_ptr, *end_ptr;
long width = 0, height = 0;
bool top_to_bottom;
bool top_to_bottom, clipped = false;
u8 B, G, R;
u8 entry[3];
ssize_t len;
Expand All @@ -366,6 +366,7 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
}
len = fw->size;
file_content = fw->data;
ret = -EINVAL;

if (!len) {
pr_err("Error: logo TGA file is empty. Not drawing fullscreen logo.\n");
Expand All @@ -391,14 +392,18 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
header[2], header[16]);
goto cleanup;
}
if (!width || !height) {
pr_err("Invalid logo file: TGA image is %ldx%ld\n", width, height);
goto cleanup;
}
// Skip header + ID field
current_ptr = file_content + 18 + header[0];

read_logo = kmalloc_array(width, height, GFP_KERNEL);
if (!read_logo)
if (!read_logo) {
ret = -ENOMEM;
goto cleanup;

image->data = read_logo;
}

// TGA pixels are stored bottom-to-top by default, unless bit 5 of
// image_descriptor is set
Expand Down Expand Up @@ -439,8 +444,10 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
image_palette.colors[current_rows][k] =
entry[k];
palette_index = current_rows;
current_rows++;
} else {
clipped = true;
}
current_rows++;
}
actual_row = top_to_bottom ? i : (height - 1 - i);

Expand All @@ -450,17 +457,11 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
current_ptr += skip_x * 3 * 2;
}

if (current_rows >= 224)
if (clipped)
pr_err("Palette overflow. Entries clipped\n");

// Set logo palette
palette = kzalloc(256 * 4, GFP_KERNEL);
if (!palette)
goto cleanup;
fb_set_logo_RGB_palette(info, &image_palette, palette, current_rows);
if (info->pseudo_palette)
memcpy(palette, info->pseudo_palette, 32 * sizeof(uint32_t));
info->pseudo_palette = palette;

image->width = min_t(unsigned int, width, info->var.xres);
image->height = min_t(unsigned int, height, info->var.yres);
Expand All @@ -473,9 +474,14 @@ static void fb_set_logo_from_file(struct fb_info *info, const char *filepath,
if (image->width < info->var.xres)
image->dx = (info->var.xres - image->width) / 2;

image->data = read_logo;
release_firmware(fw);
return 0;

cleanup:
kfree(read_logo);
release_firmware(fw);
return ret;
}


Expand All @@ -493,8 +499,18 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
return 0;

if (fullscreen_logo_enabled) {
fb_set_logo_from_file(info, fullscreen_logo_path,
&image, palette);
palette = kzalloc(256 * 4, GFP_KERNEL);
if (!palette)
return 0;

if (fb_set_logo_from_file(info, fullscreen_logo_path,
&image, palette)) {
kfree(palette);
return 0;
}

saved_pseudo_palette = info->pseudo_palette;
info->pseudo_palette = palette;
} else {
image.depth = 8;
image.data = logo->data;
Expand Down Expand Up @@ -580,6 +596,8 @@ static int fb_show_logo_line(struct fb_info *info, int rotate,
kfree(palette);
if (saved_pseudo_palette != NULL)
info->pseudo_palette = saved_pseudo_palette;
if (fullscreen_logo_enabled)
kfree(image.data);
kfree(logo_new);
kfree(logo_rotate);
return image.dy + logo->height;
Expand Down
Loading