diff --git a/common/dct.c b/common/dct.c
index 669e24f..148c010 100644
--- a/common/dct.c
+++ b/common/dct.c
@@ -568,6 +568,12 @@ void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf, int b_interlaced )
 #ifdef HAVE_MMX
         if( cpu&X264_CPU_MMXEXT )
             pf->scan_4x4 = x264_zigzag_scan_4x4_field_mmxext;
+	if( cpu&X264_CPU_SSE2 )
+	{
+	    pf->scan_4x4 = x264_zigzag_scan_4x4_field_sse2;
+	    pf->scan_8x8 = x264_zigzag_scan_8x8_field_sse2;
+            pf->sub_4x4 = x264_zigzag_sub_4x4_field_sse2;
+	}
 #endif
 
 #ifdef ARCH_PPC
@@ -581,6 +587,12 @@ void x264_zigzag_init( int cpu, x264_zigzag_function_t *pf, int b_interlaced )
         pf->scan_4x4   = zigzag_scan_4x4_frame;
         pf->sub_4x4    = zigzag_sub_4x4_frame;
 #ifdef HAVE_MMX
+	if( cpu&X264_CPU_SSE2 )
+	{
+	    pf->scan_8x8 = x264_zigzag_scan_8x8_frame_sse2;
+	    pf->scan_4x4 = x264_zigzag_scan_4x4_frame_sse2;
+            pf->sub_4x4 = x264_zigzag_sub_4x4_frame_sse2;
+	}
         if( cpu&X264_CPU_SSSE3 )
             pf->sub_4x4 = x264_zigzag_sub_4x4_frame_ssse3;
 #endif
diff --git a/common/x86/dct-a.asm b/common/x86/dct-a.asm
index 77badda..ef30b0d 100644
--- a/common/x86/dct-a.asm
+++ b/common/x86/dct-a.asm
@@ -325,6 +325,392 @@ cglobal x264_zigzag_scan_4x4_field_mmxext, 2,3
     mov    [r0+12], r2d
     RET
 
+%idefine SHUFFLE(a,b,c,d) (((a)<<0) | ((b)<<2) | ((c)<<4) | ((d)<<6))
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_8x8_frame_sse2( int16_t level[64], int16_t dct[8][8] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_8x8_frame_sse2, 2,3,0
+    ; upper stripe
+    movdqa xmm3, [r1+3*16]
+    movdqa xmm1, [r1+1*16]
+    movdqa xmm2, [r1+2*16]
+    movdqa xmm0, [r1+0*16]
+    pslldq xmm3, 1*2
+    psrldq xmm1, 1*2
+    psrldq xmm0, 2*2
+    ; save xmm1, xmm3
+    movdqa xmm5, xmm3
+    punpcklwd xmm3, xmm2 
+    movdqa xmm4, xmm1
+    punpcklwd xmm1, xmm0
+    ; save xmm3
+    movdqa xmm6, xmm3
+    punpckldq xmm3, xmm1
+    pshuflw xmm7, xmm3, SHUFFLE(0,3,2,1)
+    ;  6, 7, 8, 9
+    movhps [r0+6*2], xmm3
+    punpckhdq xmm6, xmm1
+    ; --, 3, 4, 5 
+    movq [r0+2*2], xmm7
+    pshuflw xmm7, xmm6, SHUFFLE(3,2,1,0)
+    ; 17,18,19,20
+    movhps [r0+17*2], xmm6
+    punpckhwd xmm5, xmm2
+    punpckhwd xmm4, xmm0
+    ; 10,11,12,13
+    movq [r0+10*2], xmm7
+    movdqa xmm6, xmm5
+    ; lower stripe loading interleaved
+    movdqa xmm0, [r1+4*16]
+    punpckhdq xmm5, xmm4
+    movdqa xmm1, [r1+5*16]
+    pshuflw xmm7, xmm5, SHUFFLE(3,2,1,0)
+    punpckldq xmm6, xmm4
+    movdqa xmm3, [r1+7*16]
+    ; --,36,37,38
+    movq [r0+35*2], xmm7
+    pshuflw xmm7, xmm6, SHUFFLE(3,2,1,0)
+    movdqa xmm2, [r1+6*16]
+    psrldq xmm0, 2*2
+    psrldq xmm1, 1*2
+    pslldq xmm3, 1*2
+    ; 32,33,34,35
+    movhps [r0+32*2], xmm6
+    ; save xmm0, xmm2
+    movdqa xmm4, xmm0
+    punpcklwd xmm0, xmm1
+    movdqa xmm5, xmm2
+    punpcklwd xmm2, xmm3 
+    ; save xmm0
+    movdqa xmm6, xmm0
+    ; 21,22,23,24
+    movq [r0+21*2], xmm7
+    punpckldq xmm0, xmm2
+    pshufhw xmm7, xmm0, SHUFFLE(3,2,1,0)
+    ; 25,26,27,--
+    movq [r0+2*25], xmm0
+    punpckhdq xmm6, xmm2
+    ; 28,29,30,31
+    movhps [r0+28*2], xmm7
+    pshufhw xmm7, xmm6, SHUFFLE(3,2,1,0)
+    ; 39,40,41,42
+    movq [r0+39*2], xmm6
+    punpckhwd xmm4, xmm1
+    punpckhwd xmm5, xmm3
+    movdqa xmm6, xmm4
+    ; 43,44,45,46
+    movhps [r0+43*2], xmm7
+    punpckldq xmm4, xmm5
+    pshufhw xmm7, xmm4, SHUFFLE(3,2,1,0)
+    ; 50,51,52,53
+    movq [r0+50*2], xmm4
+    punpckhdq xmm6, xmm5
+    ; 54,55,56,57
+    movhps [r0+54*2], xmm7
+    pshuflw xmm7, xmm6, SHUFFLE(1,2,3,0)
+    ; 58, 59, 60, ?
+    movq [r0+58*2], xmm7
+    ; corner: 0,1,2
+    movzx r2d, word [r1+(0+0*8)*2]
+    mov [r0+0*2], r2w
+    movzx r2d, word [r1+(0+1*8)*2]
+    mov [r0+1*2], r2w
+    movzx r2d, word [r1+(1+0*8)*2]
+    mov [r0+2*2], r2w
+    ; corner 14,15,16
+    movzx r2d, word [r1+(0+4*8)*2]
+    mov [r0+14*2], r2w
+    movzx r2d, word [r1+(0+5*8)*2]
+    mov [r0+15*2], r2w
+    movzx r2d, word [r1+(1+4*8)*2]
+    mov [r0+16*2], r2w
+    ; corner 47,48,49
+    movzx r2d, word [r1+(6+3*8)*2]
+    mov [r0+47*2], r2w
+    movzx r2d, word [r1+(7+2*8)*2]
+    mov [r0+48*2], r2w
+    movzx r2d, word [r1+(7+3*8)*2]
+    mov [r0+49*2], r2w
+    ; corner 61,62,63
+    movzx r2d, word [r1+(6+7*8)*2]
+    mov [r0+61*2], r2w
+    movzx r2d, word [r1+(7+6*8)*2]
+    mov [r0+62*2], r2w
+    movzx r2d, word [r1+(7+7*8)*2]
+    mov [r0+63*2], r2w
+    RET
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_8x8_field_sse2( int16_t level[64], int16_t dct[8][8] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_8x8_field_sse2, 2,3,0
+    ; xmm7: 60,61,62,63,52,53,58,59
+    pshufd xmm7, [r1+7*16], SHUFFLE(2,3,0,1)
+    ; xmm6: 38,51,45,46,54,55,56,57
+    pshuflw xmm6, [r1+6*16], SHUFFLE(0,3,1,2)
+    ; xmm5: 37,39,30,44,47,48,49,50
+    pshuflw xmm5, [r1+5*16], SHUFFLE(1,2,0,3)
+    ; xmm0: 0, 1, 2, 5, 6,10,11,12
+    movdqa xmm0, [r1+0*16]
+    ; xmm1: 3, 4, 7, 9,13,17,18,19
+    movdqa xmm1, [r1+1*16]
+    ; xmm2: 8,14,16,20,24,25,26,27
+    movdqa xmm2, [r1+2*16]    
+    ; xmm4: 22,29,31,36,40,41,42,43
+    movdqa xmm4, [r1+4*16]
+    ; xmm3: 21,23,15,28,32,33,34,35
+    pshuflw xmm3, [r1+3*16], SHUFFLE(1,2,0,3)
+    ; 60,61,62,63
+    movq [r0+60*2], xmm7
+    ; xmm7: 52,53,54,55,58,59,56,57
+    punpckhdq xmm7, xmm6
+    ; --,10,11,12
+    movhps [r0+9*2], xmm0
+    ; 51
+    movd [r0+50*2], xmm6
+    ; xmm6: 38,37,51,39,45,30,46,44
+    punpcklwd xmm6, xmm5
+    ; xmm7: 52,53,54,55,56,57,58,59
+    pshufhw xmm7, xmm7, SHUFFLE(2,3,0,1)
+    ; 52,53,54,55
+    movq [r0+52*2], xmm7    
+    ; 56,57,58,59
+    movhps [r0+56*2], xmm7
+    ; xmm7: 38,51,37,39,44,45,46,30
+    pshufhw xmm7, xmm6, SHUFFLE(3,0,2,1)
+    ; --,17,18,19
+    movhps [r0+16*2], xmm1
+    ; xmm6: 37,38,39,51,45,30,46,44
+    pshuflw xmm6, xmm6, SHUFFLE(1,0,3,2)
+    ; 44,45,46, --
+    movhps [r0+44*2], xmm7
+    ; xmm7: 44,45,46,30,--,--,--,--
+    psrldq xmm7, 4*2
+    ; 40,41,42,43
+    movhps [r0+40*2], xmm4
+    ; xmm4: 22,29,31,36,37,38,39,51
+    punpcklqdq xmm4, xmm6
+    ; 47,48,49,50
+    movhps [r0+47*2], xmm5
+    ; 32,33,34,35
+    movhps [r0+32*2], xmm3
+    ; xmm4: --,22,29,31,36,37,38,39
+    pslldq xmm4, 1*2
+    ; 24,25,26,27
+    movhps [r0+24*2], xmm2
+    ; 36,37,38,39
+    movhps [r0+36*2], xmm4
+    ; xmm7: 44,15,45,21,46,23,30,28
+    punpcklwd xmm7, xmm3
+    ; 0,1,2
+    movq [r0+0*2], xmm0
+    ; xmm0: 5, 6,10,11,12,-0,-0,-0
+    psrldq xmm0, 3*2
+    ; 3,4 
+    movd [r0+3*2], xmm1
+    ; xmm3: 21,23,15,28,--,22,29,31
+    punpcklqdq xmm3, xmm4
+    ; xmm7: 46,23,--,22,30,28,29,31
+    punpckhdq xmm7, xmm3
+    ; 5 6
+    movd [r0+5*2], xmm0
+    ; xmm6: 46,23,--,22,28,29,30,31
+    pshufhw xmm6, xmm7, SHUFFLE(1,2,0,3)
+    ; xmm7: 46,8,23,14,--,16,22,20
+    punpcklwd xmm7, xmm2
+    ; xmm5: xmm5: 37,39,30,44,21,23,15,28
+    punpcklqdq xmm5, xmm3
+    ; 28,29,30,31
+    movhps [r0+28*2], xmm6
+    ; xmm6: 46,8,23,14,20,22,--,16
+    pshufhw xmm6, xmm7, SHUFFLE(3,2,1,0)
+    ; 7
+    movzx r2d, word [r1+(2+8*1)*2]
+    mov [r0+7*2],r2w
+    ; 8
+    movzx r2d, word [r1+(0+2*8)*2]
+    mov [r0+8*2],r2w
+    ; xmm6: 20,21,22,23,--,15,16,28
+    punpckhwd xmm6, xmm5
+    ; 9
+    movzx r2d, word [r1+(3+1*8)*2]
+    mov [r0+9*2],r2w
+    ; 13
+    movzx r2d, word [r1+(4+1*8)*2]
+    mov [r0+13*2],r2w
+    ; 20,21,22,23
+    movq [r0+20*2], xmm6
+    ; 14
+    movzx r2d, word [r1+(1+2*8)*2]
+    mov [r0+14*2],r2w
+    ; 15
+    movzx r2d, word [r1+(0+3*8)*2]
+    mov [r0+15*2],r2w
+    ; 16
+    movzx r2d, word [r1+(2+2*8)*2]
+    mov [r0+16*2],r2w
+    RET
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_4x4_field_sse2 ( int16_t level[16], int16_t dct[4][4] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_4x4_field_sse2, 2,3,0
+    ;; *(uint32_t*)level = *(uint32_t*)dct;
+    ;; ZIG(2,0,1) ZIG(3,2,0) ZIG(4,3,0) ZIG(5,1,1)
+    ;; *(uint32_t*)(level+6) = *(uint32_t*)(*dct+6);
+    ;; *(uint64_t*)(level+8) = *(uint64_t*)(*dct+8);
+    ;; *(uint64_t*)(level+12) = *(uint64_t*)(*dct+12);
+    pshuflw xmm0, [r1+0], SHUFFLE(0,1,3,2)
+%ifndef ARCH_X86_64
+    mov r2d, [r1+16]
+    mov [r0+16], r2d
+    mov r2d, [r1+20]
+    mov [r0+20], r2d
+    mov r2d, [r1+24]
+    mov [r0+24], r2q
+    mov r2d, [r1+28]
+    mov [r0+28], r2d
+%else
+    mov r2q, [r1+16]
+    mov [r0+16], r2q
+    mov r2q, [r1+24]
+    mov [r0+24], r2q
+%endif
+    movzx r2d, word [r1 + 3*2]
+    movzx r1d, word [r1 + 4*2]
+    movq [r0+0], xmm0
+    movhps [r0+8], xmm0
+    mov [r0+2*2], r1w
+    mov [r0+4*2], r2w
+    RET
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_scan_4x4_frame_sse2 ( int16_t level[16], int16_t dct[4][4] )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_scan_4x4_frame_sse2, 2,3,0
+    movq xmm2, [r1+8]
+    pshufhw xmm3, [r1+16], SHUFFLE(1,2,0,3)
+    pshuflw xmm0, [r1], SHUFFLE(0,3,1,2)
+    pshuflw xmm2, xmm2, SHUFFLE(1,0,2,3)
+    movhps [r0+12*2], xmm3
+    punpcklwd xmm2, xmm3
+    movq [r0+0*2], xmm0
+    pshufhw xmm1, xmm2, SHUFFLE(0,3,2,1)
+    movq [r0+4*2], xmm2
+    movhps [r0+8*2], xmm1
+    ; correct results
+    movzx r2d, word [r1+(3+2*4)*2]	
+    mov [r0+14*2], r2w
+    movzx r2d, word [r1+(0+1*4)*2]
+    mov [r0+1*2], r2w		
+    movzx r2d, word [r1+(0+3*4)*2]
+    mov [r0+6*2], r2w		
+    movzx r2d, word [r1+(3+0*4)*2]
+    mov [r0+9*2], r2w
+    RET
+
+;-----------------------------------------------------------------------------
+; void x264_zigzag_sub_4x4_field_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_sub_4x4_field_sse2, 3, 3, 0
+    ; 0, 2, 8,12  xmm0, xmm4
+    ; 1, 5, 9,13  xmm1, xmm5
+    ; 3, 6,10,14  xmm2, xmm6
+    ; 4, 7,11,15  xmm3, xmm7
+    ; xmm0: 0, 1, 2, 5, 8, 9,12,13
+    ; xmm2: 3, 4, 6, 7,10,11,14,15
+    movd xmm0, [r1+0*FENC_STRIDE]
+    movd xmm1, [r1+1*FENC_STRIDE]
+    movd xmm4, [r2+0*FDEC_STRIDE]
+    movd xmm5, [r2+1*FDEC_STRIDE]
+    movd xmm6, [r2+2*FDEC_STRIDE]
+    punpcklbw xmm4, xmm5
+    movd xmm2, [r1+2*FENC_STRIDE]
+    pxor xmm5, xmm5
+    movd xmm7, [r2+3*FDEC_STRIDE]
+    movd [r2+0*FDEC_STRIDE], xmm0
+    punpcklbw xmm0, xmm1
+    movd xmm3, [r1+3*FENC_STRIDE]
+    punpcklbw xmm4, xmm5
+    punpcklbw xmm0, xmm5
+    punpcklbw xmm6, xmm7
+    movd [r2+2*FDEC_STRIDE], xmm2
+    punpcklbw xmm2, xmm3
+    punpcklbw xmm6, xmm5
+    punpcklbw xmm2, xmm5
+    movd [r2+1*FDEC_STRIDE], xmm1
+    psubw xmm0, xmm4
+    psubw xmm2, xmm6
+    movdqa xmm7, xmm0
+    ; xmm0: 0, 1, 2, 5, 3, 4, 6, 7
+    punpcklqdq xmm0, xmm2
+    movd [r2+3*FDEC_STRIDE], xmm3
+    ; xmm0: ( 3, 4),( 2, 5),( 0, 1),( 6, 7)
+    pshufd xmm0, xmm0, SHUFFLE(2,1,0,3)
+    ; xmm7: 8, 9,10,11,12,13,14,15
+    punpckhdq xmm7, xmm2
+    ; xmm0: ( 2, 3),( 4, 5),( 0, 1),( 6, 7)
+    pshuflw xmm0, xmm0, SHUFFLE(2,0,1,3)
+    movdqa [r0+16], xmm7
+    ; xmm0: ( 0, 1),( 2, 3),( 4, 5),( 6, 7)
+    pshufd xmm0, xmm0, SHUFFLE(2,0,1,3)
+    movdqa [r0+0], xmm0
+    RET
+	
+;-----------------------------------------------------------------------------
+; void x264_zigzag_sub_4x4_frame_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst )
+;-----------------------------------------------------------------------------
+cglobal x264_zigzag_sub_4x4_frame_sse2, 3, 3, 0
+    ; 0, 1, 5, 6  xmm0, xmm4
+    ; 2, 4, 7,12  xmm1, xmm5
+    ; 3, 8,11,13  xmm2, xmm6
+    ; 9,10,14,15  xmm3, xmm7
+    ; xmm0: 0, 1, 5, 6, 9,10,14,15
+    ; xmm1: 2, 3, 4, 8, 7,11,12,13
+    movd xmm6, [r2+2*FDEC_STRIDE]
+    movd xmm5, [r2+1*FDEC_STRIDE]
+    movd xmm1, [r1+1*FENC_STRIDE]
+    movd xmm2, [r1+2*FENC_STRIDE]
+    movd xmm4, [r2+0*FDEC_STRIDE]
+    punpcklbw xmm5, xmm6
+    pxor xmm6, xmm6
+    movd [r2+1*FDEC_STRIDE], xmm1
+    punpcklbw xmm1, xmm2
+    movd xmm7, [r2+3*FDEC_STRIDE]
+    punpcklbw xmm5, xmm6
+    movd xmm0, [r1+0*FENC_STRIDE]
+    punpcklbw xmm1, xmm6
+    movd xmm3, [r1+3*FENC_STRIDE]
+    psubw xmm1, xmm5
+    punpckldq xmm4, xmm7
+    movd [r2+0*FDEC_STRIDE], xmm0
+    ; xmm1:  (4, 8), (7,11), (2, 3),(12,13)
+    pshufd xmm1, xmm1, SHUFFLE(1,2,0,3)
+    punpckldq xmm0, xmm3
+    punpcklbw xmm4, xmm6
+    punpcklbw xmm0, xmm6
+    ; xmm1:  (4, 7), (8,11), (2, 3),(12,13)
+    pshuflw xmm1, xmm1, SHUFFLE(0,2,1,3) 
+    psubw xmm0, xmm4
+    ; xmm1:  (2, 3), (4, 7), (8,11),(12,13)
+    pshufd xmm1, xmm1, SHUFFLE(2,0,1,3)
+    movdqa xmm7, xmm0
+    movd [r2+3*FDEC_STRIDE], xmm3
+    ; xmm0: 0, 1, 2, 3, 5, 6, 4, 7
+    punpckldq xmm0, xmm1
+    ; xmm1: 8, 11, 9,10,12,13 14,15
+    movd [r2+2*FDEC_STRIDE], xmm2
+    punpckhdq xmm1, xmm7
+    movq [r0+0*8], xmm0
+    ; xmm2: 0, 1, 2, 3, 4, 5, 6, 7
+    pshufhw xmm2, xmm0, SHUFFLE(2,0,1,3)
+    movhps [r0+3*8], xmm1
+    ; xmm3: 8, 9,10,11,12,13 14,15
+    pshuflw xmm4, xmm1, SHUFFLE(0,2,3,1)
+    movhps [r0+1*8], xmm2
+    movq [r0+2*8], xmm4
+    RET
+
 ;-----------------------------------------------------------------------------
 ; void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst )
 ;-----------------------------------------------------------------------------
diff --git a/common/x86/dct.h b/common/x86/dct.h
index 859937c..04a9add 100644
--- a/common/x86/dct.h
+++ b/common/x86/dct.h
@@ -49,6 +49,12 @@ void x264_add8x8_idct8_sse2( uint8_t *dst, int16_t dct[8][8] );
 void x264_add16x16_idct8_sse2( uint8_t *dst, int16_t dct[4][8][8] );
 
 void x264_zigzag_scan_4x4_field_mmxext( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_4x4_field_sse2( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_8x8_field_sse2( int16_t level[64], int16_t dct[8][8] );
+void x264_zigzag_sub_4x4_field_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst );
+void x264_zigzag_scan_4x4_frame_sse2( int16_t level[16], int16_t dct[4][4] );
+void x264_zigzag_scan_8x8_frame_sse2( int16_t level[64], int16_t dct[8][8] );
+void x264_zigzag_sub_4x4_frame_sse2( int16_t level[16], const uint8_t *src, uint8_t *dst );
 void x264_zigzag_sub_4x4_frame_ssse3( int16_t level[16], const uint8_t *src, uint8_t *dst );
 
 #endif
