Скачайте в формате документа WORD

Передача информации из льтразвуковой медицинской диагностической становки ALOCA SSD650

ннотация

Дипломный проект посвящен разработке системы передачи данных из льтразвуковой медицинской диагностической установки, также получением диагностически адекватного изображения для дальнейшей диагностики, анализа и хранения. Обработка полученных изображений базируется на программном комплексе CTsoft.

Система предназначена для работы в отделениях льтразвуковой диагностики и не требует от пользователя дополнительных знаний по программированию и техническому обслуживанию персональных компьютеров. Она предоставляет пользователю добный экранный интерфейс для получения и обработки высококачественных изображений, переданных из льтразвуковой медицинской диагностической становки, кроме того, она предусматривает возможность дальнейшей передачи полученных данных по компьютерной сети.

Система прошла опытную эксплуатацию в институте хирургии им А. В. Вишневского в рамках проекта телемедицина. Отчетные материалы к дипломному проекту включают пояснительную записку, 3 приложения и графический материал.


Содержание

TOC \o "1-3" Введение 4

Обзор литературы 7

Разработки телемедицины в мире 7

Необходимость телемедицины в России 9

Задачи здравоохранения, решаемые с применением телемедицинских технологий 12

Формы применения телемедицинских технологий для решения задач здравоохранения 15

Приложения телемедицины в клинической практике 16

Требования к передаче телемединформации 17

анализ возможности передачи медицинских данных существующими программно - аппаратными средствами 20

Подключение льтразвуковой медицинской диагностической становки ALOKA SSD - 650 23

Ультразвуковая диагностическая становк ALOKA SSD - 650 25

Общие характеристики стройств 25

Принцип построения выходного сигнал 27

Устройство согласования ЗИ с персональным компьютером первичной обработки данных 29

Основные характеристики HI*DEF Plus LF 31

Формат файла получаемого изображения 32

Персональный компьютер первичной обработки 35

Локальная вычислительная сеть 38

Особенности построения компьютерной сети для института хирургии им. А. В. Вишневского 38

Программное обеспечение и сетевое оборудование 43

Персональный компьютер консультант 45

Использование фильтров 46

Фильтр сглаживания 48

Фильтр средненного сглаживания 49

Фильтр подчеркивания контуров 50

Фильтр обработки полутонов 51

Последовательное использование фильтров 52

Заключение 54

Выводы и результаты: 55

Список литературы 56

Приложение 1 58

Формат информационного поля файла изображения 58

Приложение 2 63

Модуль формирования фильтров изображений (С++) 63

Приложение 3 95

Описание программы обработки изображений Ctsoft 95

аbr clear="all">

Введение

Несмотря на сложность экономической ситуации, в стране быстро нарастает парк современной медицинской аппаратуры: льтразвуковые аппараты, компьютерные томографы, биохимические анализаторы и т.д. Однако, в силу неполного использования современных медицинских знаний, новые методики внедряются на местах крайне неэффективно. Как показывает опыт, ровень диагностики и лечения в центральных клиниках (а они сосредоточены главным образом в Москве) значительно превосходит ровень практического здравоохранения в стране, даже при том, что разница в ровне оснащения не велика. При этом в медицине объем знаний дваивается в 1,5 - 2 раза быстрее по сравнению с другими разделами науки. Таким образом, стратегически важной задачей становится организация принципиально нового взаимодействия работников практического здравоохранения с центральными научно-диагностическими чреждениями, так чтобы практическое здравоохранение в регионах могло бы оказывать высококвалифицированную помощь населению, используя имеющееся оборудование и интеллектуальный потенциал лучших клиник страны.

Экономическая ситуация в стране изменилась таким образом, что диагностическая помощь населению регионов со стороны центральных клиник становится практически недоступной, при том, что ресурсы ведущих медицинских центров вполне позволяют оказывать эту помощь. Затраты на приезд в Москву становятся сравнимыми, подчас и превосходят саму стоимость диагностики и лечения. Как показывает статистика широкопрофильного медицинского центра (Института хирургии им. А.В. Вишневского РАМН) до 1995 года за диагностической помощью обращалось порядка 10-12 тыс. пациентов в год из различных регионов страны, сейчас это количество пало до 1 тыс., при этом Институт в год проводит обследования до 70 тыс. пациентов (москвичи) и в состоянии довести это число до 120-150 тыс.

Имеющиеся и активно развивающиеся в стране современные средства связи (спутниковая, оптоволоконная, радиорелейная) позволят объединить региональные и центральные лечебные чреждения в единую сеть и таким образом обеспечить доставку интеллектуального потенциала лучших клиник страны в те места, где в нем экстренно нуждаются.

Очень большие перспективы в этом плане сулит Утелемедицина - сочетание современных научных методов диагностики и лечения заболеваний с скоренной обработкой и анализом клинико-физиологической и медико-социальной информации на базе электронно-вычислительной техники и средств связи в режиме теледоступа.

Выполнение перечисленных выше задач невозможно без технической базы, которая должна быть реализована в каждом медицинском учреждении, входящим в проект телемедицина. Эта техническая база должна включать в себя парк персональных компьютеров, объединенных в единую сеть с централизованной базой данных, подключением к медицинским диагностическим установкам и иметь выход на внешние линии связи.

Вопросы рассматриваемые в рамках нашего дипломного проекта включают в себя решение следующих задач:

Ø

Ø

Ø

Ø

В дипломном проекте рассмотрен вопрос подключения ультразвукового диагностического аппарата к сети и решение обеспечения качественной передачи данных по сети. С возможностью вывода на печать с использованием печатающих стройств общего назначения. А также анализ полученных данных.



Обзор литературы

Разработки телемедицины в мире

Первой страной, поставившей телемедицину на практические рельсы стала Норвегия, где имеется большое количество труднодоступных для традиционной медицинской помощь мест. Второй проект был осуществлен во Франции для моряков гражданского и военного флотов. А сегодня же трудно назвать западно - европейскую и американскую страну, где бы не развивались телемедицинские проекты, причем особый размах нарастание сеансов телемедицины получило в США.[8]

Скачайте в формате документа WORD

Анализ возможности передачи медицинских данных существующими программно - аппаратными средствами

При организации передачи данных от медицинского диагностического оборудования возникает ряд технических проблем, связанных с высокими требованиями предъявляемыми к качеству передаваемой информации. Эти проблемы можно разделить на три основные группы:

1.     Проблема получения диагностически адекватного изображения для дальнейшей диагностики, анализа и хранения.

2.     Проблема сопряжения диагностического оборудования с системами передачи информации.

3.     Проблема передачи полученной информации к лудаленным пользователям.

Первая проблема связана в первую очередь с психологией восприятия специалистами - врачами результатов получаемых от медицинских диагностических становок, т.е. они чаще всего, не подготовлены к работе с альтернативными вариантами предоставления медицинской, такими как, например, изображение на мониторе персонального компьютера. В связи с этим информация, с которой предполагается работать на персональных компьютерах, должна быть предоставлена в привычном для специалистов виде. Кроме того, программа обработки информации, должна быть простой в использовании и интуитивно понятной, что позволит сократить время адаптации и обеспечить быструю возможность перехода к работе с новыми методами предоставления медицинских данных.

Вторая проблема связана с тем, что не существует единого стандарта формата предоставления и хранения медицинских данных. Фирмы - разработчики медицинского оборудования основываются на собственных стандартах, которые закрыты, зачастую несовместимы с аналогичными системами других фирм, и могут изменяться в последующих разработках и модификациях же существующего оборудования. Попытки стандартизирования форматов хранения и отображения медицинских данных привели к появлению нескольких стандартов, наиболее известным из которых является DICOM3, но которые всеобщего распространения не получили. Исходя из всего выше сказанного, можно заключить, что каждая медицинская диагностическая становка требует индивидуального подхода для обеспечения возможности передачи информации.

Также существует ряд проблем возникающих при попытках обеспечения высокого качества передаваемой медицинской информации, связанных с тем, что современные программно - аппаратные средства не специализированы для передачи данных подобного рода. Это накладывает определенные требования к подбору оборудования для передачи информации из медицинской диагностической аппаратуры на персональные ЭВМ. Специализированных (стандартных) программных средств, предназначенных для обработки медицинской информации (изображений) на персональных ЭВМ на данный момент практически не существует. Использование программ общего назначения, для работы с медицинскими данными, практически невозможно. Это связано с тем, что требуется высокий ровень специальной подготовки специалистов - врачей, и требования, предъявляемые к персональным ЭВМ, для становки программ такого класса, неоправданно высоки, что практически невозможно из-за неоправданно высоких материальных и временных затрат.

Третья проблема связана с ограничениями, накладываемыми на передаваемую информацию, современными средствами связи. Медицинские данные (изображения, звук, видео) невозможно передавать в лреальном времени по современным каналам связи, с тем качеством, которое требуется для довлетворительной работы специалиста. Объемы информации требуют разработки специальных алгоритмов сжатия данных и выработки новых методик передачи информации.

Предлагаемые методы решения вышеперечисленных проблем описаны в настоящем дипломном проекте на базе подключения для передачи данных ультразвуковой диагностической становки ALOKA SSD - 650 к персональному компьютеру с последующей передачей данных по компьютерной сети.



Подключение льтразвуковой медицинской диагностической становки ALOKA SSD - 650/h1>

В связи с тем, что для осуществления даленных консультаций необходимо качественная передача данных от медицинских становок к специалистам, к оборудованию захвата, передачи и отображения информации предъявляются определенные требования, которые будут рассмотрены ниже. Общая схема передачи изображения от льтразвуковой диагностической становки к врачу - консультанту представлена на рис 1.

Использование фильтров

Для эффективной работы с полученными из ЗИ изображениями необходимо применять программные средства, которые бы обеспечили возможность обработки изображения и при этом не требовали высокой квалификации обслуживающего их персонала. Данная программа была разработана в РНЦ Курчатовский институт и называется CTsoft. В создании этого программного продукта и приняла частие и наша группа дипломников. В размерах данного проекта были предоставлены алгоритмы обработки изображения, позволяющие преобразовывать полученные картинки по специализированным алгоритмам - фильтрам. Данные фильтры предназначены для сглаживания и выделения областей на изображении. Рассматривалось четыре вида фильтров:

1.     Фильтр сглаживания - Smooth;

2.     Фильтр средненного сглаживания - Mean;

3.     Фильтр подчеркивания контуров на основе матрицы размером 3*3 пикселей - Contour;

4.     Фильтр обработки полутонов - Shading.

Все вышеуказанные фильтры работают по алгоритмам на базе матрицы размером 3*3 пикселей. Для описания алгоритмов фильтрации используем словные обозначения для каждого элемента данной матрицы см. таблицу 3.


Таблица аSEQ Таблица \* ARABIC 3 Матрица пикселей, использованная для построения фильтров.


A

B

C

D

E

F

G

H

J

Для того, чтобы можно было бы сравнить действия этих фильтров, далее будут показано изображение, полученное путем передачи данных из ЗИ в персональный компьютер. Исходное изображение показано на рис. 4. И в конце данного раздела будет показано действие нескольких фильтров для отображения определенных областей на данном изображении.

Заключение

Реформа системы здравоохранения обеспечила рывок в развитии диагностических служб региональных клиник, но одновременно и привела к тере ряда несомненных достижений советского здравоохранения. В частности практически полностью разрушена целостность системы, в результате чего жители регионов не в состоянии получить высококвалифицированную помощь, которая осталась сосредоточенной в центральных московских клиниках. Развитие проекта Телемедицина направлено на сохранение и силение положительных аспектов реформ и на нивелирование возникших негативных последствий.

Объединение клиник страны в медицинскую информационную сеть позволит организовать взаимодействие опытных специалистов центра с начинающими докторами регионов. Работа в этом направлении уже начата, однако до сих пор внутригоспитальные сети, позволяющие обмениваться информацией о больном, находятся на ровне научных разработок. До сих пор не существует единый стандарт формирования пакета медицинской информации, включая изображения (рентген, ЗИ, КТ и т.п.). Только единичные клиники работают над построением сетей, собирающих информацию.

Дипломная работа посвящена решению задачи подключения к сети льтразвукового медицинского диагностического аппарата 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.            Видеоконференции в российских клиниках. Е. Тимин, В. Столяр, А. Сильков. Журнал Открытые Системы Изд: Открытые Системы, 1г.

8.            Журнал Медицинская визуализация, Выпуски 1 - 4, издательство "ВИДАР" 1.

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.


Приложение 1

Формат информационного поля файла изображения

Позиция

Название

Значение

Описание

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

5

Мантисса ALFA*1

17

alex

-7

Экспонента ALFA

18

pp

400

Порядок регуляризации * 100

19

mk

9

m*2 = 2**mk

20


0

Тип: 0-CTSYS, 1- СРТ-М, 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

8

Максимум

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

4 и 12

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



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

Тип системы



Приложение 2

Модуль формирования фильтров изображений (С++)

#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;

mf[6]=*(p3+tr);mf[7]=*(p3+str);mf[8]=*p3;

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->bfSize = 0l; // размер файла в long-ах

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);


}


Приложение 3/h1>

Описание программы обработки изображений Ctsoft/h2>