информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Атака на InternetSpanning Tree Protocol: недокументированное применениеВсе любят мед
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Очередное исследование 19 миллиардов... 
 Оптимизация ввода-вывода как инструмент... 
 Зловреды выбирают Lisp и Delphi 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
если вы видите этот текст, отключите в настройках форума использование JavaScript
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
Теперь и с комментариями :) 21.02.02 13:13  Число просмотров: 1059
Автор: Chingachguk <Chingachguk> Статус: Member
Отредактировано 21.02.02 13:49  Количество правок: 4
<"чистая" ссылка>
> Спасиба! Я её откомпилировал - все нормально.
> {...} Или просто опиши
> как она работает - на асеме я мало что знаю: только работу
> с прерываниями, и то плохо.

Так я сделал - добавил комментарии. Я думаю, ты легко поймешь
алгоритм и реализуешь его на другом языке Ж)

Код очень крив.

Желаю удачи !

Procedure Fill_Area(Color_Bound,Color_In:byte; X,Y:word);
Const
Buff_Size=4000; {Это максимальный размер буфера}
Buff_Rezerv=1000; {А это запасец, с котрого начинаем суетиться}
Flag: boolean = False; {Флаг для процедуры @Check}
Var
Fill_Buffer:Array[1..Buff_Size] of Word;
Begin
; Пошел асм-код
Asm

; Загружаем сегмент видеопамяти 0A000h в ES
push 0A000h
pop ES <-0A000h

; Команды строк(lodsb..) будут обрабатываться вперед, но у меня это мусор
cld <-можно вообще выкинуть, я на автомате их написал

; Подготовка к закраске
; Координаты переданной точки - смещение
mov AX,320
mul Y ; регистры DX:AX = 320*Y
mov BX,X ; BX = X
add BX,AX ; BX = 320*Y+X
; Цвета
mov DH,Color_Bound ; DH будет всегда = цвету границы
mov DL,Color_In ; DL - цвету закраски

; Заделать буфер в стеке, хотя тут я облажался - обявив
; буфер в var, я, фактически, задвоил его
sub BP,Buff_Size ; Тут регистр BP=начало буфера

; Проверим стартовую точку
mov SI,BX ; Координата стартовой точки
xor CX,CX ; CL будет равно после вызова @Check числу соседей
xor DI,DI {Если будут найдены точки, то они будут добавлены в буфер}
; и BP+DI укажет на последнюю точку в буфере
call @Check ; Получить соседей стартовой точки
test CX,CX ; Есть хоть один ? (if CX=0)
jz @Done {Если нет рядом точек, годных к закраске, то EXIT}

; Основной цикл
@Main_Loop:

; Закрасить точку, ее координаты(смещение в памяти) в BX
mov ES:[BX],DL

mov Flag,False {Искать + и добавлять точки}
call @Find_Points
test DI,DI ; В буфере есть точки для обработки ? (if DI=0)
jz @Done ; Нет. EXIT

; Новое
; В буфере осталось места меньше, чем Buff_Rezerv ?
; (Для Числа точек = Buff_Rezerv /2 )
cmp DI,Buff_Size-Buff_Rezerv
jbe @SizeOk ; Пора суетиться - размер на исходе ?!
cmp DI,Buff_Size ; Ваще полный аллес - в буфере НЕТ места
ja @Done ; EXIT

; В буфере осталось места меньше, чем для Buff_Rezerv/2 Точек
; Ищем точку, у которой число соседей =0
; Готовим индекс si для просмотра буфера
xor si,si
; Бежим по буферу в поисках точки с минимальным числом соседей
@FindMin:

; Проверить точку, ее координаты(смещение в памяти) в будет передано в BX
mov bx,[bp+si]
push si ; Сохранит регистр
mov Flag,True {Искать + но не добавлять точки в буфер !!!}
call @Find_Points ; Найти число соседей для очередной точки
pop si ; Восстановить si
cmp cl,1 {Соседей >=1 ? - нахрен эту точку}
jae @NextPoint

; Подбрасываем ее на обработку, уменьшая буфер
; Следующая обрабатываемая точка будет взята последней из буфера,
; поэтому меняем найденную точку с последней в буфере,
; на последнюю счас указывает bp+di-2, на найденную - bp+si
xchg [bp+di-2],bx
mov [bp+si],bx
jmp @SizeOk ; И закончить просмотр буфера (BREAK)

; Смотреть все точки для обработки в буфере
@NextPoint:
inc si
inc si
cmp si,di ; Посмотрели все точки ?
jb @FindMin

; Буфер либо не полон, либо мы попытались его выровнять
@SizeOk:

; Укажем в буфере на последнюю точку (DI)
dec di
dec di

; Загрузим смещение точки на экране в BX (для call @Find_Points
; и mov ES:[BX],DL) - см. код выше
mov BX,[BP+DI]

; Продолжить цикл
jmp @Main_Loop

; Подпрограмма Find_Points
; Получает в BX смещение текущей обрабатываемой точки
; К экрану адресуется через ES:[BX+...
; Добавляет точки в буфер(Если Flag=False) база которого в BP,
; координата последней точки в DI
@Find_Points:

; Будем накапливать число точек в CL
xor CX,CX ; CX=0

; Проверить точку (X,Y-1)
lea SI,[BX-320]
call @Check

; Проверить точку (X,Y+1)
lea SI,[BX+320]
call @Check

; Проверить точку (X-1,Y)
lea SI,[BX-1]
call @Check

; Проверить точку (X+1,Y)
lea SI,[BX+1]
call @Check

; Нужно закрашивать точки (X+-1, Y+-1) ?
test CL,CL ; CL=0 ?
jnz @Found ; Да, есть соседи для закраса

; Проверить саму точку (X,Y)
; Я не уверен счас, что этот код нужен
dec SI
dec SI
call @Check
@Found:
ret ; Вернуться из подпрограммы

; Подпрограмма @Check
; Получает в SI координату точки(смещение),
; И добавляет ее в буфер, если она нуждается в закрасе
; (Если Flag=False), а также увеличивает на 1 число найденных точек-соседей,
; Годных для закраса (в CL)
@Check:


; ВОТ ТУТ ТЕБЕ НУЖНО МЕНЯТЬ АЛГОРИТМ
; ТУТ АНАЛИЗ ЦВЕТОВ ТОЧЕК

; Получить цвет текущей точки в AL
mov AL,ES:[SI]
; Он равен цвету границы ?
cmp AL,DH
jz @Next ; Да. Точка не подходит
; Он равен цвету заливки ?
cmp AL,DL
jz @Next ; Да. Нафиг ее

; Если параметр Flag=TRue, то НЕ ДОБАВЛЯЕМ точку в буфер
cmp Flag,True
jz @NoAddPoint

; Добавляем точку в буфер ПОСЛЕДНЕЙ
mov [BP+DI],SI ; Добавить смещение точки в буфер
inc DI
inc DI
@NoAddPoint:
; Увеличить счетчик найденных точек
inc CL
@Next: ret
@Done:
; Пурга по восстановлению BP. Не обращай внимания.
add BP,Buff_Size
End;
End;
<programming>
Помогите разобраться с заливкой 20.02.02 14:31  
Автор: Eniac Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Люди, подскажите как в DOSе сделать заливку до первого цвета (как в Paint), не используя рекурсивный вызов (т.к. при больших размерах заливаемой части прога переполняет стек)

Мыльте: eniac2002@mail.ru
Как я делал это на асм под пас. 20.02.02 14:44  
Автор: Chingachguk <Chingachguk> Статус: Member
Отредактировано 20.02.02 14:53  Количество правок: 3
<"чистая" ссылка>
> Люди, подскажите как в DOSе сделать заливку до первого
> цвета (как в Paint), не используя рекурсивный вызов (т.к.
> при больших размерах заливаемой части прога переполняет
> стек)
>
> Мыльте: eniac2002@mail.ru

{Закраска замкнутой области}
{Режим 13h, 256 цветов}
Procedure Fill_Area(Color_Bound,Color_In:byte; X,Y:word);
Const
Buff_Size=(320+200)*2; {Посмотри свой стек !!!- хватит ли его}
Var
Fill_Buffer:Array[1..Buff_Size] of Word;
Begin
Asm
push 0A000h
pop ES
cld
mov AX,320
mul Y
mov BX,X
add BX,AX
mov DH,Color_Bound
mov DL,Color_In
sub BP,Buff_Size
mov SI,BX
xor CX,CX
xor DI,DI {}
call @Check
test CX,CX
jz @Done
@Main_Loop: mov ES:[BX],DL
Call @Find_Points
test DI,DI
jz @Done
dec DI
dec DI
mov BX,[BP+DI]
jmp @Main_Loop
@Find_Points: xor CX,CX
lea SI,[BX-320]
call @Check
lea SI,[BX+320]
call @Check
lea SI,[BX-1]
call @Check
lea SI,[BX+1]
call @Check
test CL,CL
jnz @Found
dec SI
dec SI
call @Check
@Found: ret
@Check: mov AL,ES:[SI]
cmp AL,DH
jz @Next
cmp AL,DL
jz @Next
mov [BP+DI],SI
inc DI
inc DI
cmp DI,Buff_Size
ja @Done
inc CL
@Next: ret
@Done: add BP,Buff_Size
End;
End;
Begin
Graph256;
Clear(214);
PutPixel256(14,10,10);
Bar256(13,20,20,30,30);
Line256(12,40,40,100,100);
Circle256(11,12,140,140);
Fill_Area(11,9,140,140); {Тут-то и закрас пошел}
Outt256(9,20,170,ofs(MyString));
repeat until keypressed;
Close256;
End.
Но основная-то проблема всё равно осталась... 20.02.02 18:07  
Автор: Eniac Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Прога то твоя хоть и работает, но проблему со стеком не решает - слишком много памяти требует, поэтому на весь экран её в любом случае не хватит, даже на 10h, а там где мне надо закрашивать - разрешение может быть до 640x480? Может знаешь, как сделать так, чтоб меньше памяти тратилось?
Исправил. Дальше сам... 21.02.02 00:59  
Автор: Chingachguk <Chingachguk> Статус: Member
Отредактировано 21.02.02 01:10  Количество правок: 1
<"чистая" ссылка>
> Прога то твоя хоть и работает, но проблему со стеком не
> решает - слишком много памяти требует, поэтому на весь {...}
> Может знаешь, как сделать так, чтоб меньше памяти
> тратилось?

Вот. Заделал ей проверочку - в буфер теперича укладывается.
Работает, правда, очень тормозно - ну ты уж извини. Барабанил минут 10.
Если у тебя не получиться довести ее до ума, то скажи мне !

Procedure Fill_Area(Color_Bound,Color_In:byte; X,Y:word);
Const
Buff_Size=4000; {Это максимальный размер буфера}
Buff_Rezerv=1000; {А это запасец, с котрого начинаем суетиться}
Flag: boolean = False; {Флаг для процедуры @Check}
Var
Fill_Buffer:Array[1..Buff_Size] of Word;
Begin
Asm
push 0A000h
pop ES
cld
mov AX,320
mul Y
mov BX,X
add BX,AX
mov DH,Color_Bound
mov DL,Color_In
sub BP,Buff_Size
mov SI,BX
xor CX,CX
xor DI,DI {}
call @Check
test CX,CX
jz @Done
@Main_Loop: mov ES:[BX],DL
mov Flag,False {Искать + и добавлять точки}
call @Find_Points
test DI,DI
jz @Done
; Новое
cmp DI,Buff_Size-Buff_Rezerv
jbe @SizeOk ; Пора суетиться - размер на исходе ?!
cmp DI,Buff_Size ; Ваще полный аллес
ja @Done
xor si,si
; Бежим по буферу в поисках точки с минимальным числом соседей
@FindMin:
mov bx,[bp+si]
push si
mov Flag,True {Искать + но не добавлять точки !!!}
call @Find_Points
pop si
cmp cl,1 {Соседей >=1 ? - нахрен эту точку}
jae @NextPoint
; Подбрасываем ее на обработку, уменьшая буфер
xchg [bp+di-2],bx
mov [bp+si],bx
jmp @SizeOk
@NextPoint:
inc si
inc si
cmp si,di
jb @FindMin
@SizeOk:
dec di
dec di
mov BX,[BP+DI]
jmp @Main_Loop
@Find_Points: xor CX,CX
lea SI,[BX-320]
call @Check
lea SI,[BX+320]
call @Check
lea SI,[BX-1]
call @Check
lea SI,[BX+1]
call @Check
test CL,CL
jnz @Found
dec SI
dec SI
call @Check
@Found: ret
@Check: mov AL,ES:[SI]
cmp AL,DH
jz @Next
cmp AL,DL
jz @Next
cmp Flag,True
jz @NoAddPoint
mov [BP+DI],SI
inc DI
inc DI
@NoAddPoint:
inc CL
@Next: ret
@Done: add BP,Buff_Size
End;
End;
Последний вопрос по проге... 21.02.02 09:32  
Автор: Eniac Статус: Незарегистрированный пользователь
<"чистая" ссылка>
Спасиба! Я её откомпилировал - все нормально.
Послушай, а можно ли сделать так, что бы закраска происходила до первого цвета, т.е. если заранее не известно какого цвета контур, к тому же он может быть разноцветный. Если не сложно, не мог бы подсказать, plz. Или просто опиши как она работает - на асеме я мало что знаю: только работу с прерываниями, и то плохо.
Теперь и с комментариями :) 21.02.02 13:13  
Автор: Chingachguk <Chingachguk> Статус: Member
Отредактировано 21.02.02 13:49  Количество правок: 4
<"чистая" ссылка>
> Спасиба! Я её откомпилировал - все нормально.
> {...} Или просто опиши
> как она работает - на асеме я мало что знаю: только работу
> с прерываниями, и то плохо.

Так я сделал - добавил комментарии. Я думаю, ты легко поймешь
алгоритм и реализуешь его на другом языке Ж)

Код очень крив.

Желаю удачи !

Procedure Fill_Area(Color_Bound,Color_In:byte; X,Y:word);
Const
Buff_Size=4000; {Это максимальный размер буфера}
Buff_Rezerv=1000; {А это запасец, с котрого начинаем суетиться}
Flag: boolean = False; {Флаг для процедуры @Check}
Var
Fill_Buffer:Array[1..Buff_Size] of Word;
Begin
; Пошел асм-код
Asm

; Загружаем сегмент видеопамяти 0A000h в ES
push 0A000h
pop ES <-0A000h

; Команды строк(lodsb..) будут обрабатываться вперед, но у меня это мусор
cld <-можно вообще выкинуть, я на автомате их написал

; Подготовка к закраске
; Координаты переданной точки - смещение
mov AX,320
mul Y ; регистры DX:AX = 320*Y
mov BX,X ; BX = X
add BX,AX ; BX = 320*Y+X
; Цвета
mov DH,Color_Bound ; DH будет всегда = цвету границы
mov DL,Color_In ; DL - цвету закраски

; Заделать буфер в стеке, хотя тут я облажался - обявив
; буфер в var, я, фактически, задвоил его
sub BP,Buff_Size ; Тут регистр BP=начало буфера

; Проверим стартовую точку
mov SI,BX ; Координата стартовой точки
xor CX,CX ; CL будет равно после вызова @Check числу соседей
xor DI,DI {Если будут найдены точки, то они будут добавлены в буфер}
; и BP+DI укажет на последнюю точку в буфере
call @Check ; Получить соседей стартовой точки
test CX,CX ; Есть хоть один ? (if CX=0)
jz @Done {Если нет рядом точек, годных к закраске, то EXIT}

; Основной цикл
@Main_Loop:

; Закрасить точку, ее координаты(смещение в памяти) в BX
mov ES:[BX],DL

mov Flag,False {Искать + и добавлять точки}
call @Find_Points
test DI,DI ; В буфере есть точки для обработки ? (if DI=0)
jz @Done ; Нет. EXIT

; Новое
; В буфере осталось места меньше, чем Buff_Rezerv ?
; (Для Числа точек = Buff_Rezerv /2 )
cmp DI,Buff_Size-Buff_Rezerv
jbe @SizeOk ; Пора суетиться - размер на исходе ?!
cmp DI,Buff_Size ; Ваще полный аллес - в буфере НЕТ места
ja @Done ; EXIT

; В буфере осталось места меньше, чем для Buff_Rezerv/2 Точек
; Ищем точку, у которой число соседей =0
; Готовим индекс si для просмотра буфера
xor si,si
; Бежим по буферу в поисках точки с минимальным числом соседей
@FindMin:

; Проверить точку, ее координаты(смещение в памяти) в будет передано в BX
mov bx,[bp+si]
push si ; Сохранит регистр
mov Flag,True {Искать + но не добавлять точки в буфер !!!}
call @Find_Points ; Найти число соседей для очередной точки
pop si ; Восстановить si
cmp cl,1 {Соседей >=1 ? - нахрен эту точку}
jae @NextPoint

; Подбрасываем ее на обработку, уменьшая буфер
; Следующая обрабатываемая точка будет взята последней из буфера,
; поэтому меняем найденную точку с последней в буфере,
; на последнюю счас указывает bp+di-2, на найденную - bp+si
xchg [bp+di-2],bx
mov [bp+si],bx
jmp @SizeOk ; И закончить просмотр буфера (BREAK)

; Смотреть все точки для обработки в буфере
@NextPoint:
inc si
inc si
cmp si,di ; Посмотрели все точки ?
jb @FindMin

; Буфер либо не полон, либо мы попытались его выровнять
@SizeOk:

; Укажем в буфере на последнюю точку (DI)
dec di
dec di

; Загрузим смещение точки на экране в BX (для call @Find_Points
; и mov ES:[BX],DL) - см. код выше
mov BX,[BP+DI]

; Продолжить цикл
jmp @Main_Loop

; Подпрограмма Find_Points
; Получает в BX смещение текущей обрабатываемой точки
; К экрану адресуется через ES:[BX+...
; Добавляет точки в буфер(Если Flag=False) база которого в BP,
; координата последней точки в DI
@Find_Points:

; Будем накапливать число точек в CL
xor CX,CX ; CX=0

; Проверить точку (X,Y-1)
lea SI,[BX-320]
call @Check

; Проверить точку (X,Y+1)
lea SI,[BX+320]
call @Check

; Проверить точку (X-1,Y)
lea SI,[BX-1]
call @Check

; Проверить точку (X+1,Y)
lea SI,[BX+1]
call @Check

; Нужно закрашивать точки (X+-1, Y+-1) ?
test CL,CL ; CL=0 ?
jnz @Found ; Да, есть соседи для закраса

; Проверить саму точку (X,Y)
; Я не уверен счас, что этот код нужен
dec SI
dec SI
call @Check
@Found:
ret ; Вернуться из подпрограммы

; Подпрограмма @Check
; Получает в SI координату точки(смещение),
; И добавляет ее в буфер, если она нуждается в закрасе
; (Если Flag=False), а также увеличивает на 1 число найденных точек-соседей,
; Годных для закраса (в CL)
@Check:


; ВОТ ТУТ ТЕБЕ НУЖНО МЕНЯТЬ АЛГОРИТМ
; ТУТ АНАЛИЗ ЦВЕТОВ ТОЧЕК

; Получить цвет текущей точки в AL
mov AL,ES:[SI]
; Он равен цвету границы ?
cmp AL,DH
jz @Next ; Да. Точка не подходит
; Он равен цвету заливки ?
cmp AL,DL
jz @Next ; Да. Нафиг ее

; Если параметр Flag=TRue, то НЕ ДОБАВЛЯЕМ точку в буфер
cmp Flag,True
jz @NoAddPoint

; Добавляем точку в буфер ПОСЛЕДНЕЙ
mov [BP+DI],SI ; Добавить смещение точки в буфер
inc DI
inc DI
@NoAddPoint:
; Увеличить счетчик найденных точек
inc CL
@Next: ret
@Done:
; Пурга по восстановлению BP. Не обращай внимания.
add BP,Buff_Size
End;
End;
Спасиба, разобрался :0) 22.02.02 14:17  
Автор: Eniac Статус: Незарегистрированный пользователь
<"чистая" ссылка>
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2025 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach