mirror of https://github.com/i3/i3lock.git
Add rgbx, xrgb, bgr, etc. formats (#234)
parent
0be11444bc
commit
aa7984f215
4
i3lock.1
4
i3lock.1
|
@ -79,8 +79,8 @@ Display the given PNG image instead of a blank screen.
|
|||
.TP
|
||||
.BI \fB\-\-raw= format
|
||||
Read the image given by \-\-image as a raw image instead of PNG. The argument is the image's format
|
||||
as <width>x<height>:<pixfmt>. The supported pixel formats are 'native' and 'rgb'.
|
||||
The "rgb" pixel format expects a pixel to be three bytes; red, green, and blue.
|
||||
as <width>x<height>:<pixfmt>. The supported pixel formats are:
|
||||
\'native', 'rgb', 'xrgb', 'rgbx', 'bgr', 'xbgr', and 'bgrx'.
|
||||
The "native" pixel format expects a pixel as a 32-bit (4-byte) integer in
|
||||
the machine's native endianness, with the upper 8 bits unused. Red, green and blue are stored in
|
||||
the remaining bits, in that order.
|
||||
|
|
65
i3lock.c
65
i3lock.c
|
@ -657,24 +657,32 @@ static ssize_t read_raw_image_native(uint32_t *dest, FILE *src, size_t width, si
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t read_raw_image_rgb(uint32_t *dest, FILE *src, size_t width, size_t height, int pixstride) {
|
||||
unsigned char *buf = malloc(width * 3);
|
||||
struct raw_pixel_format {
|
||||
int bpp;
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
};
|
||||
|
||||
static ssize_t read_raw_image_fmt(uint32_t *dest, FILE *src, size_t width, size_t height, int pixstride,
|
||||
struct raw_pixel_format fmt) {
|
||||
unsigned char *buf = malloc(width * fmt.bpp);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
ssize_t count = 0;
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
size_t n = fread(buf, 1, width * 3, src);
|
||||
size_t n = fread(buf, 1, width * fmt.bpp, src);
|
||||
count += n;
|
||||
if (n < (size_t)(width * 3))
|
||||
if (n < (size_t)(width * fmt.bpp))
|
||||
break;
|
||||
|
||||
for (size_t x = 0; x < width; ++x) {
|
||||
int idx = x * 3;
|
||||
int idx = x * fmt.bpp;
|
||||
dest[y * pixstride + x] = 0 |
|
||||
(buf[idx + 0] << 16) |
|
||||
(buf[idx + 1] << 8) |
|
||||
(buf[idx + 2]);
|
||||
(buf[idx + fmt.red]) << 16 |
|
||||
(buf[idx + fmt.green]) << 8 |
|
||||
(buf[idx + fmt.blue]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -682,6 +690,14 @@ static ssize_t read_raw_image_rgb(uint32_t *dest, FILE *src, size_t width, size_
|
|||
return count;
|
||||
}
|
||||
|
||||
// Pre-defind pixel formats (<bytes per pixel>, <red pixel>, <green pixel>, <blue pixel>)
|
||||
static const struct raw_pixel_format raw_fmt_rgb = {3, 0, 1, 2};
|
||||
static const struct raw_pixel_format raw_fmt_rgbx = {4, 0, 1, 2};
|
||||
static const struct raw_pixel_format raw_fmt_xrgb = {4, 1, 2, 3};
|
||||
static const struct raw_pixel_format raw_fmt_bgr = {3, 2, 1, 0};
|
||||
static const struct raw_pixel_format raw_fmt_bgrx = {4, 2, 1, 0};
|
||||
static const struct raw_pixel_format raw_fmt_xbgr = {4, 3, 2, 1};
|
||||
|
||||
static cairo_surface_t *read_raw_image(const char *image_path, const char *image_raw_format) {
|
||||
cairo_surface_t *img;
|
||||
|
||||
|
@ -727,16 +743,33 @@ static cairo_surface_t *read_raw_image(const char *image_path, const char *image
|
|||
/* If the pixfmt is 'native', just read each line directly into the buffer */
|
||||
size = w * h * 4;
|
||||
count = read_raw_image_native(data, f, w, h, pixstride);
|
||||
} else if (strcmp(pixfmt, "rgb") == 0) {
|
||||
/* If the pixfmt is 'rgb', we have to convert it to the native pixfmt */
|
||||
size = w * h * 3;
|
||||
count = read_raw_image_rgb(data, f, w, h, pixstride);
|
||||
} else {
|
||||
fprintf(stderr, "Unknown raw pixel pixfmt: %s\n", pixfmt);
|
||||
fclose(f);
|
||||
cairo_surface_destroy(img);
|
||||
return NULL;
|
||||
const struct raw_pixel_format *fmt = NULL;
|
||||
|
||||
if (strcmp(pixfmt, "rgb") == 0)
|
||||
fmt = &raw_fmt_rgb;
|
||||
else if (strcmp(pixfmt, "rgbx") == 0)
|
||||
fmt = &raw_fmt_rgbx;
|
||||
else if (strcmp(pixfmt, "xrgb") == 0)
|
||||
fmt = &raw_fmt_xrgb;
|
||||
else if (strcmp(pixfmt, "bgr") == 0)
|
||||
fmt = &raw_fmt_bgr;
|
||||
else if (strcmp(pixfmt, "bgrx") == 0)
|
||||
fmt = &raw_fmt_bgrx;
|
||||
else if (strcmp(pixfmt, "xbgr") == 0)
|
||||
fmt = &raw_fmt_xbgr;
|
||||
|
||||
if (fmt == NULL) {
|
||||
fprintf(stderr, "Unknown raw pixel format: %s\n", pixfmt);
|
||||
fclose(f);
|
||||
cairo_surface_destroy(img);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = w * h * fmt->bpp;
|
||||
count = read_raw_image_fmt(data, f, w, h, pixstride, *fmt);
|
||||
}
|
||||
|
||||
cairo_surface_mark_dirty(img);
|
||||
|
||||
if (count < size) {
|
||||
|
|
Loading…
Reference in New Issue