<30362D3430BAA5C3B F28C1D629C7C7BFA4C4C9C0CC2E687770>

Similar documents
K&R2 Reference Manual 번역본

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

SRC PLUS 제어기 MANUAL

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

T100MD+

Microsoft Word - FS_ZigBee_Manual_V1.3.docx

hd1300_k_v1r2_Final_.PDF

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

슬라이드 1

Microsoft PowerPoint - 04-UDP Programming.ppt

이도경, 최덕재 Dokyeong Lee, Deokjai Choi 1. 서론

PowerPoint 프레젠테이션

BMP 파일 처리

PowerPoint 프레젠테이션

UI TASK & KEY EVENT

untitled

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

C++-¿Ïº®Çؼ³10Àå

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

슬라이드 1

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

-. Data Field 의, 개수, data 등으로구성되며, 각 에따라구성이달라집니다. -. Data 모든 의 data는 2byte로구성됩니다. Data Type는 Integer, Float형에따라다르게처리됩니다. ( 부호가없는 data 0~65535 까지부호가있는

DE1-SoC Board

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

API 매뉴얼

untitled

(SW3704) Gingerbread Source Build & Working Guide

C# Programming Guide - Types

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

PowerPoint 프레젠테이션

<312E20C0AFC0CFC4B3B5E55F C0FCC0DAB1E2C6C720B1B8B8C5BBE7BEE7BCAD2E687770>

PowerPoint 프레젠테이션

졸업논문 되어자전거의현재정보를알려주게된다 시스템의동작절차그림 3-1 리더에서의자전거정보조회동작절차위에동작절차에서알수있듯이리더에서하는동작절차에서는크게 부분으로나눌수있다 리더에서에너지를보내 로부터데이터가전송되면자전거의정보를확인한다 여기서도난당한자전거인

MPLAB C18 C

UI TASK & KEY EVENT

Microsoft PowerPoint - chap06-2pointer.ppt

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

개요

오토 2, 3월호 내지최종

Microsoft Word - ASG AT90CAN128 모듈.doc

untitled

Index Process Specification Data Dictionary

untitled

vi 사용법

특징 찾아보기 열쇠 없이 문을 열 수 있어요! 비밀번호 및 RF카드로도 문을 열 수 있습니다. 또한 비밀번호가 외부인에게 알려질 위험에 대비, 통제번호까지 입력해 둘 수 있어 더욱 안심하고 사용할 수 있습니다. 나만의 비밀번호 및 RF카드를 가질 수 있어요! 다수의 가

5.스택(강의자료).key

<4D F736F F F696E74202D20B8AEB4AABDBA20BFC0B7F920C3B3B8AEC7CFB1E22E BC8A3C8AF20B8F0B5E55D>


슬라이드 1

[8051] 강의자료.PDF

PRO1_04E [읽기 전용]

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

비트와바이트 비트와바이트 비트 (Bit) : 2진수값하나 (0 또는 1) 를저장할수있는최소메모리공간 1비트 2비트 3비트... n비트 2^1 = 2개 2^2 = 4개 2^3 = 8개... 2^n 개 1 바이트는 8 비트 2 2

PowerChute Personal Edition v3.1.0 에이전트 사용 설명서

6주차.key

슬라이드 1

13주-14주proc.PDF

목차 1. 개요 USB 드라이버 설치 (FTDI DRIVER) FTDI DRIVER 실행파일 USB 드라이버 확인방법 DEVICE-PROGRAMMER 설치 DEVICE-PROGRAMMER

CPX-E-EC_BES_C_ _ k1

02 C h a p t e r Java

강의 개요


The Pocket Guide to TCP/IP Sockets: C Version

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

UI TASK & KEY EVENT

RVC Robot Vaccum Cleaner

본 강의에 들어가기 전

놀이동산미아찾기시스템

03장.스택.key

10주차.key

PowerPoint 프레젠테이션

소식지수정본-1

PowerPoint 프레젠테이션

歯Lecture2.PDF

untitled

Microsoft Word - KPMC-400,401 SW 사용 설명서

11장 포인터

Microsoft Word - PLC제어응용-2차시.doc

PowerPoint 프레젠테이션


<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202834C1D6C2F7207E2038C1D6C2F729>

Microsoft PowerPoint - 6.pptx

- 2 -

윈도우시스템프로그래밍

PowerPoint 프레젠테이션

chap10.PDF

Chapter 4. LISTS

SQL Developer Connect to TimesTen 유니원아이앤씨 DB 기술지원팀 2010 년 07 월 28 일 문서정보 프로젝트명 SQL Developer Connect to TimesTen 서브시스템명 버전 1.0 문서명 작성일 작성자

슬라이드 제목 없음

iii. Design Tab 을 Click 하여 WindowBuilder 가자동으로생성한 GUI 프로그래밍환경을확인한다.

<4D F736F F F696E74202D B3E22032C7D0B1E220C0A9B5B5BFECB0D4C0D3C7C1B7CEB1D7B7A1B9D620C1A638B0AD202D20C7C1B7B9C0D320BCD3B5B5C0C720C1B6C0FD>

MR-3000A-MAN.hwp

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

1217 WebTrafMon II

Microsoft PowerPoint - es-arduino-lecture-03

Transcription:

해양수산부해양수산중소 벤처기업기술개발지원사업사업결과보고서 입출항신고기능을겸비한어선위치기록스마트카드시스템 2006 년 11 월 7 일 주관기업 ( 주 ) 피엘케이테크놀로지

2 0 0 6 입출항 신고기능을 겸비한 어선 위치 기록 스마트카드 시스템 ( 주 ) 피엘케이테크놀로지

이보고서는해양수산부에서시행한해양수산중소 벤처기업기술개발지원사업의사업결과보고서입니다. 이기술내용을대외적으로발표할때에는반드시해양수산부에서시행한해양수산중소 벤처기업기술개발지원사업의기술개발결과임을밝혀야합니다.

제출문 해양수산부장관 귀하 본 보고서를 [ 입출항 신고기능을 겸비한 어선 위치 기록 스마 트카드 시스템 ] 에 관한 해양수산중소 벤처기업기술개발지원사업 ( 개발기간 :2004.12.21~2006.11.30) 과제의 사업결과보고서로 제출합니 다. 2006 년 11 월 6 일 주관기업 : ( 주 ) 피엘케이테크놀로지 개발책임자 : 임상묵

목 차 제 1 장개요제1절기술개발의필요성제2절기술개발대상 1. 기술개발명칭, 규격, 성능, 기능, 용도 2. GPS 기술 3. 수요자및수요자의요구사항 4. 시장창출능력 5. 종래유사기술에대한독창성과혁신성 6. 부가가치성 7. 기대효과 제 2장 VMU(Vessel Monitoring Unit) 의개발제1절 VMU의개요제2절 IP 등급과 NMEA 제3절하드웨어제작 1. VMU 1차제작 가 VMU 의블록다이어그램나 VMU 의 1 차회로도면 다. PCB 의거버파일 라. 1 차 VMU 2. VMU 2차제작가 2차 VMU의설계도나 2차 PCB 거버파일다 PCB 형상라 2차 VMU의외장형상 제3장스마트카드와데이터처리제1절스마트카드기술제2절스마트카드시스템구축 1. 카드파일시스템 2. 데이터베이스연결을위한시스템 3. 선박용스마트카드데이터베이스프로그램

제4장실험제1절성능시험및 EEZ 실험제 2절개발과정상의문제점 ( 상세히기술 ) 1. 연안어선실험 : 실제어선에서실험을위해서연안의항구에서배 2. EEZ와 NLL의실험 제5장사업화계획제1절최종기술개발결과물의시장분석 1. 입출항신고기능을겸비한어선위치기록스마트카드시스템 2. 소수의선박을가지고직접조업을하는어민 3. 다수의선박을가지고있는선주 4. 어선과해양자원관리감독을원하는정부기관 ( 공공기관 ) 5. 대형선박에장착되는블랙박스업체나선박용 PC를제조하는업체제2절사업화계획및매출목표 ( 시장진입을위한사업화계획 ) 1. 소수의선박을가지고직접조업을하는어민 2. 다수의선박을가지고있는선주 3. 어선과해양자원관리감독을원하는정부기관 ( 공공기관 ) 4. 블랙박스와선박용 PC를제작판매하는회사와의연동 5. 제조및판매방안제3절중국 GPS 자동차운행기록계시장 1. 개요 2. 중국블랙박스시장 3. 중국시장진출계획 제6장첨부제1절 FirmWare Source Code 제2절데이터베이스 S/W Source Code 제3절중국차량용 흑상자 적용을발표하는북경공안

입출항신고기능을겸비한어선위치기록스마트카드시스템 제 1 장개요제1절기술개발의필요성우리나라는 3면이바다로둘러싸인국토를가지고있으며, 남북이가로막혀있는상황에서주변의강국들과바다를통하여교류를하여야하는위치에있다. 이런상황에서남북은서해와동해에서서로대치를하고있어서우리의바다는군사, 경제, 정치의모든이해관계가녹아있다고할수있다. 이런상황에서는이바다를터전으로삶을영위하는사람들과어선들에대한보호, 감독이다른어느나라보다도중요하고시급한문제가아닐수없다. 이러한어선들의보호, 감독의출발점은어선들이어느바다에서어떤일을하였는지를인지하고분석하는일이라고할수있다. 실제로어선들의해상에서의위치와시간을정확히알수있다면많은분쟁과문제점들이해결될수있는데그예를다음에서들어보고자한다. 첫번째예로남북의군사적충돌의위험성을항상내포하고있는북방한계선을들수있다. NLL, 즉북방한계선은우리의국토수호라는당연의명제이외에도어민들의삶과밀접한관계를가지고있다. 매년봄여름에이곳에서형성되는어장은어민들이많은위험을무릅쓰고이북방한계선을넘나들게하는중요한이유가되는것이다. 하지만이들의어로행위는남북간의분쟁을초래할직접적인원인을제공하고있어서해양경찰청에서는이들의보호와감독에매년많은노력과시간을투입하고있는것이사실이다. 하지만이러한노력도완전한감독은될수없어서지금도많은위험을내포하고있다. 이를해결하기위해서는어선들이북방한계선을넘나드는것을좌표와시간등으로기록하고보관하여, 지속적인관리와분석이필요할것이다. 실제로어선들이자신들이움직인경로와시간정보를해양경찰청에서알수있고이를통해어로금지등의더큰경제적불이익을올수있다고하면스스로이를잘지키려고노력할것이기때문이다. 또한이렇게자율로이한계선이지켜진다면지금의해양경찰청의감독노력은현저히줄이고도더좋은효과를가져올수있을것이다. 두번째로는배타적경제수역제도에대한어업자원관리도매우필요한정책이다. 1994 년유엔해양법협약이발효된이후우리나라는 1996년 배타적경제수역법 과 배타적경제수역에서의외국인어업등에대한주권적권리행사에관한법률 을제정이제도를시행하고있다. 또한 1998년 11월 28일에는일본과신한일어업협정을체결하고 2000년 8월 3일에는중국과도한중어업현정을체결시행함으로서조업가능해역이더욱줄어들어서관할수역의어업자원관리는더욱중요하게되었다. 또한이제도가시행됨에따라우리어선의일본해경들에의한나포와같은사례가매년발생하고있어서이에대한지도감독이더욱중요하게되었다.

이러한배타적경제수역상의어로행위와어업자원관리를위해서도어선의위치를저장하고이를분석할수있는장치의필요성은더욱중요시될수밖에없다. 먼저일본이나중국에나포된어선의경우수역을넘었는지의여부를가지고많은다툼이있는데이를저장하고있다면이러한다툼의원인은없앨수있으며또한나포되기이전에평상시어로행위중에어떤어선들이수역을자주넘었을경우해경에서이를미리저지함으로써미래의분쟁을미리막을수있을것이기때문이다. 또한, 어선들은자신이조업을하는위치를분석함으로서어장의변화나어획량의증대를가져올수도있으며여러척을운영하는선주에있어서는자신의어선들의관리를할수있으므로또한유익할것이다. 만약이러한정치가많이보급된상황에서는전체적이고통합적인관리가가능하게되므로정부당국에서는유용한통계정보를이용하여정책을수립하는데도크게기여할수있을것이다. 그림 1 어업지역 세번째로는사회적으로물의를일으키는공해상의밀수등과같은불법행위의근본적

인대책이될것이다. 최근중국의개방과더불어중국의사회경제활동이비약적으로늘어나면서문제가되는것이바로밀수문제이다. 밀수의문제는한국의배와중국의배가공해상에서만나서, 금, 인삼, 명품, 마약, 어류등을주고받는일이며이에대한관리감시를위해서해경에서도많은노력을기울이고있다. 하지만, 늘어나는중국의경제력과맞물리어이러한시도가증가되고있는만큼이에대한대책도매우중요할것이다. 이에대한대책또한어선들의경로를추적하고분석함으로써가장좋은해결책이될수있을것이다. 밀수를위한배들은어로행위를하는배들과는움직임이다르며공해상에멈추고있는시간도어로행위를하기위한배들과는구별될것이다. 또한해양경찰청의불시검문에서배의움직임바로확인할수있다면어선의정밀수색이없이도대략의정황을알수있으므로밀수후적발에도큰도움이될것이다. 이외에도어선들의경로, 시간을저장, 분석하여얻을수있는장점은통계를통한정책수립과어선들의자율적인협조를얻어서궁극적으로우리바다의자원을효율적으로관리하여어민들에게그이익을돌려줄수있을것이다. 이러한데이터의수집을어민들이자율적으로행하게될것이며이과정에서어민들이불편하게생각하는출입항신고를간단하게대체함으로써편리를증진시키고어민들스스로도자신의어로경로를저장분석함으로써체계적인어로행위를도울수있다. 특히어선을여러척소유하고있는선주의경우에는자신의어선들이다니는경로를분석하고이를이용할수있으며이를계절과어획량과함께저장하여효율적인어선관리를가능하게한다.

2절기술개발대상 1. 기술개발명칭, 규격, 성능, 기능, 용도이장치 (VMU) 는 GPS로부터받은어선의위치및이동경로를스마트카드에저장하고, 어선이입출항할때마다이스마트카드를통하여해양경찰청등의서버에업데이트 (Update) 시키는것을기본아이디어로하는상품이다. 그림 2 시스템개념도스마트카드는신용카드및인터넷인증, 휴대폰인증등에사용되는카드로서데이터의보안성이뛰어나며사용이간편하고, 내부에 CPU와메모리를저장하고있어서상황에따라서여러작업을수행할수있는매우똑똑한카드다. 이장치는이러한스마트카드를이용하여어선의이동경로를저장하고이데이터를입항할때마다서버에옮겨놓는장치이다. 스마트카드의이용방법을설명하면먼저해양경찰청등어선관리를하는기관에서어선과선장을등록하고이들에게배에맞는스마트카드를하나씩공급을한다. 선장들은이발급된카드를이용하여출항할때출항신고대신에이카드를카드리더기에접촉함으로서보다편리하게자동으로출항신고를마치고출항을할수있다. 선장은출항후에자유롭게조업및운행을한후에입항을하는데, 이때반드시배안에설치되어있는 VMU(Vessel Monitoring Unit) 에접촉하였다가입항신고시에이카드를다시서버의리더기에접촉을하게된다. 선장은입출항신고서류작성이필요없어져서입출항이간편해지게되며, 이러한절차가진행되는동안에리더기가연결되어있는서버에는어선들의이동경로가자연스럽게저장되게된다. 이시스템을구성하기위해서는중요한몇가지장치가필요하다. 먼저배안에서 GPS를통하여위치를인식하고정해진시간간격마다저장하는장치가필요하다. 이장치를 VMU(Vessel Monitoring Unit 이하 VMU) 이라하고이장치는저장된어선의위치와시간들을자신의짝이되는스마트카드가요구할때데이터를옮겨주는역할

도한다. 혹시라도어선의경로를알아서악용할위험을피하기위하여 VMU는인증된스마트카드가들어올때에만데이터를넘겨주고인증되지않는카드는무시하거나경고한다. 또한 VMU는어선에게기본적으로자신의 GPS 위치와위성시간, 경로등을알려주고, 저장된제한구역에들어가거나갈위험성이있는때에는경고를해주어만약에일어날수있는나포, 발포등에위험에서벗어나도록도와준다. 데이터서버는 VMU로부터스마트카드를매개로데이터를저장하고분석하는기능을갖춘서버이다. 또한스마트카드에맞추어입출항신고를자동으로하는기능을포함한다. 데이터서버는스마트카드리더기가연결되어있어서. 스마트카드가연결되면카드에맞는어선을찾아이어선이조업한경로를저장하게된다. 이경로데이터는과거의데이터와함께저장되며이를이용하여어선이북방한계수역을넘었는지얼마나있었는지, 배타적경제수역에들어갔는지갔으면얼마나있었는지를분석하고, 공해상에있었을때에는공해상에서의움직임을바로알수있는장치이다. 또한어종에따른통계분석, 조업을하는주요해역, 시간을명확하게분석한다. 선주에게는소유한어선들의경로를분석하는툴을제공하여경로시간관리및매년의계획과실행에도움을준다. 또한서버상에서월간계획, 실적, 연간실적을분석해주어향후조업계획, 투자에대한기본데이터를제시한다. 2. GPS 기술 - 우주공간에떠있는인공위성을이용한위치추적기술인 GPS는해양선박에서는예전부터사용되어왔던기술이다. 초기에는미국에서군사목적에따라서개발되었던기술이지만현재에는차량용네비게이션에서부터골프장의홀위치를찾아주는장치까지그활용범위가나날이늘어가고있는기술이다. 해외의경우에는국토가넓은미국의경우차량이사고가났을떄자동으로위치를알려주는긴급구난장치로서도활용되고있다. 활용범위가늘어나면서 GPS 휴대폰도등장하고있으며이에따른대량생산으로단가가계속하락하고있다. 향후 GPS기술은그정확도를더욱높이는많은기술을통하여그범위가늘어날전망이다. 3. 수요자및수요자의요구사항이시스템의최대수요자는각해역의관리감독을맡고있는기관이될것이며우리나라의경우에는해양경찰청이된다. 이시스템의기능이잘알려져서수출하게되었을때는연안국가, 일본, 중국, 멕시코, 캐나다, 영국, 프랑스, 이탈리아등해양강국들의해양경비를맡고있는경찰들이수요자가될수있다. 현재북방한계선의경비와관리를위해서많은노력과자원이투입되고있는데, 이시스템을도입함으로써이러한노력들은보다효율적으로관리가가능할것이며, 배타적경계수역에서매년일어나는분쟁을보다효과적으로관리할수있을것이다. 또한매년공해상에서일어나는불법어로행위 ( 중국어선이잡은고기의한국어선이송등 ) 로인하여관세청에서는골치를앓고있는데, 이시스템을적용함으로써이러한

불법행위를미연에방지할수있으며불심검문의효율성도높여줄수있다. 해양경찰청과관세청에서는어선이조업을하는경로와조업시간을정확히알기위해서는어선을돌아다니면서데이터를수집하여야하는데, 이시스템을이용하면사무실에서편리하게어선의경로를알수있기때문에매우유용한시스템이되며, 또한이러한 DB를관리할수있는기능을원한다. 또한입출항신고도어선의의무사항이지만서류작성의복잡함때문에어민들이꺼려하고있는데, 이절차를간소화시켜줌으로써대다수선량한어민들의편리를도모할수있다. 또다른수요자는여러대의어선을보유하고있는선주로서, 선주들은효율적인어선관리와어획량분석을위하여이러한시스템을필요로할것이다. 또한하나의어선을가지고있는선주의경우에도효율적인관리와조업일지작성을통하여정보교환과정보가공이가능하므로이러한선주에게도유용한시스템이라할수있다. 4. 시장창출능력시장을계산하기위해서는어선에장착되는 VMU와서버를나누어야한다. VMU는저가형선박 GPS의역할을수행하므로별도의시장으로도가치가있다. 따라서 VMU시장은다음과같다. 국내의어선의총수 : 2002년 89,327 척 ( 인용 : 해양수산부 2003년통계 동력어선기관별, 선질별, 톤급별어선척수 ) VMU의단가 : 소비자가격 490,000원 VMU의총시장 : 490,000 x 89,327 = 43,770 백만원 서버와관련된시장은서버와스마트카드발급장치가동시에필요하게되는데이시장의경우한서버에서대략 100대의어선을관리한다고하면다음의계산이가능하다. 하나의서버당관리가능한어선의수 : 100척필요서버규모 : 89,327 / 100 = 894 대서버및스마트카드발급기가격 = 20,000,000원서버및스마트카드발급시장 = 894 x 20,000,000원 = 17,880 백만원 위의두시장의합계가바로국내총시장의규모이므로다음과같이계산할수있다. 국내의총시장 VMU 시장 + 서버및발급기시장 = 43,770 + 17,880 = 61,650 백만원 해외시장의규모를알기위해서는세계시장의어선통계를살펴보아야한다. 2003년해양수산부가제시하는세계어선통계 세계선박현황 ( 주요국 ) 을보면국내는 1,153척을세계의총어선의수는 24,181척이다. 이는등록된대형어선만을통계로잡은수치로추측된다. 따라서정확한시장규모를예측할수없지만이미계산된국내시장

규모에이비율대로계산하면시장의규모를추측할수있을것이다. 해외어선 / 국내어선비율 : 24,181 / 1,153 국내시장의규모 : 61,650 백만원세계시장의규모 : 61,650 x 20.97 = 1,292,944백만원 종합하면국내시장의규모는 600억원규모이며세계시장은 1조 3000억원규모의시장이된다. 하지만이는어선관리만을위한시장규모를계산한것이며, 각국의사정에따라어선뿐만아니라화물선에도적용이가능하므로이시장까지계산하면어선보다전체선박의비율이 3.68배가되므로대략국내시장은 2,200억원규모이며세계적으로는 4조 7000억원규모의시장이다. 5. 종래유사기술에대한독창성과혁신성이시스템과비견할수있는유사장치나시스템은 VMS (Vessel Monitoring System 이하 VMS) 과선박용블랙박스를예로들수있다. 이런장치의경우우리가제안하고자하는시스템의일부기능을포함하고있으나근본적으로그쓰임새가다르고가격이고가이며비슷한목적으로사용하기에는부족한단점들을가지고있다. 이러한단점들과비교하여동시스템의혁신성에대하여서술한다. VMS와의비교 : VMS는어선의위치와시간을 GPS로받아서이를일정시간마다어선의무선통신 ( 예 :INMARSET-C) 을이용하여육상의기지에데이터를보내는것을시스템의근간으로하는장치이다. 이장치는실시간으로어선으로현재위치를보낼수있다는장점을가지고있으나, 제안하고자하는시스템의목적에는몇가지부합하지않는점이있다. 첫번째로일정한주파수로데이터를주고받음으로써보안성의문제가발생할수있다. 어선들의경우자신이알아낸어장의위치등이타선박이나선사에알려지는것을꺼려하므로선량한어선이라고해도이런문제점으로인하여이에대한노출을꺼릴수있다. 두번째로는북방한계선이나배타적경제수역의관리를위하여는무상또는저가로시스템을공급하여야실효성을거둘수있는데반하여, VMS 의경우에는장비의가격이 2000불가까운고가장비이기때문에공급하는데어려움이있어서시장형성및보호, 감독의목적을이루기가힘들다. 선박용블랙박스 : 비행기가사고가발생했을때그원인을분석하기위한블랙박스가있는것처럼선박사고에있어서도사고원인을알수있는블랙박스가있다. 블랙박스는 GPS의위치데이터뿐만아니라선박의여러가지데이터를저장하는장치로서선박안에서의기능이다양하며양도많다. 하지만이블랙박스가선박의위치를저장하는기능은같더라도이데이터를기지나서버에가져올수있는방법은없다. 따라서블랙박스로서의기능은뛰어나게수행할수있을지라도, 관리감독기능을하기위해서데이터를한곳으로수행하는방법이불가능하여동시스템이이루고자하는목

적을이룰수없다. 또한선박의사고에도데이터가남아있어야하고많은기능을포함하여야하므로가격이역시고가일수밖에없어서시장창출에어려움이있다. 동기술의독창성은첫번째로는스마트카드가갖고있는보안성이다. 어선들이자신의어장과경로노출을꺼리는데동시스템의스마트카드에서는이러한정보를타경쟁사들이기술적으로아는것이불가능하다. 또한경찰청에서는정보를접근할수있는인원을제한함으로써이러한정보누출의위험성을사전에차단할수있다. 두번째로는입출항신고의간편성을들수있다. 스마트카드접촉만으로자동으로출항및입항신고가가능해지기때문에어선들은항구에서출항및입항을위한서면신고의불편함을해소할수있으며, 경찰청에서는일일이서류를정리할필요없이 DB로관리를할수있으므로그관리가매우편리해진다. 세번째가장중요한기능으로어선의위치, 경로, 운행시간에대한정보가경찰청의수고가거의없이수집이가능하다는것이다. 어선들이입항신고를위해서스마트카드를접촉하여야하므로이때경로정보가서버에자동으로저장되므로관리에필요한자원이크게줄어들수있는장점이있다. 네번째로는장치의휴대성및안전성으로스마트카드는일반신용카드와같은크기를가지므로휴대하기편하다. 또한물에젖거나충격등에강하므로고장에대한우려를최소화할수있다. 6. 부가가치성동시스템의개발은 GPS 연동기술, 스마트카드기술, 하드웨어제작기술, 서버운용기술등다양하고복잡한기술들이어울려야지만제대로작동을할수있는시스템이다. 동사의경우에는차량에서비슷한장치를개발하고적용한경험을가지고있어서이러한기술을구현하는데타회사보다유리한위치에있다. 따라서기술개발성공가능성이매우높으며기술개발비의소요또한적게들것이다. 또한자동차양산을위한하드웨어기술을선박에적용함으로써신뢰도는자동차수준이면서도가격이저렴하여빠른보급이가능하다. 또한선박마다 GPS장치가저렴하게공급되어선박들도유리하며이에대한시장창출효과는위에설명한바와같다. 하지만이시스템의장점은이러한직접적인경제적이익외에배타적경제수역침범에따른외교적인마찰과이를해결하기위한사회적비용을획기적으로줄일수있는초석이될것이다. 7. 기대효과 기술적파급효과 - 선박의위치를 GPS를통하여알려고하는노력과장치들은많은곳에서이루어져왔다. 하지만이위치와경로를데이터베이스로만드는일은그과정이복잡하고자원이많이들어가는일로서아직시도가되지못하고있다. 하지만동시스템이개

발완료되어데이터베이스로구축이되면각지역의선박들이어디로움직이며어느시간에조업을하는지를명확히알수있게된다. 이러한데이터베이스는여러방면의지식을쌓게할수있는데, 자주출몰하는지역을알수있을때긴급조난을위한초기위치의정보를제공할수도있으며, 어장조사, 어장보호의연구목적으로활용을앞당길수있을것이다. 입출항신고의전자동화를통하여어선의현상황을예측할수있으며, 향후에는조업량보고, 어장위치측정등의업무를스마트카드를이용하여대신하게될것이다. 또한스마트카드에어선의정보와어확량을저장하는시스템의발전을통하여서는어류의경매절차의현대화도이루어질수있다. 선박제조업체들은선박의고장내용이나수리내용이기록되어있는스마트카드를이용하여자사의선박의문제점이나좋은점을파악할수있으며이를통하여좋은품질의선박제조도가능해질수있다. 경제산업적파급효과 - 장치의예상가격은 49만원으로이장치의유지관리를위한최소한의수익을가지려한다. 이시스템은인프라산업의특징을가지고있어서장치가많이쓰이면쓰일수록그효용가치가늘어나는시스템이다. 따라서초기에는장치의보급에최대한의노력을기울임으로써인프라구축에노력을한다. 이외의수익으로는서버의보급, DB 운용프로그램보급에서의수익을예상할수있다. 카드발급시스템보급과연계된사업에서의수익을제외하더라도매우많은수익을기대할수있다. 이를통한산업적인효과는다른모든효과보다도탁월하다고할수있는데, 가장당장의이익으로는북방한계선과배타적경제수역을관리감독하기위한비용을줄일수있다는점이있다. 이비용에는경비선의운행비, 인건비, 관리비용이포함되어있다. 또한, 만일에일어날수있는남북간의분쟁을막아주고, 일본, 중국해역에서의불법조업을미연에방지함으로서발생하는외교적인비용과국가의신뢰성을높일수있는효과는돈으로계산하기어려울정도의이익을줄것이다. 공해상에서의밀수는여러사회적인문제를발생하는것을막을수있을뿐만아니라저가의제품이밀수됨에따라서관련업계에입히는피해를막을수있으며이러한제품이유통되면서발생할수있는시장질서파괴의문제도해결되어관련산업에매우긍정적인영향을미친다고할수있다.

제 2장 VMU(Vessel Monitoring Unit) 의개발제 1절 VMU의개요이장치 (VMU) 는 GPS로부터받은어선의위치및이동경로를스마트카드에저장하고, 어선이입출항할때마다이스마트카드를통하여해양경찰청등의서버에업데이트 (Update) 시키는것을기본아이디어로하는상품이다. 그림 3 VMU 구성도스마트카드는신용카드및인터넷인증, 휴대폰인증등에사용되는카드로서데이터의보안성이뛰어나며사용이간편하고, 내부에 CPU와메모리를저장하고있어서상황에따라서여러작업을수행할수있는매우똑똑한카드다. 이장치는이러한스마트카드를이용하여어선의이동경로를저장하고이데이터를입항할때마다서버에옮겨놓는장치이다. 스마트카드의이용방법을설명하면먼저해양경찰청등어선관리를하는기관에서어선과선장을등록하고이들에게배에맞는스마트카드를하나씩공급을한다. 선장들은이발급된카드를이용하여출항할때출항신고대신에이카드를카드리더기에접촉함으로서보다편리하게자동으로출항신고를마치고출항을할수있다. 선장은출항후에자유롭게조업및운행을한후에입항을하는데, 이때반드시배안에설치되어있는 VMU(Vessel Monitoring Unit) 에접촉하였다가입항신고시에이카드를다시서버의리더기에접촉을하게된다. 선장은입출항신고서류작성이필요없어져서입

출항이간편해지게되며, 이러한절차가진행되는동안에리더기가연결되어있는서버에는어선들의이동경로가자연스럽게저장되게된다. 이시스템을구성하기위해서는중요한몇가지장치가필요하다. 먼저배안에서 GPS를통하여위치를인식하고정해진시간간격마다저장하는장치가필요하다. 이장치를 VMU(Vessel Monitoring Unit 이하 VMU) 이라하고이장치는저장된어선의위치와시간들을자신의짝이되는스마트카드가요구할때데이터를옮겨주는역할도한다. 혹시라도어선의경로를알아서악용할위험을피하기위하여 VMU는인증된스마트카드가들어올때에만데이터를넘겨주고인증되지않는카드는무시하거나경고한다. 또한 VMU는어선에게기본적으로자신의 GPS 위치와위성시간, 경로등을알려주고, 저장된제한구역에들어가거나갈위험성이있는때에는경고를해주어만약에일어날수있는나포, 발포등에위험에서벗어나도록도와준다. 데이터서버는 VMU로부터스마트카드를매개로데이터를저장하고분석하는기능을갖춘서버이다. 또한스마트카드에맞추어입출항신고를자동으로하는기능을포함한다. 데이터서버는스마트카드리더기가연결되어있어서. 스마트카드가연결되면카드에맞는어선을찾아이어선이조업한경로를저장하게된다. 이경로데이터는과거의데이터와함께저장되며이를이용하여어선이북방한계수역을넘었는지얼마나있었는지, 배타적경제수역에들어갔는지갔으면얼마나있었는지를분석하고, 공해상에있었을때에는공해상에서의움직임을바로알수있는장치이다. 또한어종에따른통계분석, 조업을하는주요해역, 시간을명확하게분석한다. 선주에게는소유한어선들의경로를분석하는툴을제공하여경로시간관리및매년의계획과실행에도움을준다. 또한서버상에서월간계획, 실적, 연간실적을분석해주어향후조업계획, 투자에대한기본데이터를제시한다. 제 2절 IP 등급과 NMEA IP 등급 ( 기기보호등급 ) 해상용장비는 IEC529, IEC34-5 규격에의하여, 기기보호구조에대하여防塵, 防水의등급을규정하고있다. 防塵, 防水에대한등급분류에의한표시방법은다음과같다. 방진, 방수에대한등급분류방법및시험방법에대하여는아래의표와같다. 防塵에대한등급분류 ( 첫번째번호 ) IP표시 防塵에대한보호형식보호정도시험조건 IP0 없음 없음 IP1 손의접근으로부터의보호 직경 30mm이상의固形異物體가침투되지않을것 IP2 손가락의접근으로부터의보호직경 12mm이상의固形異物體가침투되지않을것

IP3 공구의선단등으로부터의보호직경 2.5mm이상의固形異物體가침투되지않을것 IP4 WIRE등으로부터의보호 직경 1.0mm이상의固形異物體가침투되지않을것 IP5 粉塵으로부터의보호 정상동작을방해하는粉塵이침투되지않을것 IP6 完全한防塵구조 粉塵의침투로부터완전하게보호될것 표 1 IP 등급첫번째번호 防水에대한등급분류 ( 두번째번호 ) 防水에대한보호형식 IP표시보호정도시험조건 IP 0 없음없음 IP 1 IP 2 IP 3 IP 4 IP 5 IP 6 IP 7 垂直으로떨어지는물방울로부터의보호垂直의 15 범위에서떨어지는물방울로부터의보호수직의 60 범위에서뿌려지는물로부터의보호全방향으로飛散되는물로부터의보호全방향에서쏟아지는물로부터의보호파도와같이강력하게쏟아지는물로부터의보호일정한조건에서물에잠겨서도사용가능 200 mm의높이에서 3~5l/ 분의물방울을 10 분간떨어뜨린다 200 mm의높이에서 15 범위로 3~5l/ 분의물방울을 10 분간떨어뜨린다 200 mm의높이에서 60 범위로 10l/ 분의물을뿌린다 300~500 mm의거리에서全방향으로 10l / 분의물을 10 분간뿌린다 3m 의거리로부터全방향으로 12.5l/ 분 30kPa 의물을 3 분간쏟아붇는다 3m 의거리로부터全방향으로 100l/ 분 100kPa 의물을 3 분간쏟아붇는다 물밑 1m 에서 30 분간 IP 8 물밑에서사용가능사용자와제조자측과의협의에의하여 표 2 IP등급두번째번호따라서 VMU의올바른사용을위해서 IP등급 60이상의제품이필요하며, 이러한기준에 2차년도에는이러한등급에맞춘설계를할예정이다. 완성된제품은산업기술시험원 (KTL) 의등급인정을받을예정이다. - 기존의해상용 GPS와의호환, NMEA Sentence (NMEA 0183) 기존의해상용 GPS와의통신을위해서는프로토콜의이해가필요하다. NMEA라는프로토콜이 GPS와주변장치들의정보교환에이용된다. NMEA는 National Marine Electronics Association의약자로, 해양관련장비의인터페이스프로토콜의표준으로사용되고있다. GPS장치에있어서도이 NMEA 0183 프로토콜이국제표준으로되어있어, 대다수의 GPS장치들이이 NMEA0183인터페이스를지원하고있다.

NMEA Sentence의구조 GPS에는다른장비와연결할수있는잭 ( 인터페이스 ) 이있는데, 인터페이스프로토콜을 NMEA로설정해주면, 다음과같은구조로 NMEA Sentence들이흘러나오는것을볼수가있으며, 출력되는구조는다음과같다. $GPRMC,154232,A,2758.612,N,08210.515,W,085.4,084.4,230394,003.1,W*43[CR][L F] NMEA 프로토콜은 $ 로시작되어, 가운데부분에정보를담고, [CR][LF] 로끝이난다. GPS 장치에서도이런구조를가진, 정보가주기적으로흘러나오게되어있다. $ 문자다음의 GPRMC 등의문자를 NMEA Sentence라고하는데, NMEA Sentence의종류는수신기의종류및현재기능에따라조금씩바뀌어져나오게된다. NMEA Sentence 종류 APRS를운용하는무선국에서는 GPS에서 NMEA 0183프로토콜에의해위치정보를받아, 무선으로재전송해주게된다. 이때주로이용되는 NMEA Sentence는 $GPGGA, $GPRMC 등이이용된다. Garmin GPS-V와 Kenwood TM-D700E와의연동시에는 GPWPL에의해무전기로수신된 APRS정보가 GPS-V로전송되어, 이름을무선국의호출부호로하는웨이포인트가자동생성되어표기되게하는기능이있다. 예를들면다음과같이쓰이는데 $GPGGA GGA - 위치정보 (Global Positioning System Fix Data Time, Position and fix related data fora GPS receiver.) 총 15개의항목이 "," 로구분되어져있다. (1)(2)(3)(4)(5, 6, 7)(8)(9) (10) (11)(12,13,14,15) $GPGGA,170834,4124.8963,N,08151.6838,W,1,05,1.5,280.2,M,-34.0,M,,,*75 Field 내용 Number 우주표준시 Universal Time Coordinated (UTC) hhmmss.ss 1) 세계표준시 (z time) 와동일 2) 위도 Latitude ddmm.mm 3) N or S (North or South) 4) 경도 Longitude ddmm.mm 5) E or W (East or West) GPS수신상태 GPS Quality Indicator, 0 - fix not available, 6) 1 - GPS fix, 2 - Differential GPS fix 7) 감지된위성수 Number of satellites in view, 00-12 8) HDOP Horizontal Dilution of precision 평균해수면 ( 지오이드기준 ) 고도 9) Antenna Altitude above/below mean-sea-level (geoid) 10) 고도의단위 Units of antenna altitude, meters 11) WGS-84 타원체와평균해수면 ( 지오이드 ) 사이의차이 (Geoidal separation, the

difference between the WGS-84 earth ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid 12) Units of geoidal separation, meters Age of differential GPS data, time in seconds since last SC104 13) type 1 or 9 update, null field when DGPS is not used 14) Differential reference station ID, ****-**** 15) Checksum 표 3 NMEA 프로토콜따라서 VMU는위와같은 NMEA를지원할예정이며, 이를위한하드웨어는다음과같다. The NMEA (National Marine Electronics Association) 0183 Standard for Interfacing Marine Electronics Devices is a voluntary industry standard, first released in March of 1983. The NMEA 0183 Standard defines electrical signal requirements, data transmission protocol, timing and specific sentence formats for a 4800 baud serial data bus. Overview NMEA has become a standard protocol for interfacing navigational devices, e.g. GPS and DGPS receivers. It is based on the RS232 interface. NMEA settings for the RS232 are: Baudrate 4800 Data bits 8 (Bit 7 set to 0) Stop bits 1 or 2 Parity none Handshake none 표 4 NMEA 의구현을위한하드웨어사양 3절하드웨어제작 1. VMU 1차제작 1차년도에 VMU의 PCB를설계, 디버깅을위하여 VMU의하드웨어설계는 S/W의출력의범위에따라달라지므로이의정의가마무리되는시점에서시작하였다. VMU에는스마트카드와의통신부분, GPS와의통신부분, 운전자인터페이스부분과데이터저장부분으로나눌수있다. 1차년도에성능구현을위하여제작을하였으나 1차년도의평가시에선박에서장착이어렵고 IP등급에대한대책이미비하다는지적을받은바있어서 2차년도에는설계변경을하여서다시제작하였다.

가 VMU 의블록다이어그램 그림 4 VMU 블록다이어그램 나 VMU 의 1 차회로도면 그림 5 회로설계도면

다. PCB 의거버파일 그림 6 PCB 거버파일 (TOP) 그림 7 PCB 거버파일 (BOTTOM)

라. 1 차 VMU 그림 8 VMU 의겉모습 그림 9 GPS 모듈및스마트카드

2. VMU 2차제작 VMU의 2차제작은 1차제작과는달리방수등급 IP 06을맞추기위한케이스설계및이에맞는 PCB설계를다시하였다또한 1차때의경험을되살려서 LCD부분의위치조정및커넥터부분이약하다는자체결론에따라커넥터부분에도방수가가능한커넥터를사용하였다. 뿐만아니라 1차때에는일반차량의내분에서사용하던 GPS를사용하지않고해상용 GPS를연결하여작동가능함을실험하였다. 가 2 차 VMU 의설계도 그림 10 2 차 VMU 의회로도

나 2 차 PCB 거버파일 그림 11 PCB 의윗면 그림 12 PCB 의뒷면

다 PCB 형상 그림 13 PCB 형상 1 그림 14 PCB 앞모습 그림 15 스마트카드를삽입한형태

라 2 차 VMU 의외장형상 그림 16 2 차 VMU 의외장형태 그림 17 2 차 VMU 의 PCB 와스마트카드체결형상

그림 18 해상용 GPS 그림 19 해상용 GPS 와연결된상태의 VMU

제3장스마트카드와데이터처리제1절스마트카드기술기존신용카드크기의플라스틱카드에 IC(Integrated Circuit: 집적회로 ) CHIP을내장하여정보의기밀성과보안성을향상시키고, 다량의정보를저장하여다양한기능을수행할수있도록만든카드로스마트카드라고도불린다. 1974년프랑스모레노가기본개념을특허로출원해 1980년대부터전화카드에서맨처음사용되기시작하였다. 2000년현재 IC카드시장은유럽 66%, 아시아 16%, 미주 8% 등으로지역별점유율을나타내고있으며, 2002년이후급속도로보편화될것으로예상되고있다. 기존MS 신용카드와같은크기및두께의프라스틱카드에 Micro Processor, EEPROM, RAM, ROM 등의하드웨어적인구성과 COS(Chip Operating System), 보안알고리즘기능의소프트웨어적인구성으로소형컴퓨터와같은구조이다. 그메모리영역인 EEPROM에는대량의정보를기록하고정보를쉽게읽을수없는고도의보안성을보장하는신매체의카드이다. 그림 20 스마트카드내부구성도

그림 21 사용할스마트카드의결선방식 IC 카드한장으로은행이나백화점의신용카드, CD 및 ATM 을이용할수있는현금입출금카드, 공중전화카드및 POS 와연동시스템을구축하여 EFT-POS( Electronic Fund Transfer-Point Of Sales) 기능을수반한직불카드및선불카드, 신분증으로사용할수있는기능등을동시에수행할수있는종합카드로써기존의자기카드에비해기능이뛰어나기때문에 Smart Card 라고도불리우고있으며, 자기카드보다는한차원앞선차세대카드로평가받고있다. 스마트카드는 ISO-7816 표준화규격을따르는차세대보안용저장미디어로알려져있다. 그러나기술적으로엄밀히말하면스마트카드는가장단순화된컴퓨터라고말할수있다. 스마트카드내에는 OS 가내장되어있고, 응용프로그램을실행시킬수있는가상머신시스템 (VMS) 이탑재되어있어다용도로활용될수있는장점이있다. VISA, Master 등글로벌신용카드업체는기존의마그네틱카드를스마트카드로전면교체하는작업을진행중이다. 스마트카드의장점은높은보안성과휴대성, 다양한응용분야로요약되며, 실제신용카드외에도인터넷트랜젝션, 유럽의 GSM, 위성 TV 셋업박스, 보안출입카드, 의료용 ID 카드등그활용분야가기하급수적으로늘고있다. 현재스마트카드를제조하는회사로는필립스, 인피니온, 아트멜등이대표적이고국내업체로는삼성이적극적으로개발및양산에참여하고있다.

제 2 절스마트카드시스템구축 1. 카드파일시스템 Ship-GPS Smart Card File System 선주 / 선박관련파일시스템구조도 선주정보항목구성 선주정보 최대크기 37 Bytes 크 항목 기 (By te) 비고 1 0 이름 Byte s 한글 5자리까지표현 7 주민등록번호 Byte Numeric to 4bits Conversion s 영문이름 20 Bytes 영문이름 Smart-Card Command 쓰기 읽기 비고 INS 0x54 0x54 P1 0 1 P2 0 0 이름 1 1 주민등록번호 2 2 영문이름 선박정보항목구성 선박정보 최대크기 36 Bytes 크 항목 기 (By te) 비고 1 7 선박번호 Byte s 총항해거리 3 최대 16,777,216 Km까지표현

Reference Year Serial Number Applet Version 2 Bytes Byte s 4 Byte s 1 0 Byte s Short 자료형기준년도 선박의총항해거리 최대 4,294,967,296 까지부여가능 (2).(2).(4) Smart-Card Command 쓰기 읽기 비고 INS 0x50 0x50 P1 0 1 P2 0 0 선박번호 1 1 총항해거리 2 2 Serial No 3 3 Applet Version 4 4 Reference Year Offset Time 표기법 Typedef struct _tagtsoffsettime BYTE yy : 4; BYTE mm: 4; UINT16 dd: 5; UINT16 hour: 5; UINT16 min: 6; CTSOffsetTime; 레코드내의실제일시는다음과같다. 년 : Reference Year + Offset Time 의년도월 / 일 / 시 / 분 : Offset Time 의월 / 일 / 시 / 분 Smart-Card Command 쓰기 읽기 INS 0x50 0x50 P1 2 3 P2 의미없슴 N (Record Index No.)

쓰기 : 한번에 1 개레코드씩 (24byte) 씀 읽기 : 한번에 3 개레코드씩 (24byte*3 개 =72byte) 읽음항해기록분석 읽기 쓰기 항해기록 항목 Re co r d #1 (1 2B yte s)) 일시 경도 위도 항해경과시간 최대크기 크기 (By te) 3 Byte s 4 Byte 4 Byte 1 Byte 1 2 0 2 Bytes(2Bytes+12*100Record), Queue 비고 CTSOffsetTime 참조 소수점이하 4 자리단위 (-: 서, + 동 ) 소수점이하 4 자리단위 (-: 남, + 북 ) ( 단위 : 분 ) Re co r d #1 0 Re co r d #1 00 항해기록레코드는운항시매시간마다의정보가기록된다. Smart-Card Command 쓰기 읽기 INS 0x50 0x50 P1 10 11 P2 1 N (Record Index No.) 쓰기 : 한번에 1 개레코드 (12byte) 씩씀 읽기 : 한번에 10 개레코드 (12byte*10 개 =120byte) 씩읽음

2. 데이터베이스연결을위한시스템 그림 22 PC 와연결가능한스마트카드리더기 그림 23 스마트카드 그림 24 스마트카드를 PC 에서데이터를읽는사진

3. 선박용스마트카드데이터베이스프로그램 - 현재 PC 에서시뮬레이션수준에서구현되어있는 S/W 를 VMU 하드웨어에서구현하고, 궁극적으로선박적용과입출항신고서를자동으로인식이가능함을보여야한다. 그림 25 어선입출항신고서및해양경찰청출장소 현재어선들은해양경찰청의출장소등지에서입출항신고서를작성을하고입출항을하게되어있으며, 이과정은대부분수작업으로이루어져있다. 본프로젝트는어선입출항신고를자동으로이루어져야하는것이목적이기때문에어선입출항신고서양식과들어가는내용을숙지하여이를구현하여야한다. 이를위해서스마트카드의발급과정과데이터수집과정이필요하며, 스마트카드에있는데이터를읽는과정도필요하게된다. 다음은선박용스마트카드시스템에쓰이는프로그램의모습이며이를이용하여스마트카드를발급하고데이터를주고받는모습을캡처한것이다. 그림 26 선박용스마트카드시스템의초기화면

그림 27 초기에스마트카드를연결하는상태 그림 28 스마트카드를제대로인식하였을때의화면 그림 29 카드를인식하지못하거나잘못된카드가들어가는상태 그림 30 스마트카드에데이터를입력하기위한창

그림 31 카드의데이터를데이터베이스로넘긴화면 그림 32 카드의데이터를입력받아서보여주는화면

제4장실험및결과제1절성능시험및 EEZ 실험목표 : 실제어선환경에서실험을실행하고, EEZ상에서 GPS의수신이가능한지, 수신율은어떤지실험을하였다. 실험일정 : 국내해안실험국내해안실험실시 1차년도에주로차량에서시험을해왔던문제점을극복하기위해서 2차년도에는국내어선실험을추진하였으며이를통해프로젝트의현실성및장점등을파악할수있었다. 그림 33 국내연안실험 EEZ 실험 그림 34 EEZ 실험을위한인천 - 위해간실험 EEZ 실험은거리가상대적으로멀고, 실험만을위해서선박을빌리기가불가능하여 EEZ 를넘나드는중국위해와인천을오가는여객선에서실험을대신하였다.

실험에서 GPS 데이터수집은문제가없었으며, COLD Start 가늦은감이있었으나, 일단시작이되면바다위에서의 GPS 는수신율이좋았다. 그림 35 GPS 데이터수집과정 제 2 절개발과정상의문제점 1. 연안어선실험 : 실제어선에서실험을위해서연안의항구에서배를수배하여실제데이터를수집하였다. 연안실험의경우바닷물이나빗물이언제라도들어오는상황이었으며, 바닷물이갑판이오가는상황이었다. 실험한배는높은파고때문에 EEZ 까지는가기어려운어선이었으며실제열악한어선환경의데이터수집을위한실험이었다. 그림 36 실험한어선과비슷한어선 2. EEZ 와 NLL 의실험본과제는 EEZ 나 NLL 을넘나드는어선에장치하여조업활동후에조업궤도를알수있는장치이다. 따라서실제어선실험을위해서는 EEZ 와 NLL 을갈수있는어선에서

실험을해야하지만, 현실적으로불가능하였다. EEZ : 조업을하는일반어선의경우소형어선이대부분이었으며, EEZ 까지가는어선은마침일반과의독도조사선마찰이심해지면서가는것자체를꺼려했음. 또한, 실험을목적을밝히면대부분의어선들이반감을드러내서실험불가능. 해군에서실시하는민간인들을대상으로하는안보교육을참가하여 EEZ 까지가려했으나시기가맞지않아서실시하지못함. NLL : 연평도, 흑산도부근의어선들은 NLL 에대한얘기가꺼내기어려웠음. 따라서, EEZ 부근실험을위하여인근국가의항해선을타기로결정하였으나, 일본은쾌속이대부분이라시간이짧고갑판에나갈수가없어서실험포기. 중국으로가는배에서실험을결정하였음. 실험은인천에서가장가까운위해로결정하였으며이배는 12 시간정도를운행하는배이다. 갑판에서 COLD 부팅을한후엔선실에서도데이터수집이가능하였음. 제 3 절 GPS 데이터를프로그램에서실행한결과그림 그림 37 GPS 데이터분석화면위의데이터는연구목적으로북방한계선에침범할수없다는조건하에임의의범위를잡아서 GPS 신호를받아서출력한이미지임. 녹색은침범전, 적색은임의의값침범후인데우측에침범위치에대해적색으로표현되고있음.

제 5 장사업화계획 제1절최종기술개발결과물의시장분석 1. 입출항신고기능을겸비한어선위치기록스마트카드시스템 - 이시스템의수요자는어민, 선주, 어선및해양자원의관리감독을원하는정부기관인데수요자들은상황에따라서다른특성을가지고있어서이들을분석하고이들에맞는마케팅방법을다르게추진하여야한다. 따라서이들의입장에따른성향및이에따른시장을분석한다. 2. 소수의선박을가지고직접조업을하는어민 - 이들은대다수의어민이기도하며조업을하는주체이기도하다. 이시장의특징은공공의목적에는관심이적고조업에도움이되는장치를구입한다. 이시장의경우에는전체시스템에서 VMU에해당하는장치를판매하여야한다. 이경우 VMU 단독으로도경쟁력있게제작을한다. 따라서저가의선박용 GPS 장치를개발한다. 이때스마트카드는입출항신고용이아닌데이터를옮기는저장장치로서의기능만을수행하는데수요자는 GPS 데이터를자신의집에있는컴퓨터에연결하여자신이조업활동을한영역과시간을그래픽으로확인할수있다. 따라서저가의 GPS를구매하고자하고부가기능으로집에서자신의경로파악을원하는소비자라고정의한다. 3. 다수의선박을가지고있는선주 - 전체선박의많은경우배를소유한선주와이를운영하는선장이다른데이경우수요자는선장이아니고선주이다. 선주의경우에는같은배에서도수확량이다르고때에따라조업량이달라서이를관리하고자하는필요성을가지고있다. 이경우저가의 VMU도중요하지만이를통하여스마트카드에담겨있는데이터의중요성도한층더한다. 이시장에서는저가의 VMU 물론중요하지만, 스마트카드발급장치, 데이터관리를위한서버도필요하게된다. 또한각어선들의비교움직임분석도필요하기때문에이경우에는출입항자동신고기능을제외한모든시스템을구매할수있는시장이며이들이원하는어선경로비교등의기능을추가로원하는시장이다. 4. 어선과해양자원관리감독을원하는정부기관 ( 공공기관 ) - 동시스템을구매하여서가장이익을볼수있는수요자는바로이경우이다. 동시스템의모든기능을필요로하며관리감독을위한인력, 노력의절약을할수있음은물론이고, 아직까지인력및자원의부족으로할수없었던어업자원관리도효율적으로할수있으며, 북방한계선과배타적경제수역에서의마찰을줄일수있으므로국가적으로도커다란이익을얻을수있는수요자이다. 다만이수요층은의사결정이매우느리며수많은이익단체의압력이상존하는시장이므로제품의유용성에대한홍보와이장치의적용으로이익을볼수있는관련단체들과의효과적인대응이

필요한시장이기도하다. 5. 대형선박에장착되는블랙박스업체나선박용 PC를제조하는업체이러한업체의장치에서일어난데이터수거하고분석하는일은매우중요한일이다. VMU에설치가된통신포트를이용하여이러한데이터를주고받으며스마트카드를이용하여이를가져올수있으면보안성, 편리성이뛰어난스마트카드의시장이된다. 제2절사업화계획및매출목표 ( 시장진입을위한사업화계획 ) 1. 소수의선박을가지고직접조업을하는어민 - 시장분석에서밝힌것처럼이들은데이터베이스의유용성보다는 VMU의 GPS 기능에관심을가질것이다. 따라서유통채널을확보하고, 저가의 VMU를개발공급하며관련프로그램은인터넷상으로받을수있도록하여판매를위한비용을최소화하는것이중요하다. 현재조사로는선박용 GPS장치의경우가격이 1,500,000원에서 3,000,000원까지존재하고있다. 따라서이시장을공략하기위해서는전체시스템의소비자가격은 500,000원을넘지않도록기획하며, 그대신그래픽 LCD등의적용은가격부담이크므로저가의 TEXT LCD를채택하는대신스마트카드로데이터를받아서컴퓨터에연결하면이때그래픽으로분석하는프로그램을제공한다면수요자들은저가의 GPS장치를구매할수있을뿐아니라나중에컴퓨터에서자신의조업기록을분석할수있어서매우유용한제품이될것이다. 2. 다수의선박을가지고있는선주 - 앞에서언급한것과같이이시장은시스템전체를구매할가능성이높으며 VMU의경우도하나를구매하기보다는여러대의 VMU를구매할것이다. 따라서이시장은마진을보장해주어야하는유통채널 ( 대리점 ) 을이용하기보다는회사에서직판을통하여홍보하고판매하여야한다. 이경우대리점으로인한마진을깍아주어 VMU를공급하고, 대신시스템의서버와카드발급시스템을공급하여고객의요구사항에맞추어프로그램할필요가있다. 직접판매를하는만큼홍보비등의비용보다는본사의영업사원의인센티브를좋게하여시장확대가이루어지도록하여야한다. 3. 어선과해양자원관리감독을원하는정부기관 ( 공공기관 ) - 동시스템을구매하여서가장이익을볼수있으며상대적으로예산이많은곳이다. 하지만직접 VMU장치를사용하지는않으며시스템을구입하여이를통하여여러기능을활용할수있는수요처이다. 여러가지판매루트가존재하지만일단이시스템이원활하게사용되려면 VMU를가진선박이많아져야하므로이를위하여 VMU 를저가에구입하여저가에대여또는지급하는방안을유도해야한다. 선박들은자신들의움직임이노출되기때문에설치를꺼리기마련이며이에대한유도책으로초저가

의 GPS장치구입이가능하게하는방안이필요하다. 또한출입항신고제도를스마트카드로변경하여선박들이반드시서버에접촉하도록하는방안을마련하여야한다. 불법행위를하지않는선박의경우에는출입항신고가매우간편해지기때문에이를피할이유가없으므로이를강조하여선박들이스스로서버에접속하도록유도한다. 이후에는서버내의데이터를가공하고통신하고분석하는수준에따라서서버의판매가격을달리한다. 기본적으로북방한계선과배타적경제수역위반및공해상의미심쩍은경로에대한정보는기본프로그램으로비교적저가에공급하고, 공공기관등의수요자가필요에의해서가공을하여야하는데이터베이스프로그램과분석프로그램등은꼭필요하지만그수요가적으므로상대적으로높은개발비를책정한다. 관세청, 해양연구소, 통계청등조업및밀수가능성이있는선박감독어업자원의통계적, 정량적관리강조 해양경찰청등정부기관연계 NLL, EEZ 등을관할하는부서외교적사회적비용감안어민들의거부감해소가관건 많은배를거느린선주들공략선장들과선박을관리하기위한최선의솔루션을강조 일본, 미국, 스페인등해외시장 EEZ 관리와어업자원관리효율강조 소형고기배의선주, 어민저가의 GPS 장비를홍보 그림 38 마케팅방안 4. 블랙박스와선박용 PC를제작판매하는회사와의연동 VMU를필요로하는시장에는선박용블랙박스와선박용 PC를제작하는회사가있다. 선박의장치로부터데이터를받기위하여노트북을이용하거나엔지니어가직접찾아가서이를가져오기보다는선주나선원이 VMU를통하여이러한데이터를가져오고데이터를송수신할수있으면많은노력을줄일수있다. 5. 제조및판매방안 - 제조공정은서버와카드발급시스템의경우에는소량의구매이므로자체적으로해결이가능한과제이며, 제조를위한방안으로는현재제조시설을갖추지않았으

나검사장비및관련시설을갖추고투자비가많이들어가는 PCB 제조시설은외부에용역으로해결하고, 검사라인을확실하게갖추어외부용역시의불량에대한문제를해소한다. 3절중국 GPS 자동차운행기록계시장 1. 개요본프로젝트를시작할때는해군및해양경찰청의지인들을통하여필요성을인지하고시작하였다. 하지만, 실제개발을하면서실제어민들과어선주들을만나서미팅을하면서느낌점은장착되는어선의입장에서장착하기싫은장치라는것이다. 특히 NLL 근처의어민들의경우에는군인들을그들의일을방해하는존재로인식하고있어서장착할비용부담은물론이고무료로장착한다고해도장치에파손이우려되는상황이었음. 하지만, 어선입출항신고시의불편함을줄이는기능에대해서는대개긍정적인반응이많았다. 따라서이프로젝트가상업적인성공을하기위해서는국군이나해경의예산지원이필요함을느꼈으며, 의무사항이아니면적용이힘들어보였다. 하지만, 의무사항이되기위해서는법규제정및예산확보등절차와노력이결코쉽지않다고한다. 이에따라판로개척을위하여중국시장에기술을소개하는와중에선박이아닌트럭에장착하기를희망하는회사를만났으며의외로시장성이높음을알수있었다. 중국의트럭의경우며칠씩걸리는장거리운행이많았으며이때차주는고속도로톨게이트비용등을모두지불하지만, 트럭운전수들이지방도로를다녀서차량파손도심하고운행시간도늘어지는문제점이다수나타나고있다고한다. 이에따라트럭마다 GPS장치를의무화하는업체들이늘어나고법제화도추진된다고한다. 이런트럭회사에소개를한결과현재의개발가격이면충분히장착을검토하겠다고하여관련프로젝트를추진중이다. 이러한트럭회사에장착하여성능을검증하고검증된제품을추후본래목적하고자했던 EEZ나 NLL 지역에투입하게된다면보다좋은성능으로사용자를만족시킬수있으리라판단된다. 2. 중국블랙박스시장중국은 2008년북경올림픽경기개최를즈음하여일찍이 2003년차량용블랙박스에대한표준 (GB/T 19056-2003) 을만들었으며, 2005년말까지사업용자동차, 2007년말까지전차량 GPS자동차운행기록계장착의무화계획을발표하였다. 피엘케이는본과제로개발한장치의판로를개척하기위해서많은노력을기울이던차에개발된장치가중국의시장에서요구하는장치와매우유사함을알게되었다. 본장치, 특히 2차년도에개발한장치는 IP등급은 IP06으로맞춘장치로서 GPS데이터를수집하고이를스마트카드로읽어서서버에데이터베이스화하는장치이다. 현재접촉중인회사들의설명에따르면이들이원하는장치가이와유사함을알수있다. 현재 GPS형의차량용블랙박스를만드는회사는중국내에 10여개, 한국내에 1,2개정도로파악하고있으며이들은대부분 USB메모리로데이터를수집하고있었다.

하지만접촉중인북경의운송회사에서는아무나읽을수있는 USB메모리이외에스마트카드와같은보안을할수있는장치를원하고있으며현재스마트카드로되어있는제품은중국의한회사만이제조하고있다. 그림 39 차량용 GPS 운행기록계 3. 중국시장진출계획피엘케이는북경의운송업체가요구하고있는운전자별비밀번호기능 ( 스마트카드에따라해당운전자가구분됨 ) 과스마트카드를통한운전자인식및운행기록저장기능을구현하여 07년 3월까지초도샘플을제공하기로하였으며, 이결과에따라그매물량을정하기로하였다. 또한, 블랙박스의무장착의영역이넓어짐에따라서청도와상해지역의운송회사에서도접촉이진행되고있다. 중국시장진출의문제점은중국공안의인증을통과하여야하는단계가남아있는데이과정에서는현재접촉하고있는업체에일정부분의판권을주는조건으로북경의업체에서진행하도록유도중이다. 또한, 단가하락을이유로중국생산을주장하고있으나, 이는섣불리추진하다가기술유출의우려가있어서주문하는수량에따라서탄력적으로운영하기로하였다.

제6장첨부 제1절 FirmWare Source Code Firware 제작 FirmWare는 C코드를중심으로짜여져있으며, 관련된 include 파일은다음과같다. 2005-11-14 오후 07:51 948 Define.h 2005-11-14 오후 07:51 1,801 Display.h 2005-11-14 오후 07:50 2,027 eepr.h 2005-11-14 오후 08:09 2,103 GPS.h 2005-11-14 오후 07:50 1,433 lcd.h 2005-11-14 오후 07:51 798 OnEEPROM.h 2005-11-17 오후 05:02 29 r.txt 2005-11-14 오후 07:51 6,487 REGCC01.H 2005-11-14 오후 07:51 798 scufn.h 2005-11-14 오후 07:51 1,710 Serial.h 2005-11-14 오후 07:51 1,341 SysSet.h 2005-11-14 오후 07:51 4,149 TDA_Card.h 2005-11-14 오후 07:51 252 timer.h 관련된 C 프로그램파일은다음과같다 2005-11-14 오후 08:04 17,305 Card.c 2005-11-14 오후 08:02 3,787 display.c 2005-11-14 오후 07:59 6,131 eepr.c 2005-11-14 오후 08:09 9,317 GPS.c 2005-11-14 오후 07:58 3,013 lcd.c 2005-11-14 오후 07:57 13,415 main.c 2005-11-14 오후 08:06 2,294 OnEEPROM.c 2005-11-17 오후 05:03 29 r.txt 2005-11-14 오후 07:56 8,019 scufn.c 2005-11-14 오후 08:07 4,030 Serial.c 2005-11-14 오후 07:55 6,874 Setup.c 2005-11-14 오후 07:51 3,034 SysSet3.C 2005-11-14 오후 08:06 12,502 TDA.c 2005-11-14 오후 08:05 829 timer.c 2005-11-14 오후 08:05 1,362 Timer0.c 이중에핵심코드에해당하는 Card.C와 GPS.c를다음과같이첨부하며, 내용이많아서폰트를 6으로 하고다단편집을하였음. // Card.c: Card Read/Write Operation #include "Serial.h" #include "TDA_Card.h" #include "eepr.h" #include "lcd.h" #include <string.h> #include <stdio.h> / * ----------------------- ----------------------- ------- 1. 1초에한번 CardTest() 와 CardSpeed() 를호출한다음통신선을돌려받는다. 2. 돌려받는즉시 TDA로부터어떤메시지가들어오고있을가능성이있다. 예를들어카드의삽입 / 적출같은경우가발생할 수있다. 이런경우 TSCU는현재들어오고있는메시지가끝날때까지대기해야한다. 0.1초동안더이상아무메시지도없으면메시지전송이끝난것으로판단한다. 3. usrlrbuffidx = bsrlrtotmsgcnt = 0; bittdabusy = false; bsrlstatus = 0; btdaerror = 0;

btdaexpcmd = 0xEE; 4. INT1에변화가생겼다면카드가삽입됐거나적출된경우이다. 이런경우 TDA_check_reader_status() 를호출해카드가삽입되어있는지확인한다. 그리고카드가삽입된경우라면 1. TDA_power_up_iso() 2. CardGetUserName() 3. CardGetRefTime() 4. CardGetUserMsg() 5. CardWriteDiagnosis() 를차례로호출해서카드정보를갱신하고단계 1로간다. 5. 카드가정상적인상태로돌아간다는가정하에서 GPS로부터얻어진항해정보를갱신한다. TdaAutoReader() 기본적인역할은 CardCommand() 에의해보내진명령을완료하는역할이다. 1. 현재통신이진행되고있으면, 아무짓도않한다. 2. bittdabusy가 1인데 2초동안아무응답도없다면 TDA는멈춘것이다. 3. TDA가 Command에응답했다면 bittdabusy를 0 으로리셋한다. 이런경우 TSCU는단계1로돌아가야한다. ----------------------- ----------------------- ------- */ bit bitcardreadatr; bit bitcardselectapp; bit bitcardreadreftime; bit bitcardreadshipnum; bit bitcardwritediagnosis; bit bitcardwritedriverptn; bit bitcardwritemileship; bit bitcardwritemileuser; bit bitcardwritemileowner; bit bitcardreadusername; bit bitcardreadusermsg0; bit bitcardreadusermsg2; bit bitcardreadusermsg4; bit bitcardreadusermsg6; bit bitcardreadusermsg8; bit bitcardreaduserinfo2; bit bitcardwritedriverptndont; bit bitshipnumequal; void CardOpAllOff() bitcardreadatr = false; bitcardselectapp = false; bitcardreadreftime = false; bitcardreadshipnum = false; bitcardwritediagnosis = false; bitcardwritedriverptn = false; bitcardwritemileship = false; bitcardwritemileuser = false; bitcardwritemileowner = false; bitcardreadusername = false; bitcardreadusermsg0 = false; bitcardreadusermsg2 = false; bitcardreadusermsg4 = false; bitcardreadusermsg6 = false; bitcardreadusermsg8 = false; bitcardreaduserinfo2 = false; void CardOpAllOn() bitcardreadatr = true; bitcardselectapp = true; bitcardreadreftime = true; bitcardreadshipnum = true; bitcardwritediagnosis = true; bitcardreadusername = true; bitcardreadusermsg0 = true; bitcardreadusermsg2 = true; bitcardreadusermsg4 = true; bitcardreadusermsg6 = true; bitcardreadusermsg8 = true; static xdata U08 bt1sequence; xdata U08 bcardatrlen; Data Len xdata U08 arbcardatr[40]; // arbcardatr's // 32 + Dummy. Updated in TDA_power_up_iso() xdata U08 arbcardparam[3]; // FiDi CC TT xdata U08 bcardt; // T=0 or T=1 xdata U08 bcardtype; 1=JCOP10 xdata U16 ureftimer; Information xdata U16 urefyear; xdata U08 arbshipnum[17]; // 0=Win, // Card's // Year of ulreftime // Ship Number xdata U08 arbusername[20]; // Card's Information xdata U08 arbusermsg[10][32]; // Card's Information. Read 32*2 bytes xdata Card_USER_INFO2 ouserinfo2; Setup Process xdata U16 udriverptncardidx; Index for DriverPtn xdata U16 udiagnosiscardidx; Index for Diagnosis xdata U32 ulmileshipold; mileage xdata U32 ulmileuserold; mileage xdata U32 ulmileownerold; mileage xdata U32 ulmileshipgap; // Used in // Card Writing // Card Writing // Save Ship's // Save User's // Save Owner's // Writed Mileage Data, at changing mileage's 1Km(=1) xdata U32 ulmileusergap; // Writed Mileage Data, at changing mileage's 1Km(=1) xdata U32 ulmileownergap; // Writed Mileage Data, at changing mileage's 1Km(=1) void swaplongvar(u32 *a_pulvar) union LONG_BYTE U08 arb[4]; U32 ull; ltemp1, ltemp2; ltemp1.ull = *a_pulvar; ltemp2.arb[0] = ltemp1.arb[3]; ltemp2.arb[1] = ltemp1.arb[2]; ltemp2.arb[2] = ltemp1.arb[1]; ltemp2.arb[3] = ltemp1.arb[0]; *a_pulvar = ltemp2.ull; U16 getrefyear(u16 a_uyear) U16 utemp; utemp = ((a_uyear >> 8) & 0x00FF); utemp = ((a_uyear << 8) & 0xFF00); return utemp; // Get Data's LRC U08 getlrc(void *a_pbuff, U16 a_ibufflen) data U08 bxor = 0; data U16 i; for (i = 0; i < a_ibufflen; i++) bxor ^= *((U08*)a_pBuff); ((U08*)a_pBuff)++; return bxor; // Hard Reset Card and Receive ATR -> update arbcardatr[] BOOL CardGetATR() static code U08 stdaready[] = 0x60, 0x00, 0x00, 0xBB; static code U08 spowerup [] = 0x60, 0x00, 0x01, 0x69, 0x00;// IOS Reset 3v->5v static code U08 sgetparam[] = 0x60, 0x00, 0x00, 0xA6; // Get FiDi CC TT static code U08 ssetifsd [] = 0x60, 0x00, 0x01, 0x0C, 0xFE;// Set IFSD with 254 data U08 bhistorylen; if (bsrlstatus!= 0) _SrlClrRBuff(); return false; // Error or Busy if (memcmp(arbsrlrbuff, stdaready, sizeof(stdaready))!= 0) TdaSendReady(); // Transmit _SrlClrRBuff(); memcpy(arbsrltbuff, spowerup, sizeof(spowerup)); SrlSendMsg(sizeof(sPowerUp)+1); // Receive if (TdaGetResponse(0x69, 0)!= 0) _SrlClrRBuff(); return false;

// Check Error if (arbsrlrbuff[0] == 0xE0) TdaGetResponse(_TDA_NONE_CMD, 0); _SrlClrRBuff(); return false; // Response: 0x60 0x?? 0x?? 69 [ATR's data] LRC // Get ATR bcardatrlen = arbsrlrbuff[_tda_frame_lenl]; m e m c p y ( a r b C a r d A T R, &arbsrlrbuff[_tda_frame_msg], bcardatrlen); //////// Get TDA's Card Parameters FiDi CC TT memset(arbcardparam, 0xFF, sizeof(arbcardparam)); _SrlClrRBuff(); TdaStart(); if (memcmp(arbsrlrbuff, stdaready, sizeof(stdaready))!= 0) TdaSendReady(); // Transmit _SrlClrRBuff(); memcpy(arbsrltbuff, sgetparam, sizeof(sgetparam)); SrlSendMsg(sizeof(sGetParam)+1); // Receive if (TdaGetResponse(0xA6, 8)!= 0) _SrlClrRBuff(); return false; // Response: 0x60 0x00 0x03 0xA6 FiDi CC TT LRC // Get Paramters m e m c p y ( a r b C a r d P a r a m, &arbsrlrbuff[_tda_frame_msg], 3); bcardt = arbcardparam[2]; bhistorylen = arbcardatr[1] & 0x0F; i f (memcmp(arbcardatr+bcardatrlen- 1-bHistoryLen, "JCOP10", bhistorylen) == 0) bcardtype = Card_TYPE_JCOP10; else bcardtype = Card_TYPE_WINCard; bcardt = 0; //////// Set IFSD when T=1 ////////////// if (bcardt == 1) _SrlClrRBuff(); TdaStart(); TdaSendReady(); // Transmit _SrlClrRBuff(); memcpy(arbsrltbuff, ssetifsd, sizeof(ssetifsd)); SrlSendMsg(sizeof(sSetIFSD)+1); // Receive if (TdaGetResponse(0x0C, 5)!= 0) _SrlClrRBuff(); return false; // Clear Sequence bt1sequence = 0; bitcardreadatr = false; return true; U08 SCardTransmit(U08 a_bt, U08 *a_psendbuff, U16 a_usendlen, U08 *a_precvbuff, U16 a_urecvlen) static code U08 stdaready[] = 0x60, 0x00, 0x00, 0xBB; data BYTE2 ubyte2; data U08 bstatus; if (bsrlstatus!= 0) _SrlClrRBuff(); return 1; if (memcmp(arbsrlrbuff, stdaready, sizeof(stdaready))!= 0) TdaSendReady(); ubyte2.w = a_usendlen; if (a_bt == 1) ubyte2.w += _TDA_T1_LEN; // NAD, PCB, LEN,..., EDC arbsrltbuff[_tda_frame_ack ] = 0x60; arbsrltbuff[_tda_frame_lenh] = ubyte2.b.hi; arbsrltbuff[_tda_frame_lenl] = ubyte2.b.lo; arbsrltbuff[_tda_frame_cmd ] = a_bt; if (a_bt == 1) arbsrltbuff[_tda_frame_t1_nad] = 0x00; arbsrltbuff[_tda_frame_t1_pcb] = bt1sequence; arbsrltbuff[_tda_frame_t1_len] = a_usendlen; bt1sequence ^= 0x40; memcpy(arbsrltbuff+_tda_frame_t1 _DATA, a_psendbuff, a_usendlen); /* */ _usendlen] = getlrc(arbsrltbuff+_tda_frame_t1_ NAD, a_usendlen + _TDA_T1_LEN-1); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrltbuff[0], arbsrltbuff[1], arbsrltbuff[2], arbsrltbuff[3], arbsrltbuff[4], arbsrltbuff[5], arbsrltbuff[6], arbsrltbuff[7]); LcdText(TOP_LEFT, buf); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrltbuff[8], arbsrltbuff[9], arbsrltbuff[10], arbsrltbuff[11], arbsrltbuff[12], arbsrltbuff[13], arbsrltbuff[14], arbsrltbuff[15]); LcdText(BOTTOM_LEFT, buf); WatchReset(0); while (arwatch[0].ulsec < 30); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrltbuff[16], arbsrltbuff[17], arbsrltbuff[18], arbsrltbuff[19], arbsrltbuff[20], arbsrltbuff[21], arbsrltbuff[22], arbsrltbuff[23]); LcdText(TOP_LEFT, buf); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrltbuff[24], arbsrltbuff[25], arbsrltbuff[26], arbsrltbuff[27], arbsrltbuff[28], arbsrltbuff[29], arbsrltbuff[30], arbsrltbuff[31]); LcdText(BOTTOM_LEFT, buf); WatchReset(0); while (arwatch[0].ulsec < 30); else memcpy(arbsrltbuff+_tda_frame_cla, a_psendbuff, a_usendlen); if (memcmp(arbsrlrbuff, stdaready, sizeof(stdaready))!= 0) arbsrltbuff[_tda_frame_t1_data+a // Transmit _SrlClrRBuff();

SrlSendMsg(_TDA_BASE_LEN+uByte2.w); // Receive if ((bstatus = TdaGetResponse(a_bT, 0))!= 0) _SrlClrRBuff(); return 2; /* s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrlrbuff[0], arbsrlrbuff[1], arbsrlrbuff[2], arbsrlrbuff[3], arbsrlrbuff[4], arbsrlrbuff[5], arbsrlrbuff[6], arbsrlrbuff[7]); LcdText(TOP_LEFT, buf); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbsrlrbuff[8], arbsrlrbuff[9], arbsrlrbuff[10], arbsrlrbuff[11], arbsrlrbuff[12], arbsrlrbuff[13], arbsrlrbuff[14], arbsrlrbuff[15]); LcdText(BOTTOM_LEFT, buf); WatchReset(0); while (arwatch[0].ulsec < 30); */ // Check Error if (arbsrlrbuff[0] == 0xE0) _SrlClrRBuff(); return 3; if ((a_precvbuff == NULL) (a_urecvlen == 0)) return 0; if (a_bt == 1) m e m c p y ( a _ p R e c v B u f f, &arbsrlrbuff[_tda_frame_t1_data], a_urecvlen); /* s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", a_precvbuff[0], a_precvbuff[1], a_precvbuff[2], a_precvbuff[3], a_precvbuff[4], a_precvbuff[5], a_precvbuff[6], a_precvbuff[7]); LcdText(TOP_LEFT, buf); X%02bX%02bX", a_precvbuff[8], a_precvbuff[9], a_precvbuff[10], a_precvbuff[11], a_precvbuff[12], a_precvbuff[13], a_precvbuff[14], a_precvbuff[15]); LcdText(BOTTOM_LEFT, buf); WatchReset(0); while (arwatch[0].ulsec < 10); */ else m e m c p y ( a _ p R e c v B u f f, &arbsrlrbuff[_tda_frame_msg], a_urecvlen); return 0; BOOL CardCommand(Card_CMD a_bcmd, U08 a_uidx) enum _Cmd_CLA = 0, _Cmd_INS, _Cmd_P1, _Cmd_P2, _Cmd_LEN, _Cmd_Send, _Cmd_Recv ; #define _Cmd_DATA (_Cmd_LEN+1) #define _Cmd_BASE_LEN (_Cmd_LEN+1) static code U08 arbcardcmdstr[][5+2] = // CLA, INS, P1, P2, LEN Send Recv 0x00,0xA4, 4, 0,0xFF, 0xFF, 0, // _CardSelectApp, 0x00,0x54, 1, 2, 20, 0, 20, // _CardGetUserName, 0x00,0x50, 1, 4, 2, 0, 2, // _CardGetRefTime, 0x00,0x50, 1, 0, 17, 0, 17, // _CardGetShipNum 0x00,0x50, 17, 0, 64, 0, 64, // _CardGetUserMsg, 0x00,0x50, 6,0xFF, 73, 73, 0, // _CardPutDiagnosis, 0x00,0x50, 10, 1, 12, 12, 0, // _CardPutDriverPtn, 0x00,0x50, 0, 1, 3, 3, 0, // _CardPutMileShip 0x00,0x50, 0, 5, 3, 3, 0, // _CardPutMileUser 0x00,0x50, 0, 6, 3, 3, 0, // _CardPutMileOwner 0x00,0x50, 1, 7, 44, 0, 44, // _CardGetUserInfo2 ; static code U08 szselectapp[] = "SCUApplet"; T1_LEN]; data U08 bsendlen, brecvlen; if (a_bcmd >= _CardCmdEnd) _SrlClrRBuff(); return 1; // Make Command Buffer: arbbuff memcpy(arbbuff, arbcardcmdstr[a_bcmd], _Cmd_BASE_LEN); // Get Default SendLen, RecvLen bsendlen = arbcardcmdstr[a_bcmd][_cmd_send]; brecvlen = arbcardcmdstr[a_bcmd][_cmd_recv]; switch (a_bcmd) case _CardSelectApp: if (bcardtype == Card_TYPE_JCOP10) bsendlen = sizeof(szselectapp)-1; arbbuff[_cmd_len] = bsendlen; memcpy(&arbbuff[_cmd_data], szselectapp, bsendlen); else bitcardselectapp = false; return 0; break; case _CardGetUserMsg: a_uidx %= 5; arbbuff[_cmd_p2] = (U08)a_uIdx*2; break; case _CardPutDiagnosis: writeoffsettime(&arbbuff[_cmd_data]); // 3 Bytes memcpy(&arbbuff[_cmd_data+3], Diagnosis, bsendlen-3); // 70 Bytes break; case _CardPutDriverPtn: memcpy(&arbbuff[_cmd_data], DriverPtn[a_uIdx], bsendlen); break; case _CardPutMileShip: swaplongvar(&ulmileshipgap); memcpy(&arbbuff[_cmd_data], &ulmileshipgap, 3); break; case _CardPutMileUser: swaplongvar(&ulmileusergap); memcpy(&arbbuff[_cmd_data], &ulmileusergap, 3); break; case _CardPutMileOwner: swaplongvar(&ulmileownergap); memcpy(&arbbuff[_cmd_data], &ulmileownergap, 3); break; s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b xdata U08 arbbuff[254+_tda_base_len+_tda_ // Transmit if ((bsendlen = SCardTransmit(bCardT, arbbuff,

/* _Cmd_BASE_LEN+bSendLen, arbbuff, brecvlen))!= 0) _SrlClrRBuff(); return false; // Final Process switch (a_bcmd) case _CardSelectApp: bitcardselectapp = false; break; case _CardGetUserName: memcpy(arbusername, arbbuff, brecvlen); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbbuff[0], arbbuff[1], arbbuff[2], arbbuff[3], arbbuff[4], arbbuff[5], arbbuff[6], arbbuff[7]); LcdText(TOP_LEFT, buf); s p r i n t f ( b u f, "%02bX%02bX%02bX%02bX%02bX%02b X%02bX%02bX", arbbuff[8], arbbuff[9], arbbuff[10], arbbuff[11], arbbuff[12], arbbuff[13], arbbuff[14], arbbuff[15]); LcdText(BOTTOM_LEFT, buf); false; else if (a_uidx == 3) bitcardreadusermsg6 = false; else if (a_uidx == 4) bitcardreadusermsg8 = false; break; case _CardPutDiagnosis: bitcardwritediagnosis = false; udiagnosiscardidx = QueDiag; break; case _CardPutDriverPtn: bitcardwritedriverptn = false; if (++udriverptncardidx >= 100) udriverptncardidx = 0; // udriverptncardidx = QuePtn; break; case _CardPutMileShip: bitcardwritemileship = false; ulmileshipold = mileage; break; case _CardPutMileUser: bitcardwritemileuser = false; ulmileuserold = mileage; break; case _CardPutMileOwner: bitcardwritemileowner = false; ulmileownerold = mileage; break; case _CardGetUserInfo2: memcpy(&ouserinfo2, arbbuff, brecvlen); bitcardreaduserinfo2 = false; break; // Sample: Data // 0 1 2 3 4 5 6 7 / / 012345678901234567890123456789012 345678901234567890123456789012345 67890123456789 / / $PNVCAM,0,000000000000,000,0000.00 00,N,00000.0000,E,00,0,000000,00,000,0 00*20 / / $PNVCAM,3,031008090417,000,3723.79 11,N,12658.5617,E,00,0,000000,00,000,0 00*24 / / $PNVCAM,3,031008090418,002,3723.79 07,N,12658.5617,E,00,0,000000,00,000,0 00*2E / / $PNVCAM,3,031008090419,009,3723.79 07,N,12658.5626,E,00,0,000000,00,000,0 00*26 / / $PNVCAM,3,031008090420,016,3723.79 07,N,12658.5649,E,00,0,000000,00,000,0 00*2B //////////////////////////////////////////////////////////////////////////// ///// SDATA GPS_MSG argpsmsg[gps_msg_max]; SDATA U16 ugpsmsgwriteidx; SDATA U16 ugpsdataidx; SDATA U32 lgpsmsgallcnt; SDATA U32 lgpsmsgchkerrcnt; SDATA U32 lgpsmsgcnt; static XDATA char arcgpsdata[2048]; U16 ugpserrorlen; XDATA char arcgpserrorcode[256]; */ WatchReset(0); while (arwatch[0].ulsec < 10); bitcardreadusername = false; break; case _CardGetRefTime: memcpy(&ureftimer, arbbuff, brecvlen); urefyear = getrefyear(ureftimer); bitcardreadreftime = false; break; case _CardGetShipNum: memcpy(arbshipnum, arbbuff, brecvlen); bitcardreadshipnum = false; break; case _CardGetUserMsg: memcpy(arbusermsg[a_uidx*2], arbbuff, brecvlen); if (a_uidx == 0) bitcardreadusermsg0 = false; else if (a_uidx == 1) bitcardreadusermsg2 = false; else if (a_uidx == 2) bitcardreadusermsg4 = _SrlClrRBuff(); return 0; // GPS.c: NAVIUS GPS UART Protocol. #include <string.h> //////////////////////////////////////////////////////////////////////////// ///// // Sample: Reset // $Version 2.3.2-GSW2-2.05.024-C1Prod1.1 // $User Version: NSAX3 PLUS - PLK v0.2 2004.09.13 // $TOW: 0 // $WK: 1231 // $POS: 6378137 0 0 // $CLK: 96000 // $CHNL:12 // // $Baud rate: 9600 System clock: 24.553MHz$HW Type: S2AM // $Asic Version: 0x23 // $Clock Source: GPSCLK // $Internal Beacon: None / / $PNVCAM,3,031008085947,109,3726.66 47,N,12659.8146,E,00,0,000000,00,000,0 00*27 // GPS_VALUE ogpstest; #pragma optimize_for_space void GpsMakeMsg() char arcbuff[256]; U16 ustrlen, i; char *pstartmsg; char *pendmsg; char *pendmsg2; while (true) if (ugpsmsgwriteidx >= GPS_MSG_MAX) return; ustrlen = UartRxCount(); if ( ustrlen >= sizeof(arcbuff) ) ustrlen = sizeof(arcbuff) - 1; if (ustrlen <= 3) return; // $~~~~CRLF UartReadPre(arcBuff, ustrlen); arcbuff[ustrlen] = 0; if (arcbuff[0]!= '$') ugpserrorlen = ustrlen; for (i = 0; (i < sizeof(arcgpserrorcode))

&& (i < ugpserrorlen); i++) arcgpserrorcode[i] = arcbuff[i]; pstartmsg = strchr(arcbuff, '$'); if (pstartmsg == NULL) if (arcbuff[0] == 0) for (i = 1; i < ustrlen; i++) if (arcbuff[i]!= 0) break; ustrlen = i-1; if (ustrlen < 1) ustrlen = 1; else ustrlen = strlen(arcbuff); UartReadClr(uStrLen); continue; pendmsg = strchr(pstartmsg+1, 0x0D); if ((pendmsg[0] == 0x0D) && (pendmsg[1] == 0x0A)) pendmsg++; else pendmsg = NULL; pendmsg2 = strchr(pstartmsg+1, '$'); if ( (pendmsg == NULL) && (pendmsg2!= NULL) ) pendmsg = pendmsg2; pendmsg--; else if ( (pendmsg!= NULL) && (pendmsg2!= NULL) ) if (pendmsg2 < pendmsg) pendmsg = pendmsg2; pendmsg--; if (pendmsg == NULL) if (pstartmsg!= arcbuff) UartReadClr( (U16)(pStartMsg - arcbuff) ); continue; else return; pendmsg++; ustrlen = pendmsg - pstartmsg; pstartmsg, ustrlen); arcgpsdata[ugpsdataidx+ustrlen] = 0; argpsmsg[ugpsmsgwriteidx].pmsg = &arcgpsdata[ugpsdataidx]; argpsmsg[ugpsmsgwriteidx].ulen = ustrlen; ugpsmsgwriteidx++; ugpsdataidx += (ustrlen+1); UartReadClr( (U16)(pEndMsg - arcbuff) ); lgpsmsgallcnt++; void GpsClearMsg() ugpsmsgwriteidx = 0; ugpsdataidx = 0; void GpsSendMsg(char *a_pszcmd) U16 i; U08 bchksum = 0; U08 arbbuff[128]; arbbuff[0] = a_pszcmd[0]; for (i = 1; i < (sizeof(arbbuff)-2); i++) if (a_pszcmd[i] == 0x00) break; arbbuff[i] = a_pszcmd[i]; bchksum ^= a_pszcmd[i]; arbbuff[i++] = '*'; arbbuff[i] = (bchksum >> 4) + '0'; if (arbbuff[i] > '9') arbbuff[i] = arbbuff[i] - '0' - 0x0A + 'A'; i++; arbbuff[i] = (bchksum & 0x0F) + '0'; if (arbbuff[i] > '9') arbbuff[i] = arbbuff[i] - '0' - 0x0A + 'A'; i++; arbbuff[i++] = 0x0D; arbbuff[i++] = 0x0A; arbbuff[i] = 0; UartWrite(arbBuff, i); static int Str2Dec(const char *a_pstr, U16 a_ulen) int nnum = 0; while (a_ulen) nnum *= 10; nnum += (int)(*a_pstr - '0'); a_pstr++; a_ulen--; bool GpsCvtMsg(GPS_VALUE *a_pgpsvalue, char *a_pmsg) U16 i; U08 bchksum; U08 bchkchrh, bchkchrl; GPS_STRING *pgpsstr; if ( (a_pmsg[0]!= '$') (a_pmsg[1]!= 'P') (a_pmsg[2]!= 'N') (a_pmsg[3]!= 'V') (a_pmsg[4]!= 'C') (a_pmsg[5]!= 'A') (a_pmsg[6]!= 'M') ) return false; // Check Sum Test i = 1; bchksum = 0; while ( (a_pmsg[i]!= '*') && (a_pmsg[i]!= 0) ) bchksum ^= a_pmsg[i++]; if (a_pmsg[i]!= '*') lgpsmsgchkerrcnt++; return false; bchkchrh = (bchksum >> 4); if (bchkchrh < 10) bchkchrh += '0'; else bchkchrh += ('A' - 10); bchkchrl = (bchksum & 0x0F); if (bchkchrl < 10) bchkchrl += '0'; else bchkchrl += ('A' - 10); if ( (a_pmsg[i+1]!= bchkchrh) (a_pmsg[i+2]!= bchkchrl) ) lgpsmsgchkerrcnt++; return false; // Convert pgpsstr = (GPS_STRING*)a_pMsg; a_pgpsvalue->cstatus = pgpsstr->sstatus[0]; a_pgpsvalue->byear = (U08)Str2Dec(pGpsStr->sTime+ 0, 2); a_pgpsvalue->bmonth = (U08)Str2Dec(pGpsStr->sTime+ 2, 2); a_pgpsvalue->bday = (U08)Str2Dec(pGpsStr->sTime+ 4, 2); a_pgpsvalue->bhour = (U08)Str2Dec(pGpsStr->sTime+ 6, 2); a_pgpsvalue->bmin = (U08)Str2Dec(pGpsStr->sTime+ 8, 2); a_pgpsvalue->bsec = (U08)Str2Dec(pGpsStr->sTime+10, 2); memcpy(&arcgpsdata[ugpsdataidx], return nnum; a_pgpsvalue->bkph =

(U08)Str2Dec(pGpsStr->sSpeed, 3); a_pgpsvalue->lposy = (S32)Str2Dec(pGpsStr->sPosY, 4) * 10000 + (S32)Str2Dec(pGpsStr->sPosY+5, 4); if (pgpsstr->sposyd[0]!= 'N') a_pgpsvalue->lposy *= -1; a_pgpsvalue->lposx = (S32)Str2Dec(pGpsStr->sPosX, 5) * 10000 + (S32)Str2Dec(pGpsStr->sPosX+6, 4); if (pgpsstr->sposxd[0]!= 'E') a_pgpsvalue->lposx *= -1; a_pgpsvalue->bmsg = (U08)Str2Dec(pGpsStr->sMsg, 2); a_pgpsvalue->brsp = (U08)Str2Dec(pGpsStr->sRsp, 1); a _ p G p s V a l u e - > b C a m C o d e = (U08)Str2Dec(pGpsStr->sCamCode, 2); a_pgpsvalue->bcamkph = (U08)Str2Dec(pGpsStr->sCamKph, 3); a _ p G p s V a l u e - > u C a m D i s t = (U16)Str2Dec(pGpsStr->sCamDist, 3); lgpsmsgcnt++; return true; /* void printgps(gps_value *a_pgps) printf( "$pnvcam,%c,%02d%02d%02d%02d%02 d%02d,%03d,%04d.%04d,%c,%05d.%04d,%c,%02d,%d,000000,%02d,%03d,%03d* \n", a_pgps->cstatus, a_pgps->byear, a_pgps->bmonth, a_pgps->bday, a_pgps->bhour, a_pgps->bmin, a_pgps->bsec, a_pgps->bkph, a_pgps->lposy / 10000, a_pgps->lposy % 10000, (a_pgps->lposy >= 0)? 'N': 'S', a_pgps->lposx / 10000, a_pgps->lposx % 10000, (a_pgps->lposx >= 0)? 'E': 'S', a_pgps->bmsg, a_pgps->brsp, a_pgps->bcamcode, a_pgps->bcamkph, a_pgps->ucamdist ); */ void GpsTest() U32 i; U32 lctimesave; GpsSendMsg("$PSRF200,30"); lctimesave = lctimerirqcnt; while (lctimerirqcnt < (lctimesave + 5*100) ) GpsMakeMsg(); if (ugpsmsgwriteidx > 0) for (i = 0; i < ugpsmsgwriteidx; i++) // printf("%s", argpsmsg[i].pmsg); if ( GpsCvtMsg(&oGpsTest, argpsmsg[i].pmsg) ) // printgps(&ogpstest); GpsClearMsg(); GpsSendMsg("$PSRF200,33"); lctimesave = lctimerirqcnt; while (lctimerirqcnt < (lctimesave + 5*100) ) GpsMakeMsg(); if (ugpsmsgwriteidx > 0) for (i = 0; i < ugpsmsgwriteidx; i++) // printf("%s", argpsmsg[i].pmsg); if ( GpsCvtMsg(&oGpsTest, argpsmsg[i].pmsg) ) // printgps(&ogpstest); GpsClearMsg(); // GpsSendMsg("$PSRF200,34"); lctimesave = lctimerirqcnt; while (lctimerirqcnt < (lctimesave + 5*100) ) GpsMakeMsg(); if (ugpsmsgwriteidx > 0) for (i = 0; i < ugpsmsgwriteidx; i++) // printf("%s", argpsmsg[i].pmsg); if ( GpsCvtMsg(&oGpsTest, argpsmsg[i].pmsg) ) // printgps(&ogpstest); GpsClearMsg(); 제 2 절데이터베이스 S/W Source Code 데이터베이스제작 데이터베이스는 C코드를중심으로짜여져있으며, 관련된 include 파일은다음과같다. 2006-11-7 오후 04:04 2KB DataView.h 2006-11-7 오후 04:25 2KB DBgps1.h 2006-11-7 오후 04:25 2KB BitmapStatic.h 2006-11-7 오후 04:25 3KB CardConnectDlg.h 2006-11-7 오후 04:25 2KB DrawBitmap.h 2006-11-7 오후 04:54 3KB Jpeg.h 2006-11-7 오후 04:43 2KB MainDlg.h 2006-11-7 오후 04:43 2KB MapView.h 2006-11-1 오후 01:43 2KB StdAfx.h 2006-11-7 오후 05:21 2KB Tester.h

2006-11-7 오후 06:33 7KB TonyJpegDecoder.h C코드파일은다음과같다. 2006-11-7 오후 06:04 6KB DataView.cpp 2006-11-7 오후 04:32 2KB DBgps1.cpp 2006-11-7 오후 04:25 3KB BitmapStatic.cpp 2006-11-7 오후 04:12 3KB CardConnectDlg.cpp 2006-11-7 오후 04:54 12KB DrawBitmap.cpp 2006-11-7 오후 04:34 12KB Jpeg.cpp 2006-11-7 오후 04:43 12KB MainDlg.cpp 2006-11-7 오후 04:43 7KB MapView.cpp 2006-11-1 오후 01:43 1KB StdAfx.cpp 2006-11-7 오후 05:23 5KB Tester.cpp 2006-11-7 오후 06:33 51KB TonyJpegDecoder.cpp 그이외에 MicroSoft 사의 MS-SQL 데이터베이스를이용해서 DB 를구성하였다. // BitmapStatic.cpp : implementation file // #include "stdafx.h" #include "BitmapStatic.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////////////////////// / // CBitmapStatic CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here GetClientRect(&m_RectMe); CPoint PointAdj(0, 0); PointAdj.x = (m_rectme.width() - 624 ) / 2; PointAdj.y = (m_rectme.height() - 480 ) / 2; m_rectme.left += PointAdj.x; m_rectme.right -= PointAdj.x; m_rectme.top += PointAdj.y; m_rectme.bottom-= PointAdj.y; dc.selectobject(&open); if (m_rectme.ptinrect(m_mousepos)) dc.moveto(m_rectme.left+m_mousepos.x, m_rectme.top); dc.lineto(m_rectme.left+m_mousepos.x, m_rectme.bottom); d c. M o v e T o ( m _ R e c t M e.left, m_rectme.top+m_mousepos.y); dc.lineto(m_rectme.right,m_rectme.top +m_mousepos.y); CBitmapStatic::CBitmapStatic() CFileException ex; CFile fbmp; if (fbmp.open("datamap.jpg", CFile::modeRead)) m_bitmap.makedibfromjpgfile(&fbmp); fbmp.close(); CBitmapStatic::~CBitmapStatic() BEGIN_MESSAGE_MAP(CBitmapStatic, CStatic) //AFX_MSG_MAP(CBitmapStatic) ON_WM_PAINT() //AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////// / // CBitmapStatic message handlers void CBitmapStatic::OnPaint() m_bitmap.setrectdc(m_rectme); m_bitmap.draw(dc.getsafehdc()); DrawMouseCross(dc); // Do not call CStatic::OnPaint() for painting messages void CBitmapStatic::DrawMouseCross(CPaintDC &dc) int nrop2old; nrop2old = dc.setrop2(r2_xorpen); // Draw Base Line CPen *ppenold, openideal(ps_solid, 1, RGB(0x00,0xFF,0xFF)); ppenold = dc.selectobject(&openideal); /* dc.moveto(m_rectme.left+160, m_rectme.top); d c. L i n e T o ( m _ R e c t M e. l e f t + 1 6 0, m_rectme.bottom); dc.moveto(m_rectme.left, m_rectme.top+120); dc.lineto(m_rectme.right, m_rectme.top+120); */ // Draw Mouse Line CPen open(ps_solid, 1, RGB(0xFF,0xFF,0x00)); dc.setrop2(nrop2old); dc.selectobject(ppenold); ----------------------------- # i f!defined(afx_bitmapstatic_h F0F B25CC_4296_4E00_A19D_A3248CD125F 9 INCLUDED_) # d e f i n e AFX_BITMAPSTATIC_H F0FB25CC_42 96_4E00_A19D_A3248CD125F9 INCLU DED_ #include "DrawBitmap.h" // Added by ClassView #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // BitmapStatic.h : header file // //////////////////////////////////////////////////////////////////////////// / // CBitmapStatic window class CBitmapStatic : public CStatic // Construction public:

CBitmapStatic(); CDrawBitmap m_bitmap; // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CBitmapStatic) protected: //AFX_VIRTUAL // Implementation public: void DrawMouseCross(CPaintDC &dc); CPoint m_mousepos; virtual ~CBitmapStatic(); // Generated message map functions protected: CRect m_rectme; //AFX_MSG(CBitmapStatic) afx_msg void OnPaint(); //AFX_MSG m_iprotocoltype = -1; //AFX_DATA_INIT v o i d CCardConnectDlg::DoDataExchange(CDat aexchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CCardConnectDlg) DDX_Radio(pDX, IDC_RADIO1, m_isharemode); DDX_Radio(pDX, IDC_RADIO4, m_iprotocoltype); //AFX_DATA_MAP BEGIN_MESSAGE_MAP(CCardConnectDlg, CDialog) //AFX_MSG_MAP(CCardConnectDlg) //AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////// / // CCardConnectDlg message handlers class CCardConnectDlg : public CDialog // Construction public: CCardConnectDlg(CWnd* pparent = NULL); // standard constructor // Dialog Data //AFX_DATA(CCardConnectDlg) enum IDD = IDD_DLG_CARDCONNECT ; int m_isharemode; int m_iprotocoltype; //AFX_DATA // Overrides // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CCardConnectDlg) protected: virtual void DoDataExchange(CDataExchange* pdx); // DDX/DDV support //AFX_VIRTUAL DECLARE_MESSAGE_MAP() ; //////////////////////////////////////////////////////////////////////////// / //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_bitmapstatic_h F0F B25CC_4296_4E00_A19D_A3248CD125F 9 INCLUDED_) ----------------------------- // CardConnectDlg.cpp : implementation file // #include "stdafx.h" #include "Tester.h" #include "CardConnectDlg.h" #include <winscard.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////////////////////// / // CCardConnectDlg dialog extern DWORD dwsharemode; // connect 모드 extern DWORD dwprotocols; // protocol type CCardConnectDlg::CCardConnectDlg(CWnd* pparent /*=NULL*/) : CDialog(CCardConnectDlg::IDD, pparent) //AFX_DATA_INIT(CCardConnectDlg) m_isharemode = -1; void CCardConnectDlg::OnOK() UpdateData(true); switch(m_isharemode) case 0: dwsharemode = SCARD_SHARE_SHARED; break; case 1: dwsharemode = SCARD_SHARE_EXCLUSIVE; break; case 2: dwsharemode = SCARD_SHARE_DIRECT; break; switch(m_iprotocoltype) case 0: dwprotocols = SCARD_PROTOCOL_T0; break; case 1: dwprotocols = SCARD_PROTOCOL_T1; break; case 2: dwprotocols = SCARD_PROTOCOL_T0 SCARD_PROTO COL_T1; break; UpdateData(false); CDialog::OnOK(); ---------------------------- # i f!defined(afx_cardconnectdlg_h C0E2C338_341C_432F_BB8A_B6ABC126 316A INCLUDED_) # d e f i n e AFX_CARDCONNECTDLG_H C0E2C338 _341C_432F_BB8A_B6ABC126316A IN CLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // CardConnectDlg.h : header file // //////////////////////////////////////////////////////////////////////////// / // CCardConnectDlg dialog // Implementation protected: // Generated message map functions //AFX_MSG(CCardConnectDlg) virtual void OnOK(); //AFX_MSG DECLARE_MESSAGE_MAP() ; //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_cardconnectdlg_h C0E2C338_341C_432F_BB8A_B6ABC126 316A INCLUDED_) ----------------------------- // DataView.cpp : implementation file // #include "stdafx.h" #include "Tester.h" #include "DataView.h" #include "DrawBitmap.h" // Added by ClassView #include "BitmapStatic.h" #include "DBgps1.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////////////////////// / // CDataView dialog CDataView::CDataView(CWnd* pparent /*=NULL*/) : CDialog(CDataView::IDD, pparent)

//AFX_DATA_INIT(CDataView) m_maptext = _T(""); //AFX_DATA_INIT void CDataView::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CDataView) DDX_Control(pDX, IDC_LIST2, m_ctrllist); DDX_Control(pDX, IDC_IMG, m_img); DDX_Text(pDX, IDC_EDIT1, m_maptext); //AFX_DATA_MAP OnInitDlg(); BEGIN_MESSAGE_MAP(CDataView, CDialog) //AFX_MSG_MAP(CDataView) // NOTE: the ClassWizard will add message map macros here //AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////// / // CDataView message handlers BOOL CDataView::OnInitDlg() m_ctrllist.insertcolumn(0,_t(" 선박번호 "),LVCFMT_LEFT,80); m_ctrllist.insertcolumn(1,_t(" 이름 "),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(2,_t(" 주민번호 1"),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(3,_t(" 주민번호 2"),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(4,_t(" 분류 "),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(5,_t(" 카드번호 "),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(6,_t(" 발급기관 "),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(7,_t(" 발급일 "),LVCFMT_LEFT,90); m_ctrllist.insertcolumn(8,_t(" 발급코드 "),LVCFMT_LEFT,70); m_ctrllist.insertcolumn(9,_t("applet Version"),LVCFMT_LEFT,70); m_ctrllist.insertcolumn(10,_t("referenc e Year"),LVCFMT_LEFT,70); CDBgps dbgps; if(!dbgps.open()) AfxMessageBox(_T(" 데이터소스와연결하지못했습니다.")); else int i=0; CString str; while(!dbgps.iseof()) m_ctrllist.insertitem(i,dbgps.m_shipnum ); m_ctrllist.setitemtext(i,1,dbgps.m_nam e); m_ctrllist.setitemtext(i,2,dbgps.m_pid1 ); m_ctrllist.setitemtext(i,3,dbgps.m_pid2 ); if(dbgps.m_memid) str=_t(" 남성 "); else str = _T(" 여성 "); m_ctrllist.setitemtext(i,4,str); m_ctrllist.setitemtext(i,5,dbgps.m_card num); m_ctrllist.setitemtext(i,6,dbgps.m_card _org); str = CTime(dbgps.m_card_day).Format("%y- %m-%d"); m_ctrllist.setitemtext(i,7,str); m_ctrllist.setitemtext(i,8,dbgps.m_card _code); m_ctrllist.setitemtext(i,9,dbgps.m_appl et_ver); m_ctrllist.setitemtext(i,10,dbgps.m_ref _year); dbgps.movenext(); i++; return true; ----------------------------- # i f!defined(afx_dataview_h C404DD6 6_BCB5_4730_8536_2CE3E43E540E IN CLUDED_) # d e f i n e AFX_DATAVIEW_H C404DD66_BCB5_ 4730_8536_2CE3E43E540E INCLUDED _ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // DataView.h : header file // #include "BitmapStatic.h" #include "MainDlg.h" #include "DrawBitmap.h" #include <afxdb.h> //////////////////////////////////////////////////////////////////////////// / // CDataView dialog class CDataView : public CDialog // Construction public: BOOL OnInitDlg(); CDrawBitmap m_bitmap; CDataView(CWnd* pparent = NULL); // standard constructor // Dialog Data //AFX_DATA(CDataView) enum IDD = IDD_DATA_VIEW ; CListCtrl m_ctrllist; CBitmapStatic m_img; CString m_maptext; //AFX_DATA // Overrides // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CDataView) protected: virtual void DoDataExchange(CDataExchange* pdx); // DDX/DDV support //AFX_VIRTUAL // Implementation protected: // Generated message map functions //AFX_MSG(CDataView) // NOTE: the ClassWizard will add member functions here //AFX_MSG DECLARE_MESSAGE_MAP() ; //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_dataview_h C404DD6 6_BCB5_4730_8536_2CE3E43E540E IN CLUDED_) ------------------------------ // DBgps1.cpp : implementation file // #include "stdafx.h" #include "Tester.h" #include "DBgps1.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////////////////////// / // CDBgps IMPLEMENT_DYNAMIC(CDBgps, CRecordset) CDBgps::CDBgps(CDatabase* pdb) : CRecordset(pdb) //AFX_FIELD_INIT(CDBgps) m_shipnum = _T(""); m_name = _T(""); m_pid1 = _T("");

m_pid2 = _T(""); m_memid = 0; m_cardnum = _T(""); m_card_org = _T(""); m_card_code = _T(""); m_applet_ver = _T(""); m_ref_year = _T(""); m_nfields = 11; //AFX_FIELD_INIT m_ndefaulttype = snapshot; CString CDBgps::GetDefaultConnect() r e t u r n _T("ODBC;DSN=ShipGps;uid=sa;pwd=rl tkd"); CString CDBgps::GetDefaultSQL() return _T("[dbo].[card_info]"); void CDBgps::DoFieldExchange(CFieldExchange* pfx) //AFX_FIELD_MAP(CDBgps) pfx->setfieldtype(cfieldexchange::ou tputcolumn); RFX_Text(pFX, _T("[shipNum]"), m_shipnum); RFX_Text(pFX, _T("[name]"), m_name); RFX_Text(pFX, _T("[pid1]"), m_pid1); RFX_Text(pFX, _T("[pid2]"), m_pid2); RFX_Long(pFX, _T("[memid]"), m_memid); RFX_Text(pFX, _T("[cardnum]"), m_cardnum); RFX_Text(pFX, _T("[card_org]"), m_card_org); RFX_Date(pFX, _T("[card_day]"), m_card_day); RFX_Text(pFX, _T("[card_code]"), m_card_code); RFX_Text(pFX, _T("[applet_ver]"), m_applet_ver); RFX_Text(pFX, _T("[Ref_year]"), m_ref_year); //AFX_FIELD_MAP //////////////////////////////////////////////////////////////////////////// / // CDBgps diagnostics #ifdef _DEBUG void CDBgps::AssertValid() const CRecordset::AssertValid(); void CDBgps::Dump(CDumpContext& dc) const CRecordset::Dump(dc); #endif //_DEBUG ----------------------------- # i f!defined(afx_dbgps1_h 6BA6FFC2_5 400_47CE_B70F_6F38865C1174 INCLU DED_) # d e f i n e AFX_DBGPS1_H 6BA6FFC2_5400_47C E_B70F_6F38865C1174 INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // DBgps1.h : header file // //////////////////////////////////////////////////////////////////////////// // CDBgps recordset / class CDBgps : public CRecordset public: // Field/Param Data // Overrides CDBgps(CDatabase* pdatabase = NULL); DECLARE_DYNAMIC(CDBgps) //AFX_FIELD(CDBgps, CRecordset) CString m_shipnum; CString m_name; CString m_pid1; CString m_pid2; long m_memid; CString m_cardnum; CString m_card_org; CTime m_card_day; CString m_card_code; CString m_applet_ver; CString m_ref_year; //AFX_FIELD // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CDBgps) public: virtual CString GetDefaultConnect(); // Default connection string virtual CString GetDefaultSQL(); // Default SQL for Recordset virtual void DoFieldExchange(CFieldExchange* pfx); // RFX support //AFX_VIRTUAL // Implementation #ifdef _DEBUG virtual void AssertValid() const; virtual void Dump(CDumpContext& dc) const; #endif ; //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_dbgps1_h 6BA6FFC2_5 400_47CE_B70F_6F38865C1174 INCLU DED_) ------------------------------ // DrawBitmap.cpp: implementation of the CDrawBitmap class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" //#include "ShowBitmap.h" #include "DrawBitmap.h" #include "TonyJpegDecoder.h" #include <io.h> #include <stdlib.h> #include <stdio.h> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CDrawBitmap::CDrawBitmap() m_hdib = NULL; m_rectdc.left = m_rectdc.top = 0; m_rectdc.right = m_rectdc.bottom = 1; CDrawBitmap::~CDrawBitmap() DelDIB(); BOOL CDrawBitmap::Draw(HDC a_hdc) LPBITMAPINFOHEADER lpbitmapheader; LPSTR pbuf; if (m_hdib == NULL) return PatBlt(a_hDC,m_RectDC.left, m_rectdc.top, m_rectdc.width(), m_rectdc.height(), PATCOPY); lpbitmapheader = (LPBITMAPINFOHEADER)GlobalLock(m _hdib); if (lpbitmapheader == NULL) return FALSE; pbuf = (LPSTR)lpBitmapHeader + m_wdibheadersize; // (WORD)lpBitmapHeader->biSize + GetPaletteSize(lpBitmapHeader); SetDIBitsToDevice( a_hdc, m_rectdc.left, m_rectdc.top, m_rectdc.width(), m_rectdc.height(), m_rectdib.left, m_rectdib.top, m_rectdib.left, m_rectdib.height(), pbuf, (LPBITMAPINFO)lpBitmapHeader, DIB_RGB_COLORS ); GlobalUnlock(lpBitmapHeader); return TRUE; BOOL CDrawBitmap::SetRectDC(CRect a_rect) m_rectdc = a_rect;

return TRUE; BOOL CDrawBitmap::SetRectDIB(CRect a_rect) m_rectdib = a_rect; return TRUE; WORD CDrawBitmap::GetNumOfColor(void far *a_pbitmapheader) int bits; LPBITMAPINFOHEADER lpbitmapheader; LPBITMAPCOREHEADER lpbc; lpbitmapheader = ((LPBITMAPINFOHEADER)a_pBitmapH eader); lpbc = ((LPBITMAPCOREHEADER)a_pBitmapH eader); // With the BITMAPINFO format headers, the size of the palette // is in biclrused, whereas in the BITMAPCORE - style headers, it // is dependent on the bits per pixel ( = 2 raised to the power of // bits/pixel). if (lpbitmapheader->bisize!= sizeof(bitmapcoreheader)) if (lpbitmapheader->biclrused!= 0) return (int)lpbitmapheader->biclrused; bits = lpbitmapheader->bibitcount; else bits = lpbc->bcbitcount; switch (bits) case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; // A 24 bitcount DIB has no color table WORD CDrawBitmap::GetPaletteSize(void *a_pbitmapheader) LPBITMAPINFOHEADER lpbitmapheader; WORD NumColors; lpbitmapheader = (LPBITMAPINFOHEADER)a_pBitmapHe ader; NumColors = GetNumOfColor(lpBitmapHeader); if (lpbitmapheader->bisize == sizeof(bitmapcoreheader)) return (WORD)(NumColors * sizeof(rgbtriple)); else return (WORD)(NumColors * sizeof(rgbquad)); BOOL CDrawBitmap::MakeDIBFromJpgFile(CFile *a_pfile) if (a_pfile == NULL) return FALSE; DWORD dwfilelen = a_pfile->getlength(); BYTE far *pbfilebuff = new BYTE[dwFileLen]; if (pbfilebuff == NULL) return FALSE; if (a_pfile->readhuge(pbfilebuff, dwfilelen)!= dwfilelen) return FALSE;; BOOL tresult = MakeDIBFromJpg(pbFileBuff, dwfilelen); delete [] pbfilebuff; return tresult; BOOL CDrawBitmap::MakeDIBFromJpg(void far *a_pjpgbuff, DWORD a_njpgsize) DelDIB(); CTonyJpegDecoder JpgDecoder; int nimgwidth, nimgheight, nimgheadsize; i f (JpgDecoder.ReadJpgHeader((LPBYTE)a _pjpgbuff, a_njpgsize, nimgwidth, nimgheight, nimgheadsize) == FALSE) return FALSE; m_wdibheadersize = sizeof(bitmapinfoheader); m_dwdibimgsize = WIDTHBYTES(nImgWidth*24) * nimgheight; m_hdib = GlobalAlloc(GHND, (DWORD)m_wDIBHeaderSize + m_dwdibimgsize); if (!m_hdib ) return FALSE; LPBITMAPINFOHEADER lpbitmapheader; lpbitmapheader = (LPBITMAPINFOHEADER)GlobalLock(m _hdib); lpbitmapheader->bisize = sizeof(bitmapinfoheader); lpbitmapheader->biwidth = nimgwidth; lpbitmapheader->biheight = nimgheight; lpbitmapheader->biplanes = 1; lpbitmapheader->bibitcount = 24; lpbitmapheader->bicompression = BI_RGB; lpbitmapheader->bisizeimage = 0; lpbitmapheader->bixpelspermeter = 0; lpbitmapheader->biypelspermeter = 0; lpbitmapheader->biclrused = 0; lpbitmapheader->biclrimportant = 0; JpgDecoder.DecompressImage((LPBYTE )a_pjpgbuff+nimgheadsize, (LPBYTE)lpBitmapHeader+m_wDIBHead ersize); GlobalUnlock(m_hDIB); // Calculate the memory needed to hold the DIB m_rectdib.left = m_rectdib.top = 0; m_rectdib.right = nimgwidth + 1; m_rectdib.bottom = nimgheight + 1; m_rectdc = m_rectdib; return TRUE; BOOL CDrawBitmap::MakeDIBFromBmpFile(CFile *a_pfile) if (a_pfile == NULL) return FALSE; DWORD dwfilelen = a_pfile->getlength(); if ( dwfilelen < (DWORD)(SIZEOF_BITMAPFILEHEADE R_PACKED+sizeof(BITMAPINFOHEADE R)) ) return FALSE; BYTE far *pbfilebuff = new BYTE[dwFileLen]; if (pbfilebuff == NULL) return FALSE; if (a_pfile->readhuge(pbfilebuff, dwfilelen)!= dwfilelen) return FALSE;; BOOL tresult = MakeDIBFromBmp(pbFileBuff); delete [] pbfilebuff; return tresult; BOOL CDrawBitmap::MakeDIBFromBmp(void far *a_pbmpbuff) DelDIB(); BITMAPINFOHEADER BitmapHeader; LPBITMAPINFOHEADER lpbitmapheader; WORD nbitsstart = ReadHeaderFromBmp(a_pBmpBuff); if ( nbitsstart == 0 ) return FALSE; LoadDIBHeader(&BitmapHeader); // Calculate the memory needed to hold the DIB m_wdibheadersize = (WORD)BitmapHeader.biSize + GetPaletteSize(&BitmapHeader); m_dwdibimgsize = BitmapHeader.biSizeImage; m_rectdib.left = m_rectdib.top = 0; m_rectdib.right = BitmapHeader.biWidth + 1; m_rectdib.bottom = BitmapHeader.biHeight + 1; m_rectdc = m_rectdib; /* Try to increase the size of the bitmap info. buffer to hold the DIB */ HANDLE hnew = GlobalReAlloc(m_hDIB,

(DWORD)m_wDIBHeaderSize+m_dwDIBI mgsize, GHND); if (!hnew) GlobalFree(m_hDIB); m_hdib = NULL; else m_hdib = hnew; // Read in the bits if (m_hdib) lpbitmapheader = (LPBITMAPINFOHEADER)GlobalLock(m _hdib); memcpy((lpstr)lpbitmapheader + m _ w D I B H e a d e r S i z e, (LPSTR)a_pBmpBuff+nBitsStart, m_dwdibimgsize); GlobalUnlock(m_hDIB); return TRUE; WORD CDrawBitmap::ReadHeaderFromBmp(void far *a_pbmpbuff) if (a_pbmpbuff == NULL) return 0; BYTE far *pbmpbuff = (BYTE far*)a_pbmpbuff; // Check BMP File Header BITMAPFILEHEADER BitmapFileHeader = *(LPBITMAPFILEHEADER)pBmpBuff; // Do we have a RC HEADER? if (!ISDIB (BitmapFileHeader.bfType)) BitmapFileHeader.bfOffBits = 0L; else pbmpbuff += sizeof(bitmapfileheader); // Read BITMAPINFOHEADER BITMAPINFOHEADER BitmapHeader = *(LPBITMAPINFOHEADER)pBmpBuff; // Check the nature (BITMAPINFO or BITMAPCORE) of the info. block // and extract the field information accordingly. If a BITMAPCOREHEADER, // transfer it's field information to a BITMAPINFOHEADER-style block WORD nnumcolors = GetNumOfColor(&BitmapHeader); int nheadersize = (int)bitmapheader.bisize; switch (nheadersize) case sizeof (BITMAPINFOHEADER): pbmpbuff += sizeof(bitmapinfoheader); break; case sizeof (BITMAPCOREHEADER): BITMAPCOREHEADER BitmapCoreHeader = *(BITMAPCOREHEADER*)&BitmapHead er; BitmapHeader.biSize = (DWORD)sizeof(BITMAPINFOHEADER) ; BitmapHeader.biWidth = (LONG)BitmapCoreHeader.bcWidth; BitmapHeader.biHeight = (LONG)BitmapCoreHeader.bcHeight; BitmapHeader.biPlanes = BitmapCoreHeader.bcPlanes; BitmapHeader.biBitCount = BitmapCoreHeader.bcBitCount; BitmapHeader.biCompression = BI_RGB; BitmapHeader.biSizeImage = 0; BitmapHeader.biXPelsPerMeter = 0; BitmapHeader.biYPelsPerMeter = 0; BitmapHeader.biClrUsed = nnumcolors; BitmapHeader.biClrImportant = nnumcolors; pbmpbuff += (sizeof(bitmapcoreheader) - sizeof(bitmapinfoheader)); break; default: // Invalid BMP File return 0; // Fill in some default values if they are zero if (BitmapHeader.biSizeImage == 0) BitmapHeader.biSizeImage = WIDTHBYTES ( (DWORD)BitmapHeader.biWidth * BitmapHeader.biBitCount ) * BitmapHeader.biHeight; if (BitmapHeader.biClrUsed == 0) BitmapHeader.biClrUsed = GetNumOfColor(&BitmapHeader); // Allocate for the BITMAPINFO structure and the color table. m_hdib = GlobalAlloc (GHND, (LONG)BitmapHeader.biSize + nnumcolors * sizeof(rgbquad)); if (!m_hdib) return 0; LPBITMAPINFOHEADER lpbitmapheader = (LPBITMAPINFOHEADER)GlobalLock (m_hdib); *lpbitmapheader = BitmapHeader; // Get a pointer to the color table RGBQUAD FAR *prgb = (RGBQUAD FAR *)((LPSTR)lpBitmapHeader + BitmapHeader.biSize); if (nnumcolors) if (nheadersize == sizeof(bitmapcoreheader)) // Convert a old color table (3 byte RGBTRIPLEs) to a new // color table (4 byte RGBQUADs) for (int i = nnumcolors - 1; i >= 0; i--) RGBTRIPLE rgbt; RGBQUAD rgb; rgbt = *(RGBTRIPLE FAR *)pbmpbuff; rgb.rgbred = rgbt.rgbtred; rgb.rgbblue = rgbt.rgbtblue; rgb.rgbgreen = rgbt.rgbtgreen; rgb.rgbreserved = (BYTE)0; prgb[i] = rgb; pbmpbuff += sizeof(rgbtriple); else memcpy(prgb, pbmpbuff, nnumcolors * sizeof(rgbquad)); pbmpbuff += (nnumcolors * sizeof(rgbquad)); if (BitmapFileHeader.bfOffBits!= 0L) pbmpbuff = (BYTE far*)a_pbmpbuff + BitmapFileHeader.bfOffBits; GlobalUnlock(m_hDIB); return ((WORD)(pBmpBuff - (BYTE far*)a_pbmpbuff)); B O O L CDrawBitmap::LoadDIBHeader(LPBITMA PINFOHEADER a_lpbitmapheader) if (m_hdib) *a_lpbitmapheader = *(LPBITMAPINFOHEADER)GlobalLock( m_hdib); // fill in the default fields if (a_lpbitmapheader->bisize!= sizeof (BITMAPCOREHEADER)) if (a_lpbitmapheader->bisizeimage == 0L) a_lpbitmapheader->bisizeimage = WIDTHBYTES(a_lpBitmapHeader->biW idth*a_lpbitmapheader->bibitcount) * a_lpbitmapheader->biheight; if (a_lpbitmapheader->biclrused == 0L) a_lpbitmapheader->biclrused = GetNumOfColor(a_lpBitmapHeader); GlobalUnlock (m_hdib); return TRUE; return FALSE;

BOOL CDrawBitmap::DelDIB() if (m_hdib!= NULL) GlobalFree(m_hDIB); m_hdib = NULL; return TRUE; return FALSE; ---------------------------- // DrawBitmap.h: interface for the CDrawBitmap class. // ////////////////////////////////////////////////////////////////////// # i f!defined(afx_drawbitmap_h 7F37F E67_947E_4376_91F9_1A79A98CF289 INCLUDED_) # d e f i n e AFX_DRAWBITMAP_H 7F37FE67_947 E_4376_91F9_1A79A98CF289 INCLUD ED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <stdio.h> /************************************************** ************************** * * * FILE : SHOWDIB.H * * * * DESCRIPTION : Header/include file for ShowDIB example. * * * *************************************** *************************************/ #define MAXREAD 32768 /* Number of bytes to be read during */ /* each read operation. */ /* Header signatutes for various resources */ #define BFT_ICON 0x4349 /* 'IC' */ #define BFT_BITMAP 0x4d42 /* 'BM' */ #define BFT_CURSOR 0x5450 /* 'PT' */ /* macro to determine if resource is a DIB */ #define ISDIB(bft) ((bft) == BFT_BITMAP) /* Macro to align given value to the closest DWORD (unsigned long ) */ #define ALIGNULONG(i) ((i+3)/4*4) /* Macro to determine to round off the given value to the closest byte */ #define WIDTHBYTES(i) ((i+31)/32*4) #define PALVERSION 0x300 #define MAXPALETTE 256 /* max. # supported palette entries */ /************************************************** ***/ /* make new sizeof structs to cover dword alignment */ /************************************************** ***/ #define SIZEOF_BITMAPFILEHEADER_PACKED ( \ sizeof(word) + /* bftype */ \ sizeof(dword) + /* bfsize */ \ sizeof(word) + /* bfreserved1 */ \ sizeof(word) + /* bfreserved2 */ \ sizeof(dword)) /* bfoffbits */ class CDrawBitmap public: BOOL MakeDIBFromJpgFile(CFile *a_pfile); BOOL MakeDIBFromJpg(void far *a_pjpgbuff, DWORD a_njpgsize); BOOL MakeDIBFromBmpFile(CFile *a_pfile); BOOL MakeDIBFromBmp(void far *a_pbmpbuff); BOOL Draw(HDC a_hdc); BOOL DelDIB(); BOOL SetRectDIB(CRect a_rect); BOOL SetRectDC(CRect a_rect); CDrawBitmap(); virtual ~CDrawBitmap(); CRect m_rectdib; CRect m_rectdc; private: DWORD m_dwdibimgsize; WORD m_wdibheadersize; HANDLE m_hdib; protected: WORD ReadHeaderFromBmp(void far *a_pbmpbuff); B O O L LoadDIBHeader(LPBITMAPINFOHEADE R a_lpbitmapheader); WORD GetPaletteSize(void far *a_pbitmapheader); WORD GetNumOfColor(void far *a_pbitmapheader); ; #endif //!defined(afx_drawbitmap_h 7F37F E67_947E_4376_91F9_1A79A98CF289 INCLUDED_) ------------------------------ // Jpeg.cpp: implementation of the CJpeg class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Jpeg.h" #include <math.h> #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]= FILE ; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CJpeg::CJpeg() int i; m_pdata = NULL; for(i=0; i<20; i++) TbH[i].Flag = FALSE; CJpeg::~CJpeg() int i; if(m_pdata!= NULL) delete [] m_pdata; for(i=0; i<20; i++) if(tbh[i].flag) delete [] TbH[i].HUFFCODE; delete [] TbH[i].HUFFSIZE; delete [] TbH[i].HUFFVAL; //////////////////////////////////////////////////////////////////////////// ////////////// void CJpeg::LoadJPG(LPSTR FileName) // File Open & Load Entire Contents // HFILE hfile = _lopen(filename, OF_READWRITE); int FileSize = GetFileSize((HANDLE)hFile, NULL); m_pbuf = new BYTE[FileSize]; _lread(hfile, m_pbuf, FileSize); _lclose(hfile); m_index = 0; int Count=0; FindSOI(); pbyte = &m_pbuf[m_index]; while(true) FindETC(); // DRI(Define Restart Interval) FindDHT(); // Huffman Table Loading FindDQT(); // Quantization Table Loading FindSOF(); // Frame Header Loading FindSOS(); // Scan Header Loading & Decoding if( (*pbyte == 0xff) && (*(pbyte+1) == 0xd9) ) // 끝을만났을때 break; Count++; if(count > 50) // Loop 가끝날가능성이거의없을때

b r e a k ; delete [] m_pbuf; //////////////////////////////////////////////////////////////////////////// ////////////// void CJpeg::LoadJPG2 (BYTE *Buffer, int BufSize) int k; m_pbuf = new BYTE[BufSize]; for (k=0; k<bufsize; k++) m_pbuf[k] = Buffer[k]; m_index = 0; int Count=0; LASTK; 0; BITS[17]; = *p; // Table Number memcpy(bits, p, 17); 17; 을모두더해서 Num에저장 i<17; i++) int i, j, k, int Num = B Y T E BYTE Th p = p + //17개의값 for(i=1; TbH[Th].HUFFSIZE[k] = 0; LASTK = k; / / Generation of table of Huffman codes k=0; W O R D CODE = 0; BYTE SI = TbH[Th].HUFFSIZE[0]; while(true) FindSOI(); pbyte = &m_pbuf[m_index]; while(true) FindETC(); // DRI(Define Restart Interval) FindDHT(); // Huffman Table Loading FindDQT(); // Quantization Table Loading FindSOF(); // Frame Header Loading FindSOS(); // Scan Header Loading & Decoding if( (*pbyte == 0xff) && (*(pbyte+1) == 0xd9) ) // 끝을만났을때 break; Count++; if(count > 50) // Loop 가끝날가능성이거의없을때 b r e a k ; delete [] m_pbuf; void CJpeg::FindSOI() while(!((m_pbuf[m_index] == 0xff)&&(m_pBuf[m_Index+1] == 0xd8))) m_index++; m_index = m_index + 2; Num = Num + BITS[i]; TbH[Th].Flag = TRUE; TbH[Th].HUFFCODE = new WORD[Num+1]; TbH[Th].HUFFSIZE = new BYTE[Num+1]; TbH[Th].HUFFVAL = new BYTE[Num+1]; //Huffman Value 값을 Num크기만큼 p에서읽는다. memcpy(tbh[th].huffval, p, Num); //p가증가 p = p + Num; / / Generation of table of Huffman code sizes // i=1; j=1; k=0; while(i<=16) while(j<=bits[i]) do TbH[Th].HUFFCODE[k] = CODE; CODE++; k++; while(tbh[th].huffsize[k] == SI); if(tbh[th].huffsize[k] == 0) break; do CODE = CODE << 1; SI++; while(tbh[th].huffsize[k]!= SI); // Decoder table generation // i=0; j=0; void CJpeg::FindDHT() if( (m_pbuf[m_index] == 0xff) && (m_pbuf[m_index+1] == 0xc4) ) WORD SegSize = m_pbuf[m_index+2]*256 + m_pbuf[m_index+3]; // 버퍼의현재위치를포인 터로설정한다. BYTE *p = &m_pbuf[m_index+4]; do = (BYTE)i; i++; j=1; TbH[Th].HUFFSIZE[k] k++; j++; while(true) do i++; if(i>16) break; if(bits[i] == 0) TbH[Th].MAXCODE[i] = -1;

while(bits[i] == 0); if(i>16) break; TbH[Th].VALPTR[i] = j; TbH[Th].MINCODE[i] = TbH[Th].HUFFCODE[j]; j = j + BITS[i] - 1; TbH[Th].MAXCODE[i] = TbH[Th].HUFFCODE[j]; j++; TbH[Th].Num = Num; while(*p!= 0xff); m_index = m_index + SegSize + 2; void CJpeg::FindDQT() if( (m_pbuf[m_index] == 0xff) && (m_pbuf[m_index+1] == 0xdb) ) WORD SegSize = m_pbuf[m_index+2]*256 + m_pbuf[m_index+3]; BYTE *p = &m_pbuf[m_index+4]; do BYTE Tq = *(p++) & 0x0f; // Table Number m e m c p y ( T b Q [ T q ]. Q, &m_pbuf[m_index+5], 64); p = p + 64; while(*p!= 0xff); m_index = m_index + SegSize + 2; void CJpeg::FindSOF() if((m_pbuf[m_index] == 0xff)&&(m_pBuf[m_Index + 1] == 0xc0)) int i; WORD SegSize = m_pbuf[m_index + 2] * 256 + m_pbuf[m_index + 3]; FrameHeader.Y = m_pbuf[m_index + 5] * 256 + m_pbuf[m_index + 6]; FrameHeader.X = m_pbuf[m_index + 7] * 256 + m_pbuf[m_index + 8]; FrameHeader.Nf = m_pbuf[m_index + 9]; f o r ( i = 0 ; i<frameheader.nf; i++) FrameHeader.C[i] = m_pbuf[m_index + 10 + 3*i]; FrameHeader.H[i] = m_pbuf[m_index + 11 + 3*i] >> 4; FrameHeader.V[i] = m_pbuf[m_index + 11 + 3*i] & 0x0f; FrameHeader.Tq[i] = m_pbuf[m_index + 12 + 3*i]; m_index = m_index + SegSize + 2; void CJpeg::FindETC() if((m_pbuf[m_index] == 0xff)&& (( (m_pbuf[m_index + 1] & 0xf0) == 0xe0) (m_pbuf[m_index + 1] & 0xf0) == 0xf0)) WORD SegSize = m_pbuf[m_index + 2] * 256 + m_pbuf[m_index + 3]; m_index = m_index + SegSize + 2; // DRI(Define Restart Interval // if((m_pbuf[m_index] == 0xff) && (m_pbuf[m_index+1] == 0xdd)) WORD Lr = m_pbuf[m_index+2]*256+m_pbuf[m_in dex+3]; Ri = m_pbuf[m_index+4]*256+m_pbuf[m_in dex+5]; m_index = m_index + 6; void CJpeg::FindSOS() if((m_pbuf[m_index] == 0xff)&&(m_pBuf[m_Index + 1] == 0xda)) int i; WORD SegSize = m_pbuf[m_index + 2] * 256 + m_pbuf[m_index + 3]; ScanHeader.Ns = m_pbuf[m_index + 4]; f o r ( i = 0 ; i<scanheader.ns; i++) ScanHeader.Cs[i] = m_pbuf[m_index + 5 + i*2]; ScanHeader.Td[i] = m_pbuf[m_index + 6 + i*2] >> 4; ScanHeader.Ta[i] = m_pbuf[m_index + 6 + i*2] & 0x0f; ScanHeader.Ss = m_pbuf[m_index + 5 + 2 * ScanHeader.Ns]; ScanHeader.Se = m_pbuf[m_index + 6 + 2 * ScanHeader.Ns]; ScanHeader.Ah = m_pbuf[m_index + 7 + 2 * ScanHeader.Ns] >> 4; ScanHeader.Al = m_pbuf[m_index + 7 + 2 * ScanHeader.Ns] & 0x0f; m_index = m_index + SegSize + 2; // 최대 Sampling Factor 구함 // Hmax = Vmax = 0; f o r ( i = 0 ; i<frameheader.nf; i++) if(frameheader.h[i] > Hmax) Hmax = FrameHeader.H[i]; if(frameheader.v[i] > Vmax) Vmax = FrameHeader.V[i]; // 실제이미지사이즈저장 // m_rwidth = FrameHeader.X; m_rheight = FrameHeader.Y; // 이미지사이즈를 MCU 크기에맞아떨어지도록다시계산 // if(frameheader.x % (8 * Hmax)!= 0) FrameHeader.X = (FrameHeader.X / (8*Hmax) + 1)*(8*Hmax); if(frameheader.y % (8 * Vmax)!= 0) FrameHeader.Y = (FrameHeader.Y / (8*Vmax) + 1)*(8*Vmax); Decode(); WORD CJpeg::NextBit() WORD Bit; BYTE B2; static BYTE B;

while(cnt == 0) B = NextByte(); cnt = 8; if(b == 0xff) B2 = NextByte(); Bit = B >> 7; cnt--; B = B << 1; return Bit; BYTE CJpeg::NextByte() return *(pbyte++); BYTE CJpeg::hDecode(int Th) int i = 1, j; WORD CODE = NextBit(); BYTE Value; while((code > TbH[Th].MAXCODE[i]) (TbH[Th].MA XCODE[i] == 65535)) i++; CODE = (CODE << 1) + NextBit(); j = TbH[Th].VALPTR[i]; j = j + CODE - TbH[Th].MINCODE[i]; Value = TbH[Th].HUFFVAL[j]; return Value; WORD CJpeg::Receive(BYTE SSSS) BYTE i=0; WORD V = 0; while(i!= SSSS) i++; V = (V << 1) + NextBit(); return V; short CJpeg::Extend(WORD V, BYTE T) WORD Vt = 1 << (T-1); if( V < Vt ) Vt = (-1 << T) + 1; V = V + Vt; return (short)v; void CJpeg::DecodeDC(int Th) BYTE T = hdecode(th); ZZ[0] = Extend(Receive(T), T); void CJpeg::DecodeAC(int Th) int k = 1; memset((lpstr)&zz[1], 0, 63 * sizeof(short)); BYTE RS, SSSS, RRRR, R; // RRRR : ZZ에서 0 이아닌전값으로부터의상대적인위치 // SSSS : 0이아닌값의범위 (category) while(true) RS = hdecode(th); SSSS = RS % 16; RRRR = RS >> 4; R = RRRR; if(ssss == 0) if(r == 15) k = k + 16; else break; else k = k + R; ZZ[k] = Extend(Receive(SSSS), SSSS); if(k == 63) break; else k++; void CJpeg::DecodeDU(int N) // N = Component ID 0/1/2 int i; short *pos; DecodeDC(ScanHeader.Td[N]); DecodeAC(ScanHeader.Ta[N] + 16); // Differential DC Restoration// ZZ[0] = ZZ[0] + PrevDC[N]; PrevDC[N] = ZZ[0]; // Dequantization // pos = ZZ; for(i=0; i<64; i++) *pos = *pos * TbQ[FrameHeader.Tq[N]].Q[i]; pos++; // Undo Zigzag Order // Zigzag(); // Inverce Discrete Cosine Transform // IDCT(); // Level Shifting & Correct Error // pos = ZZ; for(i=0; i<64; i++) *pos = *pos + 128; if(*pos < 0) *pos = 0; else if(*pos > 255) *pos = 255; pos++; void CJpeg::Zigzag() int Index[64] = 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63; short Temp[64]; memcpy(temp, ZZ, 64 * sizeof(short)); int i, j, idx; for(i=0; i<8; i++) for(j=0; j<8; j++) idx = (i<<3)+j; ZZ[idx] = Temp[Index[idx]]; void CJpeg::IDCT() int x, y, index, coeff, idx; float tmp1[8][8]; float tmp2[8][8]; float dct_coeff[8][8] = +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.7071f, +0.9808f, +0.8315f, +0.5556f, +0.1951f, -0.1951f, -0.5556f, -0.8315f, -0.9808f, +0.9239f, +0.3827f, -0.3827f, -0.9239f, -0.9239f, -0.3827f, +0.3827f, +0.9239f, +0.8315f, -0.1951f, -0.9808f, -0.5556f, +0.5556f, +0.9808f, +0.1951f, -0.8315f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.7071f, -0.7071f, -0.7071f, +0.7071f,

+0.5556f, -0.9808f, +0.1951f, +0.8315f, -0.8315f, -0.1951f, +0.9808f, -0.5556f, +0.3827f, -0.9239f, +0.9239f, -0.3827f, -0.3827f, +0.9239f, -0.9239f, +0.3827f, +0.1951f, -0.5556f, +0.8315f, -0.9808f, +0.9808f, -0.8315f, +0.5556f, -0.1951f ; void CJpeg::DecodeMCU(int mx, int my) int i, j, k, l, m, n, o; int Ns = ScanHeader.Ns; int H, V, Rh, Rv; int mwidth = Hmax * 8, mheight = Vmax * 8; int bwidth = FrameHeader.X * Ns, bheight = FrameHeader.Y; int idx1, idx2, idx3; j<mwidth; j++) idx1 = my * mheight + i; idx2 = mx * mwidth + j; idx3 = i * mwidth + j; for(n=0; n<ns; n++) for(y=0; y<8; y++) for(x=0; x<8; x++) tmp2[y][x] = (float)zz[(y<<3)+x]; for(x=0; x<8; x++) // 1-D column IDCT for(coeff=0; coeff<8; coeff++) tmp1[coeff][x] = 0.; for(index=0; index<8; index++) for(k=0; k<ns; k++) H = FrameHeader.H[k]; V = FrameHeader.V[k]; Rh = Hmax / H; Rv = Vmax / V; for(l=0; l<v; l++) for(m=0; m<h; m++) DecodeDU(k); for(i=0; i<8; i++) for(j=0; j<8; j++) m_pdata[(idx1)*bwidth+((idx2)*ns + n)] = MCU[idx3].C[n]; void CJpeg::Decode() int Ns = ScanHeader.Ns; int mx = FrameHeader.X / 8 / Hmax; int my = FrameHeader.Y / 8 / Vmax; int i, j, k; cnt = 0; if(m_pdata!= NULL) delete [] m_pdata; m_pdata = new BYTE[FrameHeader.X * FrameHeader.Y * 3]; tmp1[coeff][x] += tmp2[index][x] * dct_coeff[index][coeff]; for(y=0; y<8; y++) // 1-D row IDCT for(coeff=0; coeff<8; coeff++) tmp2[y][coeff] = 0.; ((l<<3)+i)*rv; ((m<<3)+j)*rh; n<rv; n++) for(o = 0; o<rh; o++) idx1 = idx2 = for(n = 0; for(i=0; i<ns; i++) PrevDC[i] = 0; MCU = new SET[Vmax * Hmax * 64]; // NextByte 함수를위한포인터리셋 // pbyte = &m_pbuf[m_index]; // 실질적인 Decoding Procedure // int Count = 0;/// for(i=0; i<my; i++) for(j=0; j<mx; j++) for(index=0; index<8; index++) tmp2[y][coeff] += tmp1[y][index] * dct_coeff[index][coeff]; MCU[(idx1+n) * mwidth + (idx2+o)].c[k] = (BYTE)ZZ[(i<<3)+j]; DecodeMCU(j, i); Count++; if(count == Ri) // Restart Marker Decode Count = 0; (y<<3)+coeff; (short)(tmp2[y][coeff]/4.); idx = ZZ[idx] = i++) for(i=0; i<mheight; for(j=0; if((*pbyte == 0xff)&&((*(pByte+1) & 0xf0) == 0xd0)) cnt = 0; pbyte = pbyte + 2; for(k=0; k<3; k++) PrevDC[k] = 0;

if(b>255) B = 255; if(b<0) B = 0; *ptemp = (BYTE)B;pTemp++; *ptemp = (BYTE)G;pTemp++; void CJpeg::SaveJPG(LPSTR FileName, int Width, int Height, BYTE *pp) m_rwidth = Width; m_rheight = Height; delete [] MCU; // RGB 로바꿈 // ConvertYUV2RGB(); int CJpeg::GetWidth() return FrameHeader.X; int CJpeg::GetHeight() return FrameHeader.Y; void CJpeg::ConvertYUV2RGB() int i, j; int Width = GetWidth(); int Height = GetHeight(); int Size = Width * Height * ScanHeader.Ns; float Y, Cb, Cr; float R, G, B; BYTE *ptemp = m_pdata; BYTE *pbuf = new BYTE[Size]; BYTE *pos = pbuf; memcpy(pos, ptemp, Size); for(i=0; i<height; i++) for(j=0; j<width; j++) Y = *pos;pos++; if(scanheader.ns == 3) Cb = *pos;pos++; Cr = *pos;pos++; R = Y + 1.402f * (Cr-128); G = Y - 0.34414f * (Cb-128) - 0.71414f * (Cr-128); B = Y + 1.772f * (Cb-128); if(r>255) R = 255; if(r<0) R = 0; if(g>255) G = 255; if(g<0) G = 0; *ptemp = (BYTE)R;pTemp++; e l s e if(scanheader.ns == 1) *ptemp = (BYTE)Y;pTemp++; *ptemp = (BYTE)Y;pTemp++; *ptemp = (BYTE)Y;pTemp++; delete [] pbuf; // Clipping Useless Region // int RealBMPWidth = (m_rwidth * 3 + 3)/4 * 4; if((width!= m_rwidth) (Height!= m_rheight)) BYTE *pbuf2 = new BYTE [RealBMPWidth * m_rheight]; for(i=0; i<m_rheight; i++) memcpy(&pbuf2[i*realbmpwidth], &m_pdata[i*width*3], RealBMPWidth); delete [] m_pdata; m_pdata = pbuf2; // 본래의이미지사이즈로복원 // FrameHeader.X = m_rwidth; FrameHeader.Y = m_rheight; // Flip for BMP Structure // BYTE *pline = new BYTE[RealBMPWidth]; for(i=0; i<m_rheight/2; i++) ptemp = &m_pdata[i*realbmpwidth]; memcpy(pline, ptemp, RealBMPWidth); memcpy(ptemp, &m_pdata[(m_rheight - 1 - i)*realbmpwidth], RealBMPWidth); memcpy(&m_pdata[(m_rheight - 1 - i)*realbmpwidth], pline, RealBMPWidth); delete [] pline; int BMPWidth = (Width * 3 + 3)/4*4; // BITMAP의 4의배수인넓이 int bwidth = Width; int bheight = Height; if(width % 8!= 0) bwidth = (Width/8 + 1)*8; // bwidth 는 8의배수로만든넓이 if(height % 8!= 0) bheight = (Height/8 + 1)*8; // bheight 는 8의배수로만든높이 int i, j, k; // Huffman Table 초기화 // for(i=0; i<20; i++) if(tbh[i].flag) delete [] TbH[i].HUFFCODE; delete [] TbH[i].HUFFSIZE; delete [] TbH[i].HUFFVAL; HFILE hfile = _lcreat(filename, 0); PutSOI(hFile); // Start Of Image // PutDQT(hFile); // Quantization Table 저장 // PutDHT(hFile); // Huffman Table 저장 // PutSOF(hFile, Width, Height); // FrameHeader 저장 // PutSOS(hFile); // Scan Header 저장 // // 버퍼를마련합시다! // if(m_pdata!= NULL) delete [] m_pdata; m_pdata = new BYTE[(bWidth * 3) * bheight]; memset(m_pdata, 0, (bwidth * 3) * bheight); // 0으로초기화 // // 8의배수에맞도록버퍼를만들어서원래이미지를복사합니다 // for(i=0; i<height; i++) memcpy(&m_pdata[i*(bwidth*3)], &pp[i*bmpwidth], BMPWidth); // RGB Color를 YCbCr Color로변환합니다. // float R, G, B; float y, cb, cr;

BYTE *pos; for(i=0; i<height; i++) pos = &m_pdata[i*(bwidth*3)]; for(j=0; j<width; j++) B = (float)*pos; G = (float)*(pos+1); R = (float)*(pos+2); y = 0.299f * R + 0.587f * G + 0.114f * B; cb = -0.1687f * R - 0.3313f * G + 0.5f * B + 128; cr = 0.5f*R - 0.4187f*G - 0.0813f*B + 128; idx1 = i*bwidth+j; idx2 = i*(bwidth*3)+j*3; Y[idx1] = m_pdata[idx2] - 128; Cb[idx1] = m_pdata[idx2+1] - 128; Cr[idx1] = m_pdata[idx2+2] - 128; // DCT & Zigzag & Quantization // for(i=0; i<bheight; i = i + 8) for(j=0; j<bwidth; j = j + 8) DCT(&Y[i*bWidth+j], bwidth, FALSE); DCT(&Cb[i*bWidth+j], bwidth, TRUE); for(j=0; j<bwidth; j = j + 8) Y[i*bWidth+j] = DC1[idx]; Cb[i*bWidth+j] = DC2[idx]; Cr[i*bWidth+j] = DC3[idx]; idx++; delete [] DC1; delete [] DC2; delete [] DC3; /* AC 허프만테이블검색을빠르게하기위하여허프만테이블구조체에있는 *PT를설정한다. */ int Num, ith[4] = 16, 17, Th, key; /*y = (77 * R + 150 * G + 29 * B)>>8; cb = (B - y) + 128; cr = (R - y) + 128;*/ if(y>255.) y = 255.; if(y<0.) y = 0.; if(cb>255.) cb = 255.; if(cb<0.) cb = 0.; if(cr>255.) cr = 255.; if(cr<0.) cr = 0.; *pos = (BYTE)y; *(pos+1) = (BYTE)cb; *(pos+2) = (BYTE)cr; pos = pos + 3; // Y, Cb, Cr Plane Buffer // Y = new short[bwidth * bheight]; memset(y, 0, sizeof(short) * bwidth * bheight); Cb = new short[bwidth * bheight]; memset(cb, 0, sizeof(short) * bwidth * bheight); Cr = new short[bwidth * bheight]; memset(cr, 0, sizeof(short) * bwidth * bheight); int idx1, idx2; // Level Shifting -128 // for(i=0; i<height; i++) for(j=0; j<width; j++) DCT(&Cr[i*bWidth+j], bwidth, TRUE); // Differential DC Process // int Num_X = bwidth/8; int Num_Y = bheight/8; int idx = 0; short *DC1 = new short[num_x * Num_Y]; short *DC2 = new short[num_x * Num_Y]; short *DC3 = new short[num_x * Num_Y]; for(i=0; i<bheight; i = i + 8) for(j=0; j<bwidth; j = j + 8) DC1[idx] = Y[i*bWidth+j]; DC2[idx] = Cb[i*bWidth+j]; DC3[idx] = Cr[i*bWidth+j]; idx++; for(i=num_x * Num_Y - 1; i>0; i--) DC1[i] = DC1[i] - DC1[i-1]; DC2[i] = DC2[i] - DC2[i-1]; DC3[i] = DC3[i] - DC3[i-1]; idx = 0; for(i=0; i<bheight; i = i + 8) for(i=0; i<2; i++) Th = ith[i]; Num = TbH[Th].Num; TbH[Th].PT = new int[251]; for(k=0; k<251; k++) key = -9999; for(j=0; j<num; j++) if(tbh[th].huffval[j] == k) key = j; break; TbH[Th].PT[k] = key; /* HUFFMAN CODE ENCODEING!! */ m_pbuf = new BYTE[bWidth * bheight * 3]; // 실제로인코딩된데이터가저장될버퍼 m_index = 0; // 인덱스리셋 cnt = 0; // Bit총리셋 hencode(bwidth, bheight); while(cnt!= 0) ShotBit(0); _lwrite(hfile, (LPSTR)m_pBuf, m_index);

delete [] m_pbuf; PutEOI(hFile); (w >> 8); _lwrite(hfile, (LPSTR)&w, 2); // Number of Y Line 57, 51, 29, 40, 58, 51, 61, 60, // 임시메모리모두해제 // for(i=0; i<2; i++) Th = ith[i]; delete [] TbH[Th].PT; for(i=0; i<bheight; i++) for(j=0; j<bwidth; j++) idx1 = i*bwidth*3 + j*3; m_pdata[idx1] = (BYTE)Y[i*bWidth+j]; m_pdata[idx1+1] = (BYTE)Cb[i*bWidth+j]; m_pdata[idx1+2] = (BYTE)Cr[i*bWidth+j]; delete [] Y; delete [] Cb; delete [] Cr; // 파일폐쇄 // _lclose(hfile); void CJpeg::PutSOI(HFILE hfile) // SOI 저장 // WORD Marker = (0xd8 << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); void CJpeg::PutSOF(HFILE hfile, int Width, int Height) WORD Marker, SegSize, w; BYTE c; int i; Marker = (0xc0 << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); SegSize = 17; SegSize = (SegSize << 8) (SegSize >> 8); _lwrite(hfile, (LPSTR)&SegSize, 2); // Segment Size c = 8; _lwrite(hfile, (LPSTR)&c, 1); // P = 8 w = (WORD)Height; w = (w << 8) (w >> 8); _lwrite(hfile, (LPSTR)&w, 2); // Number of Y Line w = (WORD)Width; w = (w << 8) c = 3; _lwrite(hfile, (LPSTR)&c, 1); // Nf = 3 for(i=1; i<=3; i++) c = (BYTE)i; _lwrite(hfile, (LPSTR)&c, 1); // Component Identifier c = 17; _lwrite(hfile, (LPSTR)&c, 1); // HiVi if(i==1) c=0; else c=1; _lwrite(hfile, (LPSTR)&c, 1); // Tqi void CJpeg::PutSOS(HFILE hfile) WORD Marker, SegSize; BYTE c; int i; Marker = (0xda << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); SegSize = 12; SegSize = (SegSize << 8) (SegSize >> 8); _lwrite(hfile, (LPSTR)&SegSize, 2); // Segment Size c = 3; _lwrite(hfile, (LPSTR)&c, 1); // Ns = 3 for(i=1; i<=3; i++) c = (BYTE)i; _lwrite(hfile, (LPSTR)&c, 1); // Scan Component Selector if(i==1) c=0; else c=0x11; _lwrite(hfile, (LPSTR)&c, 1); // TdTa c = 0; _lwrite(hfile, (LPSTR)&c, 1); // Ss c = 0x3f; _lwrite(hfile, (LPSTR)&c, 1); // Se c = 0; _lwrite(hfile, (LPSTR)&c, 1); // AhAl void CJpeg::PutDQT(HFILE hfile) WORD Marker, SegSize; BYTE c; // Luminance Quantization Table // BYTE Qtb0[64] = 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, 26, 24, 22, 22, 24, 49, 36, 37, 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 66, 57, 80, 109, 81, 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, 103, 99; // Chrominance Quantization Table // BYTE Qtb1[64] = 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 ; Marker = (0xdb << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); // Marker SegSize = 67; SegSize = (SegSize << 8) (SegSize >> 8); _lwrite(hfile, (LPSTR)&SegSize, 2); // Segment Size c = 0; _lwrite(hfile, (LPSTR)&c, 1); // PqTq = 0 _lwrite(hfile, (LPSTR)Qtb0, 64); // Q0 ~ Q63 Marker = (0xdb << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); // Marker SegSize = 67; SegSize = (SegSize << 8) (SegSize >> 8); _lwrite(hfile, (LPSTR)&SegSize, 2); // Segment Size c = 1; _lwrite(hfile, (LPSTR)&c, 1); // PqTq = 1 _lwrite(hfile, (LPSTR)Qtb1, 64); // Q0 ~ Q63 void CJpeg::DCT(short * pos, int bwidth, BOOL Flag)

// DCT 분만아니라, DCT 후의 Zigzag 까지... 게다가 Quantization 까지!?// BYTE Qtb0[64] =16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40, 26, 24, 22, 22, 24, 49, 36, 37, 29, 40, 58, 51, 61, 60, 57, 51, 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 66, 57, 80, 109, 81, 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101, 103, 99; BYTE Qtb1[64] =17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99, 99,99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, +0.5556f, -0.9808f, +0.1951f, +0.8315f, -0.8315f, -0.1951f, +0.9808f, -0.5556f, +0.3827f, -0.9239f, +0.9239f, -0.3827f, -0.3827f, +0.9239f, -0.9239f, +0.3827f, +0.1951f, -0.5556f, +0.8315f, -0.9808f, +0.9808f, -0.8315f, +0.5556f, -0.1951f ; for(v=0; v<8; v++) for(u=0; u<8; u++) Sum = 0; for(y=0; y<8; y++) for(x=0; x<8; x++) Sum = Sum + pos[(int)(y*bwidth+x)] * dct_coeff[u][x] * dct_coeff[v][y]; Cu = 1.; if(u == 0) Cu = 0.7071f; Cv = 1.; if(v == 0) Cv = 0.7071f; ZZ[(int)(v*8+u)] = (short)(cu * Cv * Sum / 4.); Zigzag2(); int i, j, idx; for(i=0; i<8; i++) for(j=0; j<8; j++) idx = (i<<3)+j; ZZ[Index[idx]] = Temp[idx]; void CJpeg::PutDHT(HFILE hfile) /* standard 허프만테이블을읽어들여서멤버구조체에설정한후저장하고자하는파일에적어넣는함수입니다. */ m_pbuf = new BYTE[421]; BYTE HuffTb[421] = 255, 196, 1, 162, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99 ; if(flag) // TRUE : Chrominance, FALSE : Luminance for(i=0; i<64; i++) ZZ[i] = ZZ[i] / Qtb1[i]; else for(i=0; i<64; i++) ZZ[i] = ZZ[i] / Qtb0[i]; 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, 67, int i, j; int x, y, u, v; float Cu, Cv; float Sum; float dct_coeff[8][8] = +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +0.9808f, +0.8315f, +0.5556f, +0.1951f, -0.1951f, -0.5556f, -0.8315f, -0.9808f, +0.9239f, +0.3827f, -0.3827f, -0.9239f, -0.9239f, -0.3827f, +0.3827f, +0.9239f, +0.8315f, -0.1951f, -0.9808f, -0.5556f, +0.5556f, +0.9808f, +0.1951f, -0.8315f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, +0.7071f, -0.7071f, -0.7071f, +0.7071f, void CJpeg::Zigzag2() for(i=0; i<8; i++) for(j=0; j<8; j++) pos[i*bwidth+j] = ZZ[i*8+j]; int Index[64] = 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63; short Temp[64]; memcpy(temp, ZZ, 64 * sizeof(short)); 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181,

182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, 50, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, 243, 244, 245, 246, 247, 248, 249, 250, 255; memcpy(m_pbuf, HuffTb, 421); m_index = 0; // Huffman Table을읽어들이기위하여 Index를 Reset FindDHT(); _lwrite(hfile, (LPSTR)m_pBuf, 420); delete [] m_pbuf; // 주어진값이어느케티고리에소속되는지를반환하는함수 // BYTE CJpeg::GetCategory(short V) BYTE Num = 0; if(v < 0) V = -V; while(v!= 0) V = V >> 1; Num++; return Num; for(i=0; i<8; i++) for(j=0; j<8; j++) XX[idx] = pos[i*bwidth+j]; idx++; // DC Encode // DIFF = XX[0]; Val = GetCategory(DIFF); Code = TbH[ThDC].HUFFCODE[Val]; Size = TbH[ThDC].HUFFSIZE[Val]; if(diff < 0) DIFF--; ChargeCode(Code, Size); ChargeCode((WORD)DIFF, Val); // AC Encode // BYTE k = 0, R = 0; while(true) k++; if(xx[k] == 0) if(k==63) Rs = 0x00; 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, 131, 132, void CJpeg::hEncode(int bwidth, int bheight) int i, j; for(i=0; i<bheight; i = i + 8) for(j=0; j<bwidth; j = j + 8) EncodeDU(&Y[i*bWidth+j], FALSE, bwidth); EncodeDU(&Cb[i*bWidth+j], TRUE, bwidth); EncodeDU(&Cr[i*bWidth+j], TRUE, bwidth); Code = TbH[ThAC].HUFFCODE[TbH[ThAC].PT [Rs]]; Size = TbH[ThAC].HUFFSIZE[TbH[ThAC].PT [Rs]]; ChargeCode((WORD)Code, Size); break; else R++; else while(r>15) Rs = 0xf0; 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, void CJpeg::EncodeDU(short * pos, BOOL Flag, int bwidth) WORD Code; BYTE Val, Size; BYTE SSSS, Rs; short XX[64], DIFF; BYTE ThDC, ThAC; int idx = 0; int i, j; ThDC = 0; ThAC = 16; if(flag) ThDC = 1; ThAC = 17; Code = TbH[ThAC].HUFFCODE[TbH[ThAC].PT [Rs]]; Size = TbH[ThAC].HUFFSIZE[TbH[ThAC].PT [Rs]]; ChargeCode((WORD)Code, Size); R = R - 16; SSSS = GetCategory(XX[k]); //Rs = (R << 4) SSSS;

Rs = (R * 16) + SSSS; Code = TbH[ThAC].HUFFCODE[TbH[ThAC].PT [Rs]]; Size = TbH[ThAC].HUFFSIZE[TbH[ThAC].PT [Rs]]; ChargeCode((WORD)Code, Size); DIFF = XX[k]; if(diff < 0) DIFF = DIFF - 1; ChargeCode((WORD)DIFF, SSSS); R = 0; if(k==63) break; void CJpeg::ChargeCode(WORD Code, int Size) int i; BYTE Bit; for(i=0; i<size; i++) Bit = (Code >> (Size - 1 - i)) & 0x01; ShotBit(Bit); void CJpeg::ShotBit(BYTE Bit) static BYTE Bullet = 0; Bit = Bit << (7-cnt); Bullet = Bullet Bit; cnt++; if(cnt == 8) cnt = 0; m_pbuf[m_index] = Bullet; m_index++; if(bullet == 0xff) // 0xff가나오면 0x00으로 Byte Stuffing!! m_pbuf[m_index] = 0x00; m_index++; Bullet = 0; void CJpeg::PutEOI(HFILE hfile) // EOI 저장 // WORD Marker = (0xd9 << 8) 0xff; _lwrite(hfile, (LPSTR)&Marker, 2); ----------------------------- // Jpeg.h: interface for the CJpeg class. // ////////////////////////////////////////////////////////////////////// # i f!defined(afx_jpeg_h 2835EF17_2235 _11D2_8C8B_006097ADB77E INCLUDE D_) # d e f i n e AFX_JPEG_H 2835EF17_2235_11D2_8 C8B_006097ADB77E INCLUDED_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 struct SET BYTE C[3]; // Y, Cb, Cr 성분 ; struct DQT BYTE Q[64]; // Qantization Table 값 ; struct DHT BOOL Flag; // 사용되었는지여부를나타내는플래그 int Num; // 허프만코드의수 WORD *HUFFCODE; // 허프만코드 BYTE *HUFFSIZE; // 허프만코드의길이 BYTE *HUFFVAL; // 허프만코드가나타내는값 WORD MAXCODE[17]; // 해당길이에서가장큰코드 WORD MINCODE[17]; // 해당길이에서가장작은코드 int VALPTR[17]; // 해당길이의코드가시작되는인덱스 int *PT; // VALUE로 INDEX를빠르게찾기위한포인터 ; struct FRAMEHEADER WORD Y; // 이미지의높이 WORD X; // 이미지의넓이 BYTE Nf; // 컴포넌트수 BYTE C[3]; // 컴포넌트아이디 BYTE H[3]; // 컴포넌트의 Horizontal Sampling Factor BYTE V[3]; // 컴포넌트의 Vertical Sampling Factor BYTE Tq[3]; // 해당컴포넌트에사용되는양자화테이블번호 ; struct SCANHEADER BYTE Ns; // 컴포넌트수 BYTE Cs[3]; // 컴포넌트아이디 BYTE Td[3]; // 컴포넌트의 DC Huffman Table 번호 BYTE Ta[3]; // 컴포넌트의 AC Huffman Table 번호 BYTE Ss; BYTE Se; BYTE Ah; BYTE Al; ; class CJpeg public: // JPEG File을 Load하기위한함수들 // void LoadJPG(LPSTR FileName); // JPEG File을 Load하는함수 void LoadJPG2 (BYTE *Buffer, int BufSize); void FindSOI(); // Start of Image 마커를찾는함수 void FindDQT(); // Quantization Table 을찾아구조체에설정하는함수 void FindDHT(); // Huffman Table을찾아구조체에설정하는함수 void FindSOF(); // Frame Header를찾아구조체에설정하는함수 void FindSOS(); // Scan Header를찾아구조체에설정하는함수 void FindETC(); // DRI(Define Restart Interval) 로드 void Decode(); // 디코드를위한정보를설정하고디코드를시작 void DecodeMCU(int mx, int my); // MCU블럭을디코드하는함수 void DecodeDU(int N); // 8x8 Data Unit를디코드하는함수 void IDCT(); // Inverse DCT를하는함수 void Zigzag(); // Zigzag순으로되어있는 DU를원상복귀시키는함수 void DecodeAC(int Th); // DU중, AC 성분을디코드하는함수 void DecodeDC(int Th); // DU중, DC성분을디코드하는함수 short Extend(WORD V, BYTE T); // V를카테고리 T에맞도록확장 WORD Receive(BYTE SSSS); // 버퍼에서 SSSS비트만큼읽어오는함수 BYTE hdecode(int Th); // 허프만부호를디코드하는부분 BYTE NextByte(); // 버퍼에서다음 1 바이트를읽어오는함수 WORD NextBit(); // 버퍼에서다음 1 비트를읽어오는함수 void ConvertYUV2RGB(); // 디코드된데이터를컬러모델을바꿈과동시에 // 비트맵에호환되도록변환하는함수 // JPEG File을 Save하기위한함수들 // void SaveJPG(LPSTR FileName, int Width, int Height, BYTE *pp); // JPEG 파일을저장하는함수 void PutSOI(HFILE hfile); // Start of Image 마커를삽입 void PutDQT(HFILE hfile); // Quantizatino Table을삽입 void PutDHT(HFILE hfile); // Huffmann Table을삽입 void PutSOF(HFILE hfile, int Width,

int Height); // FrameHeader를삽입 void PutSOS(HFILE hfile); // ScanHeader를삽입 void PutEOI(HFILE hfile); // End of Image 마커를삽입 void ShotBit(BYTE Bit); // 1비트를버퍼에저장하는함수 void ChargeCode(WORD Code, int Size ); // Size만큼의길이 ( 아랫자리로부터 ) 로 Code를버퍼에저장하는함수 void EncodeDU(short *pos, BOOL Flag, int bwidth); // 8x8 Block을인코드하는함수 void hencode(int bwidth, int bheight); // 허프만인코딩하는부분 BYTE GetCategory(short V); // 주어진값의카테고리를구하는함수 void Zigzag2(); // Zigzag순서로만드는함수 void DCT(short *pos, int bwidth, BOOL Flag); // DCT를한후 Zigzag 및 Quantization 하는함수 int GetHeight(); // 이미지의높이를반환하는함수 int GetWidth(); // 이미지의넓이를반환하는함수 WORD Ri; // Restart Interval int m_rwidth; // 이미지의실제적인넓이 int m_rheight; // 이미지의실제적인높이 BYTE * pbyte; // NextByte() 함수에서쓰임 int cnt; // 비트단위로연산할때쓰이는카운터 short *Y; // Save할때쓰이는 Y Buffer short *Cb; // Save할때쓰이는 Cb Buffer short *Cr; // Save할때쓰이는 Cr Buffer SET *MCU; // MCU 단위의블럭 BYTE Hmax; // Maximum Horizontal Sampling Factor BYTE Vmax; // Maximum Vertical Sampling Factor BYTE * m_pdata; // 이미지버퍼 BYTE * m_pbuf; // 버퍼 int m_index; // 버퍼의위치를나타내는인덱스 DQT TbQ[20]; // Quantization Table DHT TbH[20]; // Huffman Table short ZZ[64]; // 8x8 Block 정보를담는배열 FRAMEHEADER FrameHeader; // FrameHeader 구조채 SCANHEADER ScanHeader; // ScanHeader 구조체 short PrevDC[3]; // DC 성분의 Predictor CJpeg(); virtual ~CJpeg(); ; #endif //!defined(afx_jpeg_h 2835EF17_2235 _11D2_8C8B_006097ADB77E INCLUDE D_) ------------------------------ // MainDlg.cpp : implementation file // #include "stdafx.h" #include "Tester.h" #include "MainDlg.h" #include "CardConnectDlg.h" #include <winscard.h> #include "string.h" #include "DBgps1.h" #include "DataView.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif // 전역변수선언...Header에선언해도됨. CString ReaderName; //Target Reader name SCARDCONTEXT hsccontext; //card context SCARDHANDLE hcardhandle; //card handle DWORD dwsharemode; // connect 모드 DWORD dwprotocols; // protocol type DWORD dwap; DWORD dwi, dwrdrcount; S C A R D _ R E A D E R S T A T E rgscstate[maximum_smartcard_re ADERS]; typedef struct char * cmdname; char * apdu; REFCOMMAND; REFCOMMAND SReg[] = //20개 "< 등록 > 선박번호쓰기 ", "005200000A", "< 등록 > 선박번호읽기 ", "00520100", "< 등록 > 등록자이름쓰기 ", "005200010A", "< 등록 > 등록자이름읽기 ", "00520101", "< 등록 > 주민번호쓰기 ", "005200020D", "< 등록 > 주민번호읽기 ", "00520102", "< 등록 > 등록자분류쓰기 ", "0052000301", "< 등록 > 등록자분류읽기 ", "00520103", "< 등록 > 카드번호쓰기 ", "005200040A", "< 등록 > 카드번호읽기 ", "00520104", "< 등록 > 발급기관쓰기 ", "005200050A", "< 등록 > 발급기관읽기 ", "00520105", "< 등록 > 발급일자쓰기 ", "0052000604", "< 등록 > 발급일자읽기 ", "00520106", "< 등록 > 발급코드쓰기 ", "0052000702", "< 등록 > 발급코드읽기 ", "00520107", "< 등록 >Applet Ver 쓰기 ", "0052000802", "< 등록 >Applet Ver 읽기 ", "00520108", "< 등록 >Ref Year 쓰기 ", "0052000902", "< 등록 >Ref Year 읽기 ", "00520109", "PIN(8-B) Verify하기 ", "00200001081122334455667788", ; REFCOMMAND SDec[] = //5개 "< 신고 > 새레코드쓰기 ", "005100FF0E", "< 신고 >N번째레코드읽기 ", "0051010N10", "< 신고 > 가장최근레코드기 ", "005103FF10", "< 신고 > 총레코드수읽기 ", "0051A1FF01", "< 신고 > 저장된레코드수읽기 ", "0051A3FF01", "PIN(8-B) Verify하기 ", "00200001081122334455667788", ; REFCOMMAND SCru[] = //5개 "< 항해 > 새레코드쓰기 ", "005000FF0C", "< 항해 >N번째레코드읽기 ", "0050010N0C", "< 항해 > 가장최근레코드기 ", "005003FF0C", "< 항해 > 총레코드수읽기 ", "0050A1FF01", "< 항해 > 저장된레코드수읽기 ", "0050A3FF01", "PIN(8-B) Verify하기 ", "00200001081122334455667788", ; //////////////////////////////////////////////////////////////////////////// / // CMainDlg dialog CMainDlg::CMainDlg(CWnd* pparent /*=NULL*/) : CDialog(CMainDlg::IDD, pparent) //AFX_DATA_INIT(CMainDlg) m_strcmd = _T(""); m_strerrcode = _T(""); m_strregcmd = _T(""); m_strdeccmd = _T(""); m_strcrucmd = _T(""); m_strshipnum = _T(""); m_strusercarnum = _T(""); m_strusercount = _T(""); m_struserid = _T(""); m_strusername = _T(""); m_strcomorg = _T(""); m_strcomday = _T("");

m_strcomcode = _T(""); m_strappletver = _T(""); m_struserid1 = _T(""); m_struserid2 = _T(""); m_strrefyear = _T(""); //AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hicon = AfxGetApp()->LoadIcon(IDR_MAINFR AME); void CMainDlg::DoDataExchange(CDataExchange* pdx) CDialog::DoDataExchange(pDX); //AFX_DATA_MAP(CMainDlg) D D X _ T e x t ( p D X, IDC_EDIT_COMMAND, m_strcmd); D D X _ T e x t ( p D X, IDC_EDIT_ISO_STATUS, m_strerrcode); DDX_Text(pDX, IDC_EDIT_REG_CMD, m_strregcmd); D D X _ T e x t ( p D X, IDC_EDIT_DECLARE_CMD, m_strdeccmd); D D X _ T e x t ( p D X, IDC_EDIT_CRUISE_CMD, m_strcrucmd); DDX_Text(pDX, IDC_SHIP_NUM, m_strshipnum); D D X _ T e x t ( p D X, I D C _ U S E R _ C A R D N U M, m_strusercarnum); DDX_Text(pDX, IDC_USER_COUNT, m_strusercount); DDX_Text(pDX, IDC_USER_ID, m_struserid); DDX_Text(pDX, IDC_USER_NAME, m_strusername); DDX_Text(pDX, IDC_COM_ORG, m_strcomorg); DDX_Text(pDX, IDC_COM_DAY, m_strcomday); DDX_Text(pDX, IDC_COM_CODE, m_strcomcode); DDX_Text(pDX, IDC_APPLET_VER, m_strappletver); DDX_Text(pDX, IDC_USER_ID1, m_struserid1); DDX_Text(pDX, IDC_USER_ID2, m_struserid2); DDX_Text(pDX, IDC_REF_YEAR, m_strrefyear); //AFX_DATA_MAP BEGIN_MESSAGE_MAP(CMainDlg, CDialog) //AFX_MSG_MAP(CMainDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_CBN_SELCHANGE(IDC_COMBO_RE ADER, OnSelectedReader) ON_BN_CLICKED(IDC_BTN_CONNECT, OnConnect) ON_BN_CLICKED(IDC_BTN_CLEAR, OnBtnClear) ON_BN_CLICKED(IDC_BTN_DISCONNE CT, OnDisconnect) ON_BN_CLICKED(IDC_BTN_SEND, OnSend) ON_BN_CLICKED(IDC_BTN_FIND, OnBtnFind) ON_CBN_SELCHANGE(IDC_COMBO_RE G, OnSelchangeComboReg) ON_CBN_SELCHANGE(IDC_COMBO_CR UISE, OnSelchangeComboCruise) ON_CBN_SELCHANGE(IDC_COMBO_DE CLARE, OnSelchangeComboDeclare) ON_BN_CLICKED(IDC_BTN_REG, OnSendRegCmd) ON_BN_CLICKED(IDC_BTN_DO_DECCM D, OnSendDecCmd) ON_BN_CLICKED(IDC_BTN_DO_CRUCM D, OnSendCruCmd) ON_BN_CLICKED(IDC_BUTTON9, OnCompleteReg) ON_BN_CLICKED(IDC_BTN_CLEAR_RE G, OnClearReg) ON_BN_CLICKED(IDC_BTN_CLEAR_DE CLARE, OnClearDeclare) ON_BN_CLICKED(IDC_BTN_CLEAR_CR UISE, OnClearCruise) ON_BN_CLICKED(IDC_MEM_SUBMIT, OnMemSubmit) ON_BN_CLICKED(IDC_MEM_SUBMIT2, OnMemSubmit_View) ON_BN_CLICKED(IDC_LIST_VIEW, OnListView) //AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////// / // CMainDlg message handlers BOOL CMainDlg::OnInitDialog() CDialog::OnInitDialog(); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon //object등록 streader = (CComboBox *)GetDlgItem(IDC_COMBO_READER); EventList = (CListBox *)GetDlgItem(IDC_EVENT_LIST); m_ctrledit = (CRichEditCtrl *)GetDlgItem(IDC_RICHEDIT_ISO_EXPL AIN); pregcombo = (CComboBox *)GetDlgItem(IDC_COMBO_REG); pdeccombo = (CComboBox *)GetDlgItem(IDC_COMBO_DECLARE); pcrucombo = (CComboBox *)GetDlgItem(IDC_COMBO_CRUISE); for(int i=0; i<6; i++) pdeccombo->addstring(sdec[i].cmdname); pcrucombo->addstring(scru[i].cmdna me); for(i=0; i<21; i++) pregcombo->addstring(sreg[i].cmdna me); // Smart Card Reader List를받아오기 LONG lreturn; LPTSTR szreaders; DWORD cchreaders = SCARD_AUTOALLOCATE; LPTSTR preader; // Establish a context. lreturn = SCardEstablishContext(SCARD_SCOPE_ USER, NULL, NULL, &hsccontext ); if ( SCARD_S_SUCCESS!= lreturn ) EventList->AddString(" 에러 >> Failed SCardEstablishContext"); EventList->SetCurSel(EventList->Get Count()-1); goto end; // Determine which readers are available. lreturn = SCardListReaders(hSCContext, NULL, (LPTSTR)&szReaders, &cchreaders ); if ( SCARD_S_SUCCESS!= lreturn ) EventList->AddString(" 에러 >> Failed SCardListReaders"); EventList->SetCurSel(EventList->Get Count()-1);

goto end; preader = szreaders; while ( '\0'!= *preader ) streader->addstring(preader); preader = preader + lstrlen(preader) + 1; streader->setcursel(0); UpdateData(false); OnSelectedReader(); end: for(int i=0,j=0; i< length; i+=2,j++) if(input[i]<0x3a) output[j] = ((input[i]-'0')<<4); else if(input[i]>0x60) input[i] -= 0x20; output[j] = ((input[i]-0x37)<<4); int index = streader->getcursel(); streader->getlbtext(index,tmp); streader->setcursel(index); ReaderName = tmp; UpdateData(false); void CMainDlg::OnConnect() UpdateData(true); CCardConnectDlg dlg; LONG lreturn = 0; return TRUE; // return TRUE unless you set the focus to a control // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CMainDlg::OnPaint() if (IsIconic()) CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.getsafehdc(), 0); // Center icon in client rectangle int cxicon = GetSystemMetrics(SM_CXICON); int cyicon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.width() - cxicon + 1) / 2; int y = (rect.height() - cyicon + 1) / 2; // Draw the icon dc.drawicon(x, y, m_hicon); else CDialog::OnPaint(); // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CMainDlg::OnQueryDragIcon() return (HCURSOR) m_hicon; int CMainDlg::Ascii2Hex(unsigned char *input, unsigned char *output, int length) if(input[i+1]<0x3a) output[j] = (input[i+1]-'0'); else if(input[i+1]>0x60) input[i+1] -= 0x20; output[j] = ((input[i+1]-0x37)); return j; unsigned char * CMainDlg::Hex2Ascii(unsigned char buffer[], int length) static unsigned char result[2048]; f o r ( i n t i=0,j=0;i<(length)&&j<2047;i++,j+=2 ) if((buffer[i]>>4)<0xa) result[j]=((buffer[i]>>4)+'0');// 첫째4 비트 (0~9인경우) else result[j]=((buffer[i]>>4)+0x37);// 첫째 4비트 (A~F인경우) if((buffer[i]&0x0f)<0xa) result[j+1]=((buffer[i]&0x0f)+'0');// 둘째4비트 (0~9인경우) else result[j+1]=((buffer[i]&0x0f)+0x37);/ / 둘째4비트 (A~F인경우) result[length*2]=0; memcpy(buffer,result,length*2); buffer[length*2]=0; return NULL; void CMainDlg::OnSelectedReader() UpdateData(true); CString tmp; if(dlg.domodal()==idok) CString str, str1; AfxMessageBox(ReaderName); if( SCARD_S_SUCCESS == (lreturn=scardconnect(hsccontext, ReaderName, dwsharemode, dwprotocols, &hcardhandle, &dwap))) switch(dwsharemode) case SCARD_SHARE_SHARED: str1 = " (Shared, "; break; case SCARD_SHARE_EXCLUSIVE: str1 = " (Exclusive, "; break; case SCARD_SHARE_DIRECT: str1 = " (Direct, "; break; switch(dwprotocols) case SCARD_PROTOCOL_T0: str1 +=" T0 ) "; break; case SCARD_PROTOCOL_T1: str1 +=" T1 ) "; break; case SCARD_PROTOCOL_T0 SCARD_PROTOCOL_T1: str1 +=" T0 T1 ) "; break; default: str1 +=" T0 T1 ) "; break;

str = " Card 연결성공 " + str1; EventList->AddString(str); EventList->SetCurSel(EventList->Get Count()-1); else str.format(" 경고 >> SCardConnect 명령실패 (0x%4x)",lReturn); EventList->AddString(str); EventList->SetCurSel(EventList->Get Count()-1); OnCardStatus(); if(lreturn == SCARD_S_SUCCESS) m_strcmd.format("00a40400095368697 02D47505301"); Transmit(m_strCmd); UpdateData(false); void CMainDlg::OnCardStatus() BYTE battr[64]; DWORD cbyte=64; DWORD cch =200; LONG lreturn; DWORD dwstate, dwprotocol; char szreader[256]; memset(szreader,0x00,200); memset(battr,0x00,cbyte); lreturn = SCardStatus(hCardHandle, szreader, &cch, &dwstate, &dwprotocol, (LPBYTE) &battr, &cbyte); if(scard_s_success!= lreturn) EventList->AddString(" Card Status 명령실패 "); EventList->SetCurSel(EventList->Get Count()-1); else CString str; Hex2Ascii(bAttr,cByte); str.format(" ATR>> %s ", battr); EventList->AddString(str); EventList->SetCurSel(EventList->Get Count()-1); void CMainDlg::OnBtnClear() EventList->ResetContent(); ASSERT(EventList->GetCount() == 0); void CMainDlg::OnDisconnect() SCardDisconnect(hCardHandle,SCARD_U NPOWER_CARD); EventList->AddString(" Card 연결이종료됐습니다 "); EventList->SetCurSel(EventList->Get Count()-1); void CMainDlg::OnSend() UpdateData(true); //Transmit(m_strCmd); void CMainDlg::ResultErrorCheck(CString get) if(get.mid(get.getlength()-4,get.getlen gth()).compare("9000")==0) m_ctrledit->setwindowtext(" 성공 "); else if(get.compare("6200")==0) m_ctrledit->setwindowtext("no information given"); else if(get.compare("6281")==0) m_ctrledit->setwindowtext("part of returned data may be corrupted"); else if(get.compare("6282")==0) m_ctrledit->setwindowtext("end of file/record reached before reading le bytes"); else if(get.compare("6283")==0) m_ctrledit->setwindowtext("selected file invalidated"); else if(get.compare("6284")==0) m_ctrledit->setwindowtext("fci not formatted according to 5.1.5"); else if(get.compare("6300")==0) m_ctrledit->setwindowtext("not information given"); else if(get.compare("6381")==0) m_ctrledit->setwindowtext("file filled up by the last write"); else if(get.compare("63c")==0) m_ctrledit->setwindowtext("cownter provided by 0 digit(cx)"); else if(get.compare("64")==0) m_ctrledit->setwindowtext("state of not valatile memory unchanged (SW2=00 other values are RFU"); else if(get.compare("6500")==0) m_ctrledit->setwindowtext("no information given"); else if(get.compare("6581")==0) m_ctrledit->setwindowtext("memory failure"); else if(get.compare("66")==0) m_ctrledit->setwindowtext("reserved for security-related issues(not defined in this part of ISO/IEC 7816"); else if(get.compare("6700")==0) m_ctrledit->setwindowtext("wrong Length"); else if(get.compare("6800")==0) m_ctrledit->setwindowtext("no information given"); else if(get.compare("6881")==0) m_ctrledit->setwindowtext("logical channel not supported"); else if(get.compare("6882")==0) m_ctrledit->setwindowtext("secure messageing not supported"); else if(get.compare("6900")==0) m_ctrledit->setwindowtext("no information given"); else if(get.compare("6981")==0) m_ctrledit->setwindowtext("command incompatible with file struecture"); else if(get.compare("6982")==0) m_ctrledit->setwindowtext("security status not satisfied"); else if(get.compare("6983")==0) m_ctrledit->setwindowtext("authentic ation method blockd"); else if(get.compare("6984")==0) m_ctrledit->setwindowtext("referance data invalidated"); else if(get.compare("6985")==0) m_ctrledit->setwindowtext("conditions of use not satisfied"); else if(get.compare("6986")==0) m_ctrledit->setwindowtext("command not allowed (no current EF"); else if(get.compare("6987")==0) m_ctrledit->setwindowtext("expected SM data objects missing"); else if(get.compare("6988")==0) m_ctrledit->setwindowtext("sm data objects incorrect"); else if(get.compare("6a00")==0) m_ctrledit->setwindowtext("no information given"); else if(get.compare("6a80")==0) m_ctrledit->setwindowtext("incorrect parameters in the data field"); else if(get.compare("6a81")==0) m_ctrledit->setwindowtext("fuction not supported"); else if(get.compare("6a82")==0) m_ctrledit->setwindowtext("file not found"); else if(get.compare("6a83")==0) m_ctrledit->setwindowtext("record not found"); else if(get.compare("6a84")==0) m_ctrledit->setwindowtext("not enough memory space in the file"); else if(get.compare("6a85")==0)

m_ctrledit->setwindowtext("lc inconsistent with TLV structure"); else if(get.compare("6a86")==0) m_ctrledit->setwindowtext("incorrect parameters P1-P2"); else if(get.compare("6a87")==0) m_ctrledit->setwindowtext("lc inconsistent with P1-P2"); else if(get.compare("6a88")==0) m_ctrledit->setwindowtext("reference d data not found"); else if(get.compare("6b00")==0) m_ctrledit->setwindowtext("wrong parameter p1,p2"); else if(get.compare("6c")==0) m_ctrledit->setwindowtext("wrong length LE : SW2 indicates the exact length "); else if(get.compare("6d00")==0) m_ctrledit->setwindowtext("ins not supported"); else if(get.compare("6e00")==0) m_ctrledit->setwindowtext("cla not supported"); else if(get.compare("6f00")==0) m_ctrledit->setwindowtext("no precise diagnosis"); void CMainDlg::OnBtnFind() UpdateData(true); ResultErrorCheck(m_strErrCode); // Combo <Reg> void CMainDlg::OnSelchangeComboReg() int current = pregcombo->getcursel(); pregcombo->setcursel(current); m_strregcmd = SReg[current].apdu; UpdateData(false); // Combo <Cruise> void CMainDlg::OnSelchangeComboCruise() int current = pcrucombo->getcursel(); pcrucombo->setcursel(current); m_strcrucmd = SCru[current].apdu; UpdateData(false); // Combo <Declare> void CMainDlg::OnSelchangeComboDeclare() int current = pdeccombo->getcursel(); pdeccombo->setcursel(current); m_strdeccmd = SDec[current].apdu; UpdateData(false); void CMainDlg::OnSendRegCmd() UpdateData(true); Transmit(m_strRegCmd); void CMainDlg::OnSendDecCmd() UpdateData(true); Transmit(m_strDecCmd); void CMainDlg::OnSendCruCmd() UpdateData(true); Transmit(m_strCruCmd); void CMainDlg::Transmit(CString sinput) unsigned char bsendbuffer[1024]; unsigned char brecvbuffer[2048]; unsigned char tmp[1024]; DWORD cbsendlength=5; unsigned long cbrecvlength=2048; LONG lreturn; memset(tmp,0,1024); int len = sinput.getlength(); memcpy(tmp,sinput,len); Ascii2Hex(tmp,bSendBuffer,len); len /=2; if(dwap == SCARD_PROTOCOL_T0) lreturn = SCardTransmit(hCardHandle, SCARD_PCI_T0, bsendbuffer, len, NULL, brecvbuffer, &cbrecvlength); else lreturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, bsendbuffer, len, NULL, brecvbuffer, &cbrecvlength); if( SCARD_S_SUCCESS!= lreturn ) CString str, tmp; str = sinput+" 명령을전송하는데실패했습니다 "; tmp.format("( 0x%x )",lreturn); str += tmp; EventList->AddString(str); EventList->SetCurSel(EventList->Get Count()-1); else CString tmp,str; tmp = " 전송 : "+sinput; EventList->AddString(tmp); EventList->SetCurSel(EventList->Get Count()-1); Hex2Ascii(bRecvBuffer, cbrecvlength); tmp.format(" 받음 : %s", brecvbuffer); EventList->AddString(tmp); EventList->SetCurSel(EventList->Get Count()-1); tmp = brecvbuffer; i f ( (strncmp(tmp,"61",2)==0) && (tmp.getlength()==4) ) str.format("00c00000%c%c",tmp.getat( 2),tmp.GetAt(3)); Transmit(str); ResultErrorCheck(tmp); UpdateData(false); void CMainDlg::Transmit2(unsigned char *a_pdata, int a_nlen) unsigned char bsendbuffer[1024]; unsigned char brecvbuffer[2048]; DWORD cbsendlength=5; unsigned long cbrecvlength=2048; LONG lreturn; int len; memcpy(bsendbuffer, a_pdata, a_nlen); len = a_nlen; if(dwap == SCARD_PROTOCOL_T0) lreturn =

SCardTransmit(hCardHandle, SCARD_PCI_T0, bsendbuffer, len, NULL, brecvbuffer, &cbrecvlength); else lreturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, Count()-1); tmp = brecvbuffer; i f ( (strncmp(tmp,"61",2)==0) && (tmp.getlength()==4) ) str.format("00c00000%c%c",tmp.getat( 2),tmp.GetAt(3)); Transmit(str); ResultErrorCheck(tmp); UpdateData(false); void CMainDlg::OnCompleteReg() CString str; str.format("0052000a"); Transmit(str); str.format("005200020d"); str += m_struserid1; Transmit(str); str.format("0052000301"); str += m_strusercount; Transmit(str); str.format("005200040a"); str += m_strusercarnum; Transmit(str); str.format("005200050a"); str += m_strcomorg; Transmit(str); str.format("0052000702"); str += m_strcomcode; Transmit(str); str.format("0052000802"); str += m_strappletver; Transmit(str); str.format("0052000902"); str += m_strrefyear; Transmit(str); */ UpdateData(false); bsendbuffer, len, NULL, brecvbuffer, &cbrecvlength); if( SCARD_S_SUCCESS!= lreturn ) CString str, tmp; str = " 명령을전송하는데실패했습니다 "; tmp.format("( 0x%x )",lreturn); str += tmp; EventList->AddString(str); EventList->SetCurSel(EventList->Get Count()-1); else CString tmp,str; tmp = " 전송 : "; EventList->AddString(tmp); EventList->SetCurSel(EventList->Get Count()-1); void CMainDlg::OnClearReg() CString str; str.format("0052c0ff"); Transmit(str); void CMainDlg::OnClearDeclare() CString str; str.format("0051c0ff"); Transmit(str); void CMainDlg::OnClearCruise() CString str; str.format("0050c0ff"); Transmit(str); void CMainDlg::OnMemSubmit() UpdateData(true); CString str; str.format("005200000a"); // unsigned char outbuf[100]; //Ascii2Hex(str,outbuf,10); str +=m_strshipnum; Transmit(str); /* unsigned char arbinbuff[100]; unsigned char arorder[40]; strcpy((char*)arorder, "005200000A"); Ascii2Hex(arOrder, arbinbuff, strlen((char*)arorder)); void CMainDlg::OnMemSubmit_View() UpdateData(true); CString str; str.format("00520100"); Transmit(str); /* str.format("00520101"); Transmit(str); str.format("00520102"); Transmit(str); str.format("00520103"); Transmit(str); str.format("00520104"); Transmit(str); str.format("00520105"); Transmit(str); str.format("00520107"); Transmit(str); str.format("00520108"); Transmit(str); str.format("00520109"); Transmit(str); */ UpdateData(false); void CMainDlg::OnListView() CDataView dlg; dlg.domodal(); Invalidate(true); ------------------------ // MainDlg.h : header file // Hex2Ascii(bRecvBuffer, cbrecvlength); tmp.format(" 받음 : %s", brecvbuffer); EventList->AddString(tmp); EventList->SetCurSel(EventList->Get memcpy(arbinbuff+strlen((char*)arorde r)/2, (LPCSTR)m_strShipNum, 10); Transmit2(arBinBuff, strlen((char*)arorder)/2+10); str.format("005200010a"); str += m_strusername; Transmit(str); # i f!defined(afx_maindlg_h A0A1A9BA _4C1D_4ED8_A4CA_291019127695 IN CLUDED_) # d e f i n e AFX_MAINDLG_H A0A1A9BA_4C1D_4 ED8_A4CA_291019127695 INCLUDED_

#if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include "DataView.h" #include <winscard.h> //////////////////////////////////////////////////////////////////////////// / // CMainDlg dialog int static g_nimgwidth = 640; int static g_nimgheight = 557; class CMainDlg : public CDialog // Construction public: void Transmit(CString sinput); void Transmit2(unsigned char *a_pdata, int a_nlen); void ResultErrorCheck(CString get); void OnCardStatus(); unsigned char * Hex2Ascii(unsigned char buffer[], int length); int Ascii2Hex(unsigned char * input, unsigned char * output, int length); CMainDlg(CWnd* pparent = NULL); // standard constructor CComboBox * streader; // Reader list CListBox * EventList; // 결과창리스트 CRichEditCtrl* m_ctrledit; //ISO7816 Error 윈도우 CComboBox * pregcombo; CComboBox * pdeccombo; CComboBox * pcrucombo; // Dialog Data //AFX_DATA(CMainDlg) enum IDD = IDD_TESTER_DIALOG ; CString m_strcmd; CString m_strerrcode; CString m_strregcmd; CString m_strdeccmd; CString m_strcrucmd; CString m_strshipnum; CString m_strusercarnum; CString m_strushipnum; CString m_strusercount; CString m_struserid; CString m_strusername; CString m_strcomorg; CString m_strcomday; CString m_strcomcode; CString m_strappletver; CString m_struserid1; CString m_struserid2; CString m_strrefyear; //AFX_DATA // ClassWizard generated virtual function overrides //AFX_VIRTUAL(CMainDlg) protected: virtual void DoDataExchange(CDataExchange* pdx); // DDX/DDV support //AFX_VIRTUAL // Implementation protected: ; HICON m_hicon; // Generated message map functions //AFX_MSG(CMainDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnSelectedReader(); afx_msg void OnConnect(); afx_msg void OnBtnClear(); afx_msg void OnDisconnect(); afx_msg void OnSend(); afx_msg void OnBtnFind(); afx_msg void OnSelchangeComboReg(); afx_msg void OnSelchangeComboCruise(); afx_msg void OnSelchangeComboDeclare(); afx_msg void OnSendRegCmd(); afx_msg void OnSendDecCmd(); afx_msg void OnSendCruCmd(); afx_msg void OnCompleteReg(); afx_msg void OnClearReg(); afx_msg void OnClearDeclare(); afx_msg void OnClearCruise(); afx_msg void OnMemSubmit(); afx_msg void OnMemSubmit_View(); afx_msg void OnListView(); //AFX_MSG DECLARE_MESSAGE_MAP() //AFX_INSERT_LOCATION // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif //!defined(afx_maindlg_h A0A1A9BA _4C1D_4ED8_A4CA_291019127695 IN CLUDED_) ------------------------------ // Tester.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "Tester.h" #include "MainDlg.h" #include <initguid.h> #include "Tester_i.c" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = FILE ; #endif //////////////////////////////////////////////////////////////////////////// / // CTesterApp BEGIN_MESSAGE_MAP(CTesterApp, CWinApp) //AFX_MSG_MAP(CTesterApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////////// / // CTesterApp construction CTesterApp::CTesterApp() // TODO: add construction code here, // Place all significant initialization in InitInstance //////////////////////////////////////////////////////////////////////////// / // The one and only CTesterApp object CTesterApp theapp; //////////////////////////////////////////////////////////////////////////// / // CTesterApp initialization BOOL CTesterApp::InitInstance() if (!InitATL()) return FALSE; AfxEnableControlContainer(); CCommandLineInfo cmdinfo; ParseCommandLine(cmdInfo); if (cmdinfo.m_brunembedded cmdinfo.m_brunautomated) return TRUE; AfxInitRichEdit(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif CMainDlg dlg; m_pmainwnd = &dlg; int nresponse = dlg.domodal(); if (nresponse == IDOK) // TODO: Place code here to handle when the dialog is // dismissed with OK else if (nresponse == IDCANCEL) // TODO: Place code here to handle when the dialog is // dismissed with

Cancel // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; CTesterModule _Module; BEGIN_OBJECT_MAP(ObjectMap) END_OBJECT_MAP() LONG CTesterModule::Unlock() AfxOleUnlockApp(); return 0; LONG CTesterModule::Lock() AfxOleLockApp(); return 1; LPCTSTR CTesterModule::FindOneOf(LPCTSTR p1, LPCTSTR p2) while (*p1!= NULL) LPCTSTR p = p2; while (*p!= NULL) if (*p1 == *p) return CharNext(p1); p = CharNext(p); p1++; return NULL; int CTesterApp::ExitInstance() if (m_batlinited) if (FAILED(hRes)) m_batlinited = FALSE; return FALSE; _Module.Init(ObjectMap, AfxGetInstanceHandle()); _Module.dwThreadID = GetCurrentThreadId(); LPTSTR lpcmdline = GetCommandLine(); //this line necessary for _ATL_MIN_CRT TCHAR sztokens[] = _T("-/"); BOOL brun = TRUE; LPCTSTR lpsztoken = _Module.FindOneOf(lpCmdLine, sztokens); while (lpsztoken!= NULL) if (lstrcmpi(lpsztoken, _T("UnregServer"))==0) _Module.UpdateRegistryFromResource(I DR_TESTER, FALSE); _Module.UnregisterServer(TRUE); //TRUE means typelib is unreg'd brun = FALSE; break; if (lstrcmpi(lpsztoken, _T("RegServer"))==0) _Module.UpdateRegistryFromResource(I DR_TESTER, TRUE); _Module.RegisterServer(TRUE); brun = FALSE; break; lpsztoken = _Module.FindOneOf(lpszToken, sztokens); return TRUE; -------------------------- _Module.RevokeClassObjects(); _Module.Term(); CoUninitialize(); return CWinApp::ExitInstance(); BOOL CTesterApp::InitATL() m_batlinited = TRUE; #if _WIN32_WINNT >= 0x0400 HRESULT hres = C o I n i t i a l i z e E x ( N U L L, COINIT_MULTITHREADED); #else HRESULT hres = CoInitialize(NULL); #endif if (!brun) m_batlinited = FALSE; _Module.Term(); CoUninitialize(); return FALSE; hres = _Module.RegisterClassObjects(CLSCTX_ LOCAL_SERVER, REGCLS_MULTIPLEUSE); if (FAILED(hRes)) m_batlinited = FALSE; CoUninitialize(); return FALSE;

제 3 절중국차량용블랙박스 ( 흑상자 ) 적용을발표하는북경공안 그림 40 차량용블랙박스 ( 흑상자 ) 적용을발표하는북경공안 - 신화통신