我将图像数据存储在 unsigned char
中大批。数据的形式为RGB0RGB0
每个字节,即每个字节和每个RGB
之后覆盖两个像素一个0
被填充以便将其对齐 4
的倍数。为了进一步处理,我需要将每个颜色分量数据 1 位转换为每个分量 8 位,即每种颜色 1 个字节。所以我正在做的是,对于每个字节,我检查 MSB,如果它是 1
,我设置一个字节为 0xFF
否则我就留下它0
。我写的代码如下:
void
convert_pixels(unsigned char *pixdata,
unsigned char *convertedpix,
int width,
int height)
{
int i,j,k, count=0;
unsigned int mask;
unsigned char temp;
for(i=0;i<height;i++)
{
count=0;
for(j=0;j<width;j++)
{
temp = *(pixdata+i*width+j);
for (mask = 0x80; mask != 0; mask >>= 1)
{
if ((temp & mask) && mask!=0x10 && mask!=0x01)
*(convertedpix+i*width*6+count)=0xFF;
count++;
}
}
}
}
它在执行时给出 SIGSEGV。 bt
上gdb
给出:
(gdb) bt
#0 0x00000000004014b0 in convert_pixels (pixdata=0x7f008a0cf010 '\377' <repeats 200 times>...,
pixdata@entry=0x7f00967e2010 'w' <repeats 200 times>..., convertedpix=0x7f00967e2010 'w' <repeats 200 times>...,
convertedpix@entry=0x7f008a0cf010 '\377' <repeats 200 times>..., width=width@entry=4958, height=height@entry=7017) at image_convert.c:166
#1 0x0000000000401007 in main (argc=<optimized out>, argv=<optimized out>) at image_convert.c:355
数组 convertedpix
已分配的内存恰好是 6
pixdata
的倍:
if(header.cupsBitsPerColor==1)
{
convertedpix = (unsigned char*)calloc(header.cupsWidth * header.cupsHeight*6,
sizeof(unsigned char));
convert_pixels(pixdata, convertedpix, header.cupsWidth,
header.cupsHeight);
}
最佳答案
您会遇到段错误,因为您以与内存布局不匹配的方式增加计数和宽度,最终会从分配的内存中写入数据。如果移动宽度和高度,则循环中的计数应相应地从 0 变为 5。
void
convert_pixels(unsigned char *pixdata, unsigned char *convertedpix,
int width, int height) {
int i, j, k;
unsigned int mask;
unsigned char temp;
for(i = 0; i < height; ++i) {
for(j = 0; j < width; ++j) {
k = 0;
temp = *(pixdata + i * width + j);
for (mask = 0x80; mask != 0; mask >>= 1) {
if (mask != 0x10 && mask != 0x01) { /* code below will be
* executed 6 times */
if (temp & mask) {
*(convertedpix + i * width + k) = 0xFF;
} else {
*(convertedpix + i * width + k) = 0;
}
++k;
}
}
}
}
}
另外,请添加对calloc
返回值的检查(可能是内存分配有问题):
if (header.cupsBitsPerColor==1) {
convertedpix = (unsigned char*) calloc(header.cupsWidth *
header.cupsHeight * 6, sizeof(unsigned char));
if (convertedpix != NULL) {
convert_pixels(pixdata, convertedpix, header.cupsWidth,
header.cupsHeight);
} else {
/* handle error */
}
}
关于c - SIGSEGV 同时将 1 位图像数据转换为 8 位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38126132/