Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.07.2013, 22:05   #1
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию Cairo + GTK-3. В чём ошибка?

(test:25563): Gdk-WARNING **: test: Fatal IO error 14 (Неправильный адрес) on X server :0.
Код:
//gcc -Wall "%f" -o "%e"  `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`

#include <stdio.h>
#include <string.h>

#include <gtk/gtk.h>
#include <cairo.h>

#define IMG_WIDTH 255
#define IMG_HEIGHT 255
#define RGB24 3

typedef unsigned char uchar;

void draw_RGB24(cairo_t *cr, uchar *buf){
	int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, IMG_WIDTH);
	cairo_surface_t *surface = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_RGB24, IMG_WIDTH, IMG_HEIGHT, stride);
		cairo_set_source_surface(cr, surface, 0, 0);
		cairo_paint(cr);
	cairo_surface_destroy(surface);
}

gboolean drawer(GtkWidget *widget, cairo_t *cr, gpointer user_data){
	uchar buf[IMG_WIDTH * IMG_HEIGHT * RGB24];
		memset(buf, 255, IMG_WIDTH * IMG_HEIGHT * RGB24);
		cr = gdk_cairo_create(gtk_widget_get_window(widget));
		draw_RGB24(cr, buf);
	cairo_destroy(cr);
	
	return FALSE;
}

int main(int argc, char *argv[]){
	GtkWidget *window, *drawing_area;

	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	drawing_area = gtk_drawing_area_new();
	
	g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawer), NULL);
		
	gtk_container_add(GTK_CONTAINER(window), drawing_area);
	
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
	
	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	gtk_window_set_default_size(GTK_WINDOW(window), IMG_WIDTH, IMG_HEIGHT); 
	gtk_window_set_title(GTK_WINDOW(window), "MB");
		
	gtk_widget_queue_draw(drawing_area);
		
	gtk_widget_show_all(window);
	gtk_main();
	
	return 0;
}
do not use your brain

Последний раз редактировалось Кащей; 09.07.2013 в 22:08.
Кащей вне форума Ответить с цитированием
Старый 10.07.2013, 00:06   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,336
По умолчанию

судя доке, перед созданием буфера изображения сначала нужно вычислить параметр stride, потом уже создавать буфер. поправил на коленке:

Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <gtk/gtk.h>
#include <cairo.h>

#define IMG_WIDTH 255
#define IMG_HEIGHT 255
#define RGB24 3

typedef unsigned char uchar;

void draw_RGB24(cairo_t *cr, uchar *buf, int stride)
{
	cairo_surface_t *surface = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_RGB24, IMG_WIDTH, IMG_HEIGHT, stride);
	cairo_set_source_surface(cr, surface, 100, 100);
	cairo_paint(cr);
	cairo_surface_destroy(surface);
}

gboolean drawer(GtkWidget *widget, cairo_t *cr, gpointer user_data)
{
	int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, IMG_WIDTH);
	size_t img_size = stride * IMG_HEIGHT;
	uchar *buf = malloc(img_size);

	memset(buf, 128, img_size);
	cr = gdk_cairo_create(gtk_widget_get_window(widget));
	draw_RGB24(cr, buf, stride);
	cairo_destroy(cr);
	free(buf);

	return FALSE;
}

int main(int argc, char *argv[]){
	GtkWidget *window, *drawing_area;

	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	drawing_area = gtk_drawing_area_new();

	g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawer), NULL);

	gtk_container_add(GTK_CONTAINER(window), drawing_area);

	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	gtk_window_set_default_size(GTK_WINDOW(window), IMG_WIDTH*2, IMG_HEIGHT*2); 
	gtk_window_set_title(GTK_WINDOW(window), "MB");

	gtk_widget_queue_draw(drawing_area);

	gtk_widget_show_all(window);
	gtk_main();

	return 0;
}
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 10.07.2013, 01:15   #3
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Проблема в том что я пытался какбы имеющиеся данные отрисовать. С bmp картинкой исключая заголовк идёт на ура. Что там такого эдакого спрятано?
Поправь меня если чтото не так:
Пиксель из трёх байт, каждый байт 8 бит от того и формат rgb24, а значит сырые данные вроде как и должны выглядеть как массив однобайтовых беззнаковых значений размером ширина*высота*3_байта_на_пиксель.
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 10.07.2013, 01:24   #4
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Если интересует, ошибка была вооот тут
Цитата:
#define RGB24 4
Ему на rgb24 4 байта подавай. Чо за дела..
Код:
//gcc -Wall "%f" -o "%e"  `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0`

#include <stdio.h>
#include <string.h>

#include <gtk/gtk.h>
#include <cairo.h>

#define IMG_WIDTH 64
#define IMG_HEIGHT 64 
#define RGB24 4
#define BUF_SIZE IMG_WIDTH * IMG_HEIGHT * RGB24

typedef unsigned char uchar;

void draw_RGB24(cairo_t *cr, uchar *buf){
	int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, IMG_WIDTH);
	cairo_surface_t *surface = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_RGB24, IMG_WIDTH, IMG_HEIGHT, stride);
	printf("%d\n", stride);
		cairo_set_source_surface(cr, surface, 0, 0);
		cairo_paint(cr);
	cairo_surface_destroy(surface);
}

gboolean drawer(GtkWidget *widget, cairo_t *cr, gpointer user_data){
	uchar buf[IMG_WIDTH * IMG_HEIGHT * RGB24];
		memset(buf, 100, IMG_WIDTH * IMG_HEIGHT * RGB24);
		cr = gdk_cairo_create(gtk_widget_get_window(widget));
		draw_RGB24(cr, buf);
	cairo_destroy(cr);
	
	return FALSE;
}

int main(int argc, char *argv[]){
	GtkWidget *window, *drawing_area;

	gtk_init(&argc, &argv);
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	drawing_area = gtk_drawing_area_new();
	
	g_signal_connect(G_OBJECT(drawing_area), "draw", G_CALLBACK(drawer), NULL);
		
	gtk_container_add(GTK_CONTAINER(window), drawing_area);
	
	g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
	
	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
	gtk_window_set_default_size(GTK_WINDOW(window), IMG_WIDTH, IMG_HEIGHT); 
	gtk_window_set_title(GTK_WINDOW(window), "MB");
		
	gtk_widget_queue_draw(drawing_area);
		
	gtk_widget_show_all(window);
	gtk_main();
	
	return 0;
}
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 10.07.2013, 01:28   #5
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,336
По умолчанию

2Кащей
догнал
Код:
	int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, IMG_WIDTH);
Цитата:
CAIRO_FORMAT_RGB24

each pixel is a 32-bit quantity, with the upper 8 bits unused. Red, Green, and Blue are stored in the remaining 24 bits in that order. (Since 1.0)
если посмотришь на результат
Код:
int stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, IMG_WIDTH);
то увидишь, что это width*height*4. вобщем по нормальному, просто откажись от своей константы
Код:
#define RGB24 3
и делай примерно так, как я показал (рассчитывай размер исходя от stride). либо в своем коде передефань на 4.

пс. я с каиро не работал, что в доках вижу, то и говорю


псс. тоже уже заметил)
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 10.07.2013, 01:32   #6
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Цитата:
что в доках вижу, то и говорю
Хорошо тебе, а я там херню несвязную вижу, по етому учусь ясновиденью. Я бы тебе люто бешано плюсанул, да тока некуда, не вижу кнопок и спасибо.
do not use your brain
Кащей вне форума Ответить с цитированием
Старый 10.07.2013, 01:37   #7
Кащей
Форумчанин
 
Аватар для Кащей
 
Регистрация: 09.07.2013
Сообщений: 249
По умолчанию

Цитата:
Ему на rgb24 4 байта подавай. Чо за дела..
Транслятор порадовал
Цитата:
причем верхний 8 битов не используется
do not use your brain
Кащей вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Кроссплатформенный анимированный осциллограф (GTK+, Cairo) oleg kutkov Qt и кроссплатформенное программирование С/С++ 15 22.10.2015 20:13
В чём ошибка? -SandwicH- Общие вопросы C/C++ 10 10.06.2012 19:05
статья - Кроссплатформенный осциллограф на GTK+/Cairo Pblog Обсуждение статей 0 28.04.2011 21:00
обновление в блоге - Кроссплатформенный анимированный осциллограф (GTK+, Cairo) Pblog Обсуждение статей 0 16.08.2009 16:00