Delphi画像処理--RGBとHSV変換

5564 ワード

ヒントを読む:
Delphi画像処理」シリーズは効率に重点を置き、一般コードはPASCAL、コアコードはBASMを採用している.
C++画像処理」シリーズはコードがはっきりしていて、可読性が主で、すべてC++コードを使用しています.
できるだけ両者の内容を一致させ、互いに対照することができる.
本明細書のコードは、文書「Delphi画像処理--データ型と共通プロセス」のImageDataを含む必要がある.pasユニット.
 
const

  _fc0: Single    = 0.0;

  _fc1: Single    = 1.0;

  _fc6: Single    = 6.0;

  _fc60: Single   = 60.0;

  _fc255: Single  = 255.0;

  _fc360: Single  = 360.0;



procedure ColorToHSV(var H, S, V: Single; Color: TARGB);

asm

    push      eax

    push      edx

    push      ecx

    movzx     ecx, Color.TARGBQuad.Blue

    movzx     edx, Color.TARGBQuad.Green

    movzx     eax, Color.TARGBQuad.Red

    cmp       ecx, edx        // ecx = rgbMax

    jge       @@1             // edx = rgbMin

    xchg      ecx, edx

@@1:

    cmp       ecx, eax

    jge       @@2

    xchg      ecx, eax

@@2:

    cmp       edx, eax

    cmova     edx, eax

    cvtsi2ss  xmm0, ecx

    movaps    xmm1, xmm0

    divss     xmm0, _fc255

    pop       eax

    movss     [eax], xmm0     // *V = rgbMax / 255

    mov       eax, ecx

    sub       ecx, edx        // delta = rgbMax - rgbmin

    jnz       @@3

    pop       edx             // if (delta == 0)

    pop       eax             // {

    mov       [eax], ecx      //   *H = *S = 0

    mov       [edx], ecx      //   return

    jmp       @@Exit          // }

@@3:

    cvtsi2ss  xmm0, ecx

    movaps    xmm2, xmm0

    divss     xmm0, xmm1

    pop       edx

    movss     [edx], xmm0     // *S = delta / rgbMax

    cmp       al, Color.TARGBQuad.Red

    jne       @@5

    movzx     eax, Color.TARGBQuad.Green

    movzx     edx, Color.TARGBQuad.Blue

    xor       ecx, ecx        // if (R == rgbMax) eax = G - B; add = 0

    jmp       @@7

@@5:

    cmp       al, Color.TARGBQuad.Green

    jne       @@6

    movzx     eax, Color.TARGBQuad.Blue

    movzx     edx, Color.TARGBQuad.Red

    mov       ecx, 120         // if (G == rgbMax) eax = B - R; add = 120

    jmp       @@7

@@6:

    movzx     eax, Color.TARGBQuad.Red

    movzx     edx, Color.TARGBQuad.Green

    mov       ecx, 240         // if (B == rgbMax) eax = R - G; add = 240

@@7:

    sub       eax, edx

    cvtsi2ss  xmm0, eax

    cvtsi2ss  xmm1, ecx

    mulss     xmm0, _fc60

    divss     xmm0, xmm2

    addss     xmm0, xmm1      // H = eax * 60 / delta + add

    comiss    xmm0, _fc0

    jae       @@8

    addss     xmm0, _fc360

@@8:

    pop       eax

    movss     [eax], xmm0

@@Exit:

end;



function HSVToColor(H, S, V: Single): TARGB;

asm

    movss     xmm1, H

    comiss    xmm1, _fc0

    jae       @@1

    addss     xmm1, _fc360

    jmp       @@2

@@1:

    comiss    xmm1, _fc360

    jb        @@2

    subss     xmm1, _fc360

@@2:

    divss     xmm1, _fc60

    cvtss2si  edx, xmm1       // index = Round(H)

    cvtsi2ss  xmm2, edx

    subss     xmm1, xmm2      // extra = H - index

    comiss    xmm1, _fc0      // if (extra < 0) //   index    

    jae       @@3             // {

    dec       edx             //   index --

    addss     xmm1, _fc1      //   extra ++

@@3:                          // }

    test      edx, 1

    jnz       @@4

    movaps    xmm2, xmm1

    movss     xmm1, _fc1

    subss     xmm1, xmm2      // if (index & 1 == 0) extra = 1 - extra

@@4:

    movss     xmm0, V

    movss     xmm2, S

    minss     xmm0, _fc1

    minss     xmm2, _fc1

    maxss     xmm0, _fc0

    maxss     xmm2, _fc0

    mulss     xmm0, _fc255

    mulss     xmm2, xmm0      // V * S

    mulss     xmm1, xmm2      // V * S * extra

    pslldq    xmm1, 4

    movss     xmm1, xmm2      // xmm1 = 0 0 V*S*E V*S

    pshufd    xmm0, xmm0, 0   // xmm0 = V V V V

    subps     xmm0, xmm1      // xmm0 -= mm1 = V V T P

    jmp       @@jmpTable[edx*4].Pointer

@@jmpTable:   dd  offset  @@H60

              dd  offset  @@H120

              dd  offset  @@H180

              dd  offset  @@H240

              dd  offset  @@H300

              dd  offset  @@H360

@@H360:                       // 300 - 359 (V, P, T)

    pshufd    xmm0, xmm0, 11100001b

    jmp       @@H60

@@H300:                       // 240 - 299 (T, P, V)

    pshufd    xmm0, xmm0, 11010010b

    jmp       @@H60

@@H240:                       // 180 - 239 (P, T, V)

    pshufd    xmm0, xmm0, 11000110b

    jmp       @@H60

@@H180:                       // 120 - 179 (P, V, T)

    pshufd    xmm0, xmm0, 11001001b

    jmp       @@H60

@@H120:                       // 60 - 119  (T, V, P)

    pshufd    xmm0, xmm0, 11011000b

@@H60:                        // 0 - 59    (V, T, P)

    cvtps2dq  xmm0, xmm0

    packssdw  xmm0, xmm0

    packuswb  xmm0, xmm0

    movd      eax, xmm0

    or        eax, 0ff000000h

end;

 
「Delphi画像処理」シリーズはGDI+ユニットを使用してアドレスをダウンロードし、説明は「GDI+for VCLベース--GDI+とVCL」を参照してください.
レベルが限られているため、間違いは避けられないので、指摘と指導を歓迎します.メールアドレス:[email protected]
ここでは『Delphi画像処理--記事インデックス』にアクセスできます.