push eax push esi push edx push edi push ecx mov ecx, dend mov edi, pixels mov edx, pixelsb mov esi, mapie // Set mm7 to zero, so we can zero extend pandn mm0, mm0 repeat: // mm0 = zero // mm1 = high 4 bytes // mm2 = low 4 bytes // mm3 = temp // mm4 = unpack to word && zero extend // mm5 = unpack to word && zero extend // Add the nearest neighbooring pixels [src] as given by // [ ] [ src ] [ ] // [ src ] [ dest] [ src ] // [ ] [ src ] [ ] mov eax, dword ptr [esi] movq mm4, qword ptr [edi][-1024] movq mm5, mm4 punpckhbw mm4, mm0 punpcklbw mm5, mm0 movq mm1, mm4 movq mm2, mm5 movq mm4, qword ptr [edi][-1023] movq mm5, mm4 punpckhbw mm4, mm0 punpcklbw mm5, mm0 paddw mm1, mm4 paddw mm2, mm5 movq mm4, qword ptr [edi][1023] movq mm5, mm4 punpckhbw mm4, mm0 punpcklbw mm5, mm0 paddw mm1, mm4 paddw mm2, mm5 movq mm4, qword ptr [edi][1025] movq mm5, mm4 punpckhbw mm4, mm0 punpcklbw mm5, mm0 paddw mm1, mm4 paddw mm2, mm5 // Divide result by four [ average the pixels ] // We're using the very common substitution >> 2 instead of Divide by 4, its much much faster psrlw mm1, 2 psrlw mm2, 2 // Pack our data back into a tidy little package packuswb mm2,mm1 // mm2 now holds our final 8 byte string of computated averages movq [edx][eax], mm2 add edx, 0x08 add edi, 0x08 add esi, 0x08 dec ecx jnz repeat emms pop ecx pop edi pop edx pop esi pop eax

caustik.com

Programming & Reverse Engineering
    Current Primary Project :     Cxbx
    Documentation :     XBE File Format 1.1
    Professional :     Resume
College Stuff (CWRU)
    Groundhog Day :     The Hike The Crowd The Walmart
    Spring Courses :     EECS 345 EECS 343 EECS 338 EECS 314 MUSC 103
    Student Project :     XBox Emulator | Progress Report
    T.A. Job :     EECS 430
Work Stuff (DivX)
    DivX Networks :     DivX.com DivXNetworks.com
How To Contact Me
    Email Address :     caustik@caustik.com
    AIM SNs :     caustik, o caustik

uint32 kt = x_xbe->m_image_header.m_kernel_image_thunk_addr ^ 0xEFB1F152; if(kt > 0x01000000) kt = x_xbe->m_image_header.m_kernel_image_thunk_addr ^ 0x5b6d40b6; ... if(kt >= m_section_header[v].m_virtual_addr + m_optional_header.m_image_base && kt < m_section_header[v].m_virtual_addr + m_section_header[v].m_virtual_size + m_optional_header.m_image_base) { uint32 *kt_tbl = (uint32*)&m_section[v][kt - m_section_header[v].m_virtual_addr - m_optional_header.m_image_base]; while(*kt_tbl != 0) *kt_tbl++ = KernelThunkTable[*kt_tbl & 0xFF]; } uint32 kt = x_xbe->m_image_header.m_kernel_image_thunk_addr ^ 0xEFB1F152; if(kt > 0x01000000) kt = x_xbe->m_image_header.m_kernel_image_thunk_addr ^ 0x5b6d40b6; ... if(kt >= m_section_header[v].m_virtual_addr + m_optional_header.m_image_base && kt < m_section_header[v].m_virtual_addr + m_section_header[v].m_virtual_size + m_optional_header.m_image_base) { uint32 *kt_tbl = (uint32*)&m_section[v][kt - m_section_header[v].m_virtual_addr - m_optional_header.m_image_base]; while(*kt_tbl != 0) *kt_tbl++ = KernelThunkTable[*kt_tbl & 0xFF]; }