; ; Colorspace 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"
; -------------------------------------------------------------------------- ; ; Convert some rows of samples to the output colorspace. ; ; GLOBAL(void) ; jsimd_ycc_rgb_convert_sse2(JDIMENSION out_width, JSAMPIMAGE input_buf, ; JDIMENSION input_row, JSAMPARRAY output_buf, ; int num_rows)
mov edi, JSAMPARRAY [output_buf(eax)]
mov eax, INT [num_rows(eax)]
test eax, eax
jle near .return
ALIGNX 16, 7
.rowloop: push eax pushedi push edx push ebx push esi pushecx; col
; 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 .nextrow
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 .nextrow movd XMM_DWORD [edi], xmmA
%endif ; RGB_PIXELSIZE ; ---------------
ALIGNX 16, 7
.nextrow:
pop ecx
pop esi
pop ebx
pop edx
pop edi
pop eax
add esi, byte SIZEOF_JSAMPROW
add ebx, byte SIZEOF_JSAMPROW
add edx, byte SIZEOF_JSAMPROW
add edi, byte SIZEOF_JSAMPROW ; output_buf
dec eax ; num_rows jg near .rowloop
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
; For some reason, the OS X linker does not honor the request to align the ; segment unless we do this. align32
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-10-12)
¤
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.