急问memset设置一块内存区域,要求不按字节,按三字节RGB的方式
如题,
现有memset只能按字节拷贝内存,现需要按三字节拷贝有好的思路没?
急!!
[解决办法]
RGB3字节不好办,RGBA4字节还凑合。参考下面:
#include <stdio.h>
float data[500];
int i;
void main() {
for (i=0;i<500;i++) {data[i]=1.0f;printf("%g\n",data[i]);}
__asm {
push ecx
push edi
mov ecx,500
mov eax,0xBF800000 //-1.0f
lea edi,data
rep stosd
pop edi
pop ecx
}
for (i=0;i<500;i++) printf("%g\n",data[i]);
}
struct rgb
{
unsigned char r;
unsigned char g;
unsigned char b;
};
rgb v = {1, 2, 3};
char buf[81];
char (*p)[3] = (char(*)[3])buf;
for(; p < (char(*)[3])(buf + sizeof(buf)); ++p)
{
(*p)[0] = v.r;
(*p)[1] = v.g;
(*p)[2] = v.b;
}
struct RGB
{
BYTE R;
BYTE G;
BYTE B;
};
void RGBSet(RGB *pRGBDest,DWORD dw0BGR,int iCount)
{
int i;
DWORD dwRBGR,dwGRBG,dwBGRB;
dwRBGR=dw0BGR
[解决办法]
(dw0BGR<<24);
dwGRBG=(dw0BGR>>8)
[解决办法]
(dw0BGR<<16);
dwBGRB=(dw0BGR<<8)
[解决办法]
(dw0BGR>>16);
for (i=0;i<iCount/4;i++)
{
((DWORD *)pRGBDest)[0]=dwRBGR;
((DWORD *)pRGBDest)[1]=dwGRBG;
((DWORD *)pRGBDest)[2]=dwBGRB;
pRGBDest+=4;
}
}
#include<algorithm>
using namespace std;
extern "C" void __stdcall OutputDebugStringA( const char*);
struct rgb
{
char r,g,b;
};
int main()
{
char t[300];
rgb v={1,2,3};
fill_n( (rgb*)t, 100 , v );
OutputDebugStringA( t );//防止优化掉
}
_TEXTSEGMENT
_v$ = -304; size = 3
_t$ = -300; size = 300
_mainPROC; COMDAT
; 14 : {
subesp, 304; 00000130H
pushesi
pushedi
; 15 : char t[300];
; 16 : rgb v={1,2,3};
movBYTE PTR _v$[esp+312], 1
movBYTE PTR _v$[esp+313], 2
; 17 : fill_n( (rgb*)t, 100 , v );
movcx, WORD PTR _v$[esp+312]
movWORD PTR _t$[esp+312], cx
moval, 3
; 18 : OutputDebugStringA( t );
leaedx, DWORD PTR _t$[esp+312]
movBYTE PTR _t$[esp+314], al
movecx, 297; 00000129H
leaesi, DWORD PTR _t$[esp+312]
leaedi, DWORD PTR _t$[esp+315]
pushedx
rep movsb
call_OutputDebugStringA@4
popedi
; 19 : }
xoreax, eax
popesi
addesp, 304; 00000130H
ret0
_mainENDP
_TEXTENDS
END
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctime>
template<size_t N, size_t uintSize>
void Memset(void* dest, char (&v)[N], size_t num);
//假设为小端模式
template<>
inline void Memset<3, 4>(void* dest, char (&v)[3], size_t num)
{
size_t totalByte = (num << 1) + num; //num * 3
unsigned int
a = ((unsigned char)(v[0]) << 0)
[解决办法]
((unsigned char)(v[1]) << 8)
[解决办法]
((unsigned char)(v[2]) << 16)
[解决办法]
((unsigned char)(v[0]) << 24),
b = ((unsigned char)(v[1]) << 0)
[解决办法]
((unsigned char)(v[2]) << 8)
[解决办法]
((unsigned char)(v[0]) << 16)
[解决办法]
((unsigned char)(v[1]) << 24),
c = ((unsigned char)(v[2]) << 0)
[解决办法]
((unsigned char)(v[0]) << 8)
[解决办法]
((unsigned char)(v[1]) << 16)
[解决办法]
((unsigned char)(v[2]) << 24);
for(size_t i = 0, mx = totalByte / 12; i < mx; )
{
((unsigned int*)dest)[i++] = a;
((unsigned int*)dest)[i++] = b;
((unsigned int*)dest)[i++] = c;
}
dest = (unsigned char*)dest + totalByte / 12 * 12;
for(size_t i = 0, mx = totalByte % 12;;)
{
((unsigned char*)dest)[i++] = (unsigned char)v[0];
if(i >= mx) break;
((unsigned char*)dest)[i++] = (unsigned char)v[1];
if(i >= mx) break;
((unsigned char*)dest)[i++] = (unsigned char)v[2];
}
}
int main()
{
char *a = (char*)malloc(4096/3*3);
char rgb[3] = {0,0,0};
time_t s = time(NULL);
for(int i = 0; i < 1024 * 1024 * 100; ++i)
Memset<3,sizeof(unsigned int)>(a, rgb, 4096/3);
time_t e = time(NULL);
printf("Memset:\n\t%lld --> %lld == %lld\n",(long long)s,(long long )e, (long long)e - s);
s = time(NULL);
for(int i = 0; i < 1024 * 1024 * 100; ++i)
memset(a, 0, 4096/3*3);
e = time(NULL);
printf("memset:\n\t%lld --> %lld == %lld\n",(long long)s,(long long )e, (long long)e - s);
free(a);
return 0;
}
Memset:
1376621011 --> 1376621026 == 15
memset:
1376621026 --> 1376621038 == 12
请按任意键继续. . .