Для того,
чтобы можно было бы сравнить действия этих фильтров, далее будут показано
изображение, полученное путем передачи данных из УЗИ в персональный компьютер.
Исходное изображение показано на рис. 4. И в конце данного раздела будет
показано действие нескольких фильтров для отображения определенных областей на
данном изображении.
Фильтр сглаживания
используется для уменьшения общей контрастности изображения. Основной алгоритм,
использующийся в данном фильтре:
Фильтр усредненного
сглаживания используется для того, чтобы устранить дефекты изображения, могущие
появиться в процессе оцифровки. Одним из самых распространенных дефектов
является появление в темной области светлого пикселя или наоборот. Данный
дефект устраняется при помощи алгоритма:
Фильтр подчеркивания
контуров на основе матрицы 3*3 пикселя используется для отображения на
изображении областей имеющих «ярко выраженную» границу с другими областями.
Алгоритм, использующийся для получения данных областей:
Фильтр обработки полутонов
используется для построения псевдорельефа. Алгоритм используемый в данном
фильтре:
Часто
встречается ситуация, когда использование одного фильтра не дает желаемого
результата. В таких случаях бывает необходимо последовательное использование
нескольких фильтров для получения желаемого результата. В данном разделе мы
рассмотрим две комбинации последовательного использования фильтров
представленных на рис. 9 и рис. 10. На рис. 6
рассматривается комбинация фильтров: сглаживания – усредненного сглаживания
– подчеркивания контуров. На рис. 7 рассматривается комбинация
фильтров: сглаживания – усредненного сглаживания – обработки полутонов.
Реформа
системы здравоохранения обеспечила рывок в развитии диагностических служб
региональных клиник, но одновременно и привела к утере ряда несомненных
достижений советского здравоохранения. В частности практически полностью
разрушена целостность системы, в результате чего жители регионов не в состоянии
получить высококвалифицированную помощь, которая осталась сосредоточенной в
центральных московских клиниках. Развитие проекта «Телемедицина» направлено на
сохранение и усиление положительных аспектов реформ и на нивелирование
возникших негативных последствий.
Объединение клиник страны в
медицинскую информационную сеть позволит организовать взаимодействие опытных
специалистов центра с начинающими докторами регионов. Работа в этом направлении
уже начата, однако до сих пор внутригоспитальные сети, позволяющие обмениваться
информацией о больном, находятся на уровне научных разработок. До сих пор не существует
единый стандарт формирования пакета медицинской информации, включая изображения
(рентген, УЗИ, КТ
и т.п.). Только
единичные клиники работают над построением сетей, собирающих информацию.
Дипломная работа посвящена
решению задачи подключения к сети ультразвукового медицинского диагностического
аппарата ALOKA SSD - 650, на выходе которого
появляется изображение (УЗИ). Главной задачей работы была передача изображения
через локальную сеть в другую часть института. Были разработаны и реализованы
алгоритмы предварительной обработки изображений. На момент начала исследования
в Институте хирургии им. А. В. Вишневского была начата работа по прокладке
оптоволоконного кабеля между двумя зданиями: главным корпусом (в котором
расположены диагностические службы) и лаб. Кибернетики (в которой расположены
вычислительные мощности и внешние коммуникации). На сегодняшний день фрагмент
сети, обеспечивающий передачу изображений, построен, испытан и реально
функционирует.
В результате проведенного
исследования получены следующие выводы и результаты.
1. Построена система передачи
изображения из ультразвуковой диагностической установки в ПК с последующей
передачей по компьютерной сети;
2. Полученные и переданные
изображения были оценены медицинскими экспертами как адекватные;
3. Установлено, что пропускная
способность коммуникационного канала на удаленных моделях связи должна быть не
менее
64 кб/с;
4. Установлено, что разрешающая
способность при регистрации изображения должна составлять не менее 768 * 586,
при отображении серого клина разрешение должно составлять не менее 10 бит.
1.
A CASE OF
GASTROSCHISIS, Dr. German Quevedo P, Santa Cruz de la Sierra, Bolivia, June 1
st, 1997.
2.
ELEMENTS
OF SUCCESS IN TELEMEDICINE PROJECTS, Mary Moor, Ph.D., October, 1996.
3.
EUROPEAN
COMMITTE FOR STANDARDIZATION.
4.
Implementing
a Telemedicine Programm Across the Mexican-U.S. Border, 1996.
5.
TELEMEDICINE:
ITS PLACE ON THE INFORMATION HIGHWAY, Frederic Williams and Mary Moor, 1995.
6.
V.D. The
Virtual Doctor - медицинские ресурсы Internet в Санкт-Петербурге.
7.
Видеоконференции
в российских клиниках. Е. Тимин, В. Столяр, А. Сильков. Журнал «Открытые
Системы» Изд: «Открытые Системы», 1999г.
8.
Журнал
«Медицинская визуализация», Выпуски 1 – 4, издательство "ВИДАР" 1999.
9.
Журнал
Американского Международного Союза Здравоохранения, "Наше Здоровье",
Том 5, Выпуск 1, Зима 1997, Раздел "Развитие информационных
технологий", Марион Болл и Джудит Дуглас, Статья "Медицинская
информатика: там, где встречаются технология и медицина", с. 18.
10.
Журнал
Американского Международного Союза Здравоохранения, "Наше Здоровье",
Том 5, Выпуск 2, Весна 1997, Раздел "Активное сотрудничество", Статья
"Бишкек-Канзас-Сити", с. 39.
11.
Информационные
технологии в охране здоровья, Санкт-Петербург, 1997.
12.
Комплекс
ИНФОРМАЦИОННО-ВЫЧИСЛИТЕЛЬНЫХ СЕТЕЙ "Телемедицина", Проект
"КИВС-МСЧ. ТП", редакция 1, Санкт-Петербург, Февраль 1997.
13.
Программа
первоочередных мероприятий по реализации программы создания системы
телемедицинских услуг в Российской Федерации («Телемедицина»); Главный информационно-аналитический
центр при Минздраве РФ, Управление информатизации Федерального Фонда ОМС.
Москва 1998г.
14.
ТЕЛЕКОНФЕРЕНЦИЯ
GlobChat, Copyright © 1997, Julius Edlavitch M.D., В. Теплинский, Ноябрь 1997.
15.
ТЕЛЕМЕДИЦИНА
- INTERNET, Copyright © 1997, Марк Стори, В. Теплинский, Январь 1997.
16.
ТЕЛЕМЕДИЦИНА
- АМСЗ, Copyright © 1997, В. Теплинский, Февраль, 1997.
17.
Телемедицина.
Новые информационные технологии на пороге XXI века; Р. М. Юсупов, Р. И.
Полонников. – СПб.:СПИИРАН, 1998. – 486с.
18.
ФЕДЕРАЛЬНАЯ
ЦЕЛЕВАЯ ПРОГРАММА «ТЕЛЕМЕДИЦИНА»: Министерство здравоохранения Российской
Федерации. Министерство науки и технологий Российской Федерации. Москва 1997г.
19.
Физика
визуализации изображений в медицине; т. 2 под. ред. С. Уэбба. Москва, «Мир»,
1991.
Позиция
|
Название
|
Значение
|
Описание
|
0
|
n
|
360
|
Число
проекций
|
1
|
m
|
512
|
Число
отсчетов в проекции
|
2
|
nx
|
512
|
Число
элементов в строке изображения
|
3
|
ny
|
512
|
Число
строк в изображении
|
4
|
fi
|
360
|
Угол
сканирования
|
5
|
fi0
|
0
|
Начальный
угол сканирования
|
6
|
r0
|
125
|
Радиус
зоны обследования
|
7
|
ri
|
150
|
Радиус
зоны реконструкции
|
8
|
xi
|
0
|
X-координата
центра зоны реконструкции
|
9
|
yi
|
0
|
Y-координата
центра зоны реконструкции
|
10
|
l
|
110
|
Уровень
окна отображения
|
11
|
w
|
250
|
Ширина
окна отображения
|
12
|
ko
|
185
|
Номер
объекта реконструкции
|
13
|
ks
|
1
|
Номер
среза реконструкции
|
14
|
no
|
877
|
Номер
объекта визуализации
|
15
|
ns
|
5
|
Номер
среза визуализации
|
16
|
alm
|
5000
|
Мантисса
ALFA*1000
|
17
|
alex
|
-7
|
Экспонента
ALFA
|
18
|
pp
|
400
|
Порядок
регуляризации * 100
|
19
|
mk
|
9
|
m*2 =
2**mk
|
20
|
|
0
|
Тип:
0-CTSYS, 1- СРТ-1000М, 2- СТ1010
|
21
|
lstp
|
5
|
Шаг
изменения по уровню окна
|
22
|
wstp
|
20
|
Шаг
изменения по ширине окна
|
23
|
scrl
|
2
|
Шаг
при сдвиге изображения по вертикали
|
24
|
ybig
|
0
|
Начальный
номер строки отображения
|
25
|
rd
|
0
|
Расстояние
от центра до фокуса в мм/10
|
26
|
nj
|
480
|
Число
измеряемых проекций
|
27
|
mj
|
384
|
Число
измеряемых отсчетов
|
28
|
nkad
|
32
|
Число
кадров в фильме
|
29
|
nsl
|
100
|
Число
срезов для 3D визуализации
|
30
|
xw1
|
20
|
Левая
X-координата
|
31
|
yw1
|
65
|
Верхняя
Y-координата
|
32
|
xw2
|
147
|
Правая
X-координата
|
33
|
yw2
|
192
|
Нижняя
Y-координата
|
34
|
hz
|
10
|
Шаг
между слоями в мм
|
35
|
max
|
8000
|
Максимум
|
36
|
min
|
80
|
Минимум
|
40
|
surf
|
20
|
Порог
плотности для выделения 3d-поверхности
|
41
|
tr
|
3500
|
Время
повторения
|
42
|
te
|
150
|
неизменяемый
параметр
|
43
|
ti
|
0
|
Время
инверсии
|
44
|
nsli
|
9
|
Количество
срезов на томограмме
|
45
|
acc
|
4
|
Количество
накоплений
|
46
|
fov
|
300
|
Поле
обзора
|
47
|
matx
|
252
|
X
матрицы
|
48
|
maty
|
252
|
Y
матрицы
|
49
|
|
1
|
|
50
|
|
7
|
|
51
|
pmin
|
-140
|
Минимум
для обрезки перед упаковкой
|
52
|
pmax
|
220
|
Максимум
для обрезки перед упаковкой
|
53
|
ncic
|
0
|
Количество
полос длинной картинки минус 1
|
54
|
yloc
|
0
|
Количество
строк полной полосы
|
60
|
sh2s
|
180
|
Сдвиг
для второго слоя в микронах
|
61
|
sfd
|
6
|
Число
сдвигов для прямого БПФ
|
62
|
nfd
|
1
|
(*10)
Делитель для спектра
|
63
|
nfl
|
480
|
(*10)
Делитель спектр*фильтр
|
64
|
sfi
|
6
|
Число
сдвигов обратного БПФ
|
65
|
nfi
|
7
|
(*10)
Делитель свернутых проекций
|
66
|
imgn
|
300
|
(*10)
Делитель для изображения
|
67
|
?
|
360
|
Так
надо ???
|
70
|
hx0
|
|
x0 -
координаты прямоугольника обрезки (печать)
|
71
|
hy0
|
13
|
y0
|
72
|
hx1
|
47
|
x1
|
73
|
hy1
|
217
|
y1
|
74
|
|
242
|
|
75
|
|
128
|
|
76
|
|
40
|
|
77
|
|
128
|
|
78
|
|
40
|
|
79
|
|
12
|
|
80
|
|
88
|
|
81
|
|
230
|
|
82
|
|
190
|
|
83
|
|
128
|
|
84
|
|
125
|
|
85
|
|
128
|
|
86
|
sque
|
142
|
Параметр
квадрата
|
89
|
|
3
|
Нач.
отсчет (для теста каналов)
|
90
|
|
568
|
Кон.
отсчет (для теста каналов)
|
91
|
|
6
|
Число
отсчетов в калибровочных зонах
|
92
|
|
39
|
Рабочая
зона детектора 1 и 9
|
93
|
|
46
|
2 и
10
|
94
|
|
53
|
3 и
11
|
95
|
|
60
|
96
|
|
67
|
5 и
13
|
97
|
|
74
|
6 и
14
|
98
|
|
81
|
7 и
15
|
99
|
|
88
|
8 и
16
|
100
|
|
527
|
Калибровочная
зона детектора 1
|
101
|
|
534
|
2
|
102
|
|
541
|
3
|
103
|
|
548
|
4
|
104
|
|
9
|
5
|
105
|
|
16
|
6
|
106
|
|
23
|
7
|
107
|
|
30
|
8
|
108
|
|
513
|
Темновая
зона детектора 1
|
109
|
|
520
|
2
|
110
|
|
527
|
3
|
111
|
|
534
|
4
|
112
|
|
542
|
5
|
113
|
|
549
|
6
|
114
|
|
556
|
7
|
115
|
|
563
|
8
|
116
|
|
28
|
mA
|
117
|
|
0
|
Угол
топограммы (0-359)
|
118
|
|
0
|
Длина
топограммы (512/256)
|
119
|
|
4590
|
Полная
доза, mAs
|
120
|
|
120
|
Число
пикселей в 10 см.
|
121
|
|
4620
|
Время
сканирования (сек.*10)
|
122
|
|
60
|
Доза,
mAs
|
123
|
|
120
|
Напряжение
,kV
|
124
|
|
4
|
Наклон
плоскости сканирования в градусах
|
125
|
|
8
|
Толщина
слоя в мм.
|
126
|
|
22
|
Позиция
стола пациента в мм. от начала
|
127
|
|
410
|
Тип
системы
|
#include <stdio.h>
#include
<stdlib.h>
#include
<string.h>
#include <math.h>
#include
<catwinds.h>
#include
<bfiles.h>
#include
<bytemap.h>
#include
<groupwrd.h>
#include <forma.h>
#include <scale.h>
#include
<groupcel.h>
#include
"color.h"
#include
"vectlib.h"
#include
"winds.h"
#include
"win2d.h"
#include
"3d.h"
#include
"filtr.h"
#include
"config.h"
#include
"ctmenu.h"
#include
"setup.h"
#include
"measure.h"
#include
"ct.h"
#include
"ct_ext.h"
#include
"console.h"
#include
"language.h"
#define POROG
(GRAY_BASE+GRAY_LVLS*4/5)
extern int
ExistWindow(WinHandle w);
extern WinHandle
MainControl;
extern WinHandle
H3d_view;
extern void InvRect(int
x0, int y0, int x1, int y1, WinHandle w, char *s);
extern void
redraw_window(WinHandle w);
extern void
redraw_cw(WinHandle w);
extern void
SetupLUT(DWIND *winds);
extern void
Screen_Save(void);
extern Rect
correct_rect(Rect r);
extern Rect
Set_Rect(WinHandle w);
extern Rect
Set_Sqr(WinHandle w);
extern void
cell_to_pcx(char *pcx_name, GCHandle ch,
int xmax, int ymax, char *pallet);
/***********************************************************/
void
Do_AddSub_Img(WinHandle w, int fl_sub)
{ GWHandle chl;
HFILE img_fil,tmp_fil;
long *L,*L1;
int
*p,*p1,*p2,*p0,*pp,k,i,j,jz,nx,ny,*pq;
char *hc,*c,name[81];
char *s;
unsigned char
*uhc,*pc;
Win2d *ud = h_data(w);
if(!ud->img_name ||
!ud->ch) return;
if(ud->frag)
return;
chl = ud->ch;
s = GetFileName(GetCfgItem("image"),H_CREATE);
if (*s == 0) return;
img_fil =
HOpen(s,H_READ); if (img_fil == 0) return;
HLocate(img_fil,0l,2048); p = HPosit(img_fil);
L = (long*)p; nx =
L[2]; ny = L[3]; ud = h_data(w);
if(nx != ud->iw) {
HClose(img_fil); return;}
if(ny != ud->ih) {
HClose(img_fil); return;}
if (chl == 0) {
HClose(img_fil); return;}
ud = h_data(w);
uhc =
(char*)&p[256+128];
if(uhc[249] !=
2-ud->ps) return;
if(ud->scale2d ==
1)
{
pp =
h_malloc(nx*4);
pq = h_malloc(nx*4);
for (j = 0; j <
ny; j++)
{ ud =
h_data(w);
if(ud->ps
== 2)
{
HLocate(img_fil,(long)j*nx*2+2048L,nx*2); p = HPosit(img_fil);
}
else
{
HLocate(img_fil,(long)j*nx+2048L,nx); pc = HPosit(img_fil);
for(i = 0;
i < nx; i++) pq[i] = (int)pc[i];
p = pq;
}
GetGWL(chl,(short*)pp,nx,j);
for(i = 0; i
< nx; i++)
if(fl_sub)
pp[i] = (pp[i]-2048 - p[i])/2 + 2048;
pp[i]
= (pp[i]-2048 + p[i])/2 + 2048;
PutGWL(chl,(short*)pp,nx,j);
}
h_mfree(pp);
h_mfree(pq);
}
else
{ p1 =
h_malloc(nx*4); p2 = h_malloc(nx*4);
p0 =
h_malloc(nx*4); pp = h_malloc(nx*4);
// Image interpolation
HLocate(img_fil,2048l,nx*2);
p =
(int*)HPosit(img_fil);
for (i = 0, k = 0;
i < nx-1; i++, k += 2)
{ p1[k] = p[i];
p1[k+1] = (p[i]+p[i+1])/2;
}
p1[k] = p[i];
for (j = 0, jz =
0; j < ny-1; j++, jz += 2)
{ // Write 1
line
GetGWL(chl,(short*)pp,nx*2-1,jz);
for(i = 0; i
< nx*2-1; i++)
if(fl_sub)
pp[i] = (pp[i]-2048 - p1[i])/2 + 2048;
pp[i] = (pp[i]-2048 + p1[i])/2 + 2048;
PutGWL(chl,(short*)pp,nx*2-1,jz);
//Read 2 line
HLocate(img_fil,(long)(j+1)*nx*2+2048l,nx*2);
p =
(int*)HPosit(img_fil);
for (i = 0, k
= 0; i < nx-1; i++, k += 2)
{ p2[k] =
p[i]; p2[k+1] = (p[i]+p[i+1])/2;
}
p2[k] = p[i];
for (i = 0; i
< nx*2-1; i++) p0[i] = (p1[i]+p2[i])/2;
// Write 2
line
GetGWL(chl,(short*)pp,nx*2-1,jz+1);
for(i = 0; i
< nx*2-1; i++)
if(fl_sub)
pp[i] = (pp[i]-2048 - p1[i])/2 + 2048;
pp[i] = (pp[i]-2048 + p0[i])/2 + 2048;
PutGWL(chl,(short*)pp,nx*2-1,jz+1);
// Line2 to
Line1
for (i = 0; i
< nx*2-1; i++) p1[i] = p2[i];
}
GetGWL(chl,(short*)pp,nx*2-1,jz);
for(i = 0; i
< nx*2-1; i++)
if(fl_sub)
pp[i] = (pp[i]-2048 - p1[i])/2 + 2048;
pp[i] = (pp[i]-2048 + p1[i])/2 + 2048;
PutGWL(chl,(short*)pp,nx*2-1,jz);
h_mfree(p1);
h_mfree(p2); h_mfree(p0); h_mfree(pp);
}
HClose(img_fil);
ud = h_data(w);
ud->x0 =
(ud->iw-ud->w)/2; // Центровка
ud->y0 =
(ud->ih-ud->h)/2; // изображения
redraw_cw(w);
}
/***********************************************************/
void Do_Inversion(WinHandle
w)
{ int i,k; int
imin,imax;
Win2d *ud = h_data(w);
WinCon *udc;
DWIND *p =
&ud->dw[0];
if(!ud->img_name ||
!ud->ch) return;
if (p->on) {
if(p->neg) p->neg = 0; else p->neg = 1;
if(!ExistWindow(H3d_view))
{ udc =
h_data(MainControl);
udc->inv_prn = p->neg;
}
}
SetupLUT(ud->dw);
redraw_cw(w);
}
/***********************************************************/
// Image filtration
functions
static void inch(int *u,int
*v)
{int temp;
temp=*u; *u=*v; *v=temp;
}
static int f9(int *mf)
{
int *max,i,j;
for(i = 0;i < 9; i++)
{max=&mf[i];
for(j = i+1;j < 9;
j++) if(*max < mf[j]) max = &mf[j];
if(max != &mf[i])
inch(max,&mf[i]);
}
return(mf[4]);
}
static int f1(int *mf)
{long s;
s=(long)mf[0]+2*(long)mf[1]+(long)mf[2]+2*(long)mf[3]
+4*(long)mf[4]+2*(long)mf[5]+(long)mf[6]+2*(long)mf[7]+(long)mf[8];
return(s/16);
}
static int f2(int *mf)
{long s;
s=(long)mf[0]+(long)mf[1]+(long)mf[2]+(long)mf[3]
+(long)mf[5]+(long)mf[6]+(long)mf[7]+(long)mf[8];
return(s/8);
}
static int f3(int *mf)
{long r1,r2;
r1 =
(long)mf[0]+(long)mf[1]+(long)mf[2]-(long)mf[6]-(long)mf[7]-(long)mf[8];
r1 = r1*r1;
r2 =
(long)mf[0]+(long)mf[3]+(long)mf[6]-(long)mf[2]-(long)mf[5]-(long)mf[8];
r2 = r2*r2;
return((int)(2.0*sqrt((double)(r1+r2))));
}
static int f4(int *mf)
{return( mf[4]);
}
static int f5(int *mf)
{long s;
s=(-2*(long)mf[0]+(long)mf[1]-2*(long)mf[2]+(long)mf[3]
+6*(long)mf[4]+(long)mf[5]-2*(long)mf[6]+(long)mf[7]-2*(long)mf[8])/2;
return((int)s);
}
static int f6(int *mf)
{int e,s;
s = f1(mf); e = mf[4];
if((2*e - s) > 30) e
= 2*e - s;
else e =
s;
return(e);
}
static int f7(int *mf)
{long s;
s=-(long)mf[0]-(long)mf[1]-(long)mf[2]+(long)mf[3]
+3*(long)mf[4]-(long)mf[5]+(long)mf[6]+(long)mf[7]-(long)mf[8];
return((int)s);
}
static int f8(int *mf)
{long s;
s=((long)mf[0]+(long)mf[1]+(long)mf[2]+(long)mf[3])/4;
return((int)s);
}
static int f10(int *mf)
{return( mf[4]);
}
static void filt(int
*p1,int *p2,int *p3,int *po,int str,int nfilt)
{
int mf[9],i,tr;
str=str-1; tr=str-1;
mf[0]=*(p1+str);mf[1]=*p1;mf[2]=*(p1+1);
mf[3]=*(p2+str);mf[4]=*p2;mf[5]=*(p2+1);
mf[6]=*(p3+str);mf[7]=*p3;mf[8]=*(p3+1);
switch (nfilt)
{ case 1:
*po=f1(mf); break;
case 2:
*po=f2(mf); break;
case 3:
*po=f3(mf); break;
case 4:
*po=f4(mf); break;
case 5:
*po=f5(mf); break;
case 6:
*po=f6(mf); break;
case 7:
*po=f7(mf); break;
case 8: *po=f8(mf);
break;
case 9:
*po=f9(mf); break;
case 10:
*po=f10(mf); break;
}
for(i = 0; i < tr;
i++)
{mf[0] = *(p1+i);
mf[1] = *(p1+i+1); mf[2] = *(p1+i+2);
mf[3] = *(p2+i);
mf[4] = *(p2+i+1); mf[5] = *(p2+i+2);
mf[6] = *(p3+i);
mf[7] = *(p3+i+1); mf[8] = *(p3+i+2);
switch (nfilt)
{ case 1:
*(po+i+1) = f1(mf); break;
case 2:
*(po+i+1) = f2(mf); break;
case 3:
*(po+i+1) = f3(mf); break;
case 4:
*(po+i+1) = f4(mf); break;
case 5:
*(po+i+1) = f5(mf); break;
case 6:
*(po+i+1) = f6(mf); break;
case 7:
*(po+i+1) = f7(mf); break;
case 8:
*(po+i+1) = f8(mf); break;
case 9:
*(po+i+1) = f9(mf); break;
case 10:
*(po+i+1) = f10(mf); break;
}
}
mf[0]=*(p1+tr);mf[1]=*(p1+str);mf[2]=*p1;
mf[3]=*(p2+tr);mf[4]=*(p2+str);mf[5]=*p2;
switch (nfilt)
{ case 1:
*(po+str)=f1(mf); break;
case 2:
*(po+str)=f2(mf); break;
case 3:
*(po+str)=f3(mf); break;
case 4:
*(po+str)=f4(mf); break;
case 5:
*(po+str)=f5(mf); break;
case 6:
*(po+str)=f6(mf); break;
case 7:
*(po+str)=f7(mf); break;
case 8:
*(po+str)=f8(mf); break;
case 9:
*(po+str)=f9(mf); break;
case 10:
*(po+str)=f10(mf); break;
}
}
void
Do_Filters(WinHandle w, int nfilt)
{ GWHandle chl;
int i,k;
int
*po,*p1,*p2,*p3,*p4,*p5,*pn,iw,ih;
double d1,d2;
Win2d *ud = h_data(w);
if ((chl = ud->ch)
== 0) return;
iw=ud->iw;
ih=ud->ih;
if(nfilt == 10)
{
po =
(int*)h_malloc(iw*2); pn = (int*)h_malloc(iw*2);
p1 =
(int*)h_malloc(iw*2); p2 = (int*)h_malloc(iw*2);
p3 =
(int*)h_malloc(iw*2); p4 = (int*)h_malloc(iw*2);
p5 =
(int*)h_malloc(iw*2);
i = 2;
GetGWL(chl,(short*)p1,iw,i-2);
for(k = 0; k <
iw; k++) p1[k] = p1[k]-2048;
GetGWL(chl,(short*)p2,iw,i-1);
for(k = 0; k <
iw; k++) p2[k] = p2[k]-2048;
GetGWL(chl,(short*)p3,iw,i);
for(k = 0; k <
iw; k++) p3[k] = p3[k]-2048;
GetGWL(chl,(short*)p4,iw,i+1);
for(k = 0; k <
iw; k++) p4[k] = p4[k]-2048;
for( i =2; i <
ih-2; i++)
{
GetGWL(chl,(short*)p5,iw,i+2);
for(k = 0; k <
iw; k++) p5[k] = p5[k]-2048;
for(k = 2; k <
iw-2; k++)
{
d1 = p1[k-2] -
p5[k+2]; d1 = d1*d1;
d2 = p5[k-2] -
p1[k+2]; d2 = d2*d2;
po[k] =
(int)sqrt(d1+d2)+2048;
}
for(k = 0; k <
iw; k++) p1[k] = p2[k];
for(k = 0; k <
iw; k++) p2[k] = p3[k];
for(k = 0; k <
iw; k++) p3[k] = p4[k];
for(k = 0; k <
iw; k++) p4[k] = p5[k];
PutGWL(chl,(short*)po,iw,i);
}
h_mfree(pn);
h_mfree(po); h_mfree(p1); h_mfree(p2); h_mfree(p3);
h_mfree(p4);
h_mfree(p5);
redraw_cw(w);
return;
}
if(nfilt == 4)
{
}
po =
(int*)h_malloc(iw*2); pn = (int*)h_malloc(iw*2);
p1 =
(int*)h_malloc(iw*2); p2 = (int*)h_malloc(iw*2);
p3 =
(int*)h_malloc(iw*2);
i = 1;
GetGWL(chl,(short*)p1,iw,i-1);
for(k = 0; k < iw;
k++) p1[k] = p1[k]-2048;
GetGWL(chl,(short*)p2,iw,i);
for(k = 0; k < iw;
k++) p2[k] = p2[k]-2048;
for( i =1; i < ih-1;
i++)
{
GetGWL(chl,(short*)p3,iw,i+1);
for(k = 0; k < iw;
k++) p3[k] = p3[k]-2048;
filt(p1,p2,p3,po,iw,nfilt);
// memcpy(p1,p2,iw);
memcpy(pn,p3,iw);
for(k = 0; k < iw;
k++) p1[k] = p2[k];
for(k = 0; k < iw;
k++) pn[k] = p3[k];
for(k = 0; k < iw;
k++) po[k] = po[k]+2048;
PutGWL(chl,(short*)po,iw,i);
// memcpy(p2,pn,iw);
for(k = 0; k < iw;
k++) p2[k] = pn[k];
}
h_mfree(pn);
h_mfree(po); h_mfree(p1); h_mfree(p2); h_mfree(p3);
redraw_cw(w);
}
/***********************************************************/
void
Do_Scale_Rotate(WinHandle w)
{ int i,k;
int nx,ny,ix,iy;
int *po;
int q1,q2,q3,q4;
double angle;
double
hi,hi_t,x,y,u,v,si,co,dx,dy;
double cox = 65536.0;
long
cx,cy,cx1,cy1,s1,s2;
long
lx,ly,ldx,ldy,lix,liy;
unsigned char *pc,s,p;
IJ ij;
GWHandle ch,chol;
Win2d *ud = h_data(w);
if ((chol=ud->ch)
== 0) return;
angle =
3.14159265*ud->angle/180.0;
hi =
1.0/ud->iw; hi_t = hi/ud->scale;
nx =
ud->scale*ud->iw; ny = ud->scale*ud->ih;
si =
sin(angle); co = cos(angle);
u =
-hi_t*(nx/2.0); v = -hi_t*(ny/2.0 - 1);
dx =
hi_t*co/hi; dy = hi_t*si/hi;
ldx=
cox*dx; ldy = cox*dy;
po =
(int*)h_malloc(nx*sizeof(int));
ch =
NewGW(f_create("rout.tmp",F_CREATE_NORMAL),0);
for( i = 0; i < ny;
i++)
{v+= hi_t;
lx = cox*( u*co -
v*si + hi_t*(nx/2.0) )/hi;
ly = cox*( u*si +
v*co + hi_t*(ny/2.0) )/hi;
for(k = 0; k <
nx; k++)
{
ix = lx >>
16; lx+= ldx;
iy = ly >>
16; ly+= ldy;
liy = iy; liy =
liy << 16;
cy = ly - liy;
cy1= 65537L -
cy;
lix = ix; lix =
lix << 16;
cx = lx - lix;
cx1= 65537L -
cx;
ij.i = ix;
ij.j = iy; GetGWA(chol, (short*)&q1, 1, &ij);
ij.i = ix+1;
ij.j = iy; GetGWA(chol, (short*)&q2, 1, &ij);
ij.i = ix;
ij.j = iy+1; GetGWA(chol, (short*)&q3, 1, &ij);
ij.i = ix+1;
ij.j = iy+1; GetGWA(chol, (short*)&q4, 1, &ij);
s1 =
((long)q1*cx1+(long)q2*cx) >> 16;
s1 =
(s1*cy1)>>16;
s2 =
((long)q3*cx1 + (long)q4*cx) >> 16;
s2 =
(s2*cy)>>16;
po[k] = s1+s2;
}
PutGWL(ch,
(short*)po, nx, i);
}
h_mfree(po);
if (chol)
DisposeGW(chol);
ud = h_data(w);
ud->ch = ch;
ud->iw = nx;
ud->ih = ny;
ud->x0 =
(ud->iw-ud->w)/2; // Центровка
ud->y0 =
(ud->ih-ud->h)/2; // изображения
redraw_window(w);
}
// зеркальное
отображение
void Do_Mirrow(WinHandle
w)
{ int i,j,vol;
int nx,ny;
int *po;
GWHandle ch;
Win2d *ud = h_data(w);
if ((ch=ud->ch) ==
0) return;
nx = ud->iw;
ny = ud->ih;
po =
(int*)h_malloc(nx*sizeof(int));
for( i = 0; i < ny;
i++)
{ GetGWL(ch,
(short*)po, nx, i);
for(j=0;j<nx/2;j++)
{ vol = po[j];
po[j] = po[nx-j-1]; po[nx-j-1] = vol;
}
PutGWL(ch,
(short*)po, nx, i);
}
h_mfree(po);
ud = h_data(w);
ud->flef^=1;
redraw_cw(w);
}
static void
Do_ResZo(WinHandle w, int nxi, int nyi, int reszo, int type)
{ int i,k;
int
nx,ny,ix,iy,new_nx,new_ny,x0,y0;
int *po;
int q1,q2,q3,q4;
double x,y,dx,dy;
long
cx,cy,cx1,cy1,s1,s2;
double sc_x,sc_y,cox =
65536.0;
long
lx,ly,ldx,ldy,lix,liy;
unsigned char *pc,s,p;
IJ ij;
GWHandle ch,chol;
Rect r;
Rect wr = WorkRect(w);
Win2d *ud = h_data(w);
if ((chol=ud->ch)
== 0) return;
if(reszo)
{ nx=nxi; ny=nyi;
new_nx = ud->iw;
new_ny = ud->ih;
if(new_nx==nx
&& new_ny==ny) return;
}
else
{
r = type ?
Set_Rect(w) : Set_Sqr(w);
if(r.x0 == -1)
return;
new_nx =
r.x1-r.x0+1; new_ny = r.y1-r.y0+1;
ud = h_data(w);
sc_x =
(double)ud->iw/new_nx;
sc_y =
(double)ud->ih/new_ny;
if( sc_x < sc_y)
{ nx = ud->iw;
ny = new_ny*sc_x;
if(ny%2) ny--;
ud->scale = sc_x;
}
else
{ ny = ud->ih;
nx = new_nx*sc_y;
if(nx%2) nx--;
ud->scale = sc_y;
}
}
OnScale(wr.x0,wr.y0);
dx =
(double)new_nx/(double)nx;
dy =
(double)new_ny/(double)ny;
ldx= cox*dx; ldy =
cox*dy;
po =
(int*)h_malloc(nx*sizeof(int));
if(reszo)
x0 = y0 = 0;
else
{ ud = h_data(w);
x0 =
r.x0-wr.x0+ud->x0;
y0 =
r.y0-wr.y0+ud->y0;
}
ch =
NewGW(f_create("rout.tmp",F_CREATE_NORMAL),0);
ly = cox*y0;
for( i = 0; i < ny;
i++)
{
lx = cox*x0;
ly+= ldy;
iy = ly>>16;
liy = iy; liy = liy
<< 16;
cy = ly - liy;
cy1= 65537L - cy;
for(k = 0; k <
nx; k++)
{
lx+= ldx;
ix =
lx>>16;
ij.i = ix;
ij.j = iy; GetGWA(chol, (short*)&q1, 1, &ij);
ij.i = ix+1;
ij.j = iy; GetGWA(chol, (short*)&q2, 1, &ij);
ij.i = ix;
ij.j = iy+1; GetGWA(chol, (short*)&q3, 1, &ij);
ij.i = ix+1;
ij.j = iy+1; GetGWA(chol, (short*)&q4, 1, &ij);
lix = ix; lix =
lix << 16;
cx = lx - lix;
cx1= 65537L -
cx;
s1 =
((long)q1*cx1+(long)q2*cx) >> 16;
s1 =
(s1*cy1)>>16;
s2 =
((long)q3*cx1 + (long)q4*cx) >> 16;
s2 =
(s2*cy)>>16;
po[k] = s1+s2;
}
PutGWL(ch,
(short*)po, nx, i);
DoneVisSave((int)((i+1)*100.0/ny+0.5));
}
h_mfree(po);
if (chol)
DisposeGW(chol);
ud = h_data(w);
ud->ch = ch;
ud->r0 =
(double)ud->r0*(double)new_nx/ud->iw;
ud->iw = nx;
ud->ih = ny;
ud->x0 =
(ud->iw-ud->w)/2; // Центровка
ud->y0 =
(ud->ih-ud->h)/2; // изображения
OffScale();
if(reszo)
redraw_window(w);
else
{ if (ud->size_big)
SetRectShape(w,&CommonRect);
else
SetRectShape(w,&ud->own_size);
redraw_cw(w);
}
}
void Do_Zoom(WinHandle
w, int type)
{
Do_ResZo(w,0,0,0,type);
}
void
Do_Resemple(WinHandle w, int nx, int ny, int type)
{
Do_ResZo(w,nx,ny,1,type);
}
/***********************************************************/
typedef unsigned char
BYTE;
typedef unsigned int
WORD;
typedef unsigned long
DWORD;
typedef struct
tagBITMAPFILEHEADER
{ WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct
tagBITMAPINFOHEADER
{ DWORD biSize;
long biWidth;
long biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD
biCompression;
DWORD biSizeImage;
long
biXPelsPerMeter;
long
biYPelsPerMeter;
DWORD biClrUsed;
DWORD
biClrImportant;
} BITMAPINFOHEADER;
void Fr_Save(WinHandle
w, int select)
{ int
i,k,x,y,x1,y1,nx,ny,format,ii,fin;
BYTE rr,gg,bb;
Rect r;
BYTE
*filp,*pallet,*pal;
GCHandle ch;
Win2d *ud = h_data(w);
USGC *s;
BITMAPFILEHEADER
*hfile;
BITMAPINFOHEADER
*hinfo;
long hi;
Rect wr = WorkRect(w);
int L = wr.x1 - wr.x0
+ 1;
int H = wr.y1 - wr.y0
+ 1;
if(ud->r0<500
&& ud->r0>10)
hi =
100.0/(0.2*(double)ud->r0/(double)(ud->iw-1));
else hi = 0l;
if(!ud->img_name ||
!ud->ch) return;
// BringToFront(w);
VisSetWin(w); // ?????
format = 0;
if(select == 0)
{r = Set_Rect(w);
if(r.x0 < 0) return;
redraw_window(w);
}
else if(select == 1)
{r.x0 = wr.x0; r.y0
= wr.y0; r.x1 = wr.x1; r.y1 = wr.y1;}
else if(select == 2)
{
if((ud->iw >
L) || (ud->ih > H))
{r.x0 = wr.x0;
r.y0 = wr.y0; r.x1 = wr.x1; r.y1 = wr.y1;}
else
{ r.x0 =
wr.x0-ud->x0; r.y0 = wr.y0-ud->y0;
r.x1 = r.x0 +
ud->iw-1; r.y1 = r.y0 + ud->ih-1;
}
}
else return;
nx = r.x1-r.x0+1; ny =
r.y1-r.y0+1;
if(nx%4) { nx-=nx%4;
r.x0++; }
if(ny%2) { ny--;
r.y0++; }
i =
InputForm(mesman,&format);
if (i != 1) return;
s = h_malloc(4096);
if(!s) return;
if(format == 2) // BMP
save
{
hfile
=h_malloc(sizeof(BITMAPFILEHEADER));
hinfo
=h_malloc(sizeof(BITMAPINFOHEADER));
// Select name and open
BMP file
filp =
GetFileName(GetCfgItem("bmp"),H_CREATE);
if (*filp == 0)
{h_mfree(s); h_mfree(hfile); h_mfree(hinfo); return;}
if ((fin =
f_create(filp, F_CREATE_NORMAL)) == -1)
{h_mfree(s);
h_mfree(hfile); h_mfree(hinfo); return;}
// Save BITMAPFILEHEADER
hfile->bfType
= 0x4D42; // BM - символы идентифицирующие формат
hfile->bfReserved1 = 0;
hfile->bfReserved2 = 0;
hfile->bfOffBits = sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)+1024L;
// смещение начала
собственно битового массива в байтах
f_write(fin, hfile,
sizeof(BITMAPFILEHEADER));
// Save BITMAPIMFOHEADER
hinfo->biSize = (long)sizeof(BITMAPINFOHEADER);
hinfo->biWidth
= (long)nx;
// кратно
long-ам (если надо, добавить нули)
hinfo->biHeight = (long)ny;
hinfo->biPlanes = 1;
hinfo->biBitCount = 8;
hinfo->biCompression = 0L;
hinfo->biSizeImage = 0L;
hinfo->biXPelsPerMeter = hi;
hinfo->biYPelsPerMeter = hi;
hinfo->biClrUsed = 0L; // к-во цветов в таблице цветности
hinfo->biClrImportant = 0L; // обязательное к-во цветов
f_write(fin, hinfo,
sizeof(BITMAPINFOHEADER));
// Save PALLETE
pallet =
h_malloc(1024); pal = pallet;
for(ii=0;
ii<256; ii++)
{
g_get_pal((USGC)ii,&rr,&gg,&bb);
*pal++ = rr*4;
*pal++ = gg*4; *pal++ = bb*4; *pal++ = 0;
}
f_write(fin,
pallet, 1024);
h_mfree(pallet);
// Save BITMAP
for(y=r.y1;
y>=r.y0; y--)
{ for(x=r.x0,k=0;
x<=r.x1; x++,k++)
{ s[k] =
g_point(x, y, 0); g_point(x, y, s[k]);}
f_write(fin, s,
nx);
}
f_close(fin);
h_mfree(hfile); h_mfree(hinfo);
}
else if(format == 0)
// IMG save
{
filp =
GetFileName(GetCfgItem("frag"),H_CREATE);
if (*filp == 0) {
h_mfree(s); return;}
if ((fin =
f_create(filp, F_CREATE_NORMAL)) == -1) {h_mfree(s); return;}
f_write(fin,
&nx, sizeof(int)); f_write(fin, &ny, sizeof(int));
for(y=r.y0;
y<=r.y1; y++)
{ for(x=r.x0,k=0;
x<=r.x1; x++,k++)
{ s[k] =
g_point(x, y, 0); g_point(x, y, s[k]);
}
f_write(fin, s,
nx);
}
f_close(fin);
ShowCursor(x,y,CURT_HAND);
}
else if(format == 1)
// PCX save
{ if ((fin =
f_create("frag.tmp", F_CREATE_NORMAL)) == -1)
{h_mfree(s);
return;}
ch = NewGC(fin,0);
pallet =
h_malloc(768);
for(y=r.y0,i = 0;
y<=r.y1; y++,i++)
{ for(x=r.x0,k=0;
x<=r.x1; x++,k++)
{ s[k] =
g_point(x, y, 0); g_point(x, y, s[k]);}
PutGCL(ch, s,
nx, i);
}
pal = pallet;
for(ii=0;
ii<256; ii++)
{
g_get_pal((USGC)ii,&rr,&gg,&bb);
*pal++ = rr*4;
*pal++ = gg*4;
*pal++ = bb*4;
}
filp =
GetFileName(GetCfgItem("pcx"),H_CREATE);
if (*filp)
cell_to_pcx(filp,
ch, nx, ny, pallet);
h_mfree(pallet);
DisposeGC(ch);
f_delete("frag.tmp");
}
h_mfree(s);
}
void PCX_Save(WinHandle
w)
{ int
i,k,x,y,x1,y1,nx,ny,ii,fin;
USGC rr,gg,bb;
Rect r;
USGC
*filp,*pallet,*pal;
GCHandle ch;
Win2d *ud;
USGC
*s,*s1,name[13],ss[81];
Rect wr = WorkRect(w);
ud = h_data(w);
if(!ud->img_name || !ud->ch) return;
r.x0 = wr.x0; r.y0 =
wr.y0; r.x1 = wr.x1; r.y1 = wr.y1;
nx = r.x1-r.x0+1; ny =
r.y1-r.y0+1;
if(nx%2) { nx--;
r.x0++; }
if(ny%2) { ny--;
r.y0++; }
s = h_malloc(1024);
if(!s) return;
// PCX save
if ((fin =
f_create("frag.tmp", F_CREATE_NORMAL)) == -1)
{h_mfree(s);
return;}
ch = NewGC(fin,0);
pallet =
h_malloc(768);
for(y=r.y0,i = 0;
y<=r.y1; y++,i++)
{ for(x=r.x0,k=0;
x<=r.x1; x++,k++)
{ s[k] =
g_point(x, y, 0); g_point(x, y, s[k]);}
PutGCL(ch, s,
nx, i);
}
pal = pallet;
for(ii=0;
ii<256; ii++)
{
g_get_pal((USGC)ii,&rr,&gg,&bb);
*pal++ = rr*4;
*pal++ = gg*4;
*pal++ = bb*4;
}
strcpy(ss,GetCfgItem("pcx"));
if(*ss != 0)
{ s1=strrchr(ss,'\\');
if(!s1) return ; else { s1++; *s1=0; }
}
ud = h_data(w);
sprintf(name,"%ld-%d.pcx",ud->no,ud->ns);
strcat(ss,name);
if (*ss)
cell_to_pcx(ss, ch, nx, ny, pallet);
h_mfree(pallet);
DisposeGC(ch);
f_delete("frag.tmp");
h_mfree(s);
}
void Fr_Load(WinHandle
w)
{ GWHandle chl;
int
i,k,x,y,x1,y1,nx,ny;
Rect r; EventRecord
e;
char
name[81],s[81],*s1;
int *pi;
unsigned char
*c,*pc,*p,*pp;
int fin;
char *filp;
Win2d *ud = h_data(w);
filp =
GetFileName(GetCfgItem("frag"),H_READ);
if (*filp == 0)
return;
if ((fin =
f_open(filp, F_OPEN_READ)) == -1) return;
f_read(fin, &nx,
sizeof(int)); f_read(fin, &ny, sizeof(int));
get_ct_handle(w, ct);
get_ctsys();
ct->l[2] = nx;
ct->l[3] = ny;
ct->b[249] = 1;
ud = h_data(w);
ud->iw = nx;
ud->ih = ny;
ud->ps = 1;
ud->frag = 1;
ud->objtype = 0;
// GW file name
definition
strcpy(name,GetCfgItem("image"));
pc =
name+strlen(name); while (pc > name && pc[-1] != '\\') pc--;
sprintf(pc,"w%d.tmp",ud->temp_name);
if (ud->ch) {
DisposeGW(ud->ch); f_delete(name); }
ud->ch =
NewGW(f_create(name,F_CREATE_NORMAL),0);
chl = ud->ch;
p = h_malloc(nx); pi
= (int*)h_malloc(nx*2);
for( k = 0; k < ny;
k++)
{f_read(fin, p, nx);
for (i = 0; i <
nx; i++) pi[i] = (int)p[i]+2048;
PutGWL(chl,(short*)pi,nx,k); // Write to GW file
}
h_mfree(p);
h_mfree(pi);
VisSetWin(w);
strcpy(s,filp);
ud = h_data(w);
if(!ud->img_old
&& ud->img_name)
{ int len = strlen(h_data(ud->img_name));
ud->img_old =
h_alloc(len+1);
ud = h_data(w);
strcpy(h_data(ud->img_old),h_data(ud->img_name));
}
if(ud->img_name)
{ if
(ud->tempimg) f_delete(h_data(ud->img_name)); h_free(ud->img_name);
}
else h_free(ud->win.title);
ud = h_data(w);
ud->img_name =
h_alloc(strlen(s)+1);
ud = h_data(w);
strcpy(h_data(ud->img_name),s);
ud->tempimg = 0;
ud->win.title =
ud->img_name;
PaintTitle(w);
ud->x0 =
(ud->iw-ud->w)/2; // Центровка
ud->y0 =
(ud->ih-ud->h)/2; // изображения
redraw_window(w);
}