; ; Merged upsampling/color conversion (32-bit SSE2) ; ; Copyright 2009, 2012 Pierre Ossman <ossman@cendio.se> for Cendio AB ; Copyright (C) 2012, 2016, 2024-2025, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; ; This file should be assembled with NASM (Netwide Assembler) or Yasm.
%include"jcolsamp.inc"
; -------------------------------------------------------------------------- ; ; Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. ; ; GLOBAL(void) ; jsimd_h2v1_merged_upsample_sse2(JDIMENSION output_width, ; JSAMPIMAGE input_buf, ; JDIMENSION in_row_group_ctr, ; JSAMPARRAY output_buf)
; NOTE: The values of RGB_RED, RGB_GREEN, and RGB_BLUE determine the ; mapping of components A, B, and C to red, green, and blue. ; ; xmmA = (A0 A2 A4 A6 A8 Aa Ac Ae) = AE ; xmmB = (A1 A3 A5 A7 A9 Ab Ad Af) = AO ; xmmC = (B0 B2 B4 B6 B8 Ba Bc Be) = BE ; xmmD = (B1 B3 B5 B7 B9 Bb Bd Bf) = BO ; xmmE = (C0 C2 C4 C6 C8 Ca Cc Ce) = CE ; xmmF = (C1 C3 C5 C7 C9 Cb Cd Cf) = CO ; xmmG = (** ** ** ** ** ** ** **) ; xmmH = (** ** ** ** ** ** ** **)
punpcklbw xmmA, xmmC ; xmmA = (A0 B0 A2 B2 A4 B4 A6 B6 A8 B8 Aa Ba Ac Bc Ae Be)
punpcklbw xmmE, xmmB ; xmmE = (C0 A1 C2 A3 C4 A5 C6 A7 C8 A9 Ca Ab Cc Ad Ce Af)
punpcklbw xmmD, xmmF ; xmmD = (B1 C1 B3 C3 B5 C5 B7 C7 B9 C9 Bb Cb Bd Cd Bf Cf)
movdqa xmmG, xmmA
movdqa xmmH, xmmA
punpcklwd xmmA, xmmE ; xmmA = (A0 B0 C0 A1 A2 B2 C2 A3 A4 B4 C4 A5 A6 B6 C6 A7)
punpckhwd xmmG, xmmE ; xmmG = (A8 B8 C8 A9 Aa Ba Ca Ab Ac Bc Cc Ad Ae Be Ce Af)
psrldq xmmH, 2 ; xmmH = (A2 B2 A4 B4 A6 B6 A8 B8 Aa Ba Ac Bc Ae Be -- --)
psrldq xmmE, 2 ; xmmE = (C2 A3 C4 A5 C6 A7 C8 A9 Ca Ab Cc Ad Ce Af -- --)
movdqa xmmC, xmmD
movdqa xmmB, xmmD
punpcklwd xmmD, xmmH ; xmmD = (B1 C1 A2 B2 B3 C3 A4 B4 B5 C5 A6 B6 B7 C7 A8 B8)
punpckhwd xmmC, xmmH ; xmmC = (B9 C9 Aa Ba Bb Cb Ac Bc Bd Cd Ae Be Bf Cf -- --)
pshufd xmmH, xmmG, 0x4E ; xmmH = (Ac Bc Cc Ad Ae Be Ce Af A8 B8 C8 A9 Aa Ba Ca Ab)
movdqa xmmB, xmmF
punpckldq xmmG, xmmC ; xmmG = (A8 B8 C8 A9 B9 C9 Aa Ba Aa Ba Ca Ab Bb Cb Ac Bc)
punpckldq xmmF, xmmH ; xmmF = (Ca Ab Bb Cb Ac Bc Cc Ad Cc Ad Bd Cd Ae Be Ce Af)
punpckhdq xmmC, xmmB ; xmmC = (Bd Cd Ae Be Ce Af Bf Cf Bf Cf -- -- -- -- -- --)
punpcklqdq xmmA, xmmE ; xmmA = (A0 B0 C0 A1 B1 C1 A2 B2 C2 A3 B3 C3 A4 B4 C4 A5)
punpcklqdq xmmD, xmmG ; xmmD = (B5 C5 A6 B6 C6 A7 B7 C7 A8 B8 C8 A9 B9 C9 Aa Ba)
punpcklqdq xmmF, xmmC ; xmmF = (Ca Ab Bb Cb Ac Bc Cc Ad Bd Cd Ae Be Ce Af Bf Cf)
.column_st32:
lea ecx, [ecx + ecx * 2] ; imul ecx, RGB_PIXELSIZE cmpecx, byte 2 * SIZEOF_XMMWORD
jb short .column_st16
movdqu XMMWORD [edi + 0 * SIZEOF_XMMWORD], xmmA
movdqu XMMWORD [edi + 1 * SIZEOF_XMMWORD], xmmD
add edi, byte 2 * SIZEOF_XMMWORD ; outptr
movdqa xmmA, xmmF subecx, byte 2 * SIZEOF_XMMWORD
jmp short .column_st15
.column_st16: cmpecx, byte SIZEOF_XMMWORD
jb short .column_st15
movdqu XMMWORD [edi + 0 * SIZEOF_XMMWORD], xmmA
add edi, byte SIZEOF_XMMWORD ; outptr
movdqa xmmA, xmmD subecx, byte SIZEOF_XMMWORD
.column_st15: ; Store the lower 8 bytes of xmmA to the output when it has enough ; space. cmpecx, byte SIZEOF_MMWORD
jb short .column_st7
movq XMM_MMWORD [edi], xmmA
add edi, byte SIZEOF_MMWORD subecx, byte SIZEOF_MMWORD
psrldq xmmA, SIZEOF_MMWORD
.column_st7: ; Store the lower 4 bytes of xmmA to the output when it has enough ; space. cmpecx, byte SIZEOF_DWORD
jb short .column_st3 movd XMM_DWORD [edi], xmmA
add edi, byte SIZEOF_DWORD subecx, byte SIZEOF_DWORD
psrldq xmmA, SIZEOF_DWORD
.column_st3: ; Store the lower 2 bytes of eax to the output when it has enough ; space. movd eax, xmmA cmpecx, byte SIZEOF_WORD
jb short .column_st1
mov word [edi], ax
add edi, byte SIZEOF_WORD subecx, byte SIZEOF_WORD shr eax, 16
.column_st1: ; Store the lower 1 byte of eax to the output when it has enough ; space.
test ecx, ecx jz short .endcolumn
mov byte [edi], al
%else ; RGB_PIXELSIZE == 4 ; -----------
%ifdef RGBX_FILLER_0XFF
pcmpeqb xmm6, xmm6 ; xmm6 = XE = X(02468ace********)
pcmpeqb xmm7, xmm7 ; xmm7 = XO = X(13579bdf********)
%else
pxor xmm6, xmm6 ; xmm6 = XE = X(02468ace********)
pxor xmm7, xmm7 ; xmm7 = XO = X(13579bdf********)
%endif ; NOTE: The values of RGB_RED, RGB_GREEN, and RGB_BLUE determine the ; mapping of components A, B, C, and D to red, green, and blue. ; ; xmmA = (A0 A2 A4 A6 A8 Aa Ac Ae) = AE ; xmmB = (A1 A3 A5 A7 A9 Ab Ad Af) = AO ; xmmC = (B0 B2 B4 B6 B8 Ba Bc Be) = BE ; xmmD = (B1 B3 B5 B7 B9 Bb Bd Bf) = BO ; xmmE = (C0 C2 C4 C6 C8 Ca Cc Ce) = CE ; xmmF = (C1 C3 C5 C7 C9 Cb Cd Cf) = CO ; xmmG = (D0 D2 D4 D6 D8 Da Dc De) = DE ; xmmH = (D1 D3 D5 D7 D9 Db Dd Df) = DO
punpcklbw xmmA, xmmC ; xmmA = (A0 B0 A2 B2 A4 B4 A6 B6 A8 B8 Aa Ba Ac Bc Ae Be)
punpcklbw xmmE, xmmG ; xmmE = (C0 D0 C2 D2 C4 D4 C6 D6 C8 D8 Ca Da Cc Dc Ce De)
punpcklbw xmmB, xmmD ; xmmB = (A1 B1 A3 B3 A5 B5 A7 B7 A9 B9 Ab Bb Ad Bd Af Bf)
punpcklbw xmmF, xmmH ; xmmF = (C1 D1 C3 D3 C5 D5 C7 D7 C9 D9 Cb Db Cd Dd Cf Df)
movdqa xmmC, xmmA
punpcklwd xmmA, xmmE ; xmmA = (A0 B0 C0 D0 A2 B2 C2 D2 A4 B4 C4 D4 A6 B6 C6 D6)
punpckhwd xmmC, xmmE ; xmmC = (A8 B8 C8 D8 Aa Ba Ca Da Ac Bc Cc Dc Ae Be Ce De)
movdqa xmmG, xmmB
punpcklwd xmmB, xmmF ; xmmB = (A1 B1 C1 D1 A3 B3 C3 D3 A5 B5 C5 D5 A7 B7 C7 D7)
punpckhwd xmmG, xmmF ; xmmG = (A9 B9 C9 D9 Ab Bb Cb Db Ad Bd Cd Dd Af Bf Cf Df)
movdqa xmmD, xmmA
punpckldq xmmA, xmmB ; xmmA = (A0 B0 C0 D0 A1 B1 C1 D1 A2 B2 C2 D2 A3 B3 C3 D3)
punpckhdq xmmD, xmmB ; xmmD = (A4 B4 C4 D4 A5 B5 C5 D5 A6 B6 C6 D6 A7 B7 C7 D7)
movdqa xmmH, xmmC
punpckldq xmmC, xmmG ; xmmC = (A8 B8 C8 D8 A9 B9 C9 D9 Aa Ba Ca Da Ab Bb Cb Db)
punpckhdq xmmH, xmmG ; xmmH = (Ac Bc Cc Dc Ad Bd Cd Dd Ae Be Ce De Af Bf Cf Df)
.column_st32: cmpecx, byte SIZEOF_XMMWORD / 2
jb short .column_st16
movdqu XMMWORD [edi + 0 * SIZEOF_XMMWORD], xmmA
movdqu XMMWORD [edi + 1 * SIZEOF_XMMWORD], xmmD
add edi, byte 2 * SIZEOF_XMMWORD ; outptr
movdqa xmmA, xmmC
movdqa xmmD, xmmH subecx, byte SIZEOF_XMMWORD / 2
.column_st16: cmpecx, byte SIZEOF_XMMWORD / 4
jb short .column_st15
movdqu XMMWORD [edi + 0 * SIZEOF_XMMWORD], xmmA
add edi, byte SIZEOF_XMMWORD ; outptr
movdqa xmmA, xmmD subecx, byte SIZEOF_XMMWORD / 4
.column_st15: ; Store two pixels (8 bytes) of xmmA to the output when it has enough ; space. cmpecx, byte SIZEOF_XMMWORD / 8
jb short .column_st7
movq XMM_MMWORD [edi], xmmA
add edi, byte SIZEOF_XMMWORD / 8 * 4 subecx, byte SIZEOF_XMMWORD / 8
psrldq xmmA, SIZEOF_XMMWORD / 8 * 4
.column_st7: ; Store one pixel (4 bytes) of xmmA to the output when it has enough ; space.
test ecx, ecx jz short .endcolumn movd XMM_DWORD [edi], xmmA
%endif ; RGB_PIXELSIZE ; ---------------
.endcolumn:
sfence ; flush the write buffer
.return:
pop edi
pop esi ; pop edx ; need not be preserved ; pop ecx ; need not be preserved
pop ebx
mov esp, ebp ; esp <- aligned ebp
pop esp; esp <- original ebp
pop ebp
ret
; -------------------------------------------------------------------------- ; ; Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. ; ; GLOBAL(void) ; jsimd_h2v2_merged_upsample_sse2(JDIMENSION output_width, ; JSAMPIMAGE input_buf, ; JDIMENSION in_row_group_ctr, ; JSAMPARRAY output_buf)
EXTN(jsimd_h2v2_merged_upsample_sse2): push ebp
mov ebp, esp push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi pushedi
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.