📄 pngvcrd.c
字号:
s_inc = 2;
}
for (i = row_info->width; i; i--)
{
png_byte v;
int j;
v = (png_byte)((*sp >> sshift) & 0x3);
for (j = 0; j < png_pass_inc[pass]; j++)
{
*dp &= (png_byte)((0x3f3f >> (6 - 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;
}
case 4:
{
png_bytep sp, dp;
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 ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
/* && 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_bytes
loop_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_bytes
loop_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, 9
loop_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, 3
loop1_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, 3
loop1_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, 7
loop1_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -