📄 pngvcrd.c
字号:
int sshift, dshift; int s_start, s_end, s_inc; png_uint_32 i; sp = row + (png_size_t)((row_info->width - 1) >> 1); dp = row + (png_size_t)((final_width - 1) >> 1);#if defined(PNG_READ_PACKSWAP_SUPPORTED) if (transformations & PNG_PACKSWAP) { sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); dshift = (png_size_t)(((final_width + 1) & 1) << 2); s_start = 4; s_end = 0; s_inc = -4; } else#endif { sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); s_start = 0; s_end = 4; s_inc = 4; } for (i = row_info->width; i; i--) { png_byte v; int j; v = (png_byte)((*sp >> sshift) & 0xf); for (j = 0; j < png_pass_inc[pass]; j++) { *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); if (dshift == s_end) { dshift = s_start; dp--; } else dshift += s_inc; } if (sshift == s_end) { sshift = s_start; sp--; } else sshift += s_inc; } break; } default: // This is the place where the routine is modified { __int64 const4 = 0x0000000000FFFFFF; // __int64 const5 = 0x000000FFFFFF0000; // unused... __int64 const6 = 0x00000000000000FF; png_bytep sptr, dp; png_uint_32 i; png_size_t pixel_bytes; int width = row_info->width; pixel_bytes = (row_info->pixel_depth >> 3); sptr = row + (width - 1) * pixel_bytes; dp = row + (final_width - 1) * pixel_bytes; // New code by Nirav Chhatrapati - Intel Corporation // sign fix by GRR // NOTE: there is NO MMX code for 48-bit and 64-bit images // use MMX routine if machine supports it if ( mmx_supported ) { if (pixel_bytes == 3) { if (((pass == 0) || (pass == 1)) && width) { _asm { mov esi, sptr mov edi, dp mov ecx, width sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytesloop_pass0: movd mm0, [esi] ; X X X X X v2 v1 v0 pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1 psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0 movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1 punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2 movq [edi+16] , mm4 psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0 movq [edi+8] , mm3 punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0 sub esi, 3 movq [edi], mm0 sub edi, 24 //sub esi, 3 dec ecx jnz loop_pass0 EMMS } } else if (((pass == 2) || (pass == 3)) && width) { _asm { mov esi, sptr mov edi, dp mov ecx, width sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytesloop_pass2: movd mm0, [esi] ; X X X X X v2 v1 v0 pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 movq [edi+4], mm0 ; move to memory psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0 movd [edi], mm0 ; move to memory sub esi, 3 sub edi, 12 dec ecx jnz loop_pass2 EMMS } } else if (width) /* && ((pass == 4) || (pass == 5)) */ { int width_mmx = ((width >> 1) << 1) - 8; if (width_mmx < 0) width_mmx = 0; width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 3 sub edi, 9loop_pass4: movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3 movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3 movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3 psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0 pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3 psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0 por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3 movq mm5, mm6 ; 0 0 0 X X v2 v1 v0 psllq mm6, 8 ; 0 0 X X v2 v1 v0 0 movq [edi], mm0 ; move quad to memory psrlq mm5, 16 ; 0 0 0 0 0 X X v2 pand mm5, const6 ; 0 0 0 0 0 0 0 v2 por mm6, mm5 ; 0 0 X X v2 v1 v0 v2 movd [edi+8], mm6 ; move double to memory sub esi, 6 sub edi, 12 sub ecx, 2 jnz loop_pass4 EMMS } } sptr -= width_mmx*3; dp -= width_mmx*6; for (i = width; i; i--) { png_byte v[8]; int j; png_memcpy(v, sptr, 3); for (j = 0; j < png_pass_inc[pass]; j++) { png_memcpy(dp, v, 3); dp -= 3; } sptr -= 3; } } } /* end of pixel_bytes == 3 */ else if (pixel_bytes == 1) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 31 sub esi, 3loop1_pass0: movd mm0, [esi] ; X X X X v0 v1 v2 v3 movq mm1, mm0 ; X X X X v0 v1 v2 v3 punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3 punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2 movq [edi], mm0 ; move to memory v3 punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 movq [edi+8], mm3 ; move to memory v2 movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1 punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0 movq [edi+16], mm2 ; move to memory v1 movq [edi+24], mm4 ; move to memory v0 sub esi, 4 sub edi, 32 sub ecx, 4 jnz loop1_pass0 EMMS } } sptr -= width_mmx; dp -= width_mmx*8; for (i = width; i; i--) { int j; /* I simplified this part in version 1.0.4e * here and in several other instances where * pixel_bytes == 1 -- GR-P * * Original code: * * png_byte v[8]; * png_memcpy(v, sptr, pixel_bytes); * for (j = 0; j < png_pass_inc[pass]; j++) * { * png_memcpy(dp, v, pixel_bytes); * dp -= pixel_bytes; * } * sptr -= pixel_bytes; * * Replacement code is in the next three lines: */ for (j = 0; j < png_pass_inc[pass]; j++) *dp-- = *sptr; sptr--; } } else if (((pass == 2) || (pass == 3)) && width) { int width_mmx = ((width >> 2) << 2); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 15 sub esi, 3loop1_pass2: movd mm0, [esi] ; X X X X v0 v1 v2 v3 punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1 movq [edi], mm0 ; move to memory v2 and v3 sub esi, 4 movq [edi+8], mm1 ; move to memory v1 and v0 sub edi, 16 sub ecx, 4 jnz loop1_pass2 EMMS } } sptr -= width_mmx; dp -= width_mmx*4; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } sptr --; } } else if (width) /* && ((pass == 4) || (pass == 5))) */ { int width_mmx = ((width >> 3) << 3); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub edi, 15 sub esi, 7loop1_pass4: movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7 movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7 punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7 //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3 movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3 sub esi, 8 movq [edi], mm0 ; move to memory v4 v5 v6 and v7 //sub esi, 4 sub edi, 16 sub ecx, 8 jnz loop1_pass4 EMMS } } sptr -= width_mmx; dp -= width_mmx*2; for (i = width; i; i--) { int j; for (j = 0; j < png_pass_inc[pass]; j++) { *dp-- = *sptr; } sptr --; } } } /* end of pixel_bytes == 1 */ else if (pixel_bytes == 2) { if (((pass == 0) || (pass == 1)) && width) { int width_mmx = ((width >> 1) << 1); width -= width_mmx; if (width_mmx) { _asm { mov esi, sptr mov edi, dp mov ecx, width_mmx sub esi, 2 sub edi, 30loop2_pass0: movd mm0, [esi] ; X X X X v1 v0 v3 v2 punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -