Friday, February 11, 2011

 

[Under-writing] 마이크로커널 구조 - On Microkernel Architecture


1. Whey Micro-kernel architecture?

-> The problem of old monolithic kernel -> Millions of lines of code. Hard to manage.

-> Hard to debug, Hard to obtain reliability.

1. Micro-kernel Architecture의 등장 배경
기존 Monolithic Kernel의 문제점 언급 -> 수백만줄, 복잡함, 관리하기 어려움 -> 신뢰성 확보의 어려움.

2. The principle of Micro-kernel architecture.

-> Divide the Monolithic Kernel into two parts. The core is called micro-kernel which is light and operates in kernel mode. The other part runs in User-mode as (mostly) threads.

-> The micro-kernel provides only a few set of core services such as Scheduling, Memory Management, etc. (The user mode OS part can utilize thise services to implement their own Scheduling and Memory Managment policies.)

2. Micro-kernel Architecture의 원리
기존 Monolithic Kernel에서 핵심적인 부분을 떼어내어 Micro-kernel로 분리한다. 이 Micro-kernel은 kernel mode에서
동작한다. OS의 나머지 부분들은 User mode service로 동작한다 (thread의 형태로). 이 때, user mode에서 동작하는
부분은 micro-kernel의 API를 통해 메모리 할당이나, scheduling과 같은 작업을 수행한다. 즉, OS가 Micro-kernel과
Micro-kernel에 기반한 user mode OS service 부분으로 나누어지는 것이다.


Brief Layout of Micro-kernel Architecture.


App1 | App2 | App3|
-----------------------------------------------------
OS1 services | OS2 services | OS 3 services |
-----------------------------------------------------
Resource Manager (kernel mode)
-----------------------------------------------------
Micro Kernel (kernel mode)
-----------------------------------------------------
Hardware Abstraction Layer ( HAL )
-----------------------------------------------------
Hardware
-----------------------------------------------------

3. List of services provided by Micro-kernel.

-> The most critical functions of OS are gathered here.
For example, L4 Micro-kernel provides only three services.

1) Address Space (Memory Management).
2) Thread and Scheduling (Process/Thread management)
3) Communication (Inter-Process Communication)

3. Micro-kernel이 제공하는 기능들.
OS에서 가장 핵심적인 기능만을 제공한다.
예를 들면, L4 Micro-kernel은 다음의 세 가지 기능만을 제공한다.

1) Address Space (Memory Management).

2) Thread and Scheduling (Process/Thread management)
3) Communication (Inter-Process Communication)

4. Strengths of Mircokernel architecture.

1. Small kernel -> less prone to errors.

2. Even if the user mode OS services goes down, the system does not crash.

(It can safely re-configure the system).

3. You can run different kinds of OS on the same Micro-kernel.

So, you can still use the legacy OS system.

(e.g. Mach OS (base for MacOSX) run BSD, DOS, and so on..)

4. 장점.
1. Kernel 모드에서 수행되는 코드의 크기가 아주 작아진다 -> 버그 수 감소
2. User Mode OS service들이 오동작을 일으켜도 시스템 자체가 다운되는 것을
방지할 수 있다. OS service들을 다시 수행하면 된다. 물론, 관련된 Application들이
죽는 것까지 방지할 수는 없다.
3. Micro-kernel을 기반으로 다양한 OS를 동시에 운영할 수 있다.
Mach의 경우, Micro-kernel 위에 BSD, DOS 등 여러 가지 OS를 올려서 수행했다.
(왜? 기존의 legacy code들을 이용하기 위해서)

5. Weaknesses.

1. Every kernel service involves "messaging" to the micro-kernel.

-> It can degrade the performance.

2. You can use various Operating Systems but you should re-write some part of

5. 단점
1. Message passing 문제로 인해 performance 저하가 있다.
2. 다양한 OS를 동시에 올릴 수는 있으나, Source code를 수정해야 한다. (물론 일부만 수정한다)
3.


6. 결론


OS에 무엇이 중요한가? "성능보다 안정성이 우선!" <- CPU 속도 향상으로 성능 문제는 이차적인 것이 됨. 바이러스, 해커의 침입, 내부 버그 등에 의한 시스템 다운이 큰 문제 -> 안정성/신뢰성 향상 필요.


Micro-kernel approach가 이러한 문제를 상당부분 해결해 줄 수 있을 것이다.


Example>

L4 : Fiasco, Iguana
Mach
Minix (limited)
Windows NT (MS insists)

1. Microkernel 방법론이 왜 나왔는가? (배경)

기존의 OS는 Memory Management, Scheduler, File system, IPC, Device Drivers 등의 수많은 기능을 포함하는 하나의 큰 프로그램으로 작성되었다. 이를 Monolithic Kernel 이라고 부른다. Unix(BSD, Linux), DOS, 초기 버전의 Windows 등이 Monolithic Kernel의 대표적인 예이다.

초창기 OS들은 Monolithic Kernel로 작성해도 관리가 가능했다. 덩치가 별로 크지 않았기 때문이다 (수십만 줄 정도). 하지만 H/W 기술이 발전하면서 OS에도 다양한 기술들이 도입되었다. Monolithic kernel에 이런 저런 기능을 추가하는 과정에서 OS는 수백만 줄 이상의 코드로 이루어진 거대한 프로그램으로 진화했다.

OS의 덩치가 커지면서 많은 문제가 발생했다. 가장 큰 문제는 OS의 신뢰성 확보 문제였다. 아무리 뛰어난 프로그래머들이 모여서 일을
한다고 해도 수백만 줄의 코드로 구성된 프로그램에서 버그를 완전히 없앤다는 것은 불가능하다. 좋은 예가 Windows 98이다. 내노라
하는 OS 프로그래머들이 모여서 작성한 OS이지만, 우리는 "Blue Screen"의 공포에 시달려야 했다(Blue Screen이 발생하는 경우,
Rebooting외에는 방법이 없었다). 뿐만 아니라 현재 사용중인 Windows XP에서도 "치명적인 오류로 인해 해당 프로그램을 종료합니다"라는
창을 수시로 접할 수 있다. MS의 차기 윈도우인 Vista는 많은 새로운 기능들을 포기했음에도 불구하고 계속 출시를 연기하고 있다.

OS는 컴퓨터를 직접 관리한다. 따라서 OS가 오동작을 일으키면 OS상에서 동작하는 모든 Application이 영향을 받게 된다.

1980년대에 이미 이러한 현상을 예측(관찰)하고 해결하려는 노력이 있었다. Mach OS로 대표되는 Micro-kernel Architecture 이다.

"왜 OS의 모든 부분들을 Kernel 모드에서 동작시켜야 하는가? 꼭 필요한 부분만 Kernel Mode 에서 동작시키고, 나머지는 User Mode에서 수행시키면 좀 더 안정한 OS가 될 것 아닌가?".


이 방법은 처음 카네기 멜론 대학에서 수행한 Mach Project에서 시작되었다. Mach는 Message Passing에 기반한 Microkernel 운영체제이다. Mach 개발자들은

Microkernel 을 작성하고, 그 위에 다양한 OS를 User Application으로 수행시키는 방법을 실험하였다. (BSD Unix, DOS 등). 현재 Apple Tiger OS는 Mach 3.0 운영체제에 기반하고 있다


(쉬어가 기 역사: Steve Jobs가 NextStep을 설립할 때 카네기 멜론 대학에서 Mach OS를 개발하던 Avie Tavarian을 데려왔죠. 이 사람은 Mach OS에 기반한 NextStep OS를 개발했습니다. 그리고 NextStep이 Apple에 흡수되면 자연스럽게 Apple Mac OS로 발전하게 되었죠. Avie Tavarian은 Apple OS Division을 책임지면서 Apple내 No.2의 위치에까지 올랐으나, 2005년도인가 Apple을 떠나 Tellme Networks라는 회사에 합류하게 됩니다.)

2. Microkernel은 어떤 기능을 제공하는가?

앞 서, Microkernel은 기존의 Monolithic OS에서 가장 중요한 기능만을 분리한 것이라고 했다. 이것들은 Address space (Memory Management), Thread & Scheduler, 그리고 Communication(IPC) 이다. 이 세가지 기능이 Microkernel 수준에서 구현되고, kernel 모드에서 동작한다. Minix 같은 경우는 Device Driver도 Microkernel 수준에서 동작시킨다. 그 이유는 INTEL CPU의 독특한 구조 때문이다.


(INTEL CPU의 구조는 관련 자료를 참조)


3. 현재 Microkernel 구조를 채용한 OS는 어떠한 것들이 있는가?

Linux : Monolithic
Minix : Microkernel
Mach : Microkernel
Windows NT : Microkernel

4. Microkernel을 어떻게 이해해야 하는가?

기존의 Kernel을 2개의 부분으로 나눈것. User Level Operating System을 작성하기 위한 핵심 서비스를 제공하는 Kernel System.


 

Using jpeglib on Windows - decoding (디코딩)

앞서 포스팅한 jpeglib 문제 해결에 이어서,

jpeg 파일을 jpeglib를 이용하여 디코딩하는 루틴을 설명합니다.

코드에 코멘트를 잘 달아놓았으므로 이해하는데 큰 문제는 없을 겁니다.

Step 1. 파일 첫머리에 다음과 같이 include를 해줍니다.

// jpeglib를 사용하기 위한 include 파일.
//
#include "jinclude.h"
#include "jpeglib.h"

Step 2. 디코딩 함수는 다음과 같습니다.

a_pFilename -> jpeg 파일 이름입니다.
a_pBuffer -> 이미지를 담을 버퍼에 대한 포인터입니다.
버퍼는 함수 내부에서 자동으로 할당합니다.

bool read(char *a_pFilename, JSAMPLE **a_pBuffer)
{

// JPEG 파일을 해석합니다.
// 해석 과정에서 width, height, color space, bytes per pixel 같은 값들이
// 추출됩니다.
//

// Data strucure required for decoding JPEG file.
//
struct jpeg_decompress_struct cInfo;
struct jpeg_error_mgr cErrMgr;

FILE *pFile;
int iRowStride, i;
JSAMPARRAY pRows;


// 파일 이름부터 체크하고,
//
if( !a_pFilename )
return false;

// 파일을 엽니다.
// 반드시 binary mode로 열어야 합니다.
//
pFile = fopen(a_pFilename, "rb");
if( !pFile )
return false;

// 1. Install error manager.
//
cInfo.err = jpeg_std_error(&cErrMgr);

// 2. Create JPEG decompressor object.
//
jpeg_create_decompress(&cInfo);

// 3. Specify the data source.
//
jpeg_stdio_src(&cInfo, pFile);

// 4. Read JPEG Header to extract image information.
//
(void) jpeg_read_header(&cInfo, TRUE);

// 이 시점부터 cInfo 구조체를 통해 jpeg image의 원래 정보들에 접근할 수 있습니다.
// 예를 들면, width, height, color space, number of components per pixel 등등
//

// 5. JPEG 이미지를 어떤 출력 포맷으로 디코딩할 것인지 지정합니다.
// 여기서는 JCS_RGB 포맷으로 디코딩합니다.
// 이전 포스팅에서 추가한 JCS_BGRA 포맷을 지정하면 32bit BGRA 포맷으로
// 디코딩됩니다. 출력포맷은 반드시 아래 Step 6에서 jpeg_start_decompress() 함수 호출
// 이전에 지정해야 합니다.

//
cInfo.out_color_space = JCS_RGB;

// 6. Initiate decompress procedure.
// 이 함수는 decoding을 위한 전처리를 하는 함수입니다.
// cInfo.output_width, cInfo.output_height와 같이 최종 출력 이미지에 대한
// 정보들이 여기에서 계산됩니다.
//

(void) jpeg_start_decompress(&cInfo);

// 7. 이미지 디코딩을 위한 메모리를 할당합니다.
// 디코더는 2단계의 버퍼를 사용합니다. 하나는 Row buffer로서 각 line별로 출력 버퍼를
// 가리킵니다. 다른 하나는 이미지 버퍼로서 실제 이미지를 저장합니다.
// 일반적인 경우, 각 Row[i]는 이미지 버퍼에서 i번째 line의 시작 주소를 저장합니다.
//

// 이미지의 한 scanline의 크기 계산.
//
iRowStride = cInfo.output_width * cInfo.output_components;

// 이미지 버퍼를 할당한다.
//
(*a_pBuffer) = new JSAMPLE[ iRowStride * cInfo.output_height ];
if( !(*a_pBuffer) )
{
// Allocation failed.
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
return false;
}

// Row 버퍼를 할당한다.
// 여기서는 한번에 한 줄씩만 디코딩한다.
//
pRows = new JSAMPROW[ 1 ];
if( !pRows )
{
// Allocation failed.
delete[] (*a_pBuffer);
(*a_pBuffer) = NULL;
jpeg_destroy_decompress(&cInfo);
fclose(pFile);
return false;
}

// 디코딩 루프: 모든 line이 디코딩될 때까지 반복한다.
//
i = 0;
while (cInfo.output_scanline < cInfo.output_height)
{
// Decode it !
pRows[0] = (JSAMPROW)( (*a_pBuffer) + iRowStride * i); // Row 버퍼 설정
(void) jpeg_read_scanlines(&cInfo, pRows, 1); // 디코딩 함수 호출
i++;
}

// 8. Finish decompression.
//
(void) jpeg_finish_decompress(&cInfo);

// 9. Reclaim resources and return.
//
delete[] pRows;
jpeg_destroy_decompress(&cInfo);
fclose(pFile);

return true;
}

 

Using jpeglib on Windows (윈도우에서 jpeglib 사용하기)

오픈 소스 jpeglib를 받아서 VIsual C++로 컴파일하는 것은 크게 어렵지 않습니다.
대부분의 경우, 소스 다운로드 받고, 프로젝트를 생성한 후, 프로젝트에 파일을 추가하고
컴파일하면 잘 돌아갑니다.

하지만, 경우에 따라서 몇가지 문제가 발생할 수 있는데, 제가 경험했던 문제들과
그 해결책을 여기에 기록으로 남깁니다.

참고로 jpeglib는 ImageMagick-windows Package에 포함되어 있는 것을
사용했습니다. 해당 Package에 VC++에서 컴파일되는 jpeglib가 만들어져 있습니다.

1. undefined refernce to "_imp_jpeg_xxxx" error
일반적으로 이 문제는 Project간 Dependency가 제대로 잡혀 있지 않을 때 나옵니다.
Linking 과정에서 함수가 포함된 Lib를 못찾는 경우죠.

하지만 제가 만난 경우는 C와 C++간 호환성 문제였습니다.
jpeglib는 C 코드로 컴파일되었고, 이 Lib를 사용하는 Windows Application은 C++ 코드로
작성되었기 때문이죠. 그런데, jpeglib 내부를 살펴보면 이 문제가 고려되어 있습니다.
C++로 컴파일 할 때에는 jpeglib.h 헤더 전체를 extern "C" { ... } 구문으로 감싸게 하는거죠.

#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
extern "C" {
#endif
#endif

...
매크로, 데이터 타입, 함수 선언 등등.
...

#ifdef __cplusplus
#ifndef DONT_USE_EXTERN_C
}
#endif
#endif

따라서 DONT_USE_EXTERC_C를 정의하지 않은 한 문제가 발생해서는 안되었습니다.
답답해서 Windows Application C++ 파일에 extern "C" jpeg_xxx(..) 형태로 함수를
선언해봤습니다. 이러면 제대로 컴파일이 되더군요. 라이브러리가 제대로 생성되지 않은 것은
아니었고, 옵션에 문제가 있는 거였죠.

더 추적을 해보니, Windows에서는 컴파일하기 위해서 몇가지 옵션이 필요했습니다.

#define _VISUALC_
#define NeedFunctionPrototypes
#define _LIB
#define _JPEGLIB_

저는 이 옵션들을 Visual C++ Project Properties의 Preprocessr Field에 정의해 사용했습니다.
그래서 혹시 이 부분이 문제인가 싶어서, Preprocessor Field에서 해당 옵션을 제거하고,
jpeglib.h 첫부분에 매크로 정의를 추가하였습니다.

#ifndef JPEGLIB_H
#define JPEGLIB_H

#define _VISUALC_
#define NeedFunctionPrototypes
#define _LIB
#define _JPEGLIB_
...

이렇게 하니 제대로 컴파일이 되더군요.
Visual Studio에서 Preprocessor Macro를 처리하는 방식의 문제인지, 아니면
소스코드 구성의 문제인지는 모르겠으나 재미있는 경헙이었습니다.

2. INT32 compile error
jpeglib를 Win32 환경에서 C++ Application과 같이 컴파일하면 INT32라는 이름이
재정의되었다고 불평합니다.

윈도우에서 제공하는 에는 typedef signed int INT32로 정의가 되어있고,
jpeglib에서 사용하는 jmorecfg.h 파일에는 typedef long INT32로 정의되어 있기 때문입니다.
같은 이름을 서로 다른 타입으로 정의했으니 에러가 발생할 수 밖에요.

이 문제는 jmorecfg.h에서 typedef long INT32를 typedef signed int INT32로 변경하면 없어집니다.
윈도우 환경에서는 이렇게 해도 큰 문제가 발생하지 않습니다.

3. 출력 포맷 변경하기.
jpeglib 사용법을 읽어보면, jpeglib 자체에서 이미지 출력 포맷을 지정할 수 있게 되어 있습니다.
정확히는
cInfo.out_color_space = (J_COLOR_SPACE)target_format;
으로 지정한 후, decoding 작업을 수행하면 됩니다.
(void) jpeg_start_decompress(&cInfo)
....

그런데 J_COLOR_SPACE로 지정할 수 있는 기본 출력 포맷은 몇가지 안됩니다.
그 외의 포맷은 사용자가 추가해서 넣어야 하죠.
기본 포맷들은 다음과 같습니다.

typedef enum {
JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */
JCS_RGB, /* red/green/blue */
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */
JCS_YCCK, /* Y/Cb/Cr/K */
} J_COLOR_SPACE;

일반적인 애플리케이션의 경우, JCS_RGB를 가장 많이 사용합니다.
하지만, 실제 Application에서는 RGBA 혹은 BGRA 포맷이 필요한 경우도 많습니다.
알파를 사용하는 다른 이미지(PNG 같은)와 Blending을 하는 경우에 특히 그렇죠.

출력포맷을 추가하는 작업은 간단합니다.
위 J_COLOR_SPACE enum에 원하는 포맷의 이름을 추가하고,
jinit_color_deconverter()@jdcolor.c 함수에 변환 루틴을 추가하면 됩니다.

(그냥 jpeglib에서 JCS_RGB로 디코딩한 후, 그 이미지를 다시 RGBA 혹은 BGRA로
변환해도 됩니다. 하지만 이렇게 하면 두 번 변환 작업을 하는 것이기 때문에 성능도
저하되고, 메모리도 2배 많이 사용해야 합니다. 모바일 환경에서는 이런 조건이
불가능한 경우가 많죠. 다음 설명과 같이 디코딩 과정에서 바로 변환을 하는 것이
제일 좋습니다. )


간단하게 32 bit BGRA 포맷으로 변환하는 경우를 살펴보면 다음과 같습니다.
(Windows에서는 BGRA 포맷을 사용합니다.)

Step 1. JCS_BGRA라는 이름으로 포맷을 J_COLOR_SPACE enum에 추가합니다.

typedef enum {
JCS_UNKNOWN, /* error/unspecified */
JCS_GRAYSCALE, /* monochrome */
JCS_RGB, /* red/green/blue */
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
JCS_CMYK, /* C/M/Y/K */
JCS_YCCK, /* Y/Cb/Cr/K */

JCS_BGRA, /* 새로 추가한 포맷입니다. */
} J_COLOR_SPACE;

Step 2. jinit_color_deconverter()@jdcolor.c 함수에 변환 구문을 추가합니다.

GLOBAL(void)
jinit_color_deconverter( j_decompress_ptr cinfo)
{
...

switch (cinfo->out_color_space)
{
...

// 아래와 같이 JCS_BGRA인 경우의 변환 규칙을 추가합니다.
// 원래 코드에는 아래 case 문이 없습니다.
//
case JCS_BGRA:
// JCS_BGRA 출력은 4바이트로 이루어져 있으므로, BGRA_PIXELSIZE = 4
// 입니다. 이 매크로는 jmorecfg.h에 정의하면 됩니다.
//
cinfo->out_color_components = BGRA_PIXELSIZE;
if (cinfo->jpeg_color_space == JCS_YCbCr)
{
// 이미지 포맷이 JCS_YCbCr이면 ycc_bgra_convert() 함수를 이용하여
// BGRA포맷으로 변환할 것을 설정합니다.
//
cconvert->pub.color_convert = ycc_bgra_convert;
build_ycc_rgb_table(cinfo);
}
else if (cinfo->jpeg_color_space == JCS_GRAYSCALE)
{
// 이미지 포맷이 JCS_GRAYSCALE이면 gray_bgra_convert() 함수를
// 이용하여
BGRA포맷으로 변환할 것을 설정합니다.
//
cconvert->pub.color_convert = gray_bgra_convert;
}
else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
{
// 이미지 포맷이 24 비트 JCS_RGB이면 rgb2bgra_convert() 함수를
// 이용하여
BGRA포맷으로 변환할 것을 설정합니다.
//
cconvert->pub.color_convert = rgb2bgra_convert;
}
else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
break;
....
}

물론 ycc_bgra_convert(), gray_bgra_convert(), rgb2bgra_convert() 함수는
jpeglib에 포함되어 있지 않습니다.
기존 함수들을 참조하여 사용자가 직접 제공해야 합니다.

제가 사용한 함수들의 구현은 다음과 같습니다.
읽어보시면 직관적으로 이해가 될 겁니다.

// YCbCr to BGRA 32 bit format, cyberyanne@gmail.com, 2010/01/28.
//
METHODDEF(void)
ycc_bgra_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
register int y, cb, cr;
register JSAMPROW outptr;
register JSAMPROW inptr0, inptr1, inptr2;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;
/* copy these pointers into registers if possible */
register JSAMPLE * range_limit = cinfo->sample_range_limit;
register int * Crrtab = cconvert->Cr_r_tab;
register int * Cbbtab = cconvert->Cb_b_tab;
register INT32 * Crgtab = cconvert->Cr_g_tab;
register INT32 * Cbgtab = cconvert->Cb_g_tab;
SHIFT_TEMPS

while (--num_rows >= 0) {
inptr0 = input_buf[0][input_row];
inptr1 = input_buf[1][input_row];
inptr2 = input_buf[2][input_row];
input_row++;
outptr = *output_buf++;
for (col = 0; col < num_cols; col++) {
y = GETJSAMPLE(inptr0[col]);
cb = GETJSAMPLE(inptr1[col]);
cr = GETJSAMPLE(inptr2[col]);
/* Range-limiting is essential due to noise introduced by DCT losses. */
outptr[2] = range_limit[y + Crrtab[cr]];
outptr[1] = range_limit[y +
((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
SCALEBITS))];
outptr[0] = range_limit[y + Cbbtab[cb]];
outptr[3] = 0xff; // 출력 이미지의 ALPHA는 255(완전불투명)으로 지정한다.
outptr += BGRA_PIXELSIZE;
}
}
}

// grayscale to RGBA format. by cyberyanne@gmail.com, 2010/01/28.
//
METHODDEF(void)
gray_bgra_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW inptr, outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;

while (--num_rows >= 0) {
inptr = input_buf[0][input_row++];
outptr = *output_buf++;
for (col = 0; col < num_cols; col++)
{
/* We can dispense with GETJSAMPLE() here */
outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
outptr[3] = 0xff; // 출력 이미지의 알파값은 완전불투명(255)로 지정한다.
outptr += RGBA_PIXELSIZE;
}
}
}

// RGB to BGRA format. by cyberyanne@gmail.com, 2010/01/28.
//
METHODDEF(void)
rgb2bgra_convert (j_decompress_ptr cinfo,
JSAMPIMAGE input_buf, JDIMENSION input_row,
JSAMPARRAY output_buf, int num_rows)
{
register JSAMPROW inptr, outptr;
register JDIMENSION col;
JDIMENSION num_cols = cinfo->output_width;

while (--num_rows >= 0)
{
inptr = input_buf[0][input_row++];
outptr = *output_buf++;
for (col = 0; col < num_cols; col++)
{
/* We can dispense with GETJSAMPLE() here */
outptr[2] = inptr[RGB_RED];
outptr[1] = inptr[RGB_GREEN];
outptr[0] = inptr[RGB_BLUE];
outptr[3] = 0xff; // 출력 이미지의 알파값은 완전불투명(255)로 지정한다.

inptr += RGB_PIXELSIZE;
outptr += BGRA_PIXELSIZE;
}
}
}

jpeglib를 사용하는데 조금이나마 도움이 되었으면 좋겠습니다.
끝.

Thursday, January 11, 2007

 

AJAX 공부

1. Overview
AJAX는 Asynchronous JavaScript and XML의 약자이다.
AJAX라는 것은 새로운 Programming 언어나 기술이 아니고, 기존의 기술들(JavaScript, HTML, XML, CSS)을 잘 조합하여 동적인 Web Application을 개발하는 방법론을 지칭한다.

AJAX의 가장 큰 특징은 서버와의 통신 방법이다. 기존의 방식은 Browser에서 Web Server에 요청을 보내면, Web Page(HTML 문서) 전체가 Browser로 전송되었다. 따라서 매번 요청할 때마다 화면 전체가 갱신되어야 하는 불편이 있었다. AJAX에서는 전체 Web Page(HTML 문서)가 아닌 필요한 정보만 XML 형식으로 Server에서 받아오고, 그것을 바탕으로 현재 Web Page에서 필요한 부분만 갱신한다. 결과적으로 사용자는 빠르고, Interactive한 Web 화면을 접하게 되는 것이다. 이러한 동적인 특성은 JavaScript에 통해 수행된다. HTML 문서에 포함된 JavaScript 코드를 이용하여 Server와의 통신, XML 데이터의 해석, 현재 Web Page의 갱신을 제어하는 것이다.

AJAX의 핵심인 JavaScript는 Browser에서 수행되기 때문에, AJAX는 Browser Technology로 분류된다.

AJAX는 Open Standard에 기반하고 있다. JavaScript, XML, HTML, CSS는 모두 Open Standard이다. 따라서 이러한 표준을 지원하는 Web Server/Browser라면 어떤 것이든 AJAX 코드를 수행할 수 있다.

Wednesday, December 27, 2006

 

내가 알고 있는 것들을 어떻게 이용할까?

올해 내가 공부해서 알게 된 것들..

XML, XML Namespace, Xerces Parser (SAX Model, DOM Model)
RDF(Resource Description Framework), RDF Schema,
UML(Unified Modeling Language),
RSS(RDF Site Summary or Really Simple Syndication),
Web Service Standards
SOAP-Simple Object Access Protocol
WSDL-Web Service Description Language
UDDI-Universal Description, Discovery and Integration
and so on

이것들을 조합해서 어떤 작품들을 만들어 낼 수 있을까 고민을 해봐야 겠다.

XML은 데이터를 표현하기 위한 표준 방법이다. 프로그램을 작성할 때 File 입/출력을 XML 형식으로 하면 Interoperability(호환성)을 확보할 수 있다.

RDF는 원래 Web Resource에 대한 Metadata를 기술하기 위한 것이다. XML 형식으로 표현되며, (Resource, Property, Value)의 Triple이 기본 구성요소이다. RDF는 굳이 Web Resource가 아니더라도 활용할 수 있다. 예를 들어, 내가 작성하는 프로그램에 대한 Metadata를 RDF로 표현할 수도 있다. 그것이 어떻게 활용될지는 잘 모르겠지만 (프로그램도 하나의 Web Resource로 생각할 수도 있겠다. Internet에 공개될 것이므로)

Web Service API는 프로그램이 Web과 소통하는 통로를 열어준다. Web 업체들이 제공하는 Open API를 사용하여 프로그램이 Standalone으로 동작할 뿐만 아니라 Internet과 연동하여 다양한 추가 기능을 제공할 수도 있다. 프로그램이 서버로 동작하여 Open API를 외부에 제공할 수도 있을 것이다. 아니면 프로그램 자체를 Web Service API를 이용하여 작성하는 것도 생각할 수 있다. PC에 Web Service 동작환경(주로 Apache-Tomcat-Axis 조합)을 설치하고, 프로그램의 기능들을 Web Service API로 구현한다. 최종 프로그램은 이러한 Web Service API를 조합하여 사용자 Interface를 제공하게 된다. 마지막 경우에서는 개인 PC에서 제공하는 API와 외부 Internet에서 제공하는 API가 동일한 것으로 취급된다. 즉, 프로그래밍의 영역이 Web 전체가 되는 것이다

 

UML Diagrams

1. use case diagram : To model the main functionality of a system and the role of user.

2. class/object diagram : To model static structure of a system.

3. statechart : to model object(system) states and their transitions.

4. activity diagram : to model dynamic behaviour of the model.

5. sequency diagram : to model message passing between entities.

6. collaboration diagrams : to model interaction between objects over time.

7. component diagram : to model concrete software unit and their interrelations.

8. deployment diagram : to model the arrangement of run-time components on run-time resources.

9. package concept : decompose a complex model into simpler sub-models.
(divide and conquer)

 

Principle: Separation of Concerns

** 프로그램을 설계할 때 여러가지 요소들을 동시에 고려하는 것은 어렵다. 따라서 각각의 요소들을 개별적으로 고려하고, 나중에 이러한 요소들을 합치는 것이 효과적인 방법이다. 예를 들어, 어떤 프로그램을 개발할 때 프로그램의 정확성 (correctness), 효율성 (efficiency), 필요성 (necessity)를 한꺼번에 생각한다고 해보자. 보통 사람들은 이렇게 다양한 관점들을 동시에 고려하지 못한다. The separation of concerns 원리는 이러한 관점들을 따로 고민하라는 것이다. 즉, 먼저 필요성을 고민하고, 그 다음 정확성을 그리고 나서 효율성을 고민하라는 것이다.

** Divide and conquer 와 비슷한 뜻인듯

** Software Modeling에서 매우 중요하게 생각하는 원리중의 하나이다.

Origin : From Wikipedia,

The term separation of concerns was probably coined by Edsger W. Dijkstra in his paper On the role of scientific thought.

Let me try to explain to you, what to my taste is characteristic for all intelligent thinking. It is, that one is willing to study in depth an aspect of one's subject matter in isolation for the sake of its own consistency, all the time knowing that one is occupying oneself only with one of the aspects. We know that a program must be correct and we can study it from that viewpoint only; we also know that it should be efficient and we can study its efficiency on another day, so to speak. In another mood we may ask ourselves whether, and if so: why, the program is desirable. But nothing is gained --on the contrary!-- by tackling these various aspects simultaneously. It is what I sometimes have called "the separation of concerns", which, even if not perfectly possible, is yet the only available technique for effective ordering of one's thoughts, that I know of. This is what I mean by "focussing one's attention upon some aspect": it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect's point of view, the other is irrelevant. It is being one- and multiple-track minded simultaneously.


This page is powered by Blogger. Isn't yours?