首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

急问memset设立一块内存区域,要求不按字节,按三字节RGB的方式

2013-08-21 
急问memset设置一块内存区域,要求不按字节,按三字节RGB的方式如题,现有memset只能按字节拷贝内存,现需要按

急问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;
}
}


一次设置4个像素,不过要求RGB的个数是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 );//防止优化掉
}

VS2008
cl test.cpp /FAs /O2 /GS- 编译
_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

应该没更快的了
[解决办法]
最简单的方法,直接用一个uchar*分配一大块memory
用one dimension模拟多dimension
uchar[0] = b, uchar[1] = g, uchar[2] = r
这一来就可以用memcpy copy了
openCV2就是这么做的
[解决办法]
#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
请按任意键继续. . .

热点排行