void ARGB_TO_RGB(void* src, void* dest, int pxels) { unsigned long long mmx_rgb888_mask = 0x00FFFFFF00FFFFFF; __asm { pushad mov edi, dest; destination mov esi, src; source mov ecx, pixels; ; set up mm6 as the mask, mm7 as zero movq mm6, mmx_rgb888_mask pxor mm7, mm7 mov edx, ecx; save ecx and ecx, 0fffffffch; clear lower two bits jnz L1 jmp L2 L1 : movq mm0, [esi]; A R G B a r g b // 1,2 Çȼ¿ pand mm0, mm6; 0 R G B 0 r g b // 1,2 ¾ËÆÄ°ª ³¯¸² movq mm1, [esi + 8]; A R G B a r g b // 3,4 Çȼ¿ pand mm1, mm6; 0 R G B 0 r g b // 3,4 ¾ËÆÄ°ª ³¯¸² // 1,2 Çȼ¿ movq mm2, mm0; 0 R G B 0 r g b // mm2 ¿¡ º¹»ç punpckhdq mm2, mm7; 0 0 0 0 0 R G B // mm2 ¿¡´Â »óÀ§ 32ºñÆ® punpckldq mm0, mm7; 0 0 0 0 0 r g b // mm0 ¿¡´Â ÇÏÀ§ 32ºñÆ® psllq mm2, 24; 0 0 R G B 0 0 0 // mm2 ¿¡ 24ºñÆ® ¹Ð±â por mm0, mm2; 0 0 R G B r g b // mm0 ¿¡ ÇÕÄ¡±â // 3,4 Çȼ¿ movq mm3, mm1; 0 R G B 0 r g b // 3,4 Çȼ¿ °ªÀ» mm3 ¿¡ º¹»ç psllq mm3, 48; g b 0 0 0 0 0 0 // mm3 ÀÇ 48ºñÆ® ½¬ÇÁÆ®¸¦ °É¾î, 16 ºñÆ®¸¸ ³²±ä´Ù por mm0, mm3; g b R G B r g b // ÀÌ°É 1,2 Çȼ¿ °ª(mm0)¿¡ ºÙÀδ٠movq mm4, mm1; 0 R G B 0 r g b // 3,4 Çȼ¿ °ªÀ» mm4 ¿¡ ´Ù½Ã º¹»ç punpckhdq mm4, mm7; 0 0 0 0 0 R G B // »óÀ§32ºñÆ® punpckldq mm1, mm7; 0 0 0 0 0 r g b // ÇÏÀ§32ºñÆ® psrlq mm1, 16; 0 0 0 R G B 0 r // ÇÏÀ§32ºñÆ®Áß 16ºñÆ®¸¦ ³¯¸°´Ù (ÀÌ¹Ì À§¿¡¼­ mm0 ¿¡ µé¾î°£ ºÎºÐ) psllq mm4, 8; 0 0 0 0 R G B 0 // »óÀ§32ºñÆ® por mm1, mm4; 0 0 0 0 R G B r // ¿Í ÇÏÀ§ ºñÆ® ³²Àº°É ºÙ¿©¼­ // ¸ñÀûÁö¿¡ °áÇÕµÈ µ¥ÀÌÅÍ (mm0, mm1) º¹»ç movq[edi], mm0 add esi, 16 // ¿øº»¿¡¼± 4Çȼ¿ , 16¹ÙÀÌÆ® ÀüÁø movd[edi + 8], mm1 add edi, 12 // ¸ñÀûÁö¿¡¼± 4Çȼ¿, 12¹ÙÀÌÆ®(4px * 24bpp) ÀüÁø sub ecx, 4 // 4 Çȼ¿¾¿ °¨¼Ò jnz L1 L2 : mov ecx, edx and ecx, 3 jz L4 L3 : mov al, [esi] mov bl, [esi + 1] mov dl, [esi + 2] mov[edi], al mov[edi + 1], bl mov[edi + 2], dl add esi, 4 add edi, 3 dec ecx jnz L3 L4 : emms popad }; }