summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoruint <abhinav.prsai@gmail.com>2025-12-14 16:57:31 +0000
committeruint <abhinav.prsai@gmail.com>2025-12-14 17:03:57 +0000
commit199ac1911f2ac6aadc31940088818e1a58f0362a (patch)
tree03b9208cc3dcfbdef4dc80c022124e997331903b
parent3e4a21e646b7b7fab8cdad370e3d03f7957bc833 (diff)
working! add channel and ppm creation
using ppm6! .
-rw-r--r--Makefile1
-rw-r--r--xnap.c56
2 files changed, 57 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index b69ebdc..ac9a786 100644
--- a/Makefile
+++ b/Makefile
@@ -10,6 +10,7 @@ LIBS = -lX11
# flags
# CPPFLAGS =
+# CFLAGS = -std=c99 -Wall -Wextra -O0 -g ${CPPFLAGS} -fdiagnostics-color=always # debug
CFLAGS = -std=c99 -Wall -Wextra -Os ${CPPFLAGS} -fdiagnostics-color=always
LDFLAGS = ${LIBS}
diff --git a/xnap.c b/xnap.c
index 1ebface..105173f 100644
--- a/xnap.c
+++ b/xnap.c
@@ -18,8 +18,10 @@ struct pointer_t {
int y1;
};
+unsigned char channel(unsigned long px, Mask m);
void compimg(void);
void die(const char* s);
+void mkppm(const char* path, XImage* img);
void quit(Bool ex);
void run(void);
void setup(void);
@@ -30,6 +32,34 @@ int scr = -1;
struct pointer_t p = {0};
XImage* img = NULL;
+unsigned char channel(unsigned long px, Mask m)
+{
+ if (m == 0)
+ return 0;
+
+ int shift = 0;
+ /* shift down until we find channel */
+ while ((m & 1UL) == 0) {
+ m >>= 1UL;
+ shift++;
+ }
+
+ /* bits in channel */
+ int bits = 0;
+ while (m & 1UL) {
+ m >>= 1UL;
+ bits++;
+ }
+
+ /* raw channel value */
+ unsigned long rv = (px >> shift) & ((1UL << bits) - 1UL);
+
+ /* scale v from [0, 2^bits-1]->[0,255] to meet standard */
+ if (bits == 8)
+ return rv;
+ return ((rv * 255UL) / ((1UL << bits) - 1UL));
+}
+
void compimg(void)
{
/* create selection rectangle */
@@ -45,6 +75,7 @@ void compimg(void)
unsigned long p0 = XGetPixel(img, 0, 0);
fprintf(stderr, "first pixe =#%lx depth=%d bpp=%d\n", p0, img->depth, img->bits_per_pixel);
+ mkppm("img.ppm", img);
XDestroyImage(img);
quit(True);
}
@@ -55,6 +86,31 @@ void die(const char* s)
exit(EXIT_FAILURE);
}
+void mkppm(const char* path, XImage* img)
+{
+ FILE* f = fopen(path, "w");
+ if (!f)
+ die("fopen failed");
+
+ /* write ppm metadata header */
+ fprintf(f, "P6\n%d %d\n255\n", img->width, img->height);
+
+ for (int y = 0; y < img->height; y++) {
+ for (int x = 0; x < img->width; x++) {
+ unsigned long px = XGetPixel(img, x, y);
+ unsigned char r = channel(px, img->red_mask);
+ unsigned char g = channel(px, img->green_mask);
+ unsigned char b = channel(px, img->blue_mask);
+
+ fputc(r, f);
+ fputc(g, f);
+ fputc(b, f);
+ }
+ }
+
+ fclose(f);
+}
+
void quit(Bool ex)
{
XUngrabPointer(dpy, CurrentTime);