Новосибирский Государственный Технический Университет. Факультет автоматики и вычислительной техники Кафедра вычислительной техники (специальность 220100). учебное пособие
Вид материала | Учебное пособие |
0.17.5 V_FAST - построчная заливка области |
- Новосибирский Государственный Технический Университет. Факультет автоматики и вычислительной, 1650.9kb.
- Рабочая программа для специальности: 220400 Программное обеспечение вычислительной, 133.96kb.
- Государственный Технический Университет. Факультет: Автоматики и Вычислительной Техники., 32.46kb.
- Образования Республики Молдова Колледж Микроэлектроники и Вычислительной Техники Кафедра, 113.64kb.
- Постоянное развитие и углубление профессиональных навыков в области информационных, 54.56kb.
- «Программное обеспечение вычислительной техники и автоматизированных систем», 1790.14kb.
- Задачи дисциплины: -изучение основ вычислительной техники; -изучение принципов построения, 37.44kb.
- Лекция №2 «История развития вычислительной техники», 78.1kb.
- Система контроля и анализа технических свойств интегральных элементов и устройств вычислительной, 582.84kb.
- Московский государственный инженерно-физический институт (технический университет), 947.05kb.
0.17.5 V_FAST - построчная заливка области
/*----------------------------------------------------- V_FAST
* Подпрограммы заливки области с затравкой
* построчным алгоритмом:
*
* Pop_Stk - Локальная подпрограмма. Извлекает координаты
* пиксела из стека в глобальные скаляры xtek,ytek
*
* Push_Stk - Локальная подпрограмма. Заносит координаты
* пиксела в стек
*
* Get_Video - Локальная подпрограмма. Читает строку из
* видеопамяти в глобальный буфер строки.
*
* Put_Video - Локальная подпрограмма. Копирует байты из
* глобального буфера строки в видеопамять.
*
* Search - Локальная подпрограмма. Ищет затравочные
* пикселы в строке видеопамяти, находящейся
* в глобальном массиве.
*
* V_FAST - Собственно подпрограмма построчной заливки
* гранично-определенной области
*
* V_FA_SET - Устанавливает количественные ограничения
* для заливки
*/
#include
#include
#include
#define MAX_GOR 2048 /* Разрешение дисплея по X */
#define MAX_VER 2048 /* Разрешение дисплея по Y */
#define MAX_STK 8192 /* Размер стека координат заливки */
static int gor_max= MAX_GOR;
static int ver_max= MAX_VER;
static int stk_max= MAX_STK;
static int *pi_stk, *pn_stk; /* Указ стека заливки */
static int xtek, ytek; /* Координаты из стека */
static char *pc_video; /* Указ на буфер строки */
static int stklen; /* Достигнутая глубина стека*/
/* только для отладочных */
/* измерений программы */
/*---------------------------------------------------- Pop_Stk
* Извлекает координаты пиксела из стека в xtek, ytek
* Возвращает 0/1 - нет/есть ошибки
*/
static int Pop_Stk ()
{ register int otw;
otw= 0;
if (pi_stk <= pn_stk) ++otw; else {
ytek= *--pi_stk; xtek= *--pi_stk;
}
return (otw);
} /* Pop_Stk */
/*--------------------------------------------------- Push_Stk
* Заносит координаты пиксела в стек
* Возвращает -1/0 - нет места под стек/норма
*/
static int Push_Stk (x, y)
register int x, y;
{
register int glu;
if ((glu= pi_stk - pn_stk) >= stk_max) x= -1; else {
*pi_stk++= x; *pi_stk++= y; x= 0;
if (glu > stklen) stklen= glu;
}
return (x);
} /* Push_Stk */
/*-------------------------------------------------- Get_Video
* В байтовый буфер строки, заданный глобальным
* указателем pc_video,
* читает из видеопамяти пикселы y-строки от xbg до xen
* Возвращает 0/1 - нет/есть ошибки
*/
static int Get_Video (y, pcxbg, pcxen)
int y; register char *pcxbg, *pcxen;
{ register int x;
if (y>=0 && y
x= pcxbg - pc_video;
do *pcxbg++= getpixel (x++, y); while (pcxbg <= pcxen);
y= 0;
} else y= 1;
return (y);
} /* Get_Video */
/*-------------------------------------------------- Put_Video
* Пикселы из буфера строки, начиная от указателя pxbg,
* до указателя pxen пишет в y-строку видеопамяти
* Возвращает 0/1 - нет/есть ошибки
*/
static int Put_Video (y, pxbg, pxen)
int y; register char *pxbg, *pxen;
{ register int x;
if (y>=0 && y
x= pxbg - pc_video;
do putpixel (x++, y, *pxbg++); while (pxbg <= pxen);
y= 0;
} else y= 1;
return (y);
} /* Put_Video */
/*----------------------------------------------------- Search
* Ищет затравочные пикселы в yt-строке видеопамяти,
* находящейся по указателю pc_video, начиная от
* указателя pcl до указателя pcr
* grn - код граничного пиксела
* new - код, которым перекрашивается область
* Возвращает: 0/1 - не найден/найден затравочный
*/
static int Search (yt, pcl, pcr, grn, new)
int yt; char *pcl, *pcr; int grn, new;
{ register int pix;
register char *pc;
int x, otw;
otw= 0;
while (pcl <= pcr) {
pc= pcl; /* Указ тек пиксела */
/* Поиск крайнего правого не закрашенного пиксела в строке */
while ((pix= *pc & 255) != grn && pix != new && pc
++pc;
if (pc != pcl) { /* Найден закрашиваемый */
++otw;
x= pc - pc_video; /* Его координата в строке */
if (pc != pcr || pix == grn || pix == new) --x;
Push_Stk (x, yt);
}
/* Продолжение анализа строки пока не достигнут прав пиксел */
pcl= pc;
while (((pix= *pc & 255) == grn || pix==new) && pc
++pc;
if (pc == pcl) ++pc;
pcl= pc;
}
return (otw);
} /* Search */
/*----------------------------------------------------- V_FAST
* Построчная заливка с затравкой гранично-определенной
* области
*
* int V_FAST (int grn_pix, int new_pix, int x_isx, int y_isx)
*
* Вход:
* grn_pix - код граничного пиксела
* new_pix - код заполняющего пиксела
* x_isx - координаты затравки
* y_isx
*
* Возвращает:
* -2 - нет места под растровую строку
* -1 - нет места под стек
* 0 - норма
* 1 - при чтении пикселов из видеопамяти в буферную
* строки выход за пределы буферной строки
* 2 - исчерпан стек при запросе координат пикселов
*
*/
int V_FAST (grn_pix, new_pix, x_isx, y_isx)
int grn_pix, new_pix, x_isx, y_isx;
{
register char *pcl; /* Указ левого пиксела в строке */
register char *pcr; /* Указ правого пиксела в строке */
int otw;
otw= 0;
/* Инициализация стека */
if ((pn_stk= (int *)malloc (stk_max)) == NULL) {
--otw; goto all;
}
pi_stk= pn_stk;
/* Заказ массива под растровую строку */
if ((pc_video= malloc (gor_max)) == NULL) {
otw= -2; goto fre_stk;
}
Push_Stk (x_isx, y_isx); /* Затравку в стек */
/* Цикл заливки строк до исчерпания стека */
while (pi_stk > pn_stk) {
/* Запрос координат затравки из стека */
if (Pop_Stk ()) {otw=2; break; }
pcl= pcr= pc_video + xtek; /* Указ затравки */
/* Запрос полной строки из видеопамяти */
if (Get_Video (ytek, pc_video, pc_video+gor_max-1))
{otw= 1; break; }
/* Закраска затравки и вправо от нее */
do *pcr++= new_pix; while ((*pcr & 255) != grn_pix);
--pcr; /* Указ крайнего правого */
/* Закраска влево */
while ((*--pcl & 255) != grn_pix) *pcl= new_pix;
++pcl; /* Указ крайнего левого */
/* Занесение подправленной строки в видеопамять */
Put_Video (ytek, pcl, pcr);
/* Поиск затравок в строках ytek+1 и ytek-1,
* начиная с левого подинтервала, заданного pcl, до
* правого подинтервала, заданного pcr
*/
if (!Get_Video (++ytek, pcl, pcr))
Search (ytek, pcl, pcr, grn_pix, new_pix);
if (!Get_Video (ytek-= 2, pcl, pcr))
Search (ytek, pcl, pcr, grn_pix, new_pix);
}
free (pc_video);
fre_stk:
free (pn_stk);
all:
return (otw);
} /* V_FAST */
/*--------------------------------------------------- V_FA_SET
* Устанавливает количественные ограничения для заливки
*/
void V_FA_SET (x_resolution, y_resolution, stack_length)
int x_resolution, y_resolution, stack_length;
{
if (x_resolution > 0 && x_resolution <= MAX_GOR)
gor_max= x_resolution;
if (y_resolution > 0 && y_resolution <= MAX_VER)
ver_max= y_resolution;
/* Кол байт координат, заносимых в стек м.б. только четным */
if (stack_length > 0) stk_max= stack_length & 0177776;
} /* V_FA_SET */