информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Сетевые кракеры и правда о деле ЛевинаПортрет посетителяГде водятся OGRы
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Google заблокировала 2 с лишним... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Теперь и с комментариями :) 21.02.02 13:13  Число просмотров: 988
Автор: 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-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach