Хочу создать аналог UOpilot для Линукс. На данный момент пробую создать нормальную функцию для поиска пикселя конкретного цвета на экране. Немного бродил по просторам интернета и склепал следующий код:
char *findColor_range(int startX, int startY,
int endX, int endY,
int startRed, int endRed, int startGreen, int endGreen, int startBlue, int endBlue) {
Display *d = XOpenDisplay((char *) NULL);
XImage *image;
int x, y;
XColor c;
char *res;
for(x = startX; x <= endX; x++) {
for(y = startY; y <= endY; y++) {
image = XGetImage(d, RootWindow(d, DefaultScreen(d)), x, y, 1, 1, AllPlanes, XYPixmap);
c.pixel = XGetPixel(image, 0, 0);
XFree(image);
XQueryColor(d, DefaultColormap(d, DefaultScreen(d)), &c);
if(c.red / 256 >= startRed && c.red / 256 <= endRed &&
c.green / 256 >= startGreen && c.green / 256 <= endGreen &&
c.blue / 256 >= startBlue && c.blue / 256 <= endBlue) {
asprintf(&res, "%d,%d", x, y);
return res;
}
}
}
asprintf(&res, "0");
return res;
}
Здесь работает поиск не по конкретному цвету, а по диапазону цветов. По названию переменных и коде думаю поймете. Это работает (хотя не очень-то и быстро, 300х300 прочесало секунды так за 4). А вот функция где по конкретному цвету, но другой алгоритм поиска:
char *findColor(int startX, int startY,
int endX, int endY,
int red, int green, int blue) {
Display *d = XOpenDisplay((char *) NULL);
XImage *image;
int x, y;
XColor c;
char *res;
image = XGetImage(d, RootWindow(d, DefaultScreen(d)), startX, startY, endX - startX, endY - startY, AllPlanes, XYPixmap);
for(x = startX; x <= endX; x++) {
for(y = startY; y <= endY; y++) {
c.pixel = XGetPixel(image, x - startX, y - startY);
XFree(image);
XQueryColor(d, DefaultColormap(d, DefaultScreen(d)), &c);
if(c.red / 256 == red && c.green / 256 == green && c.blue / 256 == blue) {
asprintf(&res, "%d,%d", x, y);
return res;
}
}
}
asprintf(&res, "0");
return res;
}
Здесь я хотел сделать, чтобы XGetImage вызывалось только раз, а соответственно нужно будет искать и этой "картинке". Ну, зато не надо каждый раз брать его отдельно для каждого пикселя. Так вот, во время выполнения этой второй функции у меня куча ошибок (в общем, ошибка адресации). Если надо, можете увидеть ее ниже.
*** glibc detected *** ./test01: double free or corruption (top): 0x000000000150dda0 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7f3d2451eb96]
/usr/lib/x86_64-linux-gnu/libX11.so.6(XFree+0x9)[0x7f3d248a06a9]
./test01[0x400e6b]
./test01[0x400ffe]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7f3d244c176d]
./test01[0x4006f9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:06 2224180 /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
00601000-00602000 r--p 00001000 08:06 2224180 /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
00602000-00603000 rw-p 00002000 08:06 2224180 /home/tolik/Dropbox/C_and_CPP/BotFramework/test01
014d6000-01519000 rw-p 00000000 00:00 0 [heap]
7f3d23a5f000-7f3d23a74000 r-xp 00000000 08:05 135186 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23a74000-7f3d23c73000 ---p 00015000 08:05 135186 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c73000-7f3d23c74000 r--p 00014000 08:05 135186 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c74000-7f3d23c75000 rw-p 00015000 08:05 135186 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3d23c75000-7f3d23c7a000 r-xp 00000000 08:05 661801 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23c7a000-7f3d23e79000 ---p 00005000 08:05 661801 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e79000-7f3d23e7a000 r--p 00004000 08:05 661801 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e7a000-7f3d23e7b000 rw-p 00005000 08:05 661801 /usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0
7f3d23e7b000-7f3d23e7d000 r-xp 00000000 08:05 661790 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d23e7d000-7f3d2407c000 ---p 00002000 08:05 661790 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407c000-7f3d2407d000 r--p 00001000 08:05 661790 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407d000-7f3d2407e000 rw-p 00002000 08:05 661790 /usr/lib/x86_64-linux-gnu/libXau.so.6.0.0
7f3d2407e000-7f3d24080000 r-xp 00000000 08:05 135178 /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24080000-7f3d24280000 ---p 00002000 08:05 135178 /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24280000-7f3d24281000 r--p 00002000 08:05 135178 /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24281000-7f3d24282000 rw-p 00003000 08:05 135178 /lib/x86_64-linux-gnu/libdl-2.15.so
7f3d24282000-7f3d2429f000 r-xp 00000000 08:05 662409 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2429f000-7f3d2449e000 ---p 0001d000 08:05 662409 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2449e000-7f3d2449f000 r--p 0001c000 08:05 662409 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d2449f000-7f3d244a0000 rw-p 0001d000 08:05 662409 /usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0
7f3d244a0000-7f3d24655000 r-xp 00000000 08:05 135165 /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24655000-7f3d24855000 ---p 001b5000 08:05 135165 /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24855000-7f3d24859000 r--p 001b5000 08:05 135165 /lib/x86_64-linux-gnu/libc-2.15.so
7f3d24859000-7f3d2485b000 rw-p 001b9000 08:05 135165 /lib/x86_64-linux-gnu/libc-2.15.so
7f3d2485b000-7f3d24860000 rw-p 00000000 00:00 0
7f3d24860000-7f3d24990000 r-xp 00000000 08:05 661788 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24990000-7f3d24b90000 ---p 00130000 08:05 661788 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b90000-7f3d24b91000 r--p 00130000 08:05 661788 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b91000-7f3d24b95000 rw-p 00131000 08:05 661788 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f3d24b95000-7f3d24bb7000 r-xp 00000000 08:05 135145 /lib/x86_64-linux-gnu/ld-2.15.so
7f3d24d05000-7f3d24d4c000 rw-p 00000000 00:00 0
7f3d24d93000-7f3d24d98000 rw-p 00000000 00:00 0
7f3d24db3000-7f3d24db7000 rw-p 00000000 00:00 0
7f3d24db7000-7f3d24db8000 r--p 00022000 08:05 135145 /lib/x86_64-linux-gnu/ld-2.15.so
7f3d24db8000-7f3d24dba000 rw-p 00023000 08:05 135145 /lib/x86_64-linux-gnu/ld-2.15.so
7fff24a57000-7fff24a78000 rw-p 00000000 00:00 0 [stack]
7fff24bd5000-7fff24bd7000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Скорее всего, ошибка где-то в алгоритме.
P.S. Вызывал через
printf("%s\n", findColor(1, 1, 300, 300, 255, 255, 255));