Database -> Pre & Post Script -> Model-Level

Code 탭 -> New 버튼클릭 -> 스크립트 입력

:: Oracle
%ForEachTable() {
    COMMENT ON TABLE %TableName IS '%EntityName';

    %ForEachColumn() {
    COMMENT ON COLUMN %TableName.%ColName IS '%AttName';
    }
}

:: MySQL
%ForEachTable() {
    ALTER TABLE %TableName COMMENT = '%EntityName';

    %ForEachColumn() {
    ALTER TABLE %TableName CHANGE COLUMN %ColName %ColName %AttDatatype %AttNullOption COMMENT '%AttName';
    }
}

Forward Engineer Schema Generation -> Option 탭 -> Schema -> Post-Script 선택하여 체크

출처 : http://koreantramp.tistory.com/198

ITU-R BT.601 정의에 따르면

Y 변환식은
Y = 0.299R + 0.587G + 0.114B
계수값들이 눈에 거슬린다. 왜 저런 값이 나왔을까?
우리 눈은 녹색>빨강>파랑 순으로 밝다고 느낀다. Y 값의 목적은 밝기를 나타내는 것이기 때문에
계수 선정은 이 사실에 기초해야 한다. G값 성분비율을 크게 하고 그 다음에 빨강, 파랑.
이렇게 얻은 값을 gray로 나타내면 흑백이 된다.
나도 한번 새로운 계수를 만들어 볼까?
계수의 합이 1이 되게하고 계수값을 적당히 조정해서 gray로 나타냈을때
앞의 계수보다 보기 좋은 흑백이 나타난다면 그 계수를 사용하면 될것이다.
표준으로 저 값을 쓴다고 하니 써야지 뭐...물론 테스트 된 최적값이겠지...
R,G,B 값의 범위를 [0,1] 했을때 Y의 범위는 [0,1]이다.

 

U 변환식은
U = B - Y
  = (1-0.114)B - 0.299R - 0.587G
  = 0.886B - 0.299R - 0.587G

R,G,B 값의 범위를 [0,1] 했을때 U의 범위는 [-0.886, +0.886] 이다.
즉 B 계수 값의 +/-이다.

 

V 변환식은
V = R - Y
  = (1-0.299)R - 0.587G - 0.114B
  = 0.701R - 0.587G - 0.114B      

R,G,B 값의 범위를 [0,1] 했을때 V의 범위는 [-0.701, +0.701] 이다.
즉 R 계수 값의 +/-이다.


정리하자면 R,G,B의 범위가 [0,1]일 경우

[식 1]
Y = 0.299R + 0.587G + 0.114B   Y의 범위는 [0,1]
U = 0.886B - 0.299R - 0.587G   U의 범위는 [-0.886, +0.886]
V = 0.701R - 0.587G - 0.114B   V의 범위는 [-0.701, +0.701]

 

 

////////////////////////////////////////////////////////////////////////////////
위 식의 문제점은 값의 범위가 일정하지 않다는 점이다. 값의 범위를 스케일링 해보자.

U, V의 범위를 [-0.5, +0.5] 로 스케일링 해보자.
U, V 문자를 쓰는 대신 Pb, Pr로 쓰자. (TV 뒤를 보면 이런문자를 보았나요^^)
U의 범위는 B의 계수 값이 결정하므로 각 계수들을 0.5/0.886 로 곱한다.
Pb = 0.5B -0.169R -0.331G
V의 범위는 R의 계수 값이 결정하므로 각 계수들을 0.5/0.701 로 곱한다.
Pr = 0.5R -0.419G -0.081B


정리하자면 아래식은 R,G,B의 범위가 [0,1]로 스케일링된 식이다.

[식 2]
Y  =   0.299R + 0.587G + 0.114B   Y의 범위는   [0,1]
Pb = -0.169R - 0.331G + 0.500B   Pb의 범위는 [-0.5, +0.5]
Pr =   0.500R - 0.419G - 0.081B   Pr의 범위는  [-0.5, +0.5]

 

 

////////////////////////////////////////////////////////////////////////////////
Y,Pb,Pr의 범위 [16, 240]로 스케일링 해보자. 변환된 Pb, Pr 대신 Cb, Cr로 쓰자.

Y,Pb,Pr의 범위를 적용하면 쉽게 아래식을 유도한다.

 

Y  = 16 + 219*Y
Cb = 128 + 224*Pb
Cr = 128 + 224*Pr

 

이식이 맞는지 조사해보자. 

예를들어 하나만 해보면 Pb의 범위가 [-0.5, +0.5]이므로 Pb의 최소값이 -0.5이면 Cb값은 16이 된다.

R,G,B의 범위를 [0,1] 대신 [0,255]로 하려면 R 대신 R/255, G 대신 G/255, B 대신 B/255로 쓰면 된다.

 

정리하자면 아래식은 R,G,B의 범위는 [0,255],  Y,Cb,Cr의 범위는 [16, 240] 로 스케일링 된 식이다.

[식 3]

Y  = 16 + 219*Y/255      =     0.257R + 0.504G + 0.098B + 16
Cb = 128 + 224*Pb/255  =   -0.148R - 0.291G + 0.439B + 128
Cr = 128 + 224*Pr/255   =     0.439R - 0.368G - 0.071B + 128

 

역변환 식은
R = 1.164(Y-16)                        + 1.596(Cr-128)
G = 1.164(Y-16) - 0.391(Cb-128) - 0.813(Cr-128)
B = 1.164(Y-16) + 2.018(Cb-128)

이 식은 유명한(??) 외국책에 나온다. MSDN에서도 이 식을 사용하는데 Cb,Cr 문자를 사용안하고

Y,U,V 문자를 사용한다. 그래서 헷갈리는것 같다.

 

 

 

////////////////////////////////////////////////////////////////////////////////
Y, Pb, Pr의 범위를 [0.255]로 할수 없을까? 당연히 할수 있다. 변환된 Pb, Pr 대신 U, V로 쓰자.

Y,Pb,Pr 식을 이용하여 변환하면 된다.

 

아래식은 R,G,B 범위를 [0,255]로, Y,U,V 범위 [0,255]로 스케일링 된 식이다.

[식 4]

Y =   0.299R + 0.587G + 0.114B           Y의 범위는 [0, +255]
U = -0.169R - 0.331G + 0.500B + 128    U의 범위는 [0, +255]
V =   0.500R - 0.419G - 0.081B + 128   V의 범위는 [0, +255]

 

역변환 식은
R = Y                        + 1.4075(V-128)
G = Y - 0.3455(U-128) - 0.7169(V-128)
B = Y + 1.7790(U-128)

 

결국 4가지의 식이 존재하는것은 모두 스케일링이 달라서 이다. 

 

참고로 ITU-R BT.709 정의

Y = 0.2125R + 0.7154G + 0.0721B  이식은 HD tv에서 쓴다고 한다. G값 비율을 높혔네...

[출처] YUV, YCbCr (1)|작성자 늘푸른숲

 

 

 

 

변환 공식중 다음 공식에서 float 연산을 빼서 계산을 빠르게 만들어 보자

 

Y   =     0.257R + 0.504G + 0.098B + 16
Cb  =    -0.148R - 0.291G + 0.439B + 128
Cr  =     0.439R - 0.368G - 0.071B + 128

 

윗식에서 반올림을 할수 있게 0.5를 더하자.


Y   =     0.257R + 0.504G + 0.098B + 0.5 + 16
Cb  =    -0.148R - 0.291G + 0.439B + 0.5 + 128
Cr  =     0.439R - 0.368G - 0.071B + 0.5 + 128


윗식에서 float 연산을 없애기 위해서 256을 곱하고 256으로 나누자

Y   =    (256*( 0.257R + 0.504G + 0.098B + 0.5 ))/256 + 16
Cb  =    (256*(-0.148R - 0.291G + 0.439B + 0.5 ))/256 + 128
Cr  =    (256*( 0.439R - 0.368G - 0.071B + 0.5 ))/256 + 128

 

 

256 나누기는 shift 연산으로 대치한다.

Y   =    ( 256*( 0.257R + 0.504G + 0.098B + 0.5 ) ) >> 8 + 16
Cb  =    ( 256*(-0.148R - 0.291G + 0.439B + 0.5 ) ) >> 8 + 128
Cr  =    ( 256*( 0.439R - 0.368G - 0.071B + 0.5 ) ) >> 8 + 128

 

 

연산을 하고 정리하면

Y   =    ( (  66*R + 129*G +  25*B + 128 )  >> 8  ) + 16
Cb  =    ( ( -38*R -  74*G + 112*B + 128 )  >> 8  )  + 128
Cr  =    ( ( 112*R -  94*G -  18*B + 128 )  >> 8  ) + 128

 

아래의 역변환 식도 변환해보자.

R = 1.164(Y-16)                        + 1.596(Cr-128)
G = 1.164(Y-16) - 0.391(Cb-128) - 0.813(Cr-128)
B = 1.164(Y-16) + 2.018(Cb-128)

 

역변환 식도 정리하면

R =  ( 298*(Y-16)                + 409*(Cr-128) + 128 ) >> 8
G =  ( 298*(Y-16) - 100*(Cb-128) - 208*(Cr-128) + 128 ) >> 8
B =  ( 298*(Y-16) + 516*(Cb-128)                + 128 ) >> 8

 

R, G, B 의 값이 [0,255] 범위에 오도록 클립한다.

#define CLIP(x) ( ((x) < 0 ) ? 0 : (((x) > 255 ) ? 255 : (x) ))

 

 

R =  CLIP( ( 298*(Y-16)                       + 409*(Cr-128) + 128 ) >> 8 )
G =  CLIP( ( 298*(Y-16) - 100*(Cb-128) - 208*(Cr-128) + 128 ) >> 8 )
B =  CLIP( ( 298*(Y-16) + 516*(Cb-128)                       + 128 ) >> 8 )


위 공식은 MSDN에 나온다.

 

더 빠르게 계산하는 방법을 생각해 보자. 방법은 lookup 테이블을 이용.

 

//전역변수에 미리 값을 계산하자.

int table_298[256];
int table_409[256];
int table_100[256];
int table_208[256];
int table_516[256];

// 클립자체도 테이블을 만들자.
unsigned char Temp_Clip[1024];
unsigned char * Clip;

 

 

// 프로그램 시작 위치에 다음 코드를 넣자

   int i;
   Clip = Temp_Clip + 384;

   for( i = -384 ; i < 640 ; i++ )
    Clip[i] = ( i<0 ) ? 0 : ( (i>255) ? 255 : i );

 

   for( i = 0 ; i < 256 ; i++ )
   {
    table_298[i] = 298*(i-16) + 128;
    table_409[i] = 409*(i-128);
    table_100[i] = 100*(i-128);
    table_208[i] = 208*(i-128);
    table_516[i] = 516*(i-128);
   }

 

 

 

// 만들어지 테이블값을 참조만 하여 값을 얻는다.

   R =  Clip[ ( table_298[Y]                      + table_409[Cr] ) >> 8 ] ;
   G =  Clip[ ( table_298[Y] - table_100[Cb] - table_208[Cr] ) >> 8 ] ;
   B =  Clip[ ( table_298[Y] + table_516[Cb]                       ) >> 8 ] ;

lookup 테이블을 이용하니까 10ms->5ms 로 반절정도로 계산시간이 줄었다.

 

또 한가지. 정밀도를 높이기 위해서 8bit shift 연산 대신 16bit shift 연산을 생각해 볼수 있다.  

계수값이 달라지겠지만 충분히 유도가능하다.

[출처] YUV RGB 변환 (2)|작성자 늘푸른숲

 

 

 

 

 

RGB의 범위가 [0,255]
Y  =   0.299R + 0.587G + 0.114B   Y의 범위는   [0,255]
Cb =  -0.169R - 0.331G + 0.500B   Cb의 범위는 [-127.5, +127.5]//-128 ~ 127 로 조율해야 한다.
Cr =   0.500R - 0.419G - 0.081B   Cr의 범위는  [-127.5, +127.5]//-128 ~ 127 로 조율해야 한다.

빠른 변환을 위해 LUT를 쓰자.

반올림/반내림을 위해 ±0.5를 해주고 우변을 256으로 곱했다가 나눈다.

Y  =   (0.299R + 0.587G + 0.114B + 0.5) * 256 / 256
Cb =  (-0.169R - 0.331G + 0.500B - 0.5) * 256 / 256
Cr =   (0.500R - 0.419G - 0.081B - 0.5) * 256 / 256

나누기 256은 shift연산으로 바꾸고 식을 정리하면

Y  =   (77R + 150G + 29B + 128) >> 8
Cb =  (-43R - 85G + 128B - 128) >> 8
Cr =   (128R - 107G - 21B - 128) >> 8

//전역변수에 미리 값을 계산하자.
int table_077[256];
int table_150[256];
int table_029[256];
int table_043[256];
int table_128[256];
int table_085[256];
int table_107[256];
int table_021[256];

for( i = 0 ; i < 256 ; i++ )
{
    table_077[i] = 77 * i;
    table_150[i] = 150 * i;
    table_029[i] = 29 * i;
    table_043[i] = 43 * i ;
    table_128[i] = 128 * i;
    table_085[i] = 85 * i;
    table_107[i] = 107 * i;
    table_021[i] = 21 * i;
}

테이블만 참조해서 계산하면 된다.
Y  =   (table_077[R] + table_150[G] + table_029[B] + 128) >> 8
Cb =  (-table_043[R] - table_085[G] + table_128[B] - 128) >> 8
Cr =   (table_128[R] - table_107[G] - table_021[B] - 128) >> 8

[출처] YUV, YCbCr|작성자 늘푸른숲



ATL에서 Composite Control 등을 기반으로 콘트롤을 추가하여 사용하고자 할 때,
아래와 같이 사용하면 MFC 콘트롤을 다루는 것과 같은 방식으로 이용할 수 있다.


:: .h 파일
#include "atlcontrols.h"

using namespace ATLControls;

class ATL_NO_VTABLE CTestControl :
{
    ...
    // 멤버변수 추가
    // using namespace 를 선언하고 사용함에도 ambiguous 오류인해 다시 스코프를 지정
    CContainedWindowT  m_ctrlListFiles;
    CContainedWindowT  m_ctrlBtDelete;
    CContainedWindowT  m_ctrlBtUpload;
    CContainedWindowT  m_ctrlPreview;
    ...
}


:: .cpp 파일
void CTestControl::InitControls()
{
    // 콘트롤 변수에 오브젝트 바인딩
    m_ctrlListFiles.Attach(GetDlgItem(IDC_LIST_FILES));
    m_ctrlBtDelete.Attach(GetDlgItem(IDC_BUTTON_DELETE));
    m_ctrlBtUpload.Attach(GetDlgItem(IDC_BUTTON_UPLOAD));
    m_ctrlPreview.Attach(GetDlgItem(IDC_PREVIEW));
}

atlcontrols.h 는 Visual Studio 2008이 설치된 디렉토리에 샘플소스안에 포함되어 있다.

atlcontrols.zip


// .h 파일
class ATL_NO_VTABLE CTestControl :
...
public IDropTarget // 인터페이스 추가
...
{
    ...
    // 오버라이딩
    STDMETHOD(DragEnter)(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect);
    STDMETHOD(DragOver)(DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect);
    STDMETHOD(DragLeave)(void);
    STDMETHOD(Drop)(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect);
    ...
}

// .cpp 파일
// 초기화 부분에 추가
::RegisterDragDrop(m_hWnd, (IDropTarget*)this);

// 함수구현
HRESULT CTestControl ::DragEnter(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
    return S_OK;
}

HRESULT CTestControl ::DragOver(DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
    return S_OK;
}

HRESULT CTestControl ::DragLeave(void)
{
    return S_OK;
}

HRESULT CTestControl ::Drop(LPDATAOBJECT pDataObject, DWORD dwKeyState, POINTL pt, LPDWORD pdwEffect)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());  // init MFC

    COleDataObject DataObj;
    HGLOBAL        hGlobal;
    HDROP          hDropInfo;

    DataObj.Attach(pDataObject, FALSE);

    // Data Object 에서 리스트를 읽어온다.
    // HDROP 구조체에 저장되므로, HDROP 핸들을 얻어와 Drag&Drop API를 사용하면 된다.
    hGlobal = DataObj.GetGlobalData (CF_HDROP);
    if ( NULL != hGlobal )
    {
        hDropInfo = (HDROP) GlobalLock (hGlobal);

        UINT uDropCnt = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);    // 드롭된 파일의 갯수
        char buffer[256];  // Drag&Drop된 파일,폴더의 절대경로 저장

        for(UINT i=0; i<uDropCnt; i++)
        {
            // 파일의 경로 얻어옴
            DragQueryFile(hDropInfo, i, buffer, 255);
            // 파일경로 확인
            ::MessageBox(NULL, buffer, _T("Filename"), MB_OK);
        }
        GlobalUnlock (hGlobal);
    }

    DataObj.Detach();
   
    return S_OK;
}

HTML 파일에서 다음과 같이 ActiveX콘트롤로 인수를 넘겨줄때
<OBJECT ..............>
<PARAM NAME="COUNT" VALUE="5">
</OBJECT>

// .h 파일
class ATL_NO_VTABLE CTestControl :
...
public IPersistPropertyBagImpl<CTestControl> // 인터페이스 상속
...
{
    ...
    STDMETHOD(Load)(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog); // 오버라이딩
}

// .cpp 파일
// 함수 구현
STDMETHODIMP CTestControl ::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
{
    CComVariant vtVal ;

    // COUNT 값
    HRESULT hr = pPropBag->Read(L"COUNT", &vtVal, pErrorLog) ;
    if (SUCCEEDED(hr) && VT_BSTR == vtVal.vt)//형검사
    {
        USES_CONVERSION;
        char* pszVal = OLE2A(vtVal.bstrVal);
        put_UploadFileCount(atoi(pszVal)) ;  //Param값 넘기기
    }
    return S_OK ;
}

출처 : 데브피아
retString = (std::tstring)((CString)recvBuf);
// WM_ERASEBKGND 메세지 추가
BOOL CMyDialog::OnEraseBkgnd(CDC* pDC)
{
    CRect rect;
    GetClientRect(&rect);
    CBrush myBrush(RGB(255, 255, 255));    // dialog background color
    CBrush *pOld = pDC->SelectObject(&myBrush);
    BOOL bRes  = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
    pDC->SelectObject(pOld);    // restore old brush
    return bRes;                // CDialog::OnEraseBkgnd(pDC);
}
void DrawBitmap(HDC hdc, int x, int y, HBITMAP hBitmap)
{
    HDC hMemDC;
    HBITMAP hOldBitmap;
    int nWidth, nHeight;
    BITMAP bitmapData;

    hMemDC = CreateCompatibleDC(hdc);
    hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);

    GetObject(hBitmap, sizeof(BITMAP), &bitmapData);
    nWidth = bitmapData.bmWidth;
    nHeight = bitmapData.bmHeight;

    SetStretchBltMode(hdc, HALFTONE);
    StretchBlt(hdc, 0, 0, 160, 120, hMemDC, 0, 0, nWidth, nHeight, SRCCOPY);
    //BitBlt(hdc, x, y, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY);

    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);
}
// 스타일 변경
m_ctrlList.SetExtendedStyle(LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

// 체크박스 영역 클릭 여부
if ( pNMItemActivate->ptAction.x >= 5 &&pNMItemActivate->ptAction.x <= 20 )
{
    ....
}

// 체크박스 체크 여부
UINT uState = m_ctrlListFiles.GetItemState(i-1, LVIS_STATEIMAGEMASK);
if(BOOL((int)(uState)-1)>>12)
{
    // 체크가 되어 있을 경우
    ....
}
else
{
    // 체크가 안되어 있을 경우
    ....
}

// 아이템 선택된 상태로 변경
m_ctrlList.SetItemState(nIndex/*아이템 Index*/, LVIS_SELECTED, LVIS_SELECTED);
#!/bin/bash

sudo apt-get install build-essential wget
sudo addgroup --system qtss
sudo adduser --system --no-create-home --ingroup qtss qtss

wget http://static.macosforge.org/dss/downloads/DarwinStreamingSrvr6.0.3-Source.tar
tar -xvf DarwinStreamingSrvr6.0.3-Source.tar
mv DarwinStreamingSrvr6.0.3-Source DarwinStreamingSrvr6.0.3-Source.orig
wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-6.0.3.patch
patch -p0 < dss-6.0.3.patch
mv DarwinStreamingSrvr6.0.3-Source.orig DarwinStreamingSrvr6.0.3-Source
wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/dss-hh-20080728-1.patch
patch -p0 < dss-hh-20080728-1.patch
#need to answer n then y
cd DarwinStreamingSrvr6.0.3-Source
mv Install Install.orig
wget http://dss.macosforge.org/trac/raw-attachment/ticket/6/Install
chmod +x Install
./Buildit
sudo ./Install